2007-03-05 05:13:22 +01:00
|
|
|
/*
|
2007-08-06 13:20:02 +02:00
|
|
|
* Copyright 2007 by Siraj Razick <siraj@kde.org>
|
|
|
|
* Copyright 2007 by Matt Broadstone <mbroadst@gmail.com>
|
2007-03-05 05:13:22 +01:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
2007-09-14 22:17:11 +02:00
|
|
|
* it under the terms of the GNU Library General Public License as
|
2007-09-14 21:06:18 +02:00
|
|
|
* published by the Free Software Foundation; either version 2, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
2007-03-05 05:13:22 +01:00
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
* License along with this program; if not, write to the
|
|
|
|
* Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
2007-05-21 16:28:03 +02:00
|
|
|
#include "pushbutton.h"
|
|
|
|
|
2007-08-05 10:10:17 +02:00
|
|
|
#include <QStylePainter>
|
|
|
|
#include <QStyleOptionButton>
|
2007-03-05 05:13:22 +01:00
|
|
|
#include <QStyle>
|
|
|
|
#include <QWidget>
|
|
|
|
#include <QPainter>
|
2007-11-15 04:35:12 +01:00
|
|
|
#include <QGraphicsScene>
|
2007-03-05 05:13:22 +01:00
|
|
|
#include <QGraphicsSceneMouseEvent>
|
2007-07-23 00:16:40 +02:00
|
|
|
#include <QFontMetricsF>
|
|
|
|
#include <QApplication>
|
|
|
|
|
2007-03-05 05:13:22 +01:00
|
|
|
namespace Plasma
|
|
|
|
{
|
|
|
|
|
|
|
|
class PushButton::Private
|
|
|
|
{
|
2007-08-05 10:10:17 +02:00
|
|
|
public:
|
|
|
|
enum ButtonShape
|
|
|
|
{
|
|
|
|
Rectangle = 0,
|
|
|
|
Round,
|
|
|
|
Custom
|
|
|
|
};
|
|
|
|
|
|
|
|
enum ButtonState
|
|
|
|
{
|
|
|
|
None,
|
|
|
|
Hover,
|
|
|
|
Pressed,
|
|
|
|
Released
|
|
|
|
};
|
|
|
|
|
|
|
|
public:
|
|
|
|
Private()
|
|
|
|
: flat(false),
|
2007-10-04 19:36:21 +02:00
|
|
|
checkable(false),
|
|
|
|
checked(false),
|
2007-08-05 10:10:17 +02:00
|
|
|
state(None)
|
|
|
|
{}
|
|
|
|
|
|
|
|
void init(PushButton *button);
|
|
|
|
void initStyleOption(QStyleOptionButton *option, const PushButton *button,
|
|
|
|
const QStyleOptionGraphicsItem *graphicsOption = 0 ) const;
|
|
|
|
|
|
|
|
QString text;
|
|
|
|
KIcon icon;
|
|
|
|
QSizeF iconSize;
|
|
|
|
bool flat;
|
2007-10-04 19:36:21 +02:00
|
|
|
bool checkable;
|
|
|
|
bool checked;
|
2007-08-05 10:10:17 +02:00
|
|
|
ButtonState state;
|
2007-03-05 05:13:22 +01:00
|
|
|
};
|
|
|
|
|
2007-08-05 10:10:17 +02:00
|
|
|
void PushButton::Private::init(PushButton *button)
|
2007-03-05 05:13:22 +01:00
|
|
|
{
|
2007-08-05 10:10:17 +02:00
|
|
|
button->setAcceptedMouseButtons(Qt::LeftButton);
|
|
|
|
button->setAcceptsHoverEvents(true);
|
|
|
|
button->setEnabled(true);
|
|
|
|
}
|
2007-03-13 04:00:09 +01:00
|
|
|
|
2007-08-05 10:10:17 +02:00
|
|
|
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;
|
|
|
|
}
|
2007-07-23 00:16:40 +02:00
|
|
|
|
2007-08-05 10:10:17 +02:00
|
|
|
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
|
|
|
|
}
|
2007-07-23 00:16:40 +02:00
|
|
|
|
2007-08-05 10:10:17 +02:00
|
|
|
option->features = QStyleOptionButton::None;
|
|
|
|
if (flat) {
|
|
|
|
option->features |= QStyleOptionButton::Flat;
|
|
|
|
}
|
2007-10-04 19:36:21 +02:00
|
|
|
if (!flat && !(checked || state == Private::Pressed)) {
|
2007-08-05 10:10:17 +02:00
|
|
|
option->state |= QStyle::State_Raised;
|
|
|
|
} else {
|
|
|
|
option->state |= QStyle::State_Sunken;
|
|
|
|
}
|
|
|
|
option->text = text;
|
|
|
|
option->icon = icon;
|
|
|
|
option->iconSize = button->iconSize().toSize();
|
2007-03-05 05:13:22 +01:00
|
|
|
}
|
|
|
|
|
2007-08-05 10:10:17 +02:00
|
|
|
PushButton::PushButton(Widget *parent)
|
|
|
|
: Plasma::Widget(parent),
|
|
|
|
d(new Private)
|
2007-03-05 05:13:22 +01:00
|
|
|
{
|
2007-08-05 10:10:17 +02:00
|
|
|
d->init(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
PushButton::PushButton(const QString &text, Widget *parent)
|
|
|
|
: Plasma::Widget(parent),
|
|
|
|
d(new Private)
|
|
|
|
{
|
|
|
|
d->init(this);
|
|
|
|
setText(text);
|
2007-03-05 05:13:22 +01:00
|
|
|
}
|
|
|
|
|
2007-08-05 10:10:17 +02:00
|
|
|
PushButton::PushButton(const KIcon &icon, const QString &text, Widget *parent)
|
|
|
|
: Plasma::Widget(parent),
|
|
|
|
d(new Private)
|
2007-03-13 04:25:19 +01:00
|
|
|
{
|
2007-08-05 10:10:17 +02:00
|
|
|
d->init(this);
|
|
|
|
setText(text);
|
|
|
|
setIcon(icon);
|
2007-03-13 04:25:19 +01:00
|
|
|
}
|
|
|
|
|
2007-08-05 10:10:17 +02:00
|
|
|
PushButton::~PushButton()
|
2007-03-05 05:13:22 +01:00
|
|
|
{
|
2007-08-05 10:10:17 +02:00
|
|
|
delete d;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PushButton::paintWidget(QPainter *painter, const QStyleOptionGraphicsItem *opt, QWidget *widget)
|
|
|
|
{
|
|
|
|
QStyleOptionButton option;
|
2007-09-28 00:05:57 +02:00
|
|
|
if (widget) {
|
|
|
|
option.initFrom(widget);
|
|
|
|
}
|
2007-08-05 10:10:17 +02:00
|
|
|
d->initStyleOption(&option, this, opt);
|
2007-03-05 05:13:22 +01:00
|
|
|
|
2007-09-28 00:05:57 +02:00
|
|
|
QApplication::style()->drawPrimitive(QStyle::PE_PanelButtonCommand, &option, painter, widget);
|
|
|
|
QApplication::style()->drawPrimitive(QStyle::PE_FrameFocusRect, &option, painter, widget);
|
|
|
|
QApplication::style()->drawControl(QStyle::CE_PushButton, &option, painter, widget);
|
2007-08-05 10:10:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void PushButton::setText(const QString& text)
|
|
|
|
{
|
|
|
|
d->text = text;
|
|
|
|
update();
|
2007-03-05 05:13:22 +01:00
|
|
|
}
|
|
|
|
|
2007-03-13 04:00:09 +01:00
|
|
|
QString PushButton::text() const
|
2007-03-05 05:13:22 +01:00
|
|
|
{
|
2007-08-05 10:10:17 +02:00
|
|
|
return d->text;
|
2007-03-05 05:13:22 +01:00
|
|
|
}
|
2007-03-13 04:00:09 +01:00
|
|
|
|
2007-08-05 10:10:17 +02:00
|
|
|
void PushButton::setIcon(const KIcon &icon)
|
2007-03-05 13:54:54 +01:00
|
|
|
{
|
2007-08-05 10:10:17 +02:00
|
|
|
d->icon = icon;
|
|
|
|
update();
|
2007-03-05 13:54:54 +01:00
|
|
|
}
|
2007-03-13 04:00:09 +01:00
|
|
|
|
2007-08-05 10:10:17 +02:00
|
|
|
void PushButton::setIcon(const QString &path)
|
2007-03-05 05:13:22 +01:00
|
|
|
{
|
2007-08-05 10:10:17 +02:00
|
|
|
KIcon icon(path);
|
|
|
|
setIcon(icon);
|
2007-03-05 05:13:22 +01:00
|
|
|
}
|
|
|
|
|
2007-08-05 10:10:17 +02:00
|
|
|
KIcon PushButton::icon() const
|
2007-03-05 05:13:22 +01:00
|
|
|
{
|
2007-08-05 10:10:17 +02:00
|
|
|
return d->icon;
|
2007-03-13 03:51:40 +01:00
|
|
|
}
|
|
|
|
|
2007-08-05 10:10:17 +02:00
|
|
|
QSizeF PushButton::iconSize() const
|
2007-03-13 03:51:40 +01:00
|
|
|
{
|
2007-08-05 10:10:17 +02:00
|
|
|
if (d->iconSize.isValid())
|
|
|
|
return d->iconSize;
|
|
|
|
|
|
|
|
qreal metric = qreal(QApplication::style()->pixelMetric(QStyle::PM_ButtonIconSize));
|
|
|
|
return QSizeF(metric, metric);
|
2007-03-05 05:13:22 +01:00
|
|
|
}
|
2007-03-12 20:16:17 +01:00
|
|
|
|
2007-08-05 10:10:17 +02:00
|
|
|
void PushButton::setIconSize(const QSizeF &size)
|
2007-03-12 20:16:17 +01:00
|
|
|
{
|
2007-08-05 10:10:17 +02:00
|
|
|
if (d->iconSize == size)
|
|
|
|
return;
|
|
|
|
|
|
|
|
d->iconSize = size;
|
|
|
|
update();
|
2007-03-12 20:16:17 +01:00
|
|
|
}
|
|
|
|
|
2007-08-05 10:10:17 +02:00
|
|
|
bool PushButton::isDown() const
|
2007-03-12 20:16:17 +01:00
|
|
|
{
|
2007-08-05 10:10:17 +02:00
|
|
|
return (d->state == Private::Pressed);
|
|
|
|
}
|
2007-03-12 20:16:17 +01:00
|
|
|
|
2007-08-05 10:10:17 +02:00
|
|
|
bool PushButton::isFlat() const
|
|
|
|
{
|
|
|
|
return d->flat;
|
2007-03-12 20:16:17 +01:00
|
|
|
}
|
|
|
|
|
2007-08-05 10:10:17 +02:00
|
|
|
void PushButton::setFlat(bool flat)
|
2007-03-12 20:16:17 +01:00
|
|
|
{
|
2007-08-05 10:10:17 +02:00
|
|
|
d->flat = flat;
|
|
|
|
update();
|
2007-03-12 20:16:17 +01:00
|
|
|
}
|
|
|
|
|
2007-10-04 19:36:21 +02:00
|
|
|
bool PushButton::isChecked() const
|
|
|
|
{
|
|
|
|
return d->checked;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PushButton::setChecked(bool checked)
|
|
|
|
{
|
|
|
|
if (isCheckable()) {
|
|
|
|
d->checked = checked;
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PushButton::isCheckable() const
|
|
|
|
{
|
|
|
|
return d->checkable;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PushButton::setCheckable(bool checkable)
|
|
|
|
{
|
|
|
|
d->checkable = checkable;
|
|
|
|
}
|
|
|
|
|
2007-08-05 10:10:17 +02:00
|
|
|
void PushButton::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
2007-03-12 20:16:17 +01:00
|
|
|
{
|
2007-08-05 10:10:17 +02:00
|
|
|
event->accept();
|
|
|
|
d->state = Private::Pressed;
|
|
|
|
update();
|
2007-03-12 20:16:17 +01:00
|
|
|
}
|
2007-03-13 04:00:09 +01:00
|
|
|
|
2007-11-15 04:35:12 +01:00
|
|
|
void PushButton::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|
|
|
{
|
|
|
|
event->accept();
|
|
|
|
if (sceneBoundingRect().contains(event->scenePos())) {
|
|
|
|
if (d->state == Private::Released && scene()->mouseGrabberItem() == this) {
|
|
|
|
d->state = Private::Pressed;
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (d->state == Private::Pressed) {
|
|
|
|
d->state = Private::Released;
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-08-05 10:10:17 +02:00
|
|
|
void PushButton::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
2007-07-20 10:06:27 +02:00
|
|
|
{
|
2007-08-05 10:10:17 +02:00
|
|
|
event->accept();
|
2007-10-04 19:36:21 +02:00
|
|
|
if (d->state == Private::Pressed) {
|
|
|
|
d->state = Private::Released;
|
2007-11-15 04:35:12 +01:00
|
|
|
emit clicked();
|
2007-10-04 19:36:21 +02:00
|
|
|
|
2007-11-15 04:35:12 +01:00
|
|
|
if (d->checkable) {
|
|
|
|
d->checked = ! d->checked;
|
|
|
|
emit toggled(d->checked);
|
2007-10-04 19:36:21 +02:00
|
|
|
}
|
2007-11-15 04:35:12 +01:00
|
|
|
update();
|
2007-10-04 19:36:21 +02:00
|
|
|
}
|
2007-07-20 10:06:27 +02:00
|
|
|
}
|
|
|
|
|
2007-08-05 19:03:18 +02:00
|
|
|
QSizeF PushButton::minimumSize() const
|
|
|
|
{
|
|
|
|
QFontMetricsF m = qApp->fontMetrics();
|
|
|
|
return m.boundingRect(text()).size() + QSizeF(5.0f, 5.0f);
|
|
|
|
}
|
|
|
|
|
2008-02-29 18:50:57 +01:00
|
|
|
Qt::Orientations PushButton::expandingDirections() const
|
|
|
|
{
|
|
|
|
return Qt::Horizontal;
|
|
|
|
}
|
|
|
|
|
|
|
|
QSizeF PushButton::sizeHint() const
|
2007-08-05 19:03:18 +02:00
|
|
|
{
|
2007-08-13 08:32:31 +02:00
|
|
|
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);
|
|
|
|
|
|
|
|
QSize textSize = option.fontMetrics.size(Qt::TextShowMnemonic, display);
|
|
|
|
width += textSize.width();
|
|
|
|
height = qMax(height, textSize.height());
|
2007-10-04 19:36:21 +02:00
|
|
|
|
2007-08-13 08:32:31 +02:00
|
|
|
return QSizeF((QApplication::style()->sizeFromContents(QStyle::CT_PushButton, &option, QSize(width, height), 0).
|
|
|
|
expandedTo(QApplication::globalStrut())));
|
2007-08-05 19:03:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-05 05:13:22 +01:00
|
|
|
} // namespace Plasma
|
2007-08-05 10:10:17 +02:00
|
|
|
|
|
|
|
#include "pushbutton.moc"
|
|
|
|
|