summaryrefslogtreecommitdiffstats
path: root/src/gui/embedded/qdecoration_qws.cpp
blob: 7e93407c081ee53e5615a747a1afd254a8afe48a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qdecoration_qws.h"

#include "qapplication.h"
#include "qdrawutil.h"
#include "qpainter.h"
#include "qregion.h"
#include "qwhatsthis.h"

#include "qmenu.h"
#include "private/qwidget_p.h"
#include "qwsmanager_qws.h"

QT_BEGIN_NAMESPACE

/*!
    \class QDecoration
    \ingroup qws

    \brief The QDecoration class is a base class for window
    decorations in Qt for Embedded Linux

    Note that this class is non-portable and only available in
    \l{Qt for Embedded Linux}.

    \l{Qt for Embedded Linux} provides window management of top level windows
    and several ready made decorations (i.e., \c Default, \c Styled
    and \c Windows). Custom decorations can be implemented by
    subclassing the QDecoration class and creating a decoration plugin
    (derived from QDecorationPlugin). The default
    implementation of the QDecorationFactory class will automatically
    detect the plugin, and load the decoration into the application at
    run-time using Qt's \l {How to Create Qt Plugins}{plugin
    system}. To actually apply a decoration, use the
    QApplication::qwsSetDecoration() function.

    When creating a custom decoration, implement the paint() function
    to paint the border and title decoration, and the region()
    function to return the regions the decoration
    occupies. Reimplement the regionClicked() and
    regionDoubleClicked() functions to respond to mouse clicks (the
    default implementations responds to (single) clicks on items in a
    widget's system menu and double clicks on a widget's title).

    QDecoration provides the DecorationRegion enum that describes the
    various regions of the window decoration, and the regionAt()
    function to determine the region containing a given point. The
    QDecoration class also provides the DecorationState enum
    describing the state of a given region, e.g. whether it is active
    or not.

    In addition, it is possible to build the system menu for a given
    top level widget using the buildSysMenu() function; whenever an
    action in this menu is triggered, the menuTriggered() function is
    called automatically.

    Finally, the QDecoration class provides a couple of static
    functions, startMove() and startResize(), which start a move or
    resize action by making the appropriate decoration region active
    and grabbing the mouse input.

    \sa QDecorationFactory, QDecorationPlugin, {Qt for Embedded Linux
    Architecture}
*/

/*!
    \fn QDecoration::QDecoration()

    Constructs a decoration object.
*/

/*!
    \fn QDecoration::~QDecoration()

    Destroys this decoration object.
*/

/*!
    \enum QDecoration::DecorationRegion

    This enum describes the various regions of the window decoration.

    \value All The entire region used by the window decoration.

    \value Top    The top border used to vertically resize the window.
    \value Bottom The bottom border used to vertically resize the window.
    \value Left   The left border used to horizontally resize the window.
    \value Right  The right border used to horizontally resize the window.
    \value TopLeft    The top-left corner of the window used to resize the
                      window both horizontally and vertically.
    \value TopRight   The top-right corner of the window used to resize the
                      window both horizontally and vertically.
    \value BottomLeft The bottom-left corner of the window used to resize the
                      window both horizontally and vertically.
    \value BottomRight The bottom-right corner of the window used to resize the
                      window both horizontally and vertically.
    \value Borders    All the regions used to describe the window's borders.

    \value Title    The region containing the window title, used
                    to move the window by dragging with the mouse cursor.
    \value Close    The region occupied by the close button. Clicking in this
                    region closes the window.
    \value Minimize The region occupied by the minimize button. Clicking in
                    this region minimizes the window.
    \value Maximize The region occupied by the maximize button. Clicking in
                    this region maximizes the window.
    \value Normalize The region occupied by a button used to restore a window's
                     normal size. Clicking in this region restores a maximized
                     window to its previous size. The region used for this
                     button is often also the Maximize region.
    \value Menu     The region occupied by the window's menu button. Clicking
                    in this region opens the window operations (system) menu.
    \value Help     The region occupied by the window's help button. Clicking
                    in this region causes the context-sensitive help function
                    to be enabled.
    \value Resize   The region used to resize the window.
    \value Move     The region used to move the window.
    \value None      No region.

    \sa region(), regionAt(), DecorationState
*/

/*!
    \enum QDecoration::DecorationState

    This enum describes the various states of a decoration region.

    \value Normal The region is active
    \value Disabled The region is inactive.
    \value Hover The cursor is hovering over the region.
    \value Pressed The region is pressed.

    \sa paint(), DecorationRegion
*/

/*!
    \fn QRegion QDecoration::region(const QWidget *widget, const QRect & rectangle, int decorationRegion)

    Implement this function to return the region specified by \a
    decorationRegion for the given top level \a widget.

    The \a rectangle parameter specifies the rectangle the decoration
    is wrapped around. The \a decorationRegion is a bitmask of the
    values described by the DecorationRegion enum.

    \sa regionAt(), paint()
*/

/*!
    \fn QRegion QDecoration::region(const QWidget *widget, int decorationRegion)
    \overload
*/

/*!
    \fn bool QDecoration::paint(QPainter *painter, const QWidget *widget, int decorationRegion,
                                DecorationState state)

    Implement this function to paint the border and title decoration
    for the specified top level \a widget using the given \a painter
    and decoration \a state. The specified \a decorationRegion is a
    bitmask of the values described by the DecorationRegion enum.

    Note that \l{Qt for Embedded Linux} expects this function to return true if
    any of the widget's decorations are repainted; otherwise it should
    return false.

    \sa region()
*/

/*!
    \fn int QDecoration::regionAt(const QWidget *widget, const QPoint &point)

    Returns the type of the first region of the specified top level \a
    widget containing the given \a point.

    The return value is one of the DecorationRegion enum's values. Use
    the region() function to retrieve the actual region. If none of
    the widget's regions contain the point, this function returns \l
    None.

    \sa region()
*/
int QDecoration::regionAt(const QWidget *w, const QPoint &point)
{
    int regions[] = {
        TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight, // Borders first
        Menu, Title, Help, Minimize, Normalize, Maximize, Close,                         // then buttons
        None
    };

//     char *regions_str[] = {
//         "TopLeft", "Top", "TopRight", "Left", "Right", "BottomLeft", "Bottom", "BottomRight",
//         "Menu", "Title", "Help", "Minimize", "Normalize", "Maximize", "Close",
//         "None"
//     };

    // First check to see if within all regions at all
    QRegion reg = region(w, w->geometry(), All);
    if (!reg.contains(point)) {
        return None;
    }

    int i = 0;
    while (regions[i]) {
        reg = region(w, w->geometry(), regions[i]);
        if (reg.contains(point)) {
//            qDebug("In region %s", regions_str[i]);
            return regions[i];
        }
        ++i;
    }
    return None;
}

#ifndef QT_NO_MENU
/*!
    Builds the system menu for the given top level \a widget, adding
    \gui Restore, \gui Move, \gui Size, \gui Minimize, \gui Maximize
    and \gui Close actions to the given \a menu.

    \sa menuTriggered()
*/
void QDecoration::buildSysMenu(QWidget *widget, QMenu *menu)
{
    QDecorationAction *act = new QDecorationAction(QLatin1String("Restore"),
                                                   menu, Maximize);
    act->setEnabled(widget->windowState() & Qt::WindowMaximized);
    menu->addAction(act);
    act = new QDecorationAction(QLatin1String("Move"), menu, Move);
    act->setEnabled(!(widget->windowState() & Qt::WindowMaximized));
    menu->addAction(act);
    menu->addAction(new QDecorationAction(QLatin1String("Size"), menu, Resize));
    act = new QDecorationAction(QLatin1String("Minimize"), menu, Minimize);
    menu->addAction(act);
    act = new QDecorationAction(QLatin1String("Maximize"), menu, Maximize);
    act->setDisabled(widget->windowState() & Qt::WindowMaximized);
    menu->addAction(act);
    menu->addSeparator();
    menu->addAction(new QDecorationAction(QLatin1String("Close"), menu, Close));
}

/*!
    This function is called whenever an action in a top level widget's
    menu is triggered, and simply calls the regionClicked() function
    passing the \a widget and \a action parameters as arguments.

    \sa buildSysMenu()
*/
void QDecoration::menuTriggered(QWidget *widget, QAction *action)
{
    QDecorationAction *decAction = static_cast<QDecorationAction *>(action);
    regionClicked(widget, decAction->reg);
}
#endif // QT_NO_MENU

/*!
    \fn void QDecoration::regionClicked(QWidget *widget, int region)

    Handles the event that the specified \a region in the given top
    level \a widget is activated by a single click (the \a region
    parameter is described using the DecorationRegion enum).

    This function is called whenever a region in a top level widget is
    clicked; the default implementation responds to clicks on items in
    the system menu, performing the requested actions.

    \sa regionDoubleClicked(), region()
*/
void QDecoration::regionClicked(QWidget *widget, int reg)
{
    switch(reg) {
    case Move:
        startMove(widget);
        break;
    case Resize:
        startResize(widget);
        break;
    case Help:
#ifndef QT_NO_WHATSTHIS
        if (QWhatsThis::inWhatsThisMode())
            QWhatsThis::leaveWhatsThisMode();
        else
            QWhatsThis::enterWhatsThisMode();
#endif
        break;
    case Close:
        widget->close();
        break;
    case Normalize:
        widget->showNormal();
        break;
    case Maximize:
        if (widget->windowState() & Qt::WindowMaximized)
            widget->showNormal();
        else
            widget->showMaximized();
        break;
    }
}

/*!
    \fn void QDecoration::regionDoubleClicked(QWidget *widget, int region)

    Handles the event that the specified \a region in the given top
    level \a widget is activated by a double click (the region
    parameter is described using the DecorationRegion enum).

    This function is called whenever a region in a top level widget is
    double clicked; the default implementation responds to a double
    click on the widget's title, toggling its size between the maximum
    and its normal size.

    \sa regionClicked(), region()
*/
void QDecoration::regionDoubleClicked(QWidget *widget, int reg)
{
    switch(reg)
    {
        case Title: {
            if (widget->windowState() & Qt::WindowMaximized)
                widget->showNormal();
            else
                widget->showMaximized();
            break;
        }
    }
}

/*!
    Starts to move the given top level \a widget by making its \l
    Title region active and grabbing the mouse input.

    \sa startResize()
*/
void QDecoration::startMove(QWidget *widget)
{
#ifdef QT_NO_QWS_MANAGER
    Q_UNUSED(widget);
#else
    QWSManager *manager = widget->d_func()->topData()->qwsManager;
    if (manager)
        manager->startMove();
#endif
}

/*!
    Starts to resize the given top level \a widget by making its \l
    BottomRight region active and grabbing the mouse input.

    \sa startMove()
*/
void QDecoration::startResize(QWidget *widget)
{
#ifdef QT_NO_QWS_MANAGER
    Q_UNUSED(widget);
#else
    QWSManager *manager = widget->d_func()->topData()->qwsManager;
    if (manager)
        manager->startResize();
#endif
}


QT_END_NAMESPACE