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);