diff --git a/components/circularprogress.cpp b/components/circularprogress.cpp index 29ea6ac..91c395d 100644 --- a/components/circularprogress.cpp +++ b/components/circularprogress.cpp @@ -120,6 +120,7 @@ void CircularProgress::setLineWidth(qreal width) d->penWidth = width; update(); + updateGeometry(); } qreal CircularProgress::lineWidth() const @@ -135,6 +136,7 @@ void CircularProgress::setSize(int size) d->size = size; update(); + updateGeometry(); } int CircularProgress::size() const @@ -178,8 +180,21 @@ void CircularProgress::paintEvent(QPaintEvent *event) Q_D(CircularProgress); QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + if (!isEnabled()) + { + QPen pen; + pen.setCapStyle(Qt::RoundCap); + pen.setWidthF(d->penWidth); + pen.setColor(Style::instance().themeColor("border")); + painter.setPen(pen); + painter.drawLine(rect().center()-QPointF(20, 20), rect().center()+QPointF(20, 20)); + painter.drawLine(rect().center()+QPointF(20, -20), rect().center()-QPointF(20, -20)); + return; + } + if (Material::IndeterminateProgress == d->progressType) { painter.translate(width()/2, height()/2); painter.rotate(d->delegate->angle()); diff --git a/components/circularprogress.h b/components/circularprogress.h index a900e88..40ad241 100644 --- a/components/circularprogress.h +++ b/components/circularprogress.h @@ -33,7 +33,7 @@ public: void setColor(const QColor &color); QColor color() const; - QSize sizeHint() const; + QSize sizeHint() const Q_DECL_OVERRIDE; protected: void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; diff --git a/components/dialog.cpp b/components/dialog.cpp index d740e05..ef2feb3 100644 --- a/components/dialog.cpp +++ b/components/dialog.cpp @@ -6,10 +6,12 @@ #include #include #include +#include #include #include #include "lib/transparencyproxy.h" #include "dialog_internal.h" +#include DialogPrivate::DialogPrivate(Dialog *q) : q_ptr(q), @@ -185,6 +187,16 @@ bool Dialog::eventFilter(QObject *obj, QEvent *event) return QWidget::eventFilter(obj, event); } +void Dialog::mousePressEvent(QMouseEvent *event) +{ + Q_D(Dialog); + + QRect rect(d->window->mapToGlobal(QPoint(0, 0)), d->window->size()); + if (!rect.contains(event->globalPos())) { + hideDialog(); + } +} + void Dialog::paintEvent(QPaintEvent *event) { Q_UNUSED(event) diff --git a/components/dialog.h b/components/dialog.h index 234e088..59f8922 100644 --- a/components/dialog.h +++ b/components/dialog.h @@ -24,6 +24,7 @@ protected slots: protected: bool event(QEvent *event) Q_DECL_OVERRIDE; bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE; + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; const QScopedPointer d_ptr; diff --git a/components/progress.cpp b/components/progress.cpp index a34e103..e016725 100644 --- a/components/progress.cpp +++ b/components/progress.cpp @@ -109,7 +109,7 @@ QColor Progress::backgroundColor() const Q_D(const Progress); if (d->useThemeColors || !d->backgroundColor.isValid()) { - return Style::instance().themeColor("accent3"); + return Style::instance().themeColor("border"); } else { return d->backgroundColor; } @@ -126,7 +126,8 @@ void Progress::paintEvent(QPaintEvent *event) QBrush brush; brush.setStyle(Qt::SolidPattern); - brush.setColor(backgroundColor()); + brush.setColor(isEnabled() ? backgroundColor() + : Style::instance().themeColor("disabled")); painter.setBrush(brush); painter.setPen(Qt::NoPen); @@ -136,16 +137,16 @@ void Progress::paintEvent(QPaintEvent *event) painter.drawRect(0, 0, width(), height()); - brush.setColor(progressColor()); - painter.setBrush(brush); + if (isEnabled()) + { + brush.setColor(progressColor()); + painter.setBrush(brush); - if (Material::IndeterminateProgress == d->progressType) - { - painter.drawRect(d->delegate->offset()*width()*2-width(), 0, width(), height()); - } - else - { - qreal p = static_cast(width())*(value()-minimum())/(maximum()-minimum()); - painter.drawRect(0, 0, p, height()); + if (Material::IndeterminateProgress == d->progressType) { + painter.drawRect(d->delegate->offset()*width()*2-width(), 0, width(), height()); + } else { + qreal p = static_cast(width())*(value()-minimum())/(maximum()-minimum()); + painter.drawRect(0, 0, p, height()); + } } } diff --git a/components/slider_internal.cpp b/components/slider_internal.cpp index 37dfad8..0cfae61 100644 --- a/components/slider_internal.cpp +++ b/components/slider_internal.cpp @@ -368,6 +368,8 @@ void SliderTrack::paintEvent(QPaintEvent *event) QPainter painter(this); + painter.drawRect(rect()); + QBrush fg; fg.setStyle(Qt::SolidPattern); fg.setColor(slider->isEnabled() ? slider->thumbColor() diff --git a/components/tabs.cpp b/components/tabs.cpp index 784c67c..03959c6 100644 --- a/components/tabs.cpp +++ b/components/tabs.cpp @@ -12,7 +12,7 @@ TabsPrivate::TabsPrivate(Tabs *q) tabLayout(new QHBoxLayout), tab(-1), useThemeColors(true), - showHalo(false), + showHalo(true), rippleStyle(Material::CenteredRipple) { } @@ -22,6 +22,8 @@ void TabsPrivate::init() Q_Q(Tabs); q->setLayout(tabLayout); + q->setStyle(&Style::instance()); + tabLayout->setSpacing(0); tabLayout->setMargin(0); } diff --git a/components/textfield.cpp b/components/textfield.cpp index 42aaf80..d30e144 100644 --- a/components/textfield.cpp +++ b/components/textfield.cpp @@ -7,6 +7,7 @@ #include "textfield_internal.h" //#include "lib/style.h" #include "xxlib/qtmaterialstyle.h" +#include TextFieldPrivate::TextFieldPrivate(TextField *q) : q_ptr(q), @@ -37,6 +38,10 @@ void TextFieldPrivate::init() machine->start(); QCoreApplication::processEvents(); + + //QPalette p; + //p.setColor(QPalette::Active, QPalette::Text, Qt::red); + //q->setPalette(p); } TextField::TextField(QWidget *parent) @@ -69,7 +74,11 @@ void TextField::setShowLabel(bool value) { Q_D(TextField); - if (!d->label) { + if (d->showLabel == value) { + return; + } + + if (!d->label && value) { d->label = new TextFieldLabel(this); d->machine->setLabel(d->label); } @@ -100,6 +109,11 @@ void TextField::setLabelFontSize(qreal size) QFont f(d->label->font()); f.setPointSizeF(size); d->label->setFont(f); + + //QFontDatabase db; + //QFont font(db.font("Roboto", "Medium", size)); + ////q->setFont(font); + //d->label->setFont(font); } } @@ -116,6 +130,7 @@ void TextField::setLabel(const QString &label) d->labelString = label; setShowLabel(true); + d->label->update(); } QString TextField::label() const @@ -220,6 +235,11 @@ QColor TextField::hintColor() const } } +QSize TextField::sizeHint() const +{ + return QLineEdit::sizeHint(); +} + bool TextField::event(QEvent *event) { Q_D(TextField); @@ -252,7 +272,8 @@ void TextField::paintEvent(QPaintEvent *event) bgBrush.setStyle(Qt::SolidPattern); bgBrush.setColor(backgroundColor()); painter.setOpacity(1-d->machine->progress()); - painter.fillRect(rect(), bgBrush); + //painter.fillRect(rect(), bgBrush); + painter.fillRect(rect(), parentWidget()->palette().color(backgroundRole())); } const int y = height()-1; diff --git a/components/textfield.h b/components/textfield.h index 7b6c6a5..da35a74 100644 --- a/components/textfield.h +++ b/components/textfield.h @@ -46,6 +46,8 @@ public: void setHintColor(const QColor &color); QColor hintColor() const; + QSize sizeHint() const Q_DECL_OVERRIDE; + protected: bool event(QEvent *event) Q_DECL_OVERRIDE; void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; diff --git a/components/textfield_internal.cpp b/components/textfield_internal.cpp index bd9f9d3..868f427 100644 --- a/components/textfield_internal.cpp +++ b/components/textfield_internal.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "textfield.h" TextFieldStateMachine::TextFieldStateMachine(TextField *parent) @@ -29,7 +30,7 @@ TextFieldStateMachine::TextFieldStateMachine(TextField *parent) animation = new QPropertyAnimation(this, "progress", this); animation->setEasingCurve(QEasingCurve::InCubic); - animation->setDuration(340); + animation->setDuration(310); transition->addAnimation(animation); transition = new QEventTransition(parent, QEvent::FocusOut); @@ -38,7 +39,7 @@ TextFieldStateMachine::TextFieldStateMachine(TextField *parent) animation = new QPropertyAnimation(this, "progress", this); animation->setEasingCurve(QEasingCurve::OutCubic); - animation->setDuration(340); + animation->setDuration(310); transition->addAnimation(animation); _normalState->assignProperty(this, "progress", 0); @@ -92,9 +93,9 @@ void TextFieldStateMachine::setProgress(qreal progress) void TextFieldStateMachine::assignProperties() { - QPalette p; - p.setColor(QPalette::Normal, QPalette::Base, textField->backgroundColor()); - textField->setPalette(p); + //QPalette p; + //p.setColor(QPalette::Normal, QPalette::Base, textField->backgroundColor()); + //textField->setPalette(p); if (_label) { @@ -109,6 +110,12 @@ void TextFieldStateMachine::assignProperties() } _focusedState->assignProperty(_label, "color", textField->inkColor()); _normalState->assignProperty(_label, "color", textField->hintColor()); + + if (0 != _label->offset().y() && !textField->text().isEmpty()) { + _label->setOffset(QPointF(0, 0-m)); + } else if (!textField->hasFocus() && _label->offset().y() <= 0 && textField->text().isEmpty()) { + _label->setOffset(QPointF(0, 26)); + } } } @@ -120,11 +127,16 @@ TextFieldLabel::TextFieldLabel(TextField *parent) _posY(26), _color(parent->hintColor()) { - QFont f; - f.setPointSizeF(parent->labelFontSize()); - f.setStyleName("Medium"); - f.setLetterSpacing(QFont::PercentageSpacing, 102); - setFont(f); + //QFont f; + //f.setPointSizeF(parent->labelFontSize()); + //f.setStyleName("Medium"); + //f.setLetterSpacing(QFont::PercentageSpacing, 102); + //setFont(f); + + QFontDatabase db; + QFont font(db.font("Roboto", "Medium", parent->labelFontSize())); + font.setLetterSpacing(QFont::PercentageSpacing, 102); + setFont(font); } TextFieldLabel::~TextFieldLabel() @@ -135,6 +147,10 @@ void TextFieldLabel::paintEvent(QPaintEvent *event) { Q_UNUSED(event) + if (!label->hasLabel()) { + return; + } + QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); diff --git a/components/textfield_internal.h b/components/textfield_internal.h index d6ba97e..d4aa62a 100644 --- a/components/textfield_internal.h +++ b/components/textfield_internal.h @@ -52,14 +52,20 @@ public: TextFieldLabel(TextField *parent); ~TextFieldLabel(); - inline void setScale(qreal scale) { _scale = scale; update(); } - inline qreal scale() const { return _scale; } + inline void setScale(qreal scale) + { _scale = scale; update(); } + inline qreal scale() const + { return _scale; } - inline void setOffset(const QPointF &pos) { _posX = pos.x(); _posY = pos.y(); update(); } - inline QPointF offset() const { return QPointF(_posX, _posY); } + inline void setOffset(const QPointF &pos) + { _posX = pos.x(); _posY = pos.y(); update(); } + inline QPointF offset() const + { return QPointF(_posX, _posY); } - inline void setColor(const QColor &color) { _color = color; update(); } - inline QColor color() const { return _color; } + inline void setColor(const QColor &color) + { _color = color; update(); } + inline QColor color() const + { return _color; } protected: void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; diff --git a/mainwindow.cpp b/mainwindow.cpp index 7f8f0c5..d2d07de 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -39,16 +39,54 @@ #include "yy/selectfieldsettingseditor.h" #include "yy/iconmenusettingseditor.h" #include "yy/checkboxsettingseditor.h" +#include "yy/radiobuttonsettingseditor.h" +#include "components/circularprogress.h" +#include "yy/circularprogresssettingseditor.h" +#include "yy/progresssettingseditor.h" +#include "components/textfield.h" +#include "components/dialog.h" +#include "yy/textfieldsettingseditor.h" +#include "components/tabs.h" +#include "xx/qtmaterialtabs.h" +#include "components/slider.h" +#include "components/toggle.h" +#include "xx/qtmaterialslider.h" +#include "yy/slidersettingseditor.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), _menu(new MenuPlus) { - CheckBoxSettingsEditor *editor = new CheckBoxSettingsEditor; + SliderSettingsEditor *editor = new SliderSettingsEditor; setCentralWidget(editor); return; + //TextFieldSettingsEditor *editor = new TextFieldSettingsEditor; + //setCentralWidget(editor); + + //return; + + //ProgressSettingsEditor *editor = new ProgressSettingsEditor; + //setCentralWidget(editor); + + //return; + + //CircularProgressSettingsEditor *editor = new CircularProgressSettingsEditor; + //setCentralWidget(editor); + + //return; + + //RadioButtonSettingsEditor *editor = new RadioButtonSettingsEditor; + //setCentralWidget(editor); + + //return; + + //CheckBoxSettingsEditor *editor = new CheckBoxSettingsEditor; + //setCentralWidget(editor); + + //return; + //IconMenuSettingsEditor *editor = new IconMenuSettingsEditor; //setCentralWidget(editor); @@ -95,15 +133,98 @@ MainWindow::MainWindow(QWidget *parent) widget->setStyleSheet("QWidget { background: white; }"); - //QtMaterialIconButton *btn = new QtMaterialIconButton(QIcon("../qt-material-widgets/ic_star_black_24px.svg")); - //layout->addWidget(btn); + + 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))); + + /* + QtMaterialIconButton *btn = new QtMaterialIconButton(QIcon("../qt-material-widgets/ic_star_black_24px.svg")); + layout->addWidget(btn); + + layout->addStretch(); + + //CircularProgress *cp = new CircularProgress; + //layout->addWidget(cp); + + TextField *tf = new TextField; + layout->addWidget(tf); + layout->addStretch(); + + Dialog *dlg = new Dialog; + dlg->setParent(this); + + //dlg->windowLayout()->addWidget(new QPushButton("Hello")); + QVBoxLayout *dl = new QVBoxLayout; + dl->addWidget(new QPushButton("Hello")); + dlg->setWindowLayout(dl); + + QPushButton *bbbtn = new QPushButton("Show dialog"); + layout->addWidget(bbbtn); + + connect(bbbtn, SIGNAL(pressed()), dlg, SLOT(showDialog())); QtMaterialIconMenu *im = new QtMaterialIconMenu(QIcon("../qt-material-widgets/ic_star_black_24px.svg")); layout->addWidget(im); layout->setAlignment(im, Qt::AlignCenter); + { + im->addMenuItem("C"); + im->addMenuItem("C++"); + im->addMenuItem("Haskell"); + im->addMenuItem("JavaScript"); + im->addMenuItem("ECMAScript"); + im->addMenuItem("OCaml"); + im->addMenuItem("Python"); + im->addMenuItem("F#"); + im->addMenuItem("Clojure"); + im->addMenuItem("Java"); + } + QtMaterialSelectField *sfp = new QtMaterialSelectField; //sfp->setBackgroundColor(Qt::white); layout->addWidget(sfp); @@ -123,6 +244,7 @@ MainWindow::MainWindow(QWidget *parent) } layout->addStretch(); + */ //layout->setAlignment(sfp, Qt::AlignCenter); @@ -134,6 +256,7 @@ MainWindow::MainWindow(QWidget *parent) //layout->setAlignment(tf, Qt::AlignCenter); + /* { QtMaterialMenuItem *b; @@ -229,6 +352,7 @@ MainWindow::MainWindow(QWidget *parent) im->addMenuItem(b); } + */ /* //layout->addWidget(_menu); diff --git a/qt-material-widgets.pro b/qt-material-widgets.pro index 3bad498..5d972cb 100644 --- a/qt-material-widgets.pro +++ b/qt-material-widgets.pro @@ -114,7 +114,23 @@ SOURCES += main.cpp\ yy/checkboxsettingseditor.cpp \ xxlib/qtmaterialcheckable.cpp \ xxlib/qtmaterialcheckable_internal.cpp \ - xx/qtmaterialcheckbox.cpp + xx/qtmaterialcheckbox.cpp \ + yy/radiobuttonsettingseditor.cpp \ + xx/qtmaterialradiobutton.cpp \ + yy/circularprogresssettingseditor.cpp \ + xx/qtmaterialcircularprogress.cpp \ + xx/qtmaterialcircularprogress_internal.cpp \ + yy/progresssettingseditor.cpp \ + xx/qtmaterialprogress.cpp \ + xx/qtmaterialprogress_internal.cpp \ + xx/qtmaterialtextfield.cpp \ + xx/qtmaterialtextfield_internal.cpp \ + yy/textfieldsettingseditor.cpp \ + xx/qtmaterialtabs.cpp \ + xx/qtmaterialtabs_internal.cpp \ + xx/qtmaterialslider.cpp \ + xx/qtmaterialslider_internal.cpp \ + yy/slidersettingseditor.cpp HEADERS += mainwindow.h \ components/appbar.h \ @@ -258,7 +274,29 @@ HEADERS += mainwindow.h \ xxlib/qtmaterialcheckable_p.h \ xxlib/qtmaterialcheckable_internal.h \ xx/qtmaterialcheckbox.h \ - xx/qtmaterialcheckbox_p.h + xx/qtmaterialcheckbox_p.h \ + yy/radiobuttonsettingseditor.h \ + xx/qtmaterialradiobutton.h \ + xx/qtmaterialradiobutton_p.h \ + yy/circularprogresssettingseditor.h \ + xx/qtmaterialcircularprogress.h \ + xx/qtmaterialcircularprogress_p.h \ + xx/qtmaterialcircularprogress_internal.h \ + yy/progresssettingseditor.h \ + xx/qtmaterialprogress.h \ + xx/qtmaterialprogress_p.h \ + xx/qtmaterialprogress_internal.h \ + xx/qtmaterialtextfield.h \ + xx/qtmaterialtextfield_p.h \ + xx/qtmaterialtextfield_internal.h \ + yy/textfieldsettingseditor.h \ + xx/qtmaterialtabs.h \ + xx/qtmaterialtabs_p.h \ + xx/qtmaterialtabs_internal.h \ + xx/qtmaterialslider.h \ + xx/qtmaterialslider_p.h \ + xx/qtmaterialslider_internal.h \ + yy/slidersettingseditor.h RESOURCES += \ resources.qrc @@ -270,4 +308,9 @@ FORMS += \ yy/badgesettingsform.ui \ yy/iconmenusettingsform.ui \ yy/selectfieldsettingsform.ui \ - yy/checkboxsettingsform.ui + yy/checkboxsettingsform.ui \ + yy/radiobuttonsettingsform.ui \ + yy/circularprogresssettingsform.ui \ + yy/progresssettingsform.ui \ + yy/textfieldsettingsform.ui \ + yy/slidersettingsform.ui diff --git a/xx/qtmaterialavatar.cpp b/xx/qtmaterialavatar.cpp index 7200615..c209e7e 100644 --- a/xx/qtmaterialavatar.cpp +++ b/xx/qtmaterialavatar.cpp @@ -89,6 +89,10 @@ void QtMaterialAvatar::setUseThemeColors(bool value) { Q_D(QtMaterialAvatar); + if (d->useThemeColors == value) { + return; + } + d->useThemeColors = value; update(); } diff --git a/xx/qtmaterialbadge.cpp b/xx/qtmaterialbadge.cpp index 7cf441c..5e579f9 100644 --- a/xx/qtmaterialbadge.cpp +++ b/xx/qtmaterialbadge.cpp @@ -82,6 +82,10 @@ void QtMaterialBadge::setUseThemeColors(bool value) { Q_D(QtMaterialBadge); + if (d->useThemeColors == value) { + return; + } + d->useThemeColors = value; update(); } diff --git a/xx/qtmaterialcircularprogress.cpp b/xx/qtmaterialcircularprogress.cpp new file mode 100644 index 0000000..a26a124 --- /dev/null +++ b/xx/qtmaterialcircularprogress.cpp @@ -0,0 +1,252 @@ +#include "xx/qtmaterialcircularprogress.h" +#include "xx/qtmaterialcircularprogress_p.h" +#include +#include +#include +#include "xx/qtmaterialcircularprogress_internal.h" +#include "xxlib/qtmaterialstyle.h" + +/*! + * \class QtMaterialCircularProgressPrivate + * \internal + */ + +QtMaterialCircularProgressPrivate::QtMaterialCircularProgressPrivate(QtMaterialCircularProgress *q) + : q_ptr(q) +{ +} + +QtMaterialCircularProgressPrivate::~QtMaterialCircularProgressPrivate() +{ +} + +void QtMaterialCircularProgressPrivate::init() +{ + Q_Q(QtMaterialCircularProgress); + + delegate = new QtMaterialCircularProgressDelegate(q); + progressType = XXMaterial::IndeterminateProgress; + penWidth = 6.25; + size = 64; + useThemeColors = true; + + q->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, + QSizePolicy::MinimumExpanding)); + + QParallelAnimationGroup *group = new QParallelAnimationGroup(q); + group->setLoopCount(-1); + + QPropertyAnimation *animation; + + animation = new QPropertyAnimation(q); + animation->setPropertyName("dashLength"); + animation->setTargetObject(delegate); + animation->setEasingCurve(QEasingCurve::InOutQuad); + animation->setStartValue(0.1); + animation->setKeyValueAt(0.15, 0.2); + animation->setKeyValueAt(0.6, 20); + animation->setKeyValueAt(0.7, 20); + animation->setEndValue(20); + animation->setDuration(2050); + + group->addAnimation(animation); + + animation = new QPropertyAnimation(q); + animation->setPropertyName("dashOffset"); + animation->setTargetObject(delegate); + animation->setEasingCurve(QEasingCurve::InOutSine); + animation->setStartValue(0); + animation->setKeyValueAt(0.15, 0); + animation->setKeyValueAt(0.6, -7); + animation->setKeyValueAt(0.7, -7); + animation->setEndValue(-25); + animation->setDuration(2050); + + group->addAnimation(animation); + + animation = new QPropertyAnimation(q); + animation->setPropertyName("angle"); + animation->setTargetObject(delegate); + animation->setStartValue(0); + animation->setEndValue(719); + animation->setDuration(2050); + + group->addAnimation(animation); + + group->start(); +} + +/*! + * \class QtMaterialCircularProgress + */ + +QtMaterialCircularProgress::QtMaterialCircularProgress(QWidget *parent) + : QProgressBar(parent), + d_ptr(new QtMaterialCircularProgressPrivate(this)) +{ + d_func()->init(); +} + +QtMaterialCircularProgress::~QtMaterialCircularProgress() +{ +} + +void QtMaterialCircularProgress::setProgressType(XXMaterial::ProgressType type) +{ + Q_D(QtMaterialCircularProgress); + + d->progressType = type; + update(); +} + +XXMaterial::ProgressType QtMaterialCircularProgress::progressType() const +{ + Q_D(const QtMaterialCircularProgress); + + return d->progressType; +} + +void QtMaterialCircularProgress::setUseThemeColors(bool value) +{ + Q_D(QtMaterialCircularProgress); + + if (d->useThemeColors == value) { + return; + } + + d->useThemeColors = value; + update(); +} + +bool QtMaterialCircularProgress::useThemeColors() const +{ + Q_D(const QtMaterialCircularProgress); + + return d->useThemeColors; +} + +void QtMaterialCircularProgress::setLineWidth(qreal width) +{ + Q_D(QtMaterialCircularProgress); + + d->penWidth = width; + update(); + updateGeometry(); +} + +qreal QtMaterialCircularProgress::lineWidth() const +{ + Q_D(const QtMaterialCircularProgress); + + return d->penWidth; +} + +void QtMaterialCircularProgress::setSize(int size) +{ + Q_D(QtMaterialCircularProgress); + + d->size = size; + update(); + updateGeometry(); +} + +int QtMaterialCircularProgress::size() const +{ + Q_D(const QtMaterialCircularProgress); + + return d->size; +} + +void QtMaterialCircularProgress::setColor(const QColor &color) +{ + Q_D(QtMaterialCircularProgress); + + d->color = color; + setUseThemeColors(false); +} + +QColor QtMaterialCircularProgress::color() const +{ + Q_D(const QtMaterialCircularProgress); + + if (d->useThemeColors || !d->color.isValid()) { + return QtMaterialStyle::instance().themeColor("primary1"); + } else { + return d->color; + } +} + +/*! + * \reimp + */ +QSize QtMaterialCircularProgress::sizeHint() const +{ + Q_D(const QtMaterialCircularProgress); + + const qreal s = d->size+d->penWidth+8; + return QSize(s, s); +} + +/*! + * \reimp + */ +void QtMaterialCircularProgress::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + + Q_D(QtMaterialCircularProgress); + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + + if (!isEnabled()) + { + QPen pen; + pen.setCapStyle(Qt::RoundCap); + pen.setWidthF(d->penWidth); + pen.setColor(QtMaterialStyle::instance().themeColor("border")); + painter.setPen(pen); + painter.drawLine(rect().center()-QPointF(20, 20), rect().center()+QPointF(20, 20)); + painter.drawLine(rect().center()+QPointF(20, -20), rect().center()-QPointF(20, -20)); + return; + } + + if (XXMaterial::IndeterminateProgress == d->progressType) + { + painter.translate(width()/2, height()/2); + painter.rotate(d->delegate->angle()); + } + + QPen pen; + pen.setCapStyle(Qt::RoundCap); + pen.setWidthF(d->penWidth); + pen.setColor(color()); + + if (XXMaterial::IndeterminateProgress == d->progressType) + { + QVector pattern; + pattern << d->delegate->dashLength()*d->size/50 << 30*d->size/50; + + pen.setDashOffset(d->delegate->dashOffset()*d->size/50); + pen.setDashPattern(pattern); + + painter.setPen(pen); + + painter.drawEllipse(QPoint(0, 0), d->size/2, d->size/2); + } + else + { + painter.setPen(pen); + + const qreal x = (width()-d->size)/2; + const qreal y = (height()-d->size)/2; + + const qreal a = 360*(value()-minimum())/(maximum()-minimum()); + + QPainterPath path; + path.arcMoveTo(x, y, d->size, d->size, 0); + path.arcTo(x, y, d->size, d->size, 0, a); + + painter.drawPath(path); + } +} diff --git a/xx/qtmaterialcircularprogress.h b/xx/qtmaterialcircularprogress.h new file mode 100644 index 0000000..79b76ef --- /dev/null +++ b/xx/qtmaterialcircularprogress.h @@ -0,0 +1,48 @@ +#ifndef QTMATERIALCIRCULARPROGRESS_H +#define QTMATERIALCIRCULARPROGRESS_H + +#include +#include "xxlib/qtmaterialtheme.h" + +class QtMaterialCircularProgressPrivate; + +class QtMaterialCircularProgress : public QProgressBar +{ + Q_OBJECT + + Q_PROPERTY(qreal lineWidth WRITE setLineWidth READ lineWidth) + Q_PROPERTY(qreal size WRITE setSize READ size) + Q_PROPERTY(QColor color WRITE setColor READ color) + +public: + explicit QtMaterialCircularProgress(QWidget *parent = 0); + ~QtMaterialCircularProgress(); + + void setProgressType(XXMaterial::ProgressType type); + XXMaterial::ProgressType progressType() const; + + void setUseThemeColors(bool value); + bool useThemeColors() const; + + void setLineWidth(qreal width); + qreal lineWidth() const; + + void setSize(int size); + int size() const; + + void setColor(const QColor &color); + QColor color() const; + + QSize sizeHint() const Q_DECL_OVERRIDE; + +protected: + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + + const QScopedPointer d_ptr; + +private: + Q_DISABLE_COPY(QtMaterialCircularProgress) + Q_DECLARE_PRIVATE(QtMaterialCircularProgress) +}; + +#endif // QTMATERIALCIRCULARPROGRESS_H diff --git a/xx/qtmaterialcircularprogress_internal.cpp b/xx/qtmaterialcircularprogress_internal.cpp new file mode 100644 index 0000000..674b750 --- /dev/null +++ b/xx/qtmaterialcircularprogress_internal.cpp @@ -0,0 +1,20 @@ +#include "xx/qtmaterialcircularprogress_internal.h" + +/*! + * \class QtMaterialCircularProgressDelegate + * \internal + */ + +QtMaterialCircularProgressDelegate::QtMaterialCircularProgressDelegate(QtMaterialCircularProgress *parent) + : QObject(parent), + m_progress(parent), + m_dashOffset(0), + m_dashLength(89), + m_angle(0) +{ + Q_ASSERT(parent); +} + +QtMaterialCircularProgressDelegate::~QtMaterialCircularProgressDelegate() +{ +} diff --git a/xx/qtmaterialcircularprogress_internal.h b/xx/qtmaterialcircularprogress_internal.h new file mode 100644 index 0000000..25a0f56 --- /dev/null +++ b/xx/qtmaterialcircularprogress_internal.h @@ -0,0 +1,70 @@ +#ifndef QTMATERIALCIRCULARPROGRESS_INTERNAL_H +#define QTMATERIALCIRCULARPROGRESS_INTERNAL_H + +#include +#include "xx/qtmaterialcircularprogress.h" + +class QtMaterialCircularProgressDelegate : public QObject +{ + Q_OBJECT + + Q_PROPERTY(qreal dashOffset WRITE setDashOffset READ dashOffset) + Q_PROPERTY(qreal dashLength WRITE setDashLength READ dashLength) + Q_PROPERTY(int angle WRITE setAngle READ angle) + +public: + QtMaterialCircularProgressDelegate(QtMaterialCircularProgress *parent); + ~QtMaterialCircularProgressDelegate(); + + inline void setDashOffset(qreal offset); + inline qreal dashOffset() const; + + inline void setDashLength(qreal length); + inline qreal dashLength() const; + + inline void setAngle(int angle); + inline int angle() const; + +private: + Q_DISABLE_COPY(QtMaterialCircularProgressDelegate) + + QtMaterialCircularProgress *const m_progress; + qreal m_dashOffset; + qreal m_dashLength; + int m_angle; +}; + +inline void QtMaterialCircularProgressDelegate::setDashOffset(qreal offset) +{ + m_dashOffset = offset; + m_progress->update(); +} + +inline qreal QtMaterialCircularProgressDelegate::dashOffset() const +{ + return m_dashOffset; +} + +inline void QtMaterialCircularProgressDelegate::setDashLength(qreal length) +{ + m_dashLength = length; + m_progress->update(); +} + +inline qreal QtMaterialCircularProgressDelegate::dashLength() const +{ + return m_dashLength; +} + +inline void QtMaterialCircularProgressDelegate::setAngle(int angle) +{ + m_angle = angle; + m_progress->update(); +} + +inline int QtMaterialCircularProgressDelegate::angle() const +{ + return m_angle; +} + +#endif // QTMATERIALCIRCULARPROGRESS_INTERNAL_H diff --git a/xx/qtmaterialcircularprogress_p.h b/xx/qtmaterialcircularprogress_p.h new file mode 100644 index 0000000..da37068 --- /dev/null +++ b/xx/qtmaterialcircularprogress_p.h @@ -0,0 +1,30 @@ +#ifndef QTMATERIALCIRCULARPROGRESS_P_H +#define QTMATERIALCIRCULARPROGRESS_P_H + +#include +#include "xxlib/qtmaterialtheme.h" + +class QtMaterialCircularProgress; +class QtMaterialCircularProgressDelegate; + +class QtMaterialCircularProgressPrivate +{ + Q_DISABLE_COPY(QtMaterialCircularProgressPrivate) + Q_DECLARE_PUBLIC(QtMaterialCircularProgress) + +public: + QtMaterialCircularProgressPrivate(QtMaterialCircularProgress *q); + ~QtMaterialCircularProgressPrivate(); + + void init(); + + QtMaterialCircularProgress *const q_ptr; + QtMaterialCircularProgressDelegate *delegate; + XXMaterial::ProgressType progressType; + QColor color; + qreal penWidth; + int size; + bool useThemeColors; +}; + +#endif // QTMATERIALCIRCULARPROGRESS_P_H diff --git a/xx/qtmaterialfab.cpp b/xx/qtmaterialfab.cpp index d504db6..342a798 100644 --- a/xx/qtmaterialfab.cpp +++ b/xx/qtmaterialfab.cpp @@ -116,6 +116,9 @@ QtMaterialFloatingActionButton::~QtMaterialFloatingActionButton() { } +/*! + * \reimp + */ QSize QtMaterialFloatingActionButton::sizeHint() const { Q_D(const QtMaterialFloatingActionButton); @@ -224,6 +227,9 @@ int QtMaterialFloatingActionButton::yOffset() const return d->offsY; } +/*! + * \reimp + */ bool QtMaterialFloatingActionButton::event(QEvent *event) { Q_D(QtMaterialFloatingActionButton); @@ -250,6 +256,9 @@ bool QtMaterialFloatingActionButton::event(QEvent *event) return QtMaterialRaisedButton::event(event); } +/*! + * \reimp + */ bool QtMaterialFloatingActionButton::eventFilter(QObject *obj, QEvent *event) { const QEvent::Type type = event->type(); @@ -263,6 +272,9 @@ bool QtMaterialFloatingActionButton::eventFilter(QObject *obj, QEvent *event) return QtMaterialRaisedButton::eventFilter(obj, event); } +/*! + * \reimp + */ void QtMaterialFloatingActionButton::paintEvent(QPaintEvent *event) { Q_UNUSED(event) diff --git a/xx/qtmaterialflatbutton.cpp b/xx/qtmaterialflatbutton.cpp index 1316593..10e9a02 100644 --- a/xx/qtmaterialflatbutton.cpp +++ b/xx/qtmaterialflatbutton.cpp @@ -129,6 +129,10 @@ void QtMaterialFlatButton::setUseThemeColors(bool value) { Q_D(QtMaterialFlatButton); + if (d->useThemeColors == value) { + return; + } + d->useThemeColors = value; d->stateMachine->setupProperties(); } diff --git a/xx/qtmaterialiconbutton.cpp b/xx/qtmaterialiconbutton.cpp index d18ee6a..feffa6d 100644 --- a/xx/qtmaterialiconbutton.cpp +++ b/xx/qtmaterialiconbutton.cpp @@ -5,6 +5,11 @@ #include "xxlib/qtmaterialstyle.h" #include "xxlib/qtmaterialrippleoverlay.h" +/*! + * \class QtMaterialIconButtonPrivate + * \internal + */ + QtMaterialIconButtonPrivate::QtMaterialIconButtonPrivate(QtMaterialIconButton *q) : q_ptr(q) { @@ -21,6 +26,8 @@ void QtMaterialIconButtonPrivate::init() rippleOverlay = new QtMaterialRippleOverlay(q->parentWidget()); useThemeColors = true; + q->setStyle(&QtMaterialStyle::instance()); + QSizePolicy policy; policy.setWidthForHeight(true); q->setSizePolicy(policy); @@ -28,6 +35,10 @@ void QtMaterialIconButtonPrivate::init() rippleOverlay->installEventFilter(q); } +/*! + * \class QtMaterialIconButton + */ + QtMaterialIconButton::QtMaterialIconButton(const QIcon &icon, QWidget *parent) : QAbstractButton(parent), d_ptr(new QtMaterialIconButtonPrivate(this)) @@ -41,6 +52,9 @@ QtMaterialIconButton::~QtMaterialIconButton() { } +/*! + * \reimp + */ QSize QtMaterialIconButton::sizeHint() const { return iconSize(); @@ -50,6 +64,10 @@ void QtMaterialIconButton::setUseThemeColors(bool value) { Q_D(QtMaterialIconButton); + if (d->useThemeColors == value) { + return; + } + d->useThemeColors = value; update(); } @@ -104,6 +122,9 @@ QtMaterialIconButton::QtMaterialIconButton(QtMaterialIconButtonPrivate &d, QWidg d_func()->init(); } +/*! + * \reimp + */ bool QtMaterialIconButton::event(QEvent *event) { Q_D(QtMaterialIconButton); @@ -123,6 +144,9 @@ bool QtMaterialIconButton::event(QEvent *event) return QAbstractButton::event(event); } +/*! + * \reimp + */ bool QtMaterialIconButton::eventFilter(QObject *obj, QEvent *event) { if (QEvent::Resize == event->type()) @@ -135,6 +159,9 @@ bool QtMaterialIconButton::eventFilter(QObject *obj, QEvent *event) return QAbstractButton::eventFilter(obj, event); } +/*! + * \reimp + */ void QtMaterialIconButton::mousePressEvent(QMouseEvent *event) { Q_D(QtMaterialIconButton); @@ -147,6 +174,9 @@ void QtMaterialIconButton::mousePressEvent(QMouseEvent *event) QAbstractButton::mousePressEvent(event); } +/*! + * \reimp + */ void QtMaterialIconButton::paintEvent(QPaintEvent *event) { Q_UNUSED(event) diff --git a/xx/qtmaterialiconmenu.cpp b/xx/qtmaterialiconmenu.cpp index 54e34a9..d998b88 100644 --- a/xx/qtmaterialiconmenu.cpp +++ b/xx/qtmaterialiconmenu.cpp @@ -116,6 +116,9 @@ void QtMaterialIconMenu::collapseDelayed() } } +/*! + * \reimp + */ bool QtMaterialIconMenu::event(QEvent *event) { Q_D(QtMaterialIconMenu); @@ -152,6 +155,9 @@ bool QtMaterialIconMenu::event(QEvent *event) return QtMaterialIconButton::event(event); } +/*! + * \reimp + */ bool QtMaterialIconMenu::eventFilter(QObject *obj, QEvent *event) { Q_D(QtMaterialIconMenu); diff --git a/xx/qtmaterialprogress.cpp b/xx/qtmaterialprogress.cpp new file mode 100644 index 0000000..ca3ad30 --- /dev/null +++ b/xx/qtmaterialprogress.cpp @@ -0,0 +1,168 @@ +#include "xx/qtmaterialprogress.h" +#include "xx/qtmaterialprogress_p.h" +#include +#include +#include "xx/qtmaterialprogress_internal.h" +#include "xxlib/qtmaterialstyle.h" + +/*! + * \class QtMaterialProgressPrivate + * \internal + */ + +QtMaterialProgressPrivate::QtMaterialProgressPrivate(QtMaterialProgress *q) + : q_ptr(q) +{ +} + +QtMaterialProgressPrivate::~QtMaterialProgressPrivate() +{ +} + +void QtMaterialProgressPrivate::init() +{ + Q_Q(QtMaterialProgress); + + delegate = new QtMaterialProgressDelegate(q); + progressType = XXMaterial::IndeterminateProgress; + useThemeColors = true; + + QPropertyAnimation *animation; + + animation = new QPropertyAnimation(q); + animation->setPropertyName("offset"); + animation->setTargetObject(delegate); + animation->setStartValue(0); + animation->setEndValue(1); + animation->setDuration(1000); + + animation->setLoopCount(-1); + + animation->start(); +} + +/*! + * \class QtMaterialProgress + */ + +QtMaterialProgress::QtMaterialProgress(QWidget *parent) + : QProgressBar(parent), + d_ptr(new QtMaterialProgressPrivate(this)) +{ + d_func()->init(); +} + +QtMaterialProgress::~QtMaterialProgress() +{ +} + +void QtMaterialProgress::setProgressType(XXMaterial::ProgressType type) +{ + Q_D(QtMaterialProgress); + + d->progressType = type; + update(); +} + +XXMaterial::ProgressType QtMaterialProgress::progressType() const +{ + Q_D(const QtMaterialProgress); + + return d->progressType; +} + +void QtMaterialProgress::setUseThemeColors(bool state) +{ + Q_D(QtMaterialProgress); + + if (d->useThemeColors == state) { + return; + } + + d->useThemeColors = state; + update(); +} + +bool QtMaterialProgress::useThemeColors() const +{ + Q_D(const QtMaterialProgress); + + return d->useThemeColors; +} + +void QtMaterialProgress::setProgressColor(const QColor &color) +{ + Q_D(QtMaterialProgress); + + d->progressColor = color; + setUseThemeColors(false); +} + +QColor QtMaterialProgress::progressColor() const +{ + Q_D(const QtMaterialProgress); + + if (d->useThemeColors || !d->progressColor.isValid()) { + return QtMaterialStyle::instance().themeColor("primary1"); + } else { + return d->progressColor; + } +} + +void QtMaterialProgress::setBackgroundColor(const QColor &color) +{ + Q_D(QtMaterialProgress); + + d->backgroundColor = color; + setUseThemeColors(false); +} + +QColor QtMaterialProgress::backgroundColor() const +{ + Q_D(const QtMaterialProgress); + + if (d->useThemeColors || !d->backgroundColor.isValid()) { + return QtMaterialStyle::instance().themeColor("border"); + } else { + return d->backgroundColor; + } +} + +/*! + * \reimp + */ +void QtMaterialProgress::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + + Q_D(QtMaterialProgress); + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + + QBrush brush; + brush.setStyle(Qt::SolidPattern); + brush.setColor(isEnabled() ? backgroundColor() + : QtMaterialStyle::instance().themeColor("disabled")); + painter.setBrush(brush); + painter.setPen(Qt::NoPen); + + QPainterPath path; + path.addRoundedRect(0, height()/2-3, width(), 6, 3, 3); + painter.setClipPath(path); + + painter.drawRect(0, 0, width(), height()); + + if (isEnabled()) + { + brush.setColor(progressColor()); + painter.setBrush(brush); + + if (XXMaterial::IndeterminateProgress == d->progressType) { + painter.drawRect(d->delegate->offset()*width()*2-width(), 0, width(), height()); + } else { + qreal p = static_cast(width())*(value()-minimum())/(maximum()-minimum()); + painter.drawRect(0, 0, p, height()); + } + } +} diff --git a/xx/qtmaterialprogress.h b/xx/qtmaterialprogress.h new file mode 100644 index 0000000..92be723 --- /dev/null +++ b/xx/qtmaterialprogress.h @@ -0,0 +1,42 @@ +#ifndef QTMATERIALPROGRESS_H +#define QTMATERIALPROGRESS_H + +#include +#include "xxlib/qtmaterialtheme.h" + +class QtMaterialProgressPrivate; + +class QtMaterialProgress : public QProgressBar +{ + Q_OBJECT + + Q_PROPERTY(QColor progressColor WRITE setProgressColor READ progressColor) + Q_PROPERTY(QColor backgroundColor WRITE setProgressColor READ backgroundColor) + +public: + explicit QtMaterialProgress(QWidget *parent = 0); + ~QtMaterialProgress(); + + void setProgressType(XXMaterial::ProgressType type); + XXMaterial::ProgressType progressType() const; + + void setUseThemeColors(bool state); + bool useThemeColors() const; + + void setProgressColor(const QColor &color); + QColor progressColor() const; + + void setBackgroundColor(const QColor &color); + QColor backgroundColor() const; + +protected: + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + + const QScopedPointer d_ptr; + +private: + Q_DISABLE_COPY(QtMaterialProgress) + Q_DECLARE_PRIVATE(QtMaterialProgress) +}; + +#endif // QTMATERIALPROGRESS_H diff --git a/xx/qtmaterialprogress_internal.cpp b/xx/qtmaterialprogress_internal.cpp new file mode 100644 index 0000000..47fe5db --- /dev/null +++ b/xx/qtmaterialprogress_internal.cpp @@ -0,0 +1,18 @@ +#include "xx/qtmaterialprogress_internal.h" + +/*! + * \class QtMaterialProgressDelegate + * \internal + */ + +QtMaterialProgressDelegate::QtMaterialProgressDelegate(QtMaterialProgress *parent) + : QObject(parent), + m_progress(parent), + m_offset(0) +{ + Q_ASSERT(parent); +} + +QtMaterialProgressDelegate::~QtMaterialProgressDelegate() +{ +} diff --git a/xx/qtmaterialprogress_internal.h b/xx/qtmaterialprogress_internal.h new file mode 100644 index 0000000..1d50a68 --- /dev/null +++ b/xx/qtmaterialprogress_internal.h @@ -0,0 +1,38 @@ +#ifndef QTMATERIALPROGRESS_INTERNAL_H +#define QTMATERIALPROGRESS_INTERNAL_H + +#include +#include "xx/qtmaterialprogress.h" + +class QtMaterialProgressDelegate : public QObject +{ + Q_OBJECT + + Q_PROPERTY(qreal offset WRITE setOffset READ offset) + +public: + QtMaterialProgressDelegate(QtMaterialProgress *parent); + ~QtMaterialProgressDelegate(); + + inline void setOffset(qreal offset); + inline qreal offset() const; + +private: + Q_DISABLE_COPY(QtMaterialProgressDelegate) + + QtMaterialProgress *const m_progress; + qreal m_offset; +}; + +inline void QtMaterialProgressDelegate::setOffset(qreal offset) +{ + m_offset = offset; + m_progress->update(); +} + +inline qreal QtMaterialProgressDelegate::offset() const +{ + return m_offset; +} + +#endif // QTMATERIALPROGRESS_INTERNAL_H diff --git a/xx/qtmaterialprogress_p.h b/xx/qtmaterialprogress_p.h new file mode 100644 index 0000000..229d99a --- /dev/null +++ b/xx/qtmaterialprogress_p.h @@ -0,0 +1,30 @@ +#ifndef QTMATERIALPROGRESS_P_H +#define QTMATERIALPROGRESS_P_H + +#include +#include +#include "xxlib/qtmaterialtheme.h" + +class QtMaterialProgress; +class QtMaterialProgressDelegate; + +class QtMaterialProgressPrivate +{ + Q_DISABLE_COPY(QtMaterialProgressPrivate) + Q_DECLARE_PUBLIC(QtMaterialProgress) + +public: + QtMaterialProgressPrivate(QtMaterialProgress *q); + ~QtMaterialProgressPrivate(); + + void init(); + + QtMaterialProgress *const q_ptr; + QtMaterialProgressDelegate *delegate; + XXMaterial::ProgressType progressType; + QColor progressColor; + QColor backgroundColor; + bool useThemeColors; +}; + +#endif // QTMATERIALPROGRESS_P_H diff --git a/xx/qtmaterialradiobutton.cpp b/xx/qtmaterialradiobutton.cpp new file mode 100644 index 0000000..aae289f --- /dev/null +++ b/xx/qtmaterialradiobutton.cpp @@ -0,0 +1,100 @@ +#include "xx/qtmaterialradiobutton.h" +#include "xx/qtmaterialradiobutton_p.h" +#include +#include +#include +#include +#include "xxlib/qtmaterialcheckable_internal.h" + +/*! + * \class QtMaterialRadioButtonPrivate + * \internal + */ + +QtMaterialRadioButtonPrivate::QtMaterialRadioButtonPrivate(QtMaterialRadioButton *q) + : QtMaterialCheckablePrivate(q) +{ +} + +QtMaterialRadioButtonPrivate::~QtMaterialRadioButtonPrivate() +{ +} + +void QtMaterialRadioButtonPrivate::init() +{ + Q_Q(QtMaterialRadioButton); + + q->setAutoExclusive(true); + + q->setCheckedIcon(QIcon("../qt-material-widgets/ic_radio_button_checked_black_24px.svg")); + q->setUncheckedIcon(QIcon("../qt-material-widgets/ic_radio_button_unchecked_black_24px.svg")); + + uncheckedState->assignProperty(checkedIcon, "iconSize", 0); + uncheckedState->assignProperty(uncheckedIcon, "iconSize", 24); + + disabledUncheckedState->assignProperty(checkedIcon, "iconSize", 0); + disabledUncheckedState->assignProperty(uncheckedIcon, "iconSize", 24); + + checkedState->assignProperty(uncheckedIcon, "iconSize", 0); + checkedState->assignProperty(checkedIcon, "iconSize", 24); + + disabledCheckedState->assignProperty(uncheckedIcon, "iconSize", 0); + disabledCheckedState->assignProperty(checkedIcon, "iconSize", 24); + + uncheckedState->assignProperty(checkedIcon, "opacity", 0); + uncheckedState->assignProperty(uncheckedIcon, "opacity", 1); + + checkedState->assignProperty(uncheckedIcon, "opacity", 0); + checkedState->assignProperty(checkedIcon, "opacity", 1); + + checkedIcon->setIconSize(0); + + // + + checkedState->assignProperty(checkedIcon, "color", q->checkedColor()); + checkedState->assignProperty(uncheckedIcon, "color", q->uncheckedColor()); + uncheckedState->assignProperty(uncheckedIcon, "color", q->uncheckedColor()); + + QPropertyAnimation *animation; + + animation = new QPropertyAnimation(checkedIcon, "iconSize", q); + animation->setDuration(250); + stateMachine->addDefaultAnimation(animation); + + animation = new QPropertyAnimation(uncheckedIcon, "iconSize", q); + animation->setDuration(250); + stateMachine->addDefaultAnimation(animation); + + animation = new QPropertyAnimation(uncheckedIcon, "opacity", q); + animation->setDuration(250); + stateMachine->addDefaultAnimation(animation); + + animation = new QPropertyAnimation(checkedIcon, "opacity", q); + animation->setDuration(250); + stateMachine->addDefaultAnimation(animation); +} + +/*! + * \class QtMaterialRadioButton + */ + +QtMaterialRadioButton::QtMaterialRadioButton(QWidget *parent) + : QtMaterialCheckable(*new QtMaterialRadioButtonPrivate(this), parent) +{ + d_func()->init(); +} + +QtMaterialRadioButton::~QtMaterialRadioButton() +{ +} + +void QtMaterialRadioButton::setupProperties() +{ + QtMaterialCheckable::setupProperties(); + + Q_D(QtMaterialRadioButton); + + d->checkedState->assignProperty(d->checkedIcon, "color", checkedColor()); + d->checkedState->assignProperty(d->uncheckedIcon, "color", uncheckedColor()); + d->uncheckedState->assignProperty(d->uncheckedIcon, "color", uncheckedColor()); +} diff --git a/xx/qtmaterialradiobutton.h b/xx/qtmaterialradiobutton.h new file mode 100644 index 0000000..7c12a45 --- /dev/null +++ b/xx/qtmaterialradiobutton.h @@ -0,0 +1,24 @@ +#ifndef QTMATERIALRADIOBUTTON_H +#define QTMATERIALRADIOBUTTON_H + +#include "xxlib/qtmaterialcheckable.h" + +class QtMaterialRadioButtonPrivate; + +class QtMaterialRadioButton : public QtMaterialCheckable +{ + Q_OBJECT + +public: + explicit QtMaterialRadioButton(QWidget *parent = 0); + ~QtMaterialRadioButton(); + +protected: + void setupProperties(); + +private: + Q_DISABLE_COPY(QtMaterialRadioButton) + Q_DECLARE_PRIVATE(QtMaterialRadioButton) +}; + +#endif // QTMATERIALRADIOBUTTON_H diff --git a/xx/qtmaterialradiobutton_p.h b/xx/qtmaterialradiobutton_p.h new file mode 100644 index 0000000..7ca9f16 --- /dev/null +++ b/xx/qtmaterialradiobutton_p.h @@ -0,0 +1,20 @@ +#ifndef QTMATERIALRADIOBUTTON_P_H +#define QTMATERIALRADIOBUTTON_P_H + +#include "xxlib/qtmaterialcheckable_p.h" + +class QtMaterialRadioButton; + +class QtMaterialRadioButtonPrivate : public QtMaterialCheckablePrivate +{ + Q_DISABLE_COPY(QtMaterialRadioButtonPrivate) + Q_DECLARE_PUBLIC(QtMaterialRadioButton) + +public: + QtMaterialRadioButtonPrivate(QtMaterialRadioButton *q); + ~QtMaterialRadioButtonPrivate(); + + void init(); +}; + +#endif // QTMATERIALRADIOBUTTON_P_H diff --git a/xx/qtmaterialscrollbar.cpp b/xx/qtmaterialscrollbar.cpp index d768e21..05a61a1 100644 --- a/xx/qtmaterialscrollbar.cpp +++ b/xx/qtmaterialscrollbar.cpp @@ -26,6 +26,12 @@ void QtMaterialScrollBarPrivate::init() hideOnMouseOut = true; useThemeColors = true; + q->setMouseTracking(true); + q->setStyle(&QtMaterialStyle::instance()); + q->setStyleSheet("QScrollBar:vertical { margin: 0; }" + "QScrollBar::add-line:vertical { height: 0; margin: 0; }" + "QScrollBar::sub-line:vertical { height: 0; margin: 0; }"); + stateMachine->start(); } @@ -44,6 +50,9 @@ QtMaterialScrollBar::~QtMaterialScrollBar() { } +/*! + * \reimp + */ QSize QtMaterialScrollBar::sizeHint() const { if (Qt::Horizontal == orientation()) { @@ -57,6 +66,10 @@ void QtMaterialScrollBar::setUseThemeColors(bool value) { Q_D(QtMaterialScrollBar); + if (d->useThemeColors == value) { + return; + } + d->useThemeColors = value; update(); } @@ -140,6 +153,9 @@ bool QtMaterialScrollBar::hideOnMouseOut() const return d->hideOnMouseOut; } +/*! + * \reimp + */ void QtMaterialScrollBar::paintEvent(QPaintEvent *event) { Q_UNUSED(event) diff --git a/xx/qtmaterialselectfield.cpp b/xx/qtmaterialselectfield.cpp index 408a57d..86ff81f 100644 --- a/xx/qtmaterialselectfield.cpp +++ b/xx/qtmaterialselectfield.cpp @@ -72,6 +72,9 @@ QtMaterialSelectField::~QtMaterialSelectField() { } +/*! + * \reimp + */ QSize QtMaterialSelectField::sizeHint() const { return QSize(300, 30); @@ -114,6 +117,10 @@ void QtMaterialSelectField::setUseThemeColors(bool value) { Q_D(QtMaterialSelectField); + if (d->useThemeColors == value) { + return; + } + d->useThemeColors = value; update(); } @@ -261,6 +268,9 @@ void QtMaterialSelectField::collapseDelayed() QTimer::singleShot(200, d->menu, SLOT(collapse())); } +/*! + * \reimp + */ bool QtMaterialSelectField::event(QEvent *event) { Q_D(QtMaterialSelectField); @@ -304,6 +314,9 @@ bool QtMaterialSelectField::event(QEvent *event) return QWidget::event(event); } +/*! + * \reimp + */ bool QtMaterialSelectField::eventFilter(QObject *obj, QEvent *event) { Q_D(QtMaterialSelectField); @@ -314,6 +327,9 @@ bool QtMaterialSelectField::eventFilter(QObject *obj, QEvent *event) return QWidget::eventFilter(obj, event); } +/*! + * \reimp + */ void QtMaterialSelectField::paintEvent(QPaintEvent *event) { Q_UNUSED(event) diff --git a/xx/qtmaterialslider.cpp b/xx/qtmaterialslider.cpp new file mode 100644 index 0000000..0ff7507 --- /dev/null +++ b/xx/qtmaterialslider.cpp @@ -0,0 +1,362 @@ +#include "xx/qtmaterialslider.h" +#include "xx/qtmaterialslider_p.h" +#include +#include +#include "xx/qtmaterialslider_internal.h" +#include "xxlib/qtmaterialstyle.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(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(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 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); +} + +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() - SliderMargin*2 + : q->height() - SliderMargin*2; + + return QtMaterialStyle::sliderValueFromPosition( + q->minimum(), + q->maximum(), + position - SliderMargin, + span, + q->invertedAppearance()); +} + +void QtMaterialSliderPrivate::setHovered(bool status) +{ + Q_Q(QtMaterialSlider); + + if (hover == status) { + return; + } + + hover = status; + + if (!q->hasFocus()) { + if (status) { + emit stateMachine->noFocusMouseEnter(); + } else { + emit stateMachine->noFocusMouseLeave(); + } + } + + 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; +} + +QSize QtMaterialSlider::minimumSizeHint() const +{ + return Qt::Horizontal == orientation() + ? QSize(20, 34) + : QSize(34, 20); +} + +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); + emit d->stateMachine->changedToMinimum(); + } else if (maximum() == value()) { + triggerAction(SliderToMaximum); + } + if (minimum() == d->oldValue) { + emit d->stateMachine->changedFromMinimum(); + } + d->oldValue = value(); + } + + QAbstractSlider::sliderChange(change); +} + +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); +} + +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); +} + +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); +} + +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); +} + +int QtMaterialSlider::thumbOffset() const +{ + return QtMaterialStyle::sliderPositionFromValue( + minimum(), + maximum(), + sliderPosition(), + Qt::Horizontal == orientation() + ? width() - QtMaterialSliderPrivate::SliderMargin*2 + : height() - QtMaterialSliderPrivate::SliderMargin*2, + invertedAppearance()); +} diff --git a/xx/qtmaterialslider.h b/xx/qtmaterialslider.h new file mode 100644 index 0000000..96f8262 --- /dev/null +++ b/xx/qtmaterialslider.h @@ -0,0 +1,57 @@ +#ifndef QTMATERIALSLIDER_H +#define QTMATERIALSLIDER_H + +#include +#include + +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; + +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; + + friend class QtMaterialSliderThumb; + friend class QtMaterialSliderTrack; + + int thumbOffset() const; + + const QScopedPointer d_ptr; + +private: + Q_DISABLE_COPY(QtMaterialSlider) + Q_DECLARE_PRIVATE(QtMaterialSlider) +}; + +#endif // QTMATERIALSLIDER_H diff --git a/xx/qtmaterialslider_internal.cpp b/xx/qtmaterialslider_internal.cpp new file mode 100644 index 0000000..130adb2 --- /dev/null +++ b/xx/qtmaterialslider_internal.cpp @@ -0,0 +1,402 @@ +#include "xx/qtmaterialslider_internal.h" +#include +#include +#include +#include +#include +#include +#include "xx/qtmaterialslider.h" +#include "xxlib/qtmaterialstyle.h" + +enum { + SliderMargin = 30 +}; + +/*! + * \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; + QPropertyAnimation *animation; + + // Show halo on mouse enter + + transition = new QSignalTransition(this, SIGNAL(noFocusMouseEnter())); + 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); + + // 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 + + transition = new QSignalTransition(this, SIGNAL(noFocusMouseLeave())); + 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); + + // 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); + + transition = new QSignalTransition(this, SIGNAL(changedFromMinimum())); + transition->setTargetState(m_normalState); + + animation = new QPropertyAnimation(thumb, "fillColor", this); + animation->setDuration(200); + transition->addAnimation(animation); + + animation = new QPropertyAnimation(thumb, "haloColor", this); + animation->setDuration(300); + transition->addAnimation(animation); + + animation = new QPropertyAnimation(thumb, "borderColor", this); + animation->setDuration(200); + transition->addAnimation(animation); + + animation = new QPropertyAnimation(thumb, "borderWidth", this); + animation->setDuration(200); + transition->addAnimation(animation); + + m_minState->addTransition(transition); + + transition = new QSignalTransition(this, SIGNAL(changedToMinimum())); + transition->setTargetState(m_minState); + + animation = new QPropertyAnimation(thumb, "fillColor", this); + animation->setDuration(200); + transition->addAnimation(animation); + + animation = new QPropertyAnimation(thumb, "haloColor", this); + animation->setDuration(300); + transition->addAnimation(animation); + + animation = new QPropertyAnimation(thumb, "borderColor", this); + animation->setDuration(200); + transition->addAnimation(animation); + + animation = new QPropertyAnimation(thumb, "borderWidth", this); + animation->setDuration(200); + transition->addAnimation(animation); + + m_normalState->addTransition(transition); + + 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); + + //m_minState->assignProperty(_thumb, "fillColor", slider->palette().color(QPalette::Base)); + m_minState->assignProperty(m_thumb, "fillColor", QColor(Qt::red)); + 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) +{ + 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(SliderMargin + m_slider->thumbOffset(), m_slider->height()/2) + : QPointF(m_slider->width()/2, SliderMargin + m_slider->thumbOffset()); + + 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_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()); + + 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(QtMaterialSlider *slider) + : QtMaterialOverlayWidget(slider->parentWidget()), + m_slider(slider), + 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_slider->thumbOffset(); + + if (Qt::Horizontal == m_slider->orientation()) { + painter.translate(m_slider->x() + SliderMargin, + 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); + } + + 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 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); +} diff --git a/xx/qtmaterialslider_internal.h b/xx/qtmaterialslider_internal.h new file mode 100644 index 0000000..6ab6708 --- /dev/null +++ b/xx/qtmaterialslider_internal.h @@ -0,0 +1,212 @@ +#ifndef QTMATERIALSLIDER_INTERNAL_H +#define QTMATERIALSLIDER_INTERNAL_H + +#include +#include "xxlib/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; + +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; +}; + +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; +} + +class QtMaterialSliderTrack : public QtMaterialOverlayWidget +{ + Q_OBJECT + + Q_PROPERTY(QColor fillColor WRITE setFillColor READ fillColor) + +public: + explicit QtMaterialSliderTrack(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; + 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 diff --git a/xx/qtmaterialslider_p.h b/xx/qtmaterialslider_p.h new file mode 100644 index 0000000..6946244 --- /dev/null +++ b/xx/qtmaterialslider_p.h @@ -0,0 +1,53 @@ +#ifndef QTMATERIALSLIDER_P_H +#define QTMATERIALSLIDER_P_H + +#include +#include +#include + +class QtMaterialSlider; +class QtMaterialSliderThumb; +class QtMaterialSliderTrack; +class QtMaterialSliderStateMachine; + +class QtMaterialSliderPrivate +{ + Q_DISABLE_COPY(QtMaterialSliderPrivate) + Q_DECLARE_PUBLIC(QtMaterialSlider) + +public: + enum { + SliderMargin = 30 + }; + + 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 diff --git a/xx/qtmaterialtabs.cpp b/xx/qtmaterialtabs.cpp new file mode 100644 index 0000000..9cf8ec7 --- /dev/null +++ b/xx/qtmaterialtabs.cpp @@ -0,0 +1,236 @@ +#include "xx/qtmaterialtabs.h" +#include "xx/qtmaterialtabs_p.h" +#include +#include "xx/qtmaterialtabs_internal.h" +#include "xxlib/qtmaterialstyle.h" + +/*! + * \QtMaterialTabsPrivate + * \internal + */ + +QtMaterialTabsPrivate::QtMaterialTabsPrivate(QtMaterialTabs *q) + : q_ptr(q) +{ +} + +QtMaterialTabsPrivate::~QtMaterialTabsPrivate() +{ +} + +void QtMaterialTabsPrivate::QtMaterialTabsPrivate::init() +{ + Q_Q(QtMaterialTabs); + + inkBar = new QtMaterialTabsInkBar(q); + tabLayout = new QHBoxLayout; + rippleStyle = XXMaterial::CenteredRipple; + tab = -1; + showHalo = true; + useThemeColors = true; + + q->setLayout(tabLayout); + q->setStyle(&QtMaterialStyle::instance()); + + tabLayout->setSpacing(0); + tabLayout->setMargin(0); +} + +/*! + * \QtMaterialTabs + */ + +QtMaterialTabs::QtMaterialTabs(QWidget *parent) + : QWidget(parent), + d_ptr(new QtMaterialTabsPrivate(this)) +{ + d_func()->init(); +} + +QtMaterialTabs::~QtMaterialTabs() +{ +} + +void QtMaterialTabs::setUseThemeColors(bool value) +{ + Q_D(QtMaterialTabs); + + d->useThemeColors = value; +} + +bool QtMaterialTabs::useThemeColors() const +{ + Q_D(const QtMaterialTabs); + + return d->useThemeColors; +} + +void QtMaterialTabs::setHaloVisible(bool value) +{ + Q_D(QtMaterialTabs); + + d->showHalo = value; + updateTabs(); +} + +bool QtMaterialTabs::isHaloVisible() const +{ + Q_D(const QtMaterialTabs); + + return d->showHalo; +} + +void QtMaterialTabs::setRippleStyle(XXMaterial::RippleStyle style) +{ + Q_D(QtMaterialTabs); + + d->rippleStyle = style; + updateTabs(); +} + +XXMaterial::RippleStyle QtMaterialTabs::rippleStyle() const +{ + Q_D(const QtMaterialTabs); + + return d->rippleStyle; +} + +void QtMaterialTabs::setInkColor(const QColor &color) +{ + Q_D(QtMaterialTabs); + + d->inkColor = color; + setUseThemeColors(false); + d->inkBar->update(); +} + +QColor QtMaterialTabs::inkColor() const +{ + Q_D(const QtMaterialTabs); + + if (d->useThemeColors || !d->inkColor.isValid()) { + return QtMaterialStyle::instance().themeColor("accent1"); + } else { + return d->inkColor; + } +} + +void QtMaterialTabs::setBackgroundColor(const QColor &color) +{ + Q_D(QtMaterialTabs); + + d->backgroundColor = color; + setUseThemeColors(false); + updateTabs(); +} + +QColor QtMaterialTabs::backgroundColor() const +{ + Q_D(const QtMaterialTabs); + + if (d->useThemeColors || !d->backgroundColor.isValid()) { + return QtMaterialStyle::instance().themeColor("primary1"); + } else { + return d->backgroundColor; + } +} + +void QtMaterialTabs::setTextColor(const QColor &color) +{ + Q_D(QtMaterialTabs); + + d->textColor = color; + setUseThemeColors(false); + updateTabs(); +} + +QColor QtMaterialTabs::textColor() const +{ + Q_D(const QtMaterialTabs); + + if (d->useThemeColors || !d->textColor.isValid()) { + return QtMaterialStyle::instance().themeColor("canvas"); + } else { + return d->textColor; + } +} + +void QtMaterialTabs::setCurrentTab(QtMaterialTab *tab) +{ + Q_D(QtMaterialTabs); + + setCurrentTab(d->tabLayout->indexOf(tab)); +} + +void QtMaterialTabs::setCurrentTab(int index) +{ + Q_D(QtMaterialTabs); + + setTabActive(d->tab, false); + d->tab = index; + setTabActive(index, true); + d->inkBar->animate(); + + emit currentChanged(index); +} + +void QtMaterialTabs::addTab(const QString &text, const QIcon &icon) +{ + Q_D(QtMaterialTabs); + + QtMaterialTab *tab = new QtMaterialTab(this); + tab->setText(text); + tab->setHaloVisible(isHaloVisible()); + tab->setRippleStyle(rippleStyle()); + + if (!icon.isNull()) { + tab->setIcon(icon); + tab->setIconSize(QSize(22, 22)); + } + + d->tabLayout->addWidget(tab); + + if (-1 == d->tab) { + d->tab = 0; + d->inkBar->refreshGeometry(); + d->inkBar->raise(); + tab->setActive(true); + } +} + +int QtMaterialTabs::currentIndex() const +{ + Q_D(const QtMaterialTabs); + + return d->tab; +} + +void QtMaterialTabs::setTabActive(int index, bool active) +{ + Q_D(QtMaterialTabs); + + QtMaterialTab *tab; + + if (index > -1) { + tab = static_cast(d->tabLayout->itemAt(index)->widget()); + if (tab) { + tab->setActive(active); + } + } +} + +void QtMaterialTabs::updateTabs() +{ + Q_D(QtMaterialTabs); + + QtMaterialTab *tab; + for (int i = 0; i < d->tabLayout->count(); ++i) { + QLayoutItem *item = d->tabLayout->itemAt(i); + if ((tab = static_cast(item->widget()))) { + tab->setRippleStyle(d->rippleStyle); + tab->setHaloVisible(d->showHalo); + tab->setBackgroundColor(backgroundColor()); + tab->setForegroundColor(textColor()); + } + } +} diff --git a/xx/qtmaterialtabs.h b/xx/qtmaterialtabs.h new file mode 100644 index 0000000..8e72320 --- /dev/null +++ b/xx/qtmaterialtabs.h @@ -0,0 +1,58 @@ +#ifndef QTMATERIALTABS_H +#define QTMATERIALTABS_H + +#include +#include +#include "xxlib/qtmaterialtheme.h" + +class QtMaterialTabsPrivate; +class QtMaterialTab; + +class QtMaterialTabs : public QWidget +{ + Q_OBJECT + +public: + explicit QtMaterialTabs(QWidget *parent = 0); + ~QtMaterialTabs(); + + void setUseThemeColors(bool value); + bool useThemeColors() const; + + void setHaloVisible(bool value); + bool isHaloVisible() const; + + void setRippleStyle(XXMaterial::RippleStyle style); + XXMaterial::RippleStyle rippleStyle() const; + + void setInkColor(const QColor &color); + QColor inkColor() const; + + void setBackgroundColor(const QColor &color); + QColor backgroundColor() const; + + void setTextColor(const QColor &color); + QColor textColor() const; + + void addTab(const QString &text, const QIcon &icon = QIcon()); + + void setCurrentTab(QtMaterialTab *tab); + void setCurrentTab(int index); + + int currentIndex() const; + +signals: + void currentChanged(int); + +protected: + void setTabActive(int index, bool active = true); + void updateTabs(); + + const QScopedPointer d_ptr; + +private: + Q_DISABLE_COPY(QtMaterialTabs) + Q_DECLARE_PRIVATE(QtMaterialTabs) +}; + +#endif // QTMATERIALTABS_H diff --git a/xx/qtmaterialtabs_internal.cpp b/xx/qtmaterialtabs_internal.cpp new file mode 100644 index 0000000..22c99d6 --- /dev/null +++ b/xx/qtmaterialtabs_internal.cpp @@ -0,0 +1,178 @@ +#include "xx/qtmaterialtabs_internal.h" +#include +#include +#include +#include +#include +#include "xx/qtmaterialtabs.h" +#include + +/*! + * \class QtMaterialTabsInkBar + * \internal + */ + +QtMaterialTabsInkBar::QtMaterialTabsInkBar(QtMaterialTabs *parent) + : QtMaterialOverlayWidget(parent), + m_tabs(parent), + m_animation(new QPropertyAnimation(parent)), + m_tween(0) +{ + Q_ASSERT(parent); + + m_animation->setPropertyName("tweenValue"); + m_animation->setEasingCurve(QEasingCurve::OutCirc); + m_animation->setTargetObject(this); + m_animation->setDuration(700); + + m_tabs->installEventFilter(this); + + setAttribute(Qt::WA_TransparentForMouseEvents); + setAttribute(Qt::WA_NoSystemBackground); +} + +QtMaterialTabsInkBar::~QtMaterialTabsInkBar() +{ +} + +void QtMaterialTabsInkBar::refreshGeometry() +{ + QLayoutItem *item = m_tabs->layout()->itemAt(m_tabs->currentIndex()); + + if (item) + { + const QRect r(item->geometry()); + const qreal s = 1-m_tween; + + if (QAbstractAnimation::Running != m_animation->state()) { + m_geometry = QRect(r.left(), r.bottom()-1, r.width(), 2); + } else { + const qreal left = m_previousGeometry.left()*s + r.left()*m_tween; + const qreal width = m_previousGeometry.width()*s + r.width()*m_tween; + m_geometry = QRect(left, r.bottom()-1, width, 2); + } + m_tabs->update(); + } +} + +void QtMaterialTabsInkBar::animate() +{ + raise(); + + m_previousGeometry = m_geometry; + + m_animation->stop(); + m_animation->setStartValue(0); + m_animation->setEndValue(1); + m_animation->start(); +} + +bool QtMaterialTabsInkBar::eventFilter(QObject *obj, QEvent *event) +{ + switch (event->type()) + { + case QEvent::Move: + case QEvent::Resize: + { + refreshGeometry(); + break; + } + default: + break; + } + return QtMaterialOverlayWidget::eventFilter(obj, event); +} + +void QtMaterialTabsInkBar::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + + QPainter painter(this); + + painter.setOpacity(1); + painter.fillRect(m_geometry, m_tabs->inkColor()); +} + +/*! + * \class QtMaterialTab + * \internal + */ + +QtMaterialTab::QtMaterialTab(QtMaterialTabs *parent) + : QtMaterialFlatButton(parent), + m_tabs(parent), + m_active(false) +{ + Q_ASSERT(parent); + + setMinimumHeight(50); + + QFont f(font()); + f.setStyleName("Normal"); + setFont(f); + + setCornerRadius(0); + setRole(XXMaterial::Primary); + setBackgroundMode(Qt::OpaqueMode); + setBaseOpacity(0.25); + + connect(this, SIGNAL(clicked(bool)), this, SLOT(activateTab())); +} + +QtMaterialTab::~QtMaterialTab() +{ +} + +QSize QtMaterialTab::sizeHint() const +{ + if (icon().isNull()) { + return QtMaterialFlatButton::sizeHint(); + } else { + return QSize(40, iconSize().height()+46); + } +} + +void QtMaterialTab::activateTab() +{ + m_tabs->setCurrentTab(this); +} + +void QtMaterialTab::paintForeground(QPainter *painter) +{ + painter->setPen(foregroundColor()); + + if (!icon().isNull()) { + painter->translate(0, 12); + } + + QSize textSize(fontMetrics().size(Qt::TextSingleLine, text())); + QSize base(size()-textSize); + + QRect textGeometry(QPoint(base.width(), base.height())/2, textSize); + + painter->drawText(textGeometry, Qt::AlignCenter, text()); + + if (!icon().isNull()) + { + const QSize &size = iconSize(); + QRect iconRect(QPoint((width()-size.width())/2, 0), size); + + QPixmap pixmap = icon().pixmap(iconSize()); + QPainter icon(&pixmap); + icon.setCompositionMode(QPainter::CompositionMode_SourceIn); + icon.fillRect(pixmap.rect(), painter->pen().color()); + painter->drawPixmap(iconRect, pixmap); + } + + if (!m_active) + { + if (!icon().isNull()) { + painter->translate(0, -12); + } + QBrush overlay; + overlay.setStyle(Qt::SolidPattern); + overlay.setColor(backgroundColor()); + painter->setOpacity(0.36); + painter->fillRect(rect(), overlay); + } +} diff --git a/xx/qtmaterialtabs_internal.h b/xx/qtmaterialtabs_internal.h new file mode 100644 index 0000000..2e78d19 --- /dev/null +++ b/xx/qtmaterialtabs_internal.h @@ -0,0 +1,88 @@ +#ifndef QTMATERIALTABS_INTERNAL_H +#define QTMATERIALTABS_INTERNAL_H + +#include "xxlib/qtmaterialoverlaywidget.h" +#include "xx/qtmaterialflatbutton.h" + +class QPropertyAnimation; +class QtMaterialTabs; + +class QtMaterialTabsInkBar : public QtMaterialOverlayWidget +{ + Q_OBJECT + + Q_PROPERTY(qreal tweenValue WRITE setTweenValue READ tweenValue) + +public: + QtMaterialTabsInkBar(QtMaterialTabs *parent); + ~QtMaterialTabsInkBar(); + + inline void setTweenValue(qreal value); + inline qreal tweenValue() const; + + void refreshGeometry(); + void animate(); + +protected: + bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE; + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QtMaterialTabsInkBar) + + QtMaterialTabs *const m_tabs; + QPropertyAnimation *const m_animation; + QRect m_geometry; + QRect m_previousGeometry; + qreal m_tween; +}; + +inline void QtMaterialTabsInkBar::setTweenValue(qreal value) +{ + m_tween = value; + refreshGeometry(); +} + +inline qreal QtMaterialTabsInkBar::tweenValue() const +{ + return m_tween; +} + +class QtMaterialTab : public QtMaterialFlatButton +{ + Q_OBJECT + +public: + explicit QtMaterialTab(QtMaterialTabs *parent); + ~QtMaterialTab(); + + inline void setActive(bool state); + inline bool isActive() const; + + QSize sizeHint() const Q_DECL_OVERRIDE; + +protected slots: + void activateTab(); + +protected: + void paintForeground(QPainter *painter) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QtMaterialTab) + + QtMaterialTabs *const m_tabs; + bool m_active; +}; + +inline void QtMaterialTab::setActive(bool state) +{ + m_active = state; + update(); +} + +inline bool QtMaterialTab::isActive() const +{ + return m_active; +} + +#endif // QTMATERIALTABS_INTERNAL_H diff --git a/xx/qtmaterialtabs_p.h b/xx/qtmaterialtabs_p.h new file mode 100644 index 0000000..3f1342d --- /dev/null +++ b/xx/qtmaterialtabs_p.h @@ -0,0 +1,34 @@ +#ifndef QTMATERIALTABS_P_H +#define QTMATERIALTABS_P_H + +#include +#include "xxlib/qtmaterialtheme.h" + +class QHBoxLayout; +class QtMaterialTabs; +class QtMaterialTabsInkBar; + +class QtMaterialTabsPrivate +{ + Q_DISABLE_COPY(QtMaterialTabsPrivate) + Q_DECLARE_PUBLIC(QtMaterialTabs) + +public: + QtMaterialTabsPrivate(QtMaterialTabs *q); + ~QtMaterialTabsPrivate(); + + void init(); + + QtMaterialTabs *const q_ptr; + QtMaterialTabsInkBar *inkBar; + QHBoxLayout *tabLayout; + XXMaterial::RippleStyle rippleStyle; + QColor inkColor; + QColor backgroundColor; + QColor textColor; + int tab; + bool showHalo; + bool useThemeColors; +}; + +#endif // QTMATERIALTABS_P_H diff --git a/xx/qtmaterialtextfield.cpp b/xx/qtmaterialtextfield.cpp new file mode 100644 index 0000000..4e517c8 --- /dev/null +++ b/xx/qtmaterialtextfield.cpp @@ -0,0 +1,289 @@ +#include "xx/qtmaterialtextfield.h" +#include "xx/qtmaterialtextfield_p.h" +#include +#include +#include +#include "xx/qtmaterialtextfield_internal.h" +#include "xxlib/qtmaterialstyle.h" +#include + +/*! + * \class QtMaterialTextFieldPrivate + * \internal + */ + +QtMaterialTextFieldPrivate::QtMaterialTextFieldPrivate(QtMaterialTextField *q) + : q_ptr(q) +{ +} + +QtMaterialTextFieldPrivate::~QtMaterialTextFieldPrivate() +{ +} + +void QtMaterialTextFieldPrivate::init() +{ + Q_Q(QtMaterialTextField); + + stateMachine = new QtMaterialTextFieldStateMachine(q); + label = 0; + labelFontSize = 9.5; + showLabel = false; + useThemeColors = true; + + q->setFrame(false); + q->setStyle(&QtMaterialStyle::instance()); + q->setAttribute(Qt::WA_Hover); + q->setMouseTracking(true); + q->setTextMargins(0, 2, 0, 4); + + QFontDatabase db; + QFont font(db.font("Roboto", "Regular", 11)); + q->setFont(font); + + stateMachine->start(); + QCoreApplication::processEvents(); +} + +/*! + * \class QtMaterialTextField + */ + +QtMaterialTextField::QtMaterialTextField(QWidget *parent) + : QLineEdit(parent), + d_ptr(new QtMaterialTextFieldPrivate(this)) +{ + d_func()->init(); +} + +QtMaterialTextField::~QtMaterialTextField() +{ +} + +void QtMaterialTextField::setUseThemeColors(bool value) +{ + Q_D(QtMaterialTextField); + + if (d->useThemeColors == value) { + return; + } + + d->useThemeColors = value; + d->stateMachine->setupProperties(); +} + +bool QtMaterialTextField::useThemeColors() const +{ + Q_D(const QtMaterialTextField); + + return d->useThemeColors; +} + +void QtMaterialTextField::setShowLabel(bool value) +{ + Q_D(QtMaterialTextField); + + if (d->showLabel == value) { + return; + } + + d->showLabel = value; + + if (!d->label && value) { + d->label = new QtMaterialTextFieldLabel(this); + d->stateMachine->setLabel(d->label); + } + + if (value) { + setContentsMargins(0, 23, 0, 0); + } else { + setContentsMargins(0, 0, 0, 0); + } +} + +bool QtMaterialTextField::hasLabel() const +{ + Q_D(const QtMaterialTextField); + + return d->showLabel; +} + +void QtMaterialTextField::setLabelFontSize(qreal size) +{ + Q_D(QtMaterialTextField); + + d->labelFontSize = size; + + if (d->label) + { + QFont font(d->label->font()); + font.setPointSizeF(size); + d->label->setFont(font); + d->label->update(); + } +} + +qreal QtMaterialTextField::labelFontSize() const +{ + Q_D(const QtMaterialTextField); + + return d->labelFontSize; +} + +void QtMaterialTextField::setLabel(const QString &label) +{ + Q_D(QtMaterialTextField); + + d->labelString = label; + setShowLabel(true); + d->label->update(); +} + +QString QtMaterialTextField::label() const +{ + Q_D(const QtMaterialTextField); + + return d->labelString; +} + +void QtMaterialTextField::setTextColor(const QColor &color) +{ + Q_D(QtMaterialTextField); + + d->textColor = color; + setStyleSheet(QString("QLineEdit { color: %1; }").arg(color.name())); + + setUseThemeColors(false); +} + +QColor QtMaterialTextField::textColor() const +{ + Q_D(const QtMaterialTextField); + + if (d->useThemeColors || !d->textColor.isValid()) { + return QtMaterialStyle::instance().themeColor("text"); + } else { + return d->textColor; + } +} + +void QtMaterialTextField::setLabelColor(const QColor &color) +{ + Q_D(QtMaterialTextField); + + d->labelColor = color; + setUseThemeColors(false); +} + +QColor QtMaterialTextField::labelColor() const +{ + Q_D(const QtMaterialTextField); + + if (d->useThemeColors || !d->labelColor.isValid()) { + return QtMaterialStyle::instance().themeColor("accent3"); + } else { + return d->labelColor; + } +} + +void QtMaterialTextField::setInkColor(const QColor &color) +{ + Q_D(QtMaterialTextField); + + d->inkColor = color; + setUseThemeColors(false); +} + +QColor QtMaterialTextField::inkColor() const +{ + Q_D(const QtMaterialTextField); + + if (d->useThemeColors || !d->inkColor.isValid()) { + return QtMaterialStyle::instance().themeColor("primary1"); + } else { + return d->inkColor; + } +} + +void QtMaterialTextField::setUnderlineColor(const QColor &color) +{ + Q_D(QtMaterialTextField); + + d->underlineColor = color; + setUseThemeColors(false); +} + +QColor QtMaterialTextField::underlineColor() const +{ + Q_D(const QtMaterialTextField); + + if (d->useThemeColors || !d->underlineColor.isValid()) { + return QtMaterialStyle::instance().themeColor("border"); + } else { + return d->underlineColor; + } +} + +/*! + * \reimp + */ +bool QtMaterialTextField::event(QEvent *event) +{ + Q_D(QtMaterialTextField); + + switch (event->type()) + { + case QEvent::Resize: + case QEvent::Move: { + if (d->label) { + d->label->setGeometry(rect()); + } + } + default: + break; + } + return QLineEdit::event(event); +} + +/*! + * \reimp + */ +void QtMaterialTextField::paintEvent(QPaintEvent *event) +{ + Q_D(QtMaterialTextField); + + QLineEdit::paintEvent(event); + + QPainter painter(this); + + if (text().isEmpty()) + { + painter.setOpacity(1-d->stateMachine->progress()); + //painter.fillRect(rect(), parentWidget()->palette().color(backgroundRole())); + painter.fillRect(rect(), Qt::white); + } + + const int y = height()-1; + const int wd = width()-5; + + QPen pen; + pen.setWidth(1); + pen.setColor(underlineColor()); + painter.setPen(pen); + painter.setOpacity(1); + painter.drawLine(2.5, y, wd, y); + + QBrush brush; + brush.setStyle(Qt::SolidPattern); + brush.setColor(inkColor()); + + const qreal progress = d->stateMachine->progress(); + + if (progress > 0) + { + painter.setPen(Qt::NoPen); + painter.setBrush(brush); + const int w = (1-progress)*static_cast(wd/2); + painter.drawRect(w+2.5, height()-2, wd-w*2, 2); + } +} diff --git a/xx/qtmaterialtextfield.h b/xx/qtmaterialtextfield.h new file mode 100644 index 0000000..de129d4 --- /dev/null +++ b/xx/qtmaterialtextfield.h @@ -0,0 +1,56 @@ +#ifndef QTMATERIALTEXTFIELD_H +#define QTMATERIALTEXTFIELD_H + +#include +#include + +class QtMaterialTextFieldPrivate; + +class QtMaterialTextField : public QLineEdit +{ + Q_OBJECT + + Q_PROPERTY(QColor textColor WRITE setTextColor READ textColor) + Q_PROPERTY(QColor inkColor WRITE setInkColor READ inkColor) + Q_PROPERTY(QColor underlineColor WRITE setUnderlineColor READ underlineColor) + +public: + explicit QtMaterialTextField(QWidget *parent = 0); + ~QtMaterialTextField(); + + void setUseThemeColors(bool value); + bool useThemeColors() const; + + void setShowLabel(bool value); + bool hasLabel() const; + + void setLabelFontSize(qreal size); + qreal labelFontSize() const; + + void setLabel(const QString &label); + QString label() const; + + void setTextColor(const QColor &color); + QColor textColor() const; + + void setLabelColor(const QColor &color); + QColor labelColor() const; + + void setInkColor(const QColor &color); + QColor inkColor() const; + + void setUnderlineColor(const QColor &color); + QColor underlineColor() const; + +protected: + bool event(QEvent *event) Q_DECL_OVERRIDE; + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + + const QScopedPointer d_ptr; + +private: + Q_DISABLE_COPY(QtMaterialTextField) + Q_DECLARE_PRIVATE(QtMaterialTextField) +}; + +#endif // QTMATERIALTEXTFIELD_H diff --git a/xx/qtmaterialtextfield_internal.cpp b/xx/qtmaterialtextfield_internal.cpp new file mode 100644 index 0000000..1068e17 --- /dev/null +++ b/xx/qtmaterialtextfield_internal.cpp @@ -0,0 +1,166 @@ +#include "xx/qtmaterialtextfield_internal.h" +#include +#include +#include +#include +#include "xx/qtmaterialtextfield.h" + +/*! + * \class QtMaterialTextFieldStateMachine + * \internal + */ + +QtMaterialTextFieldStateMachine::QtMaterialTextFieldStateMachine(QtMaterialTextField *parent) + : QStateMachine(parent), + m_textField(parent), + m_normalState(new QState), + m_focusedState(new QState), + m_label(0), + m_offsetAnimation(0), + m_colorAnimation(0), + m_progress(0.0) +{ + Q_ASSERT(parent); + + addState(m_normalState); + addState(m_focusedState); + + setInitialState(m_normalState); + + QEventTransition *transition; + QPropertyAnimation *animation; + + transition = new QEventTransition(parent, QEvent::FocusIn); + transition->setTargetState(m_focusedState); + m_normalState->addTransition(transition); + + animation = new QPropertyAnimation(this, "progress", this); + animation->setEasingCurve(QEasingCurve::InCubic); + animation->setDuration(310); + transition->addAnimation(animation); + + transition = new QEventTransition(parent, QEvent::FocusOut); + transition->setTargetState(m_normalState); + m_focusedState->addTransition(transition); + + animation = new QPropertyAnimation(this, "progress", this); + animation->setEasingCurve(QEasingCurve::OutCubic); + animation->setDuration(310); + transition->addAnimation(animation); + + m_normalState->assignProperty(this, "progress", 0); + m_focusedState->assignProperty(this, "progress", 1); + + setupProperties(); + + connect(m_textField, SIGNAL(textChanged(QString)), this, SLOT(setupProperties())); +} + +QtMaterialTextFieldStateMachine::~QtMaterialTextFieldStateMachine() +{ +} + +void QtMaterialTextFieldStateMachine::setLabel(QtMaterialTextFieldLabel *label) +{ + if (m_label) { + delete m_label; + } + + if (m_offsetAnimation) { + removeDefaultAnimation(m_offsetAnimation); + delete m_offsetAnimation; + } + + if (m_colorAnimation) { + removeDefaultAnimation(m_colorAnimation); + delete m_colorAnimation; + } + + m_label = label; + + if (m_label) + { + m_offsetAnimation = new QPropertyAnimation(m_label, "offset", this); + m_offsetAnimation->setDuration(210); + m_offsetAnimation->setEasingCurve(QEasingCurve::OutCubic); + addDefaultAnimation(m_offsetAnimation); + + m_colorAnimation = new QPropertyAnimation(m_label, "color", this); + m_colorAnimation->setDuration(210); + addDefaultAnimation(m_colorAnimation); + } + + setupProperties(); +} + +void QtMaterialTextFieldStateMachine::setupProperties() +{ + if (m_label) + { + const int m = m_textField->textMargins().top(); + + if (m_textField->text().isEmpty()) { + m_normalState->assignProperty(m_label, "offset", QPointF(0, 26)); + } else { + m_normalState->assignProperty(m_label, "offset", QPointF(0, 0-m)); + } + + m_focusedState->assignProperty(m_label, "offset", QPointF(0, 0-m)); + m_focusedState->assignProperty(m_label, "color", m_textField->inkColor()); + m_normalState->assignProperty(m_label, "color", m_textField->labelColor()); + + if (0 != m_label->offset().y() && !m_textField->text().isEmpty()) { + m_label->setOffset(QPointF(0, 0-m)); + } else if (!m_textField->hasFocus() && m_label->offset().y() <= 0 && m_textField->text().isEmpty()) { + m_label->setOffset(QPointF(0, 26)); + } + } + + m_textField->update(); +} + +/*! + * \class QtMaterialTextFieldLabel + * \internal + */ + +QtMaterialTextFieldLabel::QtMaterialTextFieldLabel(QtMaterialTextField *parent) + : QWidget(parent), + m_textField(parent), + m_scale(1), + m_posX(0), + m_posY(26), + m_color(parent->labelColor()) +{ + Q_ASSERT(parent); + + QFontDatabase db; + QFont font(db.font("Roboto", "Medium", parent->labelFontSize())); + font.setLetterSpacing(QFont::PercentageSpacing, 102); + setFont(font); +} + +QtMaterialTextFieldLabel::~QtMaterialTextFieldLabel() +{ +} + +/*! + * \reimp + */ +void QtMaterialTextFieldLabel::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + + if (!m_textField->hasLabel()) { + return; + } + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + painter.scale(m_scale, m_scale); + painter.setPen(m_color); + painter.setOpacity(1); + + QPointF pos(2+m_posX, height()-36+m_posY); + painter.drawText(pos.x(), pos.y(), m_textField->label()); +} diff --git a/xx/qtmaterialtextfield_internal.h b/xx/qtmaterialtextfield_internal.h new file mode 100644 index 0000000..afc1e0d --- /dev/null +++ b/xx/qtmaterialtextfield_internal.h @@ -0,0 +1,120 @@ +#ifndef QTMATERIALTEXTFIELD_INTERNAL_H +#define QTMATERIALTEXTFIELD_INTERNAL_H + +#include +#include +#include "xx/qtmaterialtextfield.h" + +class QPropertyAnimation; +class QtMaterialTextFieldLabel; + +class QtMaterialTextFieldStateMachine : public QStateMachine +{ + Q_OBJECT + + Q_PROPERTY(qreal progress WRITE setProgress READ progress) + +public: + QtMaterialTextFieldStateMachine(QtMaterialTextField *parent); + ~QtMaterialTextFieldStateMachine(); + + void setLabel(QtMaterialTextFieldLabel *label); + + inline void setProgress(qreal progress); + inline qreal progress() const; + +public slots: + void setupProperties(); + +private: + Q_DISABLE_COPY(QtMaterialTextFieldStateMachine) + + QtMaterialTextField *const m_textField; + QState *const m_normalState; + QState *const m_focusedState; + QtMaterialTextFieldLabel *m_label; + QPropertyAnimation *m_offsetAnimation; + QPropertyAnimation *m_colorAnimation; + qreal m_progress; +}; + +inline void QtMaterialTextFieldStateMachine::setProgress(qreal progress) +{ + m_progress = progress; + m_textField->update(); +} + +inline qreal QtMaterialTextFieldStateMachine::progress() const +{ + return m_progress; +} + +class QtMaterialTextFieldLabel : public QWidget +{ + Q_OBJECT + + Q_PROPERTY(qreal scale WRITE setScale READ scale) + Q_PROPERTY(QPointF offset WRITE setOffset READ offset) + Q_PROPERTY(QColor color WRITE setColor READ color) + +public: + QtMaterialTextFieldLabel(QtMaterialTextField *parent); + ~QtMaterialTextFieldLabel(); + + inline void setScale(qreal scale); + inline qreal scale() const; + + inline void setOffset(const QPointF &pos); + inline QPointF offset() const; + + inline void setColor(const QColor &color); + inline QColor color() const; + +protected: + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QtMaterialTextFieldLabel) + + QtMaterialTextField *const m_textField; + qreal m_scale; + qreal m_posX; + qreal m_posY; + QColor m_color; +}; + +inline void QtMaterialTextFieldLabel::setScale(qreal scale) +{ + m_scale = scale; + update(); +} + +inline qreal QtMaterialTextFieldLabel::scale() const +{ + return m_scale; +} + +inline void QtMaterialTextFieldLabel::setOffset(const QPointF &pos) +{ + m_posX = pos.x(); + m_posY = pos.y(); + update(); +} + +inline QPointF QtMaterialTextFieldLabel::offset() const +{ + return QPointF(m_posX, m_posY); +} + +inline void QtMaterialTextFieldLabel::setColor(const QColor &color) +{ + m_color = color; + update(); +} + +inline QColor QtMaterialTextFieldLabel::color() const +{ + return m_color; +} + +#endif // QTMATERIALTEXTFIELD_INTERNAL_H diff --git a/xx/qtmaterialtextfield_p.h b/xx/qtmaterialtextfield_p.h new file mode 100644 index 0000000..ad4db28 --- /dev/null +++ b/xx/qtmaterialtextfield_p.h @@ -0,0 +1,35 @@ +#ifndef QTMATERIALTEXTFIELD_P_H +#define QTMATERIALTEXTFIELD_P_H + +#include +#include + +class QtMaterialTextField; +class QtMaterialTextFieldStateMachine; +class QtMaterialTextFieldLabel; + +class QtMaterialTextFieldPrivate +{ + Q_DISABLE_COPY(QtMaterialTextFieldPrivate) + Q_DECLARE_PUBLIC(QtMaterialTextField) + +public: + QtMaterialTextFieldPrivate(QtMaterialTextField *q); + ~QtMaterialTextFieldPrivate(); + + void init(); + + QtMaterialTextField *const q_ptr; + QtMaterialTextFieldStateMachine *stateMachine; + QtMaterialTextFieldLabel *label; + QColor textColor; + QColor labelColor; + QColor inkColor; + QColor underlineColor; + QString labelString; + qreal labelFontSize; + bool showLabel; + bool useThemeColors; +}; + +#endif // QTMATERIALTEXTFIELD_P_H diff --git a/xxlib/qtmaterialcheckable.cpp b/xxlib/qtmaterialcheckable.cpp index eb4c0d2..fff548c 100644 --- a/xxlib/qtmaterialcheckable.cpp +++ b/xxlib/qtmaterialcheckable.cpp @@ -51,7 +51,7 @@ void QtMaterialCheckablePrivate::init() q->setStyle(&QtMaterialStyle::instance()); QFontDatabase db; - QFont font(db.font("Roboto", "Medium", 11)); + QFont font(db.font("Roboto", "Regular", 11)); q->setFont(font); stateMachine->addState(uncheckedState); @@ -107,6 +107,9 @@ void QtMaterialCheckablePrivate::init() uncheckedState->assignProperty(uncheckedIcon, "opacity", 1); disabledCheckedState->assignProperty(checkedIcon, "opacity", 1); + disabledCheckedState->assignProperty(uncheckedIcon, "opacity", 0); + + disabledUncheckedState->assignProperty(checkedIcon, "opacity", 0); disabledUncheckedState->assignProperty(uncheckedIcon, "opacity", 1); checkedState->assignProperty(checkedIcon, "color", q->checkedColor()); @@ -156,6 +159,10 @@ void QtMaterialCheckable::setUseThemeColors(bool value) { Q_D(QtMaterialCheckable); + if (d->useThemeColors == value) { + return; + } + d->useThemeColors = value; setupProperties(); } @@ -358,7 +365,7 @@ void QtMaterialCheckable::mousePressEvent(QMouseEvent *event) } d->rippleOverlay->addRipple(ripple); - QAbstractButton::mousePressEvent(event); + setChecked(!isChecked()); } /*! @@ -372,6 +379,10 @@ void QtMaterialCheckable::paintEvent(QPaintEvent *event) QPainter painter(this); + QPen pen; + pen.setColor(isEnabled() ? textColor() : disabledColor()); + painter.setPen(pen); + if (QtMaterialCheckable::LabelPositionLeft == d->labelPosition) { painter.drawText(4, 25, text()); } else { diff --git a/yy/checkboxsettingseditor.h b/yy/checkboxsettingseditor.h index 8f40f88..4456367 100644 --- a/yy/checkboxsettingseditor.h +++ b/yy/checkboxsettingseditor.h @@ -21,7 +21,7 @@ protected slots: private: Ui::CheckBoxSettingsForm *const ui; - QtMaterialCheckable *const m_checkBox; + QtMaterialCheckable *const m_checkBox; }; #endif // CHECKBOXSETTINGSEDITOR_H diff --git a/yy/circularprogresssettingseditor.cpp b/yy/circularprogresssettingseditor.cpp new file mode 100644 index 0000000..07a4bd7 --- /dev/null +++ b/yy/circularprogresssettingseditor.cpp @@ -0,0 +1,102 @@ +#include "circularprogresssettingseditor.h" +#include +#include +#include "xx/qtmaterialcircularprogress.h" + +CircularProgressSettingsEditor::CircularProgressSettingsEditor(QWidget *parent) + : QWidget(parent), + ui(new Ui::CircularProgressSettingsForm), + m_progress(new QtMaterialCircularProgress) +{ + 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); + layout->addWidget(m_progress); + layout->setAlignment(m_progress, Qt::AlignCenter); + + setupForm(); + + connect(ui->disabledCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget())); + connect(ui->progressTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateWidget())); + connect(ui->progressSlider, SIGNAL(valueChanged(int)), this, SLOT(updateWidget())); + connect(ui->lineWidthDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(updateWidget())); + connect(ui->sizeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(updateWidget())); + connect(ui->useThemeColorsCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget())); + connect(ui->colorToolButton, SIGNAL(pressed()), this, SLOT(selectColor())); + + ui->sizeSpinBox->setRange(10, 200); + ui->progressSlider->setRange(0, 100); +} + +CircularProgressSettingsEditor::~CircularProgressSettingsEditor() +{ + delete ui; +} + +void CircularProgressSettingsEditor::setupForm() +{ + switch (m_progress->progressType()) + { + case XXMaterial::DeterminateProgress: + ui->progressTypeComboBox->setCurrentIndex(0); + break; + case XXMaterial::IndeterminateProgress: + ui->progressTypeComboBox->setCurrentIndex(1); + break; + default: + break; + } + + ui->disabledCheckBox->setChecked(!m_progress->isEnabled()); + ui->progressSlider->setValue(m_progress->value()); + ui->lineWidthDoubleSpinBox->setValue(m_progress->lineWidth()); + ui->sizeSpinBox->setValue(m_progress->size()); + ui->useThemeColorsCheckBox->setChecked(m_progress->useThemeColors()); +} + +void CircularProgressSettingsEditor::updateWidget() +{ + switch (ui->progressTypeComboBox->currentIndex()) + { + case 0: + m_progress->setProgressType(XXMaterial::DeterminateProgress); + break; + case 1: + m_progress->setProgressType(XXMaterial::IndeterminateProgress); + break; + default: + break; + } + + m_progress->setDisabled(ui->disabledCheckBox->isChecked()); + m_progress->setValue(ui->progressSlider->value()); + m_progress->setLineWidth(ui->lineWidthDoubleSpinBox->value()); + m_progress->setSize(ui->sizeSpinBox->value()); + m_progress->setUseThemeColors(ui->useThemeColorsCheckBox->isChecked()); +} + +void CircularProgressSettingsEditor::selectColor() +{ + QColorDialog dialog; + if (dialog.exec()) { + QColor color = dialog.selectedColor(); + QString senderName = sender()->objectName(); + if ("colorToolButton" == senderName) { + m_progress->setColor(color); + ui->colorLineEdit->setText(color.name(QColor::HexRgb)); + } + } + setupForm(); +} diff --git a/yy/circularprogresssettingseditor.h b/yy/circularprogresssettingseditor.h new file mode 100644 index 0000000..5077989 --- /dev/null +++ b/yy/circularprogresssettingseditor.h @@ -0,0 +1,27 @@ +#ifndef CIRCULARPROGRESSSETTINGSEDITOR_H +#define CIRCULARPROGRESSSETTINGSEDITOR_H + +#include +#include "ui_circularprogresssettingsform.h" + +class QtMaterialCircularProgress; + +class CircularProgressSettingsEditor : public QWidget +{ + Q_OBJECT + +public: + explicit CircularProgressSettingsEditor(QWidget *parent = 0); + ~CircularProgressSettingsEditor(); + +protected slots: + void setupForm(); + void updateWidget(); + void selectColor(); + +private: + Ui::CircularProgressSettingsForm *const ui; + QtMaterialCircularProgress *const m_progress; +}; + +#endif // CIRCULARPROGRESSSETTINGSEDITOR_H diff --git a/yy/circularprogresssettingsform.ui b/yy/circularprogresssettingsform.ui new file mode 100644 index 0000000..e4fe7c5 --- /dev/null +++ b/yy/circularprogresssettingsform.ui @@ -0,0 +1,127 @@ + + + CircularProgressSettingsForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 0 + 0 + 221 + 197 + + + + + + + Disabled + + + + + + + + + + Progress type + + + + + + + + Determinate + + + + + Indeterminate + + + + + + + + Line width + + + + + + + + + + Size + + + + + + + + + + Use theme colors + + + + + + + + + + Color + + + + + + + + + + + + ... + + + + + + + + + Progress + + + + + + + Qt::Horizontal + + + + + + + + + diff --git a/yy/progresssettingseditor.cpp b/yy/progresssettingseditor.cpp new file mode 100644 index 0000000..8772551 --- /dev/null +++ b/yy/progresssettingseditor.cpp @@ -0,0 +1,99 @@ +#include "yy/progresssettingseditor.h" +#include +#include "xx/qtmaterialprogress.h" +#include "xxlib/qtmaterialtheme.h" + +ProgressSettingsEditor::ProgressSettingsEditor(QWidget *parent) + : QWidget(parent), + ui(new Ui::ProgressSettingsForm), + m_progress(new QtMaterialProgress) +{ + 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); + layout->addWidget(m_progress); + layout->setAlignment(m_progress, Qt::AlignCenter); + + setupForm(); + + connect(ui->disabledCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget())); + connect(ui->progressTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateWidget())); + connect(ui->progressSlider, SIGNAL(valueChanged(int)), this, SLOT(updateWidget())); + connect(ui->useThemeColorsCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget())); + connect(ui->progressColorToolButton, SIGNAL(pressed()), this, SLOT(selectColor())); + connect(ui->backgroundColorToolButton, SIGNAL(pressed()), this, SLOT(selectColor())); + + ui->progressSlider->setRange(0, 100); +} + +ProgressSettingsEditor::~ProgressSettingsEditor() +{ + delete ui; +} + +void ProgressSettingsEditor::setupForm() +{ + switch (m_progress->progressType()) + { + case XXMaterial::DeterminateProgress: + ui->progressTypeComboBox->setCurrentIndex(0); + break; + case XXMaterial::IndeterminateProgress: + ui->progressTypeComboBox->setCurrentIndex(1); + break; + default: + break; + } + + ui->disabledCheckBox->setChecked(!m_progress->isEnabled()); + ui->progressSlider->setValue(m_progress->value()); + ui->useThemeColorsCheckBox->setChecked(m_progress->useThemeColors()); +} + +void ProgressSettingsEditor::updateWidget() +{ + switch (ui->progressTypeComboBox->currentIndex()) + { + case 0: + m_progress->setProgressType(XXMaterial::DeterminateProgress); + break; + case 1: + m_progress->setProgressType(XXMaterial::IndeterminateProgress); + break; + default: + break; + } + + m_progress->setDisabled(ui->disabledCheckBox->isChecked()); + m_progress->setValue(ui->progressSlider->value()); + m_progress->setUseThemeColors(ui->useThemeColorsCheckBox->isChecked()); +} + +void ProgressSettingsEditor::selectColor() +{ + QColorDialog dialog; + if (dialog.exec()) { + QColor color = dialog.selectedColor(); + QString senderName = sender()->objectName(); + if ("progressColorToolButton" == senderName) { + m_progress->setProgressColor(color); + ui->progressColorLineEdit->setText(color.name(QColor::HexRgb)); + } else if ("backgroundColorToolButton" == senderName) { + m_progress->setBackgroundColor(color); + ui->backgroundColorLineEdit->setText(color.name(QColor::HexRgb)); + } + } + setupForm(); +} diff --git a/yy/progresssettingseditor.h b/yy/progresssettingseditor.h new file mode 100644 index 0000000..bc5bbaa --- /dev/null +++ b/yy/progresssettingseditor.h @@ -0,0 +1,27 @@ +#ifndef PROGRESSSETTINGSEDITOR_H +#define PROGRESSSETTINGSEDITOR_H + +#include +#include "ui_progresssettingsform.h" + +class QtMaterialProgress; + +class ProgressSettingsEditor : public QWidget +{ + Q_OBJECT + +public: + explicit ProgressSettingsEditor(QWidget *parent = 0); + ~ProgressSettingsEditor(); + +protected slots: + void setupForm(); + void updateWidget(); + void selectColor(); + +private: + Ui::ProgressSettingsForm *const ui; + QtMaterialProgress *const m_progress; +}; + +#endif // PROGRESSSETTINGSEDITOR_H diff --git a/yy/progresssettingsform.ui b/yy/progresssettingsform.ui new file mode 100644 index 0000000..b7e004b --- /dev/null +++ b/yy/progresssettingsform.ui @@ -0,0 +1,128 @@ + + + ProgressSettingsForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 0 + 0 + 240 + 197 + + + + + + + Disabled + + + + + + + + + + Progress type + + + + + + + + Determinate + + + + + Indeterminate + + + + + + + + Progress + + + + + + + Qt::Horizontal + + + + + + + Use theme colors + + + + + + + + + + Progress color + + + + + + + + + + + + ... + + + + + + + + + Background color + + + + + + + + + + + + ... + + + + + + + + + + + diff --git a/yy/radiobuttonsettingseditor.cpp b/yy/radiobuttonsettingseditor.cpp new file mode 100644 index 0000000..88bf2e6 --- /dev/null +++ b/yy/radiobuttonsettingseditor.cpp @@ -0,0 +1,135 @@ +#include "radiobuttonsettingseditor.h" +#include +#include +#include +#include "xx/qtmaterialradiobutton.h" + +RadioButtonSettingsEditor::RadioButtonSettingsEditor(QWidget *parent) + : QWidget(parent), + ui(new Ui::RadioButtonSettingsForm), + m_radioButton1(new QtMaterialRadioButton), + m_radioButton2(new QtMaterialRadioButton), + m_radioButton3(new QtMaterialRadioButton) +{ + 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); + + m_radioButton1->setText("Palak paneer"); + m_radioButton2->setText("Kadai veg"); + m_radioButton3->setText("asdfadsf"); + + layout = new QVBoxLayout; + canvas->setLayout(layout); + canvas->setMaximumHeight(350); + + layout->addStretch(); + layout->addWidget(m_radioButton1); + layout->addWidget(m_radioButton2); + layout->addWidget(m_radioButton3); + layout->addStretch(); + + layout->setMargin(0); + layout->setSpacing(0); + + setupForm(); + + connect(ui->disabledCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget())); + connect(ui->labelPositionComboBox_2, SIGNAL(currentIndexChanged(int)), this, SLOT(updateWidget())); + connect(ui->labelTextLineEdit_2, SIGNAL(textChanged(QString)), this, SLOT(updateWidget())); + connect(ui->useThemeColorsCheckBox_3, SIGNAL(toggled(bool)), this, SLOT(updateWidget())); + connect(ui->textColorToolButton_2, SIGNAL(pressed()), this, SLOT(selectColor())); + connect(ui->disabledColorToolButton_2, SIGNAL(pressed()), this, SLOT(selectColor())); + connect(ui->checkedColorToolButton_2, SIGNAL(pressed()), this, SLOT(selectColor())); + connect(ui->uncheckedColorToolButton_2, SIGNAL(pressed()), this, SLOT(selectColor())); + connect(ui->labelPositionComboBox_2, SIGNAL(currentIndexChanged(int)), this, SLOT(updateWidget())); +} + +RadioButtonSettingsEditor::~RadioButtonSettingsEditor() +{ + delete ui; +} + +void RadioButtonSettingsEditor::setupForm() +{ + switch (m_radioButton1->labelPosition()) + { + case QtMaterialCheckable::LabelPositionLeft: + ui->labelPositionComboBox_2->setCurrentIndex(0); + break; + case QtMaterialCheckable::LabelPositionRight: + ui->labelPositionComboBox_2->setCurrentIndex(1); + break; + default: + break; + } + + ui->disabledCheckBox->setChecked(!m_radioButton1->isEnabled()); + ui->labelTextLineEdit_2->setText(m_radioButton1->text()); + ui->useThemeColorsCheckBox_3->setChecked(m_radioButton1->useThemeColors()); +} + +void RadioButtonSettingsEditor::updateWidget() +{ + switch (ui->labelPositionComboBox_2->currentIndex()) + { + case 0: + m_radioButton1->setLabelPosition(QtMaterialCheckable::LabelPositionLeft); + m_radioButton2->setLabelPosition(QtMaterialCheckable::LabelPositionLeft); + m_radioButton3->setLabelPosition(QtMaterialCheckable::LabelPositionLeft); + break; + case 1: + m_radioButton1->setLabelPosition(QtMaterialCheckable::LabelPositionRight); + m_radioButton2->setLabelPosition(QtMaterialCheckable::LabelPositionRight); + m_radioButton3->setLabelPosition(QtMaterialCheckable::LabelPositionRight); + break; + default: + break; + } + + m_radioButton1->setDisabled(ui->disabledCheckBox->isChecked()); + m_radioButton1->setText(ui->labelTextLineEdit_2->text()); + m_radioButton1->setUseThemeColors(ui->useThemeColorsCheckBox_3->isChecked()); + m_radioButton2->setUseThemeColors(ui->useThemeColorsCheckBox_3->isChecked()); + m_radioButton3->setUseThemeColors(ui->useThemeColorsCheckBox_3->isChecked()); +} + +void RadioButtonSettingsEditor::selectColor() +{ + QColorDialog dialog; + if (dialog.exec()) { + QColor color = dialog.selectedColor(); + QString senderName = sender()->objectName(); + if ("textColorToolButton_2" == senderName) { + m_radioButton1->setTextColor(color); + m_radioButton2->setTextColor(color); + m_radioButton3->setTextColor(color); + ui->textColorLineEdit_2->setText(color.name(QColor::HexRgb)); + } else if ("disabledColorToolButton_2" == senderName) { + m_radioButton1->setDisabledColor(color); + m_radioButton2->setDisabledColor(color); + m_radioButton3->setDisabledColor(color); + ui->disabledColorLineEdit_2->setText(color.name(QColor::HexRgb)); + } else if ("checkedColorToolButton_2" == senderName) { + m_radioButton1->setCheckedColor(color); + m_radioButton2->setCheckedColor(color); + m_radioButton3->setCheckedColor(color); + ui->checkedColorLineEdit_2->setText(color.name(QColor::HexRgb)); + } else if ("uncheckedColorToolButton_2" == senderName) { + m_radioButton1->setUncheckedColor(color); + m_radioButton2->setUncheckedColor(color); + m_radioButton3->setUncheckedColor(color); + ui->uncheckedColorLineEdit_2->setText(color.name(QColor::HexRgb)); + } + } + setupForm(); +} diff --git a/yy/radiobuttonsettingseditor.h b/yy/radiobuttonsettingseditor.h new file mode 100644 index 0000000..76ad852 --- /dev/null +++ b/yy/radiobuttonsettingseditor.h @@ -0,0 +1,30 @@ +#ifndef RADIOBUTTONSETTINGSEDITOR_H +#define RADIOBUTTONSETTINGSEDITOR_H + +#include +#include "ui_radiobuttonsettingsform.h" + +class QtMaterialRadioButton; +class RadioButton; + +class RadioButtonSettingsEditor : public QWidget +{ + Q_OBJECT + +public: + explicit RadioButtonSettingsEditor(QWidget *parent = 0); + ~RadioButtonSettingsEditor(); + +protected slots: + void setupForm(); + void updateWidget(); + void selectColor(); + +private: + Ui::RadioButtonSettingsForm *const ui; + QtMaterialRadioButton *const m_radioButton1; + QtMaterialRadioButton *const m_radioButton2; + QtMaterialRadioButton *const m_radioButton3; +}; + +#endif // RADIOBUTTONSETTINGSEDITOR_H diff --git a/yy/radiobuttonsettingsform.ui b/yy/radiobuttonsettingsform.ui new file mode 100644 index 0000000..ff97ac4 --- /dev/null +++ b/yy/radiobuttonsettingsform.ui @@ -0,0 +1,166 @@ + + + RadioButtonSettingsForm + + + + 0 + 0 + 602 + 439 + + + + Form + + + + + 0 + 0 + 241 + 228 + + + + + + + Disabled + + + + + + + + + + Label text + + + + + + + + + + Use theme colors + + + + + + + + + + Checked color + + + + + + + Unchecked color + + + + + + + Text color + + + + + + + Disabled color + + + + + + + Label position + + + + + + + + Left + + + + + Right + + + + + + + + + + + + + ... + + + + + + + + + + + + + + ... + + + + + + + + + + + + + + ... + + + + + + + + + + + + + + ... + + + + + + + + + + + diff --git a/yy/slidersettingseditor.cpp b/yy/slidersettingseditor.cpp new file mode 100644 index 0000000..c69dcfb --- /dev/null +++ b/yy/slidersettingseditor.cpp @@ -0,0 +1,50 @@ +#include "slidersettingseditor.h" +#include +#include +#include "xx/qtmaterialslider.h" +#include "components/slider.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); + layout->addWidget(m_slider); +// layout->addWidget(new QSlider(Qt::Horizontal)); +// layout->addWidget(new Slider); + + setupForm(); +} + +SliderSettingsEditor::~SliderSettingsEditor() +{ + delete ui; +} + +void SliderSettingsEditor::setupForm() +{ +} + +void SliderSettingsEditor::updateWidget() +{ +} + +void SliderSettingsEditor::selectColor() +{ +} + diff --git a/yy/slidersettingseditor.h b/yy/slidersettingseditor.h new file mode 100644 index 0000000..07ca0df --- /dev/null +++ b/yy/slidersettingseditor.h @@ -0,0 +1,27 @@ +#ifndef SLIDERSETTINGSEDITOR_H +#define SLIDERSETTINGSEDITOR_H + +#include +#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 diff --git a/yy/slidersettingsform.ui b/yy/slidersettingsform.ui new file mode 100644 index 0000000..efb20c3 --- /dev/null +++ b/yy/slidersettingsform.ui @@ -0,0 +1,41 @@ + + + SliderSettingsForm + + + + 0 + 0 + 474 + 387 + + + + Form + + + + + 0 + 0 + 361 + 331 + + + + + + + Disabled + + + + + + + + + + + + diff --git a/yy/textfieldsettingseditor.cpp b/yy/textfieldsettingseditor.cpp new file mode 100644 index 0000000..1868474 --- /dev/null +++ b/yy/textfieldsettingseditor.cpp @@ -0,0 +1,102 @@ +#include "textfieldsettingseditor.h" +#include +#include +#include "components/textfield.h" +#include "xx/qtmaterialtextfield.h" + +TextFieldSettingsEditor::TextFieldSettingsEditor(QWidget *parent) + : QWidget(parent), + ui(new Ui::TextFieldSettingsForm), + m_textField(new QtMaterialTextField) +{ + 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); + layout->addWidget(m_textField); + layout->setAlignment(m_textField, Qt::AlignCenter); + + //TextField *tf = new TextField; + //layout->addWidget(tf); + //tf->setMinimumWidth(250); + //tf->setPlaceholderText("A placeholder is this text"); + //tf->setLabel("This is the label"); + //layout->setAlignment(tf, Qt::AlignCenter); + + m_textField->setLabel("Wat is this"); + m_textField->setMinimumWidth(250); + + setupForm(); + + connect(ui->disabledCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget())); + connect(ui->textLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updateWidget())); + connect(ui->placeholderLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updateWidget())); + connect(ui->labelCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget())); + connect(ui->labelTextLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updateWidget())); + connect(ui->useThemeColorsCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget())); + connect(ui->textColorToolButton, SIGNAL(pressed()), this, SLOT(selectColor())); + connect(ui->inkColorToolButton, SIGNAL(pressed()), this, SLOT(selectColor())); + connect(ui->underlineColorToolButton, SIGNAL(pressed()), this, SLOT(selectColor())); + connect(ui->labelColorToolButton, SIGNAL(pressed()), this, SLOT(selectColor())); + + connect(m_textField, SIGNAL(textChanged(QString)), this, SLOT(setupForm())); +} + +TextFieldSettingsEditor::~TextFieldSettingsEditor() +{ + delete ui; +} + +void TextFieldSettingsEditor::setupForm() +{ + ui->disabledCheckBox->setChecked(!m_textField->isEnabled()); + ui->textLineEdit->setText(m_textField->text()); + ui->placeholderLineEdit->setText(m_textField->placeholderText()); + ui->labelCheckBox->setChecked(m_textField->hasLabel()); + ui->labelTextLineEdit->setText(m_textField->label()); + ui->useThemeColorsCheckBox->setChecked(m_textField->useThemeColors()); +} + +void TextFieldSettingsEditor::updateWidget() +{ + m_textField->setDisabled(ui->disabledCheckBox->isChecked()); + m_textField->setText(ui->textLineEdit->text()); + m_textField->setPlaceholderText(ui->placeholderLineEdit->text()); + m_textField->setLabel(ui->labelTextLineEdit->text()); + m_textField->setShowLabel(ui->labelCheckBox->isChecked()); + m_textField->setUseThemeColors(ui->useThemeColorsCheckBox->isChecked()); +} + +void TextFieldSettingsEditor::selectColor() +{ + QColorDialog dialog; + if (dialog.exec()) { + QColor color = dialog.selectedColor(); + QString senderName = sender()->objectName(); + if ("textColorToolButton" == senderName) { + m_textField->setTextColor(color); + ui->textColorLineEdit->setText(color.name(QColor::HexRgb)); + } else if ("inkColorToolButton" == senderName) { + m_textField->setInkColor(color); + ui->inkColorLineEdit->setText(color.name(QColor::HexRgb)); + } else if ("underlineColorToolButton" == senderName) { + m_textField->setUnderlineColor(color); + ui->underlineColorLineEdit->setText(color.name(QColor::HexRgb)); + } else if ("labelColorToolButton" == senderName) { + m_textField->setLabelColor(color); + ui->labelColorLineEdit->setText(color.name(QColor::HexRgb)); + } + } + setupForm(); +} diff --git a/yy/textfieldsettingseditor.h b/yy/textfieldsettingseditor.h new file mode 100644 index 0000000..221425e --- /dev/null +++ b/yy/textfieldsettingseditor.h @@ -0,0 +1,29 @@ +#ifndef TEXTFIELDSETTINGSEDITOR_H +#define TEXTFIELDSETTINGSEDITOR_H + +#include +#include "ui_textfieldsettingsform.h" + +//class TextField; +class QtMaterialTextField; + +class TextFieldSettingsEditor : public QWidget +{ + Q_OBJECT + +public: + explicit TextFieldSettingsEditor(QWidget *parent = 0); + ~TextFieldSettingsEditor(); + +protected slots: + void setupForm(); + void updateWidget(); + void selectColor(); + +private: + Ui::TextFieldSettingsForm *const ui; + //TextField *const m_textField; + QtMaterialTextField *const m_textField; +}; + +#endif // TEXTFIELDSETTINGSEDITOR_H diff --git a/yy/textfieldsettingsform.ui b/yy/textfieldsettingsform.ui new file mode 100644 index 0000000..106c58c --- /dev/null +++ b/yy/textfieldsettingsform.ui @@ -0,0 +1,175 @@ + + + TextFieldSettingsForm + + + + 0 + 0 + 400 + 416 + + + + Form + + + + + 0 + 0 + 321 + 351 + + + + + + + Disabled + + + + + + + + + + Text + + + + + + + + + + Placeholder + + + + + + + + + + Label + + + + + + + + + + Label text + + + + + + + + + + Use theme colors + + + + + + + + + + Text color + + + + + + + + + + + + ... + + + + + + + + + Ink color + + + + + + + + + + + + ... + + + + + + + + + Underline color + + + + + + + + + + + + ... + + + + + + + + + Label color + + + + + + + + + + + + ... + + + + + + + + + + +