Skip to content

Commit

Permalink
Merge pull request #281 from badescunicu/switch_type_parameters
Browse files Browse the repository at this point in the history
Effect Button Parameters
  • Loading branch information
daschuer committed Jul 21, 2014
2 parents 63b06da + 829be5d commit b6c4384
Show file tree
Hide file tree
Showing 26 changed files with 692 additions and 138 deletions.
4 changes: 4 additions & 0 deletions build/depends.py
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,9 @@ def sources(self, build):
"effects/effectrack.cpp",
"effects/effectchainslot.cpp",
"effects/effectslot.cpp",
"effects/effectparameterslotbase.cpp",
"effects/effectparameterslot.cpp",
"effects/effectbuttonparameterslot.cpp",

"effects/effectsmanager.cpp",
"effects/effectchainmanager.cpp",
Expand Down Expand Up @@ -710,6 +712,8 @@ def sources(self, build):
"widget/weffectchain.cpp",
"widget/weffect.cpp",
"widget/weffectparameter.cpp",
"widget/weffectbuttonparameter.cpp",
"widget/weffectparameterbase.cpp",
"widget/wtime.cpp",
"widget/wkey.cpp",
"widget/wcombobox.cpp",
Expand Down
60 changes: 60 additions & 0 deletions src/effects/effect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ Effect::Effect(QObject* pParent, EffectsManager* pEffectsManager,
}
m_parametersById[parameter.id()] = pParameter;
}

foreach (const EffectManifestParameter& parameter, m_manifest.buttonParameters()) {
EffectParameter* pParameter = new EffectParameter(
this, pEffectsManager, m_buttonParameters.size(), parameter);
m_buttonParameters.append(pParameter);
if (m_buttonParametersById.contains(parameter.id())) {
qWarning() << debugString() << "WARNING: Loaded EffectManifest that had parameters with duplicate IDs. Dropping one of them.";
}
m_buttonParametersById[parameter.id()] = pParameter;
}
}

Effect::~Effect() {
Expand All @@ -37,6 +47,11 @@ Effect::~Effect() {
m_parameters[i] = NULL;
delete pParameter;
}
for (int i = 0; i < m_buttonParameters.size(); ++i) {
EffectParameter* pParameter = m_buttonParameters.at(i);
m_buttonParameters[i] = NULL;
delete pParameter;
}
}

void Effect::addToEngine(EngineEffectChain* pChain, int iIndex) {
Expand All @@ -50,6 +65,10 @@ void Effect::addToEngine(EngineEffectChain* pChain, int iIndex) {
foreach (EffectParameter* pParameter, m_parameters) {
pParameter->addToEngine();
}

foreach (EffectParameter* pParameter, m_buttonParameters) {
pParameter->addToEngine();
}
}

void Effect::removeFromEngine(EngineEffectChain* pChain, int iIndex) {
Expand All @@ -63,6 +82,10 @@ void Effect::removeFromEngine(EngineEffectChain* pChain, int iIndex) {
foreach (EffectParameter* pParameter, m_parameters) {
pParameter->removeFromEngine();
}

foreach (EffectParameter* pParameter, m_buttonParameters) {
pParameter->removeFromEngine();
}
}

void Effect::updateEngineState() {
Expand All @@ -73,6 +96,10 @@ void Effect::updateEngineState() {
foreach (EffectParameter* pParameter, m_parameters) {
pParameter->updateEngineState();
}

foreach (EffectParameter* pParameter, m_buttonParameters) {
pParameter->updateEngineState();
}
}

EngineEffect* Effect::getEngineEffect() {
Expand Down Expand Up @@ -110,6 +137,10 @@ unsigned int Effect::numParameters() const {
return m_parameters.size();
}

unsigned int Effect::numButtonParameters() const {
return m_buttonParameters.size();
}

EffectParameter* Effect::getParameterById(const QString& id) const {
EffectParameter* pParameter = m_parametersById.value(id, NULL);
if (pParameter == NULL) {
Expand All @@ -119,12 +150,27 @@ EffectParameter* Effect::getParameterById(const QString& id) const {
return pParameter;
}

EffectParameter* Effect::getButtonParameterById(const QString& id) const {
EffectParameter* pParameter = m_buttonParametersById.value(id, NULL);
if (pParameter == NULL) {
qWarning() << debugString() << "getParameterById"
<< "WARNING: parameter for id does not exist:" << id;
}
return pParameter;
}

EffectParameter* Effect::getParameter(unsigned int parameterNumber) {
// It's normal to ask for a parameter that doesn't exist. Callers must check
// for NULL.
return m_parameters.value(parameterNumber, NULL);
}

EffectParameter* Effect::getButtonParameter(unsigned int parameterNumber) {
// It's normal to ask for a parameter that doesn't exist. Callers must check
// for NULL.
return m_buttonParameters.value(parameterNumber, NULL);
}

QDomElement Effect::toXML(QDomDocument* doc) const {
QDomElement element = doc->createElement("Effect");
XmlParse::addElement(*doc, element, "Id", m_manifest.id());
Expand All @@ -144,6 +190,20 @@ QDomElement Effect::toXML(QDomDocument* doc) const {
}
element.appendChild(parameters);

QDomElement buttonParameters = doc->createElement("ButtonParameters");
foreach (EffectParameter* pParameter, m_buttonParameters) {
const EffectManifestParameter& parameterManifest =
pParameter->manifest();
QDomElement parameter = doc->createElement("ButtonParameter");
XmlParse::addElement(*doc, parameter, "Id", parameterManifest.id());
// TODO(rryan): Do smarter QVariant formatting?
XmlParse::addElement(*doc, parameter, "Value",
pParameter->getValue().toString());
// TODO(rryan): Output link state, etc.
buttonParameters.appendChild(parameter);
}
element.appendChild(buttonParameters);

return element;
}

Expand Down
5 changes: 5 additions & 0 deletions src/effects/effect.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ class Effect : public QObject {
const EffectManifest& getManifest() const;

unsigned int numParameters() const;
unsigned int numButtonParameters() const;
EffectParameter* getParameter(unsigned int parameterNumber);
EffectParameter* getButtonParameter(unsigned int parameterNumber);
EffectParameter* getParameterById(const QString& id) const;
EffectParameter* getButtonParameterById(const QString& id) const;

void setEnabled(bool enabled);
bool enabled() const;
Expand Down Expand Up @@ -65,6 +68,8 @@ class Effect : public QObject {
bool m_bEnabled;
QList<EffectParameter*> m_parameters;
QMap<QString, EffectParameter*> m_parametersById;
QList<EffectParameter*> m_buttonParameters;
QMap<QString, EffectParameter*> m_buttonParametersById;

DISALLOW_COPY_AND_ASSIGN(Effect);
};
Expand Down
132 changes: 132 additions & 0 deletions src/effects/effectbuttonparameterslot.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#include <QtDebug>

#include "controleffectknob.h"
#include "effects/effectbuttonparameterslot.h"
#include "controlobject.h"
#include "controlpushbutton.h"

EffectButtonParameterSlot::EffectButtonParameterSlot(const unsigned int iRackNumber,
const unsigned int iChainNumber,
const unsigned int iSlotNumber,
const unsigned int iParameterNumber)
: EffectParameterSlotBase(iRackNumber, iChainNumber, iSlotNumber,
iParameterNumber) {
QString itemPrefix = formatItemPrefix(iParameterNumber);
m_pControlLoaded = new ControlObject(
ConfigKey(m_group, itemPrefix + QString("_loaded")));
m_pControlLinkType = new ControlPushButton(
ConfigKey(m_group, itemPrefix + QString("_link_type")));
m_pControlLinkType->setButtonMode(ControlPushButton::TOGGLE);
m_pControlLinkType->setStates(EffectManifestParameter::NUM_LINK_TYPES);
m_pControlValue = new ControlPushButton(
ConfigKey(m_group, itemPrefix));
m_pControlValue->setButtonMode(ControlPushButton::POWERWINDOW);
m_pControlType = new ControlObject(
ConfigKey(m_group, itemPrefix + QString("_type")));

connect(m_pControlLinkType, SIGNAL(valueChanged(double)),
this, SLOT(slotLinkType(double)));
connect(m_pControlValue, SIGNAL(valueChanged(double)),
this, SLOT(slotValueChanged(double)));

// Read-only controls.
m_pControlType->connectValueChangeRequest(
this, SLOT(slotValueType(double)), Qt::AutoConnection);
m_pControlLoaded->connectValueChangeRequest(
this, SLOT(slotLoaded(double)), Qt::AutoConnection);

clear();
}

EffectButtonParameterSlot::~EffectButtonParameterSlot() {
//qDebug() << debugString() << "destroyed";
delete m_pControlValue;
}

void EffectButtonParameterSlot::loadEffect(EffectPointer pEffect) {
//qDebug() << debugString() << "loadEffect" << (pEffect ? pEffect->getManifest().name() : "(null)");
clear();
if (pEffect) {
m_pEffect = pEffect;
// Returns null if it doesn't have a parameter for that number
m_pEffectParameter = pEffect->getButtonParameter(m_iParameterNumber);

if (m_pEffectParameter) {
//qDebug() << debugString() << "Loading effect parameter" << m_pEffectParameter->name();
double dValue = m_pEffectParameter->getValue().toDouble();
double dMinimum = m_pEffectParameter->getMinimum().toDouble();
double dMinimumLimit = dMinimum; // TODO(rryan) expose limit from EffectParameter
double dMaximum = m_pEffectParameter->getMaximum().toDouble();
double dMaximumLimit = dMaximum; // TODO(rryan) expose limit from EffectParameter
double dDefault = m_pEffectParameter->getDefault().toDouble();

if (dValue > dMaximum || dValue < dMinimum ||
dMinimum < dMinimumLimit || dMaximum > dMaximumLimit ||
dDefault > dMaximum || dDefault < dMinimum) {
qWarning() << debugString() << "WARNING: EffectParameter does not satisfy basic sanity checks.";
}

// qDebug() << debugString()
// << QString("Val: %1 Min: %2 MinLimit: %3 Max: %4 MaxLimit: %5 Default: %6")
// .arg(dValue).arg(dMinimum).arg(dMinimumLimit).arg(dMaximum).arg(dMaximumLimit).arg(dDefault);

m_pControlValue->set(dValue);
m_pControlValue->setDefaultValue(dDefault);
EffectManifestParameter::ControlHint type = m_pEffectParameter->getControlHint();
// TODO(rryan) expose this from EffectParameter
m_pControlType->setAndConfirm(static_cast<double>(type));
// Default loaded parameters to loaded and unlinked
m_pControlLoaded->setAndConfirm(1.0);
m_pControlLinkType->set(m_pEffectParameter->getLinkType());

connect(m_pEffectParameter, SIGNAL(valueChanged(QVariant)),
this, SLOT(slotParameterValueChanged(QVariant)));
}

// Update the newly loaded parameter to match the current chain
// superknob if it is linked.
onChainParameterChanged(m_dChainParameter);
}
emit(updated());
}

void EffectButtonParameterSlot::clear() {
//qDebug() << debugString() << "clear";
if (m_pEffectParameter) {
m_pEffectParameter->disconnect(this);
m_pEffectParameter = NULL;
}

m_pEffect.clear();
m_pControlLoaded->setAndConfirm(0.0);
m_pControlValue->set(0.0);
m_pControlValue->setDefaultValue(0.0);
m_pControlType->setAndConfirm(0.0);
m_pControlLinkType->set(EffectManifestParameter::LINK_NONE);
emit(updated());
}

void EffectButtonParameterSlot::slotParameterValueChanged(QVariant value) {
//qDebug() << debugString() << "slotParameterValueChanged" << value.toDouble();
m_pControlValue->set(value.toDouble());
}

void EffectButtonParameterSlot::onChainParameterChanged(double parameter) {
m_dChainParameter = parameter;
if (m_pEffectParameter != NULL) {
switch (m_pEffectParameter->getLinkType()) {
case EffectManifestParameter::LINK_INVERSE:
parameter = 1.0 - parameter;
// Intentional fall-through.
case EffectManifestParameter::LINK_LINKED:
if (parameter < 0.0 || parameter > 1.0) {
return;
}
m_pControlValue->setParameterFrom(parameter, NULL);
break;
case EffectManifestParameter::LINK_NONE:
default:
break;
}
}
}
55 changes: 55 additions & 0 deletions src/effects/effectbuttonparameterslot.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#ifndef EFFECTBUTTONPARAMETERSLOT_H
#define EFFECTBUTTONPARAMETERSLOT_H

#include <QObject>
#include <QVariant>
#include <QString>

#include "util.h"
#include "controlobject.h"
#include "effects/effect.h"
#include "effects/effectparameterslotbase.h"

class ControlObject;
class ControlPushButton;

class EffectButtonParameterSlot;
typedef QSharedPointer<EffectButtonParameterSlot> EffectButtonParameterSlotPointer;

class EffectButtonParameterSlot : public EffectParameterSlotBase {
Q_OBJECT
public:
EffectButtonParameterSlot(const unsigned int iRackNumber,
const unsigned int iChainNumber,
const unsigned int iSlotNumber,
const unsigned int iParameterNumber);
virtual ~EffectButtonParameterSlot();

static QString formatItemPrefix(const unsigned int iParameterNumber) {
return QString("button_parameter%1").arg(iParameterNumber + 1);
}

// Load the parameter of the given effect into this EffectButtonParameterSlot
void loadEffect(EffectPointer pEffect);

void onChainParameterChanged(double parameter);

private slots:
// Solely for handling control changes
void slotParameterValueChanged(QVariant value);

private:
QString debugString() const {
return QString("EffectButtonParameterSlot(%1,%2)").arg(m_group).arg(m_iParameterNumber);
}

// Clear the currently loaded effect
void clear();

// Control exposed to the rest of Mixxx
ControlPushButton* m_pControlValue;

DISALLOW_COPY_AND_ASSIGN(EffectButtonParameterSlot);
};

#endif // EFFECTBUTTONPARAMETERSLOT_H
11 changes: 11 additions & 0 deletions src/effects/effectmanifest.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,21 @@ class EffectManifest {
return m_parameters;
}


virtual EffectManifestParameter* addParameter() {
m_parameters.append(EffectManifestParameter());
return &m_parameters.last();
}

virtual const QList<EffectManifestParameter>& buttonParameters() const {
return m_buttonParameters;
}

virtual EffectManifestParameter* addButtonParameter() {
m_buttonParameters.append(EffectManifestParameter());
return &m_buttonParameters.last();
}

private:
QString debugString() const {
return QString("EffectManifest(%1)").arg(m_id);
Expand All @@ -81,6 +91,7 @@ class EffectManifest {
QString m_version;
QString m_description;
QList<EffectManifestParameter> m_parameters;
QList<EffectManifestParameter> m_buttonParameters;
};

#endif /* EFFECTMANIFEST_H */
Loading

0 comments on commit b6c4384

Please sign in to comment.