fix some confusion when redrawing editor/mixer track/strip displays after track/bus...
authorPaul Davis <paul@linuxaudiosystems.com>
Sat, 21 Jun 2014 01:51:59 +0000 (21:51 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Sat, 21 Jun 2014 01:52:24 +0000 (21:52 -0400)
The code relied on the idea that the order-key resync that occurs after deletion would change the order keys and thus cause
a redisplay. But since both the editor and mixer can initiate an order-key resync, the other window's resync will actually
do nothing (the order keys will already be correct). This led to the incorrect placement of material in the tracks canvas,
because the first resync triggered a redisplay while the route still existed, and then the second resync didn't cause a
redisplay (repositioning) but the canvas elements representing the track went away.

Fixed by forcing a redisplay in both editor and mixer if a route deletion is believed to be triggering a row deletion
in their underlying data models.

gtk2_ardour/editor_routes.cc
gtk2_ardour/editor_routes.h
gtk2_ardour/mixer_ui.cc
gtk2_ardour/mixer_ui.h

index 38706a652587e2afa76d6018e2457ce0cb0be1b5..5da4979824e43d1f053546a28bf6f09104983a8f 100644 (file)
@@ -70,6 +70,7 @@ EditorRoutes::EditorRoutes (Editor* e)
         , _ignore_reorder (false)
         , _no_redisplay (false)
         , _adding_routes (false)
+        , _route_deletion_in_progress (false)
         , _menu (0)
         , old_focus (0)
         , selection_countdown (0)
@@ -271,7 +272,7 @@ EditorRoutes::EditorRoutes (Editor* e)
        active_col->set_fixed_width (30);
        active_col->set_alignment (ALIGN_CENTER);
        
-       _model->signal_row_deleted().connect (sigc::mem_fun (*this, &EditorRoutes::route_deleted));
+       _model->signal_row_deleted().connect (sigc::mem_fun (*this, &EditorRoutes::row_deleted));
        _model->signal_rows_reordered().connect (sigc::mem_fun (*this, &EditorRoutes::reordered));
 
        _display.signal_button_press_event().connect (sigc::mem_fun (*this, &EditorRoutes::button_press), false);
@@ -519,7 +520,6 @@ EditorRoutes::redisplay ()
                /* show or hide the TimeAxisView */
                if (visible) {
                        position += tv->show_at (position, n, &_editor->edit_controls_vbox);
-                       // SHOWTRACKS
                } else {
                        tv->hide ();
                }
@@ -547,18 +547,38 @@ EditorRoutes::redisplay ()
 }
 
 void
-EditorRoutes::route_deleted (Gtk::TreeModel::Path const &)
+EditorRoutes::row_deleted (Gtk::TreeModel::Path const &)
 {
-       /* this happens as the second step of a DnD within the treeview as well
-          as when a row/route is actually deleted.
+       /* this happens as the second step of a DnD within the treeview, and
+          when a route is actually removed. we don't differentiate between
+          the two cases.
+          
+          note that the sync_orders_keys() step may not actually change any
+          RID's (e.g. the last track may be removed, so all other tracks keep
+          the same RID), which means that no redisplay would happen. so we 
+           have to force a redisplay.
        */
+
        DEBUG_TRACE (DEBUG::OrderKeys, "editor routes treeview row deleted\n");
+
+        if (_route_deletion_in_progress) {
+                suspend_redisplay ();
+        }
+
        sync_order_keys_from_treeview ();
+
+        if (_route_deletion_in_progress) {
+                resume_redisplay ();
+        }
 }
 
 void
 EditorRoutes::reordered (TreeModel::Path const &, TreeModel::iterator const &, int* /*what*/)
 {
+       /* reordering implies that RID's will change, so sync_order_keys() will
+          cause a redisplay.
+       */
+
        DEBUG_TRACE (DEBUG::OrderKeys, "editor routes treeview reordered\n");
        sync_order_keys_from_treeview ();
 }
@@ -721,10 +741,13 @@ EditorRoutes::route_removed (TimeAxisView *tv)
 
        TreeModel::Children rows = _model->children();
        TreeModel::Children::iterator ri;
+       bool found = false;
 
        for (ri = rows.begin(); ri != rows.end(); ++ri) {
                if ((*ri)[_columns.tv] == tv) {
+                        PBD::Unwinder<bool> uw (_route_deletion_in_progress, true);
                        _model->erase (ri);
+                       found = true;
                        break;
                }
        }
index 9780307435adf3d3b38110a8961607cc06ea70e2..dea8da6cc08b17d2676c30b37fc149a1e82768d3 100644 (file)
@@ -73,7 +73,7 @@ private:
        void build_menu ();
        void show_menu ();
         void sync_treeview_from_order_keys ();
-       void route_deleted (Gtk::TreeModel::Path const &);
+       void row_deleted (Gtk::TreeModel::Path const &);
        void visible_changed (std::string const &);
        void active_changed (std::string const &);
        void reordered (Gtk::TreeModel::Path const &, Gtk::TreeModel::iterator const &, int *);
@@ -156,6 +156,7 @@ private:
        bool _ignore_reorder;
        bool _no_redisplay;
         bool _adding_routes;
+        bool _route_deletion_in_progress;
 
        Gtk::Menu* _menu;
         Gtk::Widget* old_focus;
index 874f8feddf7ac119cb6bb3c85701cda842b24790..dc0ca4b198a62afb38f88b61868a6d5db58dadd6 100644 (file)
@@ -92,6 +92,9 @@ Mixer_UI::Mixer_UI ()
        , _strip_width (Config->get_default_narrow_ms() ? Narrow : Wide)
        , ignore_reorder (false)
        , _following_editor_selection (false)
+        , _in_group_rebuild_or_clear (false)
+        , _route_deletion_in_progress (false)
+       , _maximised (false)
 {
        /* allow this window to become the key focus window */
        set_flags (CAN_FOCUS);
@@ -239,9 +242,6 @@ Mixer_UI::Mixer_UI ()
        list_hpane.show();
        group_display.show();
 
-       _in_group_rebuild_or_clear = false;
-       _maximised = false;
-
        MixerStrip::CatchDeletion.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::remove_strip, this, _1), gui_context());
 
         MonitorSection::setup_knob_images ();
@@ -420,6 +420,7 @@ Mixer_UI::remove_strip (MixerStrip* strip)
        
        for (ri = rows.begin(); ri != rows.end(); ++ri) {
                if ((*ri)[track_columns.strip] == strip) {
+                        PBD::Unwinder<bool> uw (_route_deletion_in_progress, true);
                        track_model->erase (ri);
                        break;
                }
@@ -997,9 +998,17 @@ Mixer_UI::track_list_delete (const Gtk::TreeModel::Path&)
 {
        /* this happens as the second step of a DnD within the treeview as well
           as when a row/route is actually deleted.
+           
+           if it was a deletion then we have to force a redisplay because
+           order keys may not have changed.
        */
+
        DEBUG_TRACE (DEBUG::OrderKeys, "mixer UI treeview row deleted\n");
        sync_order_keys_from_treeview ();
+
+        if (_route_deletion_in_progress) {
+                redisplay_track_list ();
+        }
 }
 
 void
index 693fd9dfa557b7848e0bc95899bf288d5723fbbf..e5d78f22182a79067aab8cffd736f11044732fad 100644 (file)
@@ -272,6 +272,7 @@ class Mixer_UI : public Gtk::Window, public PBD::ScopedConnectionList, public AR
            it during a session teardown.
        */
        bool _in_group_rebuild_or_clear;
+        bool _route_deletion_in_progress;
 
        void update_title ();
        MixerStrip* strip_by_x (int x);