X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-studio%2Ftrunk%2Fsrc%2Fgtkmm%2Fstate_width.cpp;fp=synfig-studio%2Ftrunk%2Fsrc%2Fgtkmm%2Fstate_width.cpp;h=b020369fa4d3721395e1c3222ebabedd846467e7;hb=c34eaa5441242b3e9a7b7645e9ee4983d14eae85;hp=d9d7697562488c9c230df6d9281210cef26f1c3e;hpb=5ddcf36f04cfbd10fabda4e3c5633cb27cdd4c0a;p=synfig.git diff --git a/synfig-studio/trunk/src/gtkmm/state_width.cpp b/synfig-studio/trunk/src/gtkmm/state_width.cpp index d9d7697..b020369 100644 --- a/synfig-studio/trunk/src/gtkmm/state_width.cpp +++ b/synfig-studio/trunk/src/gtkmm/state_width.cpp @@ -77,56 +77,56 @@ class studio::StateWidth_Context : public sigc::trackable { etl::handle canvas_view_; CanvasView::IsWorking is_working; - + //Point mouse_pos; - + handle center; handle radius; handle closestpoint; - + map,Real> changetable; - + etl::clock clocktime; Real lastt; - + bool added; void refresh_ducks(); - + bool prev_workarea_layer_clicking; bool prev_workarea_duck_clicking; Duckmatic::Type old_duckmask; - + //Toolbox settings synfigapp::Settings& settings; - + //Toolbox display Gtk::Table options_table; - + //Gtk::Entry entry_id; //what to name the layer - + Gtk::Adjustment adj_delta; Gtk::SpinButton spin_delta; - + Gtk::Adjustment adj_radius; Gtk::SpinButton spin_radius; - + Gtk::CheckButton check_relative; - + void AdjustWidth(handle c, float t, Real mult, bool invert); - + public: Real get_delta()const { return adj_delta.get_value(); } void set_delta(Real f) { adj_delta.set_value(f); } - + Real get_radius()const { return adj_radius.get_value(); } void set_radius(Real f) { adj_radius.set_value(f); } - + bool get_relative() const { return check_relative.get_active(); } void set_relative(bool r) { check_relative.set_active(r); } - - void refresh_tool_options(); //to refresh the toolbox + + void refresh_tool_options(); //to refresh the toolbox //events Smach::event_result event_stop_handler(const Smach::event& x); @@ -143,12 +143,12 @@ public: 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();} - + //Modifying settings etc. void load_settings(); void save_settings(); void reset(); - + }; // END of class StateGradient_Context /* === M E T H O D S ======================================================= */ @@ -170,20 +170,20 @@ StateWidth::~StateWidth() void StateWidth_Context::load_settings() -{ +{ String value; - + //parse the arguments yargh! if(settings.get_value("width.delta",value)) set_delta(atof(value.c_str())); else set_delta(6); - + if(settings.get_value("width.radius",value)) set_radius(atof(value.c_str())); else set_radius(15); - + //defaults to true if(settings.get_value("width.relative",value) && value == "0") set_relative(false); @@ -193,7 +193,7 @@ StateWidth_Context::load_settings() void StateWidth_Context::save_settings() -{ +{ settings.set_value("width.delta",strprintf("%f",get_delta())); settings.set_value("width.radius",strprintf("%f",get_radius())); settings.set_value("width.relative",get_relative()?"1":"0"); @@ -213,47 +213,47 @@ StateWidth_Context::StateWidth_Context(CanvasView* canvas_view): old_duckmask(get_work_area()->get_type_mask()), settings(synfigapp::Main::get_selected_input_device()->settings()), - + adj_delta(6,0,1,0.001,0.01), spin_delta(adj_delta,0.01,3), - + adj_radius(0,0,1e50,1,10), spin_radius(adj_radius,1,1), check_relative(_("Relative Growth")) { load_settings(); - + // Set up the tool options dialog - //options_table.attach(*manage(new Gtk::Label(_("Width Tool"))), 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); + //options_table.attach(*manage(new Gtk::Label(_("Width Tool"))), 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); //options_table.attach(entry_id, 0, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); //expand stuff options_table.attach(*manage(new Gtk::Label(_("Growth:"))), 0, 1, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); options_table.attach(spin_delta, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); - + options_table.attach(*manage(new Gtk::Label(_("Radius:"))), 0, 1, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); options_table.attach(spin_radius, 1, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); - + options_table.attach(check_relative, 0, 2, 3, 4, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); - + options_table.show_all(); - + refresh_tool_options(); App::dialog_tool_options->present(); // Turn off layer clicking get_work_area()->allow_layer_clicks=false; - + // clear out the ducks //get_work_area()->clear_ducks(); - + // Refresh the work area get_work_area()->queue_draw(); - + //Create the new ducks added = false; - + if(!center) { center = new Duck(); @@ -269,14 +269,14 @@ StateWidth_Context::StateWidth_Context(CanvasView* canvas_view): radius->set_type(Duck::TYPE_RADIUS); radius->set_name("radius"); } - + if(!closestpoint) { closestpoint = new Duck(); closestpoint->set_name("closest"); closestpoint->set_type(Duck::TYPE_POSITION); } - + //Disable duck clicking for the maximum coolness :) get_work_area()->allow_duck_clicks = false; get_work_area()->set_type_mask((Duck::Type)((int)Duck::TYPE_WIDTH + (int)Duck::TYPE_RADIUS)); @@ -287,10 +287,10 @@ StateWidth_Context::StateWidth_Context(CanvasView* canvas_view): // Hide the tables if they are showing //prev_table_status=get_canvas_view()->tables_are_visible(); //if(prev_table_status)get_canvas_view()->hide_tables(); - + // Hide the time bar //get_canvas_view()->hide_timebar(); - + // Connect a signal //get_work_area()->signal_user_click().connect(sigc::mem_fun(*this,&studio::StateWidth_Context::on_user_click)); @@ -316,7 +316,7 @@ StateWidth_Context::event_refresh_tool_options(const Smach::event& x) StateWidth_Context::~StateWidth_Context() { save_settings(); - + //remove ducks if need be if(added) { @@ -325,7 +325,7 @@ StateWidth_Context::~StateWidth_Context() get_work_area()->erase_duck(closestpoint); added = false; } - + // Restore Duck clicking get_work_area()->allow_duck_clicks = prev_workarea_duck_clicking; @@ -334,7 +334,7 @@ StateWidth_Context::~StateWidth_Context() // Restore the mouse pointer get_work_area()->reset_cursor(); - + // Restore duck masking get_work_area()->set_type_mask(old_duckmask); @@ -347,7 +347,7 @@ StateWidth_Context::~StateWidth_Context() // Bring back the tables if they were out before //if(prev_table_status)get_canvas_view()->show_tables(); - + // Refresh the work area get_work_area()->queue_draw(); @@ -367,24 +367,24 @@ StateWidth_Context::event_refresh_handler(const Smach::event& x) return Smach::RESULT_ACCEPT; } -void +void StateWidth_Context::AdjustWidth(handle c, float t, Real mult, bool invert) { //Leave the function if there is no curve if(!c)return; - + Real amount1=0,amount2=0; - + //decide how much to change each width /* t \in [0,1] - + both pressure and multiply amount are in mult (may want to change this to allow different types of falloff) - + rsq is the squared distance from the point on the curve (also part of the falloff) - - + + */ //may want to provide a different falloff function... if(t <= 0.2) @@ -397,24 +397,24 @@ StateWidth_Context::AdjustWidth(handle c, float t, Real mult, amount1 = (1-t)*mult; amount2 = t*mult; } - + if(invert) { amount1 *= -1; amount2 *= -1; } - + handle p1 = c->p1; handle p2 = c->p2; - + handle w1,w2; - + //find w1,w2 { const DuckList dl = get_work_area()->get_duck_list(); - + DuckList::const_iterator i = dl.begin(); - + for(;i != dl.end(); ++i) { if((*i)->get_type() == Duck::TYPE_WIDTH) @@ -423,7 +423,7 @@ StateWidth_Context::AdjustWidth(handle c, float t, Real mult, { w1 = *i; } - + if((*i)->get_origin_duck() == p2) { w2 = *i; @@ -431,26 +431,26 @@ StateWidth_Context::AdjustWidth(handle c, float t, Real mult, } } } - + if(amount1 != 0 && w1) { Real width = w1->get_point().mag(); - + width += amount1; w1->set_point(Vector(width,0)); - + //log in the list of changes... //to truly be changed after everything is said and done changetable[w1] = width; } - + if(amount2 != 0 && w2) { Real width = w2->get_point().mag(); - + width += amount2; w2->set_point(Vector(width,0)); - + //log in the list of changes... //to truly be changed after everything is said and done changetable[w2] = width; @@ -461,8 +461,8 @@ Smach::event_result StateWidth_Context::event_mouse_handler(const Smach::event& x) { const EventMouse& event(*reinterpret_cast(&x)); - - //handle ze click + + //handle ze click if( (event.key == EVENT_WORKAREA_MOUSE_BUTTON_DOWN || event.key == EVENT_WORKAREA_MOUSE_BUTTON_DRAG) && event.button == BUTTON_LEFT ) { @@ -470,81 +470,81 @@ StateWidth_Context::event_mouse_handler(const Smach::event& x) const Real ph = get_work_area()->get_ph(); const Real scale = sqrt(pw*pw+ph*ph); const Real rad = get_relative() ? scale * get_radius() : get_radius(); - + bool invert = (event.modifier&Gdk::CONTROL_MASK); - + const Real threshold = 0.08; - + float t = 0; Real rsq = 0; - + Real dtime = 1/60.0; - + //if we're dragging get the difference in time between now and then if(event.key == EVENT_WORKAREA_MOUSE_BUTTON_DRAG) { dtime = min(1/15.0,clocktime()); } clocktime.reset(); - + //make way for new ducks //get_work_area()->clear_ducks(); - + //update positions //mouse_pos = event.pos; - + center->set_point(event.pos); if(!added)get_work_area()->add_duck(center); radius->set_scalar(rad); if(!added)get_work_area()->add_duck(radius); - + //the other duck is at the current duck closestpoint->set_point(event.pos); if(!added)get_work_area()->add_duck(closestpoint); - + //get the closest curve... handle c; if(event.pressure >= threshold) c = get_work_area()->find_bezier(event.pos,scale*8,rad,&t); - + //run algorithm on event.pos to get 2nd placement if(!c.empty()) { bezier curve; Point p; - + curve[0] = c->p1->get_trans_point(); curve[1] = c->c1->get_trans_point(); curve[2] = c->c2->get_trans_point(); curve[3] = c->p2->get_trans_point(); - + p = curve(t); rsq = (p-event.pos).mag_squared(); - + const Real r = rad*rad; - + if(rsq < r) { closestpoint->set_point(curve(t)); - + //adjust the width... - //squared falloff for radius... [0,1] - + //squared falloff for radius... [0,1] + Real ri = (r - rsq)/r; AdjustWidth(c,t,ri*event.pressure*get_delta()*dtime,invert); } } - + //the points have been added added = true; - + //draw where it is yo! get_work_area()->queue_draw(); - + return Smach::RESULT_ACCEPT; } - + if(event.key == EVENT_WORKAREA_MOUSE_BUTTON_UP && event.button == BUTTON_LEFT) { if(added) @@ -554,11 +554,11 @@ StateWidth_Context::event_mouse_handler(const Smach::event& x) get_work_area()->erase_duck(closestpoint); added = false; } - + //Affect the width changes here... map,Real>::iterator i = changetable.begin(); - synfigapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("Sketch Width")); + synfigapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("Sketch Width")); for(; i != changetable.end(); ++i) { //for each duck modify IT!!! @@ -568,14 +568,14 @@ StateWidth_Context::event_mouse_handler(const Smach::event& x) { Action::Handle action(Action::create("value_desc_set")); assert(action); - - action->set_param("canvas",get_canvas()); - action->set_param("canvas_interface",get_canvas_interface()); - - action->set_param("value_desc",desc); + + action->set_param("canvas",get_canvas()); + action->set_param("canvas_interface",get_canvas_interface()); + + action->set_param("value_desc",desc); action->set_param("new_value",ValueBase(i->second)); action->set_param("time",get_canvas_view()->get_time()); - + if(!action->is_ready() || !get_canvas_view()->get_instance()->perform_action(action)) { group.cancel(); @@ -583,12 +583,12 @@ StateWidth_Context::event_mouse_handler(const Smach::event& x) return Smach::RESULT_ERROR; } } - } - + } + changetable.clear(); - + get_work_area()->queue_draw(); - + return Smach::RESULT_ACCEPT; }