Reformatted a little.
[synfig.git] / synfig-studio / trunk / src / gtkmm / canvasview.cpp
index d439d9e..8ba09bc 100644 (file)
@@ -6,7 +6,7 @@
 **
 **     \legal
 **     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**     Copyright (c) 2007 Chris Moore
+**     Copyright (c) 2007, 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
@@ -155,7 +155,6 @@ using namespace sigc;
 
 /* === C L A S S E S ======================================================= */
 
-
 class studio::UniversalScrubber
 {
        CanvasView *canvas_view;
@@ -226,7 +225,6 @@ public:
        }
 };
 
-
 class studio::CanvasViewUIInterface : public synfigapp::UIInterface
 {
        CanvasView *view;
@@ -236,7 +234,6 @@ public:
        CanvasViewUIInterface(CanvasView *view):
                view(view)
        {
-
                view->statusbar->push(_("Idle"));
        }
 
@@ -385,13 +382,9 @@ class studio::CanvasViewSelectionManager : public synfigapp::SelectionManager
        CanvasView *view;
        CanvasView::LayerTreeModel layer_tree_model;
        CanvasView::ChildrenTreeModel children_tree_model;
-public:
-
-       CanvasViewSelectionManager(CanvasView *view): view(view)
-{
-
- }
 
+public:
+       CanvasViewSelectionManager(CanvasView *view): view(view) { }
 
 private:
        void _set_selected_layer(const synfig::Layer::Handle &layer)
@@ -484,8 +477,6 @@ public:
                view->layer_tree->clear_selected_layers();
        }
 
-
-
        //! Returns the number of value_nodes selected.
        virtual int get_selected_children_count()const
        {
@@ -566,8 +557,6 @@ public:
                return;
        }
 
-
-
        int get_selected_layer_parameter_count()const
        {
                return get_selected_layer_parameters().size();
@@ -623,7 +612,6 @@ public:
 
 }; // END of class SelectionManager
 
-
 CanvasView::IsWorking::IsWorking(CanvasView &canvas_view_):
        canvas_view_(canvas_view_)
 {
@@ -701,7 +689,6 @@ CanvasView::CanvasView(etl::loose_handle<Instance> instance,etl::handle<synfigap
        //vpaned->pack2(*notebook, Gtk::SHRINK);
        //vpaned->show_all();
 
-
        //notebook->show();
 
        //notebook->append_page(*create_layer_tree(),_("Layers"));
@@ -718,7 +705,6 @@ CanvasView::CanvasView(etl::loose_handle<Instance> instance,etl::handle<synfigap
        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);
 
-
        layout_table->attach(*create_time_bar(), 0, 1, 3, 4, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
        layout_table->attach(*create_status_bar(), 0, 1, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
 
@@ -750,7 +736,6 @@ CanvasView::CanvasView(etl::loose_handle<Instance> instance,etl::handle<synfigap
        time_window_adjustment().signal_value_changed().connect(sigc::mem_fun(*this,&studio::CanvasView::refresh_time_window));
        time_adjustment().signal_value_changed().connect(sigc::mem_fun(*this,&studio::CanvasView::time_was_changed));
 
-
        work_area->signal_layer_selected().connect(sigc::mem_fun(*this,&studio::CanvasView::workarea_layer_selected));
        work_area->signal_input_device_changed().connect(sigc::mem_fun(*this,&studio::CanvasView::on_input_device_changed));
 
@@ -773,7 +758,6 @@ CanvasView::CanvasView(etl::loose_handle<Instance> instance,etl::handle<synfigap
                )
        );
 
-
        //MUCH TIME STUFF TAKES PLACE IN HERE
        refresh_rend_desc();
        refresh_time_window();
@@ -808,9 +792,6 @@ CanvasView::CanvasView(etl::loose_handle<Instance> instance,etl::handle<synfigap
        set_default_size(w,h);
        property_window_position().set_value(Gtk::WIN_POS_NONE);
 
-
-
-
        std::list<Gtk::TargetEntry> listTargets;
        listTargets.push_back( Gtk::TargetEntry("STRING") );
        listTargets.push_back( Gtk::TargetEntry("text/plain") );
@@ -819,7 +800,6 @@ CanvasView::CanvasView(etl::loose_handle<Instance> instance,etl::handle<synfigap
        drag_dest_set(listTargets);
        signal_drag_data_received().connect( sigc::mem_fun(*this, &studio::CanvasView::on_drop_drag_data_received) );
 
-
        /*
        Time length(get_canvas()->rend_desc().get_time_end()-get_canvas()->rend_desc().get_time_start());
        if(length<10.0)
@@ -864,7 +844,6 @@ CanvasView::CanvasView(etl::loose_handle<Instance> instance,etl::handle<synfigap
        time_window_adjustment().set_value(get_canvas()->rend_desc().get_time_start());
        time_window_adjustment().value_changed();
 
-
        GRAB_HINT_DATA("canvas_view");
        /*
        {
@@ -916,8 +895,6 @@ CanvasView::~CanvasView()
                synfig::info("CanvasView::~CanvasView(): Deleted");
 }
 
-
-
 std::list<int>&
 CanvasView::get_pixel_sizes()
 {
@@ -942,7 +919,6 @@ CanvasView::create_time_bar()
        timeslider->set_bounds_adjustment(&time_window_adjustment());
        //layout_table->attach(*timeslider, 0, 1, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL);
 
-
        tooltips.set_tip(*time_window_scroll,_("Moves the time window"));
        tooltips.set_tip(*timeslider,_("Changes the current time"));
        time_window_scroll->show();
@@ -1000,7 +976,6 @@ CanvasView::create_work_area()
        return work_area.get();
 }
 
-
 Gtk::Widget*
 CanvasView::create_status_bar()
 {
@@ -1021,7 +996,6 @@ CanvasView::create_status_bar()
 //     statusbartable->attach(*lowerbutton, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
 //     statusbartable->attach(*raisebutton, 1, 2, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
 
-
        current_time_widget=manage(new Widget_Time);
        current_time_widget->set_value(get_time());
        current_time_widget->set_fps(get_canvas()->rend_desc().get_frame_rate());
@@ -1048,7 +1022,6 @@ CanvasView::create_status_bar()
        refreshbutton->signal_clicked().connect(SLOT_EVENT(EVENT_REFRESH));
        stopbutton->signal_clicked().connect(SLOT_EVENT(EVENT_STOP));
 
-
        statusbartable->show_all();
        return statusbartable;
 }
@@ -1057,6 +1030,13 @@ void
 CanvasView::on_current_time_widget_changed()
 {
        set_time(current_time_widget->get_value());
+
+       // show the value being used - it will have been rounded to nearest frame
+       // this was already being done elsewhere, but only if the time was really changed;
+       // if the current time was 6f and the user edited it to 6.1f, then the 6.1f would
+       // be left in the display without the following line to fix it
+       current_time_widget->set_value(get_time());
+       current_time_widget->set_position(-1); // leave the cursor at the end
 }
 
 //     Gtk::Widget*
@@ -1196,7 +1176,7 @@ CanvasView::init_menus()
                sigc::hide_return(sigc::ptr_fun(&studio::App::new_instance))
        );
        action_group->add( Gtk::Action::create("open", Gtk::Stock::OPEN),
-               sigc::hide_return(sigc::ptr_fun(&studio::App::dialog_open))
+               sigc::hide_return(sigc::mem_fun(*get_instance().get(), &studio::Instance::open))
        );
        action_group->add( Gtk::Action::create("save", Gtk::Stock::SAVE),
                hide_return(sigc::mem_fun(*get_instance().get(), &studio::Instance::save))
@@ -1411,7 +1391,6 @@ CanvasView::init_menus()
 
        }
 
-
 #define DUCK_MASK(lower,upper,string)  \
        duck_mask_##lower=Gtk::ToggleAction::create("mask-" #lower "-ducks", string); \
        duck_mask_##lower->set_active((bool)(work_area->get_type_mask()&Duck::TYPE_##upper)); \
@@ -1486,8 +1465,6 @@ CanvasView::init_menus()
        }
 */
 
-
-
 #if 0
 //
 //     //Test some key stuff
@@ -1773,7 +1750,6 @@ CanvasView::add_layer(synfig::String x)
                target_depth=canvas->get_depth(*layer_list.begin());
        }
 
-
        Layer::Handle layer(canvas_interface()->add_layer_to(x,canvas,target_depth));
        if(layer)
        {
@@ -1896,13 +1872,11 @@ CanvasView::workarea_layer_selected(synfig::Layer::Handle layer)
                get_selection_manager()->set_selected_layer(layer);
 }
 
-
 void
 CanvasView::refresh_rend_desc()
 {
        current_time_widget->set_fps(get_canvas()->rend_desc().get_frame_rate());
 
-
        //????
        //synfig::info("Canvasview: Refreshing render desc info");
        if(!get_time().is_equal(time_adjustment().get_value()))
@@ -2005,7 +1979,6 @@ CanvasView::refresh_rend_desc()
        work_area->queue_render_preview();
 }
 
-
 bool
 CanvasView::close_view()
 {
@@ -2083,7 +2056,6 @@ CanvasView::update_title()
        set_title(title);
 }
 
-
 void
 CanvasView::on_hide()
 {
@@ -2174,7 +2146,6 @@ CanvasView::on_layer_toggle(synfig::Layer::Handle layer)
        canvas_interface()->get_instance()->perform_action(action);
 }
 
-
 void
 CanvasView::popup_param_menu(synfigapp::ValueDesc value_desc, float location)
 {
@@ -2197,7 +2168,6 @@ CanvasView::on_layer_user_click(int button, Gtk::TreeRow /*row*/, LayerTree::Col
        {
        case 3:
                {
-
                        Gtk::MenuItem* menu = dynamic_cast<Gtk::MenuItem*>(App::ui_manager()->get_widget("/menu-main/menu-layer"));
                        if(menu && menu->get_submenu())
                        {
@@ -2206,7 +2176,6 @@ CanvasView::on_layer_user_click(int button, Gtk::TreeRow /*row*/, LayerTree::Col
                                menu->get_submenu()->popup(button,gtk_get_current_event_time());
                        }
 
-
                        #if 0
                        bool multiple_selected=true;
 
@@ -2319,8 +2288,6 @@ CanvasView::on_layer_user_click(int button, Gtk::TreeRow /*row*/, LayerTree::Col
        }
 }
 
-
-
 bool
 CanvasView::on_children_user_click(int button, Gtk::TreeRow row, ChildrenTree::ColumnID column_id)
 {
@@ -2379,7 +2346,6 @@ CanvasView::on_keyframe_tree_event(GdkEvent *event)
        return false;
 }
 
-
 void
 CanvasView::refresh_time_window()
 {
@@ -2414,7 +2380,6 @@ CanvasView::on_time_changed()
 
        if(get_time() != time_adjustment().get_value())
        {
-
                //Recenters the window, causing it to jump (possibly undesirably... but whatever)
                if(time < time_window_adjustment().get_value() ||
                        time > time_window_adjustment().get_value()+time_window_adjustment().get_page_size())
@@ -2437,7 +2402,12 @@ CanvasView::on_time_changed()
 void
 CanvasView::time_zoom_in()
 {
+       float frame_rate = get_canvas()->rend_desc().get_frame_rate();
+       Time min_page_size = 2/frame_rate;
+
        time_window_adjustment().set_page_size(time_window_adjustment().get_page_size()*0.75);
+       if (time_window_adjustment().get_page_size() < min_page_size)
+               time_window_adjustment().set_page_size(min_page_size);
        time_window_adjustment().changed();
 
        refresh_time_window();
@@ -2446,7 +2416,12 @@ CanvasView::time_zoom_in()
 void
 CanvasView::time_zoom_out()
 {
+       Time length = (get_canvas()->rend_desc().get_time_end() -
+                                  get_canvas()->rend_desc().get_time_start());
+
        time_window_adjustment().set_page_size(time_window_adjustment().get_page_size()/0.75);
+       if (time_window_adjustment().get_page_size() > length)
+               time_window_adjustment().set_page_size(length);
        time_window_adjustment().changed();
 
        refresh_time_window();
@@ -2488,7 +2463,6 @@ CanvasView::on_id_changed()
        update_title();
 }
 
-
 void
 CanvasView::on_mode_changed(synfigapp::CanvasInterface::Mode mode)
 {
@@ -3089,7 +3063,6 @@ CanvasView::set_sensitive_timebar(bool sensitive)
                children_tree->set_sensitive(sensitive);
 }
 
-
 static void
 set_waypoint_model(std::set<synfig::Waypoint, std::less<UniqueID> > waypoints,
                                   Waypoint::Model model,
@@ -3157,8 +3130,7 @@ remove_waypoints(std::set<synfig::Waypoint, std::less<UniqueID> > waypoints,
 void
 CanvasView::on_waypoint_clicked_canvasview(synfigapp::ValueDesc value_desc,
                                                                                   std::set<synfig::Waypoint, std::less<UniqueID> > waypoint_set,
-                                                                                  int button,
-                                                                                  synfig::Waypoint::Side side)
+                                                                                  int button)
 {
        int size = waypoint_set.size();
        Waypoint waypoint(*(waypoint_set.begin()));
@@ -3181,52 +3153,55 @@ CanvasView::on_waypoint_clicked_canvasview(synfigapp::ValueDesc value_desc,
                Gtk::Menu* waypoint_menu(manage(new Gtk::Menu()));
                waypoint_menu->signal_hide().connect(sigc::bind(sigc::ptr_fun(&delete_widget), waypoint_menu));
 
-               Waypoint::Model model;
-               String side_string(String(" ") + (side==Waypoint::SIDE_LEFT ? _("In") : _("Out")));
-
-               // ------------------------------------------------------------------------
-               if(side==Waypoint::SIDE_LEFT)   model.set_before(INTERPOLATION_TCB);
-               else                                                    model.set_after(INTERPOLATION_TCB);
-               waypoint_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_TCB") + side_string,
-                       sigc::bind(sigc::ptr_fun(set_waypoint_model), waypoint_set, model, canvas_interface())));
-
-               if(side==Waypoint::SIDE_LEFT)   model.set_before(INTERPOLATION_LINEAR);
-               else                                                    model.set_after(INTERPOLATION_LINEAR);
-               waypoint_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_Linear") + side_string,
-                       sigc::bind(sigc::ptr_fun(set_waypoint_model), waypoint_set, model, canvas_interface())));
-
-               if(side==Waypoint::SIDE_LEFT)   model.set_before(INTERPOLATION_HALT);
-               else                                                    model.set_after(INTERPOLATION_HALT);
-               waypoint_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_Ease") + side_string,
-                       sigc::bind(sigc::ptr_fun(set_waypoint_model), waypoint_set, model, canvas_interface())));
-
-               if(side==Waypoint::SIDE_LEFT)   model.set_before(INTERPOLATION_CONSTANT);
-               else                                                    model.set_after(INTERPOLATION_CONSTANT);
-               waypoint_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_Constant") + side_string,
-                       sigc::bind(sigc::ptr_fun(set_waypoint_model), waypoint_set, model, canvas_interface())));
-
-               // ------------------------------------------------------------------------
-               waypoint_menu->items().push_back(Gtk::Menu_Helpers::SeparatorElem());
-
-               model.set_after(INTERPOLATION_TCB); model.set_before(INTERPOLATION_TCB);
-               waypoint_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("TC_B Both"),
-                       sigc::bind(sigc::ptr_fun(set_waypoint_model), waypoint_set, model, canvas_interface())));
-
-               model.set_after(INTERPOLATION_LINEAR); model.set_before(INTERPOLATION_LINEAR);
-               waypoint_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Li_near Both"),
-                       sigc::bind(sigc::ptr_fun(set_waypoint_model), waypoint_set, model, canvas_interface())));
+               Gtk::Menu* interp_menu_in(manage(new Gtk::Menu()));
+               Gtk::Menu* interp_menu_out(manage(new Gtk::Menu()));
+               Gtk::Menu* interp_menu_both(manage(new Gtk::Menu()));
 
-               model.set_after(INTERPOLATION_HALT); model.set_before(INTERPOLATION_HALT);
-               waypoint_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Ea_se Both"),
-                       sigc::bind(sigc::ptr_fun(set_waypoint_model), waypoint_set, model, canvas_interface())));
-
-               model.set_after(INTERPOLATION_CONSTANT); model.set_before(INTERPOLATION_CONSTANT);
-               waypoint_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("C_onstant Both"),
-                       sigc::bind(sigc::ptr_fun(set_waypoint_model), waypoint_set, model, canvas_interface())));
+               {
+                       Waypoint::Model model;
+
+                       model.reset(); model.set_before(INTERPOLATION_TCB);
+                       interp_menu_in->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_TCB"),
+                               sigc::bind(sigc::ptr_fun(set_waypoint_model), waypoint_set, model, canvas_interface())));
+                       model.reset(); model.set_after(INTERPOLATION_TCB);
+                       interp_menu_out->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_TCB"),
+                               sigc::bind(sigc::ptr_fun(set_waypoint_model), waypoint_set, model, canvas_interface())));
+                       model.set_before(INTERPOLATION_TCB);
+                       interp_menu_both->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_TCB"),
+                               sigc::bind(sigc::ptr_fun(set_waypoint_model), waypoint_set, model, canvas_interface())));
+
+                       model.reset(); model.set_before(INTERPOLATION_LINEAR);
+                       interp_menu_in->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_Linear"),
+                               sigc::bind(sigc::ptr_fun(set_waypoint_model), waypoint_set, model, canvas_interface())));
+                       model.reset(); model.set_after(INTERPOLATION_LINEAR);
+                       interp_menu_out->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_Linear"),
+                               sigc::bind(sigc::ptr_fun(set_waypoint_model), waypoint_set, model, canvas_interface())));
+                       model.set_before(INTERPOLATION_LINEAR);
+                       interp_menu_both->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_Linear"),
+                               sigc::bind(sigc::ptr_fun(set_waypoint_model), waypoint_set, model, canvas_interface())));
+
+                       model.reset(); model.set_before(INTERPOLATION_HALT);
+                       interp_menu_in->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_Ease In"),
+                               sigc::bind(sigc::ptr_fun(set_waypoint_model), waypoint_set, model, canvas_interface())));
+                       model.reset(); model.set_after(INTERPOLATION_HALT);
+                       interp_menu_out->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_Ease Out"),
+                               sigc::bind(sigc::ptr_fun(set_waypoint_model), waypoint_set, model, canvas_interface())));
+                       model.set_before(INTERPOLATION_HALT);
+                       interp_menu_both->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_Ease In/Out"),
+                               sigc::bind(sigc::ptr_fun(set_waypoint_model), waypoint_set, model, canvas_interface())));
+
+                       model.reset(); model.set_before(INTERPOLATION_CONSTANT);
+                       interp_menu_in->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_Constant"),
+                               sigc::bind(sigc::ptr_fun(set_waypoint_model), waypoint_set, model, canvas_interface())));
+                       model.reset(); model.set_after(INTERPOLATION_CONSTANT);
+                       interp_menu_out->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_Constant"),
+                               sigc::bind(sigc::ptr_fun(set_waypoint_model), waypoint_set, model, canvas_interface())));
+                       model.set_before(INTERPOLATION_CONSTANT);
+                       interp_menu_both->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_Constant"),
+                               sigc::bind(sigc::ptr_fun(set_waypoint_model), waypoint_set, model, canvas_interface())));
+               }
 
                // ------------------------------------------------------------------------
-               waypoint_menu->items().push_back(Gtk::Menu_Helpers::SeparatorElem());
-
                waypoint_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_Jump To"),
                        sigc::bind(sigc::mem_fun(*canvas_interface(), &synfigapp::CanvasInterface::set_time), time)));
 
@@ -3237,9 +3212,18 @@ CanvasView::on_waypoint_clicked_canvasview(synfigapp::ValueDesc value_desc,
                         sigc::bind(sigc::ptr_fun(remove_waypoints), waypoint_set, canvas_interface())));
 
                if (size == 1 && value_desc.is_valid())
-                       waypoint_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_Properties"),
+                       waypoint_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_Edit"),
                                sigc::mem_fun(waypoint_dialog,&Gtk::Widget::show)));
 
+               // ------------------------------------------------------------------------
+               waypoint_menu->items().push_back(Gtk::Menu_Helpers::SeparatorElem());
+
+               // ------------------------------------------------------------------------
+               waypoint_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_Both"), *interp_menu_both));
+               waypoint_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_In"),   *interp_menu_in));
+               waypoint_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_Out"),  *interp_menu_out));
+
+               // ------------------------------------------------------------------------
                waypoint_menu->popup(button+1,gtk_get_current_event_time());
        }
        break;
@@ -3450,7 +3434,6 @@ CanvasView::on_keyframe_remove_pressed()
        canvas_interface()->get_instance()->perform_action(action);
 }
 
-
 void
 CanvasView::toggle_duck_mask(Duckmatic::Type type)
 {
@@ -3501,7 +3484,6 @@ CanvasView::toggle_duck_mask(Duckmatic::Type type)
        work_area->queue_draw();
 }
 
-
 void
 CanvasView::image_import()
 {
@@ -3696,8 +3678,6 @@ CanvasView::on_audio_scrub()
        return true;
 }
 
-
-
 Glib::RefPtr<Glib::ObjectBase>
 CanvasView::get_ref_obj(const synfig::String& x)
 {