Update locations GUI more efficiently by avoiding a rebuild when a location is remove...
authorCarl Hetherington <carl@carlh.net>
Wed, 23 Jun 2010 01:51:55 +0000 (01:51 +0000)
committerCarl Hetherington <carl@carlh.net>
Wed, 23 Jun 2010 01:51:55 +0000 (01:51 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@7290 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/location_ui.cc
gtk2_ardour/location_ui.h
libs/ardour/ardour/location.h
libs/ardour/location.cc

index 5a2e11038c482c87c8a4e88c5baecd945b3fe509..9613aaccb50d193e42e063479e8204daf9d3a0e3 100644 (file)
@@ -452,9 +452,11 @@ LocationEditRow::hide_toggled ()
 void
 LocationEditRow::remove_button_pressed ()
 {
-       if (!location) return;
+       if (!location) {
+               return;
+       }
 
-       remove_requested(location); /*  EMIT_SIGNAL */
+       remove_requested (location); /* EMIT_SIGNAL */
 }
 
 
@@ -708,11 +710,9 @@ LocationUI::location_added (Location* location)
 
        if (location->is_auto_punch()) {
                punch_edit_row.set_location(location);
-       }
-       else if (location->is_auto_loop()) {
+       } else if (location->is_auto_loop()) {
                loop_edit_row.set_location(location);
-       }
-       else {
+       } else {
                refresh_location_list ();
        }
 }
@@ -724,12 +724,17 @@ LocationUI::location_removed (Location* location)
 
        if (location->is_auto_punch()) {
                punch_edit_row.set_location(0);
-       }
-       else if (location->is_auto_loop()) {
+       } else if (location->is_auto_loop()) {
                loop_edit_row.set_location(0);
-       }
-       else {
-               refresh_location_list ();
+       } else if (location->is_range_marker() || location->is_mark()) {
+               Box_Helpers::BoxList& children = location->is_range_marker() ? range_rows.children () : location_rows.children ();
+               for (Box_Helpers::BoxList::iterator i = children.begin(); i != children.end(); ++i) {
+                       LocationEditRow* r = dynamic_cast<LocationEditRow*> (i->get_widget());
+                       if (r && r->get_location() == location) {
+                               children.erase (i);
+                               break;
+                       }
+               }
        }
 }
 
@@ -743,7 +748,6 @@ void
 LocationUI::map_locations (Locations::LocationList& locations)
 {
        Locations::LocationList::iterator i;
-       Location* location;
        gint n;
        int mark_n = 0;
        Locations::LocationList temp = locations;
@@ -752,38 +756,32 @@ LocationUI::map_locations (Locations::LocationList& locations)
        temp.sort (cmp);
        locations = temp;
 
-       Box_Helpers::BoxList & loc_children = location_rows.children();
-       Box_Helpers::BoxList & range_children = range_rows.children();
-       LocationEditRow * erow;
-
        for (n = 0, i = locations.begin(); i != locations.end(); ++n, ++i) {
 
-               location = *i;
+               Location* location = *i;
 
                if (location->is_mark()) {
-                       mark_n++;
-                       erow = manage (new LocationEditRow(_session, location, mark_n));
+                       LocationEditRow* erow = manage (new LocationEditRow (_session, location, mark_n));
                        erow->remove_requested.connect (sigc::mem_fun(*this, &LocationUI::location_remove_requested));
-                       erow->redraw_ranges.connect (sigc::mem_fun(*this, &LocationUI::location_redraw_ranges));
+                       erow->redraw_ranges.connect (sigc::mem_fun(*this, &LocationUI::location_redraw_ranges));
+                       Box_Helpers::BoxList & loc_children = location_rows.children();
                        loc_children.push_back(Box_Helpers::Element(*erow, PACK_SHRINK, 1, PACK_START));
                        if (location == newest_location) {
                                newest_location = 0;
                                erow->focus_name();
                        }
-               }
-               else if (location->is_auto_punch()) {
+               } else if (location->is_auto_punch()) {
                        punch_edit_row.set_session (_session);
                        punch_edit_row.set_location (location);
                        punch_edit_row.show_all();
-               }
-               else if (location->is_auto_loop()) {
+               } else if (location->is_auto_loop()) {
                        loop_edit_row.set_session (_session);
                        loop_edit_row.set_location (location);
                        loop_edit_row.show_all();
-               }
-               else {
-                       erow = manage (new LocationEditRow(_session, location));
+               } else {
+                       LocationEditRow* erow = manage (new LocationEditRow(_session, location));
                        erow->remove_requested.connect (sigc::mem_fun(*this, &LocationUI::location_remove_requested));
+                       Box_Helpers::BoxList & range_children = range_rows.children();
                        range_children.push_back(Box_Helpers::Element(*erow,  PACK_SHRINK, 1, PACK_START));
                }
        }
@@ -859,7 +857,7 @@ LocationUI::set_session(ARDOUR::Session* s)
        SessionHandlePtr::set_session (s);
 
        if (_session) {
-               _session->locations()->changed.connect (_session_connections, invalidator (*this), boost::bind (&LocationUI::refresh_location_list, this), gui_context());
+               _session->locations()->changed.connect (_session_connections, invalidator (*this), boost::bind (&LocationUI::locations_changed, this, _1), gui_context());
                _session->locations()->StateChanged.connect (_session_connections, invalidator (*this), boost::bind (&LocationUI::refresh_location_list, this), gui_context());
                _session->locations()->added.connect (_session_connections, invalidator (*this), ui_bind (&LocationUI::location_added, this, _1), gui_context());
                _session->locations()->removed.connect (_session_connections, invalidator (*this), ui_bind (&LocationUI::location_removed, this, _1), gui_context());
@@ -871,6 +869,17 @@ LocationUI::set_session(ARDOUR::Session* s)
        refresh_location_list ();
 }
 
+void
+LocationUI::locations_changed (Locations::Change c)
+{
+       /* removal is signalled by both a removed and a changed signal emission from Locations,
+          so we don't need to refresh the list on a removal
+       */
+       if (c != Locations::REMOVAL) {
+               refresh_location_list ();
+       }
+}
+
 void
 LocationUI::session_going_away()
 {
index ea6b80f3a4f562396c8840e34c49e039dead60bc..c3f07cc84d980c6298bf414b22be420e7e920328 100644 (file)
@@ -186,6 +186,7 @@ class LocationUI : public Gtk::HBox, public ARDOUR::SessionHandlePtr
 
        void location_removed (ARDOUR::Location *);
        void location_added (ARDOUR::Location *);
+       void locations_changed (ARDOUR::Locations::Change);
        void map_locations (ARDOUR::Locations::LocationList&);
 };
 
index f23d2e382a272bb7b8a6f82533f1875b046136c9..7d3b0ac1a9ea003bcced6eaf41e8977500b67471 100644 (file)
@@ -163,15 +163,23 @@ class Locations : public PBD::StatefulDestructible
        int set_current (Location *, bool want_lock = true);
        Location *current () const { return current_location; }
 
-       Location *first_location_before (nframes64_t, bool include_special_ranges = false);
-       Location *first_location_after (nframes64_t, bool include_special_ranges = false);
+       Locationfirst_location_before (nframes64_t, bool include_special_ranges = false);
+       Locationfirst_location_after (nframes64_t, bool include_special_ranges = false);
 
        void marks_either_side (nframes64_t const, nframes64_t &, nframes64_t &) const;
 
        void find_all_between (nframes64_t start, nframes64_t, LocationList&, Location::Flags);
 
+       enum Change {
+               ADDITION, ///< a location was added, but nothing else changed
+               REMOVAL, ///< a location was removed, but nothing else changed
+               OTHER ///< something more complicated happened
+       };
+
        PBD::Signal1<void,Location*> current_changed;
-       PBD::Signal0<void>           changed;
+       /** something changed about the location list; the parameter gives some idea as to what */
+       PBD::Signal1<void,Change>    changed;
+       /** a location has been added to the end of the list */
        PBD::Signal1<void,Location*> added;
        PBD::Signal1<void,Location*> removed;
        PBD::Signal1<void,const PBD::PropertyChange&>    StateChanged;
index 7202e1ef035def7603447ef8fe9ca5630ac9887e..93b6b5c5fa1591f692e77bdf6f6545e2382c8f6c 100644 (file)
@@ -492,7 +492,7 @@ Locations::clear ()
                current_location = 0;
        }
 
-       changed (); /* EMIT SIGNAL */
+       changed (OTHER); /* EMIT SIGNAL */
        current_changed (0); /* EMIT SIGNAL */
 }
 
@@ -515,7 +515,7 @@ Locations::clear_markers ()
                }
        }
 
-       changed (); /* EMIT SIGNAL */
+       changed (OTHER); /* EMIT SIGNAL */
 }
 
 void
@@ -541,7 +541,7 @@ Locations::clear_ranges ()
                current_location = 0;
        }
 
-       changed (); /* EMIT SIGNAL */
+       changed (OTHER); /* EMIT SIGNAL */
        current_changed (0); /* EMIT SIGNAL */
 }
 
@@ -568,7 +568,6 @@ Locations::add (Location *loc, bool make_current)
 
 void
 Locations::remove (Location *loc)
-
 {
        bool was_removed = false;
        bool was_current = false;
@@ -602,14 +601,14 @@ Locations::remove (Location *loc)
                         current_changed (0); /* EMIT SIGNAL */
                }
 
-               changed (); /* EMIT_SIGNAL */
+               changed (REMOVAL); /* EMIT_SIGNAL */
        }
 }
 
 void
 Locations::location_changed (Location* /*loc*/)
 {
-       changed (); /* EMIT SIGNAL */
+       changed (OTHER); /* EMIT SIGNAL */
 }
 
 XMLNode&
@@ -701,7 +700,7 @@ Locations::set_state (const XMLNode& node, int version)
                }
        }
 
-       changed (); /* EMIT SIGNAL */
+       changed (OTHER); /* EMIT SIGNAL */
 
        return 0;
 }