Add Slider

This commit is contained in:
johanneshilden 2017-09-29 16:53:18 +03:00
parent 86c2a92898
commit 231f01b5a6
12 changed files with 1362 additions and 6 deletions

View File

@ -20,7 +20,7 @@
- [x] Raised Button
- [ ] Scroll Bar
- [ ] Select Field
- [ ] Slider
- [x] Slider
- [ ] Snackbar
- [ ] Tabs
- [ ] Text Field

View File

@ -20,7 +20,9 @@ SOURCES = \
qtmaterialprogress_internal.cpp \
qtmaterialprogress.cpp \
qtmaterialcircularprogress_internal.cpp \
qtmaterialcircularprogress.cpp
qtmaterialcircularprogress.cpp \
qtmaterialslider_internal.cpp \
qtmaterialslider.cpp
HEADERS = \
qtmaterialavatar_p.h \
qtmaterialavatar.h \
@ -54,6 +56,9 @@ HEADERS = \
qtmaterialprogress.h \
qtmaterialcircularprogress_internal.h \
qtmaterialcircularprogress_p.h \
qtmaterialcircularprogress.h
qtmaterialcircularprogress.h \
qtmaterialslider_internal.h \
qtmaterialslider_p.h \
qtmaterialslider.h
RESOURCES += \
resources.qrc

View File

@ -0,0 +1,394 @@
#include "qtmaterialslider.h"
#include "qtmaterialslider_p.h"
#include <QtWidgets/QApplication>
#include <QMouseEvent>
#include "qtmaterialslider_internal.h"
#include "lib/qtmaterialstyle.h"
#include "lib/qtmaterialstatetransitionevent.h"
/*!
* \class QtMaterialSliderPrivate
* \internal
*/
QtMaterialSliderPrivate::QtMaterialSliderPrivate(QtMaterialSlider *q)
: q_ptr(q)
{
}
QtMaterialSliderPrivate::~QtMaterialSliderPrivate()
{
}
void QtMaterialSliderPrivate::init()
{
Q_Q(QtMaterialSlider);
thumb = new QtMaterialSliderThumb(q);
track = new QtMaterialSliderTrack(thumb, q);
stateMachine = new QtMaterialSliderStateMachine(q, thumb, track);
stepTo = 0;
oldValue = q->value();
trackWidth = 2;
hoverTrack = false;
hoverThumb = false;
hover = false;
step = false;
pageStepMode = true;
useThemeColors = true;
q->setMouseTracking(true);
q->setFocusPolicy(Qt::StrongFocus);
q->setPageStep(1);
QSizePolicy sp(QSizePolicy::Expanding,
QSizePolicy::Fixed);
if (q->orientation() == Qt::Vertical) {
sp.transpose();
}
q->setSizePolicy(sp);
q->setAttribute(Qt::WA_WState_OwnSizePolicy, false);
stateMachine->start();
QCoreApplication::processEvents();
}
QRectF QtMaterialSliderPrivate::trackBoundingRect() const
{
Q_Q(const QtMaterialSlider);
qreal hw = static_cast<qreal>(trackWidth)/2;
return Qt::Horizontal == q->orientation()
? QRectF(QT_MATERIAL_SLIDER_MARGIN, q->height()/2 - hw,
q->width() - QT_MATERIAL_SLIDER_MARGIN*2, hw*2)
: QRectF(q->width()/2 - hw, QT_MATERIAL_SLIDER_MARGIN, hw*2,
q->height() - QT_MATERIAL_SLIDER_MARGIN*2);
}
QRectF QtMaterialSliderPrivate::thumbBoundingRect() const
{
Q_Q(const QtMaterialSlider);
return Qt::Horizontal == q->orientation()
? QRectF(thumb->offset(), q->height()/2 - QT_MATERIAL_SLIDER_MARGIN,
QT_MATERIAL_SLIDER_MARGIN*2, QT_MATERIAL_SLIDER_MARGIN*2)
: QRectF(q->width()/2 - QT_MATERIAL_SLIDER_MARGIN, thumb->offset(),
QT_MATERIAL_SLIDER_MARGIN*2, QT_MATERIAL_SLIDER_MARGIN*2);
}
int QtMaterialSliderPrivate::valueFromPosition(const QPoint &pos) const
{
Q_Q(const QtMaterialSlider);
const int position = Qt::Horizontal == q->orientation() ? pos.x() : pos.y();
const int span = Qt::Horizontal == q->orientation()
? q->width() - QT_MATERIAL_SLIDER_MARGIN*2
: q->height() - QT_MATERIAL_SLIDER_MARGIN*2;
return QtMaterialStyle::sliderValueFromPosition(
q->minimum(),
q->maximum(),
position - QT_MATERIAL_SLIDER_MARGIN,
span,
q->invertedAppearance());
}
void QtMaterialSliderPrivate::setHovered(bool status)
{
Q_Q(QtMaterialSlider);
if (hover == status) {
return;
}
hover = status;
if (!q->hasFocus()) {
if (status) {
stateMachine->postEvent(new QtMaterialStateTransitionEvent(SliderNoFocusMouseEnter));
} else {
stateMachine->postEvent(new QtMaterialStateTransitionEvent(SliderNoFocusMouseLeave));
}
}
q->update();
}
/*!
* \class QtMaterialSlider
*/
QtMaterialSlider::QtMaterialSlider(QWidget *parent)
: QAbstractSlider(parent),
d_ptr(new QtMaterialSliderPrivate(this))
{
d_func()->init();
}
QtMaterialSlider::~QtMaterialSlider()
{
}
void QtMaterialSlider::setUseThemeColors(bool value)
{
Q_D(QtMaterialSlider);
d->useThemeColors = value;
d->stateMachine->setupProperties();
}
bool QtMaterialSlider::useThemeColors() const
{
Q_D(const QtMaterialSlider);
return d->useThemeColors;
}
void QtMaterialSlider::setThumbColor(const QColor &color)
{
Q_D(QtMaterialSlider);
d->thumbColor = color;
setUseThemeColors(false);
}
QColor QtMaterialSlider::thumbColor() const
{
Q_D(const QtMaterialSlider);
if (d->useThemeColors || !d->thumbColor.isValid()) {
return QtMaterialStyle::instance().themeColor("primary1");
} else {
return d->thumbColor;
}
}
void QtMaterialSlider::setTrackColor(const QColor &color)
{
Q_D(QtMaterialSlider);
d->trackColor = color;
setUseThemeColors(false);
}
QColor QtMaterialSlider::trackColor() const
{
Q_D(const QtMaterialSlider);
if (d->useThemeColors || !d->trackColor.isValid()) {
return QtMaterialStyle::instance().themeColor("accent3");
} else {
return d->trackColor;
}
}
void QtMaterialSlider::setDisabledColor(const QColor &color)
{
Q_D(QtMaterialSlider);
d->disabledColor = color;
setUseThemeColors(false);
}
QColor QtMaterialSlider::disabledColor() const
{
Q_D(const QtMaterialSlider);
if (d->useThemeColors || !d->disabledColor.isValid()) {
return QtMaterialStyle::instance().themeColor("disabled");
} else {
return d->disabledColor;
}
}
void QtMaterialSlider::setPageStepMode(bool pageStep)
{
Q_D(QtMaterialSlider);
d->pageStepMode = pageStep;
}
bool QtMaterialSlider::pageStepMode() const
{
Q_D(const QtMaterialSlider);
return d->pageStepMode;
}
/*!
* \remip
*/
QSize QtMaterialSlider::minimumSizeHint() const
{
return Qt::Horizontal == orientation()
? QSize(130, 34)
: QSize(34, 130);
}
void QtMaterialSlider::setInvertedAppearance(bool value)
{
QAbstractSlider::setInvertedAppearance(value);
updateThumbOffset();
}
/*!
* \remip
*/
void QtMaterialSlider::sliderChange(SliderChange change)
{
Q_D(QtMaterialSlider);
if (SliderOrientationChange == change)
{
QSizePolicy sp(QSizePolicy::Expanding, QSizePolicy::Fixed);
if (orientation() == Qt::Vertical) {
sp.transpose();
}
setSizePolicy(sp);
}
else if (SliderValueChange == change)
{
if (minimum() == value()) {
triggerAction(SliderToMinimum);
d->stateMachine->postEvent(new QtMaterialStateTransitionEvent(SliderChangedToMinimum));
} else if (maximum() == value()) {
triggerAction(SliderToMaximum);
}
if (minimum() == d->oldValue) {
d->stateMachine->postEvent(new QtMaterialStateTransitionEvent(SliderChangedFromMinimum));
}
d->oldValue = value();
}
updateThumbOffset();
QAbstractSlider::sliderChange(change);
}
/*!
* \remip
*/
void QtMaterialSlider::mouseMoveEvent(QMouseEvent *event)
{
Q_D(QtMaterialSlider);
if (isSliderDown())
{
setSliderPosition(d->valueFromPosition(event->pos()));
}
else
{
QRectF track(d->trackBoundingRect().adjusted(-2, -2, 2, 2));
if (track.contains(event->pos()) != d->hoverTrack) {
d->hoverTrack = !d->hoverTrack;
update();
}
QRectF thumb(0, 0, 16, 16);
thumb.moveCenter(d->thumbBoundingRect().center());
if (thumb.contains(event->pos()) != d->hoverThumb) {
d->hoverThumb = !d->hoverThumb;
update();
}
d->setHovered(d->hoverTrack || d->hoverThumb);
}
QAbstractSlider::mouseMoveEvent(event);
}
/*!
* \remip
*/
void QtMaterialSlider::mousePressEvent(QMouseEvent *event)
{
Q_D(QtMaterialSlider);
const QPoint pos = event->pos();
QRectF thumb(0, 0, 16, 16);
thumb.moveCenter(d->thumbBoundingRect().center());
if (thumb.contains(pos)) {
setSliderDown(true);
return;
}
if (!d->pageStepMode) {
setSliderPosition(d->valueFromPosition(event->pos()));
d->thumb->setHaloSize(0);
setSliderDown(true);
return;
}
d->step = true;
d->stepTo = d->valueFromPosition(pos);
SliderAction action = d->stepTo > sliderPosition()
? SliderPageStepAdd
: SliderPageStepSub;
triggerAction(action);
setRepeatAction(action, 400, 8);
}
/*!
* \remip
*/
void QtMaterialSlider::mouseReleaseEvent(QMouseEvent *event)
{
Q_D(QtMaterialSlider);
if (isSliderDown()) {
setSliderDown(false);
} else if (d->step) {
d->step = false;
setRepeatAction(SliderNoAction, 0);
}
QAbstractSlider::mouseReleaseEvent(event);
}
/*!
* \remip
*/
void QtMaterialSlider::leaveEvent(QEvent *event)
{
Q_D(QtMaterialSlider);
if (d->hoverTrack) {
d->hoverTrack = false;
update();
}
if (d->hoverThumb) {
d->hoverThumb = false;
update();
}
d->setHovered(false);
QAbstractSlider::leaveEvent(event);
}
void QtMaterialSlider::updateThumbOffset()
{
Q_D(QtMaterialSlider);
const int offset = QtMaterialStyle::sliderPositionFromValue(
minimum(),
maximum(),
sliderPosition(),
Qt::Horizontal == orientation()
? width() - QT_MATERIAL_SLIDER_MARGIN*2
: height() - QT_MATERIAL_SLIDER_MARGIN*2,
invertedAppearance());
d->thumb->setOffset(offset);
}

View File

@ -0,0 +1,58 @@
#ifndef QTMATERIALSLIDER_H
#define QTMATERIALSLIDER_H
#include <QtWidgets/QAbstractSlider>
#include <QScopedPointer>
#define QT_MATERIAL_SLIDER_MARGIN 30
class QtMaterialSliderPrivate;
class QtMaterialSlider : public QAbstractSlider
{
Q_OBJECT
Q_PROPERTY(QColor thumbColor WRITE setThumbColor READ thumbColor)
Q_PROPERTY(QColor trackColor WRITE setTrackColor READ trackColor)
Q_PROPERTY(QColor disabledColor WRITE setDisabledColor READ disabledColor)
public:
explicit QtMaterialSlider(QWidget *parent = 0);
~QtMaterialSlider();
void setUseThemeColors(bool value);
bool useThemeColors() const;
void setThumbColor(const QColor &color);
QColor thumbColor() const;
void setTrackColor(const QColor &color);
QColor trackColor() const;
void setDisabledColor(const QColor &color);
QColor disabledColor() const;
void setPageStepMode(bool pageStep);
bool pageStepMode() const;
QSize minimumSizeHint() const Q_DECL_OVERRIDE;
void setInvertedAppearance(bool value);
protected:
void sliderChange(SliderChange change) Q_DECL_OVERRIDE;
void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void leaveEvent(QEvent *event) Q_DECL_OVERRIDE;
void updateThumbOffset();
const QScopedPointer<QtMaterialSliderPrivate> d_ptr;
private:
Q_DISABLE_COPY(QtMaterialSlider)
Q_DECLARE_PRIVATE(QtMaterialSlider)
};
#endif // QTMATERIALSLIDER_H

View File

@ -0,0 +1,408 @@
#include "qtmaterialslider_internal.h"
#include <QState>
#include <QAbstractTransition>
#include <QSignalTransition>
#include <QEventTransition>
#include <QPropertyAnimation>
#include <QPainter>
#include "qtmaterialslider.h"
#include "lib/qtmaterialstyle.h"
#include "lib/qtmaterialstatetransition.h"
/*!
* \class QtMaterialSliderStateMachine
* \internal
*/
QtMaterialSliderStateMachine::QtMaterialSliderStateMachine(
QtMaterialSlider *slider,
QtMaterialSliderThumb *thumb,
QtMaterialSliderTrack *track)
: QStateMachine(slider),
m_slider(slider),
m_thumb(thumb),
m_track(track),
m_topState(new QState(QState::ParallelStates)),
m_fstState(new QState(m_topState)),
m_sndState(new QState(m_topState)),
m_inactiveState(new QState(m_fstState)),
m_focusState(new QState(m_fstState)),
m_slidingState(new QState(m_fstState)),
m_pulseOutState(new QState(m_focusState)),
m_pulseInState(new QState(m_focusState)),
m_minState(new QState(m_sndState)),
m_normalState(new QState(m_sndState))
{
addState(m_topState);
setInitialState(m_topState);
m_fstState->setInitialState(m_inactiveState);
m_focusState->setInitialState(m_pulseOutState);
m_inactiveState->assignProperty(thumb, "haloSize", 0);
m_slidingState->assignProperty(thumb, "haloSize", 0);
m_pulseOutState->assignProperty(thumb, "haloSize", 35);
m_pulseInState->assignProperty(thumb, "haloSize", 28);
m_inactiveState->assignProperty(thumb, "diameter", 11);
m_focusState->assignProperty(thumb, "diameter", 11);
m_slidingState->assignProperty(thumb, "diameter", 17);
QAbstractTransition *transition;
QtMaterialStateTransition *customTransition;
QPropertyAnimation *animation;
// Show halo on mouse enter
customTransition = new QtMaterialStateTransition(SliderNoFocusMouseEnter);
customTransition->setTargetState(m_focusState);
animation = new QPropertyAnimation(thumb, "haloSize", this);
animation->setEasingCurve(QEasingCurve::InOutSine);
customTransition->addAnimation(animation);
customTransition->addAnimation(new QPropertyAnimation(track, "fillColor", this));
m_inactiveState->addTransition(customTransition);
// Show halo on focus in
transition = new QEventTransition(slider, QEvent::FocusIn);
transition->setTargetState(m_focusState);
animation = new QPropertyAnimation(thumb, "haloSize", this);
animation->setEasingCurve(QEasingCurve::InOutSine);
transition->addAnimation(animation);
transition->addAnimation(new QPropertyAnimation(track, "fillColor", this));
m_inactiveState->addTransition(transition);
// Hide halo on focus out
transition = new QEventTransition(slider, QEvent::FocusOut);
transition->setTargetState(m_inactiveState);
animation = new QPropertyAnimation(thumb, "haloSize", this);
animation->setEasingCurve(QEasingCurve::InOutSine);
transition->addAnimation(animation);
transition->addAnimation(new QPropertyAnimation(track, "fillColor", this));
m_focusState->addTransition(transition);
// Hide halo on mouse leave, except if widget has focus
customTransition = new QtMaterialStateTransition(SliderNoFocusMouseLeave);
customTransition->setTargetState(m_inactiveState);
animation = new QPropertyAnimation(thumb, "haloSize", this);
animation->setEasingCurve(QEasingCurve::InOutSine);
customTransition->addAnimation(animation);
customTransition->addAnimation(new QPropertyAnimation(track, "fillColor", this));
m_focusState->addTransition(customTransition);
// Pulse in
transition = new QSignalTransition(m_pulseOutState, SIGNAL(propertiesAssigned()));
transition->setTargetState(m_pulseInState);
animation = new QPropertyAnimation(thumb, "haloSize", this);
animation->setEasingCurve(QEasingCurve::InOutSine);
animation->setDuration(1000);
transition->addAnimation(animation);
m_pulseOutState->addTransition(transition);
// Pulse out
transition = new QSignalTransition(m_pulseInState, SIGNAL(propertiesAssigned()));
transition->setTargetState(m_pulseOutState);
animation = new QPropertyAnimation(thumb, "haloSize", this);
animation->setEasingCurve(QEasingCurve::InOutSine);
animation->setDuration(1000);
transition->addAnimation(animation);
m_pulseInState->addTransition(transition);
// Slider pressed
transition = new QSignalTransition(slider, SIGNAL(sliderPressed()));
transition->setTargetState(m_slidingState);
animation = new QPropertyAnimation(thumb, "diameter", this);
animation->setDuration(70);
transition->addAnimation(animation);
animation = new QPropertyAnimation(thumb, "haloSize", this);
animation->setEasingCurve(QEasingCurve::InOutSine);
transition->addAnimation(animation);
m_focusState->addTransition(transition);
// Slider released
transition = new QSignalTransition(slider, SIGNAL(sliderReleased()));
transition->setTargetState(m_focusState);
animation = new QPropertyAnimation(thumb, "diameter", this);
animation->setDuration(70);
transition->addAnimation(animation);
animation = new QPropertyAnimation(thumb, "haloSize", this);
animation->setEasingCurve(QEasingCurve::InOutSine);
transition->addAnimation(animation);
m_slidingState->addTransition(transition);
// Min. value transitions
m_minState->assignProperty(thumb, "borderWidth", 2);
m_normalState->assignProperty(thumb, "borderWidth", 0);
m_sndState->setInitialState(m_minState);
customTransition = new QtMaterialStateTransition(SliderChangedFromMinimum);
customTransition->setTargetState(m_normalState);
animation = new QPropertyAnimation(thumb, "fillColor", this);
animation->setDuration(200);
customTransition->addAnimation(animation);
animation = new QPropertyAnimation(thumb, "haloColor", this);
animation->setDuration(300);
customTransition->addAnimation(animation);
animation = new QPropertyAnimation(thumb, "borderColor", this);
animation->setDuration(200);
customTransition->addAnimation(animation);
animation = new QPropertyAnimation(thumb, "borderWidth", this);
animation->setDuration(200);
customTransition->addAnimation(animation);
m_minState->addTransition(customTransition);
customTransition = new QtMaterialStateTransition(SliderChangedToMinimum);
customTransition->setTargetState(m_minState);
animation = new QPropertyAnimation(thumb, "fillColor", this);
animation->setDuration(200);
customTransition->addAnimation(animation);
animation = new QPropertyAnimation(thumb, "haloColor", this);
animation->setDuration(300);
customTransition->addAnimation(animation);
animation = new QPropertyAnimation(thumb, "borderColor", this);
animation->setDuration(200);
customTransition->addAnimation(animation);
animation = new QPropertyAnimation(thumb, "borderWidth", this);
animation->setDuration(200);
customTransition->addAnimation(animation);
m_normalState->addTransition(customTransition);
setupProperties();
}
QtMaterialSliderStateMachine::~QtMaterialSliderStateMachine()
{
}
void QtMaterialSliderStateMachine::setupProperties()
{
QColor trackColor = m_slider->trackColor();
QColor thumbColor = m_slider->thumbColor();
m_inactiveState->assignProperty(m_track, "fillColor", trackColor.lighter(130));
m_slidingState->assignProperty(m_track, "fillColor", trackColor);
m_focusState->assignProperty(m_track, "fillColor", trackColor);
QColor holeColor = m_slider->palette().color(QPalette::Base);
if (m_slider->parentWidget()) {
holeColor = m_slider->parentWidget()->palette().color(m_slider->backgroundRole());
}
m_minState->assignProperty(m_thumb, "fillColor", holeColor);
m_minState->assignProperty(m_thumb, "haloColor", trackColor);
m_minState->assignProperty(m_thumb, "borderColor", trackColor);
m_normalState->assignProperty(m_thumb, "fillColor", thumbColor);
m_normalState->assignProperty(m_thumb, "haloColor", thumbColor);
m_normalState->assignProperty(m_thumb, "borderColor", thumbColor);
m_slider->update();
}
/*!
* \class QtMaterialSliderThumb
* \internal
*/
QtMaterialSliderThumb::QtMaterialSliderThumb(QtMaterialSlider *slider)
: QtMaterialOverlayWidget(slider->parentWidget()),
m_slider(slider),
m_diameter(11),
m_borderWidth(2),
m_haloSize(0),
m_offset(0)
{
slider->installEventFilter(this);
setAttribute(Qt::WA_TransparentForMouseEvents, true);
}
QtMaterialSliderThumb::~QtMaterialSliderThumb()
{
}
bool QtMaterialSliderThumb::eventFilter(QObject *obj, QEvent *event)
{
if (QEvent::ParentChange == event->type()) {
setParent(m_slider->parentWidget());
}
return QtMaterialOverlayWidget::eventFilter(obj, event);
}
void QtMaterialSliderThumb::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
// Halo
QBrush brush;
brush.setStyle(Qt::SolidPattern);
brush.setColor(m_haloColor);
painter.setBrush(brush);
painter.setPen(Qt::NoPen);
QPointF disp = Qt::Horizontal == m_slider->orientation()
? QPointF(QT_MATERIAL_SLIDER_MARGIN + m_offset, m_slider->height()/2)
: QPointF(m_slider->width()/2, QT_MATERIAL_SLIDER_MARGIN + m_offset);
QRectF halo((m_slider->pos() - QPointF(m_haloSize, m_haloSize)/2) + disp,
QSizeF(m_haloSize, m_haloSize));
painter.setOpacity(0.15);
painter.drawEllipse(halo);
// Knob
const bool isMin = m_slider->value() == m_slider->minimum();
brush.setColor(m_slider->isEnabled()
? m_fillColor
: m_slider->disabledColor());
painter.setBrush(!m_slider->isEnabled() && isMin
? Qt::NoBrush
: brush);
if (m_slider->isEnabled() || isMin) {
QPen pen;
pen.setColor(m_borderColor);
pen.setWidthF((isMin && !m_slider->isEnabled()) ? 1.7 : m_borderWidth);
painter.setPen(pen);
} else {
painter.setPen(Qt::NoPen);
}
QRectF geometry = Qt::Horizontal == m_slider->orientation()
? QRectF(m_offset, m_slider->height()/2 - QT_MATERIAL_SLIDER_MARGIN,
QT_MATERIAL_SLIDER_MARGIN*2, QT_MATERIAL_SLIDER_MARGIN*2).translated(m_slider->pos())
: QRectF(m_slider->width()/2 - QT_MATERIAL_SLIDER_MARGIN, m_offset,
QT_MATERIAL_SLIDER_MARGIN*2, QT_MATERIAL_SLIDER_MARGIN*2).translated(m_slider->pos());
qreal s = m_slider->isEnabled() ? m_diameter : 7;
QRectF thumb(0, 0, s, s);
thumb.moveCenter(geometry.center());
painter.setOpacity(1);
painter.drawEllipse(thumb);
}
/*!
* \class QtMaterialSliderTrack
* \internal
*/
QtMaterialSliderTrack::QtMaterialSliderTrack(QtMaterialSliderThumb *thumb, QtMaterialSlider *slider)
: QtMaterialOverlayWidget(slider->parentWidget()),
m_slider(slider),
m_thumb(thumb),
m_trackWidth(2)
{
slider->installEventFilter(this);
setAttribute(Qt::WA_TransparentForMouseEvents, true);
connect(slider, SIGNAL(sliderMoved(int)), this, SLOT(update()));
}
QtMaterialSliderTrack::~QtMaterialSliderTrack()
{
}
bool QtMaterialSliderTrack::eventFilter(QObject *obj, QEvent *event)
{
if (QEvent::ParentChange == event->type()) {
setParent(m_slider->parentWidget());
}
return QtMaterialOverlayWidget::eventFilter(obj, event);
}
void QtMaterialSliderTrack::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
QBrush fg;
fg.setStyle(Qt::SolidPattern);
fg.setColor(m_slider->isEnabled() ? m_slider->thumbColor()
: m_slider->disabledColor());
QBrush bg;
bg.setStyle(Qt::SolidPattern);
bg.setColor(m_slider->isEnabled() ? m_fillColor
: m_slider->disabledColor());
qreal offset = m_thumb->offset();
if (Qt::Horizontal == m_slider->orientation()) {
painter.translate(m_slider->x() + QT_MATERIAL_SLIDER_MARGIN,
m_slider->y() + m_slider->height()/2
- static_cast<qreal>(m_trackWidth)/2);
} else {
painter.translate(m_slider->x() + m_slider->width()/2
- static_cast<qreal>(m_trackWidth)/2,
m_slider->y() + QT_MATERIAL_SLIDER_MARGIN);
}
QRectF geometry = Qt::Horizontal == m_slider->orientation()
? QRectF(0, 0, m_slider->width() - QT_MATERIAL_SLIDER_MARGIN*2, m_trackWidth)
: QRectF(0, 0, m_trackWidth, m_slider->height() - QT_MATERIAL_SLIDER_MARGIN*2);
QRectF bgRect;
QRectF fgRect;
if (Qt::Horizontal == m_slider->orientation()) {
fgRect = QRectF(0, 0, offset, m_trackWidth);
bgRect = QRectF(offset, 0, m_slider->width(), m_trackWidth).intersected(geometry);
} else {
fgRect = QRectF(0, 0, m_trackWidth, offset);
bgRect = QRectF(0, offset, m_trackWidth, m_slider->height()).intersected(geometry);
}
if (!m_slider->isEnabled()) {
fgRect = fgRect.width() < 9 ? QRectF() : fgRect.adjusted(0, 0, -6, 0);
bgRect = bgRect.width() < 9 ? QRectF() : bgRect.adjusted(6, 0, 0, 0);
}
if (m_slider->invertedAppearance()) {
qSwap(bgRect, fgRect);
}
painter.fillRect(bgRect, bg);
painter.fillRect(fgRect, fg);
}

View File

@ -0,0 +1,228 @@
#ifndef QTMATERIALSLIDER_INTERNAL_H
#define QTMATERIALSLIDER_INTERNAL_H
#include <QStateMachine>
#include "lib/qtmaterialoverlaywidget.h"
class QtMaterialSlider;
class QtMaterialSliderThumb;
class QtMaterialSliderTrack;
class QtMaterialSliderStateMachine : public QStateMachine
{
Q_OBJECT
public:
QtMaterialSliderStateMachine(QtMaterialSlider *slider,
QtMaterialSliderThumb *thumb,
QtMaterialSliderTrack *track);
~QtMaterialSliderStateMachine();
void setupProperties();
//signals:
// void changedToMinimum();
// void changedFromMinimum();
// void noFocusMouseEnter();
// void noFocusMouseLeave();
private:
Q_DISABLE_COPY(QtMaterialSliderStateMachine)
QtMaterialSlider *const m_slider;
QtMaterialSliderThumb *const m_thumb;
QtMaterialSliderTrack *const m_track;
QState *const m_topState;
QState *const m_fstState;
QState *const m_sndState;
QState *const m_inactiveState;
QState *const m_focusState;
QState *const m_slidingState;
QState *const m_pulseOutState;
QState *const m_pulseInState;
QState *const m_minState;
QState *const m_normalState;
};
class QtMaterialSliderThumb : public QtMaterialOverlayWidget
{
Q_OBJECT
Q_PROPERTY(qreal diameter WRITE setDiameter READ diameter)
Q_PROPERTY(qreal borderWidth WRITE setBorderWidth READ borderWidth)
Q_PROPERTY(QColor borderColor WRITE setBorderColor READ borderColor)
Q_PROPERTY(QColor fillColor WRITE setFillColor READ fillColor)
Q_PROPERTY(qreal haloSize WRITE setHaloSize READ haloSize)
Q_PROPERTY(QColor haloColor WRITE setHaloColor READ haloColor)
public:
explicit QtMaterialSliderThumb(QtMaterialSlider *slider);
~QtMaterialSliderThumb();
inline void setDiameter(qreal diameter);
inline qreal diameter() const;
inline void setBorderWidth(qreal width);
inline qreal borderWidth() const;
inline void setBorderColor(const QColor &color);
inline QColor borderColor() const;
inline void setFillColor(const QColor &color);
inline QColor fillColor() const;
inline void setHaloSize(qreal size);
inline qreal haloSize() const;
inline void setHaloColor(const QColor &color);
inline QColor haloColor() const;
inline void setOffset(int offset);
inline int offset() const;
protected:
bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE;
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
private:
Q_DISABLE_COPY(QtMaterialSliderThumb)
const QtMaterialSlider *const m_slider;
QColor m_borderColor;
QColor m_fillColor;
QColor m_haloColor;
qreal m_diameter;
qreal m_borderWidth;
qreal m_haloSize;
int m_offset;
};
inline void QtMaterialSliderThumb::setDiameter(qreal diameter)
{
m_diameter = diameter;
update();
}
inline qreal QtMaterialSliderThumb::diameter() const
{
return m_diameter;
}
inline void QtMaterialSliderThumb::setBorderWidth(qreal width)
{
m_borderWidth = width;
update();
}
inline qreal QtMaterialSliderThumb::borderWidth() const
{
return m_borderWidth;
}
inline void QtMaterialSliderThumb::setBorderColor(const QColor &color)
{
m_borderColor = color;
update();
}
inline QColor QtMaterialSliderThumb::borderColor() const
{
return m_borderColor;
}
inline void QtMaterialSliderThumb::setFillColor(const QColor &color)
{
m_fillColor = color;
update();
}
inline QColor QtMaterialSliderThumb::fillColor() const
{
return m_fillColor;
}
inline void QtMaterialSliderThumb::setHaloSize(qreal size)
{
m_haloSize = size;
update();
}
inline qreal QtMaterialSliderThumb::haloSize() const
{
return m_haloSize;
}
inline void QtMaterialSliderThumb::setHaloColor(const QColor &color)
{
m_haloColor = color;
update();
}
inline QColor QtMaterialSliderThumb::haloColor() const
{
return m_haloColor;
}
inline void QtMaterialSliderThumb::setOffset(int offset)
{
m_offset = offset;
update();
}
inline int QtMaterialSliderThumb::offset() const
{
return m_offset;
}
class QtMaterialSliderTrack : public QtMaterialOverlayWidget
{
Q_OBJECT
Q_PROPERTY(QColor fillColor WRITE setFillColor READ fillColor)
public:
explicit QtMaterialSliderTrack(QtMaterialSliderThumb *thumb, QtMaterialSlider *slider);
~QtMaterialSliderTrack();
inline void setFillColor(const QColor &color);
inline QColor fillColor() const;
inline void setTrackWidth(int width);
inline int trackWidth() const;
protected:
bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE;
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
private:
Q_DISABLE_COPY(QtMaterialSliderTrack)
const QtMaterialSlider *const m_slider;
QtMaterialSliderThumb *const m_thumb;
QColor m_fillColor;
int m_trackWidth;
};
inline void QtMaterialSliderTrack::setFillColor(const QColor &color)
{
m_fillColor = color;
update();
}
inline QColor QtMaterialSliderTrack::fillColor() const
{
return m_fillColor;
}
void QtMaterialSliderTrack::setTrackWidth(int width)
{
m_trackWidth = width;
update();
}
int QtMaterialSliderTrack::trackWidth() const
{
return m_trackWidth;
}
#endif // QTMATERIALSLIDER_INTERNAL_H

View File

@ -0,0 +1,49 @@
#ifndef QTMATERIALSLIDER_P_H
#define QTMATERIALSLIDER_P_H
#include <QtGlobal>
#include <QColor>
#include <QRectF>
class QtMaterialSlider;
class QtMaterialSliderThumb;
class QtMaterialSliderTrack;
class QtMaterialSliderStateMachine;
class QtMaterialSliderPrivate
{
Q_DISABLE_COPY(QtMaterialSliderPrivate)
Q_DECLARE_PUBLIC(QtMaterialSlider)
public:
QtMaterialSliderPrivate(QtMaterialSlider *q);
~QtMaterialSliderPrivate();
void init();
QRectF trackBoundingRect() const;
QRectF thumbBoundingRect() const;
int valueFromPosition(const QPoint &pos) const;
void setHovered(bool status);
QtMaterialSlider *const q_ptr;
QtMaterialSliderThumb *thumb;
QtMaterialSliderTrack *track;
QtMaterialSliderStateMachine *stateMachine;
QColor thumbColor;
QColor trackColor;
QColor disabledColor;
int stepTo;
int oldValue;
int trackWidth;
bool hoverTrack;
bool hoverThumb;
bool hover;
bool step;
bool pageStepMode;
bool useThemeColors;
};
#endif // QTMATERIALSLIDER_P_H

View File

@ -10,7 +10,8 @@ SOURCES = mainwindow.cpp \
flatbuttonsettingseditor.cpp \
iconbuttonsettingseditor.cpp \
progresssettingseditor.cpp \
circularprogresssettingseditor.cpp
circularprogresssettingseditor.cpp \
slidersettingseditor.cpp
HEADERS = mainwindow.h \
avatarsettingseditor.h \
badgesettingseditor.h \
@ -20,7 +21,8 @@ HEADERS = mainwindow.h \
flatbuttonsettingseditor.h \
iconbuttonsettingseditor.h \
progresssettingseditor.h \
circularprogresssettingseditor.h
circularprogresssettingseditor.h \
slidersettingseditor.h
LIBS += ../components/libcomponents.a
INCLUDEPATH += ../components/
TARGET = ../examples-exe
@ -36,4 +38,5 @@ FORMS += \
flatbuttonsettingsform.ui \
iconbuttonsettingsform.ui \
progresssettingsform.ui \
circularprogresssettingsform.ui
circularprogresssettingsform.ui \
slidersettingsform.ui

View File

@ -11,6 +11,7 @@
#include "iconbuttonsettingseditor.h"
#include "progresssettingseditor.h"
#include "circularprogresssettingseditor.h"
#include "slidersettingseditor.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
@ -39,6 +40,7 @@ MainWindow::MainWindow(QWidget *parent)
IconButtonSettingsEditor *iconButton = new IconButtonSettingsEditor;
ProgressSettingsEditor *progress = new ProgressSettingsEditor;
CircularProgressSettingsEditor *circularProgress = new CircularProgressSettingsEditor;
SliderSettingsEditor *slider = new SliderSettingsEditor;
stack->addWidget(avatar);
stack->addWidget(badge);
@ -49,6 +51,7 @@ MainWindow::MainWindow(QWidget *parent)
stack->addWidget(iconButton);
stack->addWidget(progress);
stack->addWidget(raisedButton);
stack->addWidget(slider);
list->addItem("Avatar");
list->addItem("Badge");
@ -59,6 +62,7 @@ MainWindow::MainWindow(QWidget *parent)
list->addItem("Icon Button");
list->addItem("Progress");
list->addItem("Raised Button");
list->addItem("Slider");
list->setCurrentRow(0);

View File

@ -0,0 +1,98 @@
#include "slidersettingseditor.h"
#include <QVBoxLayout>
#include <QColorDialog>
#include "qtmaterialslider.h"
SliderSettingsEditor::SliderSettingsEditor(QWidget *parent)
: QWidget(parent),
ui(new Ui::SliderSettingsForm),
m_slider(new QtMaterialSlider)
{
QVBoxLayout *layout = new QVBoxLayout;
setLayout(layout);
QWidget *widget = new QWidget;
layout->addWidget(widget);
QWidget *canvas = new QWidget;
canvas->setStyleSheet("QWidget { background: white; }");
layout->addWidget(canvas);
ui->setupUi(widget);
layout->setContentsMargins(20, 20, 20, 20);
layout = new QVBoxLayout;
canvas->setLayout(layout);
canvas->setMaximumHeight(300);
layout->addWidget(m_slider);
layout->setAlignment(m_slider, Qt::AlignHCenter);
setupForm();
connect(ui->disabledCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget()));
connect(ui->valueLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updateWidget()));
connect(ui->orientationComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateWidget()));
connect(ui->invertedCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget()));
connect(m_slider, SIGNAL(valueChanged(int)), this, SLOT(setupForm()));
}
SliderSettingsEditor::~SliderSettingsEditor()
{
delete ui;
}
void SliderSettingsEditor::setupForm()
{
switch (m_slider->orientation())
{
case Qt::Horizontal:
ui->orientationComboBox->setCurrentIndex(0);
break;
case Qt::Vertical:
ui->orientationComboBox->setCurrentIndex(1);
break;
default:
break;
}
ui->disabledCheckBox->setChecked(!m_slider->isEnabled());
ui->valueLineEdit->setText(QString::number(m_slider->value()));
ui->invertedCheckBox->setChecked(m_slider->invertedAppearance());
}
void SliderSettingsEditor::updateWidget()
{
switch (ui->orientationComboBox->currentIndex())
{
case 0:
m_slider->setOrientation(Qt::Horizontal);
break;
case 1:
m_slider->setOrientation(Qt::Vertical);
break;
default:
break;
}
m_slider->setDisabled(ui->disabledCheckBox->isChecked());
m_slider->setValue(ui->valueLineEdit->text().toInt());
m_slider->setInvertedAppearance(ui->invertedCheckBox->isChecked());
}
void SliderSettingsEditor::selectColor()
{
QColorDialog dialog;
if (dialog.exec()) {
QColor color = dialog.selectedColor();
QString senderName = sender()->objectName();
//if ("textColorToolButton" == senderName) {
// m_avatar->setTextColor(color);
// ui->textColorLineEdit->setText(color.name(QColor::HexRgb));
//} else if ("backgroundColorToolButton" == senderName) {
// m_avatar->setBackgroundColor(color);
// ui->backgroundColorLineEdit->setText(color.name(QColor::HexRgb));
//}
}
setupForm();
}

View File

@ -0,0 +1,27 @@
#ifndef SLIDERSETTINGSEDITOR_H
#define SLIDERSETTINGSEDITOR_H
#include <QWidget>
#include "ui_slidersettingsform.h"
class QtMaterialSlider;
class SliderSettingsEditor : public QWidget
{
Q_OBJECT
public:
explicit SliderSettingsEditor(QWidget *parent = 0);
~SliderSettingsEditor();
protected slots:
void setupForm();
void updateWidget();
void selectColor();
private:
Ui::SliderSettingsForm *const ui;
QtMaterialSlider *const m_slider;
};
#endif // SLIDERSETTINGSEDITOR_H

View File

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SliderSettingsForm</class>
<widget class="QWidget" name="SliderSettingsForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>474</width>
<height>387</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QWidget" name="formLayoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>361</width>
<height>331</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="disabledLabel">
<property name="text">
<string>Disabled</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="disabledCheckBox"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="valueLabel">
<property name="text">
<string>Value</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="valueLineEdit"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="orientationLabel">
<property name="text">
<string>Orientation</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="orientationComboBox">
<item>
<property name="text">
<string>Horizontal</string>
</property>
</item>
<item>
<property name="text">
<string>Vertical</string>
</property>
</item>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="invertedLabel">
<property name="text">
<string>Inverted</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="invertedCheckBox"/>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>