allow ardour button to handle focused keyboard events
[ardour.git] / gtk2_ardour / editor.cc
index 559196a68531b540cf60536e0e14d75fbc33fe31..f3195daec271359348670b7499687ff7a565ddc4 100644 (file)
@@ -469,7 +469,6 @@ Editor::Editor ()
        transport_mark_label.hide();
        transport_mark_label.set_no_show_all();
 
-       initialize_rulers ();
        initialize_canvas ();
 
        _summary = new EditorSummary (this);
@@ -495,13 +494,12 @@ Editor::Editor ()
        controls_layout.add (*h);
 
        controls_layout.set_name ("EditControlsBase");
-       controls_layout.add_events (Gdk::SCROLL_MASK);
-       controls_layout.signal_scroll_event().connect (sigc::mem_fun(*this, &Editor::control_layout_scroll), false);
-
-       controls_layout.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK);
+       controls_layout.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK|Gdk::SCROLL_MASK);
        controls_layout.signal_button_release_event().connect (sigc::mem_fun(*this, &Editor::edit_controls_button_release));
+       controls_layout.signal_scroll_event().connect (sigc::mem_fun(*this, &Editor::control_layout_scroll), false);
 
        _cursors = new MouseCursors;
+       _cursors->set_cursor_set (ARDOUR_UI::config()->get_icon_set());
 
        ArdourCanvas::GtkCanvas* time_pad = manage (new ArdourCanvas::GtkCanvas ());
 
@@ -513,38 +511,22 @@ Editor::Editor ()
        // CAIROCANVAS
        time_pad->show();
 
-       time_canvas_vbox.set_size_request (-1, (int)(timebar_height * visible_timebars) + 2);
-       time_canvas_vbox.set_size_request (-1, -1);
-
-       ruler_label_event_box.add (ruler_label_vbox);
-       ruler_label_event_box.set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
-       ruler_label_event_box.signal_button_release_event().connect (sigc::mem_fun(*this, &Editor::ruler_label_button_release));
-
-       time_bars_event_box.add (time_bars_vbox);
-       time_bars_event_box.set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
-       time_bars_event_box.signal_button_release_event().connect (sigc::mem_fun(*this, &Editor::ruler_label_button_release));
-
-       time_canvas_event_box.add (time_canvas_vbox);
-       time_canvas_event_box.set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK);
-
        edit_packer.set_col_spacings (0);
        edit_packer.set_row_spacings (0);
        edit_packer.set_homogeneous (false);
        edit_packer.set_border_width (0);
        edit_packer.set_name ("EditorWindow");
 
-       /* labels for the rulers */
-       edit_packer.attach (ruler_label_event_box,   1, 2, 0, 1,    FILL,        SHRINK, 0, 0);
-       /* labels for the marker "tracks" (time bars) */
-       edit_packer.attach (time_bars_event_box,     1, 2, 1, 2,    FILL,        SHRINK, 0, 0);
-       /* the rulers */
-       edit_packer.attach (time_canvas_event_box,   2, 3, 0, 1,    FILL|EXPAND, FILL, 0, 0);
+       time_bars_event_box.add (time_bars_vbox);
+       time_bars_event_box.set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
+       time_bars_event_box.signal_button_release_event().connect (sigc::mem_fun(*this, &Editor::ruler_label_button_release));
+
+       /* labels for the time bars */
+       edit_packer.attach (time_bars_event_box,     0, 1, 0, 1,    FILL,        SHRINK, 0, 0);
        /* track controls */
-       edit_packer.attach (controls_layout,         0, 2, 2, 3,    FILL,        FILL|EXPAND, 0, 0);
-       /* time bars canvas */
-       edit_packer.attach (*_time_bars_canvas_viewport, 2, 3, 1, 2,    FILL,    FILL, 0, 0);
-       /* track canvas */
-       edit_packer.attach (*_track_canvas_viewport,  2, 3, 2, 3,    FILL|EXPAND, FILL|EXPAND, 0, 0);
+       edit_packer.attach (controls_layout,         0, 1, 1, 2,    FILL,        FILL|EXPAND, 0, 0);
+       /* canvas */
+       edit_packer.attach (*_track_canvas_viewport,  1, 2, 0, 2,    FILL|EXPAND, FILL|EXPAND, 0, 0);
 
        bottom_hbox.set_border_width (2);
        bottom_hbox.set_spacing (3);
@@ -751,6 +733,7 @@ Editor::Editor ()
        Session::AskAboutPlaylistDeletion.connect_same_thread (*this, boost::bind (&Editor::playlist_deletion_dialog, this, _1));
 
        Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&Editor::parameter_changed, this, _1), gui_context());
+       ARDOUR_UI::config()->ParameterChanged.connect (sigc::mem_fun (*this, &Editor::ui_parameter_changed));
 
        TimeAxisView::CatchDeletion.connect (*this, invalidator (*this), boost::bind (&Editor::timeaxisview_deleted, this, _1), gui_context());
 
@@ -783,7 +766,6 @@ Editor::~Editor()
         delete button_bindings;
        delete _routes;
        delete _route_groups;
-       delete _time_bars_canvas_viewport;
        delete _track_canvas_viewport;
        delete _drags;
 }
@@ -1401,185 +1383,48 @@ Editor::fill_xfade_menu (Menu_Helpers::MenuList& items, bool start)
 
 /** Pop up a context menu for when the user clicks on a start crossfade */
 void
-Editor::popup_xfade_in_context_menu (int button, int32_t time, ArdourCanvas::Item* /*item*/, ItemType /*item_type*/)
+Editor::popup_xfade_in_context_menu (int button, int32_t time, ArdourCanvas::Item* item, ItemType /*item_type*/)
 {
        using namespace Menu_Helpers;
+       AudioRegionView* arv = static_cast<AudioRegionView*> (item->get_data ("regionview"));
+       assert(arv);
 
        MenuList& items (xfade_in_context_menu.items());
+       items.clear ();
 
-       if (items.empty()) {
-               fill_xfade_menu (items, true);
+       if (arv->audio_region()->fade_in_active()) {
+               items.push_back (MenuElem (_("Deactivate"), sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_in_active), false)));
+       } else {
+               items.push_back (MenuElem (_("Activate"), sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_in_active), true)));
        }
 
+       items.push_back (SeparatorElem());
+       fill_xfade_menu (items, true);
+
        xfade_in_context_menu.popup (button, time);
 }
 
 /** Pop up a context menu for when the user clicks on an end crossfade */
 void
-Editor::popup_xfade_out_context_menu (int button, int32_t time, ArdourCanvas::Item* /*item*/, ItemType /*item_type*/)
-{
-       using namespace Menu_Helpers;
-
-       MenuList& items (xfade_out_context_menu.items());
-
-       if (items.empty()) {
-               fill_xfade_menu (items, false);
-       }
-
-       xfade_out_context_menu.popup (button, time);
-}
-
-
-/** Pop up a context menu for when the user clicks on a fade in or fade out */
-void
-Editor::popup_fade_context_menu (int button, int32_t time, ArdourCanvas::Item* item, ItemType item_type)
+Editor::popup_xfade_out_context_menu (int button, int32_t time, ArdourCanvas::Item* item, ItemType /*item_type*/)
 {
        using namespace Menu_Helpers;
        AudioRegionView* arv = static_cast<AudioRegionView*> (item->get_data ("regionview"));
+       assert(arv);
 
-       if (arv == 0) {
-               fatal << _("programming error: fade in canvas item has no regionview data pointer!") << endmsg;
-               /*NOTREACHED*/
-       }
-
-       MenuList& items (fade_context_menu.items());
+       MenuList& items (xfade_out_context_menu.items());
        items.clear ();
 
-       switch (item_type) {
-       case FadeInItem:
-       case FadeInHandleItem:
-               if (arv->audio_region()->fade_in_active()) {
-                       items.push_back (MenuElem (_("Deactivate"), sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_in_active), false)));
-               } else {
-                       items.push_back (MenuElem (_("Activate"), sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_in_active), true)));
-               }
-               
-               items.push_back (SeparatorElem());
-               
-               if (Profile->get_sae()) {
-                       
-                       items.push_back (MenuElem (_("Linear"), sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_in_shape), FadeLinear)));
-                       items.push_back (MenuElem (_("Slowest"), sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_in_shape), FadeFast)));
-                       
-               } else {
-                       
-                       items.push_back (
-                               ImageMenuElem (
-                                       _("Linear"),
-                                       *_fade_in_images[FadeLinear],
-                                       sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_in_shape), FadeLinear)
-                                       )
-                               );
-                               
-                       dynamic_cast<ImageMenuItem*>(&items.back())->set_always_show_image ();
-                               
-                       items.push_back (
-                               ImageMenuElem (
-                                       _("Slow"),
-                                       *_fade_in_images[FadeSlow],
-                                       sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_in_shape), FadeSlow)
-                                       ));
-                               
-                       dynamic_cast<ImageMenuItem*>(&items.back())->set_always_show_image ();
-                               
-                       items.push_back (
-                               ImageMenuElem (
-                                       _("Fast"),
-                                       *_fade_in_images[FadeFast],
-                                       sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_in_shape), FadeFast)
-                                       ));
-                               
-                       dynamic_cast<ImageMenuItem*>(&items.back())->set_always_show_image ();
-                               
-                       items.push_back (
-                               ImageMenuElem (
-                                       _("Symmetric"),
-                                       *_fade_in_images[FadeSymmetric],
-                                       sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_in_shape), FadeSymmetric)
-                                       ));
-                               
-                       items.push_back (
-                               ImageMenuElem (
-                                       _("Constant power"),
-                                       *_fade_in_images[FadeConstantPower],
-                                       sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_in_shape), FadeConstantPower)
-                                       ));
-
-                       dynamic_cast<ImageMenuItem*>(&items.back())->set_always_show_image ();
-               }
-
-               break;
-
-       case FadeOutItem:
-       case FadeOutHandleItem:
-               if (arv->audio_region()->fade_out_active()) {
-                       items.push_back (MenuElem (_("Deactivate"), sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_out_active), false)));
-               } else {
-                       items.push_back (MenuElem (_("Activate"), sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_out_active), true)));
-               }
-
-               items.push_back (SeparatorElem());
-
-               if (Profile->get_sae()) {
-                       items.push_back (MenuElem (_("Linear"), sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_out_shape), FadeLinear)));
-                       items.push_back (MenuElem (_("Slowest"), sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_out_shape), FadeSlow)));
-               } else {
-
-                       items.push_back (
-                               ImageMenuElem (
-                                       _("Linear"),
-                                       *_fade_out_images[FadeLinear],
-                                       sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_out_shape), FadeLinear)
-                                       )
-                               );
-
-                       dynamic_cast<ImageMenuItem*>(&items.back())->set_always_show_image ();
-
-                       items.push_back (
-                               ImageMenuElem (
-                                       _("Slow"),
-                                       *_fade_out_images[FadeSlow],
-                                       sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_out_shape), FadeSlow)
-                                       ));
-
-                       dynamic_cast<ImageMenuItem*>(&items.back())->set_always_show_image ();
-
-                       items.push_back (
-                               ImageMenuElem (
-                                       _("Fast"),
-                                       *_fade_out_images[FadeFast],
-                                       sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_out_shape), FadeFast)
-                                       ));
-
-                       dynamic_cast<ImageMenuItem*>(&items.back())->set_always_show_image ();
-
-                       items.push_back (
-                               ImageMenuElem (
-                                       _("Symmetric"),
-                                       *_fade_out_images[FadeSymmetric],
-                                       sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_out_shape), FadeSymmetric)
-                                       ));
-
-                       items.push_back (
-                               ImageMenuElem (
-                                       _("Constant power"),
-                                       *_fade_out_images[FadeConstantPower],
-                                       sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_out_shape), FadeConstantPower)
-                                       ));
-
-                       dynamic_cast<ImageMenuItem*>(&items.back())->set_always_show_image ();
-               }
-
-               break;
-
-       default:
-               fatal << _("programming error: ")
-                     << X_("non-fade canvas item passed to popup_fade_context_menu()")
-                     << endmsg;
-               /*NOTREACHED*/
+       if (arv->audio_region()->fade_out_active()) {
+               items.push_back (MenuElem (_("Deactivate"), sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_out_active), false)));
+       } else {
+               items.push_back (MenuElem (_("Activate"), sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_out_active), true)));
        }
 
-       fade_context_menu.popup (button, time);
+       items.push_back (SeparatorElem());
+       fill_xfade_menu (items, false);
+
+       xfade_out_context_menu.popup (button, time);
 }
 
 void
@@ -2264,7 +2109,7 @@ Editor::set_state (const XMLNode& node, int /*version*/)
        }
 
        if ((prop = node.property ("zoom-focus"))) {
-               set_zoom_focus ((ZoomFocus) string_2_enum (prop->value(), zoom_focus));
+               zoom_focus_selection_done ((ZoomFocus) string_2_enum (prop->value(), zoom_focus));
        }
 
        if ((prop = node.property ("zoom"))) {
@@ -2280,11 +2125,11 @@ Editor::set_state (const XMLNode& node, int /*version*/)
        }
 
        if ((prop = node.property ("snap-to"))) {
-               set_snap_to ((SnapType) string_2_enum (prop->value(), _snap_type));
+               snap_type_selection_done ((SnapType) string_2_enum (prop->value(), _snap_type));
        }
 
        if ((prop = node.property ("snap-mode"))) {
-               set_snap_mode ((SnapMode) string_2_enum (prop->value(), _snap_mode));
+               snap_mode_selection_done((SnapMode) string_2_enum (prop->value(), _snap_mode));
        }
 
        if ((prop = node.property ("internal-snap-to"))) {
@@ -2561,19 +2406,29 @@ Editor::get_state ()
        return *node;
 }
 
-
-
-/** @param y y offset from the top of all trackviews.
+/** if @param trackview_relative_offset is true, @param y y is an offset into the trackview area, in pixel units
+ *  if @param trackview_relative_offset is false, @param y y is a global canvas *  coordinate, in pixel units
+ *
  *  @return pair: TimeAxisView that y is over, layer index.
+ *
  *  TimeAxisView may be 0.  Layer index is the layer number if the TimeAxisView is valid and is
  *  in stacked or expanded region display mode, otherwise 0.
  */
 std::pair<TimeAxisView *, double>
-Editor::trackview_by_y_position (double y)
+Editor::trackview_by_y_position (double y, bool trackview_relative_offset)
 {
-       for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
+       if (!trackview_relative_offset) {
+               y -= _trackview_group->canvas_origin().y;
+       }
+
+       if (y < 0) {
+               return std::make_pair ( (TimeAxisView *) 0, 0);
+       }
 
+       for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
+                       
                std::pair<TimeAxisView*, double> const r = (*iter)->covers_y_position (y);
+                       
                if (r.first) {
                        return r;
                }
@@ -4008,26 +3863,14 @@ Editor::transport_punch_location()
 bool
 Editor::control_layout_scroll (GdkEventScroll* ev)
 {
-       if (Keyboard::some_magic_widget_has_focus()) {
-               return false;
-       }
-
-       switch (ev->direction) {
-       case GDK_SCROLL_UP:
-               scroll_tracks_up_line ();
-               return true;
-               break;
-
-       case GDK_SCROLL_DOWN:
-               scroll_tracks_down_line ();
-               return true;
-
-       default:
-               /* no left/right handling yet */
-               break;
-       }
+       /* Just forward to the normal canvas scroll method. The coordinate
+          systems are different but since the canvas is always larger than the
+          track headers, and aligned with the trackview area, this will work.
 
-       return false;
+          In the not too distant future this layout is going away anyway and
+          headers will be on the canvas.
+       */
+       return canvas_scroll_event (ev, false);
 }
 
 void
@@ -4319,10 +4162,6 @@ Editor::set_samples_per_pixel (framecnt_t spp)
 
        ArdourCanvas::GtkCanvasViewport* c;
 
-       c = get_time_bars_canvas();
-       if (c) {
-               c->canvas()->zoomed ();
-       }
        c = get_track_canvas();
        if (c) {
                c->canvas()->zoomed ();
@@ -5485,28 +5324,28 @@ void
 Editor::setup_fade_images ()
 {
        _fade_in_images[FadeLinear] = new Gtk::Image (get_icon_path (X_("fadein-linear")));
-       _fade_in_images[FadeSymmetric] = new Gtk::Image (get_icon_path (X_("fadein-short-cut")));
-       _fade_in_images[FadeFast] = new Gtk::Image (get_icon_path (X_("fadein-slow-cut")));
-       _fade_in_images[FadeSlow] = new Gtk::Image (get_icon_path (X_("fadein-fast-cut")));
-       _fade_in_images[FadeConstantPower] = new Gtk::Image (get_icon_path (X_("fadein-long-cut")));
+       _fade_in_images[FadeSymmetric] = new Gtk::Image (get_icon_path (X_("fadein-symmetric")));
+       _fade_in_images[FadeFast] = new Gtk::Image (get_icon_path (X_("fadein-fast-cut")));
+       _fade_in_images[FadeSlow] = new Gtk::Image (get_icon_path (X_("fadein-slow-cut")));
+       _fade_in_images[FadeConstantPower] = new Gtk::Image (get_icon_path (X_("fadein-constant-power")));
 
        _fade_out_images[FadeLinear] = new Gtk::Image (get_icon_path (X_("fadeout-linear")));
-       _fade_out_images[FadeSymmetric] = new Gtk::Image (get_icon_path (X_("fadeout-short-cut")));
-       _fade_out_images[FadeFast] = new Gtk::Image (get_icon_path (X_("fadeout-slow-cut")));
-       _fade_out_images[FadeSlow] = new Gtk::Image (get_icon_path (X_("fadeout-fast-cut")));
-       _fade_out_images[FadeConstantPower] = new Gtk::Image (get_icon_path (X_("fadeout-long-cut")));
+       _fade_out_images[FadeSymmetric] = new Gtk::Image (get_icon_path (X_("fadeout-symmetric")));
+       _fade_out_images[FadeFast] = new Gtk::Image (get_icon_path (X_("fadeout-fast-cut")));
+       _fade_out_images[FadeSlow] = new Gtk::Image (get_icon_path (X_("fadeout-slow-cut")));
+       _fade_out_images[FadeConstantPower] = new Gtk::Image (get_icon_path (X_("fadeout-constant-power")));
        
-       _xfade_in_images[FadeLinear] = new Gtk::Image (get_icon_path (X_("fadeout-linear")));
-       _xfade_in_images[FadeSymmetric] = new Gtk::Image (get_icon_path (X_("fadeout-short-cut")));
-       _xfade_in_images[FadeFast] = new Gtk::Image (get_icon_path (X_("fadeout-slow-cut")));
-       _xfade_in_images[FadeSlow] = new Gtk::Image (get_icon_path (X_("fadeout-fast-cut")));
-       _xfade_in_images[FadeConstantPower] = new Gtk::Image (get_icon_path (X_("fadeout-long-cut")));
+       _xfade_in_images[FadeLinear] = new Gtk::Image (get_icon_path (X_("fadein-linear")));
+       _xfade_in_images[FadeSymmetric] = new Gtk::Image (get_icon_path (X_("fadein-symmetric")));
+       _xfade_in_images[FadeFast] = new Gtk::Image (get_icon_path (X_("fadein-fast-cut")));
+       _xfade_in_images[FadeSlow] = new Gtk::Image (get_icon_path (X_("fadein-slow-cut")));
+       _xfade_in_images[FadeConstantPower] = new Gtk::Image (get_icon_path (X_("fadein-constant-power")));
 
        _xfade_out_images[FadeLinear] = new Gtk::Image (get_icon_path (X_("fadeout-linear")));
-       _xfade_out_images[FadeSymmetric] = new Gtk::Image (get_icon_path (X_("fadeout-short-cut")));
-       _xfade_out_images[FadeFast] = new Gtk::Image (get_icon_path (X_("fadeout-slow-cut")));
-       _xfade_out_images[FadeSlow] = new Gtk::Image (get_icon_path (X_("fadeout-fast-cut")));
-       _xfade_out_images[FadeConstantPower] = new Gtk::Image (get_icon_path (X_("fadeout-long-cut")));
+       _xfade_out_images[FadeSymmetric] = new Gtk::Image (get_icon_path (X_("fadeout-symmetric")));
+       _xfade_out_images[FadeFast] = new Gtk::Image (get_icon_path (X_("fadeout-fast-cut")));
+       _xfade_out_images[FadeSlow] = new Gtk::Image (get_icon_path (X_("fadeout-slow-cut")));
+       _xfade_out_images[FadeConstantPower] = new Gtk::Image (get_icon_path (X_("fadeout-constant-power")));
 
 }
 
@@ -5584,3 +5423,11 @@ Editor::zoom_vertical_modifier_released()
 {
        _stepping_axis_view = 0;
 }
+
+void
+Editor::ui_parameter_changed (string parameter)
+{
+       if (parameter == "icon-set") {
+               _cursors->set_cursor_set (ARDOUR_UI::config()->get_icon_set());
+       }
+}