From: Carl Hetherington Date: Wed, 23 Jun 2010 01:51:55 +0000 (+0000) Subject: Update locations GUI more efficiently by avoiding a rebuild when a location is remove... X-Git-Tag: 3.0-alpha5~1926 X-Git-Url: https://main.carlh.net/gitweb/?a=commitdiff_plain;h=cac03dbeb6ebdcd406385dd14a746cb8c51dd5f8;p=ardour.git Update locations GUI more efficiently by avoiding a rebuild when a location is removed. Fixes #3263. git-svn-id: svn://localhost/ardour2/branches/3.0@7290 d708f5d6-7413-0410-9779-e7cbd77b26cf --- diff --git a/gtk2_ardour/location_ui.cc b/gtk2_ardour/location_ui.cc index 5a2e11038c..9613aaccb5 100644 --- a/gtk2_ardour/location_ui.cc +++ b/gtk2_ardour/location_ui.cc @@ -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 (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() { diff --git a/gtk2_ardour/location_ui.h b/gtk2_ardour/location_ui.h index ea6b80f3a4..c3f07cc84d 100644 --- a/gtk2_ardour/location_ui.h +++ b/gtk2_ardour/location_ui.h @@ -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&); }; diff --git a/libs/ardour/ardour/location.h b/libs/ardour/ardour/location.h index f23d2e382a..7d3b0ac1a9 100644 --- a/libs/ardour/ardour/location.h +++ b/libs/ardour/ardour/location.h @@ -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); + Location* first_location_before (nframes64_t, bool include_special_ranges = false); + Location* first_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 current_changed; - PBD::Signal0 changed; + /** something changed about the location list; the parameter gives some idea as to what */ + PBD::Signal1 changed; + /** a location has been added to the end of the list */ PBD::Signal1 added; PBD::Signal1 removed; PBD::Signal1 StateChanged; diff --git a/libs/ardour/location.cc b/libs/ardour/location.cc index 7202e1ef03..93b6b5c5fa 100644 --- a/libs/ardour/location.cc +++ b/libs/ardour/location.cc @@ -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; }