From 8f7f34dbc256340427c9bb0dd44b6f90a715544f Mon Sep 17 00:00:00 2001 From: Johannes Hilden Date: Sat, 19 Mar 2016 10:50:48 +0300 Subject: [PATCH] implement icon button --- flatbutton.cpp | 18 +++++----- flatbutton.h | 2 +- iconbutton.cpp | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++ iconbutton.h | 33 ++++++++++++++++++ 4 files changed, 139 insertions(+), 9 deletions(-) diff --git a/flatbutton.cpp b/flatbutton.cpp index 84f858b..f09a471 100644 --- a/flatbutton.cpp +++ b/flatbutton.cpp @@ -30,12 +30,12 @@ QSize FlatButton::sizeHint() const int w = 0, h = 0; - QStyleOptionButton opt = getStyleOption(); + QStyleOptionButton option(getStyleOption()); #ifndef QT_NO_ICON if (!icon().isNull()) { - int ih = opt.iconSize.height(); - int iw = opt.iconSize.width() + 4; + int ih = option.iconSize.height(); + int iw = option.iconSize.width() + 4; w += iw; h = qMax(h, ih); } @@ -51,7 +51,7 @@ QSize FlatButton::sizeHint() const w += sz.width(); if (!empty || !h) h = qMax(h, sz.height()); - return (style()->sizeFromContents(QStyle::CT_PushButton, &opt, QSize(w, h), this). + return (style()->sizeFromContents(QStyle::CT_PushButton, &option, QSize(w, h), this). expandedTo(QApplication::globalStrut())); } @@ -68,12 +68,12 @@ void FlatButton::paintEvent(QPaintEvent *event) QStylePainter painter(this); - QStyleOptionButton option = getStyleOption(); + QStyleOptionButton option(getStyleOption()); painter.drawControl(QStyle::CE_PushButton, option); if (underMouse()) { - QRect r = rect(); + QRect r(rect()); QBrush brush; brush.setStyle(Qt::SolidPattern); painter.setOpacity(0.1); @@ -83,6 +83,9 @@ void FlatButton::paintEvent(QPaintEvent *event) void FlatButton::mousePressEvent(QMouseEvent *event) { + if (!_overlay) + return; + _overlay->addRipple(event->pos()); } @@ -111,8 +114,7 @@ QStyleOptionButton FlatButton::getStyleOption() const { QStyleOptionButton option; option.initFrom(this); - option.features = QStyleOptionButton::None; - option.features |= QStyleOptionButton::Flat; + option.features = QStyleOptionButton::Flat; if (isChecked()) option.state |= QStyle::State_On; option.text = text(); diff --git a/flatbutton.h b/flatbutton.h index cf34053..ec0c22f 100644 --- a/flatbutton.h +++ b/flatbutton.h @@ -25,7 +25,7 @@ protected: void leaveEvent(QEvent *event) Q_DECL_OVERRIDE; private: - inline void updateOverlayGeometry() { _overlay->setGeometry(rect()); } + inline void updateOverlayGeometry() { if (_overlay) { _overlay->setGeometry(rect()); } } QStyleOptionButton getStyleOption() const; RippleOverlay *const _overlay; diff --git a/iconbutton.cpp b/iconbutton.cpp index e69de29..d4fc4a7 100644 --- a/iconbutton.cpp +++ b/iconbutton.cpp @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include +#include "iconbutton.h" +#include "rippleoverlay.h" + +IconButton::IconButton(const QIcon &icon, QWidget *parent) + : QAbstractButton(parent), + _overlay(new RippleOverlay(parent)) +{ + setIcon(icon); +} + +IconButton::~IconButton() +{ +} + +QSize IconButton::sizeHint() const +{ + QStyleOptionButton option(getStyleOption()); + + int w = option.iconSize.width() + 4; + int h = option.iconSize.height(); + + return (style()->sizeFromContents(QStyle::CT_PushButton, &option, QSize(w, h), this). + expandedTo(QApplication::globalStrut())); +} + +void IconButton::moveEvent(QMoveEvent *event) +{ + Q_UNUSED(event) + + updateOverlayGeometry(); +} + +void IconButton::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event) + + updateOverlayGeometry(); +} + +void IconButton::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + + QStylePainter painter(this); + QStyleOptionButton option(getStyleOption()); + painter.drawControl(QStyle::CE_PushButton, option); +} + +void IconButton::mousePressEvent(QMouseEvent *event) +{ + Q_UNUSED(event) + + if (!_overlay) + return; + + const QRect &size = geometry(); + _overlay->addRipple(QPoint(size.width(), size.height()), iconSize().width()); + + emit clicked(); +} + +bool IconButton::event(QEvent *event) +{ + if (QEvent::ParentChange == event->type()) { + _overlay->setParent(parentWidget()); + } + return QAbstractButton::event(event); +} + +void IconButton::updateOverlayGeometry() +{ + if (!_overlay) + return; + + int x, y, w, h; + geometry().getRect(&x, &y, &w, &h); + _overlay->setGeometry(x-w/2, y-h/2, w*2, h*2); +} + +QStyleOptionButton IconButton::getStyleOption() const +{ + QStyleOptionButton option; + option.initFrom(this); + option.features = QStyleOptionButton::Flat; + if (isChecked()) + option.state |= QStyle::State_On; + option.icon = icon(); + option.iconSize = iconSize(); + return option; +} diff --git a/iconbutton.h b/iconbutton.h index e69de29..4503954 100644 --- a/iconbutton.h +++ b/iconbutton.h @@ -0,0 +1,33 @@ +#ifndef ICONBUTTON_H +#define ICONBUTTON_H + +#include +#include + +class RippleOverlay; + +class IconButton : public QAbstractButton +{ + Q_OBJECT + +public: + explicit IconButton(const QIcon &icon, QWidget *parent = 0); + ~IconButton(); + + QSize sizeHint() const Q_DECL_OVERRIDE; + +protected: + void moveEvent(QMoveEvent *event) Q_DECL_OVERRIDE; + void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + bool event(QEvent *event) Q_DECL_OVERRIDE; + +private: + void updateOverlayGeometry(); + QStyleOptionButton getStyleOption() const; + + RippleOverlay *const _overlay; +}; + +#endif // ICONBUTTON_H