tentative steps in trying to fix region action sensitivity
authorPaul Davis <paul@linuxaudiosystems.com>
Fri, 10 Feb 2017 21:12:28 +0000 (22:12 +0100)
committerPaul Davis <paul@linuxaudiosystems.com>
Wed, 15 Feb 2017 19:07:49 +0000 (20:07 +0100)
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_selection.cc

index e4d2a126a1c9b1ccabfede99d55236b14d85da47..4407dac256cefd07c2b9878308fd82e9a27135cc 100644 (file)
@@ -1485,7 +1485,7 @@ Editor::action_pre_activated (Glib::RefPtr<Action> const & a)
 
                   What a carry on :(
                */
-               sensitize_the_right_region_actions ();
+               sensitize_the_right_region_actions (false, !within_track_canvas);
                _last_region_menu_was_main = true;
        }
 }
@@ -1717,7 +1717,7 @@ Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type,
        /* When the region menu is opened, we setup the actions so that they look right
           in the menu.
        */
-       sensitize_the_right_region_actions ();
+       sensitize_the_right_region_actions (true, false);
        _last_region_menu_was_main = false;
 
        menu->signal_hide().connect (sigc::bind (sigc::mem_fun (*this, &Editor::sensitize_all_region_actions), true));
@@ -4738,6 +4738,8 @@ Editor::get_preferred_edit_position (EditIgnoreOption ignore, bool from_context_
        framepos_t where = 0;
        EditPoint ep = _edit_point;
 
+       cerr << "ig " << ignore << " fcm " << from_context_menu << " foc " << from_outside_canvas << endl;
+
        if (Profile->get_mixbus()) {
                if (ep == EditAtSelectedMarker) {
                        ep = EditAtPlayhead;
@@ -4765,6 +4767,8 @@ Editor::get_preferred_edit_position (EditIgnoreOption ignore, bool from_context_
 
        MusicFrame snap_mf (0, 0);
 
+       cerr << "Using EP " << enum_2_string (ep) << endl;
+
        switch (ep) {
        case EditAtPlayhead:
                if (_dragging_playhead) {
@@ -4949,7 +4953,7 @@ Editor::get_regions_after (RegionSelection& rs, framepos_t where, const TrackVie
  */
 
 RegionSelection
-Editor::get_regions_from_selection_and_edit_point ()
+Editor::get_regions_from_selection_and_edit_point (EditIgnoreOption ignore, bool from_context_menu, bool from_outside_canvas)
 {
        RegionSelection regions;
 
@@ -4966,7 +4970,7 @@ Editor::get_regions_from_selection_and_edit_point ()
                        /* no region selected or entered, but some selected tracks:
                         * act on all regions on the selected tracks at the edit point
                         */
-                       framepos_t const where = get_preferred_edit_position ();
+                       framepos_t const where = get_preferred_edit_position (ignore, from_outside_canvas, from_outside_canvas);
                        get_regions_at(regions, where, tracks);
                }
        }
index 46562a76b89dceebdf53d5a8145050360604f0b4..4b48b9a7f78c9a67fae90e136217e3c550a92f21 100644 (file)
@@ -1845,7 +1845,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
        void region_selection_changed ();
        sigc::connection editor_regions_selection_changed_connection;
        void sensitize_all_region_actions (bool);
-       void sensitize_the_right_region_actions ();
+       void sensitize_the_right_region_actions (bool from_context_menu, bool from_outside_canvas);
        bool _all_region_actions_sensitized;
        /** Flag to block region action handlers from doing what they normally do;
         *  I tried Gtk::Action::block_activate() but this doesn't work (ie it doesn't
@@ -2143,7 +2143,9 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
        void get_regions_at (RegionSelection&, framepos_t where, const TrackViewList& ts) const;
        void get_regions_after (RegionSelection&, framepos_t where, const TrackViewList& ts) const;
 
-       RegionSelection get_regions_from_selection_and_edit_point ();
+       RegionSelection get_regions_from_selection_and_edit_point (Editing::EditIgnoreOption = Editing::EDIT_IGNORE_NONE,
+                                                                  bool use_context_click = false,
+                                                                  bool from_outside_canvas = false);
        RegionSelection get_regions_from_selection_and_entered () const;
 
        void start_updating_meters ();
index 2e3b1ba8ef5b11a271c8a8a76ded4a8a1c04005a..2bcc8f1f2f638b81880be12697ec65ff0ffb01ec 100644 (file)
@@ -1087,17 +1087,20 @@ Editor::sensitize_all_region_actions (bool s)
 }
 
 /** Sensitize region-based actions based on the selection ONLY, ignoring the entered_regionview.
- *  This method should be called just before displaying a Region menu.  When a Region menu is not
- *  currently being shown, all region actions are sensitized so that hotkey-triggered actions
- *  on entered_regionviews work without having to check sensitivity every time the selection or
- *  entered_regionview changes.
+ *  This method is called from three places:
+ *
+ *    1. just before the top level Region menu is shown
+ *    2. whenever the region selection changes
+ *    3. just before popping up a track context menu
  *
  *  This method also sets up toggle action state as appropriate.
  */
 void
-Editor::sensitize_the_right_region_actions ()
+Editor::sensitize_the_right_region_actions (bool from_context_menu, bool from_outside_canvas)
 {
-       RegionSelection rs = get_regions_from_selection_and_entered ();
+       PBD::stacktrace (cerr, 20);
+       RegionSelection rs = get_regions_from_selection_and_edit_point (Editing::EDIT_IGNORE_NONE, from_context_menu, from_outside_canvas);
+
        sensitize_all_region_actions (!rs.empty ());
 
        _ignore_region_action = true;
@@ -1251,13 +1254,72 @@ Editor::sensitize_the_right_region_actions ()
                /* others were already marked sensitive */
        }
 
-       if (_edit_point == EditAtMouse) {
-               _region_actions->get_action("set-region-sync-position")->set_sensitive (false);
-               _region_actions->get_action("trim-front")->set_sensitive (false);
-               _region_actions->get_action("trim-back")->set_sensitive (false);
-               _region_actions->get_action("place-transient")->set_sensitive (false);
+       /* these actions all require a single location, taken from the edit
+        * point.
+        */
+
+       vector<string> edit_point_actions;
+       edit_point_actions.push_back ("set-region-sync-position");
+       edit_point_actions.push_back ("trim-front");
+       edit_point_actions.push_back ("trim-back");
+       edit_point_actions.push_back ("place-transient");
+       edit_point_actions.push_back ("align-regions-start");
+       edit_point_actions.push_back ("align-regions-start-relative");
+       edit_point_actions.push_back ("align-regions-end");
+       edit_point_actions.push_back ("align-regions-end-relative");
+       edit_point_actions.push_back ("align-regions-sync");
+       edit_point_actions.push_back ("align-regions-sync-relative");
+
+       /* They all use Editor::get_regions_from_selection_and_edit_point(),
+        * which is the same method used at the start of this to determine if
+        * any regions are eligible/valid for editing.
+        *
+        * there are two possible reasons why these actions should still
+        * be sensitive.
+        *
+        *  1. regions are selected
+        *  2. the edit point is inside some regions on selected tracks
+        *
+        * the first condition is satisfied if selection->regions is not empty.
+        * the second condition is satisfied if selection->regions is empty,
+        *    but @param rs (set above by the call to get_regions_from_selection_and_edit_point()
+        *    is not empty.
+        *
+        * if the mouse is the edit point, then whether get_regions_from_selection_and_edit_point()
+        * will have identified any regions will depend on the edit point setting.
+        *
+        * Editing::EditIgnoreOption that we passed to it, which in turn will
+        * depend on whether or not the pointer is still inside the track
+        * canvas. If it was, then the pointer position will determine whether
+        * or not any non-selected regions are considered eligible. If it
+        * wasn't, then we will ignore the pointer position and fallback on a
+        * secondary edit point (at this writing, that will likely be the
+        * playhead but see get_regions_from_selection_and_edit_point() to see
+        * how this works).
+        *
+        * if the edit point is not the mouse, then
+        * get_regions_from_selection_and_edit_point() will just do the right
+        * thing.
+        *
+        * However, the implementation of the actions will still use the edit
+        * point, ...
+        * 
+        */
+
+       bool sensitivity;
+
+       if (!selection->regions.empty() || !rs.empty()) { /* conditions 1 and 2 above */
+               sensitivity = true;
+       } else {
+               sensitivity = false;
+       }
+
+       for (vector<string>::const_iterator a = edit_point_actions.begin(); a != edit_point_actions.end(); ++a) {
+               _region_actions->get_action (*a)->set_sensitive (sensitivity);
        }
 
+       /* ok, moving along... */
+
        if (have_compound_regions) {
                _region_actions->get_action("uncombine-regions")->set_sensitive (true);
        } else {
@@ -1362,7 +1424,6 @@ Editor::sensitize_the_right_region_actions ()
        _all_region_actions_sensitized = false;
 }
 
-
 void
 Editor::region_selection_changed ()
 {
@@ -1384,16 +1445,7 @@ Editor::region_selection_changed ()
        _regions->block_change_connection (false);
        editor_regions_selection_changed_connection.block(false);
 
-       if (selection->regions.empty()) {
-               sensitize_all_region_actions (false);
-       } else {
-               if (!_all_region_actions_sensitized) {
-                       /* This selection change might have changed what region actions
-                          are allowed, so sensitize them all in case a key is pressed.
-                       */
-                       sensitize_all_region_actions (true);
-               }
-       }
+       sensitize_the_right_region_actions (false, false);
 
        /* propagate into backend */