Make editor independent of EditorRoutes

This commit is contained in:
Robin Gareus 2022-01-25 15:59:38 +01:00
parent a274c1473a
commit 5b3eacd421
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
5 changed files with 245 additions and 30 deletions

View File

@ -353,6 +353,8 @@ Editor::Editor ()
, edit_controls_left_menu (0)
, edit_controls_right_menu (0)
, visual_change_queued(false)
, _tvl_no_redisplay(false)
, _tvl_redisplay_on_resume(false)
, _last_update_time (0)
, _err_screen_engine (0)
, cut_buffer_start (0)
@ -1337,7 +1339,7 @@ Editor::set_session (Session *t)
_regions->set_session (_session);
_sources->set_session (_session);
_snapshots->set_session (_session);
_routes->set_session (_session);
//_routes->set_session (_session); // temp disabled for EditorRoutes update
_locations->set_session (_session);
_properties_box->set_session (_session);
@ -1353,6 +1355,7 @@ Editor::set_session (Session *t)
sfbrowser->set_session (_session);
}
initial_display ();
compute_fixed_ruler_scale ();
/* Make sure we have auto loop and auto punch ranges */
@ -4762,7 +4765,7 @@ Editor::use_visual_state (VisualState& vs)
}
}
_routes->update_visibility ();
// TODO push state to PresentationInfo, force update ?
}
/** This is the core function that controls the zoom level of the canvas. It is called
@ -5410,7 +5413,7 @@ Editor::first_idle ()
selection->set (rs);
/* first idle adds route children (automation tracks), so we need to redisplay here */
_routes->redisplay ();
redisplay_track_views ();
delete dialog;
@ -5586,20 +5589,35 @@ Editor::axis_views_from_routes (boost::shared_ptr<RouteList> r) const
void
Editor::suspend_route_redisplay ()
{
if (_routes) {
_routes->suspend_redisplay();
_tvl_no_redisplay = true;
}
void
Editor::queue_redisplay_track_views ()
{
if (!_tvl_redisplay_connection.connected ()) {
_tvl_redisplay_connection = Glib::signal_idle().connect (sigc::mem_fun (*this, &Editor::redisplay_track_views));
}
}
void
Editor::resume_route_redisplay ()
{
if (_routes) {
_routes->redisplay(); // queue redisplay
_routes->resume_redisplay();
_tvl_no_redisplay = false;
if (_tvl_redisplay_on_resume) {
queue_redisplay_track_views ();
}
}
void
Editor::initial_display ()
{
DisplaySuspender ds;
StripableList s;
_session->get_stripables (s);
add_stripables (s);
}
void
Editor::add_vcas (VCAList& vlist)
{
@ -5627,10 +5645,10 @@ Editor::add_routes (RouteList& rlist)
void
Editor::add_stripables (StripableList& sl)
{
list<TimeAxisView*> new_views;
boost::shared_ptr<VCA> v;
boost::shared_ptr<Route> r;
TrackViewList new_selection;
bool changed = false;
bool from_scratch = (track_views.size() == 0);
sl.sort (Stripable::Sorter());
@ -5645,7 +5663,10 @@ Editor::add_stripables (StripableList& sl)
VCATimeAxisView* vtv = new VCATimeAxisView (*this, _session, *_track_canvas);
vtv->set_vca (v);
new_views.push_back (vtv);
track_views.push_back (vtv);
(*s)->gui_changed.connect (*this, invalidator (*this), boost::bind (&Editor::handle_gui_changes, this, _1, _2), gui_context());
changed = true;
} else if ((r = boost::dynamic_pointer_cast<Route> (*s)) != 0) {
@ -5666,7 +5687,6 @@ Editor::add_stripables (StripableList& sl)
throw unknown_type();
}
new_views.push_back (rtv);
track_views.push_back (rtv);
new_selection.push_back (rtv);
@ -5674,12 +5694,13 @@ Editor::add_stripables (StripableList& sl)
rtv->view()->RegionViewAdded.connect (sigc::mem_fun (*this, &Editor::region_view_added));
rtv->view()->RegionViewRemoved.connect (sigc::mem_fun (*this, &Editor::region_view_removed));
(*s)->gui_changed.connect (*this, invalidator (*this), boost::bind (&Editor::handle_gui_changes, this, _1, _2), gui_context());
changed = true;
}
}
if (new_views.size() > 0) {
_routes->time_axis_views_added (new_views);
//_summary->routes_added (new_selection); /* XXX requires RouteTimeAxisViewList */
if (changed) {
queue_redisplay_track_views ();
}
/* note: !new_selection.empty() means that we got some routes rather
@ -5719,8 +5740,6 @@ Editor::timeaxisview_deleted (TimeAxisView *tv)
RouteTimeAxisView* rtav = dynamic_cast<RouteTimeAxisView*> (tv);
_routes->route_removed (tv);
TimeAxisView::Children c = tv->get_child_list ();
for (TimeAxisView::Children::const_iterator i = c.begin(); i != c.end(); ++i) {
if (entered_track == i->get()) {
@ -5806,6 +5825,9 @@ Editor::hide_track_in_display (TimeAxisView* tv, bool apply_to_selection)
}
if (rtv) {
rtv->route()->presentation_info().set_hidden (true);
/* TODO also handle Routegroups IFF (rg->is_hidden() && !rg->is_selection())
* selection currently unconditionally hides due to above if() clause :(
*/
}
}
}
@ -5819,21 +5841,92 @@ Editor::show_track_in_display (TimeAxisView* tv, bool move_into_view)
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (tv);
if (rtv) {
rtv->route()->presentation_info().set_hidden (false);
#if 0 // TODO see above
RouteGroup* rg = rtv->route ()->route_group ();
if (rg && rg->is_active () && rg->is_hidden () && !rg->is_select ()) {
boost::shared_ptr<RouteList> rl (rg->route_list ());
for (RouteList::const_iterator i = rl->begin(); i != rl->end(); ++i) {
(*i)->presentation_info().set_hidden (false);
}
}
#endif
}
if (move_into_view) {
ensure_time_axis_view_is_visible (*tv, false);
}
}
bool
Editor::sync_track_view_list_and_routes ()
struct TrackViewStripableSorter
{
track_views = TrackViewList (_routes->views ());
bool operator() (const TimeAxisView* tav_a, const TimeAxisView *tav_b)
{
StripableTimeAxisView const* stav_a = dynamic_cast<StripableTimeAxisView const*>(tav_a);
StripableTimeAxisView const* stav_b = dynamic_cast<StripableTimeAxisView const*>(tav_b);
assert (stav_a && stav_b);
boost::shared_ptr<ARDOUR::Stripable> const& a = stav_a->stripable ();
boost::shared_ptr<ARDOUR::Stripable> const& b = stav_b->stripable ();
return ARDOUR::Stripable::Sorter () (a, b);
}
};
bool
Editor::redisplay_track_views ()
{
if (!_session || _session->deletion_in_progress()) {
return false;
}
if (_tvl_no_redisplay) {
_tvl_redisplay_on_resume = true;
return false;
}
TrackViewStripableSorter cmp;
track_views.sort (cmp);
uint32_t position;
TrackViewList::const_iterator i;
/* n will be the count of tracks plus children (updated by TimeAxisView::show_at),
* so we will use that to know where to put things.
*/
int n;
for (n = 0, position = 0, i = track_views.begin(); i != track_views.end(); ++i) {
TimeAxisView *tv = (*i);
if (tv->marked_for_display ()) {
position += tv->show_at (position, n, &edit_controls_vbox);
} else {
tv->hide ();
}
n++;
}
reset_controls_layout_height (position);
reset_controls_layout_width ();
_full_canvas_height = position;
if ((vertical_adjustment.get_value() + _visible_canvas_height) > vertical_adjustment.get_upper()) {
/*
* We're increasing the size of the canvas while the bottom is visible.
* We scroll down to keep in step with the controls layout.
*/
vertical_adjustment.set_value (_full_canvas_height - _visible_canvas_height);
}
_summary->set_background_dirty();
_group_tabs->set_dirty ();
return false; // do not call again (until needed)
return false;
}
void
Editor::handle_gui_changes (string const & what, void*)
{
if (what == "track_height" || what == "visible_tracks") {
queue_redisplay_track_views ();
}
}
void

View File

@ -868,6 +868,7 @@ private:
void popup_note_context_menu (ArdourCanvas::Item*, GdkEvent*);
Gtk::Menu _note_context_menu;
void initial_display ();
void add_stripables (ARDOUR::StripableList&);
void add_routes (ARDOUR::RouteList&);
void timeaxisview_deleted (TimeAxisView*);
@ -1222,6 +1223,7 @@ private:
/* track views */
TrackViewList track_views;
std::pair<TimeAxisView*, double> trackview_by_y_position (double, bool trackview_relative_offset = true) const;
AxisView* axis_view_by_stripable (boost::shared_ptr<ARDOUR::Stripable>) const;
@ -1233,6 +1235,14 @@ private:
TrackViewList get_tracks_for_range_action () const;
Gtk::VBox list_vpacker;
void queue_redisplay_track_views ();
bool redisplay_track_views ();
bool _tvl_no_redisplay;
bool _tvl_redisplay_on_resume;
sigc::connection _tvl_redisplay_connection;
sigc::connection super_rapid_screen_update_connection;
void center_screen_internal (samplepos_t, float);
@ -1533,6 +1543,7 @@ private:
void scroll_forward (float pages=0.8f);
void scroll_tracks_down ();
void scroll_tracks_up ();
void move_selected_tracks (bool);
void set_mark ();
void clear_markers ();
void clear_xrun_markers ();
@ -1995,6 +2006,7 @@ private:
void track_selection_changed ();
void update_time_selection_display ();
void presentation_info_changed (PBD::PropertyChange const &);
void handle_gui_changes (std::string const&, void*);
void region_selection_changed ();
void catch_up_on_midi_selection ();
sigc::connection editor_regions_selection_changed_connection;
@ -2065,10 +2077,6 @@ private:
Glib::RefPtr<Gtk::TreeSelection> route_display_selection;
bool sync_track_view_list_and_routes ();
Gtk::VBox list_vpacker;
/* autoscrolling */
sigc::connection autoscroll_connection;

View File

@ -327,9 +327,9 @@ Editor::register_actions ()
reg_sens (editor_actions, "zoom_5_min", _("Zoom to 5 min"), sigc::bind (sigc::mem_fun(*this, &Editor::set_zoom_preset), 5 * 60 * 1000));
reg_sens (editor_actions, "zoom_10_min", _("Zoom to 10 min"), sigc::bind (sigc::mem_fun(*this, &Editor::set_zoom_preset), 10 * 60 * 1000));
act = reg_sens (editor_actions, "move-selected-tracks-up", _("Move Selected Tracks Up"), sigc::bind (sigc::mem_fun(*_routes, &EditorRoutes::move_selected_tracks), true));
act = reg_sens (editor_actions, "move-selected-tracks-up", _("Move Selected Tracks Up"), sigc::bind (sigc::mem_fun(*this, &Editor::move_selected_tracks), true));
ActionManager::stripable_selection_sensitive_actions.push_back (act);
act = reg_sens (editor_actions, "move-selected-tracks-down", _("Move Selected Tracks Down"), sigc::bind (sigc::mem_fun(*_routes, &EditorRoutes::move_selected_tracks), false));
act = reg_sens (editor_actions, "move-selected-tracks-down", _("Move Selected Tracks Down"), sigc::bind (sigc::mem_fun(*this, &Editor::move_selected_tracks), false));
ActionManager::stripable_selection_sensitive_actions.push_back (act);
act = reg_sens (editor_actions, "scroll-tracks-up", _("Scroll Tracks Up"), sigc::mem_fun(*this, &Editor::scroll_tracks_up));

View File

@ -618,7 +618,7 @@ EditorRoutes::redisplay_real ()
* we can't do this here, because we could mess up something that is traversing
* the track order and has caused a redisplay of the list.
*/
Glib::signal_idle().connect (sigc::mem_fun (*_editor, &Editor::sync_track_view_list_and_routes));
//Glib::signal_idle().connect (sigc::mem_fun (*_editor, &Editor::sync_track_view_list_and_routes));
_editor->reset_controls_layout_height (position);
_editor->reset_controls_layout_width ();

View File

@ -1234,16 +1234,15 @@ Editor::presentation_info_changed (PropertyChange const & what_changed)
}
}
/* STEP 4: update EditorRoutes treeview */
/* STEP 4: update Editor::track_views */
PropertyChange soh;
soh.add (Properties::selected);
soh.add (Properties::order);
soh.add (Properties::hidden);
if (what_changed.contains (soh)) {
_routes->sync_treeview_from_presentation_info (what_changed);
queue_redisplay_track_views ();
}
}
@ -2349,3 +2348,118 @@ Editor::catch_up_on_midi_selection ()
selection->set (regions);
}
}
struct ViewStripable {
TimeAxisView* tav;
boost::shared_ptr<Stripable> stripable;
ViewStripable (TimeAxisView* t, boost::shared_ptr<Stripable> s)
: tav (t), stripable (s) {}
};
void
Editor::move_selected_tracks (bool up)
{
TimeAxisView* scroll_to = 0;
StripableList sl;
_session->get_stripables (sl);
if (sl.size() < 2) {
/* nope */
return;
}
sl.sort (Stripable::Sorter());
std::list<ViewStripable> view_stripables;
/* build a list that includes time axis view information */
for (StripableList::const_iterator sli = sl.begin(); sli != sl.end(); ++sli) {
TimeAxisView* tv = time_axis_view_from_stripable (*sli);
view_stripables.push_back (ViewStripable (tv, *sli));
}
/* for each selected stripable, move it above or below the adjacent
* stripable that has a time-axis view representation here. If there's
* no such representation, then
*/
list<ViewStripable>::iterator unselected_neighbour;
list<ViewStripable>::iterator vsi;
{
PresentationInfo::ChangeSuspender cs;
if (up) {
unselected_neighbour = view_stripables.end ();
vsi = view_stripables.begin();
while (vsi != view_stripables.end()) {
if (vsi->stripable->is_selected()) {
if (unselected_neighbour != view_stripables.end()) {
PresentationInfo::order_t unselected_neighbour_order = unselected_neighbour->stripable->presentation_info().order();
PresentationInfo::order_t my_order = vsi->stripable->presentation_info().order();
unselected_neighbour->stripable->set_presentation_order (my_order);
vsi->stripable->set_presentation_order (unselected_neighbour_order);
if (!scroll_to) {
scroll_to = vsi->tav;
}
}
} else {
if (vsi->tav) {
unselected_neighbour = vsi;
}
}
++vsi;
}
} else {
unselected_neighbour = view_stripables.end();
vsi = unselected_neighbour;
do {
--vsi;
if (vsi->stripable->is_selected()) {
if (unselected_neighbour != view_stripables.end()) {
PresentationInfo::order_t unselected_neighbour_order = unselected_neighbour->stripable->presentation_info().order();
PresentationInfo::order_t my_order = vsi->stripable->presentation_info().order();
unselected_neighbour->stripable->set_presentation_order (my_order);
vsi->stripable->set_presentation_order (unselected_neighbour_order);
if (!scroll_to) {
scroll_to = vsi->tav;
}
}
} else {
if (vsi->tav) {
unselected_neighbour = vsi;
}
}
} while (vsi != view_stripables.begin());
}
}
if (scroll_to) {
ensure_time_axis_view_is_visible (*scroll_to, false);
}
}