From 45393959fc4e078e5e879ad5042e1761d6f5ccb1 Mon Sep 17 00:00:00 2001 From: laserpants Date: Wed, 20 Jul 2016 14:48:39 +0300 Subject: [PATCH] snapshot --- components/dialog.cpp | 2 +- components/snackbar.cpp | 6 +- components/snackbar.h | 3 + components/toggle_internal.cpp | 18 ++ lib/rippleoverlay.cpp | 4 +- mainwindow.cpp | 169 ++++++++++------- mainwindow.h | 5 + qt-material-widgets.pro | 19 +- xx/qtmaterialslider.cpp | 67 +++++-- xx/qtmaterialslider.h | 9 +- xx/qtmaterialslider_internal.cpp | 42 +++-- xx/qtmaterialslider_internal.h | 18 +- xx/qtmaterialslider_p.h | 4 - xx/qtmaterialsnackbar.cpp | 170 +++++++++++++++++ xx/qtmaterialsnackbar.h | 48 +++++ xx/qtmaterialsnackbar_internal.cpp | 35 ++++ xx/qtmaterialsnackbar_internal.h | 35 ++++ xx/qtmaterialsnackbar_p.h | 31 +++ xx/qtmaterialtextfield.cpp | 11 +- xx/qtmaterialtoggle.cpp | 290 +++++++++++++++++++++++++++++ xx/qtmaterialtoggle.h | 52 ++++++ xx/qtmaterialtoggle_internal.cpp | 231 +++++++++++++++++++++++ xx/qtmaterialtoggle_internal.h | 120 ++++++++++++ xx/qtmaterialtoggle_p.h | 41 ++++ xxlib/qtmaterialoverlaywidget.h | 2 +- xxlib/qtmaterialrippleoverlay.h | 7 + yy/slidersettingseditor.cpp | 62 +++++- yy/slidersettingsform.ui | 41 ++++ yy/togglesettingseditor.cpp | 113 +++++++++++ yy/togglesettingseditor.h | 27 +++ yy/togglesettingsform.ui | 166 +++++++++++++++++ 31 files changed, 1720 insertions(+), 128 deletions(-) create mode 100644 xx/qtmaterialsnackbar.cpp create mode 100644 xx/qtmaterialsnackbar.h create mode 100644 xx/qtmaterialsnackbar_internal.cpp create mode 100644 xx/qtmaterialsnackbar_internal.h create mode 100644 xx/qtmaterialsnackbar_p.h create mode 100644 xx/qtmaterialtoggle.cpp create mode 100644 xx/qtmaterialtoggle.h create mode 100644 xx/qtmaterialtoggle_internal.cpp create mode 100644 xx/qtmaterialtoggle_internal.h create mode 100644 xx/qtmaterialtoggle_p.h create mode 100644 yy/togglesettingseditor.cpp create mode 100644 yy/togglesettingseditor.h create mode 100644 yy/togglesettingsform.ui diff --git a/components/dialog.cpp b/components/dialog.cpp index ef2feb3..0457ee0 100644 --- a/components/dialog.cpp +++ b/components/dialog.cpp @@ -210,7 +210,7 @@ void Dialog::paintEvent(QPaintEvent *event) brush.setColor(Qt::black); painter.setBrush(brush); painter.setPen(Qt::NoPen); - painter.setOpacity(d->proxy->opacity()/2); + painter.setOpacity(d->proxy->opacity()/3); painter.drawRect(rect()); } diff --git a/components/snackbar.cpp b/components/snackbar.cpp index 82e12b5..93fcbe7 100644 --- a/components/snackbar.cpp +++ b/components/snackbar.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "snackbar_internal.h" SnackbarPrivate::SnackbarPrivate(Snackbar *q) @@ -25,8 +26,9 @@ void SnackbarPrivate::init() q->setAttribute(Qt::WA_TransparentForMouseEvents); - QFont font(q->font()); - font.setPointSizeF(11); + QFontDatabase db; + QFont font(db.font("Roboto", "Medium", 10)); + font.setCapitalization(QFont::AllUppercase); q->setFont(font); backgroundColor = QColor(0, 0, 0, 220); diff --git a/components/snackbar.h b/components/snackbar.h index 6b92fba..c9ff0e4 100644 --- a/components/snackbar.h +++ b/components/snackbar.h @@ -23,6 +23,9 @@ public: void setAutoHideDuration(int duration); int autoHideDuration() const; + void setUseThemeColors(bool value); + bool useThemeColors() const; + void setBackgroundColor(const QColor &color); QColor backgroundColor() const; diff --git a/components/toggle_internal.cpp b/components/toggle_internal.cpp index f0787dc..871eba1 100644 --- a/components/toggle_internal.cpp +++ b/components/toggle_internal.cpp @@ -79,6 +79,15 @@ void ToggleThumb::paintEvent(QPaintEvent *event) painter.setBrush(brush); painter.drawEllipse(r); } + + // + + QPen p; + p.setWidth(2); + p.setColor(Qt::red); + painter.setPen(p); + painter.setBrush(Qt::NoBrush); + painter.drawRect(rect()); } void ToggleThumb::updateOffset() @@ -147,4 +156,13 @@ void ToggleTrack::paintEvent(QPaintEvent *event) const QRect r(w/2, 0, w, height()); painter.drawRoundedRect(r.adjusted(4, 14, -4, -14), w/2-4, w/2-4); } + + // + + QPen p; + p.setWidth(2); + p.setColor(Qt::red); + painter.setPen(p); + painter.setBrush(Qt::NoBrush); + painter.drawRect(rect()); } diff --git a/lib/rippleoverlay.cpp b/lib/rippleoverlay.cpp index c4cc5bb..5d9a9d8 100644 --- a/lib/rippleoverlay.cpp +++ b/lib/rippleoverlay.cpp @@ -60,15 +60,13 @@ void RippleOverlay::paintEvent(QPaintEvent *event) painter.drawEllipse(center, radius, radius); } -#ifdef DEBUG_LAYOUT QPen pen; - pen.setColor(Qt::red); + pen.setColor(Qt::blue); pen.setWidth(2); painter.setOpacity(1); painter.setPen(pen); painter.setBrush(Qt::NoBrush); painter.drawRect(rect()); -#endif } void RippleOverlay::deleteRipple() diff --git a/mainwindow.cpp b/mainwindow.cpp index d2d07de..e5a74c0 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -52,15 +52,24 @@ #include "components/toggle.h" #include "xx/qtmaterialslider.h" #include "yy/slidersettingseditor.h" +#include "xx/qtmaterialtoggle.h" +#include "yy/togglesettingseditor.h" +#include "components/snackbar.h" +#include "xx/qtmaterialsnackbar.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), _menu(new MenuPlus) { - SliderSettingsEditor *editor = new SliderSettingsEditor; - setCentralWidget(editor); + //ToggleSettingsEditor *editor = new ToggleSettingsEditor; + //setCentralWidget(editor); - return; + //return; + + //SliderSettingsEditor *editor = new SliderSettingsEditor; + //setCentralWidget(editor); + + //return; //TextFieldSettingsEditor *editor = new TextFieldSettingsEditor; //setCentralWidget(editor); @@ -119,68 +128,73 @@ MainWindow::MainWindow(QWidget *parent) //setCentralWidget(ed); - _menu->addMenuItem("Menu item #1"); - _menu->addMenuItem("Menu item #2"); - _menu->addMenuItem("Menu item #3"); - //menu->setFixedSize(200, 250); - _menu->setMaximumHeight(250); - _menu->setMinimumWidth(300); - +// _menu->addMenuItem("Menu item #1"); +// _menu->addMenuItem("Menu item #2"); +// _menu->addMenuItem("Menu item #3"); +// //menu->setFixedSize(200, 250); +// _menu->setMaximumHeight(250); +// _menu->setMinimumWidth(300); +// QWidget *widget = new QWidget; QVBoxLayout *layout = new QVBoxLayout; widget->setLayout(layout); setCentralWidget(widget); - widget->setStyleSheet("QWidget { background: white; }"); - - - Slider *sldr = new Slider; - Slider *sldr2 = new Slider; - QtMaterialSlider *sldr3 = new QtMaterialSlider; - - Toggle *tgl = new Toggle; - - layout->addStretch(); - layout->addWidget(sldr); - layout->addWidget(sldr2); - layout->addWidget(sldr3); - layout->addWidget(tgl); - layout->addStretch(); - - return; - - QStackedLayout *stack = new QStackedLayout; - stack->addWidget(new QLabel("
First
")); - stack->addWidget(new QLabel("
Second
")); - stack->addWidget(new QLabel("
Third
")); - - Tabs *tabs = new Tabs; - layout->addWidget(tabs); - layout->addLayout(stack); - layout->setContentsMargins(0, 0, 0, 0); - - tabs->addTab("First", QIcon("../qt-material-widgets/ic_star_black_24px.svg")); - tabs->addTab("Second", QIcon("../qt-material-widgets/ic_star_black_24px.svg")); - tabs->addTab("Third", QIcon("../qt-material-widgets/ic_star_black_24px.svg")); - - // - - QtMaterialTabs *_tabs = new QtMaterialTabs; - layout->addWidget(_tabs); - layout->setContentsMargins(0, 0, 0, 0); - - _tabs->addTab("First", QIcon("../qt-material-widgets/ic_star_black_24px.svg")); - _tabs->addTab("Second", QIcon("../qt-material-widgets/ic_star_black_24px.svg")); - _tabs->addTab("Third", QIcon("../qt-material-widgets/ic_star_black_24px.svg")); - - QStackedLayout *stack2 = new QStackedLayout; - stack2->addWidget(new QLabel("
First
")); - stack2->addWidget(new QLabel("
Second
")); - stack2->addWidget(new QLabel("
Third
")); - - layout->addLayout(stack2); - - connect(_tabs, SIGNAL(currentChanged(int)), stack2, SLOT(setCurrentIndex(int))); +// widget->setStyleSheet("QWidget { background: white; }"); +// +// +// Slider *sldr = new Slider; +// Slider *sldr2 = new Slider; +// QtMaterialSlider *sldr3 = new QtMaterialSlider; +// +// Toggle *tgl = new Toggle; +// QtMaterialToggle *tgl2 = new QtMaterialToggle; +// +// layout->addStretch(); +// //layout->addWidget(sldr); +// //layout->addWidget(sldr2); +// //layout->addWidget(sldr3); +// layout->addWidget(tgl); +// layout->addStretch(); +// layout->addWidget(tgl2); +// layout->setAlignment(tgl, Qt::AlignCenter); +// layout->setAlignment(tgl2, Qt::AlignCenter); +// layout->addStretch(); +// +// return; +// +// QStackedLayout *stack = new QStackedLayout; +// stack->addWidget(new QLabel("
First
")); +// stack->addWidget(new QLabel("
Second
")); +// stack->addWidget(new QLabel("
Third
")); +// +// Tabs *tabs = new Tabs; +// layout->addWidget(tabs); +// layout->addLayout(stack); +// layout->setContentsMargins(0, 0, 0, 0); +// +// tabs->addTab("First", QIcon("../qt-material-widgets/ic_star_black_24px.svg")); +// tabs->addTab("Second", QIcon("../qt-material-widgets/ic_star_black_24px.svg")); +// tabs->addTab("Third", QIcon("../qt-material-widgets/ic_star_black_24px.svg")); +// +// // +// +// QtMaterialTabs *_tabs = new QtMaterialTabs; +// layout->addWidget(_tabs); +// layout->setContentsMargins(0, 0, 0, 0); +// +// _tabs->addTab("First", QIcon("../qt-material-widgets/ic_star_black_24px.svg")); +// _tabs->addTab("Second", QIcon("../qt-material-widgets/ic_star_black_24px.svg")); +// _tabs->addTab("Third", QIcon("../qt-material-widgets/ic_star_black_24px.svg")); +// +// QStackedLayout *stack2 = new QStackedLayout; +// stack2->addWidget(new QLabel("
First
")); +// stack2->addWidget(new QLabel("
Second
")); +// stack2->addWidget(new QLabel("
Third
")); +// +// layout->addLayout(stack2); +// +// connect(_tabs, SIGNAL(currentChanged(int)), stack2, SLOT(setCurrentIndex(int))); /* QtMaterialIconButton *btn = new QtMaterialIconButton(QIcon("../qt-material-widgets/ic_star_black_24px.svg")); @@ -194,9 +208,13 @@ MainWindow::MainWindow(QWidget *parent) TextField *tf = new TextField; layout->addWidget(tf); layout->addStretch(); + */ + + Drawer *drwer = new Drawer; + drwer->setParent(this); Dialog *dlg = new Dialog; - dlg->setParent(this); + //dlg->setParent(this); //dlg->windowLayout()->addWidget(new QPushButton("Hello")); QVBoxLayout *dl = new QVBoxLayout; @@ -206,12 +224,28 @@ MainWindow::MainWindow(QWidget *parent) QPushButton *bbbtn = new QPushButton("Show dialog"); layout->addWidget(bbbtn); - connect(bbbtn, SIGNAL(pressed()), dlg, SLOT(showDialog())); + //connect(bbbtn, SIGNAL(pressed()), dlg, SLOT(showDialog())); + connect(bbbtn, SIGNAL(pressed()), drwer, SLOT(openDrawer())); QtMaterialIconMenu *im = new QtMaterialIconMenu(QIcon("../qt-material-widgets/ic_star_black_24px.svg")); layout->addWidget(im); layout->setAlignment(im, Qt::AlignCenter); + snackbar = new Snackbar; + snackbar->setParent(this); + + snackbar2 = new QtMaterialSnackbar; + snackbar2->setParent(this); + + // + + QPushButton *btn = new QPushButton; + btn->setText("Show Snackbar"); + layout->addWidget(btn); + + connect(btn, SIGNAL(pressed()), this, SLOT(hello())); + + { im->addMenuItem("C"); im->addMenuItem("C++"); @@ -223,6 +257,8 @@ MainWindow::MainWindow(QWidget *parent) im->addMenuItem("F#"); im->addMenuItem("Clojure"); im->addMenuItem("Java"); + + im->itemAt(8)->setDisabled(true); } QtMaterialSelectField *sfp = new QtMaterialSelectField; @@ -244,7 +280,6 @@ MainWindow::MainWindow(QWidget *parent) } layout->addStretch(); - */ //layout->setAlignment(sfp, Qt::AlignCenter); @@ -1022,3 +1057,11 @@ void MainWindow::button4Pressed() { _menu->collapse(); } + +void MainWindow::hello() +{ + static int n = 0; + ++n; + //snackbar->addMessage(QString("Hello from the Snackbar (%1)").arg(n)); + snackbar2->addMessage(QString("Hello from the Snackbar (%1)").arg(n)); +} diff --git a/mainwindow.h b/mainwindow.h index 38685ae..b2990f3 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -4,6 +4,8 @@ #include class MenuPlus; +class Snackbar; +class QtMaterialSnackbar; class MainWindow : public QMainWindow { @@ -25,11 +27,14 @@ protected slots: void button2Pressed(); void button3Pressed(); void button4Pressed(); + void hello(); private: void _initMenu() const; MenuPlus *_menu; + Snackbar *snackbar; + QtMaterialSnackbar *snackbar2; }; /* diff --git a/qt-material-widgets.pro b/qt-material-widgets.pro index 5d972cb..b85e40f 100644 --- a/qt-material-widgets.pro +++ b/qt-material-widgets.pro @@ -130,7 +130,12 @@ SOURCES += main.cpp\ xx/qtmaterialtabs_internal.cpp \ xx/qtmaterialslider.cpp \ xx/qtmaterialslider_internal.cpp \ - yy/slidersettingseditor.cpp + yy/slidersettingseditor.cpp \ + xx/qtmaterialtoggle.cpp \ + xx/qtmaterialtoggle_internal.cpp \ + yy/togglesettingseditor.cpp \ + xx/qtmaterialsnackbar.cpp \ + xx/qtmaterialsnackbar_internal.cpp HEADERS += mainwindow.h \ components/appbar.h \ @@ -296,7 +301,14 @@ HEADERS += mainwindow.h \ xx/qtmaterialslider.h \ xx/qtmaterialslider_p.h \ xx/qtmaterialslider_internal.h \ - yy/slidersettingseditor.h + yy/slidersettingseditor.h \ + xx/qtmaterialtoggle.h \ + xx/qtmaterialtoggle_p.h \ + xx/qtmaterialtoggle_internal.h \ + yy/togglesettingseditor.h \ + xx/qtmaterialsnackbar.h \ + xx/qtmaterialsnackbar_p.h \ + xx/qtmaterialsnackbar_internal.h RESOURCES += \ resources.qrc @@ -313,4 +325,5 @@ FORMS += \ yy/circularprogresssettingsform.ui \ yy/progresssettingsform.ui \ yy/textfieldsettingsform.ui \ - yy/slidersettingsform.ui + yy/slidersettingsform.ui \ + yy/togglesettingsform.ui diff --git a/xx/qtmaterialslider.cpp b/xx/qtmaterialslider.cpp index 0ff7507..b249675 100644 --- a/xx/qtmaterialslider.cpp +++ b/xx/qtmaterialslider.cpp @@ -24,7 +24,7 @@ void QtMaterialSliderPrivate::init() Q_Q(QtMaterialSlider); thumb = new QtMaterialSliderThumb(q); - track = new QtMaterialSliderTrack(q); + track = new QtMaterialSliderTrack(thumb, q); stateMachine = new QtMaterialSliderStateMachine(q, thumb, track); stepTo = 0; oldValue = q->value(); @@ -61,10 +61,10 @@ QRectF QtMaterialSliderPrivate::trackBoundingRect() const qreal hw = static_cast(trackWidth)/2; return Qt::Horizontal == q->orientation() - ? QRectF(SliderMargin, q->height()/2 - hw, - q->width() - SliderMargin*2, hw*2) - : QRectF(q->width()/2 - hw, SliderMargin, hw*2, - q->height() - SliderMargin*2); + ? 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 @@ -72,10 +72,10 @@ QRectF QtMaterialSliderPrivate::thumbBoundingRect() const Q_Q(const QtMaterialSlider); return Qt::Horizontal == q->orientation() - ? QRectF(q->thumbOffset(), q->height()/2 - SliderMargin, - SliderMargin*2, SliderMargin*2) - : QRectF(q->width()/2 - SliderMargin, q->thumbOffset(), - SliderMargin*2, SliderMargin*2); + ? 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 @@ -85,13 +85,13 @@ int QtMaterialSliderPrivate::valueFromPosition(const QPoint &pos) const const int position = Qt::Horizontal == q->orientation() ? pos.x() : pos.y(); const int span = Qt::Horizontal == q->orientation() - ? q->width() - SliderMargin*2 - : q->height() - SliderMargin*2; + ? q->width() - QT_MATERIAL_SLIDER_MARGIN*2 + : q->height() - QT_MATERIAL_SLIDER_MARGIN*2; return QtMaterialStyle::sliderValueFromPosition( q->minimum(), q->maximum(), - position - SliderMargin, + position - QT_MATERIAL_SLIDER_MARGIN, span, q->invertedAppearance()); } @@ -218,13 +218,26 @@ bool QtMaterialSlider::pageStepMode() const return d->pageStepMode; } +/*! + * \remip + */ QSize QtMaterialSlider::minimumSizeHint() const { return Qt::Horizontal == orientation() - ? QSize(20, 34) - : QSize(34, 20); + ? QSize(130, 34) + : QSize(34, 130); } +void QtMaterialSlider::setInvertedAppearance(bool value) +{ + QAbstractSlider::setInvertedAppearance(value); + + updateThumbOffset(); +} + +/*! + * \remip + */ void QtMaterialSlider::sliderChange(SliderChange change) { Q_D(QtMaterialSlider); @@ -251,9 +264,14 @@ void QtMaterialSlider::sliderChange(SliderChange change) d->oldValue = value(); } + updateThumbOffset(); + QAbstractSlider::sliderChange(change); } +/*! + * \remip + */ void QtMaterialSlider::mouseMoveEvent(QMouseEvent *event) { Q_D(QtMaterialSlider); @@ -285,6 +303,9 @@ void QtMaterialSlider::mouseMoveEvent(QMouseEvent *event) QAbstractSlider::mouseMoveEvent(event); } +/*! + * \remip + */ void QtMaterialSlider::mousePressEvent(QMouseEvent *event) { Q_D(QtMaterialSlider); @@ -317,6 +338,9 @@ void QtMaterialSlider::mousePressEvent(QMouseEvent *event) setRepeatAction(action, 400, 8); } +/*! + * \remip + */ void QtMaterialSlider::mouseReleaseEvent(QMouseEvent *event) { Q_D(QtMaterialSlider); @@ -331,6 +355,9 @@ void QtMaterialSlider::mouseReleaseEvent(QMouseEvent *event) QAbstractSlider::mouseReleaseEvent(event); } +/*! + * \remip + */ void QtMaterialSlider::leaveEvent(QEvent *event) { Q_D(QtMaterialSlider); @@ -349,14 +376,18 @@ void QtMaterialSlider::leaveEvent(QEvent *event) QAbstractSlider::leaveEvent(event); } -int QtMaterialSlider::thumbOffset() const +void QtMaterialSlider::updateThumbOffset() { - return QtMaterialStyle::sliderPositionFromValue( + Q_D(QtMaterialSlider); + + const int offset = QtMaterialStyle::sliderPositionFromValue( minimum(), maximum(), sliderPosition(), Qt::Horizontal == orientation() - ? width() - QtMaterialSliderPrivate::SliderMargin*2 - : height() - QtMaterialSliderPrivate::SliderMargin*2, + ? width() - QT_MATERIAL_SLIDER_MARGIN*2 + : height() - QT_MATERIAL_SLIDER_MARGIN*2, invertedAppearance()); + + d->thumb->setOffset(offset); } diff --git a/xx/qtmaterialslider.h b/xx/qtmaterialslider.h index 96f8262..06fab32 100644 --- a/xx/qtmaterialslider.h +++ b/xx/qtmaterialslider.h @@ -4,6 +4,8 @@ #include #include +#define QT_MATERIAL_SLIDER_MARGIN 30 + class QtMaterialSliderPrivate; class QtMaterialSlider : public QAbstractSlider @@ -35,6 +37,8 @@ public: 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; @@ -42,10 +46,7 @@ protected: void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void leaveEvent(QEvent *event) Q_DECL_OVERRIDE; - friend class QtMaterialSliderThumb; - friend class QtMaterialSliderTrack; - - int thumbOffset() const; + void updateThumbOffset(); const QScopedPointer d_ptr; diff --git a/xx/qtmaterialslider_internal.cpp b/xx/qtmaterialslider_internal.cpp index 130adb2..6b0437e 100644 --- a/xx/qtmaterialslider_internal.cpp +++ b/xx/qtmaterialslider_internal.cpp @@ -8,10 +8,6 @@ #include "xx/qtmaterialslider.h" #include "xxlib/qtmaterialstyle.h" -enum { - SliderMargin = 30 -}; - /*! * \class QtMaterialSliderStateMachine * \internal @@ -212,8 +208,14 @@ void QtMaterialSliderStateMachine::setupProperties() m_slidingState->assignProperty(m_track, "fillColor", trackColor); m_focusState->assignProperty(m_track, "fillColor", trackColor); - //m_minState->assignProperty(_thumb, "fillColor", slider->palette().color(QPalette::Base)); - m_minState->assignProperty(m_thumb, "fillColor", QColor(Qt::red)); + 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); @@ -234,7 +236,8 @@ QtMaterialSliderThumb::QtMaterialSliderThumb(QtMaterialSlider *slider) m_slider(slider), m_diameter(11), m_borderWidth(2), - m_haloSize(0) + m_haloSize(0), + m_offset(0) { slider->installEventFilter(this); @@ -270,8 +273,8 @@ void QtMaterialSliderThumb::paintEvent(QPaintEvent *event) painter.setPen(Qt::NoPen); QPointF disp = Qt::Horizontal == m_slider->orientation() - ? QPointF(SliderMargin + m_slider->thumbOffset(), m_slider->height()/2) - : QPointF(m_slider->width()/2, SliderMargin + m_slider->thumbOffset()); + ? 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)); @@ -300,10 +303,10 @@ void QtMaterialSliderThumb::paintEvent(QPaintEvent *event) } QRectF geometry = Qt::Horizontal == m_slider->orientation() - ? QRectF(m_slider->thumbOffset(), m_slider->height()/2 - SliderMargin, - SliderMargin*2, SliderMargin*2).translated(m_slider->pos()) - : QRectF(m_slider->width()/2 - SliderMargin, m_slider->thumbOffset(), - SliderMargin*2, SliderMargin*2).translated(m_slider->pos()); + ? 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; @@ -320,9 +323,10 @@ void QtMaterialSliderThumb::paintEvent(QPaintEvent *event) * \internal */ -QtMaterialSliderTrack::QtMaterialSliderTrack(QtMaterialSlider *slider) +QtMaterialSliderTrack::QtMaterialSliderTrack(QtMaterialSliderThumb *thumb, QtMaterialSlider *slider) : QtMaterialOverlayWidget(slider->parentWidget()), m_slider(slider), + m_thumb(thumb), m_trackWidth(2) { slider->installEventFilter(this); @@ -361,21 +365,21 @@ void QtMaterialSliderTrack::paintEvent(QPaintEvent *event) bg.setColor(m_slider->isEnabled() ? m_fillColor : m_slider->disabledColor()); - qreal offset = m_slider->thumbOffset(); + qreal offset = m_thumb->offset(); if (Qt::Horizontal == m_slider->orientation()) { - painter.translate(m_slider->x() + SliderMargin, + painter.translate(m_slider->x() + QT_MATERIAL_SLIDER_MARGIN, m_slider->y() + m_slider->height()/2 - static_cast(m_trackWidth)/2); } else { painter.translate(m_slider->x() + m_slider->width()/2 - static_cast(m_trackWidth)/2, - m_slider->y() + SliderMargin); + m_slider->y() + QT_MATERIAL_SLIDER_MARGIN); } QRectF geometry = Qt::Horizontal == m_slider->orientation() - ? QRectF(0, 0, m_slider->width() - SliderMargin*2, m_trackWidth) - : QRectF(0, 0, m_trackWidth, m_slider->height() - SliderMargin*2); + ? 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; diff --git a/xx/qtmaterialslider_internal.h b/xx/qtmaterialslider_internal.h index 6ab6708..4c6272c 100644 --- a/xx/qtmaterialslider_internal.h +++ b/xx/qtmaterialslider_internal.h @@ -77,6 +77,9 @@ public: 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; @@ -91,6 +94,7 @@ private: qreal m_diameter; qreal m_borderWidth; qreal m_haloSize; + int m_offset; }; inline void QtMaterialSliderThumb::setDiameter(qreal diameter) @@ -159,6 +163,17 @@ 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 @@ -166,7 +181,7 @@ class QtMaterialSliderTrack : public QtMaterialOverlayWidget Q_PROPERTY(QColor fillColor WRITE setFillColor READ fillColor) public: - explicit QtMaterialSliderTrack(QtMaterialSlider *slider); + explicit QtMaterialSliderTrack(QtMaterialSliderThumb *thumb, QtMaterialSlider *slider); ~QtMaterialSliderTrack(); inline void setFillColor(const QColor &color); @@ -183,6 +198,7 @@ private: Q_DISABLE_COPY(QtMaterialSliderTrack) const QtMaterialSlider *const m_slider; + QtMaterialSliderThumb *const m_thumb; QColor m_fillColor; int m_trackWidth; }; diff --git a/xx/qtmaterialslider_p.h b/xx/qtmaterialslider_p.h index 6946244..ff6b7ca 100644 --- a/xx/qtmaterialslider_p.h +++ b/xx/qtmaterialslider_p.h @@ -16,10 +16,6 @@ class QtMaterialSliderPrivate Q_DECLARE_PUBLIC(QtMaterialSlider) public: - enum { - SliderMargin = 30 - }; - QtMaterialSliderPrivate(QtMaterialSlider *q); ~QtMaterialSliderPrivate(); diff --git a/xx/qtmaterialsnackbar.cpp b/xx/qtmaterialsnackbar.cpp new file mode 100644 index 0000000..1cfc08e --- /dev/null +++ b/xx/qtmaterialsnackbar.cpp @@ -0,0 +1,170 @@ +#include "xx/qtmaterialsnackbar.h" +#include "xx/qtmaterialsnackbar_p.h" +#include +#include +#include "xx/qtmaterialsnackbar_internal.h" +#include "xxlib/qtmaterialstyle.h" + +/*! + * \class QtMaterialSnackbarPrivate + * \internal + */ + +QtMaterialSnackbarPrivate::QtMaterialSnackbarPrivate(QtMaterialSnackbar *q) + : q_ptr(q) +{ +} + +QtMaterialSnackbarPrivate::~QtMaterialSnackbarPrivate() +{ +} + +void QtMaterialSnackbarPrivate::init() +{ + Q_Q(QtMaterialSnackbar); + + stateMachine = new QtMaterialSnackbarStateMachine(q); + duration = 3000; + boxWidth = 300; + useThemeColors = true; + + q->setAttribute(Qt::WA_TransparentForMouseEvents); + + stateMachine->start(); + QCoreApplication::processEvents(); +} + +/*! + * \class QtMaterialSnackbar + */ + +QtMaterialSnackbar::QtMaterialSnackbar(QWidget *parent) + : QtMaterialOverlayWidget(parent), + d_ptr(new QtMaterialSnackbarPrivate(this)) +{ + d_func()->init(); +} + +QtMaterialSnackbar::~QtMaterialSnackbar() +{ +} + +void QtMaterialSnackbar::setAutoHideDuration(int duration) +{ + Q_D(QtMaterialSnackbar); + + d->duration = duration; +} + +int QtMaterialSnackbar::autoHideDuration() const +{ + Q_D(const QtMaterialSnackbar); + + return d->duration; +} + +void QtMaterialSnackbar::setUseThemeColors(bool value) +{ + Q_D(QtMaterialSnackbar); + + if (d->useThemeColors == value) { + return; + } + + d->useThemeColors = value; + update(); +} + +bool QtMaterialSnackbar::useThemeColors() const +{ + Q_D(const QtMaterialSnackbar); + + return d->useThemeColors; +} + +void QtMaterialSnackbar::setBackgroundColor(const QColor &color) +{ + Q_D(QtMaterialSnackbar); + + d->backgroundColor = color; + setUseThemeColors(false); +} + +QColor QtMaterialSnackbar::backgroundColor() const +{ + Q_D(const QtMaterialSnackbar); + + if (d->useThemeColors || !d->backgroundColor.isValid()) { + return QtMaterialStyle::instance().themeColor("text"); + } else { + return d->backgroundColor; + } +} + +void QtMaterialSnackbar::setTextColor(const QColor &color) +{ + Q_D(QtMaterialSnackbar); + + d->textColor = color; + setUseThemeColors(false); +} + +QColor QtMaterialSnackbar::textColor() const +{ + Q_D(const QtMaterialSnackbar); + + if (d->useThemeColors || !d->textColor.isValid()) { + return QtMaterialStyle::instance().themeColor("canvas"); + } else { + return d->textColor; + } +} + +void QtMaterialSnackbar::setFontSize(qreal size) +{ + QFont f(font()); + f.setPointSizeF(size); + setFont(f); + + update(); +} + +qreal QtMaterialSnackbar::fontSize() const +{ + return font().pointSizeF(); +} + +void QtMaterialSnackbar::setBoxWidth(int width) +{ + Q_D(QtMaterialSnackbar); + + d->boxWidth = width; + update(); +} + +int QtMaterialSnackbar::boxWidth() const +{ + Q_D(const QtMaterialSnackbar); + + return d->boxWidth; +} + +void QtMaterialSnackbar::addMessage(const QString &message) +{ +} + +void QtMaterialSnackbar::addInstantMessage(const QString &message) +{ +} + +void QtMaterialSnackbar::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + + QPainter painter(this); + + QPen p; + p.setWidth(3); + p.setColor(Qt::red); + painter.setPen(p); +} diff --git a/xx/qtmaterialsnackbar.h b/xx/qtmaterialsnackbar.h new file mode 100644 index 0000000..097f02c --- /dev/null +++ b/xx/qtmaterialsnackbar.h @@ -0,0 +1,48 @@ +#ifndef QTMATERIALSNACKBAR_H +#define QTMATERIALSNACKBAR_H + +#include "xxlib/qtmaterialoverlaywidget.h" + +class QtMaterialSnackbarPrivate; + +class QtMaterialSnackbar : public QtMaterialOverlayWidget +{ + Q_OBJECT + +public: + explicit QtMaterialSnackbar(QWidget *parent = 0); + ~QtMaterialSnackbar(); + + void setAutoHideDuration(int duration); + int autoHideDuration() const; + + void setUseThemeColors(bool value); + bool useThemeColors() const; + + void setBackgroundColor(const QColor &color); + QColor backgroundColor() const; + + void setTextColor(const QColor &color); + QColor textColor() const; + + void setFontSize(qreal size); + qreal fontSize() const; + + void setBoxWidth(int width); + int boxWidth() const; + +public slots: + void addMessage(const QString &message); + void addInstantMessage(const QString &message); + +protected: + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + + const QScopedPointer d_ptr; + +private: + Q_DISABLE_COPY(QtMaterialSnackbar) + Q_DECLARE_PRIVATE(QtMaterialSnackbar) +}; + +#endif // QTMATERIALSNACKBAR_H diff --git a/xx/qtmaterialsnackbar_internal.cpp b/xx/qtmaterialsnackbar_internal.cpp new file mode 100644 index 0000000..14b7385 --- /dev/null +++ b/xx/qtmaterialsnackbar_internal.cpp @@ -0,0 +1,35 @@ +#include "xx/qtmaterialsnackbar_internal.h" +#include "xx/qtmaterialsnackbar.h" + +QtMaterialSnackbarStateMachine::QtMaterialSnackbarStateMachine(QtMaterialSnackbar *parent) + : QStateMachine(parent), + m_snackbar(parent) +{ + m_timer.setSingleShot(true); + + QState *hiddenState = new QState; + QState *visibleState = new QState; + QState *finalState = new QState; + + addState(hiddenState); + addState(visibleState); + addState(finalState); + + setInitialState(hiddenState); + + QSignalTransition *transition; + + // + + // +} + +QtMaterialSnackbarStateMachine::~QtMaterialSnackbarStateMachine() +{ +} + +void QtMaterialSnackbarStateMachine::setOffset(qreal offset) +{ + m_offset = offset; + m_snackbar->update(); +} diff --git a/xx/qtmaterialsnackbar_internal.h b/xx/qtmaterialsnackbar_internal.h new file mode 100644 index 0000000..d4931cf --- /dev/null +++ b/xx/qtmaterialsnackbar_internal.h @@ -0,0 +1,35 @@ +#ifndef QTMATERIALSNACKBAR_INTERNAL_H +#define QTMATERIALSNACKBAR_INTERNAL_H + +#include +#include + +class QtMaterialSnackbar; + +class QtMaterialSnackbarStateMachine : public QStateMachine +{ + Q_OBJECT + + Q_PROPERTY(qreal offset WRITE setOffset READ offset) + +public: + QtMaterialSnackbarStateMachine(QtMaterialSnackbar *parent); + ~QtMaterialSnackbarStateMachine(); + + void setOffset(qreal offset); + inline qreal offset() const; + +private: + Q_DISABLE_COPY(QtMaterialSnackbarStateMachine) + + QtMaterialSnackbar *const m_snackbar; + QTimer m_timer; + qreal m_offset; +}; + +inline qreal QtMaterialSnackbarStateMachine::offset() const +{ + return m_offset; +} + +#endif // QTMATERIALSNACKBAR_INTERNAL_H diff --git a/xx/qtmaterialsnackbar_p.h b/xx/qtmaterialsnackbar_p.h new file mode 100644 index 0000000..c5d7451 --- /dev/null +++ b/xx/qtmaterialsnackbar_p.h @@ -0,0 +1,31 @@ +#ifndef QTMATERIALSNACKBAR_P_H +#define QTMATERIALSNACKBAR_P_H + +#include +#include + +class QtMaterialSnackbar; +class QtMaterialSnackbarStateMachine; + +class QtMaterialSnackbarPrivate +{ + Q_DISABLE_COPY(QtMaterialSnackbarPrivate) + Q_DECLARE_PUBLIC(QtMaterialSnackbar) + +public: + QtMaterialSnackbarPrivate(QtMaterialSnackbar *q); + ~QtMaterialSnackbarPrivate(); + + void init(); + + QtMaterialSnackbar *const q_ptr; + QtMaterialSnackbarStateMachine *stateMachine; + QColor backgroundColor; + QColor textColor; + QList messages; + int duration; + int boxWidth; + bool useThemeColors; +}; + +#endif // QTMATERIALSNACKBAR_P_H diff --git a/xx/qtmaterialtextfield.cpp b/xx/qtmaterialtextfield.cpp index 4e517c8..2a0182d 100644 --- a/xx/qtmaterialtextfield.cpp +++ b/xx/qtmaterialtextfield.cpp @@ -256,11 +256,12 @@ void QtMaterialTextField::paintEvent(QPaintEvent *event) QPainter painter(this); - if (text().isEmpty()) + const qreal progress = d->stateMachine->progress(); + + if (text().isEmpty() && progress < 1) { - painter.setOpacity(1-d->stateMachine->progress()); - //painter.fillRect(rect(), parentWidget()->palette().color(backgroundRole())); - painter.fillRect(rect(), Qt::white); + painter.setOpacity(1-progress); + painter.fillRect(rect(), parentWidget()->palette().color(backgroundRole())); } const int y = height()-1; @@ -277,8 +278,6 @@ void QtMaterialTextField::paintEvent(QPaintEvent *event) brush.setStyle(Qt::SolidPattern); brush.setColor(inkColor()); - const qreal progress = d->stateMachine->progress(); - if (progress > 0) { painter.setPen(Qt::NoPen); diff --git a/xx/qtmaterialtoggle.cpp b/xx/qtmaterialtoggle.cpp new file mode 100644 index 0000000..9e82783 --- /dev/null +++ b/xx/qtmaterialtoggle.cpp @@ -0,0 +1,290 @@ +#include "xx/qtmaterialtoggle.h" +#include "xx/qtmaterialtoggle_p.h" +#include +#include +#include +#include +#include "xx/qtmaterialtoggle_internal.h" +#include "xxlib/qtmaterialstyle.h" + +/*! + * \class QtMaterialTogglePrivate + * \internal + */ + +QtMaterialTogglePrivate::QtMaterialTogglePrivate(QtMaterialToggle *q) + : q_ptr(q) +{ +} + +QtMaterialTogglePrivate::~QtMaterialTogglePrivate() +{ +} + +void QtMaterialTogglePrivate::init() +{ + Q_Q(QtMaterialToggle); + + track = new QtMaterialToggleTrack(q); + thumb = new QtMaterialToggleThumb(q); + rippleOverlay = new QtMaterialToggleRippleOverlay(thumb, track, q); + stateMachine = new QStateMachine(q); + offState = new QState; + onState = new QState; + orientation = Qt::Horizontal; + useThemeColors = true; + + q->setCheckable(true); + q->setChecked(false); + q->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + + stateMachine->addState(offState); + stateMachine->addState(onState); + stateMachine->setInitialState(offState); + + offState->assignProperty(thumb, "shift", 0); + onState->assignProperty(thumb, "shift", 1); + + QSignalTransition *transition; + QPropertyAnimation *animation; + + // + + transition = new QSignalTransition(q, SIGNAL(toggled(bool))); + transition->setTargetState(onState); + offState->addTransition(transition); + + animation = new QPropertyAnimation(q); + animation->setPropertyName("shift"); + animation->setTargetObject(thumb); + animation->setDuration(200); + animation->setEasingCurve(QEasingCurve::OutQuad); + transition->addAnimation(animation); + + animation = new QPropertyAnimation(q); + animation->setPropertyName("trackColor"); + animation->setTargetObject(track); + animation->setDuration(150); + transition->addAnimation(animation); + + animation = new QPropertyAnimation(q); + animation->setPropertyName("thumbColor"); + animation->setTargetObject(thumb); + animation->setDuration(150); + transition->addAnimation(animation); + + // + + transition = new QSignalTransition(q, SIGNAL(toggled(bool))); + transition->setTargetState(offState); + onState->addTransition(transition); + + animation = new QPropertyAnimation(q); + animation->setPropertyName("shift"); + animation->setTargetObject(thumb); + animation->setDuration(200); + animation->setEasingCurve(QEasingCurve::OutQuad); + transition->addAnimation(animation); + + animation = new QPropertyAnimation(q); + animation->setPropertyName("trackColor"); + animation->setTargetObject(track); + animation->setDuration(150); + transition->addAnimation(animation); + + animation = new QPropertyAnimation(q); + animation->setPropertyName("thumbColor"); + animation->setTargetObject(thumb); + animation->setDuration(150); + transition->addAnimation(animation); + + // + + setupProperties(); + + stateMachine->start(); + QCoreApplication::processEvents(); +} + +void QtMaterialTogglePrivate::setupProperties() +{ + Q_Q(QtMaterialToggle); + + if (q->isEnabled()) { + const qreal shift = thumb->shift(); + if (qFuzzyCompare(shift, 1)) { + thumb->setThumbColor(q->activeColor()); + track->setTrackColor(q->activeColor().lighter(110)); + } else if (qFuzzyCompare(1+shift, 1)) { + thumb->setThumbColor(q->inactiveColor()); + track->setTrackColor(q->trackColor()); + } + } + + offState->assignProperty(track, "trackColor", q->trackColor().lighter(110)); + onState->assignProperty(track, "trackColor", q->activeColor().lighter(110)); + + offState->assignProperty(thumb, "thumbColor", q->inactiveColor()); + onState->assignProperty(thumb, "thumbColor", q->activeColor()); + + q->update(); +} + +/*! + * \class QtMaterialToggle + */ + +QtMaterialToggle::QtMaterialToggle(QWidget *parent) + : QAbstractButton(parent), + d_ptr(new QtMaterialTogglePrivate(this)) +{ + d_func()->init(); +} + +QtMaterialToggle::~QtMaterialToggle() +{ +} + +void QtMaterialToggle::setUseThemeColors(bool value) +{ + Q_D(QtMaterialToggle); + + d->useThemeColors = value; + d->setupProperties(); +} + +bool QtMaterialToggle::useThemeColors() const +{ + Q_D(const QtMaterialToggle); + + return d->useThemeColors; +} + +void QtMaterialToggle::setDisabledColor(const QColor &color) +{ + Q_D(QtMaterialToggle); + + d->disabledColor = color; + setUseThemeColors(false); +} + +QColor QtMaterialToggle::disabledColor() const +{ + Q_D(const QtMaterialToggle); + + if (d->useThemeColors || !d->disabledColor.isValid()) { + return QtMaterialStyle::instance().themeColor("disabled"); + } else { + return d->disabledColor; + } +} + +void QtMaterialToggle::setActiveColor(const QColor &color) +{ + Q_D(QtMaterialToggle); + + d->activeColor = color; + setUseThemeColors(false); +} + +QColor QtMaterialToggle::activeColor() const +{ + Q_D(const QtMaterialToggle); + + if (d->useThemeColors || !d->activeColor.isValid()) { + return QtMaterialStyle::instance().themeColor("primary1"); + } else { + return d->activeColor; + } +} + +void QtMaterialToggle::setInactiveColor(const QColor &color) +{ + Q_D(QtMaterialToggle); + + d->inactiveColor = color; + setUseThemeColors(false); +} + +QColor QtMaterialToggle::inactiveColor() const +{ + Q_D(const QtMaterialToggle); + + if (d->useThemeColors || !d->inactiveColor.isValid()) { + return QtMaterialStyle::instance().themeColor("canvas"); + } else { + return d->inactiveColor; + } +} + +void QtMaterialToggle::setTrackColor(const QColor &color) +{ + Q_D(QtMaterialToggle); + + d->trackColor = color; + setUseThemeColors(false); +} + +QColor QtMaterialToggle::trackColor() const +{ + Q_D(const QtMaterialToggle); + + if (d->useThemeColors || !d->trackColor.isValid()) { + return QtMaterialStyle::instance().themeColor("accent3"); + } else { + return d->trackColor; + } +} + +void QtMaterialToggle::setOrientation(Qt::Orientation orientation) +{ + Q_D(QtMaterialToggle); + + if (d->orientation == orientation) { + return; + } + + d->orientation = orientation; + updateGeometry(); +} + +Qt::Orientation QtMaterialToggle::orientation() const +{ + Q_D(const QtMaterialToggle); + + return d->orientation; +} + +QSize QtMaterialToggle::sizeHint() const +{ + Q_D(const QtMaterialToggle); + + return Qt::Horizontal == d->orientation + ? QSize(64, 48) + : QSize(48, 64); +} + +bool QtMaterialToggle::event(QEvent *event) +{ + Q_D(QtMaterialToggle); + + switch (event->type()) + { + case QEvent::ParentChange: + { + QWidget *widget; + if ((widget = parentWidget())) { + d->rippleOverlay->setParent(widget); + } + break; + } + default: + break; + } + return QAbstractButton::event(event); +} + +void QtMaterialToggle::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) +} diff --git a/xx/qtmaterialtoggle.h b/xx/qtmaterialtoggle.h new file mode 100644 index 0000000..ba5cc3b --- /dev/null +++ b/xx/qtmaterialtoggle.h @@ -0,0 +1,52 @@ +#ifndef QTMATERIALTOGGLE_H +#define QTMATERIALTOGGLE_H + +#include + +class QtMaterialTogglePrivate; + +class QtMaterialToggle : public QAbstractButton +{ + Q_OBJECT + + Q_PROPERTY(QColor disabledColor WRITE setDisabledColor READ disabledColor) + Q_PROPERTY(QColor activeColor WRITE setActiveColor READ activeColor) + Q_PROPERTY(QColor inactiveColor WRITE setInactiveColor READ inactiveColor) + Q_PROPERTY(QColor trackColor WRITE setTrackColor READ trackColor) + +public: + explicit QtMaterialToggle(QWidget *parent = 0); + ~QtMaterialToggle(); + + void setUseThemeColors(bool value); + bool useThemeColors() const; + + void setDisabledColor(const QColor &color); + QColor disabledColor() const; + + void setActiveColor(const QColor &color); + QColor activeColor() const; + + void setInactiveColor(const QColor &color); + QColor inactiveColor() const; + + void setTrackColor(const QColor &color); + QColor trackColor() const; + + void setOrientation(Qt::Orientation orientation); + Qt::Orientation orientation() const; + + QSize sizeHint() const Q_DECL_OVERRIDE; + +protected: + bool event(QEvent *event) Q_DECL_OVERRIDE; + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + + const QScopedPointer d_ptr; + +private: + Q_DISABLE_COPY(QtMaterialToggle) + Q_DECLARE_PRIVATE(QtMaterialToggle) +}; + +#endif // QTMATERIALTOGGLE_H diff --git a/xx/qtmaterialtoggle_internal.cpp b/xx/qtmaterialtoggle_internal.cpp new file mode 100644 index 0000000..9dc8fb0 --- /dev/null +++ b/xx/qtmaterialtoggle_internal.cpp @@ -0,0 +1,231 @@ +#include "xx/qtmaterialtoggle_internal.h" +#include +#include +#include +#include "xx/qtmaterialtoggle.h" +#include "xxlib/qtmaterialripple.h" + +/*! + * \class QtMaterialToggleRippleOverlay + * \internal + */ + +QtMaterialToggleRippleOverlay::QtMaterialToggleRippleOverlay( + QtMaterialToggleThumb *thumb, + QtMaterialToggleTrack *track, + QtMaterialToggle *parent) + : QtMaterialRippleOverlay(parent->parentWidget()), + m_toggle(parent), + m_thumb(thumb), + m_track(track) +{ + connect(parent, SIGNAL(toggled(bool)), this, SLOT(addToggleRipple())); + + thumb->installEventFilter(this); +} + +QtMaterialToggleRippleOverlay::~QtMaterialToggleRippleOverlay() +{ +} + +void QtMaterialToggleRippleOverlay::addToggleRipple() +{ + if (!m_toggle->isEnabled()) { + return; + } + + int t, w; + + if (Qt::Horizontal == m_toggle->orientation()) { + t = m_toggle->height()/2; + w = m_thumb->height()/2+10; + } else { + t = m_toggle->width()/2; + w = m_thumb->width()/2+10; + } + + QtMaterialRipple *ripple = new QtMaterialRipple(QPoint(10+t, 20+t)); + ripple->setColor(m_track->trackColor()); + ripple->setRadiusEndValue(w); + ripple->setOpacityStartValue(0.8); + + addRipple(ripple); +} + +bool QtMaterialToggleRippleOverlay::eventFilter(QObject *obj, QEvent *event) +{ + if (QEvent::Paint == event->type()) { + setGeometry(overlayGeometry()); + QList::const_iterator i; + QList items = ripples(); + QColor color = m_track->trackColor(); + for (i = items.begin(); i != items.end(); ++i) { + (*i)->setColor(color); + } + } + return QtMaterialRippleOverlay::eventFilter(obj, event); +} + +QRect QtMaterialToggleRippleOverlay::overlayGeometry() const +{ + const qreal offset = m_thumb->offset(); + if (Qt::Horizontal == m_toggle->orientation()) { + return m_toggle->geometry().adjusted(-10+offset, -20, 10+offset, 20); + } else { + return m_toggle->geometry().adjusted(-10, -20+offset, 10, 20+offset); + } +} + +/*! + * \class QtMaterialToggleThumb + * \internal + */ + +QtMaterialToggleThumb::QtMaterialToggleThumb(QtMaterialToggle *parent) + : QWidget(parent), + m_toggle(parent), + m_shift(0), + m_offset(0) +{ + Q_ASSERT(parent); + + QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect; + effect->setBlurRadius(6); + effect->setColor(QColor(0, 0, 0, 80)); + effect->setOffset(QPointF(0, 1)); + setGraphicsEffect(effect); + + parent->installEventFilter(this); +} + +QtMaterialToggleThumb::~QtMaterialToggleThumb() +{ +} + +void QtMaterialToggleThumb::setShift(qreal shift) +{ + if (m_shift == shift) { + return; + } + + m_shift = shift; + updateOffset(); +} + +bool QtMaterialToggleThumb::eventFilter(QObject *obj, QEvent *event) +{ + const QEvent::Type type = event->type(); + + if (QEvent::Resize == type || QEvent::Move == type) + { + setGeometry(m_toggle->rect().adjusted(8, 8, -8, -8)); + updateOffset(); + } + return QWidget::eventFilter(obj, event); +} + +void QtMaterialToggleThumb::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + + QBrush brush; + brush.setStyle(Qt::SolidPattern); + brush.setColor(m_toggle->isEnabled() ? m_thumbColor : Qt::white); + + painter.setBrush(brush); + painter.setPen(Qt::NoPen); + + int s; + QRectF r; + + if (Qt::Horizontal == m_toggle->orientation()) { + s = height()-10; + r = QRectF(5+m_offset, 5, s, s); + } else { + s = width()-10; + r = QRectF(5, 5+m_offset, s, s); + } + + painter.drawEllipse(r); + + if (!m_toggle->isEnabled()) { + brush.setColor(m_toggle->disabledColor()); + painter.setBrush(brush); + painter.drawEllipse(r); + } +} + +void QtMaterialToggleThumb::updateOffset() +{ + const QSize s(Qt::Horizontal == m_toggle->orientation() + ? size() : size().transposed()); + m_offset = m_shift*static_cast(s.width()-s.height()); + update(); +} + +/*! + * \class QtMaterialToggleTrack + * \internal + */ + +QtMaterialToggleTrack::QtMaterialToggleTrack(QtMaterialToggle *parent) + : QWidget(parent), + m_toggle(parent) +{ + Q_ASSERT(parent); + + parent->installEventFilter(this); +} + +QtMaterialToggleTrack::~QtMaterialToggleTrack() +{ +} + +void QtMaterialToggleTrack::setTrackColor(const QColor &color) +{ + m_trackColor = color; + update(); +} + +bool QtMaterialToggleTrack::eventFilter(QObject *obj, QEvent *event) +{ + const QEvent::Type type = event->type(); + + if (QEvent::Resize == type || QEvent::Move == type) { + setGeometry(m_toggle->rect()); + } + return QWidget::eventFilter(obj, event); +} + +void QtMaterialToggleTrack::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + + QBrush brush; + if (m_toggle->isEnabled()) { + brush.setColor(m_trackColor); + painter.setOpacity(0.8); + } else { + brush.setColor(m_toggle->disabledColor()); + painter.setOpacity(0.6); + } + brush.setStyle(Qt::SolidPattern); + painter.setBrush(brush); + painter.setPen(Qt::NoPen); + + if (Qt::Horizontal == m_toggle->orientation()) { + const int h = height()/2; + const QRect r(0, h/2, width(), h); + painter.drawRoundedRect(r.adjusted(14, 4, -14, -4), h/2-4, h/2-4); + } else { + const int w = width()/2; + const QRect r(w/2, 0, w, height()); + painter.drawRoundedRect(r.adjusted(4, 14, -4, -14), w/2-4, w/2-4); + } +} diff --git a/xx/qtmaterialtoggle_internal.h b/xx/qtmaterialtoggle_internal.h new file mode 100644 index 0000000..d8f45ea --- /dev/null +++ b/xx/qtmaterialtoggle_internal.h @@ -0,0 +1,120 @@ +#ifndef QTMATERIALTOGGLE_INTERNAL_H +#define QTMATERIALTOGGLE_INTERNAL_H + +#include +#include "xxlib/qtmaterialrippleoverlay.h" + +class QtMaterialToggle; +class QtMaterialToggleThumb; +class QtMaterialToggleTrack; + +class QtMaterialToggleRippleOverlay : public QtMaterialRippleOverlay +{ + Q_OBJECT + +public: + QtMaterialToggleRippleOverlay(QtMaterialToggleThumb *thumb, + QtMaterialToggleTrack *track, + QtMaterialToggle *parent); + ~QtMaterialToggleRippleOverlay(); + +protected slots: + void addToggleRipple(); + +protected: + bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE; + QRect overlayGeometry() const Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QtMaterialToggleRippleOverlay) + + QtMaterialToggle *const m_toggle; + QtMaterialToggleThumb *const m_thumb; + QtMaterialToggleTrack *const m_track; +}; + +class QtMaterialToggleThumb : public QWidget +{ + Q_OBJECT + + Q_PROPERTY(qreal shift WRITE setShift READ shift) + Q_PROPERTY(QColor thumbColor WRITE setThumbColor READ thumbColor) + +public: + QtMaterialToggleThumb(QtMaterialToggle *parent); + ~QtMaterialToggleThumb(); + + void setShift(qreal shift); + inline qreal shift() const; + + inline qreal offset() const; + + inline void setThumbColor(const QColor &color); + inline QColor thumbColor() const; + +protected: + bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE; + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QtMaterialToggleThumb) + + void updateOffset(); + + QtMaterialToggle *const m_toggle; + QColor m_thumbColor; + qreal m_shift; + qreal m_offset; +}; + +inline qreal QtMaterialToggleThumb::shift() const +{ + return m_shift; +} + +inline qreal QtMaterialToggleThumb::offset() const +{ + return m_offset; +} + +inline void QtMaterialToggleThumb::setThumbColor(const QColor &color) +{ + m_thumbColor = color; + update(); +} + +inline QColor QtMaterialToggleThumb::thumbColor() const +{ + return m_thumbColor; +} + +class QtMaterialToggleTrack : public QWidget +{ + Q_OBJECT + + Q_PROPERTY(QColor trackColor WRITE setTrackColor READ trackColor) + +public: + QtMaterialToggleTrack(QtMaterialToggle *parent); + ~QtMaterialToggleTrack(); + + void setTrackColor(const QColor &color); + inline QColor trackColor() const; + +protected: + bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE; + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QtMaterialToggleTrack) + + QtMaterialToggle *const m_toggle; + QColor m_trackColor; +}; + +inline QColor QtMaterialToggleTrack::trackColor() const +{ + return m_trackColor; +} + +#endif // QTMATERIALTOGGLE_INTERNAL_H diff --git a/xx/qtmaterialtoggle_p.h b/xx/qtmaterialtoggle_p.h new file mode 100644 index 0000000..f50d5b3 --- /dev/null +++ b/xx/qtmaterialtoggle_p.h @@ -0,0 +1,41 @@ +#ifndef QTMATERIALTOGGLE_P_H +#define QTMATERIALTOGGLE_P_H + +#include + +class QStateMachine; +class QState; +class QColor; +class QtMaterialToggle; +class QtMaterialToggleTrack; +class QtMaterialToggleThumb; +class QtMaterialToggleRippleOverlay; + +class QtMaterialTogglePrivate +{ + Q_DISABLE_COPY(QtMaterialTogglePrivate) + Q_DECLARE_PUBLIC(QtMaterialToggle) + +public: + QtMaterialTogglePrivate(QtMaterialToggle *q); + ~QtMaterialTogglePrivate(); + + void init(); + void setupProperties(); + + QtMaterialToggle *const q_ptr; + QtMaterialToggleTrack *track; + QtMaterialToggleThumb *thumb; + QtMaterialToggleRippleOverlay *rippleOverlay; + QStateMachine *stateMachine; + QState *offState; + QState *onState; + Qt::Orientation orientation; + QColor disabledColor; + QColor activeColor; + QColor inactiveColor; + QColor trackColor; + bool useThemeColors; +}; + +#endif // QTMATERIALTOGGLE_P_H diff --git a/xxlib/qtmaterialoverlaywidget.h b/xxlib/qtmaterialoverlaywidget.h index ebf9f92..ac108cc 100644 --- a/xxlib/qtmaterialoverlaywidget.h +++ b/xxlib/qtmaterialoverlaywidget.h @@ -15,7 +15,7 @@ protected: bool event(QEvent *event) Q_DECL_OVERRIDE; bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE; - QRect overlayGeometry() const; + virtual QRect overlayGeometry() const; private: Q_DISABLE_COPY(QtMaterialOverlayWidget) diff --git a/xxlib/qtmaterialrippleoverlay.h b/xxlib/qtmaterialrippleoverlay.h index a813356..486ae3d 100644 --- a/xxlib/qtmaterialrippleoverlay.h +++ b/xxlib/qtmaterialrippleoverlay.h @@ -27,6 +27,8 @@ public: protected: void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + inline QList ripples() const; + private: Q_DISABLE_COPY(QtMaterialRippleOverlay) @@ -54,4 +56,9 @@ inline void QtMaterialRippleOverlay::setClipPath(const QPainterPath &path) update(); } +inline QList QtMaterialRippleOverlay::ripples() const +{ + return m_ripples; +} + #endif // QTMATERIALRIPPLEOVERLAY_H diff --git a/yy/slidersettingseditor.cpp b/yy/slidersettingseditor.cpp index c69dcfb..37b84c9 100644 --- a/yy/slidersettingseditor.cpp +++ b/yy/slidersettingseditor.cpp @@ -1,6 +1,7 @@ #include "slidersettingseditor.h" #include #include +#include #include "xx/qtmaterialslider.h" #include "components/slider.h" @@ -24,11 +25,24 @@ SliderSettingsEditor::SliderSettingsEditor(QWidget *parent) layout = new QVBoxLayout; canvas->setLayout(layout); + canvas->setMaximumHeight(300); layout->addWidget(m_slider); -// layout->addWidget(new QSlider(Qt::Horizontal)); -// layout->addWidget(new Slider); + layout->setAlignment(m_slider, Qt::AlignHCenter); + + QSlider *sl = new QSlider(Qt::Horizontal); + layout->addWidget(sl); + layout->setAlignment(sl, Qt::AlignCenter); + + //layout->addWidget(new Slider); 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() @@ -38,13 +52,55 @@ SliderSettingsEditor::~SliderSettingsEditor() 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(); } - diff --git a/yy/slidersettingsform.ui b/yy/slidersettingsform.ui index efb20c3..11d2ffe 100644 --- a/yy/slidersettingsform.ui +++ b/yy/slidersettingsform.ui @@ -33,6 +33,47 @@ + + + + Value + + + + + + + + + + Orientation + + + + + + + + Horizontal + + + + + Vertical + + + + + + + + Inverted + + + + + + diff --git a/yy/togglesettingseditor.cpp b/yy/togglesettingseditor.cpp new file mode 100644 index 0000000..763c9e3 --- /dev/null +++ b/yy/togglesettingseditor.cpp @@ -0,0 +1,113 @@ +#include "togglesettingseditor.h" +#include +#include "xx/qtmaterialtoggle.h" +#include "components/toggle.h" + +ToggleSettingsEditor::ToggleSettingsEditor(QWidget *parent) + : QWidget(parent), + ui(new Ui::ToggleSettingsForm), + m_toggle(new QtMaterialToggle) +{ + 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); + + Toggle *toggle = new Toggle; + toggle->setOrientation(Qt::Vertical); + + m_toggle->setOrientation(Qt::Vertical); + + layout = new QVBoxLayout; + canvas->setLayout(layout); + layout->addWidget(m_toggle); + layout->addWidget(toggle); + layout->setAlignment(m_toggle, Qt::AlignCenter); + + setupForm(); + + connect(ui->disabledCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget())); + connect(ui->checkedCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget())); + connect(ui->orientationComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateWidget())); + connect(ui->useThemeColorsCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget())); + connect(ui->disabledColorToolButton, SIGNAL(pressed()), this, SLOT(selectColor())); + connect(ui->activeColorToolButton, SIGNAL(pressed()), this, SLOT(selectColor())); + connect(ui->inactiveColorToolButton, SIGNAL(pressed()), this, SLOT(selectColor())); + connect(ui->trackColorToolButton, SIGNAL(pressed()), this, SLOT(selectColor())); + + connect(m_toggle, SIGNAL(toggled(bool)), this, SLOT(setupForm())); +} + +ToggleSettingsEditor::~ToggleSettingsEditor() +{ +} + +void ToggleSettingsEditor::setupForm() +{ + switch (m_toggle->orientation()) + { + case Qt::Horizontal: + ui->orientationComboBox->setCurrentIndex(0); + break; + case Qt::Vertical: + ui->orientationComboBox->setCurrentIndex(1); + break; + default: + break; + } + + ui->disabledCheckBox->setChecked(!m_toggle->isEnabled()); + ui->checkedCheckBox->setChecked(m_toggle->isChecked()); + ui->useThemeColorsCheckBox->setChecked(m_toggle->useThemeColors()); +} + +void ToggleSettingsEditor::updateWidget() +{ + switch (ui->orientationComboBox->currentIndex()) + { + case 0: + m_toggle->setOrientation(Qt::Horizontal); + break; + case 1: + m_toggle->setOrientation(Qt::Vertical); + break; + default: + break; + } + + m_toggle->setDisabled(ui->disabledCheckBox->isChecked()); + m_toggle->setChecked(ui->checkedCheckBox->isChecked()); + m_toggle->setUseThemeColors(ui->useThemeColorsCheckBox->isChecked()); +} + +void ToggleSettingsEditor::selectColor() +{ + QColorDialog dialog; + if (dialog.exec()) { + QColor color = dialog.selectedColor(); + QString senderName = sender()->objectName(); + if ("disabledColorToolButton" == senderName) { + m_toggle->setDisabledColor(color); + ui->disabledColorLineEdit->setText(color.name(QColor::HexRgb)); + } else if ("activeColorToolButton" == senderName) { + m_toggle->setActiveColor(color); + ui->activeColorLineEdit->setText(color.name(QColor::HexRgb)); + } else if ("inactiveColorToolButton" == senderName) { + m_toggle->setInactiveColor(color); + ui->inactiveColorLineEdit->setText(color.name(QColor::HexRgb)); + } else if ("trackColorToolButton" == senderName) { + m_toggle->setTrackColor(color); + ui->trackColorLineEdit->setText(color.name(QColor::HexRgb)); + } + } + setupForm(); +} + diff --git a/yy/togglesettingseditor.h b/yy/togglesettingseditor.h new file mode 100644 index 0000000..a74553e --- /dev/null +++ b/yy/togglesettingseditor.h @@ -0,0 +1,27 @@ +#ifndef TOGGLESETTINGSEDITOR_H +#define TOGGLESETTINGSEDITOR_H + +#include +#include "ui_togglesettingsform.h" + +class QtMaterialToggle; + +class ToggleSettingsEditor : public QWidget +{ + Q_OBJECT + +public: + explicit ToggleSettingsEditor(QWidget *parent = 0); + ~ToggleSettingsEditor(); + +protected slots: + void setupForm(); + void updateWidget(); + void selectColor(); + +private: + Ui::ToggleSettingsForm *const ui; + QtMaterialToggle *const m_toggle; +}; + +#endif // TOGGLESETTINGSEDITOR_H diff --git a/yy/togglesettingsform.ui b/yy/togglesettingsform.ui new file mode 100644 index 0000000..a6edbb7 --- /dev/null +++ b/yy/togglesettingsform.ui @@ -0,0 +1,166 @@ + + + ToggleSettingsForm + + + + 0 + 0 + 482 + 427 + + + + Form + + + + + 0 + 0 + 441 + 341 + + + + + + + Disabled + + + + + + + + + + Checked + + + + + + + + + + Orientation + + + + + + + + Horizontal + + + + + Vertical + + + + + + + + Active color + + + + + + + Inactive color + + + + + + + Disabled color + + + + + + + Track color + + + + + + + + + + + + ... + + + + + + + + + + + + + + ... + + + + + + + + + + + + + + ... + + + + + + + + + + + + + + ... + + + + + + + + + Use theme colors + + + + + + + + + + + +