diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 0b6929e86c..3181ea0728 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -1756,8 +1756,8 @@ Editor::add_region_context_items (StreamView* sv, boost::shared_ptr regi items.push_back (CheckMenuElem (_("Glue to Bars and Beats"))); CheckMenuItem* bbt_glue_item = static_cast(&items.back()); - switch (region_to_check->positional_lock_style()) { - case Region::MusicTime: + switch (region_to_check->position_lock_style()) { + case MusicTime: bbt_glue_item->set_active (true); break; default: diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index b267bcd37b..2747632968 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -4944,7 +4944,7 @@ Editor::toggle_region_lock_style () for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) { (*i)->region()->clear_history (); - Region::PositionLockStyle const ns = (*i)->region()->positional_lock_style() == Region::AudioTime ? Region::MusicTime : Region::AudioTime; + PositionLockStyle const ns = (*i)->region()->position_lock_style() == AudioTime ? MusicTime : AudioTime; (*i)->region()->set_position_lock_style (ns); _session->add_command (new StatefulDiffCommand ((*i)->region())); } diff --git a/gtk2_ardour/editor_regions.cc b/gtk2_ardour/editor_regions.cc index ab6ce76567..58a6a0e129 100644 --- a/gtk2_ardour/editor_regions.cc +++ b/gtk2_ardour/editor_regions.cc @@ -803,7 +803,7 @@ EditorRegions::populate_row (boost::shared_ptr region, TreeModel::Row co row[_columns.locked] = region->locked(); - if (region->positional_lock_style() == Region::MusicTime) { + if (region->position_lock_style() == MusicTime) { row[_columns.glued] = true; } else { row[_columns.glued] = false; diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h index 9d85c5b43d..8bc1612fbc 100644 --- a/libs/ardour/ardour/region.h +++ b/libs/ardour/ardour/region.h @@ -61,6 +61,7 @@ namespace Properties { extern PBD::PropertyDescriptor ancestral_length; extern PBD::PropertyDescriptor stretch; extern PBD::PropertyDescriptor shift; + extern PBD::PropertyDescriptor position_lock_style; }; class Playlist; @@ -84,11 +85,6 @@ class Region static void make_property_quarks (); - enum PositionLockStyle { - AudioTime, - MusicTime - }; - static PBD::Signal2, const PBD::PropertyChange&> RegionPropertyChanged; PBD::PropertyList* property_factory (const XMLNode&) const; @@ -149,7 +145,7 @@ class Region bool external() const { return _external; } bool import() const { return _import; } - PositionLockStyle positional_lock_style() const { return _positional_lock_style; } + PositionLockStyle position_lock_style() const { return _position_lock_style; } void set_position_lock_style (PositionLockStyle ps); void recompute_position_from_lock_style (); @@ -330,10 +326,10 @@ class Region PBD::Property _ancestral_length; PBD::Property _stretch; PBD::Property _shift; + PBD::EnumProperty _position_lock_style; framecnt_t _last_length; framepos_t _last_position; - PositionLockStyle _positional_lock_style; mutable RegionEditState _first_edit; BBT_Time _bbt_time; AnalysisFeatureList _transients; diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index 6374c3f9b6..cff8a12fd5 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -443,6 +443,11 @@ namespace ARDOUR { int64_t space; }; + enum PositionLockStyle { + AudioTime, + MusicTime + }; + /** A struct used to describe changes to processors in a route. * This is useful because objects that respond to a change in processors * can optimise what work they do based on details of what has changed. @@ -500,6 +505,7 @@ std::istream& operator>>(std::istream& o, ARDOUR::TimecodeFormat& sf); std::istream& operator>>(std::istream& o, ARDOUR::DenormalModel& sf); std::istream& operator>>(std::istream& o, ARDOUR::WaveformScale& sf); std::istream& operator>>(std::istream& o, ARDOUR::WaveformShape& sf); +std::istream& operator>>(std::istream& o, ARDOUR::PositionLockStyle& sf); std::ostream& operator<<(std::ostream& o, const ARDOUR::SampleFormat& sf); std::ostream& operator<<(std::ostream& o, const ARDOUR::HeaderFormat& sf); @@ -518,6 +524,7 @@ std::ostream& operator<<(std::ostream& o, const ARDOUR::TimecodeFormat& sf); std::ostream& operator<<(std::ostream& o, const ARDOUR::DenormalModel& sf); std::ostream& operator<<(std::ostream& o, const ARDOUR::WaveformScale& sf); std::ostream& operator<<(std::ostream& o, const ARDOUR::WaveformShape& sf); +std::ostream& operator<<(std::ostream& o, const ARDOUR::PositionLockStyle& sf); static inline ARDOUR::nframes64_t session_frame_to_track_frame (ARDOUR::nframes64_t session_frame, double speed) diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc index 2865701f02..2d29a59e8b 100644 --- a/libs/ardour/enums.cc +++ b/libs/ardour/enums.cc @@ -94,7 +94,7 @@ setup_enum_writer () Source::Flag _Source_Flag; Diskstream::Flag _Diskstream_Flag; Location::Flags _Location_Flags; - Region::PositionLockStyle _Region_PositionLockStyle; + PositionLockStyle _PositionLockStyle; Track::FreezeState _Track_FreezeState; AutomationList::InterpolationStyle _AutomationList_InterpolationStyle; AnyTime::Type _AnyTime_Type; @@ -417,10 +417,6 @@ setup_enum_writer () REGISTER_CLASS_ENUM (Panner, OppositeDirection); REGISTER (_Panner_LinkDirection); - REGISTER_CLASS_ENUM (Region, AudioTime); - REGISTER_CLASS_ENUM (Region, MusicTime); - REGISTER_BITS (_Region_PositionLockStyle); - REGISTER_CLASS_ENUM (Track, NoFreeze); REGISTER_CLASS_ENUM (Track, Frozen); REGISTER_CLASS_ENUM (Track, UnFrozen); @@ -553,6 +549,10 @@ setup_enum_writer () REGISTER_ENUM(Legato); REGISTER_ENUM(Groove); REGISTER(_QuantizeType); + + REGISTER_ENUM(AudioTime); + REGISTER_ENUM(MusicTime); + REGISTER(_PositionLockStyle); } } /* namespace ARDOUR */ @@ -783,4 +783,16 @@ std::ostream& operator<<(std::ostream& o, const WaveformShape& var) return o << s; } +std::istream& operator>>(std::istream& o, PositionLockStyle& var) +{ + std::string s; + o >> s; + var = (PositionLockStyle) string_2_enum (s, var); + return o; +} +std::ostream& operator<<(std::ostream& o, const PositionLockStyle& var) +{ + std::string s = enum_2_string (var); + return o << s; +} diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index f07cd645f1..fe70766e82 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -1326,7 +1326,7 @@ Playlist::shift (framepos_t at, frameoffset_t distance, bool move_intersected, b has to be done separately. */ - if (!ignore_music_glue && (*r)->positional_lock_style() != Region::AudioTime) { + if (!ignore_music_glue && (*r)->position_lock_style() != AudioTime) { fixup.push_back (*r); continue; } diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index 0ae947063f..076b0d1292 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -23,7 +23,6 @@ #include #include - #include #include "pbd/xml++.h" #include "pbd/stacktrace.h" @@ -69,6 +68,7 @@ namespace ARDOUR { PBD::PropertyDescriptor ancestral_length; PBD::PropertyDescriptor stretch; PBD::PropertyDescriptor shift; + PBD::PropertyDescriptor position_lock_style; } } @@ -119,6 +119,8 @@ Region::make_property_quarks () DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for stretch = %1\n", Properties::stretch.property_id)); Properties::shift.property_id = g_quark_from_static_string (X_("shift")); DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for shift = %1\n", Properties::shift.property_id)); + Properties::position_lock_style.property_id = g_quark_from_static_string (X_("positional-lock-style")); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for position_lock_style = %1\n", Properties::position_lock_style.property_id)); } void @@ -147,6 +149,7 @@ Region::register_properties () add_property (_ancestral_length); add_property (_stretch); add_property (_shift); + add_property (_position_lock_style); } #define REGION_DEFAULT_STATE(s,l) \ @@ -170,7 +173,8 @@ Region::register_properties () , _ancestral_start (Properties::ancestral_start, (s)) \ , _ancestral_length (Properties::ancestral_length, (l)) \ , _stretch (Properties::stretch, 1.0) \ - , _shift (Properties::shift, 1.0) + , _shift (Properties::shift, 1.0) \ + , _position_lock_style (Properties::position_lock_style, _type == DataType::AUDIO ? AudioTime : MusicTime) #define REGION_COPY_STATE(other) \ _muted (other->_muted) \ @@ -193,7 +197,8 @@ Region::register_properties () , _ancestral_start (other->_ancestral_start) \ , _ancestral_length (other->_ancestral_length) \ , _stretch (other->_stretch) \ - , _shift (other->_shift) + , _shift (other->_shift) \ + , _position_lock_style (other->_position_lock_style) /* derived-from-derived constructor (no sources in constructor) */ Region::Region (Session& s, framepos_t start, framecnt_t length, const string& name, DataType type) @@ -202,7 +207,6 @@ Region::Region (Session& s, framepos_t start, framecnt_t length, const string& n , REGION_DEFAULT_STATE(start,length) , _last_length (length) , _last_position (0) - , _positional_lock_style(AudioTime) , _first_edit (EditChangesNothing) , _read_data_count(0) , _last_layer_op(0) @@ -220,7 +224,6 @@ Region::Region (const SourceList& srcs) , REGION_DEFAULT_STATE(0,0) , _last_length (0) , _last_position (0) - , _positional_lock_style (_type == DataType::AUDIO ? AudioTime : MusicTime) , _first_edit (EditChangesNothing) , _valid_transients(false) , _read_data_count(0) @@ -250,7 +253,6 @@ Region::Region (boost::shared_ptr other, frameoffset_t offset, boo , REGION_COPY_STATE (other) , _last_length (other->_last_length) , _last_position(other->_last_position) \ - , _positional_lock_style(other->_positional_lock_style) \ , _first_edit (EditChangesNothing) , _valid_transients(false) , _read_data_count(0) @@ -276,7 +278,7 @@ Region::Region (boost::shared_ptr other, frameoffset_t offset, boo property lists. this would be nice to remove. */ - _positional_lock_style = other->_positional_lock_style; + _position_lock_style = other->_position_lock_style; _first_edit = other->_first_edit; if (offset == 0) { @@ -357,7 +359,6 @@ Region::Region (boost::shared_ptr other, const SourceList& srcs) , REGION_COPY_STATE (other) , _last_length (other->_last_length) , _last_position (other->_last_position) - , _positional_lock_style (other->_positional_lock_style) , _first_edit (EditChangesID) , _valid_transients (false) , _read_data_count (0) @@ -388,7 +389,6 @@ Region::Region (boost::shared_ptr other) , REGION_COPY_STATE (other) , _last_length (other->_last_length) , _last_position (other->_last_position) - , _positional_lock_style (other->_positional_lock_style) , _first_edit (EditChangesID) , _valid_transients(false) , _read_data_count(0) @@ -545,18 +545,22 @@ Region::special_set_position (framepos_t pos) void Region::set_position_lock_style (PositionLockStyle ps) { - boost::shared_ptr pl (playlist()); + if (_position_lock_style != ps) { - if (!pl) { - return; + boost::shared_ptr pl (playlist()); + + if (!pl) { + return; + } + + _position_lock_style = ps; + + if (_position_lock_style == MusicTime) { + _session.tempo_map().bbt_time (_position, _bbt_time); + } + + send_change (Properties::position_lock_style); } - - _positional_lock_style = ps; - - if (_positional_lock_style == MusicTime) { - _session.tempo_map().bbt_time (_position, _bbt_time); - } - } void @@ -564,7 +568,7 @@ Region::update_position_after_tempo_map_change () { boost::shared_ptr pl (playlist()); - if (!pl || _positional_lock_style != MusicTime) { + if (!pl || _position_lock_style != MusicTime) { return; } @@ -643,7 +647,7 @@ Region::set_position_on_top (framepos_t pos, void* /*src*/) void Region::recompute_position_from_lock_style () { - if (_positional_lock_style == MusicTime) { + if (_position_lock_style == MusicTime) { _session.tempo_map().bbt_time (_position, _bbt_time); } } @@ -1160,8 +1164,7 @@ Region::state (bool full) /* note: flags are stored by derived classes */ - if (_positional_lock_style != AudioTime) { - node->add_property ("positional-lock-style", enum_2_string (_positional_lock_style)); + if (_position_lock_style != AudioTime) { stringstream str; str << _bbt_time; node->add_property ("bbt-position", str.str()); @@ -1210,23 +1213,18 @@ Region::_set_state (const XMLNode& node, int version, PropertyChange& what_chang _id = prop->value(); } - if ((prop = node.property ("positional-lock-style")) != 0) { - _positional_lock_style = PositionLockStyle (string_2_enum (prop->value(), _positional_lock_style)); - - if (_positional_lock_style == MusicTime) { - if ((prop = node.property ("bbt-position")) == 0) { - /* missing BBT info, revert to audio time locking */ - _positional_lock_style = AudioTime; - } else { - if (sscanf (prop->value().c_str(), "%d|%d|%d", - &_bbt_time.bars, - &_bbt_time.beats, - &_bbt_time.ticks) != 3) { - _positional_lock_style = AudioTime; - } + if (_position_lock_style == MusicTime) { + if ((prop = node.property ("bbt-position")) == 0) { + /* missing BBT info, revert to audio time locking */ + _position_lock_style = AudioTime; + } else { + if (sscanf (prop->value().c_str(), "%d|%d|%d", + &_bbt_time.bars, + &_bbt_time.beats, + &_bbt_time.ticks) != 3) { + _position_lock_style = AudioTime; } } - } /* fix problems with old sessions corrupted by impossible diff --git a/libs/pbd/pbd/properties.h b/libs/pbd/pbd/properties.h index 1914344db9..03e42aa451 100644 --- a/libs/pbd/pbd/properties.h +++ b/libs/pbd/pbd/properties.h @@ -29,6 +29,7 @@ #include "pbd/xml++.h" #include "pbd/property_basics.h" #include "pbd/property_list.h" +#include "pbd/enumwriter.h" namespace PBD { @@ -199,14 +200,14 @@ private: * std::locale aborting on OS X if used with anything * other than C or POSIX locales. */ - std::string to_string (T const& v) const { + virtual std::string to_string (T const& v) const { std::stringstream s; s.precision (12); // in case its floating point s << v; return s.str (); } - T from_string (std::string const& s) const { + virtual T from_string (std::string const& s) const { std::stringstream t (s); T v; t >> v; @@ -250,6 +251,29 @@ private: }; +template +class EnumProperty : public Property +{ +public: + EnumProperty (PropertyDescriptor q, T const& v) + : Property (q, v) + {} + + T & operator=(T const& v) { + this->set (v); + return this->_current; + } + +private: + std::string to_string (T const & v) const { + return enum_2_string (v); + } + + T from_string (std::string const & s) const { + return static_cast (string_2_enum (s, this->_current)); + } +}; + } /* namespace PBD */ #include "pbd/property_list_impl.h"