diff options
-rw-r--r-- | gtk2_ardour/editor_drag.cc | 7 | ||||
-rw-r--r-- | libs/ardour/ardour/playlist.h | 9 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 1 | ||||
-rw-r--r-- | libs/ardour/playlist.cc | 55 | ||||
-rw-r--r-- | libs/ardour/session.cc | 9 | ||||
-rw-r--r-- | libs/evoral/evoral/types.hpp | 8 |
6 files changed, 88 insertions, 1 deletions
diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 37f15b0142..4d6268d551 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -1359,6 +1359,7 @@ RegionCreateDrag::motion (GdkEvent* event, bool first_move) { if (first_move) { add_region(); + _view->playlist()->freeze (); } else { if (_region) { framepos_t const f = adjusted_current_frame (event); @@ -1378,6 +1379,8 @@ RegionCreateDrag::finished (GdkEvent*, bool movement_occurred) { if (!movement_occurred) { add_region (); + } else { + _view->playlist()->thaw (); } if (_region) { @@ -1403,6 +1406,10 @@ RegionCreateDrag::add_region () void RegionCreateDrag::aborted (bool) { + if (_region) { + _view->playlist()->thaw (); + } + /* XXX */ } diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h index a141e7ca96..a9bbd9346b 100644 --- a/libs/ardour/ardour/playlist.h +++ b/libs/ardour/ardour/playlist.h @@ -179,6 +179,11 @@ public: /** Emitted when regions have moved (not when regions have only been trimmed) */ PBD::Signal2<void,std::list< Evoral::RangeMove<framepos_t> > const &, bool> RangesMoved; + /** Emitted when regions are extended; the ranges passed are the new extra time ranges + that these regions now occupy. + */ + PBD::Signal1<void,std::list< Evoral::Range<framepos_t> > const &> RegionsExtended; + static std::string bump_name (std::string old_name, Session&); void freeze (); @@ -260,6 +265,8 @@ public: * do automation-follows-regions. */ std::list< Evoral::RangeMove<framepos_t> > pending_range_moves; + /** Extra sections added to regions during trims */ + std::list< Evoral::Range<framepos_t> > pending_region_extensions; bool save_on_thaw; std::string last_save_reason; uint32_t in_set_state; @@ -308,6 +315,8 @@ public: void notify_contents_changed (); void notify_state_changed (const PBD::PropertyChange&); void notify_region_moved (boost::shared_ptr<Region>); + void notify_region_start_trimmed (boost::shared_ptr<Region>); + void notify_region_end_trimmed (boost::shared_ptr<Region>); void mark_session_dirty(); diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 3463c227f2..a66b3352fc 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -1270,6 +1270,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void track_playlist_changed (boost::weak_ptr<Track>); void playlist_region_added (boost::weak_ptr<Region>); void playlist_ranges_moved (std::list<Evoral::RangeMove<framepos_t> > const &); + void playlist_regions_extended (std::list<Evoral::Range<framepos_t> > const &); /* NAMED SELECTIONS */ diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index 8b839e3269..cb764e7f40 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -540,6 +540,51 @@ Playlist::notify_region_moved (boost::shared_ptr<Region> r) } void +Playlist::notify_region_start_trimmed (boost::shared_ptr<Region> r) +{ + if (r->position() >= r->last_position()) { + /* trimmed shorter */ + return; + } + + Evoral::Range<framepos_t> const extra (r->position(), r->last_position()); + + if (holding_state ()) { + + pending_region_extensions.push_back (extra); + + } else { + + list<Evoral::Range<framepos_t> > r; + r.push_back (extra); + RegionsExtended (r); + + } +} + +void +Playlist::notify_region_end_trimmed (boost::shared_ptr<Region> r) +{ + if (r->length() < r->last_length()) { + /* trimmed shorter */ + } + + Evoral::Range<framepos_t> const extra (r->position() + r->last_length(), r->position() + r->length()); + + if (holding_state ()) { + + pending_region_extensions.push_back (extra); + + } else { + + list<Evoral::Range<framepos_t> > r; + r.push_back (extra); + RegionsExtended (r); + } +} + + +void Playlist::notify_region_added (boost::shared_ptr<Region> r) { /* the length change might not be true, but we have to act @@ -663,6 +708,10 @@ Playlist::flush_notifications (bool from_undo) if (!pending_range_moves.empty ()) { RangesMoved (pending_range_moves, from_undo); } + + if (!pending_region_extensions.empty ()) { + RegionsExtended (pending_region_extensions); + } clear_pending (); @@ -676,6 +725,7 @@ Playlist::clear_pending () pending_removes.clear (); pending_bounds.clear (); pending_range_moves.clear (); + pending_region_extensions.clear (); pending_contents_change = false; pending_length = false; } @@ -1628,9 +1678,12 @@ Playlist::region_changed (const PropertyChange& what_changed, boost::shared_ptr< if (what_changed.contains (Properties::position) && !what_changed.contains (Properties::length)) { notify_region_moved (region); + } else if (!what_changed.contains (Properties::position) && what_changed.contains (Properties::length)) { + notify_region_end_trimmed (region); + } else if (what_changed.contains (Properties::position) && what_changed.contains (Properties::length)) { + notify_region_start_trimmed (region); } - /* don't notify about layer changes, since we are the only object that can initiate them, and we notify in ::relayer() */ diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index cc791af862..3d1e2956f0 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -765,6 +765,7 @@ Session::track_playlist_changed (boost::weak_ptr<Track> wp) if ((playlist = track->playlist()) != 0) { playlist->RegionAdded.connect_same_thread (*this, boost::bind (&Session::playlist_region_added, this, _1)); playlist->RangesMoved.connect_same_thread (*this, boost::bind (&Session::playlist_ranges_moved, this, _1)); + playlist->RegionsExtended.connect_same_thread (*this, boost::bind (&Session::playlist_regions_extended, this, _1)); } } @@ -2545,6 +2546,14 @@ Session::playlist_ranges_moved (list<Evoral::RangeMove<framepos_t> > const & ran } } +void +Session::playlist_regions_extended (list<Evoral::Range<framepos_t> > const & ranges) +{ + for (list<Evoral::Range<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) { + maybe_update_session_range (i->from, i->to); + } +} + /* Region management */ boost::shared_ptr<Region> diff --git a/libs/evoral/evoral/types.hpp b/libs/evoral/evoral/types.hpp index 63bfe00027..3d98d23e22 100644 --- a/libs/evoral/evoral/types.hpp +++ b/libs/evoral/evoral/types.hpp @@ -47,6 +47,14 @@ static inline bool musical_time_equal (MusicalTime a, MusicalTime b) { /** Type of an event (opaque, mapped by application) */ typedef uint32_t EventType; +/** Type to describe a time range */ +template<typename T> +struct Range { + Range (T f, T t) : from (f), to (t) {} + T from; ///< start of the range + T to; ///< end of the range +}; + /** Type to describe the movement of a time range */ template<typename T> struct RangeMove { |