From 28af0265b5867a4ad9bd35e2d98eadd7f1264693 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 26 Aug 2009 00:06:21 +0000 Subject: [PATCH] When a track is in "stacked" mode, allow regions to be moved to different layers by dragging and dropping. In stacked mode, the relayering by "recently added / moved etc. is higher" setting is ignored, and regions are put on the layer that they are dropped to, unless: 1. they are dropped so that they overlap another region on the same layer, in which case they are put on the layer above that one. 2. they are dropped such that they could be put on a lower layer with no audible difference, in which case they are put on the lower layer. git-svn-id: svn://localhost/ardour2/branches/3.0@5590 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/editor_drag.cc | 28 +++++++++++++++-------- gtk2_ardour/editor_drag.h | 2 +- gtk2_ardour/session_option_editor.cc | 2 +- gtk2_ardour/streamview.cc | 5 +++- libs/ardour/ardour/playlist.h | 13 +++++++++++ libs/ardour/ardour/region.h | 13 ++++++++++- libs/ardour/playlist.cc | 34 ++++++++++++++++++++++++---- libs/ardour/region.cc | 9 +++++++- 8 files changed, 88 insertions(+), 18 deletions(-) diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 701a0c7940..fcd859e83e 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -726,7 +726,7 @@ RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred) pair insert_result, frozen_insert_result; nframes64_t drag_delta; bool changed_tracks, changed_position; - map final; + map > final; RouteTimeAxisView* source_tv; if (!movement_occurred) { @@ -781,12 +781,13 @@ RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred) _editor->update_canvas_now (); /* make a list of where each region ended up */ - final = find_time_axis_views (); + final = find_time_axis_views_and_layers (); for (list::const_iterator i = _views.begin(); i != _views.end(); ) { RegionView* rv = (*i); - RouteTimeAxisView* dest_rtv = final[*i]; + RouteTimeAxisView* dest_rtv = final[*i].first; + layer_t dest_layer = final[*i].second; nframes64_t where; @@ -837,6 +838,10 @@ RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred) } to_playlist->add_region (new_region, where); + if (dest_rtv->view()->layer_display() == Stacked) { + new_region->set_layer (dest_layer); + new_region->set_pending_explicit_relayer (true); + } c.disconnect (); @@ -861,6 +866,11 @@ RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred) boost::shared_ptr playlist = dest_rtv->playlist(); + if (dest_rtv->view()->layer_display() == Stacked) { + rv->region()->set_layer (dest_layer); + rv->region()->set_pending_explicit_relayer (true); + } + insert_result = modified_playlists.insert (playlist); if (insert_result.second) { @@ -1214,10 +1224,10 @@ RegionInsertDrag::RegionInsertDrag (Editor* e, boost::shared_ptr r, Rout _dest_layer = _primary->region()->layer (); } -map -RegionMotionDrag::find_time_axis_views () +map > +RegionMotionDrag::find_time_axis_views_and_layers () { - map tav; + map > tav; for (list::const_iterator i = _views.begin(); i != _views.end(); ++i) { @@ -1227,7 +1237,7 @@ RegionMotionDrag::find_time_axis_views () iy1 += _editor->vertical_adjustment.get_value() - _editor->canvas_timebars_vsize; pair tv = _editor->trackview_by_y_position (iy1); - tav[*i] = dynamic_cast (tv.first); + tav[*i] = make_pair (dynamic_cast (tv.first), tv.second); } return tav; @@ -1239,9 +1249,9 @@ RegionInsertDrag::finished (GdkEvent* /*event*/, bool /*movement_occurred*/) { _editor->update_canvas_now (); - map final = find_time_axis_views (); + map > final = find_time_axis_views_and_layers (); - RouteTimeAxisView* dest_rtv = final[_primary]; + RouteTimeAxisView* dest_rtv = final[_primary].first; _primary->get_canvas_group()->reparent (*dest_rtv->view()->canvas_item()); _primary->get_canvas_group()->property_y() = 0; diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index 97e503f0d6..68b2624d11 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -186,7 +186,7 @@ protected: void copy_regions (GdkEvent *); bool y_movement_disallowed (int, int, int, TimeAxisViewSummary const &) const; - std::map find_time_axis_views (); + std::map > find_time_axis_views_and_layers (); double compute_x_delta (GdkEvent const *, nframes64_t *); bool compute_y_delta ( TimeAxisView const *, TimeAxisView*, int32_t, int32_t, TimeAxisViewSummary const &, diff --git a/gtk2_ardour/session_option_editor.cc b/gtk2_ardour/session_option_editor.cc index cbcb3ecb78..edb596c6cc 100644 --- a/gtk2_ardour/session_option_editor.cc +++ b/gtk2_ardour/session_option_editor.cc @@ -303,7 +303,7 @@ SessionOptionEditor::SessionOptionEditor (Session* s) ComboOption* lm = new ComboOption ( "layer-model", - _("Layering model"), + _("Layering model in overlaid mode"), mem_fun (*_session_config, &SessionConfiguration::get_layer_model), mem_fun (*_session_config, &SessionConfiguration::set_layer_model) ); diff --git a/gtk2_ardour/streamview.cc b/gtk2_ardour/streamview.cc index c68985ee77..fbd48ddbf2 100644 --- a/gtk2_ardour/streamview.cc +++ b/gtk2_ardour/streamview.cc @@ -351,10 +351,12 @@ StreamView::playlist_changed (boost::shared_ptr ds) /* update layers count and the y positions and heights of our regions */ _layers = ds->playlist()->top_layer() + 1; update_contents_height (); - update_coverage_frames (); + + ds->playlist()->set_explicit_relayering (_layer_display == Stacked); /* draw it */ + redisplay_diskstream (); /* catch changes */ @@ -571,6 +573,7 @@ StreamView::set_layer_display (LayerDisplay d) _layer_display = d; update_contents_height (); update_coverage_frames (); + _trackview.get_diskstream()->playlist()->set_explicit_relayering (_layer_display == Stacked); } void diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h index db928abab8..ffca22c725 100644 --- a/libs/ardour/ardour/playlist.h +++ b/libs/ardour/ardour/playlist.h @@ -159,6 +159,13 @@ class Playlist : public SessionObject, void drop_regions (); + bool explicit_relayering () const { + return _explicit_relayering; + } + void set_explicit_relayering (bool e) { + _explicit_relayering = e; + } + protected: friend class Session; @@ -215,6 +222,12 @@ class Playlist : public SessionObject, nframes_t freeze_length; bool auto_partition; + /** true if relayering should be done using region's current layers and their `pending explicit relayer' + * flags; otherwise false if relayering should be done using the layer-model (most recently moved etc.) + * Explicit relayering is used by tracks in stacked regionview mode. + */ + bool _explicit_relayering; + void init (bool hide); bool holding_state () const { diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h index 6a51ae75f5..c28e70bb5f 100644 --- a/libs/ardour/ardour/region.h +++ b/libs/ardour/ardour/region.h @@ -265,7 +265,15 @@ class Region return 0; } - void invalidate_transients (); + void invalidate_transients (); + + void set_pending_explicit_relayer (bool p) { + _pending_explicit_relayer = p; + } + + bool pending_explicit_relayer () const { + return _pending_explicit_relayer; + } protected: friend class RegionFactory; @@ -331,6 +339,9 @@ class Region SourceList _sources; /** Used when timefx are applied, so we can always use the original source */ SourceList _master_sources; + + /** true if this region has had its layer explicitly set since the playlist last relayered */ + bool _pending_explicit_relayer; boost::weak_ptr _playlist; diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index 4202b7052f..d63b643d2d 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -60,6 +60,23 @@ struct RegionSortByLayer { } }; +struct RegionSortByLayerWithPending { + bool operator () (boost::shared_ptr a, boost::shared_ptr b) { + + double p = a->layer (); + if (a->pending_explicit_relayer()) { + p += 0.5; + } + + double q = b->layer (); + if (b->pending_explicit_relayer()) { + q += 0.5; + } + + return p < q; + } +}; + struct RegionSortByPosition { bool operator() (boost::shared_ptr a, boost::shared_ptr b) { return a->position() < b->position(); @@ -246,6 +263,7 @@ Playlist::init (bool hide) _frozen = false; layer_op_counter = 0; freeze_length = 0; + _explicit_relayering = false; Modified.connect (mem_fun (*this, &Playlist::mark_session_dirty)); } @@ -1981,15 +1999,23 @@ Playlist::relayer () RegionList copy = regions; - /* sort according to the model */ + /* sort according to the model and the layering mode that we're in */ - if (_session.config.get_layer_model() == MoveAddHigher || _session.config.get_layer_model() == AddHigher) { - RegionSortByLastLayerOp cmp; - copy.sort (cmp); + if (_explicit_relayering) { + + copy.sort (RegionSortByLayerWithPending ()); + + } else if (_session.config.get_layer_model() == MoveAddHigher || _session.config.get_layer_model() == AddHigher) { + + copy.sort (RegionSortByLastLayerOp ()); + } for (RegionList::iterator i = copy.begin(); i != copy.end(); ++i) { + /* reset the pending explicit relayer flag for every region, now that we're relayering */ + (*i)->set_pending_explicit_relayer (false); + /* find the time divisions that this region covers */ int const start_division = floor ( ((*i)->position() - start) / division_size); int end_division = floor ( ((*i)->position() + (*i)->length() - start) / division_size ); diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index 1f90a0761b..0e0df08284 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -78,6 +78,7 @@ Region::Region (Session& s, nframes_t start, nframes_t length, const string& nam , _read_data_count(0) , _pending_changed(Change (0)) , _last_layer_op(0) + , _pending_explicit_relayer (false) { /* no sources at this point */ } @@ -104,7 +105,7 @@ Region::Region (boost::shared_ptr src, nframes_t start, nframes_t length , _read_data_count(0) , _pending_changed(Change (0)) , _last_layer_op(0) - + , _pending_explicit_relayer (false) { _sources.push_back (src); _master_sources.push_back (src); @@ -136,6 +137,7 @@ Region::Region (const SourceList& srcs, nframes_t start, nframes_t length, const , _read_data_count(0) , _pending_changed(Change (0)) , _last_layer_op(0) + , _pending_explicit_relayer (false) { use_sources (srcs); assert(_sources.size() > 0); @@ -145,6 +147,7 @@ Region::Region (const SourceList& srcs, nframes_t start, nframes_t length, const Region::Region (boost::shared_ptr other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags) : SessionObject(other->session(), name) , _type (other->data_type()) + , _pending_explicit_relayer (false) { _start = other->_start + offset; @@ -184,6 +187,7 @@ Region::Region (boost::shared_ptr other, nframes_t offset, nframes Region::Region (boost::shared_ptr other, nframes_t length, const string& name, layer_t layer, Flag flags) : SessionObject(other->session(), name) , _type (other->data_type()) + , _pending_explicit_relayer (false) { /* create a new Region exactly like another but starting at 0 in its sources */ @@ -256,6 +260,7 @@ Region::Region (boost::shared_ptr other) , _read_data_count(0) , _pending_changed(Change(0)) , _last_layer_op(other->_last_layer_op) + , _pending_explicit_relayer (false) { _flags = Flag (_flags | DoNotSendPropertyChanges); @@ -289,6 +294,7 @@ Region::Region (const SourceList& srcs, const XMLNode& node) , _read_data_count(0) , _pending_changed(Change(0)) , _last_layer_op(0) + , _pending_explicit_relayer (false) { use_sources (srcs); @@ -318,6 +324,7 @@ Region::Region (boost::shared_ptr src, const XMLNode& node) , _read_data_count(0) , _pending_changed(Change(0)) , _last_layer_op(0) + , _pending_explicit_relayer (false) { _sources.push_back (src);