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=0000000000000000000000000000000000000000;hb=a095981e18cc37a8ecc7cd237cc22b9c10329264;hp=1c7ef4ff2824cb4b00f5d867f9e5fee36e3d7142;hpb=9459638ad6797b8139f1e9f0715c96076dbf0890;p=synfig.git diff --git a/synfig-studio/trunk/src/gtkmm/state_width.cpp b/synfig-studio/trunk/src/gtkmm/state_width.cpp deleted file mode 100644 index 1c7ef4f..0000000 --- a/synfig-studio/trunk/src/gtkmm/state_width.cpp +++ /dev/null @@ -1,603 +0,0 @@ -/* === S Y N F I G ========================================================= */ -/*! \file state_width.cpp -** \brief Template File -** -** $Id$ -** -** \legal -** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley -** Copyright (c) 2008 Chris Moore -** -** This package is free software; you can redistribute it and/or -** modify it under the terms of the GNU General Public License as -** published by the Free Software Foundation; either version 2 of -** the License, or (at your option) any later version. -** -** This package is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** General Public License for more details. -** \endlegal -*/ -/* ========================================================================= */ - -/* === H E A D E R S ======================================================= */ - -#ifdef USING_PCH -# include "pch.h" -#else -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include - -#include - -#include -#include - -#include "state_width.h" -#include "canvasview.h" -#include "workarea.h" -#include "app.h" - -#include -#include "event_mouse.h" -#include "event_layerclick.h" -#include "toolbox.h" -#include "dialog_tooloptions.h" -#include -#include "duck.h" - -//#include -#include - -#include - -#include "general.h" - -#endif - -/* === U S I N G =========================================================== */ - -using namespace std; -using namespace etl; -using namespace synfig; -using namespace synfigapp; -using namespace studio; - -/* === M A C R O S ========================================================= */ - -/* === G L O B A L S ======================================================= */ - -StateWidth studio::state_width; - -/* === C L A S S E S & S T R U C T S ======================================= */ - -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::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 - - //events - Smach::event_result event_stop_handler(const Smach::event& x); - Smach::event_result event_refresh_handler(const Smach::event& x); - Smach::event_result event_mouse_handler(const Smach::event& x); - Smach::event_result event_refresh_tool_options(const Smach::event& x); - - //constructor destructor - StateWidth_Context(CanvasView* canvas_view); - ~StateWidth_Context(); - - //Canvas interaction - const etl::handle& 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();} - - //Modifying settings etc. - void load_settings(); - void save_settings(); - void reset(); - -}; // END of class StateWidth_Context - -/* === M E T H O D S ======================================================= */ - -StateWidth::StateWidth(): - Smach::state("width") -{ - insert(event_def(EVENT_STOP,&StateWidth_Context::event_stop_handler)); - insert(event_def(EVENT_REFRESH,&StateWidth_Context::event_refresh_handler)); - insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,&StateWidth_Context::event_mouse_handler)); - insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DRAG,&StateWidth_Context::event_mouse_handler)); - insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_UP,&StateWidth_Context::event_mouse_handler)); - insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateWidth_Context::event_refresh_tool_options)); -} - -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 false - if(settings.get_value("width.relative",value) && value == "1") - set_relative(true); - else - set_relative(false); -} - -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"); -} - -void -StateWidth_Context::reset() -{ - refresh_ducks(); -} - -StateWidth_Context::StateWidth_Context(CanvasView* canvas_view): - canvas_view_(canvas_view), - is_working(*canvas_view), - prev_workarea_layer_clicking(get_work_area()->get_allow_layer_clicks()), - prev_workarea_duck_clicking(get_work_area()->get_allow_duck_clicks()), - old_duckmask(get_work_area()->get_type_mask()), - - settings(synfigapp::Main::get_selected_input_device()->settings()), - - adj_delta(6,0,20,0.01,0.1), - spin_delta(adj_delta,0.01,3), - - adj_radius(200,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); - - //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()->set_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(); - center->set_name("p1"); - center->set_type(Duck::TYPE_POSITION); - } - - if(!radius) - { - radius = new Duck(); - radius->set_origin(center); - radius->set_radius(true); - 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()->set_allow_duck_clicks(false); - get_work_area()->set_type_mask((Duck::Type)((int)Duck::TYPE_WIDTH + (int)Duck::TYPE_RADIUS)); - - // Turn the mouse pointer to crosshairs - get_work_area()->set_cursor(Gdk::CROSSHAIR); - - // 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(); - - // Disable the time bar - //get_canvas_view()->set_sensitive_timebar(false); - - // Connect a signal - //get_work_area()->signal_user_click().connect(sigc::mem_fun(*this,&studio::StateWidth_Context::on_user_click)); - - App::toolbox->refresh(); -} - -void -StateWidth_Context::refresh_tool_options() -{ - App::dialog_tool_options->clear(); - App::dialog_tool_options->set_widget(options_table); - App::dialog_tool_options->set_local_name(_("Width Tool")); - App::dialog_tool_options->set_name("width"); -} - -Smach::event_result -StateWidth_Context::event_refresh_tool_options(const Smach::event& /*x*/) -{ - refresh_tool_options(); - return Smach::RESULT_ACCEPT; -} - -StateWidth_Context::~StateWidth_Context() -{ - save_settings(); - - //remove ducks if need be - if(added) - { - get_work_area()->erase_duck(center); - get_work_area()->erase_duck(radius); - get_work_area()->erase_duck(closestpoint); - added = false; - } - - // Restore Duck clicking - get_work_area()->set_allow_duck_clicks(prev_workarea_duck_clicking); - - // Restore layer clicking - get_work_area()->set_allow_layer_clicks(prev_workarea_layer_clicking); - - // Restore the mouse pointer - get_work_area()->reset_cursor(); - - // Restore duck masking - get_work_area()->set_type_mask(old_duckmask); - - // Tool options be rid of ye!! - App::dialog_tool_options->clear(); - - // Enable the time bar - //get_canvas_view()->set_sensitive_timebar(true); - - // 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(); - - App::toolbox->refresh(); -} - -Smach::event_result -StateWidth_Context::event_stop_handler(const Smach::event& /*x*/) -{ - throw Smach::egress_exception(); -} - -Smach::event_result -StateWidth_Context::event_refresh_handler(const Smach::event& /*x*/) -{ - refresh_ducks(); - return Smach::RESULT_ACCEPT; -} - -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) - amount1 = mult; - else if(t >= 0.8) - amount2 = mult; - else - { - t = (t-0.2)/0.6; - 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) - { - if((*i)->get_origin_duck() == p1) - { - w1 = *i; - } - - if((*i)->get_origin_duck() == p2) - { - w2 = *i; - } - } - } - } - - 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; - } -} - -Smach::event_result -StateWidth_Context::event_mouse_handler(const Smach::event& x) -{ - const EventMouse& event(*reinterpret_cast(&x)); - - //handle the click - if( (event.key == EVENT_WORKAREA_MOUSE_BUTTON_DOWN || event.key == EVENT_WORKAREA_MOUSE_BUTTON_DRAG) - && event.button == BUTTON_LEFT ) - { - const Real pw = get_work_area()->get_pw(); - 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] - - 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) - { - get_work_area()->erase_duck(center); - get_work_area()->erase_duck(radius); - 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")); - for(; i != changetable.end(); ++i) - { - //for each duck modify IT!!! - ValueDesc desc = i->first->get_value_desc(); - - if( desc.get_value_type() == ValueBase::TYPE_REAL ) - { - Action::Handle action(Action::create("ValueDescSet")); - 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("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(); - synfig::warning("Changing the width action has failed"); - return Smach::RESULT_ERROR; - } - } - } - - changetable.clear(); - - get_work_area()->queue_draw(); - - return Smach::RESULT_ACCEPT; - } - - return Smach::RESULT_OK; -} - - -void -StateWidth_Context::refresh_ducks() -{ - get_work_area()->clear_ducks(); - get_work_area()->queue_draw(); -}