[2] | 1 | /****************************************************************************
|
---|
| 2 | ** $Id: qtitlebar.cpp 8 2005-11-16 19:36:46Z dmik $
|
---|
| 3 | **
|
---|
| 4 | ** Implementation of some Qt private functions.
|
---|
| 5 | **
|
---|
| 6 | ** Created : 001101
|
---|
| 7 | **
|
---|
| 8 | ** Copyright (C) 2000-2003 Trolltech AS. All rights reserved.
|
---|
| 9 | **
|
---|
| 10 | ** This file is part of the widgets module of the Qt GUI Toolkit.
|
---|
| 11 | **
|
---|
| 12 | ** This file may be distributed under the terms of the Q Public License
|
---|
| 13 | ** as defined by Trolltech AS of Norway and appearing in the file
|
---|
| 14 | ** LICENSE.QPL included in the packaging of this file.
|
---|
| 15 | **
|
---|
| 16 | ** This file may be distributed and/or modified under the terms of the
|
---|
| 17 | ** GNU General Public License version 2 as published by the Free Software
|
---|
| 18 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
| 19 | ** packaging of this file.
|
---|
| 20 | **
|
---|
| 21 | ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
|
---|
| 22 | ** licenses may use this file in accordance with the Qt Commercial License
|
---|
| 23 | ** Agreement provided with the Software.
|
---|
| 24 | **
|
---|
| 25 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
---|
| 26 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
---|
| 27 | **
|
---|
| 28 | ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
|
---|
| 29 | ** information about Qt Commercial License Agreements.
|
---|
| 30 | ** See http://www.trolltech.com/qpl/ for QPL licensing information.
|
---|
| 31 | ** See http://www.trolltech.com/gpl/ for GPL licensing information.
|
---|
| 32 | **
|
---|
| 33 | ** Contact info@trolltech.com if any conditions of this licensing are
|
---|
| 34 | ** not clear to you.
|
---|
| 35 | **
|
---|
| 36 | **********************************************************************/
|
---|
| 37 |
|
---|
| 38 | #include "qplatformdefs.h"
|
---|
| 39 |
|
---|
| 40 | #include "qtitlebar_p.h"
|
---|
| 41 |
|
---|
| 42 | #ifndef QT_NO_TITLEBAR
|
---|
| 43 |
|
---|
| 44 | #include <qcursor.h>
|
---|
| 45 | #include "qapplication.h"
|
---|
| 46 | #include "qstyle.h"
|
---|
| 47 | #include "qdatetime.h"
|
---|
| 48 | #include "private/qapplication_p.h"
|
---|
| 49 | #include "qtooltip.h"
|
---|
| 50 | #include "qimage.h"
|
---|
| 51 | #include "qtimer.h"
|
---|
| 52 | #include "qpainter.h"
|
---|
| 53 | #include "qstyle.h"
|
---|
| 54 | #include "private/qinternal_p.h"
|
---|
| 55 | #ifndef QT_NO_WORKSPACE
|
---|
| 56 | #include "qworkspace.h"
|
---|
| 57 | #endif
|
---|
| 58 | #if defined(Q_WS_WIN)
|
---|
| 59 | #include "qt_windows.h"
|
---|
[8] | 60 | #elif defined(Q_WS_PM)
|
---|
| 61 | #include "qt_os2.h"
|
---|
[2] | 62 | #endif
|
---|
| 63 |
|
---|
| 64 | #ifndef QT_NO_TOOLTIP
|
---|
| 65 | class QTitleBarTip : public QToolTip
|
---|
| 66 | {
|
---|
| 67 | public:
|
---|
| 68 | QTitleBarTip( QWidget * parent ) : QToolTip( parent ) { }
|
---|
| 69 |
|
---|
| 70 | void maybeTip( const QPoint &pos )
|
---|
| 71 | {
|
---|
| 72 | if ( !::qt_cast<QTitleBar*>(parentWidget()) )
|
---|
| 73 | return;
|
---|
| 74 | QTitleBar *t = (QTitleBar *)parentWidget();
|
---|
| 75 |
|
---|
| 76 | QString tipstring;
|
---|
| 77 | QStyle::SubControl ctrl = t->style().querySubControl(QStyle::CC_TitleBar, t, pos);
|
---|
| 78 | QSize controlSize = t->style().querySubControlMetrics(QStyle::CC_TitleBar, t, ctrl).size();
|
---|
| 79 |
|
---|
| 80 | QWidget *window = t->window();
|
---|
| 81 | if ( window ) {
|
---|
| 82 | switch(ctrl) {
|
---|
| 83 | case QStyle::SC_TitleBarSysMenu:
|
---|
| 84 | if ( t->testWFlags( WStyle_SysMenu ) )
|
---|
| 85 | tipstring = QTitleBar::tr( "System Menu" );
|
---|
| 86 | break;
|
---|
| 87 |
|
---|
| 88 | case QStyle::SC_TitleBarShadeButton:
|
---|
| 89 | if ( t->testWFlags( WStyle_Tool ) && t->testWFlags( WStyle_MinMax ) )
|
---|
| 90 | tipstring = QTitleBar::tr( "Shade" );
|
---|
| 91 | break;
|
---|
| 92 |
|
---|
| 93 | case QStyle::SC_TitleBarUnshadeButton:
|
---|
| 94 | if ( t->testWFlags( WStyle_Tool ) && t->testWFlags( WStyle_MinMax ) )
|
---|
| 95 | tipstring = QTitleBar::tr( "Unshade" );
|
---|
| 96 | break;
|
---|
| 97 |
|
---|
| 98 | case QStyle::SC_TitleBarNormalButton:
|
---|
| 99 | case QStyle::SC_TitleBarMinButton:
|
---|
| 100 | if ( !t->testWFlags( WStyle_Tool ) && t->testWFlags( WStyle_Minimize ) ) {
|
---|
| 101 | if( window->isMinimized() )
|
---|
| 102 | tipstring = QTitleBar::tr( "Normalize" );
|
---|
| 103 | else
|
---|
| 104 | tipstring = QTitleBar::tr( "Minimize" );
|
---|
| 105 | }
|
---|
| 106 | break;
|
---|
| 107 |
|
---|
| 108 | case QStyle::SC_TitleBarMaxButton:
|
---|
| 109 | if ( !t->testWFlags( WStyle_Tool ) && t->testWFlags( WStyle_Maximize ) )
|
---|
| 110 | tipstring = QTitleBar::tr( "Maximize" );
|
---|
| 111 | break;
|
---|
| 112 |
|
---|
| 113 | case QStyle::SC_TitleBarCloseButton:
|
---|
| 114 | if ( t->testWFlags( WStyle_SysMenu ) )
|
---|
| 115 | tipstring = QTitleBar::tr( "Close" );
|
---|
| 116 | break;
|
---|
| 117 |
|
---|
| 118 | default:
|
---|
| 119 | break;
|
---|
| 120 | }
|
---|
| 121 | }
|
---|
| 122 | #ifndef QT_NO_WIDGET_TOPEXTRA
|
---|
| 123 | if ( tipstring.isEmpty() ) {
|
---|
| 124 | if ( t->visibleText() != t->caption() )
|
---|
| 125 | tipstring = t->caption();
|
---|
| 126 | }
|
---|
| 127 | #endif
|
---|
| 128 | if(!tipstring.isEmpty())
|
---|
| 129 | tip( QRect(pos, controlSize), tipstring );
|
---|
| 130 | }
|
---|
| 131 | };
|
---|
| 132 | #endif
|
---|
| 133 |
|
---|
| 134 | class QTitleBarPrivate
|
---|
| 135 | {
|
---|
| 136 | public:
|
---|
| 137 | QTitleBarPrivate()
|
---|
| 138 | : toolTip( 0 ), act( 0 ), window( 0 ), movable( 1 ), pressed( 0 ), autoraise(0)
|
---|
| 139 | {
|
---|
| 140 | }
|
---|
| 141 |
|
---|
| 142 | QStyle::SCFlags buttonDown;
|
---|
| 143 | QPoint moveOffset;
|
---|
| 144 | QToolTip *toolTip;
|
---|
| 145 | bool act :1;
|
---|
| 146 | QWidget* window;
|
---|
| 147 | bool movable :1;
|
---|
| 148 | bool pressed :1;
|
---|
| 149 | bool autoraise :1;
|
---|
| 150 | QString cuttext;
|
---|
| 151 | #ifdef QT_NO_WIDGET_TOPEXTRA
|
---|
| 152 | QString cap;
|
---|
| 153 | #endif
|
---|
| 154 | };
|
---|
| 155 |
|
---|
| 156 | QTitleBar::QTitleBar(QWidget* w, QWidget* parent, const char* name)
|
---|
| 157 | : QWidget( parent, name, WStyle_Customize | WStyle_NoBorder | WNoAutoErase )
|
---|
| 158 | {
|
---|
| 159 | d = new QTitleBarPrivate();
|
---|
| 160 |
|
---|
| 161 | #ifndef QT_NO_TOOLTIP
|
---|
| 162 | d->toolTip = new QTitleBarTip( this );
|
---|
| 163 | #endif
|
---|
| 164 | d->window = w;
|
---|
| 165 | d->buttonDown = QStyle::SC_None;
|
---|
| 166 | d->act = 0;
|
---|
| 167 | if ( w ) {
|
---|
| 168 | setWFlags( ((QTitleBar*)w)->getWFlags() | WNoAutoErase );
|
---|
| 169 | if ( w->minimumSize() == w->maximumSize() )
|
---|
| 170 | clearWFlags( WStyle_Maximize );
|
---|
| 171 | #ifndef QT_NO_WIDGET_TOPEXTRA
|
---|
| 172 | setCaption( w->caption() );
|
---|
| 173 | #endif
|
---|
| 174 | } else {
|
---|
| 175 | setWFlags( WStyle_Customize | WNoAutoErase );
|
---|
| 176 | }
|
---|
| 177 |
|
---|
| 178 | readColors();
|
---|
| 179 | setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
|
---|
| 180 | setMouseTracking(TRUE);
|
---|
| 181 | }
|
---|
| 182 |
|
---|
| 183 | QTitleBar::~QTitleBar()
|
---|
| 184 | {
|
---|
| 185 | #ifndef QT_NO_TOOLTIP
|
---|
| 186 | delete d->toolTip;
|
---|
| 187 | #endif
|
---|
| 188 |
|
---|
| 189 | delete d;
|
---|
| 190 | d = 0;
|
---|
| 191 | }
|
---|
| 192 |
|
---|
[8] | 193 | #if defined (Q_WS_WIN)
|
---|
[2] | 194 | extern QRgb qt_colorref2qrgb(COLORREF col);
|
---|
[8] | 195 | #elif defined (Q_WS_PM)
|
---|
| 196 | extern QRgb qt_sysclr2qrgb( LONG sysClr );
|
---|
[2] | 197 | #endif
|
---|
| 198 |
|
---|
| 199 | void QTitleBar::readColors()
|
---|
| 200 | {
|
---|
| 201 | QPalette pal = palette();
|
---|
| 202 |
|
---|
[8] | 203 | #if defined (Q_WS_PM)
|
---|
| 204 | // we always use PM system colors for titlebars (regardless of
|
---|
| 205 | // QApplication::desktopSettingsAware()), because the simulation will
|
---|
| 206 | // most likely produce the same color both for an active and inactive title.
|
---|
| 207 | pal.setColor( QPalette::Active, QColorGroup::Highlight,
|
---|
| 208 | QColor( qt_sysclr2qrgb( SYSCLR_ACTIVETITLE ) ) );
|
---|
| 209 | pal.setColor( QPalette::Active, QColorGroup::Base,
|
---|
| 210 | pal.active().highlight() );
|
---|
| 211 | pal.setColor( QPalette::Active, QColorGroup::HighlightedText,
|
---|
| 212 | QColor( qt_sysclr2qrgb( SYSCLR_ACTIVETITLETEXT ) ) );
|
---|
| 213 | pal.setColor( QPalette::Inactive, QColorGroup::Highlight,
|
---|
| 214 | QColor( qt_sysclr2qrgb( SYSCLR_INACTIVETITLE ) ) );
|
---|
| 215 | pal.setColor( QPalette::Inactive, QColorGroup::Base,
|
---|
| 216 | pal.inactive().highlight() );
|
---|
| 217 | pal.setColor( QPalette::Inactive, QColorGroup::HighlightedText,
|
---|
| 218 | QColor( qt_sysclr2qrgb( SYSCLR_INACTIVETITLETEXT ) ) );
|
---|
| 219 | #else
|
---|
| 220 |
|
---|
[2] | 221 | bool colorsInitialized = FALSE;
|
---|
| 222 |
|
---|
| 223 | #ifdef Q_WS_WIN // ask system properties on windows
|
---|
| 224 | #ifndef SPI_GETGRADIENTCAPTIONS
|
---|
| 225 | #define SPI_GETGRADIENTCAPTIONS 0x1008
|
---|
| 226 | #endif
|
---|
| 227 | #ifndef COLOR_GRADIENTACTIVECAPTION
|
---|
| 228 | #define COLOR_GRADIENTACTIVECAPTION 27
|
---|
| 229 | #endif
|
---|
| 230 | #ifndef COLOR_GRADIENTINACTIVECAPTION
|
---|
| 231 | #define COLOR_GRADIENTINACTIVECAPTION 28
|
---|
| 232 | #endif
|
---|
| 233 | if ( QApplication::desktopSettingsAware() ) {
|
---|
| 234 | pal.setColor( QPalette::Active, QColorGroup::Highlight, qt_colorref2qrgb(GetSysColor(COLOR_ACTIVECAPTION)) );
|
---|
| 235 | pal.setColor( QPalette::Inactive, QColorGroup::Highlight, qt_colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTION)) );
|
---|
| 236 | pal.setColor( QPalette::Active, QColorGroup::HighlightedText, qt_colorref2qrgb(GetSysColor(COLOR_CAPTIONTEXT)) );
|
---|
| 237 | pal.setColor( QPalette::Inactive, QColorGroup::HighlightedText, qt_colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTIONTEXT)) );
|
---|
| 238 | if ( qt_winver != Qt::WV_95 && qt_winver != WV_NT ) {
|
---|
| 239 | colorsInitialized = TRUE;
|
---|
| 240 | BOOL gradient;
|
---|
| 241 | QT_WA( {
|
---|
| 242 | SystemParametersInfo( SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0 );
|
---|
| 243 | } , {
|
---|
| 244 | SystemParametersInfoA( SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0 );
|
---|
| 245 | } );
|
---|
| 246 | if ( gradient ) {
|
---|
| 247 | pal.setColor( QPalette::Active, QColorGroup::Base, qt_colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION)) );
|
---|
| 248 | pal.setColor( QPalette::Inactive, QColorGroup::Base, qt_colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION)) );
|
---|
| 249 | } else {
|
---|
| 250 | pal.setColor( QPalette::Active, QColorGroup::Base, palette().active().highlight() );
|
---|
| 251 | pal.setColor( QPalette::Inactive, QColorGroup::Base, palette().inactive().highlight() );
|
---|
| 252 | }
|
---|
| 253 | }
|
---|
| 254 | }
|
---|
| 255 | #endif // Q_WS_WIN
|
---|
| 256 | if ( !colorsInitialized ) {
|
---|
| 257 | pal.setColor( QPalette::Active, QColorGroup::Highlight, palette().active().highlight() );
|
---|
| 258 | pal.setColor( QPalette::Active, QColorGroup::Base, palette().active().highlight() );
|
---|
| 259 | pal.setColor( QPalette::Inactive, QColorGroup::Highlight, palette().inactive().dark() );
|
---|
| 260 | pal.setColor( QPalette::Inactive, QColorGroup::Base, palette().inactive().dark() );
|
---|
| 261 | pal.setColor( QPalette::Inactive, QColorGroup::HighlightedText, palette().inactive().background() );
|
---|
| 262 | }
|
---|
[8] | 263 | #endif // Q_WS_PM
|
---|
[2] | 264 |
|
---|
| 265 | setPalette( pal );
|
---|
| 266 | setActive( d->act );
|
---|
| 267 | }
|
---|
| 268 |
|
---|
| 269 | void QTitleBar::mousePressEvent( QMouseEvent * e)
|
---|
| 270 | {
|
---|
| 271 | if ( !d->act )
|
---|
| 272 | emit doActivate();
|
---|
| 273 | if ( e->button() == LeftButton ) {
|
---|
| 274 | d->pressed = TRUE;
|
---|
| 275 | QStyle::SCFlags ctrl = style().querySubControl(QStyle::CC_TitleBar, this, e->pos());
|
---|
| 276 | switch (ctrl) {
|
---|
| 277 | case QStyle::SC_TitleBarSysMenu:
|
---|
| 278 | if ( testWFlags( WStyle_SysMenu ) && !testWFlags( WStyle_Tool ) ) {
|
---|
| 279 | d->buttonDown = QStyle::SC_None;
|
---|
| 280 | static QTime* t = 0;
|
---|
| 281 | static QTitleBar* tc = 0;
|
---|
| 282 | if ( !t )
|
---|
| 283 | t = new QTime;
|
---|
| 284 | if ( tc != this || t->elapsed() > QApplication::doubleClickInterval() ) {
|
---|
| 285 | emit showOperationMenu();
|
---|
| 286 | t->start();
|
---|
| 287 | tc = this;
|
---|
| 288 | } else {
|
---|
| 289 | tc = 0;
|
---|
| 290 | emit doClose();
|
---|
| 291 | return;
|
---|
| 292 | }
|
---|
| 293 | }
|
---|
| 294 | break;
|
---|
| 295 |
|
---|
| 296 | case QStyle::SC_TitleBarShadeButton:
|
---|
| 297 | case QStyle::SC_TitleBarUnshadeButton:
|
---|
| 298 | if ( testWFlags( WStyle_MinMax ) && testWFlags( WStyle_Tool ) )
|
---|
| 299 | d->buttonDown = ctrl;
|
---|
| 300 | break;
|
---|
| 301 |
|
---|
| 302 | case QStyle::SC_TitleBarNormalButton:
|
---|
| 303 | if( testWFlags( WStyle_Minimize ) && !testWFlags( WStyle_Tool ) )
|
---|
| 304 | d->buttonDown = ctrl;
|
---|
| 305 | break;
|
---|
| 306 |
|
---|
| 307 | case QStyle::SC_TitleBarMinButton:
|
---|
| 308 | if( testWFlags( WStyle_Minimize ) && !testWFlags( WStyle_Tool ) )
|
---|
| 309 | d->buttonDown = ctrl;
|
---|
| 310 | break;
|
---|
| 311 |
|
---|
| 312 | case QStyle::SC_TitleBarMaxButton:
|
---|
| 313 | if ( testWFlags( WStyle_Maximize ) && !testWFlags( WStyle_Tool ) )
|
---|
| 314 | d->buttonDown = ctrl;
|
---|
| 315 | break;
|
---|
| 316 |
|
---|
| 317 | case QStyle::SC_TitleBarCloseButton:
|
---|
| 318 | if ( testWFlags( WStyle_SysMenu ) )
|
---|
| 319 | d->buttonDown = ctrl;
|
---|
| 320 | break;
|
---|
| 321 |
|
---|
| 322 | case QStyle::SC_TitleBarLabel:
|
---|
| 323 | d->buttonDown = ctrl;
|
---|
| 324 | d->moveOffset = mapToParent( e->pos() );
|
---|
| 325 | break;
|
---|
| 326 |
|
---|
| 327 | default:
|
---|
| 328 | break;
|
---|
| 329 | }
|
---|
| 330 | repaint( FALSE );
|
---|
| 331 | } else {
|
---|
| 332 | d->pressed = FALSE;
|
---|
| 333 | }
|
---|
| 334 | }
|
---|
| 335 |
|
---|
| 336 | void QTitleBar::contextMenuEvent( QContextMenuEvent *e )
|
---|
| 337 | {
|
---|
| 338 | QStyle::SCFlags ctrl = style().querySubControl(QStyle::CC_TitleBar, this, e->pos());
|
---|
| 339 | if( ctrl == QStyle::SC_TitleBarLabel || ctrl == QStyle::SC_TitleBarSysMenu )
|
---|
| 340 | emit popupOperationMenu(e->globalPos());
|
---|
| 341 | else
|
---|
| 342 | e->ignore();
|
---|
| 343 | }
|
---|
| 344 |
|
---|
| 345 | void QTitleBar::mouseReleaseEvent( QMouseEvent * e)
|
---|
| 346 | {
|
---|
| 347 | if ( e->button() == LeftButton && d->pressed) {
|
---|
| 348 | QStyle::SCFlags ctrl = style().querySubControl(QStyle::CC_TitleBar, this, e->pos());
|
---|
| 349 |
|
---|
| 350 | if (ctrl == d->buttonDown) {
|
---|
| 351 | switch(ctrl) {
|
---|
| 352 | case QStyle::SC_TitleBarShadeButton:
|
---|
| 353 | case QStyle::SC_TitleBarUnshadeButton:
|
---|
| 354 | if( testWFlags( WStyle_MinMax ) && testWFlags( WStyle_Tool ) )
|
---|
| 355 | emit doShade();
|
---|
| 356 | break;
|
---|
| 357 |
|
---|
| 358 | case QStyle::SC_TitleBarNormalButton:
|
---|
| 359 | if( testWFlags( WStyle_MinMax ) && !testWFlags( WStyle_Tool ) )
|
---|
| 360 | emit doNormal();
|
---|
| 361 | break;
|
---|
| 362 |
|
---|
| 363 | case QStyle::SC_TitleBarMinButton:
|
---|
| 364 | if( testWFlags( WStyle_Minimize ) && !testWFlags( WStyle_Tool ) )
|
---|
| 365 | emit doMinimize();
|
---|
| 366 | break;
|
---|
| 367 |
|
---|
| 368 | case QStyle::SC_TitleBarMaxButton:
|
---|
| 369 | if( d->window && testWFlags( WStyle_Maximize ) && !testWFlags( WStyle_Tool ) ) {
|
---|
| 370 | if(d->window->isMaximized())
|
---|
| 371 | emit doNormal();
|
---|
| 372 | else
|
---|
| 373 | emit doMaximize();
|
---|
| 374 | }
|
---|
| 375 | break;
|
---|
| 376 |
|
---|
| 377 | case QStyle::SC_TitleBarCloseButton:
|
---|
| 378 | if( testWFlags( WStyle_SysMenu ) ) {
|
---|
| 379 | d->buttonDown = QStyle::SC_None;
|
---|
| 380 | repaint(FALSE);
|
---|
| 381 | emit doClose();
|
---|
| 382 | return;
|
---|
| 383 | }
|
---|
| 384 | break;
|
---|
| 385 |
|
---|
| 386 | default:
|
---|
| 387 | break;
|
---|
| 388 | }
|
---|
| 389 | }
|
---|
| 390 | d->buttonDown = QStyle::SC_None;
|
---|
| 391 | repaint(FALSE);
|
---|
| 392 | d->pressed = FALSE;
|
---|
| 393 | }
|
---|
| 394 | }
|
---|
| 395 |
|
---|
| 396 | void QTitleBar::mouseMoveEvent( QMouseEvent * e)
|
---|
| 397 | {
|
---|
| 398 | switch (d->buttonDown) {
|
---|
| 399 | case QStyle::SC_None:
|
---|
| 400 | if(autoRaise())
|
---|
| 401 | repaint( FALSE );
|
---|
| 402 | break;
|
---|
| 403 | case QStyle::SC_TitleBarSysMenu:
|
---|
| 404 | break;
|
---|
| 405 | case QStyle::SC_TitleBarShadeButton:
|
---|
| 406 | case QStyle::SC_TitleBarUnshadeButton:
|
---|
| 407 | case QStyle::SC_TitleBarNormalButton:
|
---|
| 408 | case QStyle::SC_TitleBarMinButton:
|
---|
| 409 | case QStyle::SC_TitleBarMaxButton:
|
---|
| 410 | case QStyle::SC_TitleBarCloseButton:
|
---|
| 411 | {
|
---|
| 412 | QStyle::SCFlags last_ctrl = d->buttonDown;
|
---|
| 413 | d->buttonDown = style().querySubControl(QStyle::CC_TitleBar, this, e->pos());
|
---|
| 414 | if( d->buttonDown != last_ctrl)
|
---|
| 415 | d->buttonDown = QStyle::SC_None;
|
---|
| 416 | repaint(FALSE);
|
---|
| 417 | d->buttonDown = last_ctrl;
|
---|
| 418 | }
|
---|
| 419 | break;
|
---|
| 420 |
|
---|
| 421 | case QStyle::SC_TitleBarLabel:
|
---|
| 422 | if ( d->buttonDown == QStyle::SC_TitleBarLabel && d->movable && d->pressed ) {
|
---|
| 423 | if ( (d->moveOffset - mapToParent( e->pos() ) ).manhattanLength() >= 4 ) {
|
---|
| 424 | QPoint p = mapFromGlobal(e->globalPos());
|
---|
| 425 | #ifndef QT_NO_WORKSPACE
|
---|
| 426 | if(d->window && d->window->parentWidget()->inherits("QWorkspaceChild")) {
|
---|
| 427 | QWorkspace *workspace = ::qt_cast<QWorkspace*>(d->window->parentWidget()->parentWidget());
|
---|
| 428 | if(workspace) {
|
---|
| 429 | p = workspace->mapFromGlobal( e->globalPos() );
|
---|
| 430 | if ( !workspace->rect().contains(p) ) {
|
---|
| 431 | if ( p.x() < 0 )
|
---|
| 432 | p.rx() = 0;
|
---|
| 433 | if ( p.y() < 0 )
|
---|
| 434 | p.ry() = 0;
|
---|
| 435 | if ( p.x() > workspace->width() )
|
---|
| 436 | p.rx() = workspace->width();
|
---|
| 437 | if ( p.y() > workspace->height() )
|
---|
| 438 | p.ry() = workspace->height();
|
---|
| 439 | }
|
---|
| 440 | }
|
---|
| 441 | }
|
---|
| 442 | #endif
|
---|
| 443 | QPoint pp = p - d->moveOffset;
|
---|
| 444 | if (!parentWidget()->isMaximized())
|
---|
| 445 | parentWidget()->move( pp );
|
---|
| 446 | }
|
---|
| 447 | } else {
|
---|
| 448 | QStyle::SCFlags last_ctrl = d->buttonDown;
|
---|
| 449 | d->buttonDown = QStyle::SC_None;
|
---|
| 450 | if( d->buttonDown != last_ctrl)
|
---|
| 451 | repaint(FALSE);
|
---|
| 452 | }
|
---|
| 453 | break;
|
---|
| 454 | }
|
---|
| 455 | }
|
---|
| 456 |
|
---|
| 457 | void QTitleBar::resizeEvent( QResizeEvent *r)
|
---|
| 458 | {
|
---|
| 459 | QWidget::resizeEvent(r);
|
---|
| 460 | cutText();
|
---|
| 461 | }
|
---|
| 462 |
|
---|
| 463 | void QTitleBar::paintEvent(QPaintEvent *)
|
---|
| 464 | {
|
---|
| 465 | QStyle::SCFlags ctrls = QStyle::SC_TitleBarLabel;
|
---|
| 466 | if ( testWFlags( WStyle_SysMenu) ) {
|
---|
| 467 | if ( testWFlags( WStyle_Tool ) ) {
|
---|
| 468 | ctrls |= QStyle::SC_TitleBarCloseButton;
|
---|
| 469 | if ( d->window && testWFlags( WStyle_MinMax ) ) {
|
---|
| 470 | if ( d->window->isMinimized() )
|
---|
| 471 | ctrls |= QStyle::SC_TitleBarUnshadeButton;
|
---|
| 472 | else
|
---|
| 473 | ctrls |= QStyle::SC_TitleBarShadeButton;
|
---|
| 474 | }
|
---|
| 475 | } else {
|
---|
| 476 | ctrls |= QStyle::SC_TitleBarSysMenu | QStyle::SC_TitleBarCloseButton;
|
---|
| 477 | if ( d->window && testWFlags( WStyle_Minimize ) ) {
|
---|
| 478 | if( d->window && d->window->isMinimized() )
|
---|
| 479 | ctrls |= QStyle::SC_TitleBarNormalButton;
|
---|
| 480 | else
|
---|
| 481 | ctrls |= QStyle::SC_TitleBarMinButton;
|
---|
| 482 | }
|
---|
| 483 | if ( d->window && testWFlags( WStyle_Maximize ) && !d->window->isMaximized() )
|
---|
| 484 | ctrls |= QStyle::SC_TitleBarMaxButton;
|
---|
| 485 | }
|
---|
| 486 | }
|
---|
| 487 |
|
---|
| 488 | QStyle::SCFlags under_mouse = QStyle::SC_None;
|
---|
| 489 | if( autoRaise() && hasMouse() ) {
|
---|
| 490 | QPoint p(mapFromGlobal(QCursor::pos()));
|
---|
| 491 | under_mouse = style().querySubControl(QStyle::CC_TitleBar, this, p);
|
---|
| 492 | ctrls ^= under_mouse;
|
---|
| 493 | }
|
---|
| 494 |
|
---|
| 495 | QSharedDoubleBuffer buffer( this, rect() );
|
---|
| 496 | style().drawComplexControl(QStyle::CC_TitleBar, buffer.painter(), this, rect(),
|
---|
| 497 | colorGroup(),
|
---|
| 498 | isEnabled() ? QStyle::Style_Enabled :
|
---|
| 499 | QStyle::Style_Default, ctrls, d->buttonDown);
|
---|
| 500 | if(under_mouse != QStyle::SC_None)
|
---|
| 501 | style().drawComplexControl(QStyle::CC_TitleBar, buffer.painter(), this, rect(),
|
---|
| 502 | colorGroup(),
|
---|
| 503 | QStyle::Style_MouseOver |
|
---|
| 504 | (isEnabled() ? QStyle::Style_Enabled : 0),
|
---|
| 505 | under_mouse, d->buttonDown);
|
---|
| 506 | }
|
---|
| 507 |
|
---|
| 508 | void QTitleBar::mouseDoubleClickEvent( QMouseEvent *e )
|
---|
| 509 | {
|
---|
| 510 | if ( e->button() != LeftButton )
|
---|
| 511 | return;
|
---|
| 512 |
|
---|
| 513 | switch(style().querySubControl(QStyle::CC_TitleBar, this, e->pos())) {
|
---|
| 514 | case QStyle::SC_TitleBarLabel:
|
---|
| 515 | emit doubleClicked();
|
---|
| 516 | break;
|
---|
| 517 |
|
---|
| 518 | case QStyle::SC_TitleBarSysMenu:
|
---|
| 519 | if ( testWFlags( WStyle_SysMenu ) )
|
---|
| 520 | emit doClose();
|
---|
| 521 | break;
|
---|
| 522 |
|
---|
| 523 | default:
|
---|
| 524 | break;
|
---|
| 525 | }
|
---|
| 526 | }
|
---|
| 527 |
|
---|
| 528 | #ifdef QT_NO_WIDGET_TOPEXTRA
|
---|
| 529 | // We provide one, since titlebar is useless otherwise.
|
---|
| 530 | QString QTitleBar::caption() const
|
---|
| 531 | {
|
---|
| 532 | return d->cap;
|
---|
| 533 | }
|
---|
| 534 | #endif
|
---|
| 535 |
|
---|
| 536 | void QTitleBar::cutText()
|
---|
| 537 | {
|
---|
| 538 | QFontMetrics fm( font() );
|
---|
| 539 |
|
---|
| 540 | int maxw = style().querySubControlMetrics(QStyle::CC_TitleBar, this,
|
---|
| 541 | QStyle::SC_TitleBarLabel).width();
|
---|
| 542 | if ( !d->window )
|
---|
| 543 | maxw = width() - 20;
|
---|
| 544 | const QString txt = caption();
|
---|
| 545 | d->cuttext = txt;
|
---|
| 546 | if ( fm.width( txt + "m" ) > maxw ) {
|
---|
| 547 | int i = txt.length();
|
---|
| 548 | int dotlength = fm.width( "..." );
|
---|
| 549 | while ( i>0 && fm.width(txt.left( i )) + dotlength > maxw )
|
---|
| 550 | i--;
|
---|
| 551 | if(i != (int)txt.length())
|
---|
| 552 | d->cuttext = txt.left( i ) + "...";
|
---|
| 553 | }
|
---|
| 554 | }
|
---|
| 555 |
|
---|
| 556 | void QTitleBar::setCaption( const QString& title )
|
---|
| 557 | {
|
---|
| 558 | if( caption() == title)
|
---|
| 559 | return;
|
---|
| 560 | #ifndef QT_NO_WIDGET_TOPEXTRA
|
---|
| 561 | QWidget::setCaption( title );
|
---|
| 562 | #else
|
---|
| 563 | d->cap = title;
|
---|
| 564 | #endif
|
---|
| 565 | cutText();
|
---|
| 566 |
|
---|
| 567 | update();
|
---|
| 568 | }
|
---|
| 569 |
|
---|
| 570 |
|
---|
| 571 | void QTitleBar::setIcon( const QPixmap& icon )
|
---|
| 572 | {
|
---|
| 573 | #ifndef QT_NO_WIDGET_TOPEXTRA
|
---|
| 574 | #ifndef QT_NO_IMAGE_SMOOTHSCALE
|
---|
| 575 | QRect menur = style().querySubControlMetrics(QStyle::CC_TitleBar, this,
|
---|
| 576 | QStyle::SC_TitleBarSysMenu);
|
---|
| 577 |
|
---|
| 578 | QPixmap theIcon;
|
---|
| 579 | if (icon.width() > menur.width()) {
|
---|
| 580 | // try to keep something close to the same aspect
|
---|
| 581 | int aspect = (icon.height() * 100) / icon.width();
|
---|
| 582 | int newh = (aspect * menur.width()) / 100;
|
---|
| 583 | theIcon.convertFromImage( icon.convertToImage().smoothScale(menur.width(),
|
---|
| 584 | newh) );
|
---|
| 585 | } else if (icon.height() > menur.height()) {
|
---|
| 586 | // try to keep something close to the same aspect
|
---|
| 587 | int aspect = (icon.width() * 100) / icon.height();
|
---|
| 588 | int neww = (aspect * menur.height()) / 100;
|
---|
| 589 | theIcon.convertFromImage( icon.convertToImage().smoothScale(neww,
|
---|
| 590 | menur.height()) );
|
---|
| 591 | } else
|
---|
| 592 | theIcon = icon;
|
---|
| 593 |
|
---|
| 594 | QWidget::setIcon( theIcon );
|
---|
| 595 | #else
|
---|
| 596 | QWidget::setIcon( icon );
|
---|
| 597 | #endif
|
---|
| 598 |
|
---|
| 599 | update();
|
---|
| 600 | #endif
|
---|
| 601 | }
|
---|
| 602 |
|
---|
| 603 | void QTitleBar::leaveEvent( QEvent * )
|
---|
| 604 | {
|
---|
| 605 | if(autoRaise() && !d->pressed)
|
---|
| 606 | repaint( FALSE );
|
---|
| 607 | }
|
---|
| 608 |
|
---|
| 609 | void QTitleBar::enterEvent( QEvent * )
|
---|
| 610 | {
|
---|
| 611 | if(autoRaise() && !d->pressed)
|
---|
| 612 | repaint( FALSE );
|
---|
| 613 | QEvent e( QEvent::Leave );
|
---|
| 614 | QApplication::sendEvent( parentWidget(), &e );
|
---|
| 615 | }
|
---|
| 616 |
|
---|
| 617 | void QTitleBar::setActive( bool active )
|
---|
| 618 | {
|
---|
| 619 | if ( d->act == active )
|
---|
| 620 | return ;
|
---|
| 621 |
|
---|
| 622 | d->act = active;
|
---|
| 623 | update();
|
---|
| 624 | }
|
---|
| 625 |
|
---|
| 626 | bool QTitleBar::isActive() const
|
---|
| 627 | {
|
---|
| 628 | return d->act;
|
---|
| 629 | }
|
---|
| 630 |
|
---|
| 631 | bool QTitleBar::usesActiveColor() const
|
---|
| 632 | {
|
---|
| 633 | return ( isActive() && isActiveWindow() ) ||
|
---|
| 634 | ( !window() && topLevelWidget()->isActiveWindow() );
|
---|
| 635 | }
|
---|
| 636 |
|
---|
| 637 | QString QTitleBar::visibleText() const
|
---|
| 638 | {
|
---|
| 639 | return d->cuttext;
|
---|
| 640 | }
|
---|
| 641 |
|
---|
| 642 | QWidget *QTitleBar::window() const
|
---|
| 643 | {
|
---|
| 644 | return d->window;
|
---|
| 645 | }
|
---|
| 646 |
|
---|
| 647 | bool QTitleBar::event( QEvent* e )
|
---|
| 648 | {
|
---|
| 649 | if ( e->type() == QEvent::ApplicationPaletteChange ) {
|
---|
| 650 | readColors();
|
---|
| 651 | return TRUE;
|
---|
| 652 | } else if ( e->type() == QEvent::WindowActivate ) {
|
---|
| 653 | setActive( d->act );
|
---|
| 654 | } else if ( e->type() == QEvent::WindowDeactivate ) {
|
---|
| 655 | bool wasActive = d->act;
|
---|
| 656 | setActive( FALSE );
|
---|
| 657 | d->act = wasActive;
|
---|
| 658 | }
|
---|
| 659 |
|
---|
| 660 | return QWidget::event( e );
|
---|
| 661 | }
|
---|
| 662 |
|
---|
| 663 | void QTitleBar::setMovable(bool b)
|
---|
| 664 | {
|
---|
| 665 | d->movable = b;
|
---|
| 666 | }
|
---|
| 667 |
|
---|
| 668 | bool QTitleBar::isMovable() const
|
---|
| 669 | {
|
---|
| 670 | return d->movable;
|
---|
| 671 | }
|
---|
| 672 |
|
---|
| 673 | void QTitleBar::setAutoRaise(bool b)
|
---|
| 674 | {
|
---|
| 675 | d->autoraise = b;
|
---|
| 676 | }
|
---|
| 677 |
|
---|
| 678 | bool QTitleBar::autoRaise() const
|
---|
| 679 | {
|
---|
| 680 | return d->autoraise;
|
---|
| 681 | }
|
---|
| 682 |
|
---|
| 683 | QSize QTitleBar::sizeHint() const
|
---|
| 684 | {
|
---|
| 685 | constPolish();
|
---|
| 686 | QRect menur = style().querySubControlMetrics(QStyle::CC_TitleBar, this,
|
---|
| 687 | QStyle::SC_TitleBarSysMenu);
|
---|
| 688 | return QSize( menur.width(), style().pixelMetric( QStyle::PM_TitleBarHeight, this ) );
|
---|
| 689 | }
|
---|
| 690 |
|
---|
| 691 | #endif //QT_NO_TITLEBAR
|
---|