_much_ more complete version of the PushButton widget, also fully documented

svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=696541
This commit is contained in:
Matt Broadstone 2007-08-05 08:10:17 +00:00
parent f74b94a1d5
commit 2a2348b0e4
2 changed files with 280 additions and 189 deletions

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2007 by Siraj Razick siraj@kde.org
* Copyright (C) 2007 by Siraj Razick <siraj@kde.org>
* Copyright (C) 2007 by Matt Broadstone <mbroadst@gmail.com>
*
* 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 <QStyleOptionFrameV2>
#include <QStyleOption>
#include <QStylePainter>
#include <QStyleOptionButton>
#include <QStyle>
#include <QWidget>
#include <QPainter>
@ -27,47 +28,139 @@
#include <QFontMetricsF>
#include <QApplication>
#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"

View File

@ -1,6 +1,7 @@
/*
* Copyright (C) 2007 by Siraj Razick siraj@kde.org
* and Matias Valdenegro <mvaldenegro@informatica.utem.cl>
* Copyright (C) 2007 by Siraj Razick <siraj@kde.org>
* Copyright (C) 2007 by Matias Valdenegro <mvaldenegro@informatica.utem.cl>
* Copyright (C) 2007 by Matt Broadstone <mbroadst@gmail.com>
*
* 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 <QtGui/QGraphicsTextItem>
#include <QtGui/QLayoutItem>
#include <KIcon>
#include <plasma/dataengine.h>
#include <plasma/widgets/widget.h>
#include <plasma/plasma_export.h>
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;
};