X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-studio%2Ftrunk%2Fsrc%2Fgtkmm%2Fstate_draw.cpp;h=4beb8e7c0f7236759e8b63aadef523ce6157c825;hb=c3ad95144d148602f672e95ddda1f18fc35502f8;hp=76be3dc5750a5ad9aaac41ed10419d478cd31b82;hpb=c34eaa5441242b3e9a7b7645e9ee4983d14eae85;p=synfig.git diff --git a/synfig-studio/trunk/src/gtkmm/state_draw.cpp b/synfig-studio/trunk/src/gtkmm/state_draw.cpp index 76be3dc..4beb8e7 100644 --- a/synfig-studio/trunk/src/gtkmm/state_draw.cpp +++ b/synfig-studio/trunk/src/gtkmm/state_draw.cpp @@ -1,11 +1,12 @@ /* === S Y N F I G ========================================================= */ -/*! \file rotoscope_bline.cpp +/*! \file state_draw.cpp ** \brief Template File ** -** $Id: state_draw.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $ +** $Id$ ** ** \legal ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley +** Copyright (c) 2007 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 @@ -123,11 +124,14 @@ class studio::StateDraw_Context : public sigc::trackable synfigapp::Settings& settings; Gtk::Table options_table; + Gtk::Entry entry_id; Gtk::CheckButton checkbutton_pressure_width; Gtk::CheckButton checkbutton_round_ends; - Gtk::CheckButton checkbutton_auto_loop; - Gtk::CheckButton checkbutton_auto_connect; + Gtk::CheckButton checkbutton_auto_loop; // whether to loop new strokes which start and end in the same place + Gtk::CheckButton checkbutton_auto_extend; // whether to extend existing lines + Gtk::CheckButton checkbutton_auto_link; // whether to link new ducks to existing ducks Gtk::CheckButton checkbutton_region_only; + Gtk::CheckButton checkbutton_auto_export; Gtk::Button button_fill_last_stroke; //pressure spinner and such @@ -149,18 +153,27 @@ class studio::StateDraw_Context : public sigc::trackable synfigapp::BLineConverter blineconv; public: + synfig::String get_id()const { return entry_id.get_text(); } + void set_id(const synfig::String& x) { return entry_id.set_text(x); } + bool get_pressure_width_flag()const { return checkbutton_pressure_width.get_active(); } void set_pressure_width_flag(bool x) { return checkbutton_pressure_width.set_active(x); } bool get_auto_loop_flag()const { return checkbutton_auto_loop.get_active(); } void set_auto_loop_flag(bool x) { return checkbutton_auto_loop.set_active(x); } - bool get_auto_connect_flag()const { return checkbutton_auto_connect.get_active(); } - void set_auto_connect_flag(bool x) { return checkbutton_auto_connect.set_active(x); } + bool get_auto_extend_flag()const { return checkbutton_auto_extend.get_active(); } + void set_auto_extend_flag(bool x) { return checkbutton_auto_extend.set_active(x); } + + bool get_auto_link_flag()const { return checkbutton_auto_link.get_active(); } + void set_auto_link_flag(bool x) { return checkbutton_auto_link.set_active(x); } bool get_region_only_flag()const { return checkbutton_region_only.get_active(); } void set_region_only_flag(bool x) { return checkbutton_region_only.set_active(x); } + bool get_auto_export_flag()const { return checkbutton_auto_export.get_active(); } + void set_auto_export_flag(bool x) { return checkbutton_auto_export.set_active(x); } + Real get_min_pressure() const { return adj_min_pressure.get_value(); } void set_min_pressure(Real x) { return adj_min_pressure.set_value(x); } @@ -181,6 +194,7 @@ public: void load_settings(); void save_settings(); + void increment_id(); Smach::event_result event_stop_handler(const Smach::event& x); @@ -235,6 +249,11 @@ StateDraw_Context::load_settings() { String value; + if(settings.get_value("draw.id",value)) + set_id(value); + else + set_id("NewDrawing"); + if(settings.get_value("draw.pressure_width",value) && value=="0") set_pressure_width_flag(false); else @@ -245,16 +264,26 @@ StateDraw_Context::load_settings() else set_auto_loop_flag(true); - if(settings.get_value("draw.auto_connect",value) && value=="0") - set_auto_connect_flag(false); + if(settings.get_value("draw.auto_extend",value) && value=="0") + set_auto_extend_flag(false); + else + set_auto_extend_flag(true); + + if(settings.get_value("draw.auto_link",value) && value=="0") + set_auto_link_flag(false); else - set_auto_connect_flag(true); + set_auto_link_flag(true); if(settings.get_value("draw.region_only",value) && value=="1") set_region_only_flag(true); else set_region_only_flag(false); + if(settings.get_value("draw.auto_export",value) && value=="1") + set_auto_export_flag(true); + else + set_auto_export_flag(false); + if(settings.get_value("draw.min_pressure_on",value) && value=="0") set_min_pressure_flag(false); else @@ -295,10 +324,13 @@ StateDraw_Context::load_settings() void StateDraw_Context::save_settings() { + settings.set_value("draw.id",get_id().c_str()); settings.set_value("draw.pressure_width",get_pressure_width_flag()?"1":"0"); settings.set_value("draw.auto_loop",get_auto_loop_flag()?"1":"0"); - settings.set_value("draw.auto_connect",get_auto_connect_flag()?"1":"0"); + settings.set_value("draw.auto_extend",get_auto_extend_flag()?"1":"0"); + settings.set_value("draw.auto_link",get_auto_link_flag()?"1":"0"); settings.set_value("draw.region_only",get_region_only_flag()?"1":"0"); + settings.set_value("draw.auto_export",get_auto_export_flag()?"1":"0"); settings.set_value("draw.min_pressure",strprintf("%f",get_min_pressure())); settings.set_value("draw.feather",strprintf("%f",get_feather())); settings.set_value("draw.min_pressure_on",get_min_pressure_flag()?"1":"0"); @@ -307,16 +339,62 @@ StateDraw_Context::save_settings() settings.set_value("draw.localize",get_local_error_flag()?"1":"0"); } +void +StateDraw_Context::increment_id() +{ + String id(get_id()); + int number=1; + int digits=0; + + if(id.empty()) + id="Drawing"; + + // If there is a number + // already at the end of the + // id, then remove it. + if(id[id.size()-1]<='9' && id[id.size()-1]>='0') + { + // figure out how many digits it is + for(digits=0;(int)id.size()-1>=digits && id[id.size()-1-digits]<='9' && id[id.size()-1-digits]>='0';digits++)while(false); + + String str_number; + str_number=String(id,id.size()-digits,id.size()); + id=String(id,0,id.size()-digits); + synfig::info("---------------- \"%s\"",str_number.c_str()); + + number=atoi(str_number.c_str()); + } + else + { + number=1; + digits=3; + } + + number++; + + // Add the number back onto the id + { + const String format(strprintf("%%0%dd",digits)); + id+=strprintf(format.c_str(),number); + } + + // Set the ID + set_id(id); +} + StateDraw_Context::StateDraw_Context(CanvasView* canvas_view): canvas_view_(canvas_view), is_working(*canvas_view), loop_(false), prev_workarea_layer_status_(get_work_area()->allow_layer_clicks), settings(synfigapp::Main::get_selected_input_device()->settings()), + entry_id(), checkbutton_pressure_width(_("Pressure Width")), checkbutton_auto_loop(_("Auto Loop")), - checkbutton_auto_connect(_("Auto Connect")), + checkbutton_auto_extend(_("Auto Extend")), + checkbutton_auto_link(_("Auto Link")), checkbutton_region_only(_("Create Region Only")), + checkbutton_auto_export(_("Auto Export")), button_fill_last_stroke(_("Fill Last Stroke")), adj_min_pressure(0,0,1,0.01,0.1), spin_min_pressure(adj_min_pressure,0.1,3), @@ -337,22 +415,25 @@ StateDraw_Context::StateDraw_Context(CanvasView* canvas_view): UpdateErrorBox(); //options_table.attach(*manage(new Gtk::Label(_("Draw Tool"))), 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); - options_table.attach(checkbutton_pressure_width, 0, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); - options_table.attach(checkbutton_auto_loop, 0, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); - options_table.attach(checkbutton_auto_connect, 0, 2, 3, 4, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); - options_table.attach(checkbutton_region_only, 0, 2, 4, 5, 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); + options_table.attach(checkbutton_pressure_width,0, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); + options_table.attach(checkbutton_auto_loop, 0, 2, 3, 4, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); + options_table.attach(checkbutton_auto_extend, 0, 2, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); + options_table.attach(checkbutton_auto_link, 0, 2, 5, 6, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); + options_table.attach(checkbutton_region_only, 0, 2, 6, 7, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); + options_table.attach(checkbutton_auto_export, 0, 2, 7, 8, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); - options_table.attach(check_min_pressure, 0, 2, 5, 6, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); - options_table.attach(spin_min_pressure, 0, 2, 6, 7, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); + options_table.attach(check_min_pressure, 0, 2, 8, 9, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); + options_table.attach(spin_min_pressure, 0, 2, 9, 10, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); - options_table.attach(*manage(new Gtk::Label(_("Feather"))), 0, 1, 7, 8, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); - options_table.attach(spin_feather, 1, 2, 7, 8, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); + options_table.attach(*manage(new Gtk::Label(_("Feather"))), 0, 1, 10, 11, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); + options_table.attach(spin_feather, 1, 2, 10, 11, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); - options_table.attach(check_localerror, 0, 2, 8, 9, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); - options_table.attach(*manage(new Gtk::Label(_("Smooth"))), 0, 1, 9, 10, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); - options_table.attach(spin_globalthres, 1, 2, 9, 10, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); + options_table.attach(check_localerror, 0, 2, 11, 12, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); + options_table.attach(*manage(new Gtk::Label(_("Smooth"))), 0, 1, 12, 13, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); + options_table.attach(spin_globalthres, 1, 2, 12, 13, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); - //options_table.attach(button_fill_last_stroke, 0, 2, 10, 11, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); + //options_table.attach(button_fill_last_stroke, 0, 2, 13, 14, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); button_fill_last_stroke.signal_pressed().connect(sigc::mem_fun(*this,&StateDraw_Context::fill_last_stroke)); check_localerror.signal_toggled().connect(sigc::mem_fun(*this,&StateDraw_Context::UpdateErrorBox)); @@ -382,8 +463,8 @@ StateDraw_Context::StateDraw_Context(CanvasView* canvas_view): 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(); + // 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::StateDraw_Context::on_user_click)); @@ -434,7 +515,7 @@ StateDraw_Context::refresh_tool_options() } Smach::event_result -StateDraw_Context::event_refresh_tool_options(const Smach::event& x) +StateDraw_Context::event_refresh_tool_options(const Smach::event& /*x*/) { refresh_tool_options(); return Smach::RESULT_ACCEPT; @@ -456,9 +537,8 @@ StateDraw_Context::~StateDraw_Context() // Restore duck clicking get_work_area()->allow_duck_clicks=true; - // Show the time bar - if(get_canvas_view()->get_canvas()->rend_desc().get_time_start()!=get_canvas_view()->get_canvas()->rend_desc().get_time_end()) - get_canvas_view()->show_timebar(); + // 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(); @@ -470,13 +550,13 @@ StateDraw_Context::~StateDraw_Context() } Smach::event_result -StateDraw_Context::event_stop_handler(const Smach::event& x) +StateDraw_Context::event_stop_handler(const Smach::event& /*x*/) { throw Smach::egress_exception(); } Smach::event_result -StateDraw_Context::event_refresh_handler(const Smach::event& x) +StateDraw_Context::event_refresh_handler(const Smach::event& /*x*/) { refresh_ducks(); return Smach::RESULT_ACCEPT; @@ -618,9 +698,9 @@ StateDraw_Context::process_stroke(StrokeData stroke_data, WidthData width_data, synfigapp::BLineConverter::EnforceMinWidth(bline,get_min_pressure()); } - // If the start and end points are similar, then make then the same point - if(get_auto_loop_flag()) - if(bline.size()>2&&(bline.front().get_vertex()-bline.back().get_vertex()).mag()<=radius) + // If the start and end points are similar, then make them the same point + if(get_auto_loop_flag() && + bline.size()>2&&(bline.front().get_vertex()-bline.back().get_vertex()).mag()<=radius) { loop_bline_flag=true; Vector tangent; @@ -649,13 +729,13 @@ StateDraw_Context::process_stroke(StrokeData stroke_data, WidthData width_data, // Add the widths of the two points { - Real width(bline.front().get_width()+width); - width=width<=1?width:1; - bline.front().set_width(width); + Real tmp_width(bline.front().get_width()+width); + tmp_width=tmp_width<=1?tmp_width:1; + bline.front().set_width(tmp_width); } } - // If the bline only has once blinepoint, then there is nothing to do. + // If the bline only has one blinepoint, then there is nothing to do. if(bline.size()<=1) return Smach::RESULT_OK; @@ -671,53 +751,24 @@ StateDraw_Context::new_bline(std::list bline,bool loop_bline // Create the action group synfigapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("Sketch BLine")); - //ValueNode_BLine::Handle value_node(ValueNode_BLine::create(synfig::ValueBase(bline,loop_bline_flag))); - ValueNode_BLine::Handle value_node; - - { - std::list trans_bline; - std::list::iterator iter; - const synfig::TransformStack& transform(get_canvas_view()->get_curr_transform_stack()); - - for(iter=bline.begin();iter!=bline.end();++iter) - { - BLinePoint bline_point(*iter); - Point new_vertex(transform.unperform(bline_point.get_vertex())); - - bline_point.set_tangent1( - transform.unperform( - bline_point.get_tangent1()+bline_point.get_vertex() - ) -new_vertex - ); - - bline_point.set_tangent2( - transform.unperform( - bline_point.get_tangent2()+bline_point.get_vertex() - ) -new_vertex - ); - - bline_point.set_vertex(new_vertex); - - trans_bline.push_back(bline_point); - } - value_node=ValueNode_BLine::create(synfig::ValueBase(trans_bline,loop_bline_flag)); - } + bool shift_offset = false; + Vector shift_offset_vector; + bool join_start_no_extend=false,join_finish_no_extend=false; + synfigapp::ValueDesc start_duck_value_desc,finish_duck_value_desc; + bool extend_start=false,extend_finish=false,complete_loop=false; + bool extend_start_join_same=false,extend_start_join_different=false; + bool extend_finish_join_same=false,extend_finish_join_different=false; + int start_duck_index = 0,finish_duck_index = 0; // initialised to keep the compiler happy; shouldn't be needed though + ValueNode_BLine::Handle start_duck_value_node_bline=NULL,finish_duck_value_node_bline=NULL; // Find any ducks at the start or end that we might attach to - // (this used to only run if we aren't a loop - ie. !loop_bline_flag + // (this used to only run if we didn't just draw a loop - ie. !loop_bline_flag // but having loops auto-connect can be useful as well) - if(get_auto_connect_flag()) + if(get_auto_extend_flag() || get_auto_link_flag()) { - bool extend_start=false,extend_finish=false,complete_loop=false; - bool extend_start_join_same=false,extend_start_join_different=false,extend_finish_join_same=false,extend_finish_join_different=false; - int start_duck_index,finish_duck_index; - etl::handle start_duck(get_work_area()->find_duck(bline.front().get_vertex(),radius,Duck::TYPE_VERTEX)); etl::handle finish_duck(get_work_area()->find_duck(bline.back().get_vertex(),radius,Duck::TYPE_VERTEX)); - synfigapp::ValueDesc start_duck_value_desc,finish_duck_value_desc; - ValueNode_BLine::Handle start_duck_value_node_bline=NULL,finish_duck_value_node_bline=NULL; - // check whether the start of the new line extends an // existing line. this is only the case if the new // line isn't a self-contained loop, and if the new @@ -725,15 +776,21 @@ StateDraw_Context::new_bline(std::list bline,bool loop_bline if(start_duck)do { if(!(start_duck_value_desc=start_duck->get_value_desc()))break; - if(loop_bline_flag)break; + if(loop_bline_flag)break; // loops don't extend anything if(!start_duck_value_desc.parent_is_value_node())break; - start_duck_index=start_duck_value_desc.get_index(); + start_duck_index=start_duck_value_desc.get_index(); // which point on the line did we start drawing at start_duck_value_node_bline=ValueNode_BLine::Handle::cast_dynamic(start_duck_value_desc.get_parent_value_node()); + if(!get_auto_extend_flag())break; // don't extend looped blines if(start_duck_value_node_bline&&!start_duck_value_node_bline->get_loop()&& + // did we start drawing at either end of the line? (start_duck_index==0||start_duck_index==start_duck_value_node_bline->link_count()-1)) + { extend_start=true; + shift_offset=true; + shift_offset_vector=start_duck->get_origin(); + } }while(0); // check whether the end of the new line extends an @@ -747,6 +804,7 @@ StateDraw_Context::new_bline(std::list bline,bool loop_bline if(!finish_duck_value_desc.parent_is_value_node())break; finish_duck_index=finish_duck_value_desc.get_index(); finish_duck_value_node_bline=ValueNode_BLine::Handle::cast_dynamic(finish_duck_value_desc.get_parent_value_node()); + if(!get_auto_extend_flag())break; // don't extend looped blines if(finish_duck_value_node_bline&&!finish_duck_value_node_bline->get_loop()&& @@ -758,19 +816,26 @@ StateDraw_Context::new_bline(std::list bline,bool loop_bline // of the same bline, only extend the one we started on if(start_duck_value_node_bline==finish_duck_value_node_bline) complete_loop=extend_finish=true; - }else + }else{ extend_finish=true; + shift_offset=true; + shift_offset_vector=finish_duck->get_origin(); + } }while(0); // if the new line's start didn't extend an existing line, // check whether it needs to be linked to an existing duck - if(!extend_start&&start_duck&&start_duck_value_desc) { + if(!extend_start&&get_auto_link_flag()&&start_duck&&start_duck_value_desc) switch(start_duck_value_desc.get_value_type()) { case synfig::ValueBase::TYPE_BLINEPOINT: start_duck_value_desc=synfigapp::ValueDesc(LinkableValueNode::Handle::cast_dynamic(start_duck_value_desc.get_value_node()),0); // fall through case synfig::ValueBase::TYPE_VECTOR: + if (shift_offset && shift_offset_vector != start_duck->get_origin()) + break; + shift_offset = true; + shift_offset_vector = start_duck->get_origin(); get_canvas_interface()->auto_export(start_duck_value_desc); if (extend_finish) if(start_duck_value_node_bline&&start_duck_value_node_bline==finish_duck_value_node_bline) @@ -778,22 +843,24 @@ StateDraw_Context::new_bline(std::list bline,bool loop_bline else extend_finish_join_different=true; else - LinkableValueNode::Handle::cast_dynamic(value_node->list.front().value_node)-> - set_link(0,start_duck_value_desc.get_value_node()); + join_start_no_extend=true; // fall through default:break; } - } // if the new line's end didn't extend an existing line, // check whether it needs to be linked to an existing duck - if(!extend_finish&&finish_duck&&finish_duck_value_desc) + if(!extend_finish&&get_auto_link_flag()&&finish_duck&&finish_duck_value_desc) switch(finish_duck_value_desc.get_value_type()) { case synfig::ValueBase::TYPE_BLINEPOINT: finish_duck_value_desc=synfigapp::ValueDesc(LinkableValueNode::Handle::cast_dynamic(finish_duck_value_desc.get_value_node()),0); // fall through case synfig::ValueBase::TYPE_VECTOR: + if (shift_offset && shift_offset_vector != finish_duck->get_origin()) + break; + shift_offset = true; + shift_offset_vector = finish_duck->get_origin(); get_canvas_interface()->auto_export(finish_duck_value_desc); if(extend_start) if(finish_duck_value_node_bline&&start_duck_value_node_bline==finish_duck_value_node_bline) @@ -801,71 +868,123 @@ StateDraw_Context::new_bline(std::list bline,bool loop_bline else extend_start_join_different=true; else - LinkableValueNode::Handle::cast_dynamic(value_node->list.back().value_node)-> - set_link(0,finish_duck_value_desc.get_value_node()); + join_finish_no_extend=true; // fall through default:break; } + } - Smach::event_result result; - synfig::ValueNode_DynamicList::ListEntry source; - int target_index; + ValueNode_BLine::Handle value_node; + std::list trans_bline; + + { + std::list::iterator iter; + const synfig::TransformStack& transform(get_canvas_view()->get_curr_transform_stack()); - // the new line's start extends an existing line - if(extend_start) + for(iter=bline.begin();iter!=bline.end();++iter) { - if(complete_loop)bline.pop_back(); - bline.pop_front(); - if(start_duck_index==0) - { // We need to reverse the BLine first. - reverse_bline(bline); - result=extend_bline_from_begin(start_duck_value_node_bline,bline,complete_loop); - source=start_duck_value_node_bline->list.front(); - target_index=bline.size()+finish_duck_index; - } - else - { - result=extend_bline_from_end(start_duck_value_node_bline,bline,complete_loop); - source=start_duck_value_node_bline->list.back(); - target_index=finish_duck_index; - } + BLinePoint bline_point(*iter); + Point new_vertex(transform.unperform(bline_point.get_vertex())); + + bline_point.set_tangent1( + transform.unperform( + bline_point.get_tangent1()+bline_point.get_vertex() + ) -new_vertex + ); + + bline_point.set_tangent2( + transform.unperform( + bline_point.get_tangent2()+bline_point.get_vertex() + ) -new_vertex + ); + + if (shift_offset) + new_vertex=new_vertex-shift_offset_vector; + + bline_point.set_vertex(new_vertex); - if(extend_start_join_different) - LinkableValueNode::Handle::cast_dynamic(source.value_node)-> - set_link(0,finish_duck_value_desc.get_value_node()); - else if(extend_start_join_same) - LinkableValueNode::Handle::cast_dynamic(source.value_node)-> - set_link(0,synfigapp::ValueDesc(LinkableValueNode::Handle::cast_dynamic(start_duck_value_node_bline-> - list[target_index].value_node),0).get_value_node()); - return result; + trans_bline.push_back(bline_point); } + value_node=ValueNode_BLine::create(synfig::ValueBase(trans_bline,loop_bline_flag)); + } - // the new line's end extends an existing line - if(extend_finish) - { // SPECIAL CASE -- EXTENSION - bline.pop_back(); - if(finish_duck_index==0) - { - result=extend_bline_from_begin(finish_duck_value_node_bline,bline,false); - source=finish_duck_value_node_bline->list.front(); - target_index=bline.size()+start_duck_index; - } - else - { // We need to reverse the BLine first. - reverse_bline(bline); - result=extend_bline_from_end(finish_duck_value_node_bline,bline,false); - source=finish_duck_value_node_bline->list.back(); - target_index=start_duck_index; - } + Smach::event_result result; + synfig::ValueNode_DynamicList::ListEntry source; - if(extend_finish_join_different) - LinkableValueNode::Handle::cast_dynamic(source.value_node)-> - set_link(0,start_duck_value_desc.get_value_node()); - else if(extend_finish_join_same) - LinkableValueNode::Handle::cast_dynamic(source.value_node)-> - set_link(0,synfigapp::ValueDesc(LinkableValueNode::Handle::cast_dynamic(finish_duck_value_node_bline-> - list[target_index].value_node),0).get_value_node()); - return result; + // the new line's start extends an existing line + if(extend_start) + { + int target_offset = 0; + if(complete_loop)trans_bline.pop_back(); + trans_bline.pop_front(); + if(start_duck_index==0) + { // We need to reverse the BLine first. + reverse_bline(trans_bline); + result=extend_bline_from_begin(start_duck_value_node_bline,trans_bline,complete_loop); + source=start_duck_value_node_bline->list.front(); + target_offset=trans_bline.size(); + } + else + { + result=extend_bline_from_end(start_duck_value_node_bline,trans_bline,complete_loop); + source=start_duck_value_node_bline->list.back(); + } + + if(extend_start_join_different) + LinkableValueNode::Handle::cast_dynamic(source.value_node)-> + set_link(0,finish_duck_value_desc.get_value_node()); + else if(extend_start_join_same) + LinkableValueNode::Handle::cast_dynamic(source.value_node)-> + set_link(0,synfigapp::ValueDesc(LinkableValueNode::Handle::cast_dynamic(start_duck_value_node_bline-> + list[target_offset+finish_duck_index].value_node),0).get_value_node()); + return result; + } + + // the new line's end extends an existing line + if(extend_finish) + { + int target_offset = 0; + trans_bline.pop_back(); + if(finish_duck_index==0) + { + result=extend_bline_from_begin(finish_duck_value_node_bline,trans_bline,false); + source=finish_duck_value_node_bline->list.front(); + target_offset=trans_bline.size(); + } + else + { // We need to reverse the BLine first. + reverse_bline(trans_bline); + result=extend_bline_from_end(finish_duck_value_node_bline,trans_bline,false); + source=finish_duck_value_node_bline->list.back(); + } + + if(extend_finish_join_different) + LinkableValueNode::Handle::cast_dynamic(source.value_node)-> + set_link(0,start_duck_value_desc.get_value_node()); + else if(extend_finish_join_same) + LinkableValueNode::Handle::cast_dynamic(source.value_node)-> + set_link(0,synfigapp::ValueDesc(LinkableValueNode::Handle::cast_dynamic(finish_duck_value_node_bline-> + list[target_offset+start_duck_index].value_node),0).get_value_node()); + return result; + } + + if (join_start_no_extend) + LinkableValueNode::Handle::cast_dynamic(value_node->list.front().value_node)-> + set_link(0,start_duck_value_desc.get_value_node()); + + if (join_finish_no_extend) + LinkableValueNode::Handle::cast_dynamic(value_node->list.back().value_node)-> + set_link(0,finish_duck_value_desc.get_value_node()); + + if(get_auto_export_flag()) { + printf("this is where we would export the new line\n"); + if (!get_canvas_interface()->add_value_node(value_node,get_id())) + { + /* it's no big deal, is it? let's keep the shape anyway */ + // get_canvas_view()->get_ui_interface()->error(_("Unable to add value node")); + // group.cancel(); + // increment_id(); + // return Smach::RESULT_ERROR; } } @@ -888,9 +1007,15 @@ StateDraw_Context::new_bline(std::list bline,bool loop_bline synfigapp::PushMode push_mode(get_canvas_interface(),synfigapp::MODE_NORMAL); if(get_region_only_flag()) + { layer=get_canvas_interface()->add_layer_to("region",canvas,depth); + layer->set_description(get_id()+_(" Region")); + } else + { layer=get_canvas_interface()->add_layer_to("outline",canvas,depth); + layer->set_description(get_id()+_(" Outline")); + } if(get_feather()) { @@ -901,7 +1026,9 @@ StateDraw_Context::new_bline(std::list bline,bool loop_bline //layer->set_description(strprintf("Stroke %d",number)); //get_canvas_interface()->signal_layer_new_description()(layer,layer->get_description()); - + if (shift_offset) + get_canvas_interface()-> + change_value(synfigapp::ValueDesc(layer,"offset"),shift_offset_vector); synfigapp::Action::Handle action(synfigapp::Action::create("layer_param_connect")); @@ -919,6 +1046,7 @@ StateDraw_Context::new_bline(std::list bline,bool loop_bline { get_canvas_view()->get_ui_interface()->error(_("Unable to create layer")); group.cancel(); + increment_id(); //refresh_ducks(); return Smach::RESULT_ERROR; } @@ -926,6 +1054,7 @@ StateDraw_Context::new_bline(std::list bline,bool loop_bline //refresh_ducks(); } + increment_id(); last_stroke=value_node; return Smach::RESULT_ACCEPT; } @@ -1284,10 +1413,8 @@ StateDraw_Context::extend_bline_from_begin(ValueNode_BLine::Handle value_node,st } std::list::reverse_iterator iter; - iter=bline.rbegin(); - for(;!(iter==bline.rend());++iter) + for(iter=bline.rbegin();!(iter==bline.rend());++iter) { - //iter->reverse(); ValueNode_Composite::Handle composite(ValueNode_Composite::create(*iter)); synfigapp::Action::Handle action(synfigapp::Action::create("value_node_dynamic_list_insert")); @@ -1337,8 +1464,7 @@ StateDraw_Context::extend_bline_from_end(ValueNode_BLine::Handle value_node,std: } std::list::iterator iter; - iter=bline.begin(); - for(;iter!=bline.end();++iter) + for(iter=bline.begin();iter!=bline.end();++iter) { ValueNode_Composite::Handle composite(ValueNode_Composite::create(*iter));