1 #pragma once 2 3 #include <QObject> 4 #include <QEvent> 5 #include <QMutex> 6 7 #include "preferences/usersettings.h" 8 #include "controllers/midi/midimessage.h" 9 #include "control/control.h" 10 11 class ControlObject : public QObject { 12 Q_OBJECT 13 public: 14 ControlObject(); 15 16 // bIgnoreNops: Don't emit a signal if the CO is set to its current value. 17 // bTrack: Record statistics about this control. 18 // bPersist: Store value on exit, load on startup. 19 // defaultValue: default value of CO. If CO is persistent and there is no valid 20 // value found in the config, this is also the initial value. 21 ControlObject(const ConfigKey& key, 22 bool bIgnoreNops = true, 23 bool bTrack = false, 24 bool bPersist = false, 25 double defaultValue = 0.0); 26 virtual ~ControlObject(); 27 28 // Returns a pointer to the ControlObject matching the given ConfigKey 29 static ControlObject* getControl(const ConfigKey& key, ControlFlags flags = ControlFlag::None); 30 static ControlObject* getControl(const QString& group, 31 const QString& item, 32 ControlFlags flags = ControlFlag::None) { 33 ConfigKey key(group, item); 34 return getControl(key, flags); 35 } 36 name()37 QString name() const { 38 return m_pControl ? m_pControl->name() : QString(); 39 } 40 setName(const QString & name)41 void setName(const QString& name) { 42 if (m_pControl) { 43 m_pControl->setName(name); 44 } 45 } 46 description()47 const QString description() const { 48 return m_pControl ? m_pControl->description() : QString(); 49 } 50 setDescription(const QString & description)51 void setDescription(const QString& description) { 52 if (m_pControl) { 53 m_pControl->setDescription(description); 54 } 55 } 56 57 // Return the key of the object getKey()58 inline ConfigKey getKey() const { 59 return m_key; 60 } 61 62 // Returns the value of the ControlObject get()63 inline double get() const { 64 return m_pControl ? m_pControl->get() : 0.0; 65 } 66 67 // Returns the bool interpretation of the ControlObject toBool()68 inline bool toBool() const { 69 return get() > 0.0; 70 } 71 72 // Instantly returns the value of the ControlObject 73 static double get(const ConfigKey& key); 74 75 /// Returns the boolean interpretation of the ControlObject's value. toBool(const ConfigKey & key)76 static bool toBool(const ConfigKey& key) { 77 return ControlObject::get(key) > 0; 78 } 79 80 // Sets the ControlObject value. May require confirmation by owner. set(double value)81 inline void set(double value) { 82 if (m_pControl) { 83 m_pControl->set(value, this); 84 } 85 } 86 87 // Sets the ControlObject value and confirms it. setAndConfirm(double value)88 inline void setAndConfirm(double value) { 89 if (m_pControl) { 90 m_pControl->setAndConfirm(value, this); 91 } 92 } 93 94 // Forces the control to 'value', regardless of whether it has a change 95 // request handler attached (identical to setAndConfirm). forceSet(double value)96 inline void forceSet(double value) { 97 setAndConfirm(value); 98 } 99 100 // Instantly sets the value of the ControlObject 101 static void set(const ConfigKey& key, const double& value); 102 103 // Sets the default value reset()104 inline void reset() { 105 if (m_pControl) { 106 m_pControl->reset(); 107 } 108 } 109 setDefaultValue(double dValue)110 inline void setDefaultValue(double dValue) { 111 if (m_pControl) { 112 m_pControl->setDefaultValue(dValue); 113 } 114 } defaultValue()115 inline double defaultValue() const { 116 return m_pControl ? m_pControl->defaultValue() : 0.0; 117 } 118 119 // Returns the parameterized value of the object. Thread safe, non-blocking. 120 virtual double getParameter() const; 121 122 // Returns the parameterized value of the object. Thread safe, non-blocking. 123 virtual double getParameterForValue(double value) const; 124 125 // Returns the parameterized value of the object. Thread safe, non-blocking. 126 virtual double getParameterForMidi(double midiValue) const; 127 128 // Sets the control parameterized value to v. Thread safe, non-blocking. 129 virtual void setParameter(double v); 130 131 // Sets the control parameterized value to v. Thread safe, non-blocking. 132 virtual void setParameterFrom(double v, QObject* pSender = NULL); 133 134 // Connects a Qt slot to a signal that is delivered when a new value change 135 // request arrives for this control. 136 // Qt::AutoConnection: Qt ensures that the signal slot is called from the 137 // thread where the receiving object was created 138 // You need to use Qt::DirectConnection for the engine objects, since the 139 // audio thread has no Qt event queue. But be a ware of race conditions in this case. 140 // ref: http://qt-project.org/doc/qt-4.8/qt.html#ConnectionType-enum 141 template <typename Receiver, typename Slot> 142 bool connectValueChangeRequest(Receiver receiver, Slot func, 143 Qt::ConnectionType type = Qt::AutoConnection) { 144 bool ret = false; 145 if (m_pControl) { 146 ret = m_pControl->connectValueChangeRequest(receiver, func, type); 147 } 148 return ret; 149 } 150 151 // Installs a value-change request handler that ignores all sets. 152 void setReadOnly(); 153 154 signals: 155 void valueChanged(double); 156 157 public: 158 // DEPRECATED: Called to set the control value from the controller 159 // subsystem. 160 virtual void setValueFromMidi(MidiOpCode o, double v); 161 virtual double getMidiParameter() const; 162 163 protected: 164 // Key of the object 165 ConfigKey m_key; 166 QSharedPointer<ControlDoublePrivate> m_pControl; 167 168 private slots: 169 void privateValueChanged(double value, QObject* pSetter); 170 void readOnlyHandler(double v); 171 172 private: 173 ControlObject(ControlObject&&) = delete; 174 ControlObject(const ControlObject&) = delete; 175 ControlObject& operator=(ControlObject&&) = delete; 176 ControlObject& operator=(const ControlObject&) = delete; 177 ignoreNops()178 inline bool ignoreNops() const { 179 return m_pControl ? m_pControl->ignoreNops() : true; 180 } 181 }; 182