1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the Qt 3 compatibility classes of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
29
#include "qplatformdefs.h"
31
#ifndef QT_NO_TITLEBAR
33
#include "qapplication.h"
35
#include "qdatetime.h"
39
#include "qiodevice.h"
42
#include "qstyleoption.h"
47
#include "qt_windows.h"
50
#include "private/qapplication_p.h"
51
#include "private/qinternal_p.h"
52
#include "private/q3titlebar_p.h"
53
#include "private/qwidget_p.h"
55
class Q3TitleBarPrivate : public QWidgetPrivate
57
Q_DECLARE_PUBLIC(Q3TitleBar)
60
: toolTip(0), act(0), window(0), movable(1), pressed(0), autoraise(0), inevent(0)
65
QStyle::SubControl buttonDown;
75
int titleBarState() const;
76
QStyleOptionTitleBar getStyleOption() const;
80
inline int Q3TitleBarPrivate::titleBarState() const
82
uint state = window ? window->windowState() : static_cast<Qt::WindowStates>(Qt::WindowNoState);
83
state |= uint(act ? QStyle::State_Active : QStyle::State_None);
87
QStyleOptionTitleBar Q3TitleBarPrivate::getStyleOption() const
89
Q_Q(const Q3TitleBar);
90
QStyleOptionTitleBar opt;
92
opt.text = q->windowTitle();
94
QIcon icon = q->windowIcon();
95
QSize s = icon.actualSize(QSize(64, 64));
96
opt.icon = icon.pixmap(s);
97
opt.subControls = QStyle::SC_All;
98
opt.activeSubControls = QStyle::SC_None;
99
opt.titleBarState = titleBarState();
100
opt.titleBarFlags = flags;
104
Q3TitleBar::Q3TitleBar(QWidget *w, QWidget *parent, Qt::WFlags f)
105
: QWidget(*new Q3TitleBarPrivate, parent, Qt::WStyle_Customize | Qt::WStyle_NoBorder)
109
f = w->windowFlags();
112
d->buttonDown = QStyle::SC_None;
115
if (w->minimumSize() == w->maximumSize())
116
d->flags &= ~Qt::WindowMaximizeButtonHint;
117
setWindowTitle(w->windowTitle());
121
setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
122
setMouseTracking(true);
123
setAutoRaise(style()->styleHint(QStyle::SH_TitleBar_AutoRaise, 0, this));
126
Q3TitleBar::~Q3TitleBar()
130
QStyleOptionTitleBar Q3TitleBar::getStyleOption() const
132
return d_func()->getStyleOption();
136
static inline QRgb colorref2qrgb(COLORREF col)
138
return qRgb(GetRValue(col),GetGValue(col),GetBValue(col));
142
void Q3TitleBarPrivate::readColors()
145
QPalette pal = q->palette();
147
bool colorsInitialized = false;
149
#ifdef Q_WS_WIN // ask system properties on windows
150
#ifndef SPI_GETGRADIENTCAPTIONS
151
#define SPI_GETGRADIENTCAPTIONS 0x1008
153
#ifndef COLOR_GRADIENTACTIVECAPTION
154
#define COLOR_GRADIENTACTIVECAPTION 27
156
#ifndef COLOR_GRADIENTINACTIVECAPTION
157
#define COLOR_GRADIENTINACTIVECAPTION 28
159
if (QApplication::desktopSettingsAware()) {
160
pal.setColor(QPalette::Active, QPalette::Highlight, colorref2qrgb(GetSysColor(COLOR_ACTIVECAPTION)));
161
pal.setColor(QPalette::Inactive, QPalette::Highlight, colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTION)));
162
pal.setColor(QPalette::Active, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_CAPTIONTEXT)));
163
pal.setColor(QPalette::Inactive, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTIONTEXT)));
164
if (QSysInfo::WindowsVersion != QSysInfo::WV_95 && QSysInfo::WindowsVersion != QSysInfo::WV_NT) {
165
colorsInitialized = true;
168
SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0);
170
SystemParametersInfoA(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0);
173
pal.setColor(QPalette::Active, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION)));
174
pal.setColor(QPalette::Inactive, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION)));
176
pal.setColor(QPalette::Active, QPalette::Base, pal.color(QPalette::Active, QPalette::Highlight));
177
pal.setColor(QPalette::Inactive, QPalette::Base, pal.color(QPalette::Inactive, QPalette::Highlight));
182
if (!colorsInitialized) {
183
pal.setColor(QPalette::Active, QPalette::Highlight,
184
pal.color(QPalette::Active, QPalette::Highlight));
185
pal.setColor(QPalette::Active, QPalette::Base,
186
pal.color(QPalette::Active, QPalette::Highlight));
187
pal.setColor(QPalette::Inactive, QPalette::Highlight,
188
pal.color(QPalette::Inactive, QPalette::Dark));
189
pal.setColor(QPalette::Inactive, QPalette::Base,
190
pal.color(QPalette::Inactive, QPalette::Dark));
191
pal.setColor(QPalette::Inactive, QPalette::HighlightedText,
192
pal.color(QPalette::Inactive, QPalette::Background));
199
void Q3TitleBar::changeEvent(QEvent *ev)
201
if(ev->type() == QEvent::ModifiedChange)
203
QWidget::changeEvent(ev);
206
void Q3TitleBar::mousePressEvent(QMouseEvent *e)
211
if (e->button() == Qt::LeftButton) {
213
QStyleOptionTitleBar opt = d->getStyleOption();
214
QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
217
case QStyle::SC_TitleBarSysMenu:
218
if (d->flags & Qt::WindowSystemMenuHint) {
219
d->buttonDown = QStyle::SC_None;
221
static Q3TitleBar *tc = 0;
224
if (tc != this || t->elapsed() > QApplication::doubleClickInterval()) {
225
emit showOperationMenu();
236
case QStyle::SC_TitleBarShadeButton:
237
case QStyle::SC_TitleBarUnshadeButton:
238
if (d->flags & Qt::WindowShadeButtonHint)
239
d->buttonDown = ctrl;
242
case QStyle::SC_TitleBarNormalButton:
243
if (d->flags & Qt::WindowMinMaxButtonsHint)
244
d->buttonDown = ctrl;
247
case QStyle::SC_TitleBarMinButton:
248
if (d->flags & Qt::WindowMinimizeButtonHint)
249
d->buttonDown = ctrl;
252
case QStyle::SC_TitleBarMaxButton:
253
if (d->flags & Qt::WindowMaximizeButtonHint)
254
d->buttonDown = ctrl;
257
case QStyle::SC_TitleBarCloseButton:
258
if (d->flags & Qt::WindowSystemMenuHint)
259
d->buttonDown = ctrl;
262
case QStyle::SC_TitleBarLabel:
263
d->buttonDown = ctrl;
264
d->moveOffset = mapToParent(e->pos());
276
void Q3TitleBar::contextMenuEvent(QContextMenuEvent *e)
279
QStyleOptionTitleBar opt = d->getStyleOption();
280
QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt, e->pos(),
282
if(ctrl == QStyle::SC_TitleBarLabel || ctrl == QStyle::SC_TitleBarSysMenu) {
284
emit popupOperationMenu(e->globalPos());
290
void Q3TitleBar::mouseReleaseEvent(QMouseEvent *e)
293
if (e->button() == Qt::LeftButton && d->pressed) {
295
QStyleOptionTitleBar opt = d->getStyleOption();
296
QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
299
if (ctrl == d->buttonDown) {
300
d->buttonDown = QStyle::SC_None;
303
case QStyle::SC_TitleBarShadeButton:
304
case QStyle::SC_TitleBarUnshadeButton:
305
if(d->flags & Qt::WindowShadeButtonHint)
309
case QStyle::SC_TitleBarNormalButton:
310
if(d->flags & Qt::WindowMaximizeButtonHint)
314
case QStyle::SC_TitleBarMinButton:
315
if(d->flags & Qt::WindowMinimizeButtonHint) {
316
if (d->window && d->window->isMinimized())
323
case QStyle::SC_TitleBarMaxButton:
324
if(d->flags & Qt::WindowMaximizeButtonHint) {
325
if(d->window && d->window->isMaximized())
332
case QStyle::SC_TitleBarCloseButton:
333
if(d->flags & Qt::WindowSystemMenuHint) {
334
d->buttonDown = QStyle::SC_None;
350
void Q3TitleBar::mouseMoveEvent(QMouseEvent *e)
354
switch (d->buttonDown) {
355
case QStyle::SC_None:
359
case QStyle::SC_TitleBarSysMenu:
361
case QStyle::SC_TitleBarShadeButton:
362
case QStyle::SC_TitleBarUnshadeButton:
363
case QStyle::SC_TitleBarNormalButton:
364
case QStyle::SC_TitleBarMinButton:
365
case QStyle::SC_TitleBarMaxButton:
366
case QStyle::SC_TitleBarCloseButton:
368
QStyle::SubControl last_ctrl = d->buttonDown;
369
QStyleOptionTitleBar opt = d->getStyleOption();
370
d->buttonDown = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt, e->pos(), this);
371
if (d->buttonDown != last_ctrl)
372
d->buttonDown = QStyle::SC_None;
374
d->buttonDown = last_ctrl;
378
case QStyle::SC_TitleBarLabel:
379
if (d->buttonDown == QStyle::SC_TitleBarLabel && d->movable && d->pressed) {
380
if ((d->moveOffset - mapToParent(e->pos())).manhattanLength() >= 4) {
381
QPoint p = mapFromGlobal(e->globalPos());
383
QWidget *parent = d->window ? d->window->parentWidget() : 0;
384
if(parent && parent->inherits("Q3WorkspaceChild")) {
385
QWidget *workspace = parent->parentWidget();
386
p = workspace->mapFromGlobal(e->globalPos());
387
if (!workspace->rect().contains(p)) {
392
if (p.x() > workspace->width())
393
p.rx() = workspace->width();
394
if (p.y() > workspace->height())
395
p.ry() = workspace->height();
399
QPoint pp = p - d->moveOffset;
400
if (!parentWidget()->isMaximized())
401
parentWidget()->move(pp);
404
QStyle::SubControl last_ctrl = d->buttonDown;
405
d->buttonDown = QStyle::SC_None;
406
if(d->buttonDown != last_ctrl)
415
void Q3TitleBar::resizeEvent(QResizeEvent *r)
417
QWidget::resizeEvent(r);
421
bool Q3TitleBar::isTool() const
423
return (d_func()->flags & Qt::WindowType_Mask) == Qt::Tool;
426
void Q3TitleBar::paintEvent(QPaintEvent *)
429
QStyleOptionTitleBar opt = d->getStyleOption();
430
opt.subControls = QStyle::SC_TitleBarLabel;
431
opt.activeSubControls = d->buttonDown;
432
if (d->flags & Qt::WindowSystemMenuHint) {
433
opt.subControls |= QStyle::SC_TitleBarSysMenu | QStyle::SC_TitleBarCloseButton;
434
if (d->window && (d->flags & Qt::WindowShadeButtonHint)) {
435
if (d->window->isMinimized())
436
opt.subControls |= QStyle::SC_TitleBarUnshadeButton;
438
opt.subControls |= QStyle::SC_TitleBarShadeButton;
440
if (d->window && (d->flags & Qt::WindowMinMaxButtonsHint)) {
441
if(d->window && d->window->isMinimized())
442
opt.subControls |= QStyle::SC_TitleBarNormalButton;
444
opt.subControls |= QStyle::SC_TitleBarMinButton;
446
if (d->window && (d->flags & Qt::WindowMaximizeButtonHint) && !d->window->isMaximized())
447
opt.subControls |= QStyle::SC_TitleBarMaxButton;
450
QStyle::SubControl under_mouse = QStyle::SC_None;
451
if(autoRaise() && underMouse()) {
452
under_mouse = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
453
mapFromGlobal(QCursor::pos()), this);
454
opt.activeSubControls |= under_mouse;
455
opt.state |= QStyle::State_MouseOver;
457
opt.palette.setCurrentColorGroup(usesActiveColor() ? QPalette::Active : QPalette::Inactive);
460
style()->drawComplexControl(QStyle::CC_TitleBar, &opt, &p, this);
463
void Q3TitleBar::mouseDoubleClickEvent(QMouseEvent *e)
466
if (e->button() != Qt::LeftButton) {
471
QStyleOptionTitleBar opt = d->getStyleOption();
472
switch (style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt, e->pos(), this)) {
473
case QStyle::SC_TitleBarLabel:
474
emit doubleClicked();
477
case QStyle::SC_TitleBarSysMenu:
478
if (d->flags & Qt::WStyle_SysMenu)
487
void Q3TitleBar::cutText()
490
QFontMetrics fm(font());
491
QStyleOptionTitleBar opt = d->getStyleOption();
492
int maxw = style()->subControlRect(QStyle::CC_TitleBar, &opt, QStyle::SC_TitleBarLabel,
497
QString txt = d->window->windowTitle();
498
if (style()->styleHint(QStyle::SH_TitleBar_ModifyNotification, 0, this) && d->window
499
&& d->window->isWindowModified())
502
QString cuttext = txt;
503
if (fm.width(txt + "m") > maxw) {
504
int i = txt.length();
505
int dotlength = fm.width("...");
506
while (i>0 && fm.width(txt.left(i)) + dotlength > maxw)
508
if(i != (int)txt.length())
509
cuttext = txt.left(i) + "...";
512
setWindowTitle(cuttext);
516
void Q3TitleBar::leaveEvent(QEvent *)
518
if(autoRaise() && !d_func()->pressed)
522
void Q3TitleBar::enterEvent(QEvent *)
524
if(autoRaise() && !d_func()->pressed)
526
QEvent e(QEvent::Leave);
527
QApplication::sendEvent(parentWidget(), &e);
530
void Q3TitleBar::setActive(bool active)
533
if (d->act == active)
540
bool Q3TitleBar::isActive() const
542
return d_func()->act;
545
bool Q3TitleBar::usesActiveColor() const
547
return (isActive() && isActiveWindow()) ||
548
(!window() && QWidget::window()->isActiveWindow());
551
QWidget *Q3TitleBar::window() const
553
return d_func()->window;
556
bool Q3TitleBar::event(QEvent *e)
560
return QWidget::event(e);
562
if (e->type() == QEvent::ApplicationPaletteChange) {
565
} else if (e->type() == QEvent::WindowActivate) {
567
} else if (e->type() == QEvent::WindowDeactivate) {
568
bool wasActive = d->act;
571
} else if (e->type() == QEvent::WindowIconChange) {
573
} else if (e->type() == QEvent::WindowTitleChange) {
579
return QWidget::event(e);
582
void Q3TitleBar::setMovable(bool b)
584
d_func()->movable = b;
587
bool Q3TitleBar::isMovable() const
589
return d_func()->movable;
592
void Q3TitleBar::setAutoRaise(bool b)
594
d_func()->autoraise = b;
597
bool Q3TitleBar::autoRaise() const
599
return d_func()->autoraise;
602
QSize Q3TitleBar::sizeHint() const
605
QStyleOptionTitleBar opt = d_func()->getStyleOption();
606
QRect menur = style()->subControlRect(QStyle::CC_TitleBar, &opt,
607
QStyle::SC_TitleBarSysMenu, this);
608
return QSize(menur.width(), style()->pixelMetric(QStyle::PM_TitleBarHeight, &opt, this));
611
#endif //QT_NO_TITLEBAR