diff options
Diffstat (limited to 'gtk2_ardour')
-rw-r--r-- | gtk2_ardour/audio_streamview.cc | 19 | ||||
-rw-r--r-- | gtk2_ardour/audio_time_axis.cc | 12 | ||||
-rw-r--r-- | gtk2_ardour/editor.cc | 4 | ||||
-rw-r--r-- | gtk2_ardour/editor.h | 2 | ||||
-rw-r--r-- | gtk2_ardour/editor_drag.cc | 97 | ||||
-rw-r--r-- | gtk2_ardour/editor_drag.h | 13 | ||||
-rw-r--r-- | gtk2_ardour/enums.h | 3 | ||||
-rw-r--r-- | gtk2_ardour/midi_time_axis.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/route_time_axis.cc | 1 | ||||
-rw-r--r-- | gtk2_ardour/session_option_editor.cc | 10 | ||||
-rw-r--r-- | gtk2_ardour/streamview.cc | 18 | ||||
-rw-r--r-- | gtk2_ardour/time_axis_view.cc | 37 | ||||
-rw-r--r-- | gtk2_ardour/time_axis_view.h | 2 |
13 files changed, 163 insertions, 57 deletions
diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc index a69f398ef4..6dbef4484d 100644 --- a/gtk2_ardour/audio_streamview.cc +++ b/gtk2_ardour/audio_streamview.cc @@ -809,13 +809,14 @@ AudioStreamView::update_contents_height () void AudioStreamView::update_content_height (CrossfadeView* cv) { - if (_layer_display == Overlaid) { - + switch (_layer_display) { + case Overlaid: cv->set_y (0); cv->set_height (height); + break; - } else { - + case Stacked: + case Expanded: layer_t const inl = cv->crossfade->in()->layer (); layer_t const outl = cv->crossfade->out()->layer (); @@ -824,9 +825,13 @@ AudioStreamView::update_content_height (CrossfadeView* cv) const double h = child_height (); - cv->set_y ((_layers - high - 1) * h); - cv->set_height ((high - low + 1) * h); - + if (_layer_display == Stacked) { + cv->set_y ((_layers - high - 1) * h); + cv->set_height ((high - low + 1) * h); + } else { + cv->set_y (((_layers - high) * 2 - 1) * h); + cv->set_height (((high - low) * 2 + 1) * h); + } } } diff --git a/gtk2_ardour/audio_time_axis.cc b/gtk2_ardour/audio_time_axis.cc index c7ee43f4cb..b2a1d6bf10 100644 --- a/gtk2_ardour/audio_time_axis.cc +++ b/gtk2_ardour/audio_time_axis.cc @@ -87,15 +87,23 @@ AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session* sess, Canvas& c void AudioTimeAxisView::set_route (boost::shared_ptr<Route> rt) { + _route = rt; + + /* RouteTimeAxisView::set_route() sets up some things in the View, + so it must be created before RouteTimeAxis::set_route() is + called. + */ + _view = new AudioStreamView (*this); + RouteTimeAxisView::set_route (rt); + _view->apply_color (color (), StreamView::RegionColor); + // Make sure things are sane... assert(!is_track() || is_audio_track()); subplugin_menu.set_name ("ArdourContextMenu"); - _view = new AudioStreamView (*this); - ignore_toggle = false; if (is_audio_track()) { diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index fa3ea175ce..30bde56a68 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -2477,12 +2477,12 @@ Editor::get_state () * TimeAxisView may be 0. Layer index is the layer number if the TimeAxisView is valid and is * in stacked region display mode, otherwise 0. */ -std::pair<TimeAxisView *, layer_t> +std::pair<TimeAxisView *, double> Editor::trackview_by_y_position (double y) { for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) { - std::pair<TimeAxisView*, int> const r = (*iter)->covers_y_position (y); + std::pair<TimeAxisView*, double> const r = (*iter)->covers_y_position (y); if (r.first) { return r; } diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 9ecc9c5da6..7f84176d61 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -1032,7 +1032,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD /* track views */ TrackViewList track_views; - std::pair<TimeAxisView*, ARDOUR::layer_t> trackview_by_y_position (double); + std::pair<TimeAxisView*, double> trackview_by_y_position (double); TimeAxisView* axis_view_from_route (boost::shared_ptr<ARDOUR::Route>) const; TrackViewList get_tracks_for_range_action () const; diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 020428a76b..06f602d5a0 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -485,9 +485,13 @@ RegionMotionDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) show_verbose_cursor_time (_last_frame_position); - pair<TimeAxisView*, int> const tv = _editor->trackview_by_y_position (_drags->current_pointer_y ()); + pair<TimeAxisView*, double> const tv = _editor->trackview_by_y_position (_drags->current_pointer_y ()); _last_pointer_time_axis_view = find_time_axis_view (tv.first); _last_pointer_layer = tv.first->layer_display() == Overlaid ? 0 : tv.second; + + if (tv.first->view()->layer_display() == Stacked) { + tv.first->view()->set_layer_display (Expanded); + } } double @@ -554,7 +558,7 @@ RegionMotionDrag::compute_x_delta (GdkEvent const * event, framepos_t* pending_r } bool -RegionMotionDrag::y_movement_allowed (int delta_track, layer_t delta_layer) const +RegionMotionDrag::y_movement_allowed (int delta_track, double delta_layer) const { for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) { int const n = i->time_axis_view + delta_track; @@ -569,8 +573,13 @@ RegionMotionDrag::y_movement_allowed (int delta_track, layer_t delta_layer) cons return false; } - int const l = i->layer + delta_layer; - if (delta_track == 0 && (l < 0 || l >= int (to->view()->layers()))) { + double const l = i->layer + delta_layer; + + /* Note that we allow layer to be up to 0.5 below zero, as this is used by `Expanded' + mode to allow the user to place a region below another on layer 0. + */ + + if (delta_track == 0 && (l < -0.5 || l >= int (to->view()->layers()))) { /* Off the top or bottom layer; note that we only refuse if the track hasn't changed. If it has, the layers will be munged later anyway, so it's ok. */ @@ -588,7 +597,7 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move) assert (!_views.empty ()); /* Find the TimeAxisView that the pointer is now over */ - pair<TimeAxisView*, int> const tv = _editor->trackview_by_y_position (_drags->current_pointer_y ()); + pair<TimeAxisView*, double> const tv = _editor->trackview_by_y_position (_drags->current_pointer_y ()); /* Bail early if we're not over a track */ RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (tv.first); @@ -601,7 +610,7 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move) /* Here's the current pointer position in terms of time axis view and layer */ int const current_pointer_time_axis_view = find_time_axis_view (tv.first); - layer_t const current_pointer_layer = tv.first->layer_display() == Overlaid ? 0 : tv.second; + double const current_pointer_layer = tv.first->layer_display() == Overlaid ? 0 : tv.second; /* Work out the change in x */ framepos_t pending_region_position; @@ -609,7 +618,7 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move) /* Work out the change in y */ int delta_time_axis_view = current_pointer_time_axis_view - _last_pointer_time_axis_view; - int delta_layer = current_pointer_layer - _last_pointer_layer; + double delta_layer = current_pointer_layer - _last_pointer_layer; if (!y_movement_allowed (delta_time_axis_view, delta_layer)) { /* this y movement is not allowed, so do no y movement this time */ @@ -659,14 +668,24 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move) confusion when dragging regions from non-zero layers onto different tracks. */ - int this_delta_layer = delta_layer; + double this_delta_layer = delta_layer; if (delta_time_axis_view != 0) { this_delta_layer = - i->layer; } /* The TimeAxisView that this region is now on */ TimeAxisView* tv = _time_axis_views[i->time_axis_view + delta_time_axis_view]; + + /* Ensure it is moved from stacked -> expanded if appropriate */ + if (tv->view()->layer_display() == Stacked) { + tv->view()->set_layer_display (Expanded); + } + /* We're only allowed to go -ve in layer on Expanded views */ + if (tv->view()->layer_display() != Expanded && (i->layer + this_delta_layer) < 0) { + this_delta_layer = - i->layer; + } + /* Set height */ rv->set_height (tv->view()->child_height ()); @@ -695,10 +714,17 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move) /* And adjust for the layer that it should be on */ StreamView* cv = tv->view (); - if (cv->layer_display() == Stacked) { + switch (cv->layer_display ()) { + case Overlaid: + break; + case Stacked: y += (cv->layers() - i->layer - 1) * cv->child_height (); + break; + case Expanded: + y += (cv->layers() - i->layer - 0.5) * 2 * cv->child_height (); + break; } - + /* Now move the region view */ rv->move (x_delta, y - rv->get_canvas_group()->property_y()); } @@ -789,8 +815,19 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move) } void -RegionMoveDrag::finished (GdkEvent *, bool movement_occurred) +RegionMotionDrag::finished (GdkEvent *, bool) { + for (vector<TimeAxisView*>::iterator i = _time_axis_views.begin(); i != _time_axis_views.end(); ++i) { + if ((*i)->view()->layer_display() == Expanded) { + (*i)->view()->set_layer_display (Stacked); + } + } +} + +void +RegionMoveDrag::finished (GdkEvent* ev, bool movement_occurred) +{ + RegionMotionDrag::finished (ev, movement_occurred); if (!movement_occurred) { /* just a click */ return; @@ -924,6 +961,9 @@ RegionMoveDrag::finished_no_copy ( RegionSelection new_views; PlaylistSet modified_playlists; PlaylistSet frozen_playlists; + PlaylistSet relayer_suspended_playlists; + + list<pair<boost::shared_ptr<Region>, double> > pending_relayers; if (_brushing) { /* all changes were made during motion event handlers */ @@ -942,7 +982,7 @@ RegionMoveDrag::finished_no_copy ( RegionView* rv = i->view; RouteTimeAxisView* const dest_rtv = dynamic_cast<RouteTimeAxisView*> (_time_axis_views[i->time_axis_view]); - layer_t const dest_layer = i->layer; + double const dest_layer = i->layer; if (rv->region()->locked()) { ++i; @@ -1002,9 +1042,10 @@ RegionMoveDrag::finished_no_copy ( boost::shared_ptr<Playlist> playlist = dest_rtv->playlist(); - if (dest_rtv->view()->layer_display() == Stacked) { - rv->region()->set_layer (dest_layer); - rv->region()->set_pending_explicit_relayer (true); + bool const explicit_relayer = dest_rtv->view()->layer_display() == Stacked || dest_rtv->view()->layer_display() == Expanded; + + if (explicit_relayer) { + pending_relayers.push_back (make_pair (rv->region (), dest_layer)); } /* freeze playlist to avoid lots of relayering in the case of a multi-region drag */ @@ -1024,6 +1065,9 @@ RegionMoveDrag::finished_no_copy ( playlist->clear_changes (); } + relayer_suspended_playlists.insert (playlist); + playlist->suspend_relayer (); + rv->region()->set_position (where); _editor->session()->add_command (new StatefulDiffCommand (rv->region())); @@ -1068,10 +1112,18 @@ RegionMoveDrag::finished_no_copy ( _editor->selection->set (new_views); } - for (set<boost::shared_ptr<Playlist> >::iterator p = frozen_playlists.begin(); p != frozen_playlists.end(); ++p) { + for (PlaylistSet::iterator p = frozen_playlists.begin(); p != frozen_playlists.end(); ++p) { (*p)->thaw(); } + for (PlaylistSet::iterator p = relayer_suspended_playlists.begin(); p != relayer_suspended_playlists.end(); ++p) { + (*p)->resume_relayer (); + } + + for (list<pair<boost::shared_ptr<Region>, double> >::iterator i = pending_relayers.begin(); i != pending_relayers.end(); ++i) { + i->first->playlist()->relayer (i->first, i->second); + } + /* write commands for the accumulated diffs for all our modified playlists */ add_stateful_diff_commands_for_playlists (modified_playlists); @@ -1137,9 +1189,8 @@ RegionMoveDrag::insert_region_into_playlist ( dest_playlist->add_region (region, where); - if (dest_rtv->view()->layer_display() == Stacked) { - region->set_layer (dest_layer); - region->set_pending_explicit_relayer (true); + if (dest_rtv->view()->layer_display() == Stacked || dest_rtv->view()->layer_display() == Expanded) { + dest_playlist->relayer (region, dest_layer); } c.disconnect (); @@ -1188,6 +1239,12 @@ RegionMoveDrag::aborted (bool movement_occurred) void RegionMotionDrag::aborted (bool) { + for (vector<TimeAxisView*>::iterator i = _time_axis_views.begin(); i != _time_axis_views.end(); ++i) { + if ((*i)->view()->layer_display() == Expanded) { + (*i)->view()->set_layer_display (Stacked); + } + } + for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) { RegionView* rv = i->view; TimeAxisView* tv = &(rv->get_time_axis_view ()); @@ -1295,7 +1352,7 @@ RegionSpliceDrag::motion (GdkEvent* event, bool) { /* Which trackview is this ? */ - pair<TimeAxisView*, int> const tvp = _editor->trackview_by_y_position (_drags->current_pointer_y ()); + pair<TimeAxisView*, double> const tvp = _editor->trackview_by_y_position (_drags->current_pointer_y ()); RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*> (tvp.first); /* The region motion is only processed if the pointer is over diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index c8308c6910..a6f5088d43 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -249,8 +249,11 @@ struct DraggingView * or -1 if it is not visible. */ int time_axis_view; - /** layer that this region is currently being displayed on */ - ARDOUR::layer_t layer; + /** Layer that this region is currently being displayed on. This is a double + rather than a layer_t as we use fractional layers during drags to allow the user + to indicate a new layer to put a region on. + */ + double layer; double initial_y; ///< the initial y position of the view before any reparenting framepos_t initial_position; ///< initial position of the region framepos_t initial_end; ///< initial end position of the region @@ -295,7 +298,7 @@ public: virtual void start_grab (GdkEvent *, Gdk::Cursor *); virtual void motion (GdkEvent *, bool); - virtual void finished (GdkEvent *, bool) = 0; + virtual void finished (GdkEvent *, bool); virtual void aborted (bool); /** @return true if the regions being `moved' came from somewhere on the canvas; @@ -306,13 +309,13 @@ public: protected: double compute_x_delta (GdkEvent const *, ARDOUR::framecnt_t *); - bool y_movement_allowed (int, ARDOUR::layer_t) const; + bool y_movement_allowed (int, double) const; bool _brushing; ARDOUR::framepos_t _last_frame_position; ///< last position of the thing being dragged double _total_x_delta; int _last_pointer_time_axis_view; - ARDOUR::layer_t _last_pointer_layer; + double _last_pointer_layer; }; diff --git a/gtk2_ardour/enums.h b/gtk2_ardour/enums.h index 92b2923894..680421e271 100644 --- a/gtk2_ardour/enums.h +++ b/gtk2_ardour/enums.h @@ -35,7 +35,8 @@ namespace Gnome { enum LayerDisplay { Overlaid, - Stacked + Stacked, + Expanded }; struct SelectionRect { diff --git a/gtk2_ardour/midi_time_axis.cc b/gtk2_ardour/midi_time_axis.cc index cbdf2919ae..c3df55a439 100644 --- a/gtk2_ardour/midi_time_axis.cc +++ b/gtk2_ardour/midi_time_axis.cc @@ -139,6 +139,8 @@ MidiTimeAxisView::set_route (boost::shared_ptr<Route> rt) */ RouteTimeAxisView::set_route (rt); + _view->apply_color (_color, StreamView::RegionColor); + subplugin_menu.set_name ("ArdourContextMenu"); if (!gui_property ("note-range-min").empty ()) { diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc index 4feafd5667..581e3eb238 100644 --- a/gtk2_ardour/route_time_axis.cc +++ b/gtk2_ardour/route_time_axis.cc @@ -468,6 +468,7 @@ RouteTimeAxisView::build_display_menu () ++overlaid; break; case Stacked: + case Expanded: ++stacked; break; } diff --git a/gtk2_ardour/session_option_editor.cc b/gtk2_ardour/session_option_editor.cc index 98ca09bb69..6ffb95b464 100644 --- a/gtk2_ardour/session_option_editor.cc +++ b/gtk2_ardour/session_option_editor.cc @@ -272,9 +272,17 @@ SessionOptionEditor::SessionOptionEditor (Session* s) ); lm->add (LaterHigher, _("later is higher")); - lm->add (MoveAddHigher, _("most recently moved or added is higher")); + lm->add (AddOrBoundsChangeHigher, _("most recently edited or added is higher")); lm->add (AddHigher, _("most recently added is higher")); + add_option (_("Misc"), new BoolOption ( + "relayer-on-all-edits", + _("Relayer regions after every edit"), + sigc::mem_fun (*_session_config, &SessionConfiguration::get_relayer_on_all_edits), + sigc::mem_fun (*_session_config, &SessionConfiguration::set_relayer_on_all_edits) + )); + + add_option (_("Misc"), lm); add_option (_("Misc"), new OptionEditorHeading (_("MIDI Options"))); diff --git a/gtk2_ardour/streamview.cc b/gtk2_ardour/streamview.cc index 28905ee45f..2bc70cf997 100644 --- a/gtk2_ardour/streamview.cc +++ b/gtk2_ardour/streamview.cc @@ -57,7 +57,6 @@ StreamView::StreamView (RouteTimeAxisView& tv, ArdourCanvas::Group* background_g , _samples_per_unit (_trackview.editor().get_current_zoom ()) , rec_updating(false) , rec_active(false) - , region_color(_trackview.color()) , stream_base_color(0xFFFFFFFF) , _layers (1) , _layer_display (Overlaid) @@ -302,7 +301,7 @@ StreamView::playlist_layered (boost::weak_ptr<Track> wtr) _layers = tr->playlist()->top_layer() + 1; } - if (_layer_display == Stacked) { + if (_layer_display == Stacked || _layer_display == Expanded) { update_contents_height (); update_coverage_frames (); } else { @@ -330,8 +329,6 @@ StreamView::playlist_switched (boost::weak_ptr<Track> wtr) update_contents_height (); update_coverage_frames (); - tr->playlist()->set_explicit_relayering (_layer_display == Stacked); - /* draw it */ redisplay_track (); @@ -569,10 +566,16 @@ StreamView::get_inverted_selectables (Selection& sel, list<Selectable*>& results double StreamView::child_height () const { - if (_layer_display == Stacked) { + switch (_layer_display) { + case Overlaid: + return height; + case Stacked: return height / _layers; + case Expanded: + return height / (_layers * 2 + 1); } + /* NOTREACHED */ return height; } @@ -589,6 +592,9 @@ StreamView::update_contents_height () case Stacked: (*i)->set_y (height - ((*i)->region()->layer() + 1) * h); break; + case Expanded: + (*i)->set_y (height - ((*i)->region()->layer() + 1) * 2 * h); + break; } (*i)->set_height (h); @@ -600,6 +606,7 @@ StreamView::update_contents_height () i->rectangle->property_y2() = height; break; case Stacked: + case Expanded: /* In stacked displays, the recregion is always at the top */ i->rectangle->property_y1() = 0; i->rectangle->property_y2() = h; @@ -614,7 +621,6 @@ StreamView::set_layer_display (LayerDisplay d) _layer_display = d; update_contents_height (); update_coverage_frames (); - _trackview.track()->playlist()->set_explicit_relayering (_layer_display == Stacked); } void diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc index e71bbe4778..fe02a8bc15 100644 --- a/gtk2_ardour/time_axis_view.cc +++ b/gtk2_ardour/time_axis_view.cc @@ -1195,10 +1195,10 @@ TimeAxisView::color_handler () * TimeAxisView is non-0 if this object covers y, or one of its children does. * If the covering object is a child axis, then the child is returned. * TimeAxisView is 0 otherwise. - * Layer index is the layer number if the TimeAxisView is valid and is in stacked - * region display mode, otherwise 0. + * Layer index is the layer number (possibly fractional) if the TimeAxisView is valid + * and is in stacked or expanded region display mode, otherwise 0. */ -std::pair<TimeAxisView*, layer_t> +std::pair<TimeAxisView*, double> TimeAxisView::covers_y_position (double y) { if (hidden()) { @@ -1208,15 +1208,30 @@ TimeAxisView::covers_y_position (double y) if (_y_position <= y && y < (_y_position + height)) { /* work out the layer index if appropriate */ - layer_t l = 0; - if (layer_display () == Stacked && view ()) { - /* compute layer */ - l = layer_t ((_y_position + height - y) / (view()->child_height ())); - /* clamp to max layers to be on the safe side; sometimes the above calculation - returns a too-high value */ - if (l >= view()->layers ()) { - l = view()->layers() - 1; + double l = 0; + switch (layer_display ()) { + case Overlaid: + break; + case Stacked: + if (view ()) { + /* compute layer */ + l = floor ((_y_position + height - y) / (view()->child_height ())); + /* clamp to max layers to be on the safe side; sometimes the above calculation + returns a too-high value */ + if (l >= view()->layers ()) { + l = view()->layers() - 1; + } + } + break; + case Expanded: + if (view ()) { + int n = floor ((_y_position + height - y) / (view()->child_height ())); + l = n * 0.5 - 0.5; + if (l >= (view()->layers() - 0.5)) { + l = view()->layers() - 0.5; + } } + break; } return std::make_pair (this, l); diff --git a/gtk2_ardour/time_axis_view.h b/gtk2_ardour/time_axis_view.h index 9771c8b200..52385b17aa 100644 --- a/gtk2_ardour/time_axis_view.h +++ b/gtk2_ardour/time_axis_view.h @@ -146,7 +146,7 @@ class TimeAxisView : public virtual AxisView virtual void reset_visual_state (); - std::pair<TimeAxisView*, ARDOUR::layer_t> covers_y_position (double); + std::pair<TimeAxisView*, double> covers_y_position (double); virtual void step_height (bool); |