[2] | 1 | /****************************************************************************
|
---|
| 2 | **
|
---|
[846] | 3 | ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
---|
[561] | 4 | ** All rights reserved.
|
---|
| 5 | ** Contact: Nokia Corporation (qt-info@nokia.com)
|
---|
[2] | 6 | **
|
---|
| 7 | ** This file is part of the QtGui module of the Qt Toolkit.
|
---|
| 8 | **
|
---|
| 9 | ** $QT_BEGIN_LICENSE:LGPL$
|
---|
| 10 | ** Commercial Usage
|
---|
| 11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
| 12 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
| 13 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
| 14 | ** a written agreement between you and Nokia.
|
---|
| 15 | **
|
---|
| 16 | ** GNU Lesser General Public License Usage
|
---|
| 17 | ** Alternatively, this file may be used under the terms of the GNU Lesser
|
---|
| 18 | ** General Public License version 2.1 as published by the Free Software
|
---|
| 19 | ** Foundation and appearing in the file LICENSE.LGPL included in the
|
---|
| 20 | ** packaging of this file. Please review the following information to
|
---|
| 21 | ** ensure the GNU Lesser General Public License version 2.1 requirements
|
---|
| 22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
---|
| 23 | **
|
---|
[561] | 24 | ** In addition, as a special exception, Nokia gives you certain additional
|
---|
| 25 | ** rights. These rights are described in the Nokia Qt LGPL Exception
|
---|
| 26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
---|
[2] | 27 | **
|
---|
| 28 | ** GNU General Public License Usage
|
---|
| 29 | ** Alternatively, this file may be used under the terms of the GNU
|
---|
| 30 | ** General Public License version 3.0 as published by the Free Software
|
---|
| 31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
| 32 | ** packaging of this file. Please review the following information to
|
---|
| 33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
---|
| 34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
---|
| 35 | **
|
---|
[561] | 36 | ** If you have questions regarding the use of this file, please contact
|
---|
| 37 | ** Nokia at qt-info@nokia.com.
|
---|
[2] | 38 | ** $QT_END_LICENSE$
|
---|
| 39 | **
|
---|
| 40 | ****************************************************************************/
|
---|
| 41 |
|
---|
| 42 | #include "qcdestyle.h"
|
---|
| 43 |
|
---|
| 44 | #if !defined(QT_NO_STYLE_CDE) || defined(QT_PLUGIN)
|
---|
| 45 |
|
---|
| 46 | #include "qmenu.h"
|
---|
| 47 | #include "qapplication.h"
|
---|
| 48 | #include "qpainter.h"
|
---|
| 49 | #include "qdrawutil.h"
|
---|
| 50 | #include "qpixmap.h"
|
---|
| 51 | #include "qpalette.h"
|
---|
| 52 | #include "qwidget.h"
|
---|
| 53 | #include "qpushbutton.h"
|
---|
| 54 | #include "qscrollbar.h"
|
---|
| 55 | #include "qtabbar.h"
|
---|
| 56 | #include "qtabwidget.h"
|
---|
| 57 | #include "qlistview.h"
|
---|
| 58 | #include "qsplitter.h"
|
---|
| 59 | #include "qslider.h"
|
---|
| 60 | #include "qcombobox.h"
|
---|
| 61 | #include "qlineedit.h"
|
---|
| 62 | #include "qprogressbar.h"
|
---|
| 63 | #include "qimage.h"
|
---|
| 64 | #include "qfocusframe.h"
|
---|
| 65 | #include "qpainterpath.h"
|
---|
| 66 | #include "qdebug.h"
|
---|
| 67 | #include <limits.h>
|
---|
| 68 |
|
---|
| 69 | QT_BEGIN_NAMESPACE
|
---|
| 70 |
|
---|
| 71 | /*!
|
---|
| 72 | \class QCDEStyle
|
---|
| 73 | \brief The QCDEStyle class provides a CDE look and feel.
|
---|
| 74 |
|
---|
| 75 | \ingroup appearance
|
---|
| 76 |
|
---|
| 77 | This style provides a slightly improved Motif look similar to some
|
---|
| 78 | versions of the Common Desktop Environment (CDE). The main
|
---|
| 79 | differences are thinner frames and more modern radio buttons and
|
---|
| 80 | checkboxes. Together with a dark background and a bright
|
---|
| 81 | text/foreground color, the style looks quite attractive (at least
|
---|
| 82 | for Motif fans).
|
---|
| 83 |
|
---|
| 84 | Note that most of the functions provided by QCDEStyle are
|
---|
| 85 | reimplementations of QStyle functions; see QStyle for their
|
---|
| 86 | documentation. QCDEStyle provides overloads for drawControl() and
|
---|
| 87 | drawPrimitive() which are documented here.
|
---|
| 88 |
|
---|
| 89 | \img qcdestyle.png
|
---|
| 90 | \sa QWindowsXPStyle, QMacStyle, QWindowsStyle, QPlastiqueStyle, QMotifStyle
|
---|
| 91 | */
|
---|
| 92 |
|
---|
| 93 | /*!
|
---|
| 94 | Constructs a QCDEStyle.
|
---|
| 95 |
|
---|
| 96 | If \a useHighlightCols is false (the default), then the style will
|
---|
| 97 | polish the application's color palette to emulate the Motif way of
|
---|
| 98 | highlighting, which is a simple inversion between the base and the
|
---|
| 99 | text color.
|
---|
| 100 | */
|
---|
| 101 | QCDEStyle::QCDEStyle(bool useHighlightCols)
|
---|
| 102 | : QMotifStyle(useHighlightCols)
|
---|
| 103 | {
|
---|
| 104 | }
|
---|
| 105 |
|
---|
| 106 | /*!
|
---|
| 107 | Destroys the style.
|
---|
| 108 | */
|
---|
| 109 | QCDEStyle::~QCDEStyle()
|
---|
| 110 | {
|
---|
| 111 | }
|
---|
| 112 |
|
---|
| 113 |
|
---|
| 114 | /*!\reimp
|
---|
| 115 | */
|
---|
| 116 | int QCDEStyle::pixelMetric(PixelMetric metric, const QStyleOption *option,
|
---|
| 117 | const QWidget *widget) const
|
---|
| 118 | /*
|
---|
| 119 | int QCDEStyle::pixelMetric(PixelMetric metric, const QStyleOption *option,
|
---|
| 120 | const QWidget *widget) const
|
---|
| 121 | */
|
---|
| 122 | {
|
---|
| 123 | int ret = 0;
|
---|
| 124 |
|
---|
| 125 | switch(metric) {
|
---|
| 126 | case PM_MenuBarPanelWidth:
|
---|
| 127 | case PM_DefaultFrameWidth:
|
---|
| 128 | case PM_FocusFrameVMargin:
|
---|
| 129 | case PM_FocusFrameHMargin:
|
---|
| 130 | case PM_MenuPanelWidth:
|
---|
| 131 | case PM_SpinBoxFrameWidth:
|
---|
| 132 | case PM_MenuBarVMargin:
|
---|
| 133 | case PM_MenuBarHMargin:
|
---|
| 134 | case PM_DockWidgetFrameWidth:
|
---|
| 135 | ret = 1;
|
---|
| 136 | break;
|
---|
| 137 | case PM_ScrollBarExtent:
|
---|
| 138 | ret = 13;
|
---|
| 139 | break;
|
---|
| 140 | default:
|
---|
| 141 | ret = QMotifStyle::pixelMetric(metric, option, widget);
|
---|
| 142 | break;
|
---|
| 143 | }
|
---|
| 144 | return ret;
|
---|
| 145 | }
|
---|
| 146 |
|
---|
| 147 | /*!
|
---|
| 148 | \reimp
|
---|
| 149 | */
|
---|
| 150 | void QCDEStyle::drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
|
---|
| 151 | const QWidget *widget) const
|
---|
| 152 | {
|
---|
| 153 |
|
---|
| 154 | switch(element) {
|
---|
| 155 | case CE_MenuBarItem: {
|
---|
| 156 | if (opt->state & State_Selected) // active item
|
---|
| 157 | qDrawShadePanel(p, opt->rect, opt->palette, true, 1,
|
---|
| 158 | &opt->palette.brush(QPalette::Button));
|
---|
| 159 | else // other item
|
---|
| 160 | p->fillRect(opt->rect, opt->palette.brush(QPalette::Button));
|
---|
| 161 | QCommonStyle::drawControl(element, opt, p, widget);
|
---|
| 162 | break; }
|
---|
| 163 | case CE_RubberBand: {
|
---|
| 164 | p->save();
|
---|
| 165 | p->setClipping(false);
|
---|
| 166 | QPainterPath path;
|
---|
| 167 | path.addRect(opt->rect);
|
---|
| 168 | path.addRect(opt->rect.adjusted(2, 2, -2, -2));
|
---|
| 169 | p->fillPath(path, opt->palette.color(QPalette::Active, QPalette::Text));
|
---|
| 170 | p->restore();
|
---|
| 171 | break; }
|
---|
| 172 | default:
|
---|
| 173 | QMotifStyle::drawControl(element, opt, p, widget);
|
---|
| 174 | break;
|
---|
| 175 | }
|
---|
| 176 | }
|
---|
| 177 |
|
---|
| 178 | /*!
|
---|
| 179 | \reimp
|
---|
| 180 | */
|
---|
| 181 | void QCDEStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
|
---|
| 182 | const QWidget *widget) const
|
---|
| 183 | {
|
---|
| 184 | switch(pe) {
|
---|
| 185 | case PE_IndicatorCheckBox: {
|
---|
| 186 | bool down = opt->state & State_Sunken;
|
---|
| 187 | bool on = opt->state & State_On;
|
---|
| 188 | bool showUp = !(down ^ on);
|
---|
| 189 | QBrush fill = (showUp || (opt->state & State_NoChange)) ? opt->palette.brush(QPalette::Button) : opt->palette.brush(QPalette::Mid);
|
---|
| 190 | qDrawShadePanel(p, opt->rect, opt->palette, !showUp, pixelMetric(PM_DefaultFrameWidth), &opt->palette.brush(QPalette::Button));
|
---|
| 191 |
|
---|
| 192 | if (on || (opt->state & State_NoChange)) {
|
---|
| 193 | QRect r = opt->rect;
|
---|
| 194 | QPolygon a(7 * 2);
|
---|
| 195 | int i, xx, yy;
|
---|
| 196 | xx = r.x() + 3;
|
---|
| 197 | yy = r.y() + 5;
|
---|
| 198 | if (opt->rect.width() <= 9) {
|
---|
| 199 | // When called from CE_MenuItem in QMotifStyle
|
---|
| 200 | xx -= 2;
|
---|
| 201 | yy -= 2;
|
---|
| 202 | }
|
---|
| 203 |
|
---|
| 204 | for (i = 0; i < 3; i++) {
|
---|
| 205 | a.setPoint(2 * i, xx, yy);
|
---|
| 206 | a.setPoint(2 * i + 1, xx, yy + 2);
|
---|
| 207 | xx++; yy++;
|
---|
| 208 | }
|
---|
| 209 | yy -= 2;
|
---|
| 210 | for (i = 3; i < 7; i++) {
|
---|
| 211 | a.setPoint(2 * i, xx, yy);
|
---|
| 212 | a.setPoint(2 * i + 1, xx, yy + 2);
|
---|
| 213 | xx++; yy--;
|
---|
| 214 | }
|
---|
| 215 | if (opt->state & State_NoChange)
|
---|
| 216 | p->setPen(opt->palette.dark().color());
|
---|
| 217 | else
|
---|
| 218 | p->setPen(opt->palette.foreground().color());
|
---|
| 219 | p->drawPolyline(a);
|
---|
| 220 | }
|
---|
| 221 | if (!(opt->state & State_Enabled) && styleHint(SH_DitherDisabledText))
|
---|
| 222 | p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern));
|
---|
| 223 | } break;
|
---|
| 224 | case PE_IndicatorRadioButton:
|
---|
| 225 | {
|
---|
| 226 | QRect r = opt->rect;
|
---|
| 227 | #define INTARRLEN(x) sizeof(x)/(sizeof(int)*2)
|
---|
| 228 | static const int pts1[] = { // up left lines
|
---|
| 229 | 1,9, 1,8, 0,7, 0,4, 1,3, 1,2, 2,1, 3,1, 4,0, 7,0, 8,1, 9,1 };
|
---|
| 230 | static const int pts4[] = { // bottom right lines
|
---|
| 231 | 2,10, 3,10, 4,11, 7,11, 8,10, 9,10, 10,9, 10,8, 11,7,
|
---|
| 232 | 11,4, 10,3, 10,2 };
|
---|
| 233 | static const int pts5[] = { // inner fill
|
---|
| 234 | 4,2, 7,2, 9,4, 9,7, 7,9, 4,9, 2,7, 2,4 };
|
---|
| 235 | bool down = opt->state & State_Sunken;
|
---|
| 236 | bool on = opt->state & State_On;
|
---|
| 237 | QPolygon a(INTARRLEN(pts1), pts1);
|
---|
| 238 |
|
---|
| 239 | //center when rect is larger than indicator size
|
---|
| 240 | int xOffset = 0;
|
---|
| 241 | int yOffset = 0;
|
---|
| 242 | int indicatorWidth = pixelMetric(PM_ExclusiveIndicatorWidth);
|
---|
| 243 | int indicatorHeight = pixelMetric(PM_ExclusiveIndicatorWidth);
|
---|
| 244 | if (r.width() > indicatorWidth)
|
---|
| 245 | xOffset += (r.width() - indicatorWidth)/2;
|
---|
| 246 | if (r.height() > indicatorHeight)
|
---|
| 247 | yOffset += (r.height() - indicatorHeight)/2;
|
---|
| 248 | p->translate(xOffset, yOffset);
|
---|
| 249 |
|
---|
| 250 | a.translate(r.x(), r.y());
|
---|
| 251 | QPen oldPen = p->pen();
|
---|
| 252 | QBrush oldBrush = p->brush();
|
---|
| 253 | p->setPen((down || on) ? opt->palette.dark().color() : opt->palette.light().color());
|
---|
| 254 | p->drawPolyline(a);
|
---|
| 255 | a.setPoints(INTARRLEN(pts4), pts4);
|
---|
| 256 | a.translate(r.x(), r.y());
|
---|
| 257 | p->setPen((down || on) ? opt->palette.light().color() : opt->palette.dark().color());
|
---|
| 258 | p->drawPolyline(a);
|
---|
| 259 | a.setPoints(INTARRLEN(pts5), pts5);
|
---|
| 260 | a.translate(r.x(), r.y());
|
---|
| 261 | QColor fillColor = on ? opt->palette.dark().color() : opt->palette.background().color();
|
---|
| 262 | p->setPen(fillColor);
|
---|
| 263 | p->setBrush(on ? opt->palette.brush(QPalette::Dark) :
|
---|
| 264 | opt->palette.brush(QPalette::Window));
|
---|
| 265 | p->drawPolygon(a);
|
---|
| 266 | if (!(opt->state & State_Enabled) && styleHint(SH_DitherDisabledText))
|
---|
| 267 | p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern));
|
---|
| 268 | p->setPen(oldPen);
|
---|
| 269 | p->setBrush(oldBrush);
|
---|
| 270 |
|
---|
| 271 | p->translate(-xOffset, -yOffset);
|
---|
| 272 |
|
---|
| 273 | } break;
|
---|
| 274 | default:
|
---|
| 275 | QMotifStyle::drawPrimitive(pe, opt, p, widget);
|
---|
| 276 | }
|
---|
| 277 | }
|
---|
| 278 |
|
---|
| 279 | /*!\reimp*/
|
---|
| 280 | QPalette QCDEStyle::standardPalette() const
|
---|
| 281 | {
|
---|
| 282 | QColor background(0xb6, 0xb6, 0xcf);
|
---|
| 283 | QColor light = background.lighter();
|
---|
| 284 | QColor mid = background.darker(150);
|
---|
| 285 | QColor dark = background.darker();
|
---|
| 286 | QPalette palette(Qt::black, background, light, dark, mid, Qt::black, Qt::white);
|
---|
| 287 | palette.setBrush(QPalette::Disabled, QPalette::WindowText, dark);
|
---|
| 288 | palette.setBrush(QPalette::Disabled, QPalette::Text, dark);
|
---|
| 289 | palette.setBrush(QPalette::Disabled, QPalette::ButtonText, dark);
|
---|
| 290 | palette.setBrush(QPalette::Disabled, QPalette::Base, background);
|
---|
| 291 | return palette;
|
---|
| 292 | }
|
---|
| 293 |
|
---|
| 294 | /*!
|
---|
| 295 | \internal
|
---|
| 296 | */
|
---|
| 297 | QIcon QCDEStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt,
|
---|
| 298 | const QWidget *widget) const
|
---|
| 299 | {
|
---|
| 300 | return QMotifStyle::standardIconImplementation(standardIcon, opt, widget);
|
---|
| 301 | }
|
---|
| 302 |
|
---|
| 303 | QT_END_NAMESPACE
|
---|
| 304 |
|
---|
| 305 | #endif
|
---|