RangeSlider
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#include "evalspinboxplugin.h"
|
||||
#include "imageviewplugin.h"
|
||||
#include "scroll_spin_boxplugin.h"
|
||||
#include "rangesliderplugin.h"
|
||||
|
||||
|
||||
QADWidgets::QADWidgets(QObject * parent): QObject(parent) {
|
||||
@@ -36,6 +37,7 @@ QADWidgets::QADWidgets(QObject * parent): QObject(parent) {
|
||||
m_widgets.append(new EvalSpinBoxPlugin(this));
|
||||
m_widgets.append(new ImageViewPlugin(this));
|
||||
m_widgets.append(new ScrollSpinBoxPlugin(this));
|
||||
m_widgets.append(new RangeSliderPlugin(this));
|
||||
}
|
||||
|
||||
|
||||
|
||||
69
libs/widgets/plugin/rangesliderplugin.cpp
Normal file
69
libs/widgets/plugin/rangesliderplugin.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include "rangeslider.h"
|
||||
#include "rangesliderplugin.h"
|
||||
#include <QtCore/QtPlugin>
|
||||
|
||||
|
||||
RangeSliderPlugin::RangeSliderPlugin(QObject * parent): QObject(parent) {
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
|
||||
void RangeSliderPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
|
||||
if (m_initialized)
|
||||
return;
|
||||
|
||||
// Add extension registrations, etc. here
|
||||
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
|
||||
bool RangeSliderPlugin::isInitialized() const {
|
||||
return m_initialized;
|
||||
}
|
||||
|
||||
|
||||
QWidget * RangeSliderPlugin::createWidget(QWidget * parent) {
|
||||
return new RangeSlider(parent);
|
||||
}
|
||||
|
||||
|
||||
QString RangeSliderPlugin::name() const {
|
||||
return QLatin1String("RangeSlider");
|
||||
}
|
||||
|
||||
|
||||
QString RangeSliderPlugin::group() const {
|
||||
return QLatin1String("Input Widgets");
|
||||
}
|
||||
|
||||
|
||||
QIcon RangeSliderPlugin::icon() const {
|
||||
return QIcon();
|
||||
}
|
||||
|
||||
|
||||
QString RangeSliderPlugin::toolTip() const {
|
||||
return QLatin1String("Range Slider");
|
||||
}
|
||||
|
||||
|
||||
QString RangeSliderPlugin::whatsThis() const {
|
||||
return QLatin1String("Range Slider");
|
||||
}
|
||||
|
||||
|
||||
bool RangeSliderPlugin::isContainer() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
QString RangeSliderPlugin::domXml() const {
|
||||
return QLatin1String("<widget class=\"RangeSlider\" name=\"rangeSlider\">\n</widget>\n");
|
||||
}
|
||||
|
||||
|
||||
QString RangeSliderPlugin::includeFile() const {
|
||||
return QLatin1String("rangeslider.h");
|
||||
}
|
||||
|
||||
36
libs/widgets/plugin/rangesliderplugin.h
Normal file
36
libs/widgets/plugin/rangesliderplugin.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef RANGESLIDERPLUGIN_H
|
||||
#define RANGESLIDERPLUGIN_H
|
||||
|
||||
#include <QObject>
|
||||
#if QT_VERSION >= 0x050000
|
||||
# include <QtUiPlugin/QDesignerCustomWidgetInterface>
|
||||
#else
|
||||
# include <QDesignerCustomWidgetInterface>
|
||||
#endif
|
||||
|
||||
class RangeSliderPlugin: public QObject, public QDesignerCustomWidgetInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDesignerCustomWidgetInterface)
|
||||
|
||||
public:
|
||||
RangeSliderPlugin(QObject * parent = 0);
|
||||
|
||||
bool isContainer() const;
|
||||
bool isInitialized() const;
|
||||
QIcon icon() const;
|
||||
QString domXml() const;
|
||||
QString group() const;
|
||||
QString includeFile() const;
|
||||
QString name() const;
|
||||
QString toolTip() const;
|
||||
QString whatsThis() const;
|
||||
QWidget * createWidget(QWidget * parent);
|
||||
void initialize(QDesignerFormEditorInterface * core);
|
||||
|
||||
private:
|
||||
bool m_initialized;
|
||||
|
||||
};
|
||||
|
||||
#endif // RANGESLIDERPLUGIN_H
|
||||
266
libs/widgets/rangeslider.cpp
Normal file
266
libs/widgets/rangeslider.cpp
Normal file
@@ -0,0 +1,266 @@
|
||||
#include "rangeslider.h"
|
||||
#include "qad_types.h"
|
||||
#include <QPalette>
|
||||
|
||||
|
||||
RangeSlider::RangeSlider(QWidget * parent)
|
||||
: QWidget(parent),
|
||||
m_minimum(0),
|
||||
m_maximum(100),
|
||||
m_lowerValue(0),
|
||||
m_upperValue(100),
|
||||
mFirstHandlePressed(false),
|
||||
mSecondHandlePressed(false),
|
||||
orientation(Qt::Horizontal),
|
||||
m_mode(DoubleHandles)
|
||||
{init();}
|
||||
|
||||
|
||||
RangeSlider::RangeSlider(Qt::Orientation ori, Mode m, QWidget * parent)
|
||||
: QWidget(parent),
|
||||
m_minimum(0),
|
||||
m_maximum(100),
|
||||
m_lowerValue(0),
|
||||
m_upperValue(100),
|
||||
mFirstHandlePressed(false),
|
||||
mSecondHandlePressed(false),
|
||||
orientation(ori),
|
||||
m_mode(m)
|
||||
{init();}
|
||||
|
||||
|
||||
void RangeSlider::init() {
|
||||
setMouseTracking(true);
|
||||
scHandleSideLength = 16*lineThickness();
|
||||
scSliderBarHeight = 8*lineThickness();
|
||||
scLeftRightMargin = 2*lineThickness();
|
||||
}
|
||||
|
||||
void RangeSlider::paintEvent(QPaintEvent *) {
|
||||
QPainter painter(this);
|
||||
// Background
|
||||
QRectF backgroundRect;
|
||||
if(orientation == Qt::Horizontal)
|
||||
backgroundRect = QRectF(scLeftRightMargin, (height() - scSliderBarHeight) / 2, width() - scLeftRightMargin * 2, scSliderBarHeight);
|
||||
else
|
||||
backgroundRect = QRectF((width() - scSliderBarHeight) / 2, scLeftRightMargin, scSliderBarHeight, height() - scLeftRightMargin*2);
|
||||
|
||||
QPen pen(palette().color(QPalette::Disabled, QPalette::Text));
|
||||
painter.setPen(pen);
|
||||
if (isEnabled()) {
|
||||
painter.setBrush(palette().color(QPalette::Active, QPalette::Base));
|
||||
} else {
|
||||
painter.setBrush(palette().color(QPalette::Disabled, QPalette::Base));
|
||||
}
|
||||
painter.drawRect(backgroundRect);
|
||||
|
||||
// First value handle rect
|
||||
painter.setPen(pen);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
painter.setBrush(palette().color(QPalette::Active, QPalette::Button));
|
||||
QRectF leftHandleRect = firstHandleRect();
|
||||
if(m_mode.testFlag(LeftHandle))
|
||||
painter.drawEllipse(leftHandleRect);
|
||||
|
||||
// Second value handle rect
|
||||
QRectF rightHandleRect = secondHandleRect();
|
||||
if(m_mode.testFlag(RightHandle))
|
||||
painter.drawEllipse(rightHandleRect);
|
||||
|
||||
// Handles
|
||||
painter.setRenderHint(QPainter::Antialiasing, false);
|
||||
QRectF selectedRect(backgroundRect);
|
||||
if(orientation == Qt::Horizontal) {
|
||||
selectedRect.setLeft((m_mode.testFlag(LeftHandle) ? leftHandleRect.right() : leftHandleRect.left()) + 0.5);
|
||||
selectedRect.setRight((m_mode.testFlag(RightHandle) ? rightHandleRect.left() : rightHandleRect.right()) - 0.5);
|
||||
} else {
|
||||
selectedRect.setTop((m_mode.testFlag(LeftHandle) ? leftHandleRect.bottom() : leftHandleRect.top()) + 0.5);
|
||||
selectedRect.setBottom((m_mode.testFlag(RightHandle) ? rightHandleRect.top() : rightHandleRect.bottom()) - 0.5);
|
||||
}
|
||||
if (isEnabled()) {
|
||||
painter.setBrush(palette().color(QPalette::Active, QPalette::Highlight));
|
||||
} else {
|
||||
painter.setBrush(palette().color(QPalette::Disabled, QPalette::Text));
|
||||
}
|
||||
painter.drawRect(selectedRect);
|
||||
}
|
||||
|
||||
|
||||
QRectF RangeSlider::firstHandleRect() const {
|
||||
float percentage = (m_lowerValue - m_minimum) * 1.0 / interval();
|
||||
return handleRect(percentage * validLength() + scLeftRightMargin);
|
||||
}
|
||||
|
||||
|
||||
QRectF RangeSlider::secondHandleRect() const {
|
||||
float percentage = (m_upperValue - m_minimum) * 1.0 / interval();
|
||||
return handleRect(percentage * validLength() + scLeftRightMargin + (m_mode.testFlag(LeftHandle) ? scHandleSideLength : 0));
|
||||
}
|
||||
|
||||
|
||||
QRectF RangeSlider::handleRect(int value) const {
|
||||
if(orientation == Qt::Horizontal)
|
||||
return QRect(value, (height()-scHandleSideLength) / 2, scHandleSideLength, scHandleSideLength);
|
||||
else
|
||||
return QRect((width()-scHandleSideLength) / 2, value, scHandleSideLength, scHandleSideLength);
|
||||
}
|
||||
|
||||
|
||||
void RangeSlider::mousePressEvent(QMouseEvent* e) {
|
||||
if(e->buttons() & Qt::LeftButton) {
|
||||
int posCheck, posMax, posValue, firstHandleRectPosValue, secondHandleRectPosValue;
|
||||
posCheck = (orientation == Qt::Horizontal) ? e->pos().y() : e->pos().x();
|
||||
posMax = (orientation == Qt::Horizontal) ? height() : width();
|
||||
posValue = (orientation == Qt::Horizontal) ? e->pos().x() : e->pos().y();
|
||||
firstHandleRectPosValue = (orientation == Qt::Horizontal) ? firstHandleRect().x() : firstHandleRect().y();
|
||||
secondHandleRectPosValue = (orientation == Qt::Horizontal) ? secondHandleRect().x() : secondHandleRect().y();
|
||||
|
||||
mSecondHandlePressed = secondHandleRect().contains(e->pos());
|
||||
mFirstHandlePressed = !mSecondHandlePressed && firstHandleRect().contains(e->pos());
|
||||
if(mFirstHandlePressed) {
|
||||
mDelta = posValue - (firstHandleRectPosValue + scHandleSideLength / 2);
|
||||
} else if(mSecondHandlePressed) {
|
||||
mDelta = posValue - (secondHandleRectPosValue + scHandleSideLength / 2);
|
||||
}
|
||||
if(posCheck >= 2 && posCheck <= posMax - 2) {
|
||||
int step = interval() / 10 < 1 ? 1 : interval() / 10;
|
||||
if(posValue < firstHandleRectPosValue)
|
||||
setLowerValue(m_lowerValue - step);
|
||||
else if(((posValue > firstHandleRectPosValue + scHandleSideLength) || !m_mode.testFlag(LeftHandle))
|
||||
&& ((posValue < secondHandleRectPosValue) || !m_mode.testFlag(RightHandle)))
|
||||
{
|
||||
if(m_mode.testFlag(DoubleHandles)) {
|
||||
if(posValue - (firstHandleRectPosValue + scHandleSideLength) <
|
||||
(secondHandleRectPosValue - (firstHandleRectPosValue + scHandleSideLength)) / 2) {
|
||||
setLowerValue((m_lowerValue + step < m_upperValue) ? m_lowerValue + step : m_upperValue);
|
||||
} else {
|
||||
setUpperValue((m_upperValue - step > m_lowerValue) ? m_upperValue - step : m_lowerValue);
|
||||
}
|
||||
} else if(m_mode.testFlag(LeftHandle)) {
|
||||
setLowerValue((m_lowerValue + step < m_upperValue) ? m_lowerValue + step : m_upperValue);
|
||||
} else if(m_mode.testFlag(RightHandle)) {
|
||||
setUpperValue((m_upperValue - step > m_lowerValue) ? m_upperValue - step : m_lowerValue);
|
||||
}
|
||||
}
|
||||
else if(posValue > secondHandleRectPosValue + scHandleSideLength)
|
||||
setUpperValue(m_upperValue + step);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RangeSlider::mouseMoveEvent(QMouseEvent* e) {
|
||||
if(e->buttons() & Qt::LeftButton) {
|
||||
int posValue, firstHandleRectPosValue, secondHandleRectPosValue;
|
||||
posValue = (orientation == Qt::Horizontal) ? e->pos().x() : e->pos().y();
|
||||
firstHandleRectPosValue = (orientation == Qt::Horizontal) ? firstHandleRect().x() : firstHandleRect().y();
|
||||
secondHandleRectPosValue = (orientation == Qt::Horizontal) ? secondHandleRect().x() : secondHandleRect().y();
|
||||
if(mFirstHandlePressed && m_mode.testFlag(LeftHandle)) {
|
||||
if(posValue - mDelta + scHandleSideLength / 2 <= secondHandleRectPosValue) {
|
||||
setLowerValue((posValue - mDelta - scLeftRightMargin - scHandleSideLength / 2) * 1.0 / validLength() * interval() + m_minimum);
|
||||
} else {
|
||||
setLowerValue(m_upperValue);
|
||||
}
|
||||
} else if(mSecondHandlePressed && m_mode.testFlag(RightHandle)) {
|
||||
if(firstHandleRectPosValue + scHandleSideLength * (m_mode.testFlag(DoubleHandles) ? 1.5 : 0.5) <= posValue - mDelta) {
|
||||
setUpperValue((posValue - mDelta - scLeftRightMargin - scHandleSideLength / 2 - (m_mode.testFlag(DoubleHandles) ? scHandleSideLength : 0)) * 1.0 / validLength() * interval() + m_minimum);
|
||||
} else {
|
||||
setUpperValue(m_lowerValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RangeSlider::mouseReleaseEvent(QMouseEvent *) {
|
||||
mFirstHandlePressed = false;
|
||||
mSecondHandlePressed = false;
|
||||
}
|
||||
|
||||
|
||||
void RangeSlider::changeEvent(QEvent * e) {
|
||||
if(e->type() == QEvent::EnabledChange) {
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QSize RangeSlider::minimumSizeHint() const {
|
||||
return QSize(scHandleSideLength * 2 + scLeftRightMargin * 2, scHandleSideLength);
|
||||
}
|
||||
|
||||
|
||||
void RangeSlider::setLowerValue(int value) {
|
||||
if(value > m_maximum) value = m_maximum;
|
||||
if(value < m_minimum) value = m_minimum;
|
||||
m_lowerValue = value;
|
||||
emit lowerValueChanged(m_lowerValue);
|
||||
emit valueChanged(m_lowerValue, m_upperValue);
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void RangeSlider::setUpperValue(int value) {
|
||||
if(value > m_maximum) value = m_maximum;
|
||||
if(value < m_minimum) value = m_minimum;
|
||||
m_upperValue = value;
|
||||
emit upperValueChanged(m_upperValue);
|
||||
emit valueChanged(m_lowerValue, m_upperValue);
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void RangeSlider::setMinimum(int minimum) {
|
||||
if(minimum <= m_maximum) {
|
||||
m_minimum = minimum;
|
||||
} else {
|
||||
int oldMax = m_maximum;
|
||||
m_minimum = oldMax;
|
||||
m_maximum = minimum;
|
||||
}
|
||||
update();
|
||||
setLowerValue(m_minimum);
|
||||
setUpperValue(m_maximum);
|
||||
emit minimumChanged(m_maximum);
|
||||
emit rangeChanged(m_minimum, m_maximum);
|
||||
}
|
||||
|
||||
|
||||
void RangeSlider::setMaximum(int maximum) {
|
||||
if(maximum >= m_minimum) {
|
||||
m_maximum = maximum;
|
||||
} else {
|
||||
int oldMin = m_minimum;
|
||||
m_maximum = oldMin;
|
||||
m_minimum = maximum;
|
||||
}
|
||||
update();
|
||||
setLowerValue(m_minimum);
|
||||
setUpperValue(m_maximum);
|
||||
emit maximumChanged(m_maximum);
|
||||
emit rangeChanged(m_minimum, m_maximum);
|
||||
}
|
||||
|
||||
|
||||
int RangeSlider::validLength() const {
|
||||
int len = (orientation == Qt::Horizontal) ? width() : height();
|
||||
return len - scLeftRightMargin * 2 - scHandleSideLength * (m_mode.testFlag(DoubleHandles) ? 2 : 1);
|
||||
}
|
||||
|
||||
|
||||
int RangeSlider::interval() const {
|
||||
return m_maximum - m_minimum;
|
||||
}
|
||||
|
||||
|
||||
void RangeSlider::setRange(int minimum, int maximum) {
|
||||
setMinimum(minimum);
|
||||
setMaximum(maximum);
|
||||
}
|
||||
|
||||
|
||||
void RangeSlider::setMode(Mode m) {
|
||||
m_mode = m;
|
||||
update();
|
||||
emit modeChanged(m_mode);
|
||||
}
|
||||
92
libs/widgets/rangeslider.h
Normal file
92
libs/widgets/rangeslider.h
Normal file
@@ -0,0 +1,92 @@
|
||||
#ifndef RANGESLIDER_H
|
||||
#define RANGESLIDER_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QPainter>
|
||||
#include <QMouseEvent>
|
||||
#include "qad_widgets_export.h"
|
||||
|
||||
|
||||
class QAD_WIDGETS_EXPORT RangeSlider : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_FLAGS(Mode)
|
||||
Q_PROPERTY(int minimum READ minimum WRITE setMinimum NOTIFY minimumChanged)
|
||||
Q_PROPERTY(int maximum READ maximum WRITE setMaximum NOTIFY maximumChanged)
|
||||
Q_PROPERTY(int lowerValue READ lowerValue WRITE setLowerValue NOTIFY lowerValueChanged)
|
||||
Q_PROPERTY(int upperValue READ upperValue WRITE setUpperValue NOTIFY upperValueChanged)
|
||||
Q_PROPERTY(Mode mode READ mode WRITE setMode NOTIFY modeChanged)
|
||||
|
||||
public:
|
||||
enum ModeEnum {
|
||||
NoHandle = 0x0,
|
||||
LeftHandle = 0x1,
|
||||
RightHandle = 0x2,
|
||||
DoubleHandles = LeftHandle | RightHandle
|
||||
};
|
||||
Q_DECLARE_FLAGS(Mode, ModeEnum)
|
||||
|
||||
RangeSlider(QWidget* parent = Q_NULLPTR);
|
||||
RangeSlider(Qt::Orientation ori, Mode m = DoubleHandles, QWidget * parent = Q_NULLPTR);
|
||||
|
||||
|
||||
int minimum() const {return m_minimum;}
|
||||
int maximum() const {return m_maximum;}
|
||||
int lowerValue() const {return m_lowerValue;}
|
||||
int upperValue() const {return m_upperValue;}
|
||||
QPair<int, int> value() const {return QPair<int, int>(m_lowerValue, m_upperValue);}
|
||||
Mode mode() const {return m_mode;}
|
||||
|
||||
protected:
|
||||
QSize minimumSizeHint() const override;
|
||||
void paintEvent(QPaintEvent *) override;
|
||||
void mousePressEvent(QMouseEvent * e) override;
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *) override;
|
||||
void changeEvent(QEvent * e) override;
|
||||
|
||||
QRectF firstHandleRect() const;
|
||||
QRectF secondHandleRect() const;
|
||||
QRectF handleRect(int value) const;
|
||||
|
||||
signals:
|
||||
void lowerValueChanged(int value);
|
||||
void upperValueChanged(int value);
|
||||
void valueChanged(int lower_value, int upper_value);
|
||||
void rangeChanged(int min, int max);
|
||||
void minimumChanged(int minimum);
|
||||
void maximumChanged(int maximum);
|
||||
void modeChanged(Mode m);
|
||||
|
||||
public slots:
|
||||
void setLowerValue(int value);
|
||||
void setUpperValue(int value);
|
||||
void setMinimum(int minimum);
|
||||
void setMaximum(int maximum);
|
||||
void setRange(int minimum, int maximum);
|
||||
void setMode(Mode m);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(RangeSlider)
|
||||
float currentPercentage();
|
||||
int validLength() const;
|
||||
int interval() const;
|
||||
void init();
|
||||
|
||||
int m_minimum;
|
||||
int m_maximum;
|
||||
int m_lowerValue;
|
||||
int m_upperValue;
|
||||
bool mFirstHandlePressed;
|
||||
bool mSecondHandlePressed;
|
||||
int mDelta;
|
||||
Qt::Orientation orientation;
|
||||
Mode m_mode;
|
||||
int scHandleSideLength;
|
||||
int scSliderBarHeight;
|
||||
int scLeftRightMargin;
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(RangeSlider::Mode)
|
||||
|
||||
#endif //RANGESLIDER_H
|
||||
Reference in New Issue
Block a user