From 8520cc39ac0e01ac850e4d3868cb3810f77077b8 Mon Sep 17 00:00:00 2001 From: Ivan Mahonin Date: Oct 16 2019 09:55:17 +0000 Subject: move-origin duck --- diff --git a/synfig-studio/src/gui/duck.cpp b/synfig-studio/src/gui/duck.cpp index ca81d0c..f7c7abb 100644 --- a/synfig-studio/src/gui/duck.cpp +++ b/synfig-studio/src/gui/duck.cpp @@ -90,6 +90,7 @@ Duck::Duck(): exponential_(false), track_axes_(false), lock_aspect_(false), + move_origin_(false), scalar_(1), origin_(0,0), axis_x_angle_(Angle::deg(0)), @@ -98,57 +99,30 @@ Duck::Duck(): axis_y_mag_(1), rotations_(synfig::Angle::deg(0)), aspect_point_(1,1) -{ duck_count++; _DuckCounter::counter++; } +{ + duck_count++; + _DuckCounter::counter++; +} Duck::Duck(const synfig::Point &point): - guid_(0), - type_(TYPE_POSITION), - editable_(false), - alternative_editable_(false), - edit_immediatelly_(false), - radius_(false), - tangent_(false), - hover_(false), - ignore_(false), - exponential_(false), - track_axes_(false), - lock_aspect_(false), - scalar_(1), - origin_(0,0), - axis_x_angle_(Angle::deg(0)), - axis_x_mag_(1), - axis_y_angle_(Angle::deg(90)), - axis_y_mag_(1), - point_(point), - rotations_(synfig::Angle::deg(0)), - aspect_point_(1,1) -{ duck_count++; _DuckCounter::counter++;} + Duck() +{ + type_ = TYPE_POSITION; + point_ = point; +} -Duck::Duck(const synfig::Point &point,const synfig::Point &origin): - guid_(0), - type_(TYPE_NONE), - editable_(false), - alternative_editable_(false), - edit_immediatelly_(false), - radius_(true), - tangent_(false), - hover_(false), - ignore_(false), - exponential_(false), - track_axes_(false), - lock_aspect_(false), - scalar_(1), - origin_(origin), - axis_x_angle_(Angle::deg(0)), - axis_x_mag_(1), - axis_y_angle_(Angle::deg(90)), - axis_y_mag_(1), - point_(point), - rotations_(synfig::Angle::deg(0)), - aspect_point_(1,1) -{ duck_count++; _DuckCounter::counter++;} +Duck::Duck(const synfig::Point &point, const synfig::Point &origin): + Duck() +{ + origin_ = origin; + point_ = point; +} -Duck::~Duck() { duck_count--; _DuckCounter::counter--;} +Duck::~Duck() +{ + duck_count--; + _DuckCounter::counter--; +} synfig::GUID Duck::get_data_guid()const @@ -189,6 +163,12 @@ Duck::operator==(const Duck &rhs)const void Duck::set_point(const synfig::Point &x) { + if (get_move_origin() && origin_duck_) { + Point offset = get_trans_point(x) - get_trans_point(); + origin_duck_->set_trans_point(origin_duck_->get_trans_point() + offset); + return; + } + if (is_aspect_locked()) point_ = aspect_point_ * (x * aspect_point_); else @@ -225,6 +205,12 @@ Duck::get_trans_point()const return transform_stack_.perform(get_sub_trans_point()); } +synfig::Point +Duck::get_trans_point(const synfig::Point &x)const +{ + return transform_stack_.perform(get_sub_trans_point(x)); +} + void Duck::set_trans_point(const synfig::Point &x) { @@ -254,9 +240,7 @@ Duck::get_sub_trans_point_without_offset(const synfig::Point &x)const { synfig::Point Duck::get_sub_trans_point(const synfig::Point &x)const { - Point p(x*get_scalar()); - return get_axis_x()*p[0] - + get_axis_y()*p[1] + return get_sub_trans_point_without_offset(x) + get_sub_trans_origin(); } diff --git a/synfig-studio/src/gui/duck.h b/synfig-studio/src/gui/duck.h index 0a5446f..2699ae1 100644 --- a/synfig-studio/src/gui/duck.h +++ b/synfig-studio/src/gui/duck.h @@ -129,6 +129,7 @@ private: bool exponential_; bool track_axes_; bool lock_aspect_; + bool move_origin_; // positioning @@ -284,6 +285,12 @@ public: void set_lock_aspect(bool r) { if (!lock_aspect_ && r) aspect_point_=point_.norm(); lock_aspect_=r; } + void set_move_origin(bool x) + { move_origin_=x; } + //! Retrieves the exponential value + bool get_move_origin()const + { return move_origin_; } + // positioning void set_transform_stack(const synfig::TransformStack& x) @@ -418,6 +425,7 @@ public: // calculation of position of duck at workarea synfig::Point get_trans_point()const; + synfig::Point get_trans_point(const synfig::Point &x)const; void set_trans_point(const synfig::Point &x); void set_trans_point(const synfig::Point &x, const synfig::Time &time); diff --git a/synfig-studio/src/gui/duckmatic.cpp b/synfig-studio/src/gui/duckmatic.cpp index 05332fb..ea3c7d3 100644 --- a/synfig-studio/src/gui/duckmatic.cpp +++ b/synfig-studio/src/gui/duckmatic.cpp @@ -1037,21 +1037,21 @@ Duckmatic::on_duck_changed(const studio::Duck &duck,const synfigapp::ValueDesc& else if (type == type_transformation) { - if (get_alternative_mode() - && duck.get_alternative_editable() - && duck.get_alternative_value_desc().is_valid() - && duck.get_alternative_value_desc().parent_is_layer() - && etl::handle::cast_dynamic(duck.get_alternative_value_desc().get_layer()) - && duck.get_alternative_value_desc().get_param_name() == "origin") + if ( duck.get_move_origin() + && duck.get_origin_duck() + && duck.get_value_desc().is_valid() + && duck.get_value_desc().parent_is_layer() + && etl::handle::cast_dynamic(duck.get_value_desc().get_layer()) + && duck.get_value_desc().get_param_name() == "origin" ) { - Point origin = duck.get_alternative_value_desc().get_value(get_time()).get(Point()); - Transformation transformation = duck.get_value_desc().get_value(get_time()).get(Transformation()); - Point delta_offset = value - transformation.offset; + Point origin = duck.get_value_desc().get_value(get_time()).get(Point()); + Transformation transformation = duck.get_origin_duck()->get_value_desc().get_value(get_time()).get(Transformation()); + Point delta_offset = duck.get_origin_duck()->get_point() - transformation.offset; Point delta_origin = transformation.back_transform(delta_offset, false); transformation.offset += delta_offset; origin += delta_origin; - return canvas_interface->change_value(duck.get_alternative_value_desc(), origin, lock_animation) - && canvas_interface->change_value(duck.get_value_desc(), transformation, lock_animation); + return canvas_interface->change_value(duck.get_value_desc(), origin, lock_animation) + && canvas_interface->change_value(duck.get_origin_duck()->get_value_desc(), transformation, lock_animation); } else { @@ -1124,7 +1124,7 @@ Duckmatic::on_duck_changed(const studio::Duck &duck,const synfigapp::ValueDesc& return canvas_interface->change_value(value_desc, point, lock_animation); } - + return canvas_interface->change_value(value_desc,value,lock_animation); } @@ -1968,14 +1968,14 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handle layer = etl::handle::cast_dynamic(value_desc.get_layer()); if (layer) { - synfigapp::ValueDesc alternative_value_desc(value_desc.get_layer(), "origin"); + synfigapp::ValueDesc origin_value_desc(value_desc.get_layer(), "origin"); Transformation transformation = value_desc.get_value(get_time()).get(Transformation()); bool editable = !value_desc.is_value_node() || synfigapp::is_editable(value_desc.get_value_node()); - bool alternative_editable = !alternative_value_desc.is_value_node() - || synfigapp::is_editable(alternative_value_desc.get_value_node()); - alternative_editable = alternative_editable && editable; + bool origin_editable = !origin_value_desc.is_value_node() + || synfigapp::is_editable(origin_value_desc.get_value_node()); + origin_editable = origin_editable && editable; Point axis_x(1, transformation.angle); Point axis_y(1, transformation.angle + Angle::deg(90.f) + transformation.skew_angle); @@ -2000,9 +2000,7 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handleset_point(transformation.offset); duck->set_editable(editable); - duck->set_alternative_editable(alternative_editable); duck->set_type(Duck::TYPE_POSITION); - duck->set_alternative_value_desc(alternative_value_desc); connect_signals(duck, duck->get_value_desc(), *canvas_view); add_duck(duck); @@ -2080,6 +2078,23 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handleget_value_desc(), *canvas_view); add_duck(duck); + // add move-origin duck + if (origin_editable) { + duck=new Duck(); + set_duck_value_desc(*duck, origin_value_desc, transform_stack); + duck->set_point(Point(0, -0.2)); + duck->set_editable(origin_editable); + duck->set_type(Duck::TYPE_POSITION); + duck->set_origin(origin_duck); + duck->set_move_origin(true); + duck->set_axis_x_angle(scale_x_duck); + duck->set_axis_x_mag(scale_x_duck); + duck->set_axis_y_angle(scale_y_duck); + duck->set_axis_y_mag(scale_y_duck); + connect_signals(duck, duck->get_origin_duck()->get_value_desc(), *canvas_view); + add_duck(duck); + } + return true; } } @@ -3119,12 +3134,15 @@ DuckDrag_Translate::begin_duck_drag(Duckmatic* duckmatic, const synfig::Vector& { is_moving = false; - last_translate_=Vector(0,0); - { - drag_offset_=duckmatic->find_duck(offset)->get_trans_point(); - - snap=Vector(0,0); - } + Duck::Handle duck = duckmatic->find_duck(offset); + assert(duck); + Duck::Handle origin_duck = duck; + while(origin_duck->get_move_origin() && origin_duck->get_origin_duck()) + origin_duck = origin_duck->get_origin_duck(); + + last_translate_ = Vector(0, 0); + drag_offset_ = duck->get_trans_point(); + snap_offset_ = origin_duck->get_trans_point() - drag_offset_; const DuckList selected_ducks(duckmatic->get_selected_ducks()); DuckList::const_iterator iter; @@ -3158,21 +3176,24 @@ DuckDrag_Translate::duck_drag(Duckmatic* duckmatic, const synfig::Vector& vector const DuckList selected_ducks(duckmatic->get_selected_ducks()); DuckList::const_iterator iter; - synfig::Vector vect(duckmatic->snap_point_to_grid(vector)-drag_offset_); + synfig::Vector offset = + duckmatic->snap_point_to_grid(vector + snap_offset_) + - snap_offset_ + - drag_offset_; int i; Time time(duckmatic->get_time()); // drag the vertex and position ducks first for (i=0,iter=selected_ducks.begin(); iter!=selected_ducks.end(); ++iter,i++) if((*iter)->get_type() == Duck::TYPE_VERTEX || (*iter)->get_type() == Duck::TYPE_POSITION) - (*iter)->set_trans_point(positions[i]+vect, time); + (*iter)->set_trans_point(positions[i] + offset, time); // then drag the others for (i=0,iter=selected_ducks.begin(); iter!=selected_ducks.end(); ++iter,i++) if ((*iter)->get_type() != Duck::TYPE_VERTEX && (*iter)->get_type() != Duck::TYPE_POSITION) - (*iter)->set_trans_point(positions[i]+vect, time); + (*iter)->set_trans_point(positions[i] + offset, time); - last_translate_=vect; + last_translate_ = offset; if(last_translate_.mag()>0.0001) is_moving = true; diff --git a/synfig-studio/src/gui/duckmatic.h b/synfig-studio/src/gui/duckmatic.h index dcda940..1c00afd 100644 --- a/synfig-studio/src/gui/duckmatic.h +++ b/synfig-studio/src/gui/duckmatic.h @@ -74,7 +74,7 @@ class DuckDrag_Translate : public DuckDrag_Base { synfig::Vector last_translate_; synfig::Vector drag_offset_; - synfig::Vector snap; + synfig::Vector snap_offset_; std::vector positions; bool is_moving = false;