From 2a2348b0e421468bfd1fbe3c50dc66007a1781cc Mon Sep 17 00:00:00 2001 From: Matt Broadstone Date: Sun, 5 Aug 2007 08:10:17 +0000 Subject: [PATCH] _much_ more complete version of the PushButton widget, also fully documented svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=696541 --- widgets/pushbutton.cpp | 292 ++++++++++++++++++++++++++--------------- widgets/pushbutton.h | 177 +++++++++++++------------ 2 files changed, 280 insertions(+), 189 deletions(-) diff --git a/widgets/pushbutton.cpp b/widgets/pushbutton.cpp index ea102992f..66256b850 100644 --- a/widgets/pushbutton.cpp +++ b/widgets/pushbutton.cpp @@ -1,5 +1,6 @@ /* - * Copyright (C) 2007 by Siraj Razick siraj@kde.org + * Copyright (C) 2007 by Siraj Razick + * Copyright (C) 2007 by Matt Broadstone * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License version 2 as @@ -18,8 +19,8 @@ #include "pushbutton.h" -#include -#include +#include +#include #include #include #include @@ -27,47 +28,139 @@ #include #include -#include "pushbutton.moc" - namespace Plasma { class PushButton::Private { - public: - Private() {} - ~Private() {} +public: + enum ButtonShape + { + Rectangle = 0, + Round, + Custom + }; - QString labelText; - QString labelIcon; - QColor labelTextColor; - QIcon icon; - QSize iconSize; - bool hasIcon; - int labelTextOpacity; - int radius; - QTimer *updateTimer; - PushButton::ButtonState state; + enum ButtonState + { + None, + Hover, + Pressed, + Released + }; + +public: + Private() + : flat(false), + state(None) + {} + + void init(PushButton *button); + void initStyleOption(QStyleOptionButton *option, const PushButton *button, + const QStyleOptionGraphicsItem *graphicsOption = 0 ) const; + + QString text; + KIcon icon; + QSizeF iconSize; + QSizeF size; + bool flat; + ButtonState state; }; +void PushButton::Private::init(PushButton *button) +{ + button->setAcceptedMouseButtons(Qt::LeftButton); + button->setAcceptsHoverEvents(true); + button->setEnabled(true); +} + +void PushButton::Private::initStyleOption(QStyleOptionButton *option, const PushButton *button, + const QStyleOptionGraphicsItem *graphicsOption) const +{ + option->state = QStyle::State_None; + if (button->isEnabled()) { + option->state |= QStyle::State_Enabled; + } + if (button->hasFocus()) { + option->state |= QStyle::State_HasFocus; + } + if (state == Private::Hover) { + option->state |= QStyle::State_MouseOver; + } + + if (graphicsOption) { + option->palette = graphicsOption->palette; + option->fontMetrics = graphicsOption->fontMetrics; + option->rect = graphicsOption->rect; + } else { + option->palette = QApplication::palette(); // pretty good guess + option->fontMetrics = QApplication::fontMetrics(); // hrm + } + + option->features = QStyleOptionButton::None; + if (flat) { + option->features |= QStyleOptionButton::Flat; + } + if (!flat && !(state == Private::Pressed)) { + option->state |= QStyle::State_Raised; + } else { + option->state |= QStyle::State_Sunken; + } + option->text = text; + option->icon = icon; + option->iconSize = button->iconSize().toSize(); +} + PushButton::PushButton(Widget *parent) : Plasma::Widget(parent), d(new Private) { - setAcceptedMouseButtons(Qt::LeftButton); - setAcceptsHoverEvents(true); - setEnabled(true); + d->init(this); +} - resize(40.0f, 100.0f); - setPos(QPointF(0.0,0.0)); +PushButton::PushButton(const QString &text, Widget *parent) + : Plasma::Widget(parent), + d(new Private) +{ + d->init(this); + setText(text); +} - /*FIXME: Don't use hardcoded strings and colors. */ +PushButton::PushButton(const KIcon &icon, const QString &text, Widget *parent) + : Plasma::Widget(parent), + d(new Private) +{ + d->init(this); + setText(text); + setIcon(icon); +} - d->state = PushButton::None; - d->labelText = QString("Plasma"); - d->labelTextColor = QColor(201, 201, 255); - d->hasIcon = false; - d->iconSize = QSize(32,32); +QRectF PushButton::boundingRect() const +{ + if (!d->size.isValid()) { + int width = 0; + int height = 0; + + QStyleOptionButton option; + d->initStyleOption(&option, this); + + if (!icon().isNull()) { + height += qMax(option.iconSize.height(), height); + width += 2 + option.iconSize.width() + 2; // add margin + } + + QString display(option.text); + if (display.isEmpty()) + display = "Plasma"; + + QSize textSize = option.fontMetrics.size(Qt::TextShowMnemonic, display); + width += textSize.width(); + height = qMax(height, textSize.height()); + d->size = QSizeF((QApplication::style()->sizeFromContents(QStyle::CT_PushButton, &option, QSize(width, height), 0). + expandedTo(QApplication::globalStrut()))); + } + + return QRectF(QPointF(0.0, 0.0), d->size); } PushButton::~PushButton() @@ -75,112 +168,99 @@ PushButton::~PushButton() delete d; } -void PushButton::updated(const QString&, const DataEngine::Data &data) +void PushButton::paintWidget(QPainter *painter, const QStyleOptionGraphicsItem *opt, QWidget *widget) { - Q_UNUSED(data) -} + QStyleOptionButton option; + option.initFrom(widget); + d->initStyleOption(&option, this, opt); -void PushButton::paintWidget(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) -{ - QStyleOptionButton options; - options.initFrom(widget); - options.state = option->state; - options.state |= isDown() ? QStyle::State_Sunken : QStyle::State_Raised; - options.rect = boundingRect().toRect(); - options.text = text(); - - if (d->hasIcon) - { - options.icon= d->icon; - options.iconSize = d->iconSize; - } - - widget->style()->drawPrimitive(QStyle::PE_PanelButtonCommand, &options, painter, widget); - widget->style()->drawPrimitive(QStyle::PE_FrameFocusRect, &options, painter, widget); - widget->style()->drawControl(QStyle::CE_PushButton, &options, painter, widget); + widget->style()->drawPrimitive(QStyle::PE_PanelButtonCommand, &option, painter, widget); + widget->style()->drawPrimitive(QStyle::PE_FrameFocusRect, &option, painter, widget); + widget->style()->drawControl(QStyle::CE_PushButton, &option, painter, widget); } void PushButton::setText(const QString& text) { - d->labelText = text; -/* - QFont * font = new QFont (text); - QFontMetrics * fm = new QFontMetrics(*font); - if (fm->width(text) >= d->width) - setWidth(fm->width(d->labelText) + 4); - delete fm; - delete font; -*/ - + d->text = text; + d->size = QSizeF(); + update(); } QString PushButton::text() const { - return d->labelText; + return d->text; } -void PushButton::setIcon(const QString& path) +void PushButton::setIcon(const KIcon &icon) { - if (!path.isNull()) - { - QPixmap iconPixmap(path); - d->icon = QIcon(iconPixmap); - d->iconSize = iconPixmap.size(); - d->hasIcon=true; - } - else - d->hasIcon = false; + d->icon = icon; + d->size = QSizeF(); + update(); } -bool PushButton::isDown() +void PushButton::setIcon(const QString &path) { - if (d->state == PushButton::Pressed) - return true; - return false; + KIcon icon(path); + setIcon(icon); +} + +KIcon PushButton::icon() const +{ + return d->icon; +} + +QSizeF PushButton::iconSize() const +{ + if (d->iconSize.isValid()) + return d->iconSize; + + qreal metric = qreal(QApplication::style()->pixelMetric(QStyle::PM_ButtonIconSize)); + return QSizeF(metric, metric); +} + +void PushButton::setIconSize(const QSizeF &size) +{ + if (d->iconSize == size) + return; + + d->iconSize = size; + d->size = QSizeF(); + update(); +} + +bool PushButton::isDown() const +{ + return (d->state == Private::Pressed); +} + +bool PushButton::isFlat() const +{ + return d->flat; +} + +void PushButton::setFlat(bool flat) +{ + d->flat = flat; + update(); } void PushButton::mousePressEvent(QGraphicsSceneMouseEvent *event) { event->accept(); - d->state = PushButton::Pressed; + d->state = Private::Pressed; update(); -// emit clicked(); } void PushButton::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { event->accept(); - if (d->state == PushButton::Pressed) + if (d->state == Private::Pressed) emit clicked(); - d->state = PushButton::Released; + d->state = Private::Released; update(); } -QSizeF PushButton::sizeHint() const -{ - return minimumSize(); -} - -QSizeF PushButton::minimumSize() const -{ - QFontMetricsF m = qApp->fontMetrics(); - - return m.boundingRect(text()).size() + QSizeF(5.0f, 5.0f); -} - -QSizeF PushButton::maximumSize() const -{ - return QSizeF(); -} - -Qt::Orientations PushButton::expandingDirections() const -{ - return Qt::Horizontal; -} - -bool PushButton::isEmpty() const -{ - return false; -} - } // namespace Plasma + +#include "pushbutton.moc" + diff --git a/widgets/pushbutton.h b/widgets/pushbutton.h index f0996b271..a6714e0c5 100644 --- a/widgets/pushbutton.h +++ b/widgets/pushbutton.h @@ -1,6 +1,7 @@ /* - * Copyright (C) 2007 by Siraj Razick siraj@kde.org - * and Matias Valdenegro + * Copyright (C) 2007 by Siraj Razick + * Copyright (C) 2007 by Matias Valdenegro + * Copyright (C) 2007 by Matt Broadstone * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License version 2 as @@ -16,7 +17,6 @@ * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - #ifndef PUSHBUTTON_H #define PUSHBUTTON_H @@ -24,120 +24,131 @@ #include #include +#include + #include #include #include +class QStyleOptionButton; namespace Plasma { /** * Class that emulates a QPushButton inside Plasma * - * @author Siraj Razick and Matias Valdenegro. + * @author Siraj Razick + * @author Matias Valdenegro + * @author Matt Broadstone * * */ class PLASMA_EXPORT PushButton : public Plasma::Widget { Q_OBJECT - Q_ENUMS( ButtonShape ) - Q_ENUMS( ButtonState ) Q_PROPERTY( QString text READ text WRITE setText ) - Q_PROPERTY( QString icon WRITE setIcon ) + Q_PROPERTY( QSizeF iconSize READ iconSize WRITE setIconSize ) + Q_PROPERTY( KIcon icon READ icon WRITE setIcon ) +public: + /** + * Creates a new Plasma::PushButton. + * @param parent the Widge this button is parented to. + */ + explicit PushButton(Widget *parent = 0); - public: - enum ButtonShape - { - Rectangle = 0, - Round, - Custom - }; + /** + * Creates a new Plasma::PushButton with a text label. + * @param text the text to display next to the button. + * @param parent the QGraphicsItem this icon is parented to. + */ + explicit PushButton(const QString &text, Widget *parent = 0); - enum ButtonState - { - None, - Hover, - Pressed, - Released - }; + /** + * Creates a new Plasma::PushButton with an icon and text + * @param icon the icon to display with this button. + * @param text the text to display with this button. + * @param parent the QGraphicsItem this icon is parented to. + */ + explicit PushButton(const KIcon &icon, const QString &text, Widget *parent = 0); - public: + /** + * Destroys this Plasma::PushButton. + */ + virtual ~PushButton(); - /** - * Constructor. - */ - PushButton(Widget *parent = 0); + /** + * @return text associated with this Plasma::PushButton + */ + Q_INVOKABLE QString text() const; - /** - * Virtual Destructor. - */ - virtual ~PushButton(); + /** + * Sets the text to be displayed by this button. + * @param text the text to display + */ + Q_INVOKABLE void setText(const QString &text); - /** - * Returns the text of this Button. - */ - QString text() const; + /** + * @return the icon displayed by this button. + */ + Q_INVOKABLE KIcon icon() const; - /** - * Sets the text of this Button. - */ - void setText(const QString &text); + /** + * Sets the icon to be displayed by this Plasma::Icon. + * @param icon the KIcon to display. + */ + Q_INVOKABLE void setIcon(const KIcon &icon); - /** - * Sets the icon of this Button. - * @param path Path to the icon file. TODO : WTF is path? - */ - void setIcon(const QString& path); + /** + * Convenience method to set the icon of this Plasma::PushButton + * based on the icon path, or name. + * @see KIconLoader + * @param path the path to, or name of the icon to display. + */ + Q_INVOKABLE void setIcon(const QString& path); - /** - * Paint function. - */ - virtual void paintWidget(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + /** + * @return the size of the icon displayed by this Plasma::PushButton. + */ + Q_INVOKABLE QSizeF iconSize() const; - /** - * Reimplemented from Plasma::Widget. - */ - virtual QSizeF sizeHint() const ; + /** + * Sets the size of icon shown by this button. + * @param size size of the icon. + */ + Q_INVOKABLE void setIconSize(const QSizeF &size); - /** - * Reimplemented from Plasma::Widget. - */ - virtual QSizeF minimumSize() const; + /** + * @return whether this button is currently in a down/pressed state. + */ + bool isDown() const; - /** - * Reimplemented from Plasma::Widget. - */ - virtual QSizeF maximumSize() const ; + /** + * @return whether this button is drawn flat. + */ + bool isFlat() const; - /** - * Buttons prefer to expand in Horizontal direction. - */ - virtual Qt::Orientations expandingDirections() const; + /** + * Sets whether the button is drawn flat. + * @param flat whether to draw it flat or not. + */ + void setFlat(bool flat); - /** - * TODO: What does this function do? - */ - virtual bool isEmpty() const; +Q_SIGNALS: + /** + * Triggered when the button has been clicked. + */ + void clicked(); - Q_SIGNALS: +protected: + void mousePressEvent(QGraphicsSceneMouseEvent *event); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); - /** - * Triggers whatever this button is clicked. - */ - void clicked(); + void paintWidget(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + QRectF boundingRect() const; - public Q_SLOTS: - void updated(const QString&, const DataEngine::Data &); - - protected: - bool isDown(); - void mousePressEvent(QGraphicsSceneMouseEvent *event); - void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); - - private: - class Private ; - Private * const d; +private: + class Private ; + Private * const d; };