implement Radio Button
This commit is contained in:
parent
309e9eb5a8
commit
3493507c12
|
@ -1,13 +1,21 @@
|
|||
#include "radiobutton.h"
|
||||
#include <QPainter>
|
||||
#include <QEvent>
|
||||
#include <QSignalTransition>
|
||||
#include <QPropertyAnimation>
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include "radiobutton_p.h"
|
||||
#include "lib/rippleoverlay.h"
|
||||
#include "lib/style.h"
|
||||
#include "lib/ripple.h"
|
||||
|
||||
RadioButtonPrivate::RadioButtonPrivate(RadioButton *q)
|
||||
: q_ptr(q),
|
||||
checkedIcon(QIcon("../qt-material-widgets/ic_radio_button_checked_black_24px.svg")),
|
||||
uncheckedIcon(QIcon("../qt-material-widgets/ic_radio_button_unchecked_black_24px.svg"))
|
||||
checkedIcon(new RadioButtonIcon(QIcon("../qt-material-widgets/ic_radio_button_checked_black_24px.svg"))),
|
||||
uncheckedIcon(new RadioButtonIcon(QIcon("../qt-material-widgets/ic_radio_button_unchecked_black_24px.svg"))),
|
||||
iconSize(24),
|
||||
useThemeColors(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -15,12 +23,79 @@ void RadioButtonPrivate::init()
|
|||
{
|
||||
Q_Q(RadioButton);
|
||||
|
||||
checkedIcon->setParent(q);
|
||||
uncheckedIcon->setParent(q);
|
||||
|
||||
ripple = new RippleOverlay(q->parentWidget());
|
||||
iconWidget = new RadioButtonIcon(q);
|
||||
machine = new QStateMachine(q);
|
||||
|
||||
QFont f(q->font());
|
||||
f.setPointSizeF(11);
|
||||
q->setFont(f);
|
||||
|
||||
uncheckedState = new QState;
|
||||
checkedState = new QState;
|
||||
|
||||
machine->addState(uncheckedState);
|
||||
machine->addState(checkedState);
|
||||
|
||||
machine->setInitialState(uncheckedState);
|
||||
|
||||
QSignalTransition *transition;
|
||||
QPropertyAnimation *animation;
|
||||
|
||||
transition = new QSignalTransition(q, SIGNAL(toggled(bool)));
|
||||
transition->setTargetState(checkedState);
|
||||
uncheckedState->addTransition(transition);
|
||||
|
||||
animation = new QPropertyAnimation(checkedIcon, "iconSize");
|
||||
animation->setDuration(250);
|
||||
transition->addAnimation(animation);
|
||||
|
||||
animation = new QPropertyAnimation(uncheckedIcon, "iconSize");
|
||||
animation->setDuration(250);
|
||||
transition->addAnimation(animation);
|
||||
|
||||
transition = new QSignalTransition(q, SIGNAL(toggled(bool)));
|
||||
transition->setTargetState(uncheckedState);
|
||||
checkedState->addTransition(transition);
|
||||
|
||||
animation = new QPropertyAnimation(checkedIcon, "iconSize");
|
||||
animation->setDuration(250);
|
||||
transition->addAnimation(animation);
|
||||
|
||||
animation = new QPropertyAnimation(uncheckedIcon, "iconSize");
|
||||
animation->setDuration(250);
|
||||
transition->addAnimation(animation);
|
||||
|
||||
assignAnimationProperties();
|
||||
updatePalette();
|
||||
|
||||
machine->start();
|
||||
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
|
||||
void RadioButtonPrivate::assignAnimationProperties()
|
||||
{
|
||||
uncheckedState->assignProperty(checkedIcon, "iconSize", 0);
|
||||
uncheckedState->assignProperty(uncheckedIcon, "iconSize", iconSize);
|
||||
|
||||
checkedState->assignProperty(uncheckedIcon, "iconSize", 0);
|
||||
checkedState->assignProperty(checkedIcon, "iconSize", iconSize);
|
||||
}
|
||||
|
||||
void RadioButtonPrivate::updatePalette()
|
||||
{
|
||||
Q_Q(RadioButton);
|
||||
|
||||
if (q->isEnabled()) {
|
||||
checkedIcon->setColor(q->checkedColor());
|
||||
uncheckedIcon->setColor(q->uncheckedColor());
|
||||
} else {
|
||||
checkedIcon->setColor(q->disabledColor());
|
||||
uncheckedIcon->setColor(q->disabledColor());
|
||||
}
|
||||
}
|
||||
|
||||
RadioButton::RadioButton(QWidget *parent)
|
||||
|
@ -28,21 +103,161 @@ RadioButton::RadioButton(QWidget *parent)
|
|||
d_ptr(new RadioButtonPrivate(this))
|
||||
{
|
||||
d_func()->init();
|
||||
|
||||
//QPushButton *b = new QPushButton;
|
||||
//b->setParent(this);
|
||||
//b->setIcon(d_func()->checkedIcon);
|
||||
//b->setIconSize(QSize(12, 12));
|
||||
|
||||
//QGraphicsColorizeEffect *effect = new QGraphicsColorizeEffect;
|
||||
//effect->setColor(Qt::blue);
|
||||
//b->setGraphicsEffect(effect);
|
||||
}
|
||||
|
||||
RadioButton::~RadioButton()
|
||||
{
|
||||
}
|
||||
|
||||
void RadioButton::setUseThemeColors(bool state)
|
||||
{
|
||||
Q_D(RadioButton);
|
||||
|
||||
d->useThemeColors = state;
|
||||
d->updatePalette();
|
||||
update();
|
||||
}
|
||||
|
||||
bool RadioButton::useThemeColors() const
|
||||
{
|
||||
Q_D(const RadioButton);
|
||||
|
||||
return d->useThemeColors;
|
||||
}
|
||||
|
||||
void RadioButton::setCheckedColor(const QColor &color)
|
||||
{
|
||||
Q_D(RadioButton);
|
||||
|
||||
d->checkedColor = color;
|
||||
setUseThemeColors(false);
|
||||
}
|
||||
|
||||
QColor RadioButton::checkedColor() const
|
||||
{
|
||||
Q_D(const RadioButton);
|
||||
|
||||
if (d->useThemeColors || !d->checkedColor.isValid()) {
|
||||
return Style::instance().themeColor("primary1");
|
||||
} else {
|
||||
return d->checkedColor;
|
||||
}
|
||||
}
|
||||
|
||||
void RadioButton::setUncheckedColor(const QColor &color)
|
||||
{
|
||||
Q_D(RadioButton);
|
||||
|
||||
d->uncheckedColor = color;
|
||||
setUseThemeColors(false);
|
||||
}
|
||||
|
||||
QColor RadioButton::uncheckedColor() const
|
||||
{
|
||||
Q_D(const RadioButton);
|
||||
|
||||
if (d->useThemeColors || !d->uncheckedColor.isValid()) {
|
||||
return Style::instance().themeColor("text");
|
||||
} else {
|
||||
return d->uncheckedColor;
|
||||
}
|
||||
}
|
||||
|
||||
void RadioButton::setTextColor(const QColor &color)
|
||||
{
|
||||
Q_D(RadioButton);
|
||||
|
||||
d->textColor = color;
|
||||
setUseThemeColors(false);
|
||||
}
|
||||
|
||||
QColor RadioButton::textColor() const
|
||||
{
|
||||
Q_D(const RadioButton);
|
||||
|
||||
if (d->useThemeColors || !d->textColor.isValid()) {
|
||||
return Style::instance().themeColor("text");
|
||||
} else {
|
||||
return d->textColor;
|
||||
}
|
||||
}
|
||||
|
||||
void RadioButton::setDisabledColor(const QColor &color)
|
||||
{
|
||||
Q_D(RadioButton);
|
||||
|
||||
d->disabledColor = color;
|
||||
setUseThemeColors(false);
|
||||
}
|
||||
|
||||
QColor RadioButton::disabledColor() const
|
||||
{
|
||||
Q_D(const RadioButton);
|
||||
|
||||
if (d->useThemeColors || !d->disabledColor.isValid()) {
|
||||
// Transparency will not work here, since we use this color to
|
||||
// tint the icon using a QGraphicsColorizeEffect
|
||||
return Style::instance().themeColor("accent3");
|
||||
} else {
|
||||
return d->disabledColor;
|
||||
}
|
||||
}
|
||||
|
||||
void RadioButton::setCheckedIcon(const QIcon &icon)
|
||||
{
|
||||
Q_D(RadioButton);
|
||||
|
||||
d->checkedIcon->setIcon(icon);
|
||||
}
|
||||
|
||||
QIcon RadioButton::checkedIcon() const
|
||||
{
|
||||
Q_D(const RadioButton);
|
||||
|
||||
return d->checkedIcon->icon();
|
||||
}
|
||||
|
||||
void RadioButton::setUncheckedIcon(const QIcon &icon)
|
||||
{
|
||||
Q_D(RadioButton);
|
||||
|
||||
d->uncheckedIcon->setIcon(icon);
|
||||
}
|
||||
|
||||
QIcon RadioButton::uncheckedIcon() const
|
||||
{
|
||||
Q_D(const RadioButton);
|
||||
|
||||
return d->uncheckedIcon->icon();
|
||||
}
|
||||
|
||||
void RadioButton::setIconSize(int size)
|
||||
{
|
||||
Q_D(RadioButton);
|
||||
|
||||
if (size > 38) {
|
||||
size = 38;
|
||||
qWarning() << "RadioButton::setIconSize: maximum allowed icon size is 38";
|
||||
}
|
||||
|
||||
d->iconSize = size;
|
||||
d->assignAnimationProperties();
|
||||
|
||||
if (isChecked()) {
|
||||
d->checkedIcon->setIconSize(size);
|
||||
} else {
|
||||
d->uncheckedIcon->setIconSize(size);
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
int RadioButton::iconSize() const
|
||||
{
|
||||
Q_D(const RadioButton);
|
||||
|
||||
return d->iconSize;
|
||||
}
|
||||
|
||||
QSize RadioButton::sizeHint() const
|
||||
{
|
||||
QString s(text());
|
||||
|
@ -64,7 +279,8 @@ bool RadioButton::event(QEvent *event)
|
|||
case QEvent::Resize:
|
||||
case QEvent::Move:
|
||||
d->ripple->setGeometry(geometry().adjusted(-8, -8, 8, 8));
|
||||
d->iconWidget->setGeometry(geometry());
|
||||
d->checkedIcon->setGeometry(rect());
|
||||
d->uncheckedIcon->setGeometry(rect());
|
||||
break;
|
||||
case QEvent::ParentChange:
|
||||
QWidget *widget;
|
||||
|
@ -72,6 +288,16 @@ bool RadioButton::event(QEvent *event)
|
|||
d->ripple->setParent(widget);
|
||||
}
|
||||
break;
|
||||
case QEvent::EnabledChange:
|
||||
d->updatePalette();
|
||||
if (isChecked()) {
|
||||
d->checkedIcon->setIconSize(d->iconSize);
|
||||
d->uncheckedIcon->setIconSize(0);
|
||||
} else {
|
||||
d->checkedIcon->setIconSize(0);
|
||||
d->uncheckedIcon->setIconSize(d->iconSize);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -80,39 +306,30 @@ bool RadioButton::event(QEvent *event)
|
|||
|
||||
void RadioButton::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
if (!isEnabled())
|
||||
return;
|
||||
|
||||
Q_D(RadioButton);
|
||||
|
||||
d->ripple->addRipple(QPoint(24, 24), 24);
|
||||
Ripple *ripple = new Ripple(QPoint(24, 24));
|
||||
ripple->setRadiusEndValue(24);
|
||||
ripple->setColor(isChecked() ? d->checkedIcon->color() : Qt::black);
|
||||
d->ripple->addRipple(ripple);
|
||||
|
||||
QRadioButton::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void RadioButton::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
QRadioButton::mouseReleaseEvent(event);
|
||||
setChecked(!isChecked());
|
||||
}
|
||||
|
||||
void RadioButton::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
//Q_D(RadioButton);
|
||||
|
||||
QPainter painter(this);
|
||||
|
||||
//painter.save();
|
||||
//QRadioButton::paintEvent(event);
|
||||
//painter.restore();
|
||||
|
||||
//painter.drawRect(rect().adjusted(0, 0, -1, -1));
|
||||
|
||||
// Icon
|
||||
|
||||
//d->checkedIcon.paint(&painter, QRect(4, 4, 24, 24), Qt::AlignCenter, QIcon::Normal);
|
||||
|
||||
//d->checkedIcon.pixmap()
|
||||
|
||||
// Label
|
||||
QPen pen;
|
||||
pen.setColor(isEnabled() ? textColor() : disabledColor());
|
||||
painter.setPen(pen);
|
||||
|
||||
painter.drawText(44, 21, text());
|
||||
}
|
||||
|
|
|
@ -13,12 +13,35 @@ public:
|
|||
explicit RadioButton(QWidget *parent = 0);
|
||||
~RadioButton();
|
||||
|
||||
void setUseThemeColors(bool state);
|
||||
bool useThemeColors() const;
|
||||
|
||||
void setCheckedColor(const QColor &color);
|
||||
QColor checkedColor() const;
|
||||
|
||||
void setUncheckedColor(const QColor &color);
|
||||
QColor uncheckedColor() const;
|
||||
|
||||
void setTextColor(const QColor &color);
|
||||
QColor textColor() const;
|
||||
|
||||
void setDisabledColor(const QColor &color);
|
||||
QColor disabledColor() const;
|
||||
|
||||
void setCheckedIcon(const QIcon &icon);
|
||||
QIcon checkedIcon() const;
|
||||
|
||||
void setUncheckedIcon(const QIcon &icon);
|
||||
QIcon uncheckedIcon() const;
|
||||
|
||||
void setIconSize(int size);
|
||||
int iconSize() const;
|
||||
|
||||
QSize sizeHint() const;
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event) Q_DECL_OVERRIDE;
|
||||
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
const QScopedPointer<RadioButtonPrivate> d_ptr;
|
||||
|
|
|
@ -1,21 +1,58 @@
|
|||
#include "radiobutton_internal.h"
|
||||
#include <QPainter>
|
||||
#include <QGraphicsColorizeEffect>
|
||||
|
||||
RadioButtonIcon::RadioButtonIcon(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
RadioButtonIcon::RadioButtonIcon(const QIcon &icon, QWidget *parent)
|
||||
: QWidget(parent),
|
||||
_icon(icon),
|
||||
_iconSize(24),
|
||||
_effect(new QGraphicsColorizeEffect)
|
||||
{
|
||||
setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
|
||||
setGraphicsEffect(_effect);
|
||||
}
|
||||
|
||||
RadioButtonIcon::~RadioButtonIcon()
|
||||
{
|
||||
}
|
||||
|
||||
void RadioButtonIcon::setColor(const QColor &color)
|
||||
{
|
||||
_effect->setColor(color);
|
||||
update();
|
||||
}
|
||||
|
||||
QColor RadioButtonIcon::color() const
|
||||
{
|
||||
return _effect->color();
|
||||
}
|
||||
|
||||
void RadioButtonIcon::setIconSize(int size)
|
||||
{
|
||||
_iconSize = size;
|
||||
update();
|
||||
}
|
||||
|
||||
int RadioButtonIcon::iconSize() const
|
||||
{
|
||||
return _iconSize;
|
||||
}
|
||||
|
||||
void RadioButtonIcon::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
#ifdef DEBUG_LAYOUT
|
||||
QPainter debug(this);
|
||||
debug.drawRect(rect().adjusted(0, 0, -1, -1));
|
||||
#endif
|
||||
|
||||
if (0 == _iconSize)
|
||||
return;
|
||||
|
||||
QPainter painter(this);
|
||||
|
||||
painter.setPen(Qt::red);
|
||||
painter.drawRect(rect());
|
||||
const int p = (height() - _iconSize)/2;
|
||||
_icon.paint(&painter, QRect(p, p, _iconSize, _iconSize));
|
||||
}
|
||||
|
|
|
@ -2,20 +2,39 @@
|
|||
#define RADIOBUTTON_INTERNAL_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QIcon>
|
||||
|
||||
class QGraphicsColorizeEffect;
|
||||
|
||||
class RadioButtonIcon : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QColor color READ color WRITE setColor)
|
||||
Q_PROPERTY(int iconSize READ iconSize WRITE setIconSize)
|
||||
|
||||
public:
|
||||
RadioButtonIcon(QWidget *parent = 0);
|
||||
RadioButtonIcon(const QIcon &icon, QWidget *parent = 0);
|
||||
~RadioButtonIcon();
|
||||
|
||||
inline void setIcon(const QIcon &icon) { _icon = icon; update(); }
|
||||
inline QIcon icon() const { return _icon; }
|
||||
|
||||
void setColor(const QColor &color);
|
||||
QColor color() const;
|
||||
|
||||
void setIconSize(int size);
|
||||
int iconSize() const;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(RadioButtonIcon)
|
||||
|
||||
QIcon _icon;
|
||||
int _iconSize;
|
||||
QGraphicsColorizeEffect *const _effect;
|
||||
};
|
||||
|
||||
#endif // RADIOBUTTON_INTERNAL_H
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define RADIOBUTTON_P_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QStateMachine>
|
||||
#include "radiobutton_internal.h"
|
||||
|
||||
class RadioButton;
|
||||
|
@ -17,11 +18,22 @@ public:
|
|||
|
||||
void init();
|
||||
|
||||
void assignAnimationProperties();
|
||||
void updatePalette();
|
||||
|
||||
RadioButton *const q_ptr;
|
||||
RippleOverlay *ripple;
|
||||
RadioButtonIcon *iconWidget;
|
||||
QIcon checkedIcon;
|
||||
QIcon uncheckedIcon;
|
||||
RadioButtonIcon *checkedIcon;
|
||||
RadioButtonIcon *uncheckedIcon;
|
||||
QStateMachine *machine;
|
||||
QState *uncheckedState;
|
||||
QState *checkedState;
|
||||
int iconSize;
|
||||
QColor checkedColor;
|
||||
QColor uncheckedColor;
|
||||
QColor textColor;
|
||||
QColor disabledColor;
|
||||
bool useThemeColors;
|
||||
};
|
||||
|
||||
#endif // RADIOBUTTON_P_H
|
||||
|
|
|
@ -17,13 +17,27 @@ RadioButtonExamples::RadioButtonExamples(QWidget *parent)
|
|||
RadioButton *radioButton1 = new RadioButton;
|
||||
RadioButton *radioButton2 = new RadioButton;
|
||||
RadioButton *radioButton3 = new RadioButton;
|
||||
RadioButton *radioButton4 = new RadioButton;
|
||||
RadioButton *radioButton5 = new RadioButton;
|
||||
|
||||
radioButton3->setCheckedIcon(QIcon("../qt-material-widgets/ic_star_black_24px.svg"));
|
||||
radioButton3->setUncheckedIcon(QIcon("../qt-material-widgets/ic_star_border_black_24px.svg"));
|
||||
radioButton3->setIconSize(30);
|
||||
|
||||
radioButton1->setText("Auto select");
|
||||
radioButton2->setText("Option #2");
|
||||
radioButton4->setText("Disabled option");
|
||||
radioButton5->setText("Disabled option (checked)");
|
||||
|
||||
bg->addButton(radioButton1);
|
||||
bg->addButton(radioButton2);
|
||||
bg->addButton(radioButton3);
|
||||
radioButton4->setDisabled(true);
|
||||
radioButton5->setDisabled(true);
|
||||
radioButton5->setChecked(true);
|
||||
|
||||
bg->addButton(radioButton1, 1);
|
||||
bg->addButton(radioButton2, 2);
|
||||
bg->addButton(radioButton3, 3);
|
||||
bg->addButton(radioButton4, 4);
|
||||
bg->addButton(radioButton5, 5);
|
||||
|
||||
QWidget *widget = new QWidget;
|
||||
QVBoxLayout *vbl = new QVBoxLayout;
|
||||
|
@ -38,6 +52,8 @@ RadioButtonExamples::RadioButtonExamples(QWidget *parent)
|
|||
vbl->addWidget(radioButton1);
|
||||
vbl->addWidget(radioButton2);
|
||||
vbl->addWidget(radioButton3);
|
||||
vbl->addWidget(radioButton4);
|
||||
vbl->addWidget(radioButton5);
|
||||
|
||||
ExampleView *view = new ExampleView;
|
||||
view->setWidget(widget);
|
||||
|
|
|
@ -15,7 +15,7 @@ RaisedButtonExamples::RaisedButtonExamples(QWidget *parent)
|
|||
raisedButton->setText("Press me!");
|
||||
raisedButton->setMaximumWidth(408);
|
||||
|
||||
raisedButton->setDisabled(true);
|
||||
//raisedButton->setDisabled(true);
|
||||
|
||||
//raisedButton->setDisabled(true);
|
||||
|
||||
|
|
Loading…
Reference in New Issue