diff --git a/README.md b/README.md index 9e5af98..6d89c71 100644 --- a/README.md +++ b/README.md @@ -13,22 +13,18 @@ - [x] Floating Action Button - [x] Flat Button - [x] Icon Button -- [ ] Icon Menu - [ ] Menu - [x] Progress -- [ ] Radio Button +- [x] Radio Button - [x] Raised Button - [ ] Scroll Bar -- [ ] Select Field - [x] Slider - [ ] Snackbar -- [ ] Tabs -- [ ] Text Field -- [ ] Toggle +- [x] Tabs +- [x] Text Field +- [x] Toggle -#### Needs some work - -#### Not implemented +#### Not implemented or needs more work - [ ] App Bar - [ ] Autocomplete @@ -36,9 +32,11 @@ - [ ] Discrete Slider - [ ] Divider - [ ] Grid List +- [ ] Icon Menu - [ ] List - [ ] Paper - [ ] Search Field +- [ ] Select Field - [ ] Stepper - [ ] Table - [ ] Toolbar diff --git a/components/components.pro b/components/components.pro index f025231..ada5c06 100644 --- a/components/components.pro +++ b/components/components.pro @@ -23,7 +23,21 @@ SOURCES = \ qtmaterialcircularprogress.cpp \ qtmaterialslider_internal.cpp \ qtmaterialslider.cpp \ +<<<<<<< HEAD \ + qtmaterialsnackbar_internal.cpp \ qtmaterialsnackbar.cpp + qtmaterialsnackbar.cpp +======= + qtmaterialradiobutton.cpp \ + qtmaterialtoggle_internal.cpp \ + qtmaterialtoggle.cpp \ + qtmaterialtextfield_internal.cpp \ + qtmaterialtextfield.cpp \ + qtmaterialtabs_internal.cpp \ + qtmaterialtabs.cpp \ + qtmaterialscrollbar_internal.cpp \ + qtmaterialscrollbar.cpp +>>>>>>> cleanup HEADERS = \ qtmaterialavatar_p.h \ qtmaterialavatar.h \ @@ -61,7 +75,27 @@ HEADERS = \ qtmaterialslider_internal.h \ qtmaterialslider_p.h \ qtmaterialslider.h \ +<<<<<<< HEAD \ + qtmaterialsnackbar_internal.h \ qtmaterialsnackbar_p.h \ qtmaterialsnackbar.h + qtmaterialsnackbar_p.h \ + qtmaterialsnackbar.h +======= + qtmaterialradiobutton_p.h \ + qtmaterialradiobutton.h \ + qtmaterialtoggle_internal.h \ + qtmaterialtoggle_p.h \ + qtmaterialtoggle.h \ + qtmaterialtextfield_internal.h \ + qtmaterialtextfield_p.h \ + qtmaterialtextfield.h \ + qtmaterialtabs_internal.h \ + qtmaterialtabs_p.h \ + qtmaterialtabs.h \ + qtmaterialscrollbar_internal.h \ + qtmaterialscrollbar_p.h \ + qtmaterialscrollbar.h +>>>>>>> cleanup RESOURCES += \ resources.qrc diff --git a/components/qtmaterialprogress.cpp b/components/qtmaterialprogress.cpp index cdbcfdd..da8c40c 100644 --- a/components/qtmaterialprogress.cpp +++ b/components/qtmaterialprogress.cpp @@ -95,7 +95,9 @@ void QtMaterialProgress::setProgressColor(const QColor &color) Q_D(QtMaterialProgress); d->progressColor = color; - setUseThemeColors(false); + + MATERIAL_DISABLE_THEME_COLORS + update(); } QColor QtMaterialProgress::progressColor() const @@ -114,7 +116,9 @@ void QtMaterialProgress::setBackgroundColor(const QColor &color) Q_D(QtMaterialProgress); d->backgroundColor = color; - setUseThemeColors(false); + + MATERIAL_DISABLE_THEME_COLORS + update(); } QColor QtMaterialProgress::backgroundColor() const diff --git a/components/qtmaterialradiobutton.cpp b/components/qtmaterialradiobutton.cpp new file mode 100644 index 0000000..86427c7 --- /dev/null +++ b/components/qtmaterialradiobutton.cpp @@ -0,0 +1,100 @@ +#include "qtmaterialradiobutton.h" +#include "qtmaterialradiobutton_p.h" +#include +#include +#include +#include +#include "lib/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(":/icons/icons/toggle/svg/production/ic_radio_button_checked_24px.svg")); + q->setUncheckedIcon(QIcon(":/icons/icons/toggle/svg/production/ic_radio_button_unchecked_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/components/qtmaterialradiobutton.h b/components/qtmaterialradiobutton.h new file mode 100644 index 0000000..adc535c --- /dev/null +++ b/components/qtmaterialradiobutton.h @@ -0,0 +1,24 @@ +#ifndef QTMATERIALRADIOBUTTON_H +#define QTMATERIALRADIOBUTTON_H + +#include "lib/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/components/qtmaterialradiobutton_p.h b/components/qtmaterialradiobutton_p.h new file mode 100644 index 0000000..6bb954a --- /dev/null +++ b/components/qtmaterialradiobutton_p.h @@ -0,0 +1,20 @@ +#ifndef QTMATERIALRADIOBUTTON_P_H +#define QTMATERIALRADIOBUTTON_P_H + +#include "lib/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/components/qtmaterialscrollbar.cpp b/components/qtmaterialscrollbar.cpp new file mode 100644 index 0000000..16b6978 --- /dev/null +++ b/components/qtmaterialscrollbar.cpp @@ -0,0 +1,201 @@ +#include "qtmaterialscrollbar.h" +#include "qtmaterialscrollbar_p.h" +#include +#include "qtmaterialscrollbar_internal.h" +#include "lib/qtmaterialstyle.h" + +/*! + * \class QtMaterialScrollBarPrivate + * \internal + */ + +QtMaterialScrollBarPrivate::QtMaterialScrollBarPrivate(QtMaterialScrollBar *q) + : q_ptr(q) +{ +} + +QtMaterialScrollBarPrivate::~QtMaterialScrollBarPrivate() +{ +} + +void QtMaterialScrollBarPrivate::init() +{ + Q_Q(QtMaterialScrollBar); + + stateMachine = new QtMaterialScrollBarStateMachine(q); + 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(); +} + +/*! + * \class QtMaterialScrollBar + */ + +QtMaterialScrollBar::QtMaterialScrollBar(QWidget *parent) + : QScrollBar(parent), + d_ptr(new QtMaterialScrollBarPrivate(this)) +{ + d_func()->init(); +} + +QtMaterialScrollBar::~QtMaterialScrollBar() +{ +} + +/*! + * \reimp + */ +QSize QtMaterialScrollBar::sizeHint() const +{ + if (Qt::Horizontal == orientation()) { + return QSize(1, 10); + } else { + return QSize(10, 1); + } +} + +void QtMaterialScrollBar::setUseThemeColors(bool value) +{ + Q_D(QtMaterialScrollBar); + + if (d->useThemeColors == value) { + return; + } + + d->useThemeColors = value; + update(); +} + +bool QtMaterialScrollBar::useThemeColors() const +{ + Q_D(const QtMaterialScrollBar); + + return d->useThemeColors; +} + +void QtMaterialScrollBar::setCanvasColor(const QColor &color) +{ + Q_D(QtMaterialScrollBar); + + d->canvasColor = color; + + MATERIAL_DISABLE_THEME_COLORS + update(); +} + +QColor QtMaterialScrollBar::canvasColor() const +{ + Q_D(const QtMaterialScrollBar); + + if (d->useThemeColors || !d->canvasColor.isValid()) { + return parentWidget()->palette().color(backgroundRole()); + } else { + return d->canvasColor; + } +} + +void QtMaterialScrollBar::setBackgroundColor(const QColor &color) +{ + Q_D(QtMaterialScrollBar); + + d->backgroundColor = color; + + MATERIAL_DISABLE_THEME_COLORS + update(); +} + +QColor QtMaterialScrollBar::backgroundColor() const +{ + Q_D(const QtMaterialScrollBar); + + if (d->useThemeColors || !d->backgroundColor.isValid()) { + return QtMaterialStyle::instance().themeColor("border"); + } else { + return d->backgroundColor; + } +} + +void QtMaterialScrollBar::setSliderColor(const QColor &color) +{ + Q_D(QtMaterialScrollBar); + + d->sliderColor = color; + + MATERIAL_DISABLE_THEME_COLORS + update(); +} + +QColor QtMaterialScrollBar::sliderColor() const +{ + Q_D(const QtMaterialScrollBar); + + if (d->useThemeColors || !d->sliderColor.isValid()) { + return QtMaterialStyle::instance().themeColor("primary1"); + } else { + return d->sliderColor; + } +} + +void QtMaterialScrollBar::setHideOnMouseOut(bool value) +{ + Q_D(QtMaterialScrollBar); + + d->hideOnMouseOut = value; + update(); +} + +bool QtMaterialScrollBar::hideOnMouseOut() const +{ + Q_D(const QtMaterialScrollBar); + + return d->hideOnMouseOut; +} + +/*! + * \reimp + */ +void QtMaterialScrollBar::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + + Q_D(QtMaterialScrollBar); + + QPainter painter(this); + painter.fillRect(rect(), canvasColor()); + + int x, y, w, h; + rect().getRect(&x, &y, &w, &h); + + QMargins margins(2, 2, 2, 2); + + QBrush brush; + brush.setStyle(Qt::SolidPattern); + brush.setColor(backgroundColor()); + painter.setBrush(brush); + painter.setPen(Qt::NoPen); + + if (d->hideOnMouseOut) { + painter.setOpacity(d->stateMachine->opacity()); + } + + painter.drawRect(rect().marginsRemoved(margins)); + + const qreal q = h / static_cast(maximum()-minimum()+pageStep()-1); + + QRect handle = Qt::Horizontal == orientation() + ? QRect(sliderPosition()*q, y, pageStep()*q, h) + : QRect(x, sliderPosition()*q, w, pageStep()*q); + + brush.setColor(sliderColor()); + painter.setBrush(brush); + + painter.drawRect(handle.marginsRemoved(margins)); +} diff --git a/components/qtmaterialscrollbar.h b/components/qtmaterialscrollbar.h new file mode 100644 index 0000000..591c9f1 --- /dev/null +++ b/components/qtmaterialscrollbar.h @@ -0,0 +1,47 @@ +#ifndef QTMATERIALSCROLLBAR_H +#define QTMATERIALSCROLLBAR_H + +#include + +class QtMaterialScrollBarPrivate; + +class QtMaterialScrollBar : public QScrollBar +{ + Q_OBJECT + + Q_PROPERTY(QColor canvasColor WRITE setCanvasColor READ canvasColor) + Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor) + Q_PROPERTY(QColor sliderColor WRITE setSliderColor READ sliderColor) + +public: + explicit QtMaterialScrollBar(QWidget *parent = 0); + ~QtMaterialScrollBar(); + + QSize sizeHint() const Q_DECL_OVERRIDE; + + void setUseThemeColors(bool value); + bool useThemeColors() const; + + void setCanvasColor(const QColor &color); + QColor canvasColor() const; + + void setBackgroundColor(const QColor &color); + QColor backgroundColor() const; + + void setSliderColor(const QColor &color); + QColor sliderColor() const; + + void setHideOnMouseOut(bool value); + bool hideOnMouseOut() const; + +protected: + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + + const QScopedPointer d_ptr; + +private: + Q_DISABLE_COPY(QtMaterialScrollBar) + Q_DECLARE_PRIVATE(QtMaterialScrollBar) +}; + +#endif // QTMATERIALSCROLLBAR_H diff --git a/components/qtmaterialscrollbar_internal.cpp b/components/qtmaterialscrollbar_internal.cpp new file mode 100644 index 0000000..e473698 --- /dev/null +++ b/components/qtmaterialscrollbar_internal.cpp @@ -0,0 +1,51 @@ +#include "qtmaterialscrollbar_internal.h" +#include +#include + +/*! + * \class QtMaterialScrollBarStateMachine + * \internal + */ + +/*! + * \internal + */ +QtMaterialScrollBarStateMachine::QtMaterialScrollBarStateMachine(QtMaterialScrollBar *parent) + : QStateMachine(parent), + m_scrollBar(parent), + m_focusState(new QState), + m_blurState(new QState), + m_opacity(0) +{ + Q_ASSERT(parent); + + addState(m_focusState); + addState(m_blurState); + setInitialState(m_blurState); + + QEventTransition *transition; + + transition = new QEventTransition(parent, QEvent::HoverEnter); + transition->setTargetState(m_focusState); + m_blurState->addTransition(transition); + + transition = new QEventTransition(parent, QEvent::HoverLeave); + transition->setTargetState(m_blurState); + m_focusState->addTransition(transition); + + m_focusState->assignProperty(this, "opacity", 1); + m_blurState->assignProperty(this, "opacity", 0); + + QPropertyAnimation *animation; + + animation = new QPropertyAnimation(this, "opacity", this); + animation->setDuration(340); + addDefaultAnimation(animation); +} + +/*! + * \internal + */ +QtMaterialScrollBarStateMachine::~QtMaterialScrollBarStateMachine() +{ +} diff --git a/components/qtmaterialscrollbar_internal.h b/components/qtmaterialscrollbar_internal.h new file mode 100644 index 0000000..adffdbd --- /dev/null +++ b/components/qtmaterialscrollbar_internal.h @@ -0,0 +1,40 @@ +#ifndef QTMATERIALSCROLLBAR_INTERNAL_H +#define QTMATERIALSCROLLBAR_INTERNAL_H + +#include +#include "qtmaterialscrollbar.h" + +class QtMaterialScrollBarStateMachine : public QStateMachine +{ + Q_OBJECT + + Q_PROPERTY(qreal opacity WRITE setOpacity READ opacity) + +public: + QtMaterialScrollBarStateMachine(QtMaterialScrollBar *parent); + ~QtMaterialScrollBarStateMachine(); + + inline void setOpacity(qreal opacity); + inline qreal opacity() const; + +private: + Q_DISABLE_COPY(QtMaterialScrollBarStateMachine) + + QtMaterialScrollBar *const m_scrollBar; + QState *m_focusState; + QState *m_blurState; + qreal m_opacity; +}; + +inline void QtMaterialScrollBarStateMachine::setOpacity(qreal opacity) +{ + m_opacity = opacity; + m_scrollBar->update(); +} + +inline qreal QtMaterialScrollBarStateMachine::opacity() const +{ + return m_opacity; +} + +#endif // QTMATERIALSCROLLBAR_INTERNAL_H diff --git a/components/qtmaterialscrollbar_p.h b/components/qtmaterialscrollbar_p.h new file mode 100644 index 0000000..1d22cc0 --- /dev/null +++ b/components/qtmaterialscrollbar_p.h @@ -0,0 +1,30 @@ +#ifndef QTMATERIALSCROLLBAR_P_H +#define QTMATERIALSCROLLBAR_P_H + +#include +#include + +class QtMaterialScrollBar; +class QtMaterialScrollBarStateMachine; + +class QtMaterialScrollBarPrivate +{ + Q_DISABLE_COPY(QtMaterialScrollBarPrivate) + Q_DECLARE_PUBLIC(QtMaterialScrollBar) + +public: + QtMaterialScrollBarPrivate(QtMaterialScrollBar *q); + ~QtMaterialScrollBarPrivate(); + + void init(); + + QtMaterialScrollBar *const q_ptr; + QtMaterialScrollBarStateMachine *stateMachine; + QColor backgroundColor; + QColor sliderColor; + QColor canvasColor; + bool hideOnMouseOut; + bool useThemeColors; +}; + +#endif // QTMATERIALSCROLLBAR_P_H diff --git a/components/qtmaterialslider.cpp b/components/qtmaterialslider.cpp index d04a1f5..a0d17dc 100644 --- a/components/qtmaterialslider.cpp +++ b/components/qtmaterialslider.cpp @@ -137,6 +137,10 @@ void QtMaterialSlider::setUseThemeColors(bool value) { Q_D(QtMaterialSlider); + if (d->useThemeColors == value) { + return; + } + d->useThemeColors = value; d->stateMachine->setupProperties(); } @@ -153,7 +157,10 @@ void QtMaterialSlider::setThumbColor(const QColor &color) Q_D(QtMaterialSlider); d->thumbColor = color; - setUseThemeColors(false); + + MATERIAL_DISABLE_THEME_COLORS + d->stateMachine->setupProperties(); + update(); } QColor QtMaterialSlider::thumbColor() const @@ -172,7 +179,10 @@ void QtMaterialSlider::setTrackColor(const QColor &color) Q_D(QtMaterialSlider); d->trackColor = color; - setUseThemeColors(false); + + MATERIAL_DISABLE_THEME_COLORS + d->stateMachine->setupProperties(); + update(); } QColor QtMaterialSlider::trackColor() const @@ -191,7 +201,10 @@ void QtMaterialSlider::setDisabledColor(const QColor &color) Q_D(QtMaterialSlider); d->disabledColor = color; - setUseThemeColors(false); + + MATERIAL_DISABLE_THEME_COLORS + d->stateMachine->setupProperties(); + update(); } QColor QtMaterialSlider::disabledColor() const diff --git a/components/qtmaterialslider_internal.h b/components/qtmaterialslider_internal.h index eab83bf..6f2649e 100644 --- a/components/qtmaterialslider_internal.h +++ b/components/qtmaterialslider_internal.h @@ -20,12 +20,6 @@ public: void setupProperties(); -//signals: -// void changedToMinimum(); -// void changedFromMinimum(); -// void noFocusMouseEnter(); -// void noFocusMouseLeave(); - private: Q_DISABLE_COPY(QtMaterialSliderStateMachine) diff --git a/components/qtmaterialtabs.cpp b/components/qtmaterialtabs.cpp new file mode 100644 index 0000000..dbc55bd --- /dev/null +++ b/components/qtmaterialtabs.cpp @@ -0,0 +1,242 @@ +#include "qtmaterialtabs.h" +#include "qtmaterialtabs_p.h" +#include +#include "qtmaterialtabs_internal.h" +#include "lib/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 = Material::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(Material::RippleStyle style) +{ + Q_D(QtMaterialTabs); + + d->rippleStyle = style; + updateTabs(); +} + +Material::RippleStyle QtMaterialTabs::rippleStyle() const +{ + Q_D(const QtMaterialTabs); + + return d->rippleStyle; +} + +void QtMaterialTabs::setInkColor(const QColor &color) +{ + Q_D(QtMaterialTabs); + + d->inkColor = color; + + MATERIAL_DISABLE_THEME_COLORS + d->inkBar->update(); + 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; + + MATERIAL_DISABLE_THEME_COLORS + updateTabs(); + update(); +} + +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; + + MATERIAL_DISABLE_THEME_COLORS + updateTabs(); + update(); +} + +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/components/qtmaterialtabs.h b/components/qtmaterialtabs.h new file mode 100644 index 0000000..11a122e --- /dev/null +++ b/components/qtmaterialtabs.h @@ -0,0 +1,58 @@ +#ifndef QTMATERIALTABS_H +#define QTMATERIALTABS_H + +#include +#include +#include "lib/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(Material::RippleStyle style); + Material::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/components/qtmaterialtabs_internal.cpp b/components/qtmaterialtabs_internal.cpp new file mode 100644 index 0000000..e952c02 --- /dev/null +++ b/components/qtmaterialtabs_internal.cpp @@ -0,0 +1,178 @@ +#include "qtmaterialtabs_internal.h" +#include +#include +#include +#include +#include +#include "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(Material::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/components/qtmaterialtabs_internal.h b/components/qtmaterialtabs_internal.h new file mode 100644 index 0000000..75dc034 --- /dev/null +++ b/components/qtmaterialtabs_internal.h @@ -0,0 +1,88 @@ +#ifndef QTMATERIALTABS_INTERNAL_H +#define QTMATERIALTABS_INTERNAL_H + +#include "lib/qtmaterialoverlaywidget.h" +#include "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/components/qtmaterialtabs_p.h b/components/qtmaterialtabs_p.h new file mode 100644 index 0000000..1f32b04 --- /dev/null +++ b/components/qtmaterialtabs_p.h @@ -0,0 +1,34 @@ +#ifndef QTMATERIALTABS_P_H +#define QTMATERIALTABS_P_H + +#include +#include "lib/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; + Material::RippleStyle rippleStyle; + QColor inkColor; + QColor backgroundColor; + QColor textColor; + int tab; + bool showHalo; + bool useThemeColors; +}; + +#endif // QTMATERIALTABS_P_H diff --git a/components/qtmaterialtextfield.cpp b/components/qtmaterialtextfield.cpp new file mode 100644 index 0000000..86643d6 --- /dev/null +++ b/components/qtmaterialtextfield.cpp @@ -0,0 +1,295 @@ +#include "qtmaterialtextfield.h" +#include "qtmaterialtextfield_p.h" +#include +#include +#include +#include "qtmaterialtextfield_internal.h" +#include "lib/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())); + + MATERIAL_DISABLE_THEME_COLORS + d->stateMachine->setupProperties(); +} + +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; + + MATERIAL_DISABLE_THEME_COLORS + d->stateMachine->setupProperties(); +} + +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; + + MATERIAL_DISABLE_THEME_COLORS + d->stateMachine->setupProperties(); +} + +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; + + MATERIAL_DISABLE_THEME_COLORS + d->stateMachine->setupProperties(); +} + +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); + + const qreal progress = d->stateMachine->progress(); + + if (text().isEmpty() && progress < 1) + { + painter.setOpacity(1-progress); + painter.fillRect(rect(), parentWidget()->palette().color(backgroundRole())); + } + + 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()); + + 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/components/qtmaterialtextfield.h b/components/qtmaterialtextfield.h new file mode 100644 index 0000000..81f740b --- /dev/null +++ b/components/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/components/qtmaterialtextfield_internal.cpp b/components/qtmaterialtextfield_internal.cpp new file mode 100644 index 0000000..156acc9 --- /dev/null +++ b/components/qtmaterialtextfield_internal.cpp @@ -0,0 +1,166 @@ +#include "qtmaterialtextfield_internal.h" +#include +#include +#include +#include +#include "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/components/qtmaterialtextfield_internal.h b/components/qtmaterialtextfield_internal.h new file mode 100644 index 0000000..e510287 --- /dev/null +++ b/components/qtmaterialtextfield_internal.h @@ -0,0 +1,120 @@ +#ifndef QTMATERIALTEXTFIELD_INTERNAL_H +#define QTMATERIALTEXTFIELD_INTERNAL_H + +#include +#include +#include "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/components/qtmaterialtextfield_p.h b/components/qtmaterialtextfield_p.h new file mode 100644 index 0000000..ad4db28 --- /dev/null +++ b/components/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/components/qtmaterialtoggle.cpp b/components/qtmaterialtoggle.cpp new file mode 100644 index 0000000..6d11fc9 --- /dev/null +++ b/components/qtmaterialtoggle.cpp @@ -0,0 +1,298 @@ +#include "qtmaterialtoggle.h" +#include "qtmaterialtoggle_p.h" +#include +#include +#include +#include +#include "qtmaterialtoggle_internal.h" +#include "lib/qtmaterialstyle.h" + +/*! + * \class QtMaterialTogglePrivate + * \internal + */ + +QtMaterialTogglePrivate::QtMaterialTogglePrivate(QtMaterialToggle *q) + : q_ptr(q) +{ +} + +QtMaterialTogglePrivate::~QtMaterialTogglePrivate() +{ +} + +void QtMaterialTogglePrivate::init() +{ + Q_Q(QtMaterialToggle); + + track = new QtMaterialToggleTrack(q); + thumb = new QtMaterialToggleThumb(q); + rippleOverlay = new QtMaterialToggleRippleOverlay(thumb, track, q); + stateMachine = new QStateMachine(q); + offState = new QState; + onState = new QState; + orientation = Qt::Horizontal; + useThemeColors = true; + + q->setCheckable(true); + q->setChecked(false); + q->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + + stateMachine->addState(offState); + stateMachine->addState(onState); + stateMachine->setInitialState(offState); + + offState->assignProperty(thumb, "shift", 0); + onState->assignProperty(thumb, "shift", 1); + + QSignalTransition *transition; + QPropertyAnimation *animation; + + // + + transition = new QSignalTransition(q, SIGNAL(toggled(bool))); + transition->setTargetState(onState); + offState->addTransition(transition); + + animation = new QPropertyAnimation(q); + animation->setPropertyName("shift"); + animation->setTargetObject(thumb); + animation->setDuration(200); + animation->setEasingCurve(QEasingCurve::OutQuad); + transition->addAnimation(animation); + + animation = new QPropertyAnimation(q); + animation->setPropertyName("trackColor"); + animation->setTargetObject(track); + animation->setDuration(150); + transition->addAnimation(animation); + + animation = new QPropertyAnimation(q); + animation->setPropertyName("thumbColor"); + animation->setTargetObject(thumb); + animation->setDuration(150); + transition->addAnimation(animation); + + // + + transition = new QSignalTransition(q, SIGNAL(toggled(bool))); + transition->setTargetState(offState); + onState->addTransition(transition); + + animation = new QPropertyAnimation(q); + animation->setPropertyName("shift"); + animation->setTargetObject(thumb); + animation->setDuration(200); + animation->setEasingCurve(QEasingCurve::OutQuad); + transition->addAnimation(animation); + + animation = new QPropertyAnimation(q); + animation->setPropertyName("trackColor"); + animation->setTargetObject(track); + animation->setDuration(150); + transition->addAnimation(animation); + + animation = new QPropertyAnimation(q); + animation->setPropertyName("thumbColor"); + animation->setTargetObject(thumb); + animation->setDuration(150); + transition->addAnimation(animation); + + // + + setupProperties(); + + stateMachine->start(); + QCoreApplication::processEvents(); +} + +void QtMaterialTogglePrivate::setupProperties() +{ + Q_Q(QtMaterialToggle); + + if (q->isEnabled()) { + const qreal shift = thumb->shift(); + if (qFuzzyCompare(shift, 1)) { + thumb->setThumbColor(q->activeColor()); + track->setTrackColor(q->activeColor().lighter(110)); + } else if (qFuzzyCompare(1+shift, 1)) { + thumb->setThumbColor(q->inactiveColor()); + track->setTrackColor(q->trackColor()); + } + } + + offState->assignProperty(track, "trackColor", q->trackColor().lighter(110)); + onState->assignProperty(track, "trackColor", q->activeColor().lighter(110)); + + offState->assignProperty(thumb, "thumbColor", q->inactiveColor()); + onState->assignProperty(thumb, "thumbColor", q->activeColor()); + + q->update(); +} + +/*! + * \class QtMaterialToggle + */ + +QtMaterialToggle::QtMaterialToggle(QWidget *parent) + : QAbstractButton(parent), + d_ptr(new QtMaterialTogglePrivate(this)) +{ + d_func()->init(); +} + +QtMaterialToggle::~QtMaterialToggle() +{ +} + +void QtMaterialToggle::setUseThemeColors(bool value) +{ + Q_D(QtMaterialToggle); + + d->useThemeColors = value; + d->setupProperties(); +} + +bool QtMaterialToggle::useThemeColors() const +{ + Q_D(const QtMaterialToggle); + + return d->useThemeColors; +} + +void QtMaterialToggle::setDisabledColor(const QColor &color) +{ + Q_D(QtMaterialToggle); + + d->disabledColor = color; + + MATERIAL_DISABLE_THEME_COLORS + d->setupProperties(); +} + +QColor QtMaterialToggle::disabledColor() const +{ + Q_D(const QtMaterialToggle); + + if (d->useThemeColors || !d->disabledColor.isValid()) { + return QtMaterialStyle::instance().themeColor("disabled"); + } else { + return d->disabledColor; + } +} + +void QtMaterialToggle::setActiveColor(const QColor &color) +{ + Q_D(QtMaterialToggle); + + d->activeColor = color; + + MATERIAL_DISABLE_THEME_COLORS + d->setupProperties(); +} + +QColor QtMaterialToggle::activeColor() const +{ + Q_D(const QtMaterialToggle); + + if (d->useThemeColors || !d->activeColor.isValid()) { + return QtMaterialStyle::instance().themeColor("primary1"); + } else { + return d->activeColor; + } +} + +void QtMaterialToggle::setInactiveColor(const QColor &color) +{ + Q_D(QtMaterialToggle); + + d->inactiveColor = color; + + MATERIAL_DISABLE_THEME_COLORS + d->setupProperties(); +} + +QColor QtMaterialToggle::inactiveColor() const +{ + Q_D(const QtMaterialToggle); + + if (d->useThemeColors || !d->inactiveColor.isValid()) { + return QtMaterialStyle::instance().themeColor("canvas"); + } else { + return d->inactiveColor; + } +} + +void QtMaterialToggle::setTrackColor(const QColor &color) +{ + Q_D(QtMaterialToggle); + + d->trackColor = color; + + MATERIAL_DISABLE_THEME_COLORS + d->setupProperties(); +} + +QColor QtMaterialToggle::trackColor() const +{ + Q_D(const QtMaterialToggle); + + if (d->useThemeColors || !d->trackColor.isValid()) { + return QtMaterialStyle::instance().themeColor("accent3"); + } else { + return d->trackColor; + } +} + +void QtMaterialToggle::setOrientation(Qt::Orientation orientation) +{ + Q_D(QtMaterialToggle); + + if (d->orientation == orientation) { + return; + } + + d->orientation = orientation; + updateGeometry(); +} + +Qt::Orientation QtMaterialToggle::orientation() const +{ + Q_D(const QtMaterialToggle); + + return d->orientation; +} + +QSize QtMaterialToggle::sizeHint() const +{ + Q_D(const QtMaterialToggle); + + return Qt::Horizontal == d->orientation + ? QSize(64, 48) + : QSize(48, 64); +} + +bool QtMaterialToggle::event(QEvent *event) +{ + Q_D(QtMaterialToggle); + + switch (event->type()) + { + case QEvent::ParentChange: + { + QWidget *widget; + if ((widget = parentWidget())) { + d->rippleOverlay->setParent(widget); + } + break; + } + default: + break; + } + return QAbstractButton::event(event); +} + +void QtMaterialToggle::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) +} diff --git a/components/qtmaterialtoggle.h b/components/qtmaterialtoggle.h new file mode 100644 index 0000000..5d5a557 --- /dev/null +++ b/components/qtmaterialtoggle.h @@ -0,0 +1,52 @@ +#ifndef QTMATERIALTOGGLE_H +#define QTMATERIALTOGGLE_H + +#include + +class QtMaterialTogglePrivate; + +class QtMaterialToggle : public QAbstractButton +{ + Q_OBJECT + + Q_PROPERTY(QColor disabledColor WRITE setDisabledColor READ disabledColor) + Q_PROPERTY(QColor activeColor WRITE setActiveColor READ activeColor) + Q_PROPERTY(QColor inactiveColor WRITE setInactiveColor READ inactiveColor) + Q_PROPERTY(QColor trackColor WRITE setTrackColor READ trackColor) + +public: + explicit QtMaterialToggle(QWidget *parent = 0); + ~QtMaterialToggle(); + + void setUseThemeColors(bool value); + bool useThemeColors() const; + + void setDisabledColor(const QColor &color); + QColor disabledColor() const; + + void setActiveColor(const QColor &color); + QColor activeColor() const; + + void setInactiveColor(const QColor &color); + QColor inactiveColor() const; + + void setTrackColor(const QColor &color); + QColor trackColor() const; + + void setOrientation(Qt::Orientation orientation); + Qt::Orientation orientation() const; + + QSize sizeHint() const Q_DECL_OVERRIDE; + +protected: + bool event(QEvent *event) Q_DECL_OVERRIDE; + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + + const QScopedPointer d_ptr; + +private: + Q_DISABLE_COPY(QtMaterialToggle) + Q_DECLARE_PRIVATE(QtMaterialToggle) +}; + +#endif // QTMATERIALTOGGLE_H diff --git a/components/qtmaterialtoggle_internal.cpp b/components/qtmaterialtoggle_internal.cpp new file mode 100644 index 0000000..9bcf823 --- /dev/null +++ b/components/qtmaterialtoggle_internal.cpp @@ -0,0 +1,231 @@ +#include "qtmaterialtoggle_internal.h" +#include +#include +#include +#include "qtmaterialtoggle.h" +#include "lib/qtmaterialripple.h" + +/*! + * \class QtMaterialToggleRippleOverlay + * \internal + */ + +QtMaterialToggleRippleOverlay::QtMaterialToggleRippleOverlay( + QtMaterialToggleThumb *thumb, + QtMaterialToggleTrack *track, + QtMaterialToggle *parent) + : QtMaterialRippleOverlay(parent->parentWidget()), + m_toggle(parent), + m_thumb(thumb), + m_track(track) +{ + connect(parent, SIGNAL(toggled(bool)), this, SLOT(addToggleRipple())); + + thumb->installEventFilter(this); +} + +QtMaterialToggleRippleOverlay::~QtMaterialToggleRippleOverlay() +{ +} + +void QtMaterialToggleRippleOverlay::addToggleRipple() +{ + if (!m_toggle->isEnabled()) { + return; + } + + int t, w; + + if (Qt::Horizontal == m_toggle->orientation()) { + t = m_toggle->height()/2; + w = m_thumb->height()/2+10; + } else { + t = m_toggle->width()/2; + w = m_thumb->width()/2+10; + } + + QtMaterialRipple *ripple = new QtMaterialRipple(QPoint(10+t, 20+t)); + ripple->setColor(m_track->trackColor()); + ripple->setRadiusEndValue(w); + ripple->setOpacityStartValue(0.8); + + addRipple(ripple); +} + +bool QtMaterialToggleRippleOverlay::eventFilter(QObject *obj, QEvent *event) +{ + if (QEvent::Paint == event->type()) { + setGeometry(overlayGeometry()); + QList::const_iterator i; + QList items = ripples(); + QColor color = m_track->trackColor(); + for (i = items.begin(); i != items.end(); ++i) { + (*i)->setColor(color); + } + } + return QtMaterialRippleOverlay::eventFilter(obj, event); +} + +QRect QtMaterialToggleRippleOverlay::overlayGeometry() const +{ + const qreal offset = m_thumb->offset(); + if (Qt::Horizontal == m_toggle->orientation()) { + return m_toggle->geometry().adjusted(-10+offset, -20, 10+offset, 20); + } else { + return m_toggle->geometry().adjusted(-10, -20+offset, 10, 20+offset); + } +} + +/*! + * \class QtMaterialToggleThumb + * \internal + */ + +QtMaterialToggleThumb::QtMaterialToggleThumb(QtMaterialToggle *parent) + : QWidget(parent), + m_toggle(parent), + m_shift(0), + m_offset(0) +{ + Q_ASSERT(parent); + + QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect; + effect->setBlurRadius(6); + effect->setColor(QColor(0, 0, 0, 80)); + effect->setOffset(QPointF(0, 1)); + setGraphicsEffect(effect); + + parent->installEventFilter(this); +} + +QtMaterialToggleThumb::~QtMaterialToggleThumb() +{ +} + +void QtMaterialToggleThumb::setShift(qreal shift) +{ + if (m_shift == shift) { + return; + } + + m_shift = shift; + updateOffset(); +} + +bool QtMaterialToggleThumb::eventFilter(QObject *obj, QEvent *event) +{ + const QEvent::Type type = event->type(); + + if (QEvent::Resize == type || QEvent::Move == type) + { + setGeometry(m_toggle->rect().adjusted(8, 8, -8, -8)); + updateOffset(); + } + return QWidget::eventFilter(obj, event); +} + +void QtMaterialToggleThumb::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + + QBrush brush; + brush.setStyle(Qt::SolidPattern); + brush.setColor(m_toggle->isEnabled() ? m_thumbColor : Qt::white); + + painter.setBrush(brush); + painter.setPen(Qt::NoPen); + + int s; + QRectF r; + + if (Qt::Horizontal == m_toggle->orientation()) { + s = height()-10; + r = QRectF(5+m_offset, 5, s, s); + } else { + s = width()-10; + r = QRectF(5, 5+m_offset, s, s); + } + + painter.drawEllipse(r); + + if (!m_toggle->isEnabled()) { + brush.setColor(m_toggle->disabledColor()); + painter.setBrush(brush); + painter.drawEllipse(r); + } +} + +void QtMaterialToggleThumb::updateOffset() +{ + const QSize s(Qt::Horizontal == m_toggle->orientation() + ? size() : size().transposed()); + m_offset = m_shift*static_cast(s.width()-s.height()); + update(); +} + +/*! + * \class QtMaterialToggleTrack + * \internal + */ + +QtMaterialToggleTrack::QtMaterialToggleTrack(QtMaterialToggle *parent) + : QWidget(parent), + m_toggle(parent) +{ + Q_ASSERT(parent); + + parent->installEventFilter(this); +} + +QtMaterialToggleTrack::~QtMaterialToggleTrack() +{ +} + +void QtMaterialToggleTrack::setTrackColor(const QColor &color) +{ + m_trackColor = color; + update(); +} + +bool QtMaterialToggleTrack::eventFilter(QObject *obj, QEvent *event) +{ + const QEvent::Type type = event->type(); + + if (QEvent::Resize == type || QEvent::Move == type) { + setGeometry(m_toggle->rect()); + } + return QWidget::eventFilter(obj, event); +} + +void QtMaterialToggleTrack::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + + QBrush brush; + if (m_toggle->isEnabled()) { + brush.setColor(m_trackColor); + painter.setOpacity(0.8); + } else { + brush.setColor(m_toggle->disabledColor()); + painter.setOpacity(0.6); + } + brush.setStyle(Qt::SolidPattern); + painter.setBrush(brush); + painter.setPen(Qt::NoPen); + + if (Qt::Horizontal == m_toggle->orientation()) { + const int h = height()/2; + const QRect r(0, h/2, width(), h); + painter.drawRoundedRect(r.adjusted(14, 4, -14, -4), h/2-4, h/2-4); + } else { + const int w = width()/2; + const QRect r(w/2, 0, w, height()); + painter.drawRoundedRect(r.adjusted(4, 14, -4, -14), w/2-4, w/2-4); + } +} diff --git a/components/qtmaterialtoggle_internal.h b/components/qtmaterialtoggle_internal.h new file mode 100644 index 0000000..079e369 --- /dev/null +++ b/components/qtmaterialtoggle_internal.h @@ -0,0 +1,120 @@ +#ifndef QTMATERIALTOGGLE_INTERNAL_H +#define QTMATERIALTOGGLE_INTERNAL_H + +#include +#include "lib/qtmaterialrippleoverlay.h" + +class QtMaterialToggle; +class QtMaterialToggleThumb; +class QtMaterialToggleTrack; + +class QtMaterialToggleRippleOverlay : public QtMaterialRippleOverlay +{ + Q_OBJECT + +public: + QtMaterialToggleRippleOverlay(QtMaterialToggleThumb *thumb, + QtMaterialToggleTrack *track, + QtMaterialToggle *parent); + ~QtMaterialToggleRippleOverlay(); + +protected slots: + void addToggleRipple(); + +protected: + bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE; + QRect overlayGeometry() const Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QtMaterialToggleRippleOverlay) + + QtMaterialToggle *const m_toggle; + QtMaterialToggleThumb *const m_thumb; + QtMaterialToggleTrack *const m_track; +}; + +class QtMaterialToggleThumb : public QWidget +{ + Q_OBJECT + + Q_PROPERTY(qreal shift WRITE setShift READ shift) + Q_PROPERTY(QColor thumbColor WRITE setThumbColor READ thumbColor) + +public: + QtMaterialToggleThumb(QtMaterialToggle *parent); + ~QtMaterialToggleThumb(); + + void setShift(qreal shift); + inline qreal shift() const; + + inline qreal offset() const; + + inline void setThumbColor(const QColor &color); + inline QColor thumbColor() const; + +protected: + bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE; + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QtMaterialToggleThumb) + + void updateOffset(); + + QtMaterialToggle *const m_toggle; + QColor m_thumbColor; + qreal m_shift; + qreal m_offset; +}; + +inline qreal QtMaterialToggleThumb::shift() const +{ + return m_shift; +} + +inline qreal QtMaterialToggleThumb::offset() const +{ + return m_offset; +} + +inline void QtMaterialToggleThumb::setThumbColor(const QColor &color) +{ + m_thumbColor = color; + update(); +} + +inline QColor QtMaterialToggleThumb::thumbColor() const +{ + return m_thumbColor; +} + +class QtMaterialToggleTrack : public QWidget +{ + Q_OBJECT + + Q_PROPERTY(QColor trackColor WRITE setTrackColor READ trackColor) + +public: + QtMaterialToggleTrack(QtMaterialToggle *parent); + ~QtMaterialToggleTrack(); + + void setTrackColor(const QColor &color); + inline QColor trackColor() const; + +protected: + bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE; + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QtMaterialToggleTrack) + + QtMaterialToggle *const m_toggle; + QColor m_trackColor; +}; + +inline QColor QtMaterialToggleTrack::trackColor() const +{ + return m_trackColor; +} + +#endif // QTMATERIALTOGGLE_INTERNAL_H diff --git a/components/qtmaterialtoggle_p.h b/components/qtmaterialtoggle_p.h new file mode 100644 index 0000000..f50d5b3 --- /dev/null +++ b/components/qtmaterialtoggle_p.h @@ -0,0 +1,41 @@ +#ifndef QTMATERIALTOGGLE_P_H +#define QTMATERIALTOGGLE_P_H + +#include + +class QStateMachine; +class QState; +class QColor; +class QtMaterialToggle; +class QtMaterialToggleTrack; +class QtMaterialToggleThumb; +class QtMaterialToggleRippleOverlay; + +class QtMaterialTogglePrivate +{ + Q_DISABLE_COPY(QtMaterialTogglePrivate) + Q_DECLARE_PUBLIC(QtMaterialToggle) + +public: + QtMaterialTogglePrivate(QtMaterialToggle *q); + ~QtMaterialTogglePrivate(); + + void init(); + void setupProperties(); + + QtMaterialToggle *const q_ptr; + QtMaterialToggleTrack *track; + QtMaterialToggleThumb *thumb; + QtMaterialToggleRippleOverlay *rippleOverlay; + QStateMachine *stateMachine; + QState *offState; + QState *onState; + Qt::Orientation orientation; + QColor disabledColor; + QColor activeColor; + QColor inactiveColor; + QColor trackColor; + bool useThemeColors; +}; + +#endif // QTMATERIALTOGGLE_P_H diff --git a/examples/examples.pro b/examples/examples.pro index afad009..1c8fa4a 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -11,7 +11,11 @@ SOURCES = mainwindow.cpp \ iconbuttonsettingseditor.cpp \ progresssettingseditor.cpp \ circularprogresssettingseditor.cpp \ - slidersettingseditor.cpp + slidersettingseditor.cpp \ + radiobuttonsettingseditor.cpp \ + togglesettingseditor.cpp \ + textfieldsettingseditor.cpp \ + tabssettingseditor.cpp HEADERS = mainwindow.h \ avatarsettingseditor.h \ badgesettingseditor.h \ @@ -22,7 +26,11 @@ HEADERS = mainwindow.h \ iconbuttonsettingseditor.h \ progresssettingseditor.h \ circularprogresssettingseditor.h \ - slidersettingseditor.h + slidersettingseditor.h \ + radiobuttonsettingseditor.h \ + togglesettingseditor.h \ + textfieldsettingseditor.h \ + tabssettingseditor.h LIBS += ../components/libcomponents.a INCLUDEPATH += ../components/ TARGET = ../examples-exe @@ -40,4 +48,8 @@ FORMS += \ progresssettingsform.ui \ circularprogresssettingsform.ui \ slidersettingsform.ui \ - snackbarsettingsform.ui + snackbarsettingsform.ui \ + radiobuttonsettingsform.ui \ + togglesettingsform.ui \ + textfieldsettingsform.ui \ + tabssettingsform.ui diff --git a/examples/mainwindow.cpp b/examples/mainwindow.cpp index 71dc2a0..81795c5 100644 --- a/examples/mainwindow.cpp +++ b/examples/mainwindow.cpp @@ -12,6 +12,10 @@ #include "progresssettingseditor.h" #include "circularprogresssettingseditor.h" #include "slidersettingseditor.h" +#include "radiobuttonsettingseditor.h" +#include "togglesettingseditor.h" +#include "textfieldsettingseditor.h" +#include "tabssettingseditor.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) @@ -24,13 +28,13 @@ MainWindow::MainWindow(QWidget *parent) QStackedLayout *stack = new QStackedLayout; QListWidget *list = new QListWidget; - setCentralWidget(widget); - layout->addWidget(list); layout->addLayout(stack); layout->setStretch(1, 2); + setCentralWidget(widget); + AvatarSettingsEditor *avatar = new AvatarSettingsEditor; BadgeSettingsEditor *badge = new BadgeSettingsEditor; CheckBoxSettingsEditor *checkbox = new CheckBoxSettingsEditor; @@ -41,6 +45,10 @@ MainWindow::MainWindow(QWidget *parent) ProgressSettingsEditor *progress = new ProgressSettingsEditor; CircularProgressSettingsEditor *circularProgress = new CircularProgressSettingsEditor; SliderSettingsEditor *slider = new SliderSettingsEditor; + RadioButtonSettingsEditor *radioButton = new RadioButtonSettingsEditor; + ToggleSettingsEditor *toggle = new ToggleSettingsEditor; + TextFieldSettingsEditor *textField = new TextFieldSettingsEditor; + TabsSettingsEditor *tabs = new TabsSettingsEditor; stack->addWidget(avatar); stack->addWidget(badge); @@ -50,8 +58,12 @@ MainWindow::MainWindow(QWidget *parent) stack->addWidget(flatButton); stack->addWidget(iconButton); stack->addWidget(progress); + stack->addWidget(radioButton); stack->addWidget(raisedButton); stack->addWidget(slider); + stack->addWidget(tabs); + stack->addWidget(textField); + stack->addWidget(toggle); list->addItem("Avatar"); list->addItem("Badge"); @@ -61,8 +73,12 @@ MainWindow::MainWindow(QWidget *parent) list->addItem("Flat Button"); list->addItem("Icon Button"); list->addItem("Progress"); + list->addItem("Radio Button"); list->addItem("Raised Button"); list->addItem("Slider"); + list->addItem("Tabs"); + list->addItem("Text Field"); + list->addItem("Toggle"); list->setCurrentRow(0); diff --git a/examples/radiobuttonsettingseditor.cpp b/examples/radiobuttonsettingseditor.cpp new file mode 100644 index 0000000..1bdf8df --- /dev/null +++ b/examples/radiobuttonsettingseditor.cpp @@ -0,0 +1,144 @@ +#include "radiobuttonsettingseditor.h" +#include +#include +#include +#include "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); + + QWidget *buttonWidget = new QWidget; + QVBoxLayout *buttonLayout = new QVBoxLayout; + buttonWidget->setLayout(buttonLayout); + + layout->addWidget(buttonWidget); + buttonLayout->addWidget(m_radioButton1); + buttonLayout->addWidget(m_radioButton2); + buttonLayout->addWidget(m_radioButton3); + + QSizePolicy policy; + policy.setHorizontalPolicy(QSizePolicy::Maximum); + buttonWidget->setSizePolicy(policy); + + layout->setAlignment(Qt::AlignCenter); + + 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/examples/radiobuttonsettingseditor.h b/examples/radiobuttonsettingseditor.h new file mode 100644 index 0000000..76ad852 --- /dev/null +++ b/examples/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/examples/radiobuttonsettingsform.ui b/examples/radiobuttonsettingsform.ui new file mode 100644 index 0000000..ff97ac4 --- /dev/null +++ b/examples/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/examples/slidersettingseditor.cpp b/examples/slidersettingseditor.cpp index c0b9236..d066543 100644 --- a/examples/slidersettingseditor.cpp +++ b/examples/slidersettingseditor.cpp @@ -79,20 +79,3 @@ void SliderSettingsEditor::updateWidget() m_slider->setValue(ui->valueLineEdit->text().toInt()); m_slider->setInvertedAppearance(ui->invertedCheckBox->isChecked()); } - -void SliderSettingsEditor::selectColor() -{ - QColorDialog dialog; - if (dialog.exec()) { - QColor color = dialog.selectedColor(); - QString senderName = sender()->objectName(); - //if ("textColorToolButton" == senderName) { - // m_avatar->setTextColor(color); - // ui->textColorLineEdit->setText(color.name(QColor::HexRgb)); - //} else if ("backgroundColorToolButton" == senderName) { - // m_avatar->setBackgroundColor(color); - // ui->backgroundColorLineEdit->setText(color.name(QColor::HexRgb)); - //} - } - setupForm(); -} diff --git a/examples/slidersettingseditor.h b/examples/slidersettingseditor.h index 07ca0df..11e1a85 100644 --- a/examples/slidersettingseditor.h +++ b/examples/slidersettingseditor.h @@ -17,7 +17,6 @@ public: protected slots: void setupForm(); void updateWidget(); - void selectColor(); private: Ui::SliderSettingsForm *const ui; diff --git a/examples/slidersettingsform.ui b/examples/slidersettingsform.ui index 11d2ffe..688aab5 100644 --- a/examples/slidersettingsform.ui +++ b/examples/slidersettingsform.ui @@ -19,7 +19,7 @@ 0 0 361 - 331 + 111 @@ -76,6 +76,19 @@ + + + + 20 + 130 + 171 + 16 + + + + TODO + + diff --git a/examples/tabssettingseditor.cpp b/examples/tabssettingseditor.cpp new file mode 100644 index 0000000..24eca89 --- /dev/null +++ b/examples/tabssettingseditor.cpp @@ -0,0 +1,89 @@ +#include "tabssettingseditor.h" +#include +#include +#include "qtmaterialtabs.h" + +TabsSettingsEditor::TabsSettingsEditor(QWidget *parent) + : QWidget(parent), + ui(new Ui::TabsSettingsForm), + m_tabs(new QtMaterialTabs) +{ + QVBoxLayout *layout = new QVBoxLayout; + setLayout(layout); + + QWidget *widget = new QWidget; + layout->addWidget(widget); + + QWidget *canvas = new QWidget; + canvas->setStyleSheet("QWidget { background: white; }"); + layout->addWidget(canvas); + + ui->setupUi(widget); + layout->setContentsMargins(20, 20, 20, 20); + + layout = new QVBoxLayout; + canvas->setLayout(layout); + canvas->setMaximumHeight(300); + layout->addWidget(m_tabs); + layout->setAlignment(m_tabs, Qt::AlignHCenter); + + m_tabs->addTab("Media"); + m_tabs->addTab("Playback"); + m_tabs->addTab("Audio"); + m_tabs->addTab("Video"); + m_tabs->addTab("Tools"); + + m_tabs->setMinimumWidth(700); + +// setupForm(); + +// connect(ui->disabledCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget())); +// connect(ui->valueLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updateWidget())); +// connect(ui->orientationComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateWidget())); +// connect(ui->invertedCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget())); +// +// connect(m_slider, SIGNAL(valueChanged(int)), this, SLOT(setupForm())); +} + +TabsSettingsEditor::~TabsSettingsEditor() +{ + delete ui; +} + +void TabsSettingsEditor::setupForm() +{ +// switch (m_slider->orientation()) +// { +// case Qt::Horizontal: +// ui->orientationComboBox->setCurrentIndex(0); +// break; +// case Qt::Vertical: +// ui->orientationComboBox->setCurrentIndex(1); +// break; +// default: +// break; +// } +// +// ui->disabledCheckBox->setChecked(!m_slider->isEnabled()); +// ui->valueLineEdit->setText(QString::number(m_slider->value())); +// ui->invertedCheckBox->setChecked(m_slider->invertedAppearance()); +} + +void TabsSettingsEditor::updateWidget() +{ +// switch (ui->orientationComboBox->currentIndex()) +// { +// case 0: +// m_slider->setOrientation(Qt::Horizontal); +// break; +// case 1: +// m_slider->setOrientation(Qt::Vertical); +// break; +// default: +// break; +// } +// +// m_slider->setDisabled(ui->disabledCheckBox->isChecked()); +// m_slider->setValue(ui->valueLineEdit->text().toInt()); +// m_slider->setInvertedAppearance(ui->invertedCheckBox->isChecked()); +} diff --git a/examples/tabssettingseditor.h b/examples/tabssettingseditor.h new file mode 100644 index 0000000..7bf3e97 --- /dev/null +++ b/examples/tabssettingseditor.h @@ -0,0 +1,26 @@ +#ifndef TABSSETTINGSEDITOR_H +#define TABSSETTINGSEDITOR_H + +#include +#include "ui_tabssettingsform.h" + +class QtMaterialTabs; + +class TabsSettingsEditor : public QWidget +{ + Q_OBJECT + +public: + explicit TabsSettingsEditor(QWidget *parent = 0); + ~TabsSettingsEditor(); + +protected slots: + void setupForm(); + void updateWidget(); + +private: + Ui::TabsSettingsForm *const ui; + QtMaterialTabs *const m_tabs; +}; + +#endif // TABSSETTINGSEDITOR_H diff --git a/examples/tabssettingsform.ui b/examples/tabssettingsform.ui new file mode 100644 index 0000000..8c6d306 --- /dev/null +++ b/examples/tabssettingsform.ui @@ -0,0 +1,54 @@ + + + TabsSettingsForm + + + + 0 + 0 + 474 + 387 + + + + Form + + + + + 0 + 0 + 361 + 61 + + + + + + + Disabled + + + + + + + + + + + + 10 + 70 + 171 + 16 + + + + TODO + + + + + + diff --git a/examples/textfieldsettingseditor.cpp b/examples/textfieldsettingseditor.cpp new file mode 100644 index 0000000..3f2fe5f --- /dev/null +++ b/examples/textfieldsettingseditor.cpp @@ -0,0 +1,94 @@ +#include "textfieldsettingseditor.h" +#include +#include +#include "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); + + 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/examples/textfieldsettingseditor.h b/examples/textfieldsettingseditor.h new file mode 100644 index 0000000..21c69f5 --- /dev/null +++ b/examples/textfieldsettingseditor.h @@ -0,0 +1,27 @@ +#ifndef TEXTFIELDSETTINGSEDITOR_H +#define TEXTFIELDSETTINGSEDITOR_H + +#include +#include "ui_textfieldsettingsform.h" + +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; + QtMaterialTextField *const m_textField; +}; + +#endif // TEXTFIELDSETTINGSEDITOR_H diff --git a/examples/textfieldsettingsform.ui b/examples/textfieldsettingsform.ui new file mode 100644 index 0000000..106c58c --- /dev/null +++ b/examples/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 + + + + + + + + + + + + ... + + + + + + + + + + + diff --git a/examples/togglesettingseditor.cpp b/examples/togglesettingseditor.cpp new file mode 100644 index 0000000..3952f8d --- /dev/null +++ b/examples/togglesettingseditor.cpp @@ -0,0 +1,107 @@ +#include "togglesettingseditor.h" +#include +#include "qtmaterialtoggle.h" + +ToggleSettingsEditor::ToggleSettingsEditor(QWidget *parent) + : QWidget(parent), + ui(new Ui::ToggleSettingsForm), + m_toggle(new QtMaterialToggle) +{ + QVBoxLayout *layout = new QVBoxLayout; + setLayout(layout); + + QWidget *widget = new QWidget; + layout->addWidget(widget); + + QWidget *canvas = new QWidget; + canvas->setStyleSheet("QWidget { background: white; }"); + layout->addWidget(canvas); + + ui->setupUi(widget); + layout->setContentsMargins(20, 20, 20, 20); + + m_toggle->setOrientation(Qt::Vertical); + + layout = new QVBoxLayout; + canvas->setLayout(layout); + layout->addWidget(m_toggle); + layout->setAlignment(m_toggle, Qt::AlignCenter); + + setupForm(); + + connect(ui->disabledCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget())); + connect(ui->checkedCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget())); + connect(ui->orientationComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateWidget())); + connect(ui->useThemeColorsCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget())); + connect(ui->disabledColorToolButton, SIGNAL(pressed()), this, SLOT(selectColor())); + connect(ui->activeColorToolButton, SIGNAL(pressed()), this, SLOT(selectColor())); + connect(ui->inactiveColorToolButton, SIGNAL(pressed()), this, SLOT(selectColor())); + connect(ui->trackColorToolButton, SIGNAL(pressed()), this, SLOT(selectColor())); + + connect(m_toggle, SIGNAL(toggled(bool)), this, SLOT(setupForm())); +} + +ToggleSettingsEditor::~ToggleSettingsEditor() +{ +} + +void ToggleSettingsEditor::setupForm() +{ + switch (m_toggle->orientation()) + { + case Qt::Horizontal: + ui->orientationComboBox->setCurrentIndex(0); + break; + case Qt::Vertical: + ui->orientationComboBox->setCurrentIndex(1); + break; + default: + break; + } + + ui->disabledCheckBox->setChecked(!m_toggle->isEnabled()); + ui->checkedCheckBox->setChecked(m_toggle->isChecked()); + ui->useThemeColorsCheckBox->setChecked(m_toggle->useThemeColors()); +} + +void ToggleSettingsEditor::updateWidget() +{ + switch (ui->orientationComboBox->currentIndex()) + { + case 0: + m_toggle->setOrientation(Qt::Horizontal); + break; + case 1: + m_toggle->setOrientation(Qt::Vertical); + break; + default: + break; + } + + m_toggle->setDisabled(ui->disabledCheckBox->isChecked()); + m_toggle->setChecked(ui->checkedCheckBox->isChecked()); + m_toggle->setUseThemeColors(ui->useThemeColorsCheckBox->isChecked()); +} + +void ToggleSettingsEditor::selectColor() +{ + QColorDialog dialog; + if (dialog.exec()) { + QColor color = dialog.selectedColor(); + QString senderName = sender()->objectName(); + if ("disabledColorToolButton" == senderName) { + m_toggle->setDisabledColor(color); + ui->disabledColorLineEdit->setText(color.name(QColor::HexRgb)); + } else if ("activeColorToolButton" == senderName) { + m_toggle->setActiveColor(color); + ui->activeColorLineEdit->setText(color.name(QColor::HexRgb)); + } else if ("inactiveColorToolButton" == senderName) { + m_toggle->setInactiveColor(color); + ui->inactiveColorLineEdit->setText(color.name(QColor::HexRgb)); + } else if ("trackColorToolButton" == senderName) { + m_toggle->setTrackColor(color); + ui->trackColorLineEdit->setText(color.name(QColor::HexRgb)); + } + } + setupForm(); +} diff --git a/examples/togglesettingseditor.h b/examples/togglesettingseditor.h new file mode 100644 index 0000000..a74553e --- /dev/null +++ b/examples/togglesettingseditor.h @@ -0,0 +1,27 @@ +#ifndef TOGGLESETTINGSEDITOR_H +#define TOGGLESETTINGSEDITOR_H + +#include +#include "ui_togglesettingsform.h" + +class QtMaterialToggle; + +class ToggleSettingsEditor : public QWidget +{ + Q_OBJECT + +public: + explicit ToggleSettingsEditor(QWidget *parent = 0); + ~ToggleSettingsEditor(); + +protected slots: + void setupForm(); + void updateWidget(); + void selectColor(); + +private: + Ui::ToggleSettingsForm *const ui; + QtMaterialToggle *const m_toggle; +}; + +#endif // TOGGLESETTINGSEDITOR_H diff --git a/examples/togglesettingsform.ui b/examples/togglesettingsform.ui new file mode 100644 index 0000000..a6edbb7 --- /dev/null +++ b/examples/togglesettingsform.ui @@ -0,0 +1,166 @@ + + + ToggleSettingsForm + + + + 0 + 0 + 482 + 427 + + + + Form + + + + + 0 + 0 + 441 + 341 + + + + + + + Disabled + + + + + + + + + + Checked + + + + + + + + + + Orientation + + + + + + + + Horizontal + + + + + Vertical + + + + + + + + Active color + + + + + + + Inactive color + + + + + + + Disabled color + + + + + + + Track color + + + + + + + + + + + + ... + + + + + + + + + + + + + + ... + + + + + + + + + + + + + + ... + + + + + + + + + + + + + + ... + + + + + + + + + Use theme colors + + + + + + + + + + + +