** \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
time_adjustment_ (0,0,25,0,0,0),
time_window_adjustment_ (0,0,25,0,0,0),
quality_adjustment_ (8,1,10,1,1,0),
+ future_onion_adjustment_ (0,0,2,1,1,0),
+ past_onion_adjustment_ (0,0,2,1,1,0),
statusbar (manage(new class Gtk::Statusbar())),
timeslider (new Widget_Timeslider),
+ widget_kf_list (new Widget_Keyframe_List),
ui_interface_ (new CanvasViewUIInterface(this)),
selection_manager_ (new CanvasViewSelectionManager(this)),
toggling_ducks_=false;
changing_resolution_=false;
updating_quality_=false;
+ toggling_show_grid=false;
+ toggling_snap_grid=false;
+ toggling_onion_skin=false;
smach_.set_default_state(&state_normal);
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"));
keyframedial->show();
keyframebutton=keyframedial->get_lock_button();
- timebar = manage(new class Gtk::Table(5, 4, false));
+ 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(*framedial, 0, 1, 2, 3,Gtk::SHRINK, Gtk::SHRINK);
- timebar->attach(*current_time_widget, 0, 1, 1, 2, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
- timebar->attach(*timeslider, 1, 3, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK);
+ //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, 1, 2, Gtk::SHRINK, Gtk::SHRINK);
- timebar->attach(*animatebutton, 4, 5, 1, 2, Gtk::SHRINK, 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);
timebar->show();
Gtk::Widget*
CanvasView::create_display_bar()
{
- displaybar = manage(new class Gtk::Table(1, 5, false));
-
+ displaybar = manage(new class Gtk::Table(10, 1, false));
+ Gtk::IconSize iconsize=Gtk::IconSize::from_name("synfig-small_icon_16x16");
// Setup the ToggleDuckDial widget
- toggleducksdial = Gtk::manage(new class ToggleDucksDial());
+ toggleducksdial = Gtk::manage(new class ToggleDucksDial(iconsize));
Duck::Type m = work_area->get_type_mask();
toggleducksdial->update_toggles(m);
toggleducksdial->show();
// Set up the ResolutionDial widget
- resolutiondial=Gtk::manage(new class ResolutionDial());
+ resolutiondial=Gtk::manage(new class ResolutionDial(iconsize));
resolutiondial->update_lowres(work_area->get_low_resolution_flag());
resolutiondial->signal_increase_resolution().connect(
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"), iconsize));
+ 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"), iconsize));
+ 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"), iconsize));
+ 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();
}
action_group->add( action,
sigc::bind(
- sigc::mem_fun(*work_area, &studio::WorkArea::set_quality),
+ sigc::mem_fun(*this, &studio::CanvasView::set_quality),
i
)
);
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)
);
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());
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")),
}
}
+ 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:
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);
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<Gtk::RadioAction> action=Glib::RefPtr<Gtk::RadioAction>::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<Gtk::ToggleAction> action = Glib::RefPtr<Gtk::ToggleAction>::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
CanvasView::on_dirty_preview()
{
if(!is_playing_)