/**************************************************************************** | |
** | |
** 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 |