summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/widget/weffectpushbutton.cpp405
-rw-r--r--src/widget/weffectpushbutton.h77
-rw-r--r--src/widget/wpushbutton.cpp17
-rw-r--r--src/widget/wpushbutton.h6
4 files changed, 47 insertions, 458 deletions
diff --git a/src/widget/weffectpushbutton.cpp b/src/widget/weffectpushbutton.cpp
index 77eb07bb40..3f884b9b96 100644
--- a/src/widget/weffectpushbutton.cpp
+++ b/src/widget/weffectpushbutton.cpp
@@ -1,175 +1,20 @@
#include "widget/weffectpushbutton.h"
-#include <QStylePainter>
-#include <QStyleOption>
-#include <QPixmap>
#include <QtDebug>
-#include <QMouseEvent>
-#include <QTouchEvent>
-#include <QPaintEvent>
-#include <QApplication>
-#include "widget/wpixmapstore.h"
-#include "controlobject.h"
-#include "controlpushbutton.h"
-#include "control/controlbehavior.h"
-#include "util/debug.h"
#include "widget/effectwidgetutils.h"
WEffectPushButton::WEffectPushButton(QWidget* pParent, EffectsManager* pEffectsManager)
- : WWidget(pParent),
- m_leftButtonMode(ControlPushButton::PUSH),
- m_rightButtonMode(ControlPushButton::PUSH),
+ : WPushButton(pParent),
m_pEffectsManager(pEffectsManager) {
- setStates(0);
-}
-
-WEffectPushButton::WEffectPushButton(QWidget* pParent, ControlPushButton::ButtonMode leftButtonMode,
- ControlPushButton::ButtonMode rightButtonMode)
- : WWidget(pParent),
- m_leftButtonMode(leftButtonMode),
- m_rightButtonMode(rightButtonMode) {
- setStates(0);
}
WEffectPushButton::~WEffectPushButton() {
}
void WEffectPushButton::setup(QDomNode node, const SkinContext& context) {
- // Number of states
- int iNumStates = context.selectInt(node, "NumberStates");
- setStates(iNumStates);
-
- // Set background pixmap if available
- if (context.hasNode(node, "BackPath")) {
- QString mode_str = context.selectAttributeString(
- context.selectElement(node, "BackPath"), "scalemode", "TILE");
- PixmapSource backSource = context.getPixmapSource(context.selectNode(node, "BackPath"));
- if (!backSource.isEmpty()) {
- setPixmapBackground(backSource, Paintable::DrawModeFromString(mode_str));
- }
- }
-
- // Load pixmaps for associated states
- QDomNode state = context.selectNode(node, "State");
- while (!state.isNull()) {
- if (state.isElement() && state.nodeName() == "State") {
- int iState = context.selectInt(state, "Number");
- if (iState < m_iNoStates) {
- PixmapSource pixmapSource;
-
- pixmapSource = context.getPixmapSource(context.selectNode(state, "Unpressed"));
- if (!pixmapSource.isEmpty()) {
- setPixmap(iState, false, pixmapSource);
- }
-
- pixmapSource = context.getPixmapSource(context.selectNode(state, "Pressed"));
- if (!pixmapSource.isEmpty()) {
- setPixmap(iState, true, pixmapSource);
- }
-
- m_text.replace(iState, context.selectString(state, "Text"));
- QString alignment = context.selectString(state, "Alignment");
- if (alignment == "left") {
- m_align.replace(iState, Qt::AlignLeft);
- } else if (alignment == "right") {
- m_align.replace(iState, Qt::AlignRight);
- } else {
- // Default is center.
- m_align.replace(iState, Qt::AlignCenter);
- }
- }
- }
- state = state.nextSibling();
- }
-
- ControlParameterWidgetConnection* leftConnection = NULL;
- if (m_leftConnections.isEmpty()) {
- if (!m_connections.isEmpty()) {
- // If no left connection is set, the this is the left connection
- leftConnection = m_connections.at(0);
- }
- } else {
- leftConnection = m_leftConnections.at(0);
- }
-
- if (leftConnection) {
- bool leftClickForcePush = context.selectBool(node, "LeftClickIsPushButton", false);
- m_leftButtonMode = ControlPushButton::PUSH;
- if (!leftClickForcePush) {
- const ConfigKey& configKey = leftConnection->getKey();
- ControlPushButton* p = dynamic_cast<ControlPushButton*>(
- ControlObject::getControl(configKey));
- if (p) {
- m_leftButtonMode = p->getButtonMode();
- }
- }
- if (leftConnection->getEmitOption() &
- ControlParameterWidgetConnection::EMIT_DEFAULT) {
- switch (m_leftButtonMode) {
- case ControlPushButton::PUSH:
- case ControlPushButton::LONGPRESSLATCHING:
- case ControlPushButton::POWERWINDOW:
- leftConnection->setEmitOption(
- ControlParameterWidgetConnection::EMIT_ON_PRESS_AND_RELEASE);
- break;
- default:
- leftConnection->setEmitOption(
- ControlParameterWidgetConnection::EMIT_ON_PRESS);
- break;
- }
- }
- if (leftConnection->getDirectionOption() &
- ControlParameterWidgetConnection::DIR_DEFAULT) {
- if (m_pDisplayConnection == leftConnection) {
- leftConnection->setDirectionOption(ControlParameterWidgetConnection::DIR_FROM_AND_TO_WIDGET);
- } else {
- leftConnection->setDirectionOption(ControlParameterWidgetConnection::DIR_FROM_WIDGET);
- if (m_pDisplayConnection->getDirectionOption() &
- ControlParameterWidgetConnection::DIR_DEFAULT) {
- m_pDisplayConnection->setDirectionOption(ControlParameterWidgetConnection::DIR_TO_WIDGET);
- }
- }
- }
- }
-
- if (!m_rightConnections.isEmpty()) {
- ControlParameterWidgetConnection* rightConnection = m_rightConnections.at(0);
- bool rightClickForcePush = context.selectBool(node, "RightClickIsPushButton", false);
- m_rightButtonMode = ControlPushButton::PUSH;
- if (!rightClickForcePush) {
- const ConfigKey configKey = rightConnection->getKey();
- ControlPushButton* p = dynamic_cast<ControlPushButton*>(
- ControlObject::getControl(configKey));
- if (p) {
- m_rightButtonMode = p->getButtonMode();
- if (m_rightButtonMode != ControlPushButton::PUSH) {
- qWarning()
- << "WEffectPushButton::setup: Connecting a Pushbutton not in PUSH mode is not implemented\n"
- << "Please set <RightClickIsPushButton>true</RightClickIsPushButton>";
- }
- }
- }
- if (rightConnection->getEmitOption() &
- ControlParameterWidgetConnection::EMIT_DEFAULT) {
- switch (m_rightButtonMode) {
- case ControlPushButton::PUSH:
- case ControlPushButton::LONGPRESSLATCHING:
- case ControlPushButton::POWERWINDOW:
- leftConnection->setEmitOption(
- ControlParameterWidgetConnection::EMIT_ON_PRESS_AND_RELEASE);
- break;
- default:
- leftConnection->setEmitOption(
- ControlParameterWidgetConnection::EMIT_ON_PRESS);
- break;
- }
- }
- if (rightConnection->getDirectionOption() &
- ControlParameterWidgetConnection::DIR_DEFAULT) {
- rightConnection->setDirectionOption(ControlParameterWidgetConnection::DIR_FROM_WIDGET);
- }
- }
+ // Setup parent class.
+ WPushButton::setup(node, context);
m_pButtonMenu = new QMenu(this);
connect(m_pButtonMenu, SIGNAL(triggered(QAction*)),
@@ -195,254 +40,52 @@ void WEffectPushButton::setup(QDomNode node, const SkinContext& context) {
}
}
-void WEffectPushButton::setStates(int iStates) {
- m_bPressed = false;
- m_iNoStates = iStates;
- m_activeTouchButton = Qt::NoButton;
-
- m_pressedPixmaps.resize(iStates);
- m_unpressedPixmaps.resize(iStates);
- m_text.resize(iStates);
- m_align.resize(iStates);
-}
-
-void WEffectPushButton::setPixmap(int iState, bool bPressed,
- const PixmapSource& source) {
- QVector<PaintablePointer>& pixmaps = bPressed ?
- m_pressedPixmaps : m_unpressedPixmaps;
-
- if (iState < 0 || iState >= pixmaps.size()) {
- return;
- }
-
- PaintablePointer pPixmap = WPixmapStore::getPaintable(source,
- Paintable::STRETCH);
-
- if (pPixmap.isNull() || pPixmap->isNull()) {
- // Only log if it looks like the user tried to specify a pixmap.
- if (!source.isEmpty()) {
- qDebug() << "WEffectPushButton: Error loading pixmap:"
- << source.getPath();
- }
- } else {
- // Set size of widget equal to pixmap size
- setFixedSize(pPixmap->size());
- }
- pixmaps.replace(iState, pPixmap);
-}
-
-void WEffectPushButton::setPixmapBackground(const PixmapSource &source,
- Paintable::DrawMode mode) {
- // Load background pixmap
- m_pPixmapBack = WPixmapStore::getPaintable(source, mode);
- if (!source.isEmpty() &&
- (m_pPixmapBack.isNull() || m_pPixmapBack->isNull())) {
- // Only log if it looks like the user tried to specify a pixmap.
- qDebug() << "WEffectPushButton: Error loading background pixmap:"
- << source.getPath();
- }
-}
-
void WEffectPushButton::onConnectedControlChanged(double dParameter, double dValue) {
- Q_UNUSED(dParameter);
- // Enums are not currently represented using parameter space so it doesn't
- // make sense to use the parameter here yet.
- if (m_iNoStates == 1) {
- m_bPressed = (dValue == 1.0);
- }
-
foreach (QAction* action, m_pButtonMenu->actions()) {
if (action->data().toDouble() == dValue) {
action->setChecked(true);
break;
}
}
-
-
- double value = getControlParameterDisplay();
- if (isnan(value) || m_iNoStates == 0) {
- return;
- }
-
- int idx = static_cast<int>(value) % m_iNoStates;
- emit(displayValueChanged(idx));
- // According to http://stackoverflow.com/a/3822243 this is the least
- // expensive way to restyle just this widget.
- // Since we expect button connections to not change at high frequency we
- // don't try to detect whether things have changed for WEffectPushButton, we just
- // re-render.
- style()->unpolish(this);
- style()->polish(this);
- // These calls don't always trigger the repaint, so call it explicitly.
- repaint();
+ WPushButton::onConnectedControlChanged(dParameter, dValue);
}
-void WEffectPushButton::paintEvent(QPaintEvent* e) {
- Q_UNUSED(e);
- QStyleOption option;
- option.initFrom(this);
- QStylePainter p(this);
- p.drawPrimitive(QStyle::PE_Widget, option);
-
- if (m_iNoStates == 0) {
- return;
- }
-
- if (m_pPixmapBack) {
- m_pPixmapBack->draw(0, 0, &p);
- }
-
- const QVector<PaintablePointer>& pixmaps = m_bPressed ?
- m_pressedPixmaps : m_unpressedPixmaps;
-
-
- // m_text, m_pressedPixmaps and m_unpressedPixmaps are all the same size (as
- // per setup()) so if one is empty, all are empty.
- if (pixmaps.isEmpty()) {
- return;
- }
-
- int idx = readDisplayValue();
- // Just in case m_iNoStates is somehow different from pixmaps.size().
- if (idx < 0) {
- idx = 0;
- } else if (idx >= pixmaps.size()) {
- idx = pixmaps.size() - 1;
- }
-
- PaintablePointer pPixmap = pixmaps.at(idx);
- if (!pPixmap.isNull() && !pPixmap->isNull()) {
- pPixmap->draw(0, 0, &p);
- }
-
- QString text = m_text.at(idx);
- if (!text.isEmpty()) {
- p.drawText(rect(), m_align.at(idx), text);
- }
-}
-
-void WEffectPushButton::mousePressEvent(QMouseEvent * e) {
- const bool leftClick = e->button() == Qt::LeftButton;
+void WEffectPushButton::mousePressEvent(QMouseEvent* e) {
const bool rightClick = e->button() == Qt::RightButton;
-
if (rightClick && m_pButtonMenu->actions().size()) {
m_pButtonMenu->exec(e->globalPos());
- }
-
- if (m_leftButtonMode == ControlPushButton::POWERWINDOW
- && m_iNoStates == 2) {
- if (leftClick) {
- if (getControlParameterLeft() == 0.0) {
- m_clickTimer.setSingleShot(true);
- m_clickTimer.start(ControlPushButtonBehavior::kPowerWindowTimeMillis);
- }
- m_bPressed = true;
- setControlParameterLeftDown(1.0);
- update();
- }
- // discharge right clicks here, because is used for latching in POWERWINDOW mode
return;
}
- if (leftClick) {
- double emitValue;
- if (m_leftButtonMode == ControlPushButton::PUSH
- || m_iNoStates == 1) {
- // This is either forced to behave like a push button on left-click
- // or this is a push button.
- emitValue = 1.0;
- } else {
- // Toggle thru the states
- emitValue = getControlParameterLeft();
- if (!isnan(emitValue) && m_iNoStates) {
- emitValue = static_cast<int>(emitValue + 1.0) % m_iNoStates;
- }
- if (m_leftButtonMode == ControlPushButton::LONGPRESSLATCHING) {
- m_clickTimer.setSingleShot(true);
- m_clickTimer.start(ControlPushButtonBehavior::kLongPressLatchingTimeMillis);
- }
+ // Pass all other press events to the base class.
+ WPushButton::mousePressEvent(e);
- // Check the corresponding QAction
- foreach (QAction* action, m_pButtonMenu->actions()) {
- if (action->data().toDouble() == emitValue) {
- action->setChecked(true);
- break;
- }
- }
+ // The push handler may have set the left value. Check the corresponding
+ // QAction.
+ double leftValue = getControlParameterLeft();
+ foreach (QAction* action, m_pButtonMenu->actions()) {
+ if (action->data().toDouble() == leftValue) {
+ action->setChecked(true);
+ break;
}
- m_bPressed = true;
- setControlParameterLeftDown(emitValue);
- update();
}
}
-void WEffectPushButton::focusOutEvent(QFocusEvent* e) {
- Q_UNUSED(e);
- if (e->reason() != Qt::MouseFocusReason) {
- // Since we support multi touch there is no reason to reset
- // the pressed flag if the Primary touch point is moved to an
- // other widget
- m_bPressed = false;
- update();
- }
-}
+void WEffectPushButton::mouseReleaseEvent(QMouseEvent* e) {
+ // Pass all other press events to the base class.
+ WPushButton::mousePressEvent(e);
-void WEffectPushButton::mouseReleaseEvent(QMouseEvent * e) {
- const bool leftClick = e->button() == Qt::LeftButton;
- const bool rightClick = e->button() == Qt::RightButton;
-
- if (m_leftButtonMode == ControlPushButton::POWERWINDOW
- && m_iNoStates == 2) {
- if (leftClick) {
- const bool rightButtonDown = QApplication::mouseButtons() & Qt::RightButton;
- if (m_bPressed && !m_clickTimer.isActive() && !rightButtonDown) {
- // Release button after timer, but not if right button is clicked
- setControlParameterLeftUp(0.0);
- }
- m_bPressed = false;
- } else if (rightClick) {
- m_bPressed = false;
- }
- update();
- return;
- }
-
- if (leftClick) {
- double emitValue = getControlParameterLeft();
- if (m_leftButtonMode == ControlPushButton::PUSH
- || m_iNoStates == 1) {
- // This is a Pushbutton
- emitValue = 0.0;
- } else {
- if (m_leftButtonMode == ControlPushButton::LONGPRESSLATCHING
- && m_clickTimer.isActive() && emitValue >= 1.0) {
- // revert toggle if button is released too early
- if (!isnan(emitValue) && m_iNoStates) {
- emitValue = static_cast<int>(emitValue - 1.0) % m_iNoStates;
- }
- } else {
- // Nothing special happens when releasing a normal toggle button
- }
+ // The release handler may have set the left value. Check the corresponding
+ // QAction.
+ double leftValue = getControlParameterLeft();
+ foreach (QAction* action, m_pButtonMenu->actions()) {
+ if (action->data().toDouble() == leftValue) {
+ action->setChecked(true);
+ break;
}
- m_bPressed = false;
- setControlParameterLeftUp(emitValue);
- update();
}
}
-void WEffectPushButton::fillDebugTooltip(QStringList* debug) {
- WWidget::fillDebugTooltip(debug);
- *debug << QString("NumberStates: %1").arg(m_iNoStates)
- << QString("LeftCurrentState: %1").arg(
- static_cast<int>(getControlParameterLeft()) %
- (m_iNoStates > 0 ? m_iNoStates : 1))
- << QString("Pressed: %1").arg(toDebugString(m_bPressed))
- << QString("LeftButtonMode: %1")
- .arg(ControlPushButton::buttonModeToString(m_leftButtonMode))
- << QString("RightButtonMode: %1")
- .arg(ControlPushButton::buttonModeToString(m_rightButtonMode));
-}
-
void WEffectPushButton::parameterUpdated() {
m_pButtonMenu->clear();
const QList<QPair<QString, double> >& options = m_pEffectParameterSlot->getManifest().getSteps();
diff --git a/src/widget/weffectpushbutton.h b/src/widget/weffectpushbutton.h
index ff1902a2dd..780469bb4f 100644
--- a/src/widget/weffectpushbutton.h
+++ b/src/widget/weffectpushbutton.h
@@ -2,98 +2,35 @@
#define WEFFECTPUSHBUTTON_H
#include <QMenu>
-#include <QPaintEvent>
-#include <QPixmap>
-#include <QString>
-#include <QPaintEvent>
+#include <QAction>
#include <QMouseEvent>
-#include <QFocusEvent>
-#include <QTimer>
-#include <QVector>
+#include <QDomNode>
+#include <QWidget>
-#include "widget/wwidget.h"
-#include "widget/wpixmapstore.h"
-#include "controlpushbutton.h"
+#include "widget/wpushbutton.h"
#include "skin/skincontext.h"
-#include "controlwidgetconnection.h"
#include "effects/effectsmanager.h"
-class WEffectPushButton : public WWidget {
+class WEffectPushButton : public WPushButton {
Q_OBJECT
public:
WEffectPushButton(QWidget* pParent, EffectsManager* pEffectsManager);
- // Used by WEffectPushButtonTest.
- WEffectPushButton(QWidget* pParent, ControlPushButton::ButtonMode leftButtonMode,
- ControlPushButton::ButtonMode rightButtonMode);
virtual ~WEffectPushButton();
- Q_PROPERTY(bool pressed READ isPressed);
-
- bool isPressed() const {
- return m_bPressed;
- }
-
- // The displayValue property is used to restyle the pushbutton with CSS.
- // The declaration #MyButton[displayValue="0"] { } will define the style
- // when the widget is in state 0. This allows for effects like reversing
- // background and foreground colors to indicate enabled/disabled state.
- Q_PROPERTY(int displayValue READ readDisplayValue NOTIFY displayValueChanged)
-
- int readDisplayValue() const {
- double value = getControlParameterDisplay();
- int idx = static_cast<int>(value) % m_iNoStates;
- return idx;
- }
-
- void setup(QDomNode node, const SkinContext& context);
-
- // Sets the number of states associated with this button, and removes
- // associated pixmaps.
- void setStates(int iStatesW);
-
- signals:
- void displayValueChanged(int value);
+ virtual void setup(QDomNode node, const SkinContext& context);
public slots:
- void onConnectedControlChanged(double dParameter, double dValue);
+ virtual void onConnectedControlChanged(double dParameter, double dValue);
protected:
- virtual void paintEvent(QPaintEvent*);
virtual void mousePressEvent(QMouseEvent* e);
virtual void mouseReleaseEvent(QMouseEvent* e);
- virtual void focusOutEvent(QFocusEvent* e);
- void fillDebugTooltip(QStringList* debug);
private slots:
void parameterUpdated();
void slotActionChosen(QAction* action);
private:
- // Associates a pixmap of a given state of the button with the widget
- void setPixmap(int iState, bool bPressed, const PixmapSource &source);
-
- // Associates a background pixmap with the widget. This is only needed if
- // the button pixmaps contains alpha channel values.
- void setPixmapBackground(const PixmapSource &source, Paintable::DrawMode mode);
-
- // True, if the button is currently pressed
- bool m_bPressed;
-
- // Array of associated pixmaps
- int m_iNoStates;
- QVector<QString> m_text;
- QVector<PaintablePointer> m_pressedPixmaps;
- QVector<PaintablePointer> m_unpressedPixmaps;
-
- // Associated background pixmap
- PaintablePointer m_pPixmapBack;
-
- // short click toggle button long click push button
- ControlPushButton::ButtonMode m_leftButtonMode;
- ControlPushButton::ButtonMode m_rightButtonMode;
- QTimer m_clickTimer;
- QVector<int> m_align;
-
EffectsManager* m_pEffectsManager;
EffectParameterSlotBasePointer m_pEffectParameterSlot;
QMenu* m_pButtonMenu;
diff --git a/src/widget/wpushbutton.cpp b/src/widget/wpushbutton.cpp
index fc4f5c0c54..5b57a74f71 100644
--- a/src/widget/wpushbutton.cpp
+++ b/src/widget/wpushbutton.cpp
@@ -31,6 +31,7 @@
#include "controlpushbutton.h"
#include "control/controlbehavior.h"
#include "util/debug.h"
+#include "util/math.h"
WPushButton::WPushButton(QWidget* pParent)
: WWidget(pParent),
@@ -247,8 +248,11 @@ void WPushButton::onConnectedControlChanged(double dParameter, double dValue) {
}
double value = getControlParameterDisplay();
- int idx = static_cast<int>(value) % m_iNoStates;
- emit(displayValueChanged(idx));
+ if (!isnan(value) && m_iNoStates > 0) {
+ int idx = static_cast<int>(value) % m_iNoStates;
+ emit(displayValueChanged(idx));
+ }
+
// According to http://stackoverflow.com/a/3822243 this is the least
// expensive way to restyle just this widget.
// Since we expect button connections to not change at high frequency we
@@ -344,7 +348,10 @@ void WPushButton::mousePressEvent(QMouseEvent * e) {
emitValue = 1.0;
} else {
// Toggle thru the states
- emitValue = static_cast<int>(getControlParameterLeft() + 1.0) % m_iNoStates;
+ emitValue = getControlParameterLeft();
+ if (!isnan(emitValue) && m_iNoStates > 0) {
+ emitValue = static_cast<int>(emitValue + 1.0) % m_iNoStates;
+ }
if (m_leftButtonMode == ControlPushButton::LONGPRESSLATCHING) {
m_clickTimer.setSingleShot(true);
m_clickTimer.start(ControlPushButtonBehavior::kLongPressLatchingTimeMillis);
@@ -410,7 +417,9 @@ void WPushButton::mouseReleaseEvent(QMouseEvent * e) {
if (m_leftButtonMode == ControlPushButton::LONGPRESSLATCHING
&& m_clickTimer.isActive() && emitValue >= 1.0) {
// revert toggle if button is released too early
- emitValue = static_cast<int>(emitValue - 1.0) % m_iNoStates;
+ if (!isnan(emitValue) && m_iNoStates > 0) {
+ emitValue = static_cast<int>(emitValue - 1.0) % m_iNoStates;
+ }
} else {
// Nothing special happens when releasing a normal toggle button
}
diff --git a/src/widget/wpushbutton.h b/src/widget/wpushbutton.h
index d69e851bbc..a7d40884d4 100644
--- a/src/widget/wpushbutton.h
+++ b/src/widget/wpushbutton.h
@@ -60,7 +60,7 @@ class WPushButton : public WWidget {
return idx;
}
- void setup(QDomNode node, const SkinContext& context);
+ virtual void setup(QDomNode node, const SkinContext& context);
// Sets the number of states associated with this button, and removes
// associated pixmaps.
@@ -70,7 +70,7 @@ class WPushButton : public WWidget {
void displayValueChanged(int value);
public slots:
- void onConnectedControlChanged(double dParameter, double dValue);
+ virtual void onConnectedControlChanged(double dParameter, double dValue);
protected:
virtual void paintEvent(QPaintEvent*);
@@ -79,7 +79,7 @@ class WPushButton : public WWidget {
virtual void focusOutEvent(QFocusEvent* e);
void fillDebugTooltip(QStringList* debug);
- private:
+ protected:
// Associates a pixmap of a given state of the button with the widget
void setPixmap(int iState, bool bPressed, PixmapSource source);