X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-studio%2Fsrc%2Fgtkmm%2Fstate_normal.cpp;h=66c7453e43d7e51d921d20f353b34f5638e9f0a7;hb=f7042790c7926b36e9ccdd56e35e6f64c3cfacd4;hp=2810db2d431a5fdb4ad20834a86b16d7afe108e7;hpb=f5a6faad95ff8a107f3196d69c81dd2acd45e3f8;p=synfig.git diff --git a/synfig-studio/src/gtkmm/state_normal.cpp b/synfig-studio/src/gtkmm/state_normal.cpp index 2810db2..66c7453 100644 --- a/synfig-studio/src/gtkmm/state_normal.cpp +++ b/synfig-studio/src/gtkmm/state_normal.cpp @@ -6,7 +6,8 @@ ** ** \legal ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley -** Copyright (c) 2008 Chris Moore +** Copyright (c) 2007, 2008 Chris Moore +** Copyright (c) 2009 Nikita Kitaev ** ** This package is free software; you can redistribute it and/or ** modify it under the terms of the GNU General Public License as @@ -34,6 +35,7 @@ #include #include +#include #include #include #include @@ -94,10 +96,10 @@ class DuckDrag_Combo : public DuckDrag_Base bool move_only; public: - etl::handle canvas_view_; + CanvasView* canvas_view_; bool scale; bool rotate; - bool constrain; + bool constrain; DuckDrag_Combo(); void begin_duck_drag(Duckmatic* duckmatic, const synfig::Vector& begin); bool end_duck_drag(Duckmatic* duckmatic); @@ -109,7 +111,7 @@ public: class studio::StateNormal_Context : public sigc::trackable { - etl::handle canvas_view_; + CanvasView* canvas_view_; synfigapp::Settings& settings; @@ -137,24 +139,13 @@ public: bool get_constrain_flag()const { return checkbutton_constrain.get_active(); } void set_constrain_flag(bool x) { checkbutton_constrain.set_active(x); refresh_constrain_flag(); } void refresh_constrain_flag() { if(duck_dragger_)duck_dragger_->constrain=get_constrain_flag(); } - - Smach::event_result event_stop_handler(const Smach::event& x); - Smach::event_result event_refresh_handler(const Smach::event& x); - Smach::event_result event_refresh_ducks_handler(const Smach::event& x); - Smach::event_result event_undo_handler(const Smach::event& x); - Smach::event_result event_redo_handler(const Smach::event& x); - Smach::event_result event_mouse_button_down_handler(const Smach::event& x); - Smach::event_result event_multiple_ducks_clicked_handler(const Smach::event& x); - Smach::event_result event_refresh_tool_options(const Smach::event& x); - Smach::event_result event_layer_click(const Smach::event& x); - - void refresh_tool_options(); + void refresh_cursor(); StateNormal_Context(CanvasView* canvas_view); ~StateNormal_Context(); - const etl::handle& get_canvas_view()const{return canvas_view_;} + CanvasView* get_canvas_view()const{return canvas_view_;} etl::handle get_canvas_interface()const{return canvas_view_->canvas_interface();} synfig::Canvas::Handle get_canvas()const{return canvas_view_->get_canvas();} WorkArea * get_work_area()const{return canvas_view_->get_work_area();} @@ -165,6 +156,18 @@ public: bool key_pressed(GdkEventKey *event); bool key_released(GdkEventKey *event); + Smach::event_result event_stop_handler(const Smach::event& x); + Smach::event_result event_refresh_handler(const Smach::event& x); + Smach::event_result event_refresh_ducks_handler(const Smach::event& x); + Smach::event_result event_undo_handler(const Smach::event& x); + Smach::event_result event_redo_handler(const Smach::event& x); + Smach::event_result event_mouse_button_down_handler(const Smach::event& x); + Smach::event_result event_multiple_ducks_clicked_handler(const Smach::event& x); + Smach::event_result event_refresh_tool_options(const Smach::event& x); + void refresh_tool_options(); + Smach::event_result event_layer_click(const Smach::event& x); + + }; // END of class StateNormal_Context /* === M E T H O D S ======================================================= */ @@ -181,12 +184,53 @@ StateNormal::StateNormal(): insert(event_def(EVENT_WORKAREA_MULTIPLE_DUCKS_CLICKED,&StateNormal_Context::event_multiple_ducks_clicked_handler)); insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateNormal_Context::event_refresh_tool_options)); insert(event_def(EVENT_WORKAREA_LAYER_CLICKED,&StateNormal_Context::event_layer_click)); + } StateNormal::~StateNormal() { } +void StateNormal_Context::refresh_cursor() +{ + // Check the current state and return when applicable + synfig::String sname; + sname=get_canvas_view()->get_smach().get_state_name(); + if (sname=="smooth_move"||sname=="zoom"||sname=="width" || + sname=="text"||sname=="stroke"||sname=="star"||sname=="sketch"|| + sname=="scale"||sname=="zoom"||sname=="rotate"||sname=="rectangle"|| + sname=="polygon"||sname=="gradient"||sname=="fill"||sname=="draw"|| + sname=="circle") + return; + + // Change the cursor based on key flags + if(get_rotate_flag() && !get_scale_flag()) + { + get_work_area()->set_cursor(Gdk::EXCHANGE); + return; + } + if(!get_rotate_flag() && get_scale_flag()) + { + get_work_area()->set_cursor(Gdk::SIZING); + return; + } + if(get_rotate_flag() && get_scale_flag()) + { + get_work_area()->set_cursor(Gdk::CROSSHAIR); + return; + } + // If we are in BLine state and there is not key pressed return to + // the bline cursor. + if (sname=="bline") + { + get_work_area()->set_cursor(Gdk::CROSSHAIR); + return; + } + // Default cursor for Transform tool + get_work_area()->set_cursor(Gdk::ARROW); + +} + void StateNormal_Context::load_settings() { @@ -228,7 +272,7 @@ StateNormal_Context::StateNormal_Context(CanvasView* canvas_view): duck_dragger_->canvas_view_=get_canvas_view(); // Set up the tool options dialog - options_table.attach(*manage(new Gtk::Label(_("Normal Tool"))), 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); + options_table.attach(*manage(new Gtk::Label(_("Transform Tool"))), 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); options_table.attach(checkbutton_rotate, 0, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); options_table.attach(checkbutton_scale, 0, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); options_table.attach(checkbutton_constrain, 0, 2, 3, 4, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); @@ -241,7 +285,7 @@ StateNormal_Context::StateNormal_Context(CanvasView* canvas_view): options_table.show_all(); refresh_tool_options(); //App::dialog_tool_options->set_widget(options_table); - App::dialog_tool_options->present(); + //App::dialog_tool_options->present(); get_work_area()->set_allow_layer_clicks(true); get_work_area()->set_duck_dragger(duck_dragger_); @@ -249,8 +293,9 @@ StateNormal_Context::StateNormal_Context(CanvasView* canvas_view): keypress_connect=get_work_area()->signal_key_press_event().connect(sigc::mem_fun(*this,&StateNormal_Context::key_pressed),false); keyrelease_connect=get_work_area()->signal_key_release_event().connect(sigc::mem_fun(*this,&StateNormal_Context::key_released),false); -// get_canvas_view()->work_area->set_cursor(Gdk::CROSSHAIR); - get_canvas_view()->work_area->reset_cursor(); + //these will segfault +// get_work_area()->set_cursor(Gdk::CROSSHAIR); +// get_work_area()->reset_cursor(); App::toolbox->refresh(); @@ -278,6 +323,7 @@ StateNormal_Context::key_pressed(GdkEventKey *event) default: break; } + refresh_cursor(); return false; //Pass on the event to other handlers, just in case } @@ -301,6 +347,7 @@ StateNormal_Context::key_released(GdkEventKey *event) default: break; } + refresh_cursor(); return false; //Pass on the event to other handlers } @@ -309,7 +356,7 @@ StateNormal_Context::refresh_tool_options() { App::dialog_tool_options->clear(); App::dialog_tool_options->set_widget(options_table); - App::dialog_tool_options->set_local_name(_("Normal Tool")); + App::dialog_tool_options->set_local_name(_("Transform Tool")); App::dialog_tool_options->set_name("normal"); } @@ -320,7 +367,7 @@ StateNormal_Context::~StateNormal_Context() save_settings(); get_work_area()->clear_duck_dragger(); - get_canvas_view()->work_area->reset_cursor(); + get_work_area()->reset_cursor(); keypress_connect.disconnect(); keyrelease_connect.disconnect(); @@ -330,6 +377,207 @@ StateNormal_Context::~StateNormal_Context() App::toolbox->refresh(); } +DuckDrag_Combo::DuckDrag_Combo(): + scale(false), + rotate(false), + constrain(false) // Lock aspect for scale; smooth move for translate +{ +} + +void +DuckDrag_Combo::begin_duck_drag(Duckmatic* duckmatic, const synfig::Vector& offset) +{ + last_move=Vector(1,1); + + const DuckList selected_ducks(duckmatic->get_selected_ducks()); + DuckList::const_iterator iter; + + bad_drag=false; + + drag_offset=duckmatic->find_duck(offset)->get_trans_point(); + + //snap=drag_offset-duckmatic->snap_point_to_grid(drag_offset); + //snap=offset-drag_offset_; + snap=Vector(0,0); + + // Calculate center + Point vmin(100000000,100000000); + Point vmax(-100000000,-100000000); + //std::set >::iterator iter; + positions.clear(); + int i; + for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++) + { + Point p((*iter)->get_trans_point()); + vmin[0]=min(vmin[0],p[0]); + vmin[1]=min(vmin[1],p[1]); + vmax[0]=max(vmax[0],p[0]); + vmax[1]=max(vmax[1],p[1]); + positions.push_back(p); + } + center=(vmin+vmax)*0.5; + if((vmin-vmax).mag()<=EPSILON) + move_only=true; + else + move_only=false; + + + synfig::Vector vect(offset-center); + original_angle=Angle::tan(vect[1],vect[0]); + original_mag=vect.mag(); +} + + +void +DuckDrag_Combo::duck_drag(Duckmatic* duckmatic, const synfig::Vector& vector) +{ + if (!duckmatic) return; + + if(bad_drag) + return; + + //Override axis lock set in workarea when holding down the shift key + if (!move_only && (scale || rotate)) + duckmatic->set_axis_lock(false); + + synfig::Vector vect; + if (move_only || (!scale && !rotate)) + vect= duckmatic->snap_point_to_grid(vector)-drag_offset+snap; + else + vect= duckmatic->snap_point_to_grid(vector)-center+snap; + + last_move=vect; + + const DuckList selected_ducks(duckmatic->get_selected_ducks()); + DuckList::const_iterator iter; + + Time time(duckmatic->get_time()); + + int i; + if( move_only || (!scale && !rotate) ) + { + 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); + } + 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); + } + } + + if (rotate) + { + Angle::deg angle(Angle::tan(vect[1],vect[0])); + angle=original_angle-angle; + if (constrain) + { + float degrees = angle.get()/15; + angle= Angle::deg (degrees>0?std::floor(degrees)*15:std::ceil(degrees)*15); + } + Real mag(vect.mag()/original_mag); + Real sine(Angle::sin(angle).get()); + Real cosine(Angle::cos(angle).get()); + + 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)continue; + + Vector x(positions[i]-center),p; + + p[0]=cosine*x[0]+sine*x[1]; + p[1]=-sine*x[0]+cosine*x[1]; + if(scale)p*=mag; + p+=center; + (*iter)->set_trans_point(p, time); + } + 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))continue; + + Vector x(positions[i]-center),p; + + p[0]=cosine*x[0]+sine*x[1]; + p[1]=-sine*x[0]+cosine*x[1]; + if(scale)p*=mag; + p+=center; + (*iter)->set_trans_point(p, time); + } + } else if (scale) + { + if(!constrain) + { + if(abs(drag_offset[0]-center[0])>EPSILON) + vect[0]/=drag_offset[0]-center[0]; + else + vect[0]=1; + if(abs(drag_offset[1]-center[1])>EPSILON) + vect[1]/=drag_offset[1]-center[1]; + else + vect[1]=1; + } + else + { + //vect[0]=vect[1]=vect.mag()*0.707106781; + Real amount(vect.mag()/(drag_offset-center).mag()); + vect[0]=vect[1]=amount; + } + + if(vect[0]-EPSILON) + vect[0]=1; + if(vect[1]-EPSILON) + vect[1]=1; + + 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))continue; + + Vector p(positions[i]-center); + + p[0]*=vect[0]; + p[1]*=vect[1]; + p+=center; + (*iter)->set_trans_point(p, time); + } + 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))continue; + + Vector p(positions[i]-center); + + p[0]*=vect[0]; + p[1]*=vect[1]; + p+=center; + (*iter)->set_trans_point(p, time); + } + } + + // then patch up the tangents for the vertices we've moved + duckmatic->update_ducks(); + + last_move=vect; +} + +bool +DuckDrag_Combo::end_duck_drag(Duckmatic* duckmatic) +{ + if(bad_drag)return false; + + //synfigapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("Rotate Ducks")); + + if((last_move-Vector(1,1)).mag()>0.0001) + { + duckmatic->signal_edited_selected_ducks(); + return true; + } + else + { + duckmatic->signal_user_click_selected_ducks(0); + return false; + } +} Smach::event_result StateNormal_Context::event_refresh_tool_options(const Smach::event& /*x*/) @@ -616,209 +864,4 @@ StateNormal_Context::event_multiple_ducks_clicked_handler(const Smach::event& /* return Smach::RESULT_ACCEPT; } -DuckDrag_Combo::DuckDrag_Combo(): - scale(false), - rotate(false), - constrain(false) // Lock aspect for scale; smooth move for translate -{ -} - -void -DuckDrag_Combo::begin_duck_drag(Duckmatic* duckmatic, const synfig::Vector& offset) -{ - last_move=Vector(1,1); - - const DuckList selected_ducks(duckmatic->get_selected_ducks()); - DuckList::const_iterator iter; - - bad_drag=false; - - drag_offset=duckmatic->find_duck(offset)->get_trans_point(); - - //snap=drag_offset-duckmatic->snap_point_to_grid(drag_offset); - //snap=offset-drag_offset_; - snap=Vector(0,0); - - // Calculate center - Point vmin(100000000,100000000); - Point vmax(-100000000,-100000000); - //std::set >::iterator iter; - positions.clear(); - int i; - for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++) - { - Point p((*iter)->get_trans_point()); - vmin[0]=min(vmin[0],p[0]); - vmin[1]=min(vmin[1],p[1]); - vmax[0]=max(vmax[0],p[0]); - vmax[1]=max(vmax[1],p[1]); - positions.push_back(p); - } - center=(vmin+vmax)*0.5; - if((vmin-vmax).mag()<=EPSILON) - move_only=true; - else - move_only=false; - - - synfig::Vector vect(offset-center); - original_angle=Angle::tan(vect[1],vect[0]); - original_mag=vect.mag(); -} - - -void -DuckDrag_Combo::duck_drag(Duckmatic* duckmatic, const synfig::Vector& vector) -{ - if (!duckmatic) return; - - if(bad_drag) - return; - - //Override axis lock set in workarea when holding down the shift key - if (!move_only && (scale || rotate)) - duckmatic->set_axis_lock(false); - - synfig::Vector vect; - if (move_only || (!scale && !rotate)) - vect= duckmatic->snap_point_to_grid(vector)-drag_offset+snap; - else - vect= duckmatic->snap_point_to_grid(vector)-center+snap; - - last_move=vect; - - const DuckList selected_ducks(duckmatic->get_selected_ducks()); - DuckList::const_iterator iter; - - Time time(duckmatic->get_time()); - - int i; - if( move_only || (!scale && !rotate) ) - { - 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); - } - 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); - } - DuckList duck_list(duckmatic->get_duck_list()); - for (iter=duck_list.begin(); iter!=duck_list.end(); ++iter) - { - if ((*iter)->get_type() == Duck::TYPE_TANGENT || (*iter)->get_type() == Duck::TYPE_WIDTH) - { - (*iter)->update(time); - } - } - return; - } - - if (rotate) - { - Angle::deg angle(Angle::tan(vect[1],vect[0])); - angle=original_angle-angle; - if (constrain) - { - float degrees = angle.get()/15; - angle= Angle::deg (degrees>0?std::floor(degrees)*15:std::ceil(degrees)*15); - } - Real mag(vect.mag()/original_mag); - Real sine(Angle::sin(angle).get()); - Real cosine(Angle::cos(angle).get()); - - 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)continue; - - Vector x(positions[i]-center),p; - - p[0]=cosine*x[0]+sine*x[1]; - p[1]=-sine*x[0]+cosine*x[1]; - if(scale)p*=mag; - p+=center; - (*iter)->set_trans_point(p, time); - } - 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))continue; - - Vector x(positions[i]-center),p; - - p[0]=cosine*x[0]+sine*x[1]; - p[1]=-sine*x[0]+cosine*x[1]; - if(scale)p*=mag; - p+=center; - (*iter)->set_trans_point(p, time); - } - } else if (scale) - { - if(!constrain) - { - if(abs(drag_offset[0]-center[0])>EPSILON) - vect[0]/=drag_offset[0]-center[0]; - else - vect[0]=1; - if(abs(drag_offset[1]-center[1])>EPSILON) - vect[1]/=drag_offset[1]-center[1]; - else - vect[1]=1; - } - else - { - //vect[0]=vect[1]=vect.mag()*0.707106781; - Real amount(vect.mag()/(drag_offset-center).mag()); - vect[0]=vect[1]=amount; - } - - if(vect[0]-EPSILON) - vect[0]=1; - if(vect[1]-EPSILON) - vect[1]=1; - - 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))continue; - - Vector p(positions[i]-center); - - p[0]*=vect[0]; - p[1]*=vect[1]; - p+=center; - (*iter)->set_trans_point(p, time); - } - 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))continue; - - Vector p(positions[i]-center); - - p[0]*=vect[0]; - p[1]*=vect[1]; - p+=center; - (*iter)->set_trans_point(p, time); - } - } - last_move=vect; -} - -bool -DuckDrag_Combo::end_duck_drag(Duckmatic* duckmatic) -{ - if(bad_drag)return false; - //synfigapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("Rotate Ducks")); - - if((last_move-Vector(1,1)).mag()>0.0001) - { - duckmatic->signal_edited_selected_ducks(); - return true; - } - else - { - duckmatic->signal_user_click_selected_ducks(0); - return false; - } -}