diff --git a/components/components.pro b/components/components.pro index dd68afe..bed915c 100644 --- a/components/components.pro +++ b/components/components.pro @@ -15,7 +15,8 @@ SOURCES = \ qtmaterialraisedbutton.cpp \ qtmaterialflatbutton_internal.cpp \ qtmaterialflatbutton.cpp \ - lib/qtmaterialstatetransition.cpp + lib/qtmaterialstatetransition.cpp \ + qtmaterialiconbutton.cpp HEADERS = \ qtmaterialavatar_p.h \ qtmaterialavatar.h \ @@ -41,6 +42,8 @@ HEADERS = \ qtmaterialflatbutton_p.h \ qtmaterialflatbutton.h \ lib/qtmaterialstatetransition.h \ - lib/qtmaterialstatetransitionevent.h + lib/qtmaterialstatetransitionevent.h \ + qtmaterialiconbutton_p.h \ + qtmaterialiconbutton.h RESOURCES += \ resources.qrc diff --git a/components/qtmaterialiconbutton.cpp b/components/qtmaterialiconbutton.cpp new file mode 100644 index 0000000..feffa6d --- /dev/null +++ b/components/qtmaterialiconbutton.cpp @@ -0,0 +1,191 @@ +#include "xx/qtmaterialiconbutton.h" +#include "xx/qtmaterialiconbutton_p.h" +#include +#include +#include "xxlib/qtmaterialstyle.h" +#include "xxlib/qtmaterialrippleoverlay.h" + +/*! + * \class QtMaterialIconButtonPrivate + * \internal + */ + +QtMaterialIconButtonPrivate::QtMaterialIconButtonPrivate(QtMaterialIconButton *q) + : q_ptr(q) +{ +} + +QtMaterialIconButtonPrivate::~QtMaterialIconButtonPrivate() +{ +} + +void QtMaterialIconButtonPrivate::init() +{ + Q_Q(QtMaterialIconButton); + + rippleOverlay = new QtMaterialRippleOverlay(q->parentWidget()); + useThemeColors = true; + + q->setStyle(&QtMaterialStyle::instance()); + + QSizePolicy policy; + policy.setWidthForHeight(true); + q->setSizePolicy(policy); + + rippleOverlay->installEventFilter(q); +} + +/*! + * \class QtMaterialIconButton + */ + +QtMaterialIconButton::QtMaterialIconButton(const QIcon &icon, QWidget *parent) + : QAbstractButton(parent), + d_ptr(new QtMaterialIconButtonPrivate(this)) +{ + d_func()->init(); + + setIcon(icon); +} + +QtMaterialIconButton::~QtMaterialIconButton() +{ +} + +/*! + * \reimp + */ +QSize QtMaterialIconButton::sizeHint() const +{ + return iconSize(); +} + +void QtMaterialIconButton::setUseThemeColors(bool value) +{ + Q_D(QtMaterialIconButton); + + if (d->useThemeColors == value) { + return; + } + + d->useThemeColors = value; + update(); +} + +bool QtMaterialIconButton::useThemeColors() const +{ + Q_D(const QtMaterialIconButton); + + return d->useThemeColors; +} + +void QtMaterialIconButton::setColor(const QColor &color) +{ + Q_D(QtMaterialIconButton); + + d->color = color; + update(); +} + +QColor QtMaterialIconButton::color() const +{ + Q_D(const QtMaterialIconButton); + + if (d->useThemeColors || !d->color.isValid()) { + return QtMaterialStyle::instance().themeColor("text"); + } + return d->color; +} + +void QtMaterialIconButton::setDisabledColor(const QColor &color) +{ + Q_D(QtMaterialIconButton); + + d->disabledColor = color; + update(); +} + +QColor QtMaterialIconButton::disabledColor() const +{ + Q_D(const QtMaterialIconButton); + + if (d->useThemeColors || !d->disabledColor.isValid()) { + return QtMaterialStyle::instance().themeColor("disabled"); + } + return d->disabledColor; +} + +QtMaterialIconButton::QtMaterialIconButton(QtMaterialIconButtonPrivate &d, QWidget *parent) + : QAbstractButton(parent), + d_ptr(&d) +{ + d_func()->init(); +} + +/*! + * \reimp + */ +bool QtMaterialIconButton::event(QEvent *event) +{ + Q_D(QtMaterialIconButton); + + switch (event->type()) + { + case QEvent::ParentChange: { + QWidget *widget; + if ((widget = parentWidget())) { + d->rippleOverlay->setParent(widget); + } + break; + } + default: + break; + } + return QAbstractButton::event(event); +} + +/*! + * \reimp + */ +bool QtMaterialIconButton::eventFilter(QObject *obj, QEvent *event) +{ + if (QEvent::Resize == event->type()) + { + Q_D(QtMaterialIconButton); + + const int s = iconSize().width()/2; + d->rippleOverlay->setGeometry(geometry().adjusted(-s, -s, s, s)); + } + return QAbstractButton::eventFilter(obj, event); +} + +/*! + * \reimp + */ +void QtMaterialIconButton::mousePressEvent(QMouseEvent *event) +{ + Q_D(QtMaterialIconButton); + + d->rippleOverlay->addRipple(QPoint(d->rippleOverlay->width(), + d->rippleOverlay->height())/2, + iconSize().width()); + emit clicked(); + + QAbstractButton::mousePressEvent(event); +} + +/*! + * \reimp + */ +void QtMaterialIconButton::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + + QPainter painter(this); + + QPixmap pixmap = icon().pixmap(iconSize()); + QPainter icon(&pixmap); + icon.setCompositionMode(QPainter::CompositionMode_SourceIn); + icon.fillRect(pixmap.rect(), isEnabled() ? color() : disabledColor()); + painter.drawPixmap(0, 0, pixmap); +} diff --git a/components/qtmaterialiconbutton.h b/components/qtmaterialiconbutton.h new file mode 100644 index 0000000..2f13b0a --- /dev/null +++ b/components/qtmaterialiconbutton.h @@ -0,0 +1,42 @@ +#ifndef QTMATERIALICONBUTTON_H +#define QTMATERIALICONBUTTON_H + +#include + +class QtMaterialIconButtonPrivate; + +class QtMaterialIconButton : public QAbstractButton +{ + Q_OBJECT + +public: + explicit QtMaterialIconButton(const QIcon &icon, QWidget *parent = 0); + ~QtMaterialIconButton(); + + QSize sizeHint() const Q_DECL_OVERRIDE; + + void setUseThemeColors(bool value); + bool useThemeColors() const; + + void setColor(const QColor &color); + QColor color() const; + + void setDisabledColor(const QColor &color); + QColor disabledColor() const; + +protected: + QtMaterialIconButton(QtMaterialIconButtonPrivate &d, QWidget *parent = 0); + + 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; + +private: + Q_DISABLE_COPY(QtMaterialIconButton) + Q_DECLARE_PRIVATE(QtMaterialIconButton) +}; + +#endif // QTMATERIALICONBUTTON_H diff --git a/components/qtmaterialiconbutton_p.h b/components/qtmaterialiconbutton_p.h new file mode 100644 index 0000000..3f7fe61 --- /dev/null +++ b/components/qtmaterialiconbutton_p.h @@ -0,0 +1,28 @@ +#ifndef QTMATERIALICONBUTTON_P_H +#define QTMATERIALICONBUTTON_P_H + +#include + +class QtMaterialIconButton; +class QtMaterialRippleOverlay; +class QColor; + +class QtMaterialIconButtonPrivate +{ + Q_DISABLE_COPY(QtMaterialIconButtonPrivate) + Q_DECLARE_PUBLIC(QtMaterialIconButton) + +public: + QtMaterialIconButtonPrivate(QtMaterialIconButton *q); + virtual ~QtMaterialIconButtonPrivate(); + + void init(); + + QtMaterialIconButton *const q_ptr; + QtMaterialRippleOverlay *rippleOverlay; + QColor color; + QColor disabledColor; + bool useThemeColors; +}; + +#endif // QTMATERIALICONBUTTON_P_H