X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-studio%2Ftrunk%2Fsrc%2Fgtkmm%2Fcanvasview.cpp;h=7ffc505fb96f00fd01242876063d9df60427fd19;hb=c50f074b4b3c7b65519f85392e522fb0821b3cea;hp=76437b9b1bf0f51e13adf6298b67ff3fb43075e4;hpb=70eafd12bd61c47015b2ee21d87e93e5a38eb61e;p=synfig.git diff --git a/synfig-studio/trunk/src/gtkmm/canvasview.cpp b/synfig-studio/trunk/src/gtkmm/canvasview.cpp index 76437b9..7ffc505 100644 --- a/synfig-studio/trunk/src/gtkmm/canvasview.cpp +++ b/synfig-studio/trunk/src/gtkmm/canvasview.cpp @@ -7,6 +7,7 @@ ** \legal ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley ** Copyright (c) 2007, 2008 Chris Moore +** Copyright (c) 2009 Carlos López ** ** This package is free software; you can redistribute it and/or ** modify it under the terms of the GNU General Public License as @@ -41,6 +42,7 @@ #include #include #include +#include #include #include @@ -682,9 +684,13 @@ CanvasView::CanvasView(etl::loose_handle instance,etl::handle instance,etl::handle instance,etl::handleattach(*vpaned, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); layout_table->attach(*create_work_area(), 0, 1, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); + layout_table->attach(*create_display_bar(), 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0); init_menus(); //layout_table->attach(*App::ui_manager()->get_widget("/menu-main"), 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0); @@ -954,6 +967,10 @@ CanvasView::create_time_bar() timeslider->set_time_adjustment(&time_adjustment()); timeslider->set_bounds_adjustment(&time_window_adjustment()); //layout_table->attach(*timeslider, 0, 1, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL); + //Setup the keyframe list widget + widget_kf_list->set_time_adjustment(&time_adjustment()); + widget_kf_list->set_canvas_interface(canvas_interface()); + widget_kf_list->show(); tooltips.set_tip(*time_window_scroll,_("Moves the time window")); tooltips.set_tip(*timeslider,_("Changes the current time")); @@ -1021,23 +1038,31 @@ CanvasView::create_time_bar() keyframedial->show(); keyframebutton=keyframedial->get_lock_button(); - Gtk::Table *table = manage(new class Gtk::Table(5, 3, false)); - timebar = table; + timebar = Gtk::manage(new class Gtk::Table(5, 4, false)); + + //Adjust both widgets to be the same as the + int header_height = 0; + if(getenv("SYNFIG_TIMETRACK_HEADER_HEIGHT")) + header_height = atoi(getenv("SYNFIG_TIMETRACK_HEADER_HEIGHT")); + if (header_height < 3) + header_height = 24; + timeslider->set_size_request(-1,header_height-header_height/3+1); + widget_kf_list->set_size_request(-1,header_height/3+1); + + //Attach widgets to the timebar + //timebar->attach(*manage(disp_audio), 1, 5, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK); + timebar->attach(*current_time_widget, 0, 1, 0, 2, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0); + timebar->attach(*framedial, 0, 1, 2, 3, Gtk::SHRINK, Gtk::SHRINK); + timebar->attach(*timeslider, 1, 3, 1, 2, Gtk::FILL|Gtk::SHRINK, Gtk::FILL|Gtk::SHRINK); + timebar->attach(*widget_kf_list, 1, 3, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::SHRINK); + timebar->attach(*time_window_scroll, 1, 3, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK); + timebar->attach(*keyframedial, 3, 4, 0, 2, Gtk::SHRINK, Gtk::SHRINK); + timebar->attach(*animatebutton, 4, 5, 0, 2, Gtk::SHRINK, Gtk::SHRINK); + //timebar->attach(*keyframebutton, 1, 2, 3, 4, Gtk::SHRINK, Gtk::SHRINK); - //Attach widgets to the time bar table - table->attach(*manage(disp_audio), 1, 5, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK); - table->attach(*framedial, 0, 1, 2, 3,Gtk::SHRINK, Gtk::SHRINK); - table->attach(*current_time_widget, 0, 1, 1, 2, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0); - table->attach(*timeslider, 1, 3, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK); - table->attach(*time_window_scroll, 1, 3, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK); - table->attach(*keyframedial, 3, 4, 1, 2, Gtk::SHRINK, Gtk::SHRINK); - table->attach(*animatebutton, 4, 5, 1, 2, Gtk::SHRINK, Gtk::SHRINK); - //table->attach(*keyframebutton, 1, 2, 3, 4, Gtk::SHRINK, Gtk::SHRINK); - - - table->show(); + timebar->show(); - return table; + return timebar; } Gtk::Widget * @@ -1095,6 +1120,133 @@ CanvasView::create_status_bar() return statusbartable; } +Gtk::Widget* +CanvasView::create_display_bar() +{ + displaybar = manage(new class Gtk::Table(1, 7, false)); + + // Setup the ToggleDuckDial widget + toggleducksdial = Gtk::manage(new class ToggleDucksDial()); + + Duck::Type m = work_area->get_type_mask(); + toggleducksdial->update_toggles(m); + + toggleducksdial->signal_ducks_position().connect( + sigc::bind(sigc::mem_fun(*this, &studio::CanvasView::toggle_duck_mask),Duck::TYPE_POSITION) + ); + toggleducksdial->signal_ducks_vertex().connect( + sigc::bind(sigc::mem_fun(*this, &studio::CanvasView::toggle_duck_mask),Duck::TYPE_VERTEX) + ); + toggleducksdial->signal_ducks_tangent().connect( + sigc::bind(sigc::mem_fun(*this, &studio::CanvasView::toggle_duck_mask),Duck::TYPE_TANGENT) + ); + toggleducksdial->signal_ducks_radius().connect( + sigc::bind(sigc::mem_fun(*this, &studio::CanvasView::toggle_duck_mask),Duck::TYPE_RADIUS) + ); + toggleducksdial->signal_ducks_width().connect( + sigc::bind(sigc::mem_fun(*this, &studio::CanvasView::toggle_duck_mask),Duck::TYPE_WIDTH) + ); + toggleducksdial->signal_ducks_angle().connect( + sigc::bind(sigc::mem_fun(*this, &studio::CanvasView::toggle_duck_mask),Duck::TYPE_ANGLE) + ); + toggleducksdial->show(); + + // Set up the ResolutionDial widget + resolutiondial=Gtk::manage(new class ResolutionDial()); + + resolutiondial->update_lowres(work_area->get_low_resolution_flag()); + resolutiondial->signal_increase_resolution().connect( + sigc::mem_fun(*this, &studio::CanvasView::decrease_low_res_pixel_size)); + resolutiondial->signal_decrease_resolution().connect( + sigc::mem_fun(*this, &studio::CanvasView::increase_low_res_pixel_size)); + resolutiondial->signal_use_low_resolution().connect( + sigc::mem_fun(*this, &studio::CanvasView::toggle_low_res_pixel_flag)); + resolutiondial->show(); + + // Set up a separator + Gtk::VSeparator *separator1 = Gtk::manage(new class Gtk::VSeparator()); + separator1->show(); + Gtk::VSeparator *separator2 = Gtk::manage(new class Gtk::VSeparator()); + separator2->show(); + + // Set up quality spin button + quality_spin=Gtk::manage(new class Gtk::SpinButton(quality_adjustment_)); + quality_spin->signal_value_changed().connect( + sigc::mem_fun(*this, &studio::CanvasView::update_quality)); + tooltips.set_tip(*quality_spin, _("Quality (lower is better)")); + quality_spin->show(); + + // Set up the show grid toggle button + show_grid = Gtk::manage(new class Gtk::ToggleButton()); + show_grid->set_active(work_area->grid_status()); + Gtk::Image *icon = manage(new Gtk::Image(Gtk::StockID("synfig-toggle_show_grid"), Gtk::IconSize::from_name("synfig-small_icon"))); + icon->set_padding(0, 0); + icon->show(); + show_grid->add(*icon); + show_grid->signal_toggled().connect( + sigc::mem_fun(*this, &studio::CanvasView::toggle_show_grid)); + tooltips.set_tip(*show_grid, _("Show grid when enabled")); + show_grid->set_relief(Gtk::RELIEF_NONE); + show_grid->show(); + + // Set up the snap to grid toggle button + snap_grid = Gtk::manage(new class Gtk::ToggleButton()); + snap_grid->set_active(work_area->grid_status()); + Gtk::Image *icon2 = manage(new Gtk::Image(Gtk::StockID("synfig-toggle_snap_grid"), Gtk::IconSize::from_name("synfig-small_icon"))); + icon2->set_padding(0, 0); + icon2->show(); + snap_grid->add(*icon2); + snap_grid->signal_toggled().connect( + sigc::mem_fun(*this, &studio::CanvasView::toggle_snap_grid)); + tooltips.set_tip(*snap_grid, _("Snap grid when enabled")); + snap_grid->set_relief(Gtk::RELIEF_NONE); + snap_grid->show(); + + // Set up the onion skin toggle button + onion_skin = Gtk::manage(new class Gtk::ToggleButton()); + onion_skin->set_active(work_area->get_onion_skin()); + Gtk::Image *icon3 = manage(new Gtk::Image(Gtk::StockID("synfig-toggle_onion_skin"), Gtk::IconSize::from_name("synfig-small_icon"))); + icon3->set_padding(0, 0); + icon3->show(); + onion_skin->add(*icon3); + onion_skin->signal_toggled().connect( + sigc::mem_fun(*this, &studio::CanvasView::toggle_onion_skin)); + tooltips.set_tip(*onion_skin, _("Shows onion skin when enabled")); + onion_skin->set_relief(Gtk::RELIEF_NONE); + onion_skin->show(); + + // Set up past onion skin spin button + past_onion_spin=Gtk::manage(new class Gtk::SpinButton(past_onion_adjustment_)); + past_onion_spin->signal_value_changed().connect( + sigc::mem_fun(*this, &studio::CanvasView::set_onion_skins)); + tooltips.set_tip(*past_onion_spin, _("Past onion skins")); + past_onion_spin->show(); + + // Set up future onion skin spin button + future_onion_spin=Gtk::manage(new class Gtk::SpinButton(future_onion_adjustment_)); + future_onion_spin->signal_value_changed().connect( + sigc::mem_fun(*this, &studio::CanvasView::set_onion_skins)); + tooltips.set_tip(*future_onion_spin, _("Future onion skins")); + future_onion_spin->show(); + + + displaybar->attach(*toggleducksdial, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK); + displaybar->attach(*separator1, 1, 2, 0, 1, Gtk::FILL, Gtk::FILL); + displaybar->attach(*resolutiondial, 2, 3, 0, 1, Gtk::SHRINK, Gtk::SHRINK); + displaybar->attach(*separator2, 3, 4, 0, 1, Gtk::FILL, Gtk::FILL); + displaybar->attach(*quality_spin, 4, 5, 0, 1, Gtk::SHRINK, Gtk::SHRINK); + displaybar->attach(*show_grid, 5, 6, 0, 1, Gtk::SHRINK, Gtk::SHRINK); + displaybar->attach(*snap_grid, 6, 7, 0, 1, Gtk::SHRINK, Gtk::SHRINK); + displaybar->attach(*past_onion_spin, 7, 8, 0, 1, Gtk::SHRINK, Gtk::SHRINK); + displaybar->attach(*onion_skin, 8, 9, 0, 1, Gtk::SHRINK, Gtk::SHRINK); + displaybar->attach(*future_onion_spin, 9, 10, 0, 1, Gtk::SHRINK, Gtk::SHRINK); + + displaybar->show(); + + return displaybar; + +} + void CanvasView::on_current_time_widget_changed() { @@ -1352,7 +1504,7 @@ CanvasView::init_menus() } action_group->add( action, sigc::bind( - sigc::mem_fun(*work_area, &studio::WorkArea::set_quality), + sigc::mem_fun(*this, &studio::CanvasView::set_quality), i ) ); @@ -1394,7 +1546,7 @@ CanvasView::init_menus() sigc::mem_fun(*this, &studio::CanvasView::play) ); - action_group->add( Gtk::Action::create("dialog-flipbook", _("Flipbook Dialog")), + action_group->add( Gtk::Action::create("dialog-flipbook", _("Preview Window")), sigc::mem_fun0(*preview_dialog, &studio::Dialog_Preview::present) ); @@ -1403,11 +1555,11 @@ CanvasView::init_menus() grid_show_toggle = Gtk::ToggleAction::create("toggle-grid-show", _("Show Grid")); grid_show_toggle->set_active(work_area->grid_status()); - action_group->add(grid_show_toggle, sigc::mem_fun(*work_area, &studio::WorkArea::toggle_grid)); + action_group->add(grid_show_toggle, sigc::mem_fun(*this, &studio::CanvasView::toggle_show_grid)); grid_snap_toggle = Gtk::ToggleAction::create("toggle-grid-snap", _("Snap to Grid")); grid_snap_toggle->set_active(work_area->get_grid_snap()); - action_group->add(grid_snap_toggle, sigc::mem_fun(*work_area, &studio::WorkArea::toggle_grid_snap)); + action_group->add(grid_snap_toggle, sigc::mem_fun(*this, &studio::CanvasView::toggle_snap_grid)); action = Gtk::ToggleAction::create("toggle-guide-show", _("Show Guides")); action->set_active(work_area->get_show_guides()); @@ -1415,11 +1567,11 @@ CanvasView::init_menus() action = Gtk::ToggleAction::create("toggle-low-res", _("Use Low-Res")); action->set_active(work_area->get_low_resolution_flag()); - action_group->add(action, sigc::mem_fun(*work_area, &studio::WorkArea::toggle_low_resolution_flag)); + action_group->add(action, sigc::mem_fun(*this, &studio::CanvasView::toggle_low_res_pixel_flag)); action = Gtk::ToggleAction::create("toggle-onion-skin", _("Show Onion Skin")); action->set_active(work_area->get_onion_skin()); - action_group->add(action, sigc::mem_fun(*work_area, &studio::WorkArea::toggle_onion_skin)); + action_group->add(action, sigc::mem_fun(*this, &studio::CanvasView::toggle_onion_skin)); } action_group->add( Gtk::Action::create("canvas-zoom-fit", Gtk::StockID("gtk-zoom-fit")), @@ -2580,10 +2732,11 @@ void CanvasView::on_mode_changed(synfigapp::CanvasInterface::Mode mode) { // If the animate flag was set in mode... + Gtk::IconSize iconsize=Gtk::IconSize::from_name("synfig-small_icon"); if(mode&synfigapp::MODE_ANIMATE) { Gtk::Image *icon; - icon=manage(new Gtk::Image(Gtk::StockID("gtk-no"),Gtk::ICON_SIZE_BUTTON)); + icon=manage(new Gtk::Image(Gtk::StockID("gtk-no"),iconsize)); animatebutton->remove(); animatebutton->add(*icon); tooltips.set_tip(*animatebutton,_("In Animate Editing Mode")); @@ -2593,7 +2746,7 @@ CanvasView::on_mode_changed(synfigapp::CanvasInterface::Mode mode) else { Gtk::Image *icon; - icon=manage(new Gtk::Image(Gtk::StockID("gtk-yes"),Gtk::ICON_SIZE_BUTTON)); + icon=manage(new Gtk::Image(Gtk::StockID("gtk-yes"),iconsize)); animatebutton->remove(); animatebutton->add(*icon); tooltips.set_tip(*animatebutton,_("Not in Animate Editing Mode")); @@ -2749,6 +2902,18 @@ CanvasView::on_duck_changed(const synfig::Point &value,const synfigapp::ValueDes } } + if (ValueNode_Scale::Handle scale_value_node = ValueNode_Scale::Handle::cast_dynamic(value_desc.get_value_node())) + { + int link_index(scale_value_node->get_link_index_from_name("link")); + if(scale_value_node->is_invertible(get_time())) + return canvas_interface()->change_value( + synfigapp::ValueDesc(scale_value_node,link_index), + scale_value_node->get_inverse(get_time(), value) + ); + else + return false; + } + switch(value_desc.get_value_type()) { case ValueBase::TYPE_REAL: @@ -2770,6 +2935,18 @@ CanvasView::on_duck_angle_changed(const synfig::Angle &rotation,const synfigapp: return canvas_interface()->change_value(synfigapp::ValueDesc(bline_tangent,offset_index), old_offset + rotation); } + if (ValueNode_Scale::Handle scale_value_node = ValueNode_Scale::Handle::cast_dynamic(value_desc.get_value_node())) + { + int link_index(scale_value_node->get_link_index_from_name("link")); + if(scale_value_node->is_invertible(get_time())) + return canvas_interface()->change_value( + synfigapp::ValueDesc(scale_value_node,link_index), + scale_value_node->get_inverse(get_time(), rotation) + ); + else + return false; + + } // \todo will this really always be the case? assert(value_desc.get_value_type() == ValueBase::TYPE_ANGLE); return canvas_interface()->change_value(value_desc, value_desc.get_value(get_time()).get(Angle()) + rotation); @@ -3028,9 +3205,11 @@ CanvasView::rebuild_ducks() void CanvasView::decrease_low_res_pixel_size() { + if(changing_resolution_) + return; + changing_resolution_=true; list sizes = CanvasView::get_pixel_sizes(); int pixel_size = work_area->get_low_res_pixel_size(); - for (list::iterator iter = sizes.begin(); iter != sizes.end(); iter++) if (*iter == pixel_size) { @@ -3046,17 +3225,32 @@ CanvasView::decrease_low_res_pixel_size() } break; } + // Update the "toggle-low-res" action + Glib::RefPtr action = Glib::RefPtr::cast_dynamic(action_group->get_action("toggle-low-res")); + action->set_active(work_area->get_low_resolution_flag()); + // Update toggle low res button + resolutiondial->update_lowres(work_area->get_low_resolution_flag()); + changing_resolution_=false; } void CanvasView::increase_low_res_pixel_size() { + if(changing_resolution_) + return; + changing_resolution_=true; list sizes = CanvasView::get_pixel_sizes(); int pixel_size = work_area->get_low_res_pixel_size(); - if (!work_area->get_low_resolution_flag()) { + // We were using "hi res" so change it to low res. work_area->set_low_resolution_flag(true); + // Update the "toggle-low-res" action + Glib::RefPtr action = Glib::RefPtr::cast_dynamic(action_group->get_action("toggle-low-res")); + action->set_active(true); + // Update the toggle low res button + resolutiondial->update_lowres(true); + changing_resolution_=false; return; } @@ -3072,6 +3266,109 @@ CanvasView::increase_low_res_pixel_size() } break; } + // Update the "toggle-low-res" action + Glib::RefPtr action = Glib::RefPtr::cast_dynamic(action_group->get_action("toggle-low-res")); + action->set_active(work_area->get_low_resolution_flag()); + // Update toggle low res button + resolutiondial->update_lowres(work_area->get_low_resolution_flag()); + changing_resolution_=false; +} + +void +CanvasView::toggle_low_res_pixel_flag() +{ + if(changing_resolution_) + return; + changing_resolution_=true; + work_area->toggle_low_resolution_flag(); + // Update the toggle low res button + resolutiondial->update_lowres(work_area->get_low_resolution_flag()); + // Update the "toggle-low-res" action + Glib::RefPtr action = Glib::RefPtr::cast_dynamic(action_group->get_action("toggle-low-res")); + action->set_active(work_area->get_low_resolution_flag()); + changing_resolution_=false; +} + +void +CanvasView::update_quality() +{ + //if(working_depth) + // return; + if(updating_quality_) + return; + updating_quality_=true; + work_area->set_quality((int) quality_spin->get_value()); + // Update Quality Radio actions + Glib::RefPtr action=Glib::RefPtr::cast_dynamic( + action_group->get_action(strprintf("quality-%02d",(int) quality_spin->get_value())) + ); + action->set_active(); + + updating_quality_=false; +} + +void +CanvasView::set_quality(int x) +{ + if(updating_quality_) + return; + work_area->set_quality(x); + // Update the quality spin button + quality_spin->set_value(x); +} + +void +CanvasView::set_onion_skins() +{ + if(toggling_onion_skin) + return; + int onion_skins[2]; + onion_skins[0]=past_onion_spin->get_value(); + onion_skins[1]=future_onion_spin->get_value(); + work_area->set_onion_skins(onion_skins); +} + +void +CanvasView::toggle_show_grid() +{ + if(toggling_show_grid) + return; + toggling_show_grid=true; + work_area->toggle_grid(); + // Update the toggle grid show action + set_grid_show_toggle(work_area->grid_status()); + // Update the toggle grid show check button + show_grid->set_active(work_area->grid_status()); + toggling_show_grid=false; +} + +void +CanvasView::toggle_snap_grid() +{ + if(toggling_snap_grid) + return; + toggling_snap_grid=true; + work_area->toggle_grid_snap(); + // Update the toggle grid snap action + set_grid_snap_toggle(work_area->get_grid_snap()); + // Update the toggle grid snap check button + snap_grid->set_active(work_area->get_grid_snap()); + toggling_snap_grid=false; +} + +void +CanvasView::toggle_onion_skin() +{ + if(toggling_onion_skin) + return; + toggling_onion_skin=true; + work_area->toggle_onion_skin(); + // Update the toggle onion skin action + Glib::RefPtr action = Glib::RefPtr::cast_dynamic(action_group->get_action("toggle-onion-skin")); + action->set_active(work_area->get_onion_skin()); + // Update the toggle grid snap check button + onion_skin->set_active(work_area->get_onion_skin()); + toggling_onion_skin=false; } void @@ -3633,6 +3930,9 @@ CanvasView::on_keyframe_remove_pressed() void CanvasView::toggle_duck_mask(Duckmatic::Type type) { + if(toggling_ducks_) + return; + toggling_ducks_=true; bool is_currently_on(work_area->get_type_mask()&type); if(is_currently_on) @@ -3641,6 +3941,30 @@ CanvasView::toggle_duck_mask(Duckmatic::Type type) work_area->set_type_mask(work_area->get_type_mask()|type); work_area->queue_draw(); + try + { + // Update the toggle ducks actions + Glib::RefPtr action; + action = Glib::RefPtr::cast_dynamic(action_group->get_action("mask-position-ducks")); + action->set_active((bool)(work_area->get_type_mask()&Duck::TYPE_POSITION)); + action = Glib::RefPtr::cast_dynamic(action_group->get_action("mask-tangent-ducks")); + action->set_active((bool)(work_area->get_type_mask()&Duck::TYPE_TANGENT)); + action = Glib::RefPtr::cast_dynamic(action_group->get_action("mask-vertex-ducks")); + action->set_active((bool)(work_area->get_type_mask()&Duck::TYPE_VERTEX)); + action = Glib::RefPtr::cast_dynamic(action_group->get_action("mask-radius-ducks")); + action->set_active((bool)(work_area->get_type_mask()&Duck::TYPE_RADIUS)); + action = Glib::RefPtr::cast_dynamic(action_group->get_action("mask-width-ducks")); + action->set_active((bool)(work_area->get_type_mask()&Duck::TYPE_WIDTH)); + action = Glib::RefPtr::cast_dynamic(action_group->get_action("mask-angle-ducks")); + action->set_active((bool)(work_area->get_type_mask()&Duck::TYPE_ANGLE)); + // Update toggle ducks buttons + toggleducksdial->update_toggles(work_area->get_type_mask()); + } + catch(...) + { + toggling_ducks_=false; + } + toggling_ducks_=false; } void