1
/* This file is part of the KDE project
2
Copyright (c) 2007 Marijn Kruisselbrink <m.kruisselbrink@student.tue.nl>
3
Copyright (C) 2007 Thomas Zander <zander@kde.org>
5
This library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Library General Public
7
License as published by the Free Software Foundation; either
8
version 2 of the License, or (at your option) any later version.
10
This library is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Library General Public License for more details.
15
You should have received a copy of the GNU Library General Public License
16
along with this library; see the file COPYING.LIB. If not, write to
17
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18
Boston, MA 02110-1301, USA.
21
#include "KoDockWidgetTitleBar.h"
26
#include <QAbstractButton>
31
#include <QStylePainter>
32
#include <QStyleOptionFrame>
34
static inline bool hasFeature(const QDockWidget *dockwidget, QDockWidget::DockWidgetFeature feature)
36
return (dockwidget->features() & feature) == feature;
40
class KoDockWidgetTitleBarButton : public QAbstractButton
43
KoDockWidgetTitleBarButton(KoDockWidgetTitleBar *titleBar);
45
QSize sizeHint() const;
46
inline QSize minimumSizeHint() const {
50
virtual void enterEvent(QEvent *event);
51
virtual void leaveEvent(QEvent *event);
52
virtual void paintEvent(QPaintEvent *event);
58
KoDockWidgetTitleBarButton::KoDockWidgetTitleBarButton(KoDockWidgetTitleBar *titleBar)
59
: QAbstractButton(titleBar)
61
setFocusPolicy(Qt::NoFocus);
63
m_styleSize = QSize(0,0);
66
QSize KoDockWidgetTitleBarButton::sizeHint() const
70
const int margin = style()->pixelMetric(QStyle::PM_DockWidgetTitleBarButtonMargin, 0, this);
72
return QSize(margin, margin);
74
int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this);
75
if (iconSize != m_iconSize) {
76
const_cast<KoDockWidgetTitleBarButton*>(this)->m_iconSize = iconSize;
77
const QPixmap pm = icon().pixmap(iconSize);
78
const_cast<KoDockWidgetTitleBarButton*>(this)->m_styleSize = QSize(pm.width() + margin, pm.height() + margin);
83
// redraw the button when the mouse enters or leaves it
84
void KoDockWidgetTitleBarButton::enterEvent(QEvent *event)
86
if (isEnabled()) update();
87
QAbstractButton::enterEvent(event);
90
void KoDockWidgetTitleBarButton::leaveEvent(QEvent *event)
92
if (isEnabled()) update();
93
QAbstractButton::leaveEvent(event);
96
void KoDockWidgetTitleBarButton::paintEvent(QPaintEvent *)
101
QStyleOptionToolButton opt;
103
opt.state |= QStyle::State_AutoRaise;
105
if (isEnabled() && underMouse() && !isChecked() && !isDown())
106
opt.state |= QStyle::State_Raised;
108
opt.state |= QStyle::State_On;
110
opt.state |= QStyle::State_Sunken;
111
style()->drawPrimitive(QStyle::PE_PanelButtonTool, &opt, &p, this);
115
opt.activeSubControls = 0;
116
opt.features = QStyleOptionToolButton::None;
117
opt.arrowType = Qt::NoArrow;
118
int size = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this);
119
opt.iconSize = QSize(size, size);
120
style()->drawComplexControl(QStyle::CC_ToolButton, &opt, &p, this);
124
class KoDockWidgetTitleBar::Private
127
Private(KoDockWidgetTitleBar* thePublic) : thePublic(thePublic),
128
openIcon(thePublic->style()->standardIcon(QStyle::SP_TitleBarShadeButton)), closeIcon(thePublic->style()->standardIcon(QStyle::SP_TitleBarUnshadeButton)) {if (openIcon.isNull()) openIcon= KIcon("arrow-down");if (closeIcon.isNull()) closeIcon= KIcon("arrow-right");}
129
KoDockWidgetTitleBar* thePublic;
130
KIcon openIcon, closeIcon;
131
QAbstractButton* closeButton;
132
QAbstractButton* floatButton;
133
QAbstractButton* collapseButton;
135
void toggleFloating();
136
void toggleCollapsed();
137
void featuresChanged(QDockWidget::DockWidgetFeatures features);
140
KoDockWidgetTitleBar::KoDockWidgetTitleBar(QDockWidget* dockWidget)
141
: QWidget(dockWidget), d(new Private(this))
143
QDockWidget *q = dockWidget;
145
d->floatButton = new KoDockWidgetTitleBarButton(this);
146
d->floatButton->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarNormalButton, 0, q));
147
connect(d->floatButton, SIGNAL(clicked()), SLOT(toggleFloating()));
148
d->floatButton->setVisible(true);
150
d->closeButton = new KoDockWidgetTitleBarButton(this);
151
d->closeButton->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton, 0, q));
152
connect(d->closeButton, SIGNAL(clicked()), q, SLOT(close()));
153
d->closeButton->setVisible(true);
155
d->collapseButton = new KoDockWidgetTitleBarButton(this);
156
d->collapseButton->setIcon(d->openIcon);
157
connect(d->collapseButton, SIGNAL(clicked()), SLOT(toggleCollapsed()));
158
d->collapseButton->setVisible(true);
160
connect(dockWidget, SIGNAL(featuresChanged(QDockWidget::DockWidgetFeatures)), SLOT(featuresChanged(QDockWidget::DockWidgetFeatures)));
162
d->featuresChanged(0);
165
KoDockWidgetTitleBar::~KoDockWidgetTitleBar()
170
QSize KoDockWidgetTitleBar::minimumSizeHint() const
175
QSize KoDockWidgetTitleBar::sizeHint() const
177
QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget());
179
int mw = q->style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, 0, q);
180
int fw = q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, q);
182
// get size of buttons...
183
QSize closeSize(0, 0);
184
if (d->closeButton) {
185
closeSize = d->closeButton->sizeHint();
187
QSize floatSize(0, 0);
188
if (d->floatButton) {
189
floatSize = d->floatButton->sizeHint();
191
QSize hideSize(0, 0);
192
if (d->collapseButton) {
193
hideSize = d->collapseButton->sizeHint();
196
int buttonHeight = qMax(qMax(closeSize.height(), floatSize.height()), hideSize.height()) + 2;
197
int buttonWidth = closeSize.width() + floatSize.width() + hideSize.width();
200
QFontMetrics titleFontMetrics = q->fontMetrics();
201
int fontHeight = titleFontMetrics.lineSpacing() + 2 * mw;
203
int height = qMax(buttonHeight, fontHeight);
204
return QSize(buttonWidth + height + 4*mw + 2*fw, height);
207
void KoDockWidgetTitleBar::paintEvent(QPaintEvent*)
209
QStylePainter p(this);
211
QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget());
213
int fw = q->isFloating() ? q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, q) : 0;
214
int mw = q->style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, 0, q);
216
QStyleOptionDockWidgetV2 titleOpt;
217
titleOpt.initFrom(q);
218
titleOpt.rect = QRect(QPoint(fw + mw + d->collapseButton->size().width(), fw),
219
QSize(geometry().width() - (fw * 2) - mw - d->collapseButton->size().width(), geometry().height() - (fw * 2)));
220
titleOpt.title = q->windowTitle();
221
titleOpt.closable = hasFeature(q, QDockWidget::DockWidgetClosable);
222
titleOpt.floatable = hasFeature(q, QDockWidget::DockWidgetFloatable);
223
p.drawControl(QStyle::CE_DockWidgetTitle, titleOpt);
226
void KoDockWidgetTitleBar::resizeEvent(QResizeEvent*)
228
QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget());
229
int fw = q->isFloating() ? q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, q) : 0;
230
QStyleOptionDockWidgetV2 opt;
232
opt.rect = QRect(QPoint(fw, fw), QSize(geometry().width() - (fw * 2), geometry().height() - (fw * 2)));
233
opt.title = q->windowTitle();
234
opt.closable = hasFeature(q, QDockWidget::DockWidgetClosable);
235
opt.floatable = hasFeature(q, QDockWidget::DockWidgetFloatable);
237
QRect floatRect = q->style()->subElementRect(QStyle::SE_DockWidgetFloatButton, &opt, q);
238
if (!floatRect.isNull())
239
d->floatButton->setGeometry(floatRect);
241
QRect closeRect = q->style()->subElementRect(QStyle::SE_DockWidgetCloseButton, &opt, q);
242
if (!closeRect.isNull())
243
d->closeButton->setGeometry(closeRect);
246
if (!floatRect.isNull()) top = floatRect.y();
247
else if (!closeRect.isNull()) top = closeRect.y();
249
QSize size = d->collapseButton->size();
250
if (!closeRect.isNull()) {
251
size = d->closeButton->size();
252
} else if (!floatRect.isNull()) {
253
size = d->floatButton->size();
255
QRect collapseRect = QRect(QPoint(fw, top), size);
256
d->collapseButton->setGeometry(collapseRect);
259
void KoDockWidgetTitleBar::setCollapsed(bool collapsed)
261
QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget());
262
if (q && q->widget() && q->widget()->isHidden() != collapsed)
263
d->toggleCollapsed();
266
void KoDockWidgetTitleBar::Private::toggleFloating()
268
QDockWidget *q = qobject_cast<QDockWidget*>(thePublic->parentWidget());
270
q->setFloating(!q->isFloating());
273
void KoDockWidgetTitleBar::Private::toggleCollapsed()
275
QDockWidget *q = qobject_cast<QDockWidget*>(thePublic->parentWidget());
276
if (q == 0) // there does not *have* to be anything on the dockwidget.
278
q->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); // will be overwritten again next
279
q->widget()->setVisible(q->widget()->isHidden());
280
collapseButton->setIcon(q->widget()->isHidden() ? closeIcon : openIcon);
283
void KoDockWidgetTitleBar::Private::featuresChanged(QDockWidget::DockWidgetFeatures)
285
QDockWidget *q = qobject_cast<QDockWidget*>(thePublic->parentWidget());
286
closeButton->setVisible(hasFeature(q, QDockWidget::DockWidgetClosable));
287
floatButton->setVisible(hasFeature(q, QDockWidget::DockWidgetFloatable));
288
thePublic->resizeEvent(0);
290
#include "KoDockWidgetTitleBar.moc"