From d58cb3daa3f0e091a11e3846b28e83bcf0f93587 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sun, 5 Jun 2016 15:11:43 -0400 Subject: extensive changes to PresentationInfo API Now handles color, partially. --- libs/ardour/ardour/presentation_info.h | 61 +++++++---- libs/ardour/ardour/stripable.h | 22 +--- libs/ardour/globals.cc | 2 + libs/ardour/luabindings.cc | 2 +- libs/ardour/presentation_info.cc | 194 +++++++++++++++++++++++++-------- libs/ardour/route.cc | 2 +- libs/ardour/session.cc | 12 +- libs/ardour/stripable.cc | 55 ++-------- libs/ardour/vca.cc | 2 +- 9 files changed, 208 insertions(+), 144 deletions(-) (limited to 'libs') diff --git a/libs/ardour/ardour/presentation_info.h b/libs/ardour/ardour/presentation_info.h index 2afaa345d1..0de0a3d8bc 100644 --- a/libs/ardour/ardour/presentation_info.h +++ b/libs/ardour/ardour/presentation_info.h @@ -25,13 +25,25 @@ #include +#include "pbd/signals.h" +#include "pbd/stateful.h" +#include "pbd/properties.h" + #include "ardour/libardour_visibility.h" class XMLNode; namespace ARDOUR { -class LIBARDOUR_API PresentationInfo +namespace Properties { + LIBARDOUR_API extern PBD::PropertyDescriptor order; + LIBARDOUR_API extern PBD::PropertyDescriptor color; + LIBARDOUR_API extern PBD::PropertyDescriptor selected; + /* we use this; declared in region.cc */ + LIBARDOUR_API extern PBD::PropertyDescriptor hidden; +} + +class LIBARDOUR_API PresentationInfo : public PBD::Stateful { public: @@ -110,7 +122,7 @@ class LIBARDOUR_API PresentationInfo Selected = 0x100, Hidden = 0x200, /* single bit indicates that the group order is set */ - GroupOrderSet = 0x400, + OrderSet = 0x400, /* special mask to delect out "state" bits */ StatusMask = (Selected|Hidden) @@ -121,18 +133,24 @@ class LIBARDOUR_API PresentationInfo static const Flag Bus; typedef uint32_t order_t; - typedef uint64_t global_order_t; + typedef uint32_t color_t; - PresentationInfo (Flag f) : _order (0), _flags (Flag (f & ~GroupOrderSet)) { /* GroupOrderSet is not set */ } - PresentationInfo (order_t o, Flag f) : _order (o), _flags (Flag (f | GroupOrderSet)) { /* GroupOrderSet is set */ } + PresentationInfo (Flag f); + PresentationInfo (order_t o, Flag f); + PresentationInfo (PresentationInfo const &); static const order_t max_order; order_t order() const { return _order; } + color_t color() const { return _color; } + + void set_color (color_t); + void set_selected (bool yn); + void set_hidden (bool yn); PresentationInfo::Flag flags() const { return _flags; } - bool order_set() const { return _flags & GroupOrderSet; } + bool order_set() const { return _flags & OrderSet; } bool hidden() const { return _flags & Hidden; } bool selected() const { return _flags & Selected; } @@ -182,21 +200,13 @@ class LIBARDOUR_API PresentationInfo return f == _flags; } - std::string to_string () const; - - uint64_t to_integer () const { - return ((uint64_t) _flags << (8*sizeof(order_t))) | _order; - } + int set_state (XMLNode const&, int); + XMLNode& get_state (); bool operator< (PresentationInfo const& other) const { return order() < other.order(); } - PresentationInfo& operator= (std::string const& str) { - parse (str); - return *this; - } - bool match (PresentationInfo const& other) const { return (_order == other.order()) && flag_match (other.flags()); } @@ -209,19 +219,28 @@ class LIBARDOUR_API PresentationInfo return (_order != other.order()) || (_flags != other.flags()); } + PresentationInfo& operator= (PresentationInfo const& other); + static Flag get_flags (XMLNode const& node); + static std::string state_node_name; + + /* for things concerned about *any* PresentationInfo. This is emitted + * only at the request of another object that has finished making some + * changes (e.g. reordering things) + */ + + static PBD::Signal0 Change; + + static void make_property_quarks (); protected: friend class Stripable; - void set_order (order_t order) { _order = order; _flags = Flag (_flags|GroupOrderSet); } + void set_order (order_t order); private: order_t _order; Flag _flags; - - PresentationInfo (std::string const & str); - int parse (std::string const&); - int parse (order_t, Flag f); + color_t _color; }; } diff --git a/libs/ardour/ardour/stripable.h b/libs/ardour/ardour/stripable.h index b21b98f2bb..e49767f50d 100644 --- a/libs/ardour/ardour/stripable.h +++ b/libs/ardour/ardour/stripable.h @@ -76,16 +76,8 @@ class LIBARDOUR_API Stripable : public SessionObject { /* set just the order */ - void set_presentation_group_order (PresentationInfo::order_t, bool notify_class_listeners = true); - void set_presentation_group_order_explicit (PresentationInfo::order_t); - - /* for things concerned about *this* route's RID */ - - PBD::Signal0 PresentationInfoChanged; - - /* for things concerned about *any* route's RID changes */ - - static PBD::Signal0 PresentationInfoChange; + void set_presentation_order (PresentationInfo::order_t, bool notify_class_listeners = true); + void set_presentation_order_explicit (PresentationInfo::order_t); /*************************************************************** * Pure interface begins here @@ -182,16 +174,6 @@ class LIBARDOUR_API Stripable : public SessionObject { protected: PresentationInfo _presentation_info; - - /* set the entire info. This should only be used in cases where the - * derived could not supply the correct Flag and/or order information - * in its constructor. - */ - - void set_presentation_info (PresentationInfo id, bool notify_class_listeners = true); - void set_presentation_info_explicit (PresentationInfo); - - void add_state (XMLNode&) const; }; struct PresentationInfoSorter { diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc index f3b4a653c7..7d4730d290 100644 --- a/libs/ardour/globals.cc +++ b/libs/ardour/globals.cc @@ -102,6 +102,7 @@ #include "ardour/operations.h" #include "ardour/panner_manager.h" #include "ardour/plugin_manager.h" +#include "ardour/presentation_info.h" #include "ardour/process_thread.h" #include "ardour/profile.h" #include "ardour/rc_configuration.h" @@ -442,6 +443,7 @@ ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir RouteGroup::make_property_quarks (); Playlist::make_property_quarks (); AudioPlaylist::make_property_quarks (); + PresentationInfo::make_property_quarks (); /* this is a useful ready to use PropertyChange that many things need to check. This avoids having to compose diff --git a/libs/ardour/luabindings.cc b/libs/ardour/luabindings.cc index ba0d282187..3c7dd670e0 100644 --- a/libs/ardour/luabindings.cc +++ b/libs/ardour/luabindings.cc @@ -954,7 +954,7 @@ LuaBindings::common (lua_State* L) .addConst ("Auditioner", ARDOUR::PresentationInfo::Flag(PresentationInfo::Auditioner)) .addConst ("Selected", ARDOUR::PresentationInfo::Flag(PresentationInfo::Selected)) .addConst ("Hidden", ARDOUR::PresentationInfo::Flag(PresentationInfo::Hidden)) - .addConst ("GroupOrderSet", ARDOUR::PresentationInfo::Flag(PresentationInfo::GroupOrderSet)) + .addConst ("GroupOrderSet", ARDOUR::PresentationInfo::Flag(PresentationInfo::OrderSet)) .addConst ("StatusMask", ARDOUR::PresentationInfo::Flag(PresentationInfo::StatusMask)) .endNamespace () .endNamespace () diff --git a/libs/ardour/presentation_info.cc b/libs/ardour/presentation_info.cc index b992f6d5c9..5490f983be 100644 --- a/libs/ardour/presentation_info.cc +++ b/libs/ardour/presentation_info.cc @@ -21,6 +21,8 @@ #include +#include "pbd/convert.h" +#include "pbd/debug.h" #include "pbd/enumwriter.h" #include "pbd/error.h" #include "pbd/failed_constructor.h" @@ -34,90 +36,188 @@ using namespace ARDOUR; using namespace PBD; using std::string; +string PresentationInfo::state_node_name = X_("PresentationInfo"); +PBD::Signal0 PresentationInfo::Change; + +namespace ARDOUR { + namespace Properties { + PBD::PropertyDescriptor selected; + PBD::PropertyDescriptor order; + PBD::PropertyDescriptor color; + } +} + const PresentationInfo::order_t PresentationInfo::max_order = UINT32_MAX; const PresentationInfo::Flag PresentationInfo::Bus = PresentationInfo::Flag (PresentationInfo::AudioBus|PresentationInfo::MidiBus); const PresentationInfo::Flag PresentationInfo::Track = PresentationInfo::Flag (PresentationInfo::AudioTrack|PresentationInfo::MidiTrack); const PresentationInfo::Flag PresentationInfo::Route = PresentationInfo::Flag (PresentationInfo::Bus|PresentationInfo::Track); -PresentationInfo::PresentationInfo (std::string const & str) +void +PresentationInfo::make_property_quarks () { - if (parse (str)) { - throw failed_constructor (); - } + Properties::selected.property_id = g_quark_from_static_string (X_("selected")); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for selected = %1\n", Properties::selected.property_id)); + Properties::color.property_id = g_quark_from_static_string (X_("color")); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for color = %1\n", Properties::color.property_id)); + Properties::order.property_id = g_quark_from_static_string (X_("order")); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for order = %1\n", Properties::order.property_id)); } -int -PresentationInfo::parse (string const& str) +PresentationInfo::PresentationInfo (Flag f) + : _order (0) + , _flags (Flag (f & ~OrderSet)) + , _color (0) { - std::stringstream s (str); - - /* new school, segmented string "NNN:TYPE" */ - string f; - char c; + /* OrderSet is not set */ +} - s >> _order; - /* skip colon */ - s >> c; - /* grab flags */ - s >> f; +PresentationInfo::PresentationInfo (order_t o, Flag f) + : _order (o) + , _flags (Flag (f | OrderSet)) + , _color (0) +{ + /* OrderSet is set */ +} +PresentationInfo::PresentationInfo (PresentationInfo const& other) + : _order (other.order()) + , _flags (other.flags()) + , _color (other.color()) +{ +} - _flags = Flag (string_2_enum (f, _flags)|GroupOrderSet); +XMLNode& +PresentationInfo::get_state () +{ + XMLNode* node = new XMLNode (state_node_name); + node->add_property ("order", PBD::to_string (_order, std::dec)); + node->add_property ("flags", enum_2_string (_flags)); + node->add_property ("color", PBD::to_string (_color, std::dec)); - return 0; + return *node; } int -PresentationInfo::parse (uint32_t n, Flag f) +PresentationInfo::set_state (XMLNode const& node, int /* version */) { - if (n < UINT32_MAX) { - assert (f != Flag (0)); - _order = n; - _flags = Flag (f|GroupOrderSet); - } else { - _order = (n & 0xffff); - _flags = Flag ((n >> 16)|GroupOrderSet); + if (node.name() != state_node_name) { + return -1; } - return 0; -} + XMLProperty const* prop; + PropertyChange pc; -std::string -PresentationInfo::to_string() const -{ - std::stringstream ss; + if ((prop = node.property (X_("order"))) != 0) { + order_t o = atoi (prop->value()); + if (o != _order) { + pc.add (Properties::order); + _order = o; + } + _order = atoi (prop->value()); + } - /* Do not save or selected hidden status, or group-order set bit */ + if ((prop = node.property (X_("flags"))) != 0) { + Flag f = Flag (string_2_enum (prop->value(), f)); + if ((f&Hidden) != (_flags&Hidden)) { + pc.add (Properties::hidden); + } + _flags = f; + } + + if ((prop = node.property (X_("color"))) != 0) { + color_t c = atoi (prop->value()); + if (c != _color) { + pc.add (Properties::order); + _color = c; + } + } - Flag f = Flag (_flags & ~(Hidden|Selected|GroupOrderSet)); + send_change (PropertyChange (pc)); - ss << _order << ':' << enum_2_string (f); + return 0; - return ss.str(); } PresentationInfo::Flag PresentationInfo::get_flags (XMLNode const& node) { - const XMLProperty *prop; XMLNodeList nlist = node.children (); - XMLNodeConstIterator niter; - XMLNode *child; - for (niter = nlist.begin(); niter != nlist.end(); ++niter){ - child = *niter; + for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter){ + XMLNode* child = *niter; - if (child->name() == X_("PresentationInfo")) { - if ((prop = child->property (X_("value"))) != 0) { - PresentationInfo pi (prop->value()); - return pi.flags (); + if (child->name() == PresentationInfo::state_node_name) { + XMLProperty const* prop = child->property (X_("flags")); + if (prop) { + Flag f = (Flag) string_2_enum (prop->value(), f); + return f; } } } return Flag (0); } +void +PresentationInfo::set_color (PresentationInfo::color_t c) +{ + if (c != _color) { + _color = c; + send_change (PropertyChange (Properties::color)); + } +} + +void +PresentationInfo::set_selected (bool yn) +{ + if (yn != selected()) { + if (yn) { + _flags = Flag (_flags | Selected); + } else { + _flags = Flag (_flags & ~Selected); + } + send_change (PropertyChange (Properties::selected)); + } +} + +void +PresentationInfo::set_hidden (bool yn) +{ + if (yn != hidden()) { + + if (yn) { + _flags = Flag (_flags | Hidden); + } else { + _flags = Flag (_flags & ~Hidden); + } + + send_change (PropertyChange (Properties::hidden)); + } +} + +void +PresentationInfo::set_order (order_t order) +{ + _flags = Flag (_flags|OrderSet); + + if (order != _order) { + _order = order; + send_change (PropertyChange (Properties::order)); + } +} + +PresentationInfo& +PresentationInfo::operator= (PresentationInfo const& other) +{ + if (this != &other) { + _order = other.order(); + _flags = other.flags(); + _color = other.color(); + } + + return *this; +} + std::ostream& -operator<<(std::ostream& o, ARDOUR::PresentationInfo const& rid) +operator<<(std::ostream& o, ARDOUR::PresentationInfo const& pi) { - return o << rid.to_string (); + return o << pi.order() << '/' << enum_2_string (pi.flags()) << '/' << pi.color(); } diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 5a0959f8bb..60db5a1ffe 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -2237,7 +2237,7 @@ Route::state(bool full_state) node->add_property("default-type", _default_type.to_string()); node->add_property ("strict-io", _strict_io); - Stripable::add_state (*node); + node->add_child_nocopy (_presentation_info.get_state()); node->add_property("active", _active?"yes":"no"); string p; diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index ed27def461..ecb71c74a1 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -2944,7 +2944,7 @@ Session::ensure_route_presentation_info_gap (PresentationInfo::order_t first_new } if (rt->presentation_info().order () >= first_new_order) { - rt->set_presentation_group_order (rt->presentation_info().order () + how_many); + rt->set_presentation_order (rt->presentation_info().order () + how_many); } } } @@ -3444,10 +3444,10 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool if (order == PresentationInfo::max_order) { /* just add to the end */ - r->set_presentation_group_order_explicit (n_routes + added); + r->set_presentation_order_explicit (n_routes + added); DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("group order not set, set to NR %1 + %2 = %3\n", n_routes, added, n_routes + added)); } else { - r->set_presentation_group_order_explicit (order + added); + r->set_presentation_order (order + added); DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("group order not set, set to %1 + %2 = %3\n", order, added, order + added)); } } else { @@ -3459,7 +3459,7 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool r->name(), r->presentation_info().order(), enum_2_string (r->presentation_info().flags()), - r->presentation_info().to_string())); + r->presentation_info())); if (input_auto_connect || output_auto_connect) { @@ -3679,7 +3679,7 @@ Session::remove_routes (boost::shared_ptr routes_to_remove) return; } - Stripable::PresentationInfoChange(); /* EMIT SIGNAL */ + PresentationInfo::Change(); /* EMIT SIGNAL */ /* save the new state of the world */ @@ -6719,7 +6719,7 @@ Session::notify_presentation_info_change () return; } - Stripable::PresentationInfoChange (); /* EMIT SIGNAL */ + PresentationInfo::Change (); /* EMIT SIGNAL */ reassign_track_numbers(); #ifdef USE_TRACKS_CODE_FEATURES diff --git a/libs/ardour/stripable.cc b/libs/ardour/stripable.cc index 4fe3fb4287..2a86ef2529 100644 --- a/libs/ardour/stripable.cc +++ b/libs/ardour/stripable.cc @@ -32,8 +32,6 @@ using namespace ARDOUR; using namespace PBD; using std::string; -PBD::Signal0 Stripable::PresentationInfoChange; - Stripable::Stripable (Session& s, string const & name, PresentationInfo const & pi) : SessionObject (s, name) , _presentation_info (pi) @@ -41,46 +39,19 @@ Stripable::Stripable (Session& s, string const & name, PresentationInfo const & } void -Stripable::set_presentation_group_order (PresentationInfo::order_t order, bool notify_class_listeners) -{ - set_presentation_info (PresentationInfo (order, _presentation_info.flags()), notify_class_listeners); -} - -void -Stripable::set_presentation_group_order_explicit (PresentationInfo::order_t order) -{ - set_presentation_group_order (order, false); -} - -void -Stripable::set_presentation_info (PresentationInfo pi, bool notify_class_listeners) +Stripable::set_presentation_order (PresentationInfo::order_t order, bool notify_class_listeners) { - if (pi != presentation_info()) { - -#ifndef __APPLE__ - /* clang can't deal with the operator<< (ostream&,PresentationInfo&) method. not sure why yet. */ - DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("%1: set presentation info to %2\n", name(), pi)); -#endif - if (is_master()) { - _presentation_info = PresentationInfo (0, PresentationInfo::MasterOut); - } else if (is_monitor()) { - _presentation_info = PresentationInfo (0, PresentationInfo::MonitorOut); - } else { - _presentation_info = pi; - } + _presentation_info.set_order (order); - PresentationInfoChanged (); - - if (notify_class_listeners) { - PresentationInfoChange (); - } + if (notify_class_listeners) { + PresentationInfo::Change (); } } void -Stripable::set_presentation_info_explicit (PresentationInfo pi) +Stripable::set_presentation_order_explicit (PresentationInfo::order_t order) { - set_presentation_info (pi, false); + _presentation_info.set_order (order); } int @@ -96,10 +67,8 @@ Stripable::set_state (XMLNode const& node, int version) for (niter = nlist.begin(); niter != nlist.end(); ++niter){ child = *niter; - if (child->name() == X_("PresentationInfo")) { - if ((prop = child->property (X_("value"))) != 0) { - _presentation_info = prop->value (); - } + if (child->name() == PresentationInfo::state_node_name) { + _presentation_info.set_state (*child, version); } } @@ -143,11 +112,3 @@ Stripable::set_state (XMLNode const& node, int version) return 0; } - -void -Stripable::add_state (XMLNode& node) const -{ - XMLNode* remote_control_node = new XMLNode (X_("PresentationInfo")); - remote_control_node->add_property (X_("value"), _presentation_info.to_string()); - node.add_child_nocopy (*remote_control_node); -} diff --git a/libs/ardour/vca.cc b/libs/ardour/vca.cc index 2c87a80db4..36ed09cf25 100644 --- a/libs/ardour/vca.cc +++ b/libs/ardour/vca.cc @@ -110,7 +110,7 @@ VCA::get_state () node->add_property (X_("name"), _name); node->add_property (X_("number"), _number); - Stripable::add_state (*node); + node->add_child_nocopy (_presentation_info.get_state()); node->add_child_nocopy (_gain_control->get_state()); node->add_child_nocopy (_solo_control->get_state()); -- cgit v1.2.3