Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Qwt widgets #13

Merged
merged 8 commits into from
Jun 22, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions Changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ This this the changelog file for the Pothos Plotters toolkit.
Release 0.1.2 (pending)
==========================

- Added QwtThermo, QwtKnob, and QwtDial widget to QwtWidgets
- Added saveState()/restoreState() hooks for all plotters
- Replace use of QwtText in metatype due to Qt unload bug

Expand Down
3 changes: 3 additions & 0 deletions QwtWidgets/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ POTHOS_MODULE_UTIL(
TARGET QwtWidgets
SOURCES
QwtSlider.cpp
QwtThermo.cpp
QwtKnob.cpp
QwtDial.cpp
ENABLE_DOCS
LIBRARIES ${Qt5_LIBRARIES}
DESTINATION plotters
Expand Down
195 changes: 195 additions & 0 deletions QwtWidgets/QwtDial.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
// Copyright (c) 2016-2016 Josh Blum
// SPDX-License-Identifier: BSL-1.0

#include <Pothos/Framework.hpp>
#include <qwt_dial.h>
#include <qwt_scale_engine.h>
#include <qwt_dial_needle.h>
#include <QGroupBox>
#include <QVBoxLayout>
#include <QMouseEvent>

/***********************************************************************
* |PothosDoc QWT Dial
*
* The dial widget is a circular status indicator for a floating point value.
* http://qwt.sourceforge.net/class_qwt_dial.html
*
* |category /Widgets
* |keywords dial turn compass
*
* |param title The name of the value displayed by this widget
* |default "My Dial"
* |widget StringEntry()
*
* |param mode The dial mode (rotate scale or rotate needle).
* |default "RotateNeedle"
* |option [Rotate Needle] "RotateNeedle"
* |option [Rotate Scale] "RotateScale"
* |preview disable
*
* |param needle The needle type (ray, arrow, compass, etc...).
* |default "SimpleArrow"
* |option [Simple Arrow] "SimpleArrow"
* |option [Simple Ray] "SimpleRay"
* |option [Compass Triangle] "CompassTriangle"
* |option [Compass Thin] "CompassThin"
* |option [Wind Arrow 1] "WindArrow1"
* |option [Wind Arrow 2] "WindArrow2"
* |preview disable
* |tab Needle
*
* |param color1[Color 1] The first color for the dial's needle.
* |widget ColorPicker()
* |default "blue"
* |preview disable
* |tab Needle
*
* |param color2[Color 2] The second color for the dial's needle.
* |widget ColorPicker()
* |default "red"
* |preview disable
* |tab Needle
*
* |param scaleEngine[Scale Engine] The scaling engine, linear or logarithmic.
* |default "Linear"
* |option [Linear] "Linear"
* |option [Log2] "Log2"
* |option [Log10] "Log10"
* |preview disable
*
* |param lowerBound[Lower Bound] The minimum value of this widget.
* |default -1.0
* |widget DoubleSpinBox()
*
* |param upperBound[Upper Bound] The maximum value of this widget.
* |default 1.0
* |widget DoubleSpinBox()
*
* |param stepSize[Step Size] The delta in-between discrete values in this widget.
* Use a value of 0.0 for automatic step-size calculation.
* |default 0.0
* |widget DoubleSpinBox()
* |preview valid
*
* |mode graphWidget
* |factory /widgets/qwt_dial()
* |setter setTitle(title)
* |setter setMode(mode)
* |setter setNeedle(needle, color1, color2)
* |setter setScaleEngine(scaleEngine)
* |setter setLowerBound(lowerBound)
* |setter setUpperBound(upperBound)
* |setter setStepSize(stepSize)
**********************************************************************/
class QwtDialBlock : public QGroupBox, public Pothos::Block
{
Q_OBJECT
public:

static Block *make(void)
{
return new QwtDialBlock();
}

QwtDialBlock(void):
_dial(new QwtDial(this))
{
auto layout = new QVBoxLayout(this);
layout->setContentsMargins(QMargins());
layout->addWidget(_dial);
this->setStyleSheet("QGroupBox {font-weight: bold;}");

this->registerCall(this, POTHOS_FCN_TUPLE(QwtDialBlock, setTitle));
this->registerCall(this, POTHOS_FCN_TUPLE(QwtDialBlock, setMode));
this->registerCall(this, POTHOS_FCN_TUPLE(QwtDialBlock, setNeedle));
this->registerCall(this, POTHOS_FCN_TUPLE(QwtDialBlock, widget));
this->registerCall(this, POTHOS_FCN_TUPLE(QwtDialBlock, value));
this->registerCall(this, POTHOS_FCN_TUPLE(QwtDialBlock, setValue));
this->registerCall(this, POTHOS_FCN_TUPLE(QwtDialBlock, setLowerBound));
this->registerCall(this, POTHOS_FCN_TUPLE(QwtDialBlock, setUpperBound));
this->registerCall(this, POTHOS_FCN_TUPLE(QwtDialBlock, setStepSize));
this->registerCall(this, POTHOS_FCN_TUPLE(QwtDialBlock, setScaleEngine));
}

QWidget *widget(void)
{
return this;
}

void setTitle(const QString &title)
{
QMetaObject::invokeMethod(this, "handleSetTitle", Qt::QueuedConnection, Q_ARG(QString, title));
}

void setMode(const QString &mode)
{
if (mode == "RotateNeedle") _dial->setMode(QwtDial::RotateNeedle);
if (mode == "RotateScale") _dial->setMode(QwtDial::RotateScale);
}

void setNeedle(const QString &type, const QString &color1, const QString &color2)
{
if (type == "SimpleArrow") _dial->setNeedle(new QwtDialSimpleNeedle(QwtDialSimpleNeedle::Arrow, true, color1, color2));
if (type == "SimpleRay") _dial->setNeedle(new QwtDialSimpleNeedle(QwtDialSimpleNeedle::Ray, true, color1, color2));
if (type == "CompassTriangle") _dial->setNeedle(new QwtCompassMagnetNeedle(QwtCompassMagnetNeedle::TriangleStyle, color1, color2));
if (type == "CompassThin") _dial->setNeedle(new QwtCompassMagnetNeedle(QwtCompassMagnetNeedle::ThinStyle, color1, color2));
if (type == "WindArrow1") _dial->setNeedle(new QwtCompassWindArrow(QwtCompassWindArrow::Style1, color1, color2));
if (type == "WindArrow2") _dial->setNeedle(new QwtCompassWindArrow(QwtCompassWindArrow::Style2, color1, color2));
}

double value(void) const
{
return _dial->value();
}

void setValue(const double value)
{
_dial->setValue(value);
}

void setLowerBound(const double value)
{
_dial->setLowerBound(value);
}

void setUpperBound(const double value)
{
_dial->setUpperBound(value);
}

void setStepSize(const double step)
{
_dial->setScaleStepSize(step);
}

void setScaleEngine(const QString &engine)
{
if (engine == "Linear") _dial->setScaleEngine(new QwtLinearScaleEngine());
if (engine == "Log2") _dial->setScaleEngine(new QwtLogScaleEngine(2));
if (engine == "Log10") _dial->setScaleEngine(new QwtLogScaleEngine(10));
_dial->setScale(_dial->lowerBound(), _dial->upperBound()); //refresh
}

private slots:

void handleSetTitle(const QString &title)
{
QGroupBox::setTitle(title);
}

protected:
void mousePressEvent(QMouseEvent *event)
{
QGroupBox::mousePressEvent(event);
event->ignore(); //allows for dragging from QGroupBox title
}

private:
QwtDial *_dial;
};

static Pothos::BlockRegistry registerQwtDialBlock(
"/widgets/qwt_dial", &QwtDialBlock::make);

#include "QwtDial.moc"
175 changes: 175 additions & 0 deletions QwtWidgets/QwtKnob.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
// Copyright (c) 2016-2016 Josh Blum
// SPDX-License-Identifier: BSL-1.0

#include <Pothos/Framework.hpp>
#include <qwt_knob.h>
#include <qwt_scale_engine.h>
#include <QVariant>
#include <QGroupBox>
#include <QVBoxLayout>
#include <QMouseEvent>

/***********************************************************************
* |PothosDoc QWT Knob
*
* A knob widget for angular control of a floating point value.
* http://qwt.sourceforge.net/class_qwt_knob.html
*
* |category /Widgets
* |keywords knob turn dial
*
* |param title The name of the value displayed by this widget
* |default "My Knob"
* |widget StringEntry()
*
* |param scaleEngine[Scale Engine] The scaling engine, linear or logarithmic.
* |default "Linear"
* |option [Linear] "Linear"
* |option [Log2] "Log2"
* |option [Log10] "Log10"
* |preview disable
*
* |param value The initial value of this widget.
* |default 0.0
* |widget DoubleSpinBox()
*
* |param lowerBound[Lower Bound] The minimum value of this widget.
* |default -1.0
* |widget DoubleSpinBox()
*
* |param upperBound[Upper Bound] The maximum value of this widget.
* |default 1.0
* |widget DoubleSpinBox()
*
* |param stepSize[Step Size] The delta in-between discrete values in this widget.
* Use a value of 0.0 for automatic step-size calculation.
* |default 0.0
* |widget DoubleSpinBox()
* |preview valid
*
* |mode graphWidget
* |factory /widgets/qwt_knob()
* |setter setTitle(title)
* |setter setScaleEngine(scaleEngine)
* |setter setLowerBound(lowerBound)
* |setter setUpperBound(upperBound)
* |setter setStepSize(stepSize)
* |setter setValue(value)
**********************************************************************/
class QwtKnobBlock : public QGroupBox, public Pothos::Block
{
Q_OBJECT
public:

static Block *make(void)
{
return new QwtKnobBlock();
}

QwtKnobBlock(void):
_knob(new QwtKnob(this))
{
auto layout = new QVBoxLayout(this);
layout->setContentsMargins(QMargins());
layout->addWidget(_knob);
this->setStyleSheet("QGroupBox {font-weight: bold;}");

this->registerCall(this, POTHOS_FCN_TUPLE(QwtKnobBlock, setTitle));
this->registerCall(this, POTHOS_FCN_TUPLE(QwtKnobBlock, widget));
this->registerCall(this, POTHOS_FCN_TUPLE(QwtKnobBlock, value));
this->registerCall(this, POTHOS_FCN_TUPLE(QwtKnobBlock, setValue));
this->registerCall(this, POTHOS_FCN_TUPLE(QwtKnobBlock, setLowerBound));
this->registerCall(this, POTHOS_FCN_TUPLE(QwtKnobBlock, setUpperBound));
this->registerCall(this, POTHOS_FCN_TUPLE(QwtKnobBlock, setStepSize));
this->registerCall(this, POTHOS_FCN_TUPLE(QwtKnobBlock, setScaleEngine));
this->registerSignal("valueChanged");
connect(_knob, SIGNAL(valueChanged(const double)), this, SLOT(handleValueChanged(const double)));
}

QWidget *widget(void)
{
return this;
}

void setTitle(const QString &title)
{
QMetaObject::invokeMethod(this, "handleSetTitle", Qt::QueuedConnection, Q_ARG(QString, title));
}

double value(void) const
{
return _knob->value();
}

void setValue(const double value)
{
_knob->setValue(value);
}

void setLowerBound(const double value)
{
_knob->setLowerBound(value);
}

void setUpperBound(const double value)
{
_knob->setUpperBound(value);
}

void setStepSize(const double step)
{
_knob->setScaleStepSize(step);
}

void setScaleEngine(const QString &engine)
{
if (engine == "Linear") _knob->setScaleEngine(new QwtLinearScaleEngine());
if (engine == "Log2") _knob->setScaleEngine(new QwtLogScaleEngine(2));
if (engine == "Log10") _knob->setScaleEngine(new QwtLogScaleEngine(10));
_knob->setScale(_knob->lowerBound(), _knob->upperBound()); //refresh
}

void activate(void)
{
//emit current value when design becomes active
this->callVoid("valueChanged", this->value());
}

public slots:

QVariant saveState(void) const
{
return this->value();
}

void restoreState(const QVariant &state)
{
this->setValue(state.toDouble());
}

private slots:
void handleValueChanged(const double value)
{
this->callVoid("valueChanged", value);
}

void handleSetTitle(const QString &title)
{
QGroupBox::setTitle(title);
}

protected:
void mousePressEvent(QMouseEvent *event)
{
QGroupBox::mousePressEvent(event);
event->ignore(); //allows for dragging from QGroupBox title
}

private:
QwtKnob *_knob;
};

static Pothos::BlockRegistry registerQwtKnobBlock(
"/widgets/qwt_knob", &QwtKnobBlock::make);

#include "QwtKnob.moc"