| /**************************************************************************** |
| ** |
| ** 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$ |
| ** GNU Lesser General Public License Usage |
| ** 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. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU General |
| ** Public License version 3.0 as published by the Free Software Foundation |
| ** and appearing in the file LICENSE.GPL included in the packaging of this |
| ** file. Please review the following information to ensure the GNU General |
| ** Public License version 3.0 requirements will be met: |
| ** http://www.gnu.org/copyleft/gpl.html. |
| ** |
| ** Other Usage |
| ** Alternatively, this file may be used in accordance with the terms and |
| ** conditions contained in a signed written agreement between you and Nokia. |
| ** |
| ** |
| ** |
| ** |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include "qcdestyle.h" |
| |
| #if !defined(QT_NO_STYLE_CDE) || defined(QT_PLUGIN) |
| |
| #include "qmenu.h" |
| #include "qapplication.h" |
| #include "qpainter.h" |
| #include "qdrawutil.h" |
| #include "qpixmap.h" |
| #include "qpalette.h" |
| #include "qwidget.h" |
| #include "qpushbutton.h" |
| #include "qscrollbar.h" |
| #include "qtabbar.h" |
| #include "qtabwidget.h" |
| #include "qlistview.h" |
| #include "qsplitter.h" |
| #include "qslider.h" |
| #include "qcombobox.h" |
| #include "qlineedit.h" |
| #include "qprogressbar.h" |
| #include "qimage.h" |
| #include "qfocusframe.h" |
| #include "qpainterpath.h" |
| #include "qdebug.h" |
| #include <limits.h> |
| |
| QT_BEGIN_NAMESPACE |
| |
| /*! |
| \class QCDEStyle |
| \brief The QCDEStyle class provides a CDE look and feel. |
| |
| \ingroup appearance |
| |
| This style provides a slightly improved Motif look similar to some |
| versions of the Common Desktop Environment (CDE). The main |
| differences are thinner frames and more modern radio buttons and |
| checkboxes. Together with a dark background and a bright |
| text/foreground color, the style looks quite attractive (at least |
| for Motif fans). |
| |
| Note that most of the functions provided by QCDEStyle are |
| reimplementations of QStyle functions; see QStyle for their |
| documentation. QCDEStyle provides overloads for drawControl() and |
| drawPrimitive() which are documented here. |
| |
| \img qcdestyle.png |
| \sa QWindowsXPStyle, QMacStyle, QWindowsStyle, QPlastiqueStyle, QMotifStyle |
| */ |
| |
| /*! |
| Constructs a QCDEStyle. |
| |
| If \a useHighlightCols is false (the default), then the style will |
| polish the application's color palette to emulate the Motif way of |
| highlighting, which is a simple inversion between the base and the |
| text color. |
| */ |
| QCDEStyle::QCDEStyle(bool useHighlightCols) |
| : QMotifStyle(useHighlightCols) |
| { |
| } |
| |
| /*! |
| Destroys the style. |
| */ |
| QCDEStyle::~QCDEStyle() |
| { |
| } |
| |
| |
| /*!\reimp |
| */ |
| int QCDEStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, |
| const QWidget *widget) const |
| /* |
| int QCDEStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, |
| const QWidget *widget) const |
| */ |
| { |
| int ret = 0; |
| |
| switch(metric) { |
| case PM_MenuBarPanelWidth: |
| case PM_DefaultFrameWidth: |
| case PM_FocusFrameVMargin: |
| case PM_FocusFrameHMargin: |
| case PM_MenuPanelWidth: |
| case PM_SpinBoxFrameWidth: |
| case PM_MenuBarVMargin: |
| case PM_MenuBarHMargin: |
| case PM_DockWidgetFrameWidth: |
| ret = 1; |
| break; |
| case PM_ScrollBarExtent: |
| ret = 13; |
| break; |
| default: |
| ret = QMotifStyle::pixelMetric(metric, option, widget); |
| break; |
| } |
| return ret; |
| } |
| |
| /*! |
| \reimp |
| */ |
| void QCDEStyle::drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, |
| const QWidget *widget) const |
| { |
| |
| switch(element) { |
| case CE_MenuBarItem: { |
| if (opt->state & State_Selected) // active item |
| qDrawShadePanel(p, opt->rect, opt->palette, true, 1, |
| &opt->palette.brush(QPalette::Button)); |
| else // other item |
| p->fillRect(opt->rect, opt->palette.brush(QPalette::Button)); |
| QCommonStyle::drawControl(element, opt, p, widget); |
| break; } |
| case CE_RubberBand: { |
| p->save(); |
| p->setClipping(false); |
| QPainterPath path; |
| path.addRect(opt->rect); |
| path.addRect(opt->rect.adjusted(2, 2, -2, -2)); |
| p->fillPath(path, opt->palette.color(QPalette::Active, QPalette::Text)); |
| p->restore(); |
| break; } |
| default: |
| QMotifStyle::drawControl(element, opt, p, widget); |
| break; |
| } |
| } |
| |
| /*! |
| \reimp |
| */ |
| void QCDEStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, |
| const QWidget *widget) const |
| { |
| switch(pe) { |
| case PE_IndicatorCheckBox: { |
| bool down = opt->state & State_Sunken; |
| bool on = opt->state & State_On; |
| bool showUp = !(down ^ on); |
| QBrush fill = (showUp || (opt->state & State_NoChange)) ? opt->palette.brush(QPalette::Button) : opt->palette.brush(QPalette::Mid); |
| qDrawShadePanel(p, opt->rect, opt->palette, !showUp, pixelMetric(PM_DefaultFrameWidth), &opt->palette.brush(QPalette::Button)); |
| |
| if (on || (opt->state & State_NoChange)) { |
| QRect r = opt->rect; |
| QPolygon a(7 * 2); |
| int i, xx, yy; |
| xx = r.x() + 3; |
| yy = r.y() + 5; |
| if (opt->rect.width() <= 9) { |
| // When called from CE_MenuItem in QMotifStyle |
| xx -= 2; |
| yy -= 2; |
| } |
| |
| for (i = 0; i < 3; i++) { |
| a.setPoint(2 * i, xx, yy); |
| a.setPoint(2 * i + 1, xx, yy + 2); |
| xx++; yy++; |
| } |
| yy -= 2; |
| for (i = 3; i < 7; i++) { |
| a.setPoint(2 * i, xx, yy); |
| a.setPoint(2 * i + 1, xx, yy + 2); |
| xx++; yy--; |
| } |
| if (opt->state & State_NoChange) |
| p->setPen(opt->palette.dark().color()); |
| else |
| p->setPen(opt->palette.foreground().color()); |
| p->drawPolyline(a); |
| } |
| if (!(opt->state & State_Enabled) && styleHint(SH_DitherDisabledText)) |
| p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern)); |
| } break; |
| case PE_IndicatorRadioButton: |
| { |
| QRect r = opt->rect; |
| #define INTARRLEN(x) sizeof(x)/(sizeof(int)*2) |
| static const int pts1[] = { // up left lines |
| 1,9, 1,8, 0,7, 0,4, 1,3, 1,2, 2,1, 3,1, 4,0, 7,0, 8,1, 9,1 }; |
| static const int pts4[] = { // bottom right lines |
| 2,10, 3,10, 4,11, 7,11, 8,10, 9,10, 10,9, 10,8, 11,7, |
| 11,4, 10,3, 10,2 }; |
| static const int pts5[] = { // inner fill |
| 4,2, 7,2, 9,4, 9,7, 7,9, 4,9, 2,7, 2,4 }; |
| bool down = opt->state & State_Sunken; |
| bool on = opt->state & State_On; |
| QPolygon a(INTARRLEN(pts1), pts1); |
| |
| //center when rect is larger than indicator size |
| int xOffset = 0; |
| int yOffset = 0; |
| int indicatorWidth = pixelMetric(PM_ExclusiveIndicatorWidth); |
| int indicatorHeight = pixelMetric(PM_ExclusiveIndicatorWidth); |
| if (r.width() > indicatorWidth) |
| xOffset += (r.width() - indicatorWidth)/2; |
| if (r.height() > indicatorHeight) |
| yOffset += (r.height() - indicatorHeight)/2; |
| p->translate(xOffset, yOffset); |
| |
| a.translate(r.x(), r.y()); |
| QPen oldPen = p->pen(); |
| QBrush oldBrush = p->brush(); |
| p->setPen((down || on) ? opt->palette.dark().color() : opt->palette.light().color()); |
| p->drawPolyline(a); |
| a.setPoints(INTARRLEN(pts4), pts4); |
| a.translate(r.x(), r.y()); |
| p->setPen((down || on) ? opt->palette.light().color() : opt->palette.dark().color()); |
| p->drawPolyline(a); |
| a.setPoints(INTARRLEN(pts5), pts5); |
| a.translate(r.x(), r.y()); |
| QColor fillColor = on ? opt->palette.dark().color() : opt->palette.background().color(); |
| p->setPen(fillColor); |
| p->setBrush(on ? opt->palette.brush(QPalette::Dark) : |
| opt->palette.brush(QPalette::Window)); |
| p->drawPolygon(a); |
| if (!(opt->state & State_Enabled) && styleHint(SH_DitherDisabledText)) |
| p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern)); |
| p->setPen(oldPen); |
| p->setBrush(oldBrush); |
| |
| p->translate(-xOffset, -yOffset); |
| |
| } break; |
| default: |
| QMotifStyle::drawPrimitive(pe, opt, p, widget); |
| } |
| } |
| |
| /*!\reimp*/ |
| QPalette QCDEStyle::standardPalette() const |
| { |
| QColor background(0xb6, 0xb6, 0xcf); |
| QColor light = background.lighter(); |
| QColor mid = background.darker(150); |
| QColor dark = background.darker(); |
| QPalette palette(Qt::black, background, light, dark, mid, Qt::black, Qt::white); |
| palette.setBrush(QPalette::Disabled, QPalette::WindowText, dark); |
| palette.setBrush(QPalette::Disabled, QPalette::Text, dark); |
| palette.setBrush(QPalette::Disabled, QPalette::ButtonText, dark); |
| palette.setBrush(QPalette::Disabled, QPalette::Base, background); |
| return palette; |
| } |
| |
| /*! |
| \internal |
| */ |
| QIcon QCDEStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt, |
| const QWidget *widget) const |
| { |
| return QMotifStyle::standardIconImplementation(standardIcon, opt, widget); |
| } |
| |
| QT_END_NAMESPACE |
| |
| #endif |