~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/gui/widgets/qframe.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the widgets module of the Qt Toolkit.
 
6
**
 
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.
 
10
**
 
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.
 
15
**
 
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.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
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.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "qframe.h"
 
30
#include "qbitmap.h"
 
31
#include "qdrawutil.h"
 
32
#include "qevent.h"
 
33
#include "qpainter.h"
 
34
#include "qstyle.h"
 
35
#include "qstyleoption.h"
 
36
 
 
37
#include "qframe_p.h"
 
38
 
 
39
QFramePrivate::QFramePrivate()
 
40
    : frect(QRect(0, 0, 0, 0)),
 
41
      frameStyle(QFrame::NoFrame | QFrame::Plain),
 
42
      lineWidth(1),
 
43
      midLineWidth(0),
 
44
      frameWidth(0)
 
45
{
 
46
}
 
47
 
 
48
/*!
 
49
    \class QFrame
 
50
    \brief The QFrame class is the base class of widgets that can have a frame.
 
51
 
 
52
    \ingroup abstractwidgets
 
53
    \mainclass
 
54
 
 
55
    QMenu uses this to "raise" the menu above the surrounding
 
56
    screen. QProgressBar has a "sunken" look. QLabel has a flat look.
 
57
    The frames of widgets like these can be changed.
 
58
 
 
59
    \code
 
60
    QLabel label(...);
 
61
    label.setFrameStyle(QFrame::Panel | QFrame::Raised);
 
62
    label.setLineWidth(2);
 
63
 
 
64
    QProgressBar pbar(...);
 
65
    label.setFrameStyle(QFrame::NoFrame);
 
66
    \endcode
 
67
 
 
68
    The QFrame class can also be used directly for creating simple
 
69
    frames without any contents, although usually you would use a
 
70
    QHBox or QVBox because they automatically lay out the widgets you
 
71
    put inside the frame.
 
72
 
 
73
    A frame widget has four attributes: frameStyle(), lineWidth(),
 
74
    midLineWidth(), and margin().
 
75
 
 
76
    The frame style is specified by a \link QFrame::Shape frame
 
77
    shape\endlink and a \link QFrame::Shadow shadow style\endlink. The
 
78
    frame shapes are \c NoFrame, \c Box, \c Panel, \c StyledPanel,
 
79
    HLine and \c VLine; the shadow styles are \c Plain, \c Raised and
 
80
    \c Sunken.
 
81
 
 
82
    The line width is the width of the frame border.
 
83
 
 
84
    The mid-line width specifies the width of an extra line in the
 
85
    middle of the frame, which uses a third color to obtain a special
 
86
    3D effect. Notice that a mid-line is only drawn for \c Box, \c
 
87
    HLine and \c VLine frames that are raised or sunken.
 
88
 
 
89
    The margin is the gap between the frame and the contents of the
 
90
    frame.
 
91
 
 
92
    \target picture
 
93
    This table shows the most useful combinations of styles and widths
 
94
    (and some rather useless ones):
 
95
 
 
96
    \img frames.png Table of frame styles
 
97
*/
 
98
 
 
99
 
 
100
/*!
 
101
    \enum QFrame::Shape
 
102
 
 
103
    This enum type defines the shapes of a QFrame's frame.
 
104
 
 
105
    \value NoFrame  QFrame draws nothing
 
106
    \value Box  QFrame draws a box around its contents
 
107
    \value Panel  QFrame draws a panel to make the contents appear
 
108
    raised or sunken
 
109
    \value StyledPanel  draws a rectangular panel with a look that
 
110
    depends on the current GUI style. It can be raised or sunken.
 
111
    \value HLine  QFrame draws a horizontal line that frames nothing
 
112
    (useful as separator)
 
113
    \value VLine  QFrame draws a vertical line that frames nothing
 
114
    (useful as separator)
 
115
    \value WinPanel draws a rectangular panel that can be raised or
 
116
    sunken like those in Windows 95. Specifying this shape sets
 
117
    the line width to 2 pixels. WinPanel is provided for compatibility.
 
118
    For GUI style independence we recommend using StyledPanel instead.
 
119
 
 
120
    \omitvalue GroupBoxPanel
 
121
    \omitvalue ToolBarPanel
 
122
    \omitvalue MenuBarPanel
 
123
    \omitvalue PopupPanel
 
124
    \omitvalue LineEditPanel
 
125
    \omitvalue TabWidgetPanel
 
126
 
 
127
    When it does not call QStyle, Shape interacts with QFrame::Shadow,
 
128
    the lineWidth() and the midLineWidth() to create the total result.
 
129
    See the picture of the frames in the main class documentation.
 
130
 
 
131
    \sa QFrame::Shadow QFrame::style() QStyle::drawPrimitive()
 
132
*/
 
133
 
 
134
 
 
135
/*!
 
136
    \enum QFrame::Shadow
 
137
 
 
138
    This enum type defines the 3D effect used for QFrame's frame.
 
139
 
 
140
    \value Plain  the frame and contents appear level with the
 
141
    surroundings; draws using the palette foreground color (without
 
142
    any 3D effect)
 
143
    \value Raised the frame and contents appear raised; draws a 3D
 
144
    raised line using the light and dark colors of the current color
 
145
    group
 
146
    \value Sunken the frame and contents appear sunken; draws a 3D
 
147
    sunken line using the light and dark colors of the current color
 
148
    group
 
149
 
 
150
    Shadow interacts with QFrame::Shape, the lineWidth() and the
 
151
    midLineWidth(). See the picture of the frames in the main class
 
152
    documentation.
 
153
 
 
154
    \sa QFrame::Shape lineWidth() midLineWidth()
 
155
*/
 
156
 
 
157
/*!
 
158
    \variable QFrame::Shadow_Mask
 
159
 
 
160
    The mask of the QFrame's shadow.
 
161
 
 
162
    \sa QFrame::frameShadow
 
163
*/
 
164
 
 
165
/*!
 
166
    \variable QFrame::Shape_Mask
 
167
 
 
168
    The mask of the QFrame's shape.
 
169
 
 
170
    \sa QFrame::frameShape
 
171
*/
 
172
 
 
173
/*!
 
174
    Constructs a frame widget with frame style \c NoFrame and a
 
175
    1-pixel frame width.
 
176
 
 
177
    The \a parent and \a f arguments are passed to the QWidget
 
178
    constructor.
 
179
*/
 
180
 
 
181
QFrame::QFrame(QWidget* parent, Qt::WFlags f)
 
182
    : QWidget(*new QFramePrivate, parent, f)
 
183
{
 
184
}
 
185
 
 
186
/*! \internal */
 
187
QFrame::QFrame(QFramePrivate &dd, QWidget* parent, Qt::WFlags f)
 
188
    : QWidget(dd, parent, f)
 
189
{
 
190
}
 
191
 
 
192
#ifdef QT3_SUPPORT
 
193
/*!
 
194
    Use one of the constructors that doesn't take the \a name
 
195
    argument and then use setObjectName() instead.
 
196
*/
 
197
QFrame::QFrame(QWidget *parent, const char *name, Qt::WFlags f)
 
198
    : QWidget(*new QFramePrivate, parent, f)
 
199
{
 
200
    setObjectName(name);
 
201
}
 
202
#endif
 
203
 
 
204
/*!
 
205
  Destroys the frame.
 
206
 */
 
207
QFrame::~QFrame()
 
208
{
 
209
}
 
210
 
 
211
/*!
 
212
    Returns the frame style.
 
213
 
 
214
    The default value is QFrame::NoFrame.
 
215
 
 
216
    \sa setFrameStyle(), frameShape(), frameShadow()
 
217
*/
 
218
int QFrame::frameStyle() const
 
219
{
 
220
    Q_D(const QFrame);
 
221
    return d->frameStyle;
 
222
}
 
223
 
 
224
/*!
 
225
    \property QFrame::frameShape
 
226
    \brief the frame shape value from the frame style
 
227
 
 
228
    \sa frameStyle(), frameShadow()
 
229
*/
 
230
 
 
231
QFrame::Shape QFrame::frameShape() const
 
232
{
 
233
    Q_D(const QFrame);
 
234
    return (Shape) (d->frameStyle & Shape_Mask);
 
235
}
 
236
 
 
237
void QFrame::setFrameShape(QFrame::Shape s)
 
238
{
 
239
    Q_D(QFrame);
 
240
    setFrameStyle((d->frameStyle & Shadow_Mask) | s);
 
241
}
 
242
 
 
243
 
 
244
/*!
 
245
    \property QFrame::frameShadow
 
246
    \brief the frame shadow value from the frame style
 
247
 
 
248
    \sa frameStyle(), frameShape()
 
249
*/
 
250
QFrame::Shadow QFrame::frameShadow() const
 
251
{
 
252
    Q_D(const QFrame);
 
253
    return (Shadow) (d->frameStyle & Shadow_Mask);
 
254
}
 
255
 
 
256
void QFrame::setFrameShadow(QFrame::Shadow s)
 
257
{
 
258
    Q_D(QFrame);
 
259
    setFrameStyle((d->frameStyle & Shape_Mask) | s);
 
260
}
 
261
 
 
262
/*!
 
263
    Sets the frame style to \a style.
 
264
 
 
265
    The \a style is the bitwise OR between a frame shape and a frame
 
266
    shadow style. See the picture of the frames in the main class
 
267
    documentation.
 
268
 
 
269
    The frame shapes are given in \l{QFrame::Shape} and the shadow
 
270
    styles in \l{QFrame::Shadow}.
 
271
 
 
272
    If a mid-line width greater than 0 is specified, an additional
 
273
    line is drawn for \c Raised or \c Sunken \c Box, \c HLine, and \c
 
274
    VLine frames. The mid-color of the current color group is used for
 
275
    drawing middle lines.
 
276
 
 
277
    \sa frameStyle()
 
278
*/
 
279
 
 
280
void QFrame::setFrameStyle(int style)
 
281
{
 
282
    Q_D(QFrame);
 
283
    if (!testAttribute(Qt::WA_WState_OwnSizePolicy)) {
 
284
        switch (style & Shape_Mask) {
 
285
        case HLine:
 
286
            setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
 
287
            break;
 
288
        case VLine:
 
289
            setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
 
290
            break;
 
291
        default:
 
292
            if ((d->frameStyle & Shape_Mask) == HLine || (d->frameStyle & Shape_Mask) == VLine)
 
293
                setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
 
294
        }
 
295
        setAttribute(Qt::WA_WState_OwnSizePolicy, false);
 
296
    }
 
297
    d->frameStyle = (short)style;
 
298
    update();
 
299
    d->updateFrameWidth();
 
300
}
 
301
 
 
302
/*!
 
303
    \property QFrame::lineWidth
 
304
    \brief the line width
 
305
 
 
306
    Note that the \e total line width for \c HLine and \c VLine is
 
307
    specified by frameWidth(), not lineWidth().
 
308
 
 
309
    The default value is 1.
 
310
 
 
311
    \sa midLineWidth(), frameWidth()
 
312
*/
 
313
 
 
314
void QFrame::setLineWidth(int w)
 
315
{
 
316
    Q_D(QFrame);
 
317
    d->lineWidth = (short)w;
 
318
    d->updateFrameWidth();
 
319
}
 
320
 
 
321
int QFrame::lineWidth() const
 
322
{
 
323
    Q_D(const QFrame);
 
324
    return d->lineWidth;
 
325
}
 
326
 
 
327
/*!
 
328
    \property QFrame::midLineWidth
 
329
    \brief the width of the mid-line
 
330
 
 
331
    The default value is 0.
 
332
 
 
333
    \sa lineWidth(), frameWidth()
 
334
*/
 
335
 
 
336
void QFrame::setMidLineWidth(int w)
 
337
{
 
338
    Q_D(QFrame);
 
339
    d->midLineWidth = (short)w;
 
340
    d->updateFrameWidth();
 
341
}
 
342
 
 
343
int QFrame::midLineWidth() const
 
344
{
 
345
    Q_D(const QFrame);
 
346
    return d->midLineWidth;
 
347
}
 
348
 
 
349
 
 
350
/*!
 
351
  \internal
 
352
  Updated the frameWidth parameter.
 
353
*/
 
354
 
 
355
void QFramePrivate::updateFrameWidth()
 
356
{
 
357
    Q_Q(QFrame);
 
358
    QRect fr = q->frameRect();
 
359
 
 
360
    int frameShape  = frameStyle & QFrame::Shape_Mask;
 
361
    int frameShadow = frameStyle & QFrame::Shadow_Mask;
 
362
 
 
363
    frameWidth = -1;
 
364
 
 
365
    switch (frameShape) {
 
366
 
 
367
    case QFrame::NoFrame:
 
368
        frameWidth = 0;
 
369
        break;
 
370
 
 
371
    case QFrame::Box:
 
372
    case QFrame::HLine:
 
373
    case QFrame::VLine:
 
374
        switch (frameShadow) {
 
375
        case QFrame::Plain:
 
376
            frameWidth = lineWidth;
 
377
            break;
 
378
        case QFrame::Raised:
 
379
        case QFrame::Sunken:
 
380
            frameWidth = (short)(lineWidth*2 + midLineWidth);
 
381
            break;
 
382
        }
 
383
        break;
 
384
 
 
385
    case QFrame::StyledPanel:
 
386
        frameWidth = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, q);
 
387
        break;
 
388
 
 
389
    case QFrame::WinPanel:
 
390
        frameWidth = 2;
 
391
        break;
 
392
 
 
393
 
 
394
    case QFrame::Panel:
 
395
        switch (frameShadow) {
 
396
        case QFrame::Plain:
 
397
        case QFrame::Raised:
 
398
        case QFrame::Sunken:
 
399
            frameWidth = lineWidth;
 
400
            break;
 
401
        }
 
402
        break;
 
403
    }
 
404
 
 
405
    if (frameWidth == -1)                                // invalid style
 
406
        frameWidth = 0;
 
407
 
 
408
    q->setFrameRect(fr);
 
409
}
 
410
 
 
411
 
 
412
/*!
 
413
    \property QFrame::frameWidth
 
414
    \brief the width of the frame that is drawn.
 
415
 
 
416
    Note that the frame width depends on the \link
 
417
    QFrame::setFrameStyle() frame style \endlink, not only the line
 
418
    width and the mid-line width. For example, the style \c NoFrame
 
419
    always has a frame width of 0, whereas the style \c Panel has a
 
420
    frame width equivalent to the line width.
 
421
 
 
422
    \sa lineWidth(), midLineWidth(), frameStyle()
 
423
*/
 
424
int QFrame::frameWidth() const
 
425
{
 
426
    Q_D(const QFrame);
 
427
    return d->frameWidth;
 
428
}
 
429
 
 
430
 
 
431
/*!
 
432
    \property QFrame::frameRect
 
433
    \brief the frame's rectangle
 
434
 
 
435
    The frame's rectangle is the rectangle the frame is drawn in. By
 
436
    default, this is the entire widget. Setting the rectangle does
 
437
    does \e not cause a widget update. The frame rectangle is
 
438
    automatically adjusted when the widget changes size.
 
439
 
 
440
    If you set the rectangle to a null rectangle (for example
 
441
    \c{QRect(0, 0, 0, 0)}), then the resulting frame rectangle is
 
442
    equivalent to the \link QWidget::rect() widget rectangle\endlink.
 
443
*/
 
444
 
 
445
QRect QFrame::frameRect() const
 
446
{
 
447
    Q_D(const QFrame);
 
448
    QRect fr = contentsRect();
 
449
    fr.adjust(-d->frameWidth, -d->frameWidth, d->frameWidth, d->frameWidth);
 
450
    return fr;
 
451
}
 
452
 
 
453
void QFrame::setFrameRect(const QRect &r)
 
454
{
 
455
    Q_D(QFrame);
 
456
    QRect cr = r.isValid() ? r : rect();
 
457
    cr.adjust(d->frameWidth, d->frameWidth, -d->frameWidth, -d->frameWidth);
 
458
    setContentsMargins(cr.left(), cr.top(), rect().right() - cr.right(), rect().bottom() - cr.bottom());
 
459
}
 
460
 
 
461
/*!\reimp
 
462
*/
 
463
QSize QFrame::sizeHint() const
 
464
{
 
465
    Q_D(const QFrame);
 
466
    //   Returns a size hint for the frame - for HLine and VLine
 
467
    //   shapes, this is stretchable one way and 3 pixels wide the
 
468
    //   other.  For other shapes, QWidget::sizeHint() is used.
 
469
    switch (d->frameStyle & Shape_Mask) {
 
470
    case HLine:
 
471
        return QSize(-1,3);
 
472
    case VLine:
 
473
        return QSize(3,-1);
 
474
    default:
 
475
        return QWidget::sizeHint();
 
476
    }
 
477
}
 
478
 
 
479
/*!\reimp
 
480
*/
 
481
 
 
482
void QFrame::paintEvent(QPaintEvent *)
 
483
{
 
484
    QPainter paint(this);
 
485
    drawFrame(&paint);
 
486
}
 
487
 
 
488
/*!
 
489
    \internal
 
490
 
 
491
    Mostly for the sake of Q3Frame
 
492
 */
 
493
void QFrame::drawFrame(QPainter *p)
 
494
{
 
495
    Q_D(QFrame);
 
496
    QPoint      p1, p2;
 
497
    QStyleOptionFrame opt;
 
498
    opt.init(this);
 
499
    int frameShape  = d->frameStyle & QFrame::Shape_Mask;
 
500
    int frameShadow = d->frameStyle & QFrame::Shadow_Mask;
 
501
 
 
502
    int lw = 0;
 
503
    int mlw = 0;
 
504
    opt.rect = frameRect();
 
505
    switch (frameShape) {
 
506
    case QFrame::Box:
 
507
    case QFrame::HLine:
 
508
    case QFrame::VLine:
 
509
    case QFrame::StyledPanel:
 
510
        lw = d->lineWidth;
 
511
        mlw = d->midLineWidth;
 
512
        break;
 
513
    default:
 
514
        // most frame styles do not handle customized line and midline widths
 
515
        // (see updateFrameWidth()).
 
516
        lw = d->frameWidth;
 
517
        break;
 
518
    }
 
519
    opt.lineWidth = lw;
 
520
    opt.midLineWidth = mlw;
 
521
    if (frameShadow == Sunken)
 
522
        opt.state |= QStyle::State_Sunken;
 
523
    else if (frameShadow == Raised)
 
524
        opt.state |= QStyle::State_Raised;
 
525
 
 
526
    switch (frameShape) {
 
527
    case Box:
 
528
        if (frameShadow == Plain)
 
529
            qDrawPlainRect(p, opt.rect, opt.palette.foreground().color(), lw);
 
530
        else
 
531
            qDrawShadeRect(p, opt.rect, opt.palette, frameShadow == Sunken, lw, mlw);
 
532
        break;
 
533
 
 
534
 
 
535
    case StyledPanel:
 
536
        style()->drawPrimitive(QStyle::PE_Frame, &opt, p, this);
 
537
        break;
 
538
 
 
539
    case Panel:
 
540
        if (frameShadow == Plain)
 
541
            qDrawPlainRect(p, opt.rect, opt.palette.foreground().color(), lw);
 
542
        else
 
543
            qDrawShadePanel(p, opt.rect, opt.palette, frameShadow == Sunken, lw);
 
544
        break;
 
545
 
 
546
    case WinPanel:
 
547
        if (frameShadow == Plain)
 
548
            qDrawPlainRect(p, opt.rect, opt.palette.foreground().color(), lw);
 
549
        else
 
550
            qDrawWinPanel(p, opt.rect, opt.palette, frameShadow == Sunken);
 
551
        break;
 
552
    case HLine:
 
553
    case VLine:
 
554
        if (frameShape == HLine) {
 
555
            p1 = QPoint(opt.rect.x(), opt.rect.height() / 2);
 
556
            p2 = QPoint(opt.rect.x() + opt.rect.width(), p1.y());
 
557
        } else {
 
558
            p1 = QPoint(opt.rect.x()+opt.rect.width() / 2, 0);
 
559
            p2 = QPoint(p1.x(), opt.rect.height());
 
560
        }
 
561
        if (frameShadow == Plain) {
 
562
            QPen oldPen = p->pen();
 
563
            p->setPen(QPen(opt.palette.foreground().color(), lw));
 
564
            p->drawLine(p1, p2);
 
565
            p->setPen(oldPen);
 
566
        } else {
 
567
            qDrawShadeLine(p, p1, p2, opt.palette, frameShadow == Sunken, lw, mlw);
 
568
        }
 
569
        break;
 
570
    }
 
571
}
 
572
 
 
573
 
 
574
/*!\reimp
 
575
 */
 
576
void QFrame::changeEvent(QEvent *ev)
 
577
{
 
578
    Q_D(QFrame);
 
579
    if(ev->type() == QEvent::StyleChange)
 
580
        d->updateFrameWidth();
 
581
    QWidget::changeEvent(ev);
 
582
}
 
583
 
 
584