13
0

Reduce mixer redraws, and fix scrolling to newly added tracks

PresentationInfo::Change (Properties::selected) is emitted and
handled before Mixer_UI::add_routes() is called. At that point
in time the MixerStrip(s) to be selected may not exist.
Visual selection state was lost.

Furthermore move_stripable_into_view() calling translate_coordinates()
only works after GTK has completed the resize operation.
This lead to the mixer scrolling back to the left edge when creating
new tracks.

Also each selection change caused all tracks to be re-packed.
Now redisplay_track_list() is only called if visibility or order
changes. This signficanly improves performance with large sessions.
This commit is contained in:
Robin Gareus 2022-06-15 02:24:03 +02:00
parent cb2e51808d
commit 5d10fd84eb
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04

View File

@ -677,6 +677,7 @@ Mixer_UI::add_stripables (StripableList& slist)
} }
strip = new MixerStrip (*this, _session, route); strip = new MixerStrip (*this, _session, route);
strip->set_selected (route->is_selected ());
strips.push_back (strip); strips.push_back (strip);
UIConfiguration::instance().get_default_narrow_ms() ? _strip_width = Narrow : _strip_width = Wide; UIConfiguration::instance().get_default_narrow_ms() ? _strip_width = Narrow : _strip_width = Wide;
@ -716,14 +717,20 @@ Mixer_UI::add_stripables (StripableList& slist)
track_display.set_model (track_model); track_display.set_model (track_model);
/* catch up on selection state, which we left to the editor to set */
sync_treeview_from_presentation_info (PropertyChange (Properties::selected));
if (!from_scratch) { if (!from_scratch) {
sync_presentation_info_from_treeview (); sync_presentation_info_from_treeview ();
} }
redisplay_track_list (); redisplay_track_list ();
if (!from_scratch) {
/* Mixer_UI::move_stripable_into_view() can only correctly calculate
* the scroll offset after the layout was updated.
* We update update after the resize operation (+10), but before drawing (+20)
* https://docs.gtk.org/glib/const.PRIORITY_HIGH_IDLE.html
*/
Glib::signal_idle().connect (sigc::bind_return (sigc::bind (sigc::mem_fun (*this, &Mixer_UI::sync_treeview_from_presentation_info), PropertyChange (Properties::selected)), false), G_PRIORITY_HIGH_IDLE + 15);
}
} }
void void
@ -891,44 +898,49 @@ Mixer_UI::sync_treeview_from_presentation_info (PropertyChange const & what_chan
* order for the GUI, so reorder the treeview model to match it. * order for the GUI, so reorder the treeview model to match it.
*/ */
vector<int> neworder; if (what_changed.contains (Properties::order)) {
TreeModel::Children rows = track_model->children(); vector<int> neworder;
uint32_t old_order = 0; TreeModel::Children rows = track_model->children();
bool changed = false; uint32_t old_order = 0;
bool changed = false;
if (rows.empty()) { if (rows.empty()) {
return; return;
} }
TreeOrderKeys sorted; TreeOrderKeys sorted;
for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri, ++old_order) { for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri, ++old_order) {
boost::shared_ptr<Stripable> stripable = (*ri)[stripable_columns.stripable]; boost::shared_ptr<Stripable> stripable = (*ri)[stripable_columns.stripable];
sorted.push_back (TreeOrderKey (old_order, stripable)); sorted.push_back (TreeOrderKey (old_order, stripable));
} }
TreeOrderKeySorter cmp; TreeOrderKeySorter cmp;
sort (sorted.begin(), sorted.end(), cmp); sort (sorted.begin(), sorted.end(), cmp);
neworder.assign (sorted.size(), 0); neworder.assign (sorted.size(), 0);
uint32_t n = 0; uint32_t n = 0;
for (TreeOrderKeys::iterator sr = sorted.begin(); sr != sorted.end(); ++sr, ++n) { for (TreeOrderKeys::iterator sr = sorted.begin(); sr != sorted.end(); ++sr, ++n) {
neworder[n] = sr->old_display_order; neworder[n] = sr->old_display_order;
if (sr->old_display_order != n) { if (sr->old_display_order != n) {
changed = true; changed = true;
}
}
if (changed) {
Unwinder<bool> uw (ignore_track_reorder, true);
track_model->reorder (neworder);
} }
} }
if (changed) { if (what_changed.contains (Properties::order) || what_changed.contains (Properties::hidden)) {
Unwinder<bool> uw (ignore_track_reorder, true); redisplay_track_list ();
track_model->reorder (neworder);
} }
if (what_changed.contains (Properties::selected)) { if (what_changed.contains (Properties::selected)) {
PresentationInfo::ChangeSuspender cs; PresentationInfo::ChangeSuspender cs;
for (list<MixerStrip *>::const_iterator i = strips.begin(); i != strips.end(); ++i) { for (list<MixerStrip *>::const_iterator i = strips.begin(); i != strips.end(); ++i) {
@ -958,8 +970,6 @@ Mixer_UI::sync_treeview_from_presentation_info (PropertyChange const & what_chan
} }
} }
} }
redisplay_track_list ();
} }
void void