diff options
Diffstat (limited to 'src/fqterm/3rdparty/dotnetstyle.cpp')
-rw-r--r-- | src/fqterm/3rdparty/dotnetstyle.cpp | 1274 |
1 files changed, 1274 insertions, 0 deletions
diff --git a/src/fqterm/3rdparty/dotnetstyle.cpp b/src/fqterm/3rdparty/dotnetstyle.cpp new file mode 100644 index 0000000..d016ff2 --- /dev/null +++ b/src/fqterm/3rdparty/dotnetstyle.cpp @@ -0,0 +1,1274 @@ +/**************************************************************************** +** +** Copyright (C) 2007-2007 Trolltech ASA. All rights reserved. +** +** This file is part of the DotNetStyle project on Trolltech Labs. +** +** This file may be used under the terms of the GNU General Public +** License version 2.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 GNU +** General Public Licensing requirements will be met: +** http://www.trolltech.com/products/qt/opensource.html +** +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://www.trolltech.com/products/qt/licensing.html or contact the +** sales department at sales@trolltech.com. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#ifdef USE_DOTNET_STYLE +#include "dotnetstyle.h" +#include <QStyleOption> +#include <QPainter> +#include <QMainWindow> +#include <QDockWidget> +#include <QDialogButtonBox> +#include <QToolBar> +#include <QDialog> +#include <QLineEdit> +#include <QComboBox> +#include <QLibrary> +#include <QStatusBar> +#include <QApplication> +#include <qt_windows.h> + +typedef bool (WINAPI *PtrIsAppThemed)(); +typedef HRESULT (WINAPI *PtrGetCurrentThemeName)(OUT LPWSTR pszThemeFileName, int cchMaxNameChars, OUT OPTIONAL LPWSTR pszColorBuff, int cchMaxColorChars, OUT OPTIONAL LPWSTR pszSizeBuff, int cchMaxSizeChars); + +static PtrIsAppThemed pIsAppThemed = 0; +static PtrGetCurrentThemeName pGetCurrentThemeName = 0; + +static const int windowsItemFrame = 2; // menu item frame width +static const int windowsSepHeight = 9; // separator item height +static const int windowsItemHMargin = 3; // menu item hor text margin +static const int windowsItemVMargin = 2; // menu item ver text margin +static const int windowsArrowHMargin = 6; // arrow horizontal margin +static const int windowsRightBorder = 15; // right border on windows + +class DotNetStylePrivate +{ +public: + DotNetStylePrivate() + { + QLibrary themeLib("uxtheme"); + themeLib.load(); + if (themeLib.isLoaded()) { //resolve uxtheme functions + pIsAppThemed = (PtrIsAppThemed)themeLib.resolve("IsAppThemed"); + pGetCurrentThemeName = (PtrGetCurrentThemeName)themeLib.resolve("GetCurrentThemeName"); + } + } + ~DotNetStylePrivate() + {} + + enum InternalPalette { + Blue, + Silver, + Olive, + System, + Classic + }; + + void init(); + QColor gradientDarkColor(const QStyleOption *option) const; + QColor gradientLightColor(const QStyleOption *option) const; + QColor highlightOutlineColor(const QStyleOption *option, bool act) const; + QColor shadowColor(const QStyleOption *option) const; + QBrush highlightBrush(const QStyleOption *option, bool act) const; + QBrush highlightMenuCheckBrush(const QStyleOption *option, bool act) const; + QLinearGradient toolbarGradient(const QStyleOption *option, QRect rect, Qt::Orientation orientaion) const; + QLinearGradient menuGradient(const QStyleOption *option, QRect rect, Qt::Orientation orientaion) const; + void updatePalette(); + + QColor menuSeparatorColor; + QColor menuBackgroundColor; + QColor menuFrameColor; + InternalPalette internalPalette; //internal color theme + DotNetStyle::ColorTheme theme; //external color theme + QPalette currentPal; //used to detect system palette changes + }; + + + +inline QColor DotNetStylePrivate::gradientDarkColor(const QStyleOption *option) const { + QColor color = option->palette.background().color(); + switch (internalPalette) { + case Olive: + color = QColor(217, 217, 167); + break; + case Blue: + color = QColor(158, 190, 245); + break; + case Silver: + color = QColor(216, 216, 229); + break; + default: + break; + } + return color; +} + +inline QColor DotNetStylePrivate::gradientLightColor(const QStyleOption *option) const { + QColor color = option->palette.background().color().lighter(106); + switch (internalPalette) { + case Olive: + color = QColor(241, 240, 227); + break; + case Blue: + color = QColor(196, 217, 249); + break; + case Silver: + color = QColor(242, 242, 247); + break; + case Classic: + color = option->palette.light().color().lighter(106); + default: + break; + } + return color; +} + +inline QColor DotNetStylePrivate::shadowColor(const QStyleOption *option) const { + QColor color; + switch (internalPalette) { + case Blue: + color = QColor(59, 97, 156); + break; + case Silver: + color = QColor(124, 124, 148); + break; + case Olive: + color = QColor(96, 128, 88); + break; + case Classic: + color = option->palette.background().color(); + break; + default: + color = option->palette.dark().color(); + break; + } + return color; +} + +inline QColor DotNetStylePrivate::highlightOutlineColor(const QStyleOption *option, bool act = false) const { + QColor color; + switch (internalPalette) { + case Blue: + color = QColor(0, 0, 128); + break; + case Silver: + color = QColor(75, 75, 111); + break; + case Olive: + color = QColor(63, 93, 56); + break; + default: + if (act) + return option->palette.highlight().color().darker(110); + else + return option->palette.highlight().color().lighter(110); + break; + } + return color; +} + +QBrush DotNetStylePrivate::highlightBrush(const QStyleOption *option, bool act) const { + QBrush brush; + QColor highlight; + switch (internalPalette) { + case Silver: + case Olive: + case Blue: + if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) { + brush = QColor(255, 238, 194); + } else { + QLinearGradient gradient(option->rect.topLeft(), option->rect.bottomLeft()); + if (act) { + gradient.setColorAt(0, QColor(254, 149, 82)); + gradient.setColorAt(1, QColor(255, 211, 142)); + } else { + gradient.setColorAt(0, QColor(255, 252, 200)); + gradient.setColorAt(1, QColor(255, 208, 145)); + } + brush = gradient; + } + break; + default: + highlight = option->palette.highlight().color().lighter(120); + if (act) + highlight.setHsv(highlight.hue(), 70, 220); + else + highlight.setHsv(highlight.hue(), 40, 230); + brush = QBrush(highlight); + break; + } + return brush; +} + +QBrush DotNetStylePrivate::highlightMenuCheckBrush(const QStyleOption *option, bool act) const { + QBrush brush; + QColor highlight; + + switch (internalPalette) { + case Silver: + case Olive: + case Blue: + if (act) + brush = QColor(254, 128, 62); + else + brush = QColor(255, 192, 111); + break; + default: + highlight = option->palette.highlight().color().lighter(120); + if (act) + highlight.setHsv(highlight.hue(), 120, 180); + else { + highlight.setHsv(highlight.hue(), 30, 230); + } + highlight.setAlpha(170); + brush = highlight; + break; + } + return brush; +} + +QLinearGradient DotNetStylePrivate::toolbarGradient(const QStyleOption *option, QRect rect, Qt::Orientation orientation= Qt::Vertical) const { + QLinearGradient gradient(rect.topLeft(), orientation == Qt::Vertical ? rect.topRight() : rect.bottomLeft()); + QColor start, stop; + switch (internalPalette) + { + case Blue: + start = QColor(220, 235, 254); + stop = QColor(129, 169, 226); + gradient.setColorAt(0.3, start); + break; + case Silver: + start = QColor(242, 242, 249); + stop = QColor(153, 151, 181); + gradient.setColorAt(0.3, start); + break; + case Olive: + start = QColor(241, 245, 217); + stop = QColor(183, 198, 145); + gradient.setColorAt(0.0, start); + break; + default: + start = option->palette.light().color(); + if (internalPalette == Classic) + start = start.lighter(130); + start.setAlpha(180); + stop = option->palette.button().color(); + stop.setHsv(stop.hue(), qMin(stop.saturation()*2, 255), (stop.value()*2)/3); + stop.setAlpha(128); + if (internalPalette == Classic) + stop.setAlpha(0); + gradient.setColorAt(0.3, start); + break; + } + gradient.setColorAt(1, stop); + return gradient; +} + + +QLinearGradient DotNetStylePrivate::menuGradient(const QStyleOption *option, QRect rect, Qt::Orientation orientaion = Qt::Horizontal) const { + + QColor start, stop; + QLinearGradient grad; + if (orientaion == Qt::Vertical) { + grad.setStart(rect.left(), rect.top()); + grad.setFinalStop(rect.left(), rect.bottom()); + } else { + grad.setStart(QPoint(rect.left(), 0)); + grad.setFinalStop(QPoint(rect.left() + 24, 0)); + } + switch (internalPalette) + { + case Blue: + start = QColor(220, 235, 254); + stop = QColor(129, 169, 226); + grad.setColorAt(0.3, start); + break; + case Olive: + start = QColor(246, 248, 224); + stop = QColor(186, 201, 148); + grad.setColorAt(0.0, start); + break; + case Silver: + start = QColor(215, 215, 226); + stop = QColor(138, 137, 166); + grad.setColorAt(0.4, start); + break; + default: + start = option->palette.brush(QPalette::Active, QPalette::Base).color(); + stop = gradientDarkColor(option); + stop.setHsv(stop.hue(), qMin((int)(stop.saturation()*1.2), 255), (5*stop.value()/7)); + if (internalPalette == Classic) + stop.setAlpha(120); + grad.setColorAt(0, start); + break; + } + grad.setColorAt(1, stop); + return grad; +} + + + +/*! + \class DotNetStyle qtdotnetstyle.h + \brief The DotNetStyle class provides an alternative, modern look for Qt applications on Windows. + + The GUI look is very similar to the style introduced in + Visual Studio 2005, Office 2003 as well as in .NET Windows + Forms (when the RenderMode is set to "Professional" + instead of "System"). It gives applications a modern + gradient appearance for tool bars and menus while + retaining the native look and feel for other widgets. + + The style supports different color themes, which may be specified in + the constructor. The default is \c Standard color theme. + + This is the textedit example running with the Standard style: + \img dotnetstyle.png + + This is the textedit example running with the Office style: + \img dotnetstyle2.png + + \sa QStyle, QWindowsVistaStyle, QWindowsXPStyle +*/ + + +/*! + \enum DotNetStyle::ColorTheme + + This enum describes the different color schemes supported by the style. + + \value Standard Use gradients based on the operating system palette. + \value Office Use Microsoft Office 2003 style gradients. +*/ + +/*! + Constructs a DotNetStyle object which uses the default color + theme (\c Office). +*/ +DotNetStyle::DotNetStyle() +: QWindowsVistaStyle(), d(new DotNetStylePrivate()) +{ + d->theme = Office; +} + + +/*! + Constructs a DotNetStyle object which uses the color theme \a + colortheme. +*/ +DotNetStyle::DotNetStyle(ColorTheme colortheme) + : QWindowsVistaStyle(), d(new DotNetStylePrivate()) +{ + d->theme = colortheme; +} + + +/*! + Destroys the DotNetStyle object. +*/ +DotNetStyle::~DotNetStyle() +{ + delete d; +} + + +/*! + \reimp + */ +void DotNetStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, + QPainter *painter, const QWidget *widget) const +{ + QColor gradientDark = d->gradientDarkColor(option); + QColor gradientLight = d->gradientLightColor(option); + QColor shadow = d->shadowColor(option); + + QRect rect = option->rect; + switch (element) { + case PE_IndicatorDockWidgetResizeHandle: + break; + case PE_PanelLineEdit: + if (widget && qobject_cast<QToolBar*>(widget->parentWidget())) { + QRect rect = option->rect.adjusted(2, 1, -2, -2); + painter->save(); + bool active = option->state & State_Active && + ((option->state & State_MouseOver) + || (option->state & State_HasFocus)); + QBrush editBrush = option->palette.brush(QPalette::Base); + painter->setPen(QPen(editBrush.color())); + painter->fillRect(rect, editBrush); + + QRect re = option->rect ; + if (active) { + painter->setPen(d->highlightOutlineColor(option)); + painter->drawRect(rect); + } + painter->restore(); + } else { + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + QWindowsVistaStyle::drawPrimitive(element, option, painter, widget); + else + QWindowsXPStyle::drawPrimitive(element, option, painter, widget); + } + case PE_PanelButtonTool: + { + QStyleOption opt2 = *option; + if (widget) + if(QDockWidget *dw = qobject_cast<QDockWidget *>(widget->parentWidget())) { + if (!dw->isFloating()) + opt2.palette.setBrush(QPalette::Button, Qt::transparent); + } + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + QWindowsVistaStyle::drawPrimitive(element, &opt2, painter, widget); + else + QWindowsXPStyle::drawPrimitive(element, &opt2, painter, widget); + } + break; + case PE_FrameMenu: + { + QPen pen = painter->pen(); + QBrush brush = painter->brush(); + if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar*>(option)) + { + Qt::Orientation orientation =(toolbar->toolBarArea == Qt::RightToolBarArea || + toolbar->toolBarArea == Qt::LeftToolBarArea) ? + Qt::Vertical : Qt::Horizontal; + painter->setBrush(d->toolbarGradient(toolbar, toolbar->rect, orientation)); + } else { + painter->setBrush(d->menuBackgroundColor); + } + painter->setPen(d->menuFrameColor); + painter->drawRect(option->rect.adjusted(0, 0, -1, -1)); + painter->setPen(pen); + painter->setBrush(brush); + } + break; + case PE_Widget: + if (const QMainWindow *mw = qobject_cast<const QMainWindow *>(widget)) { + if (d->currentPal != qApp->palette()) //workaround for style polish on theme color change + { + d->currentPal = qApp->palette(); + d->updatePalette(); + } + painter->save(); + QPoint begin = widget->geometry().topRight(); + QPoint end = widget->geometry().topLeft() + QPoint(0, widget->geometry().height()/2); + begin = widget->mapFromGlobal(begin); + end = widget->mapFromGlobal(end); + QLinearGradient menubargradient(begin, end); + menubargradient.setColorAt(0, gradientLight); + if (d->internalPalette == DotNetStylePrivate::System) + menubargradient.setColorAt(0.3, gradientDark); + else + menubargradient.setColorAt(0.8, gradientDark); + menubargradient.setColorAt(1, gradientDark); + QRect windowRect = option->rect; + if (QStatusBar *statusBar = mw->findChild<QStatusBar*>()) { + windowRect.adjust(0, 0, 0, -statusBar->height()); + painter->setPen(option->palette.background().color().lighter(106)); + painter->drawLine(windowRect.bottomLeft() + QPoint(0, 1), + windowRect.bottomRight() + QPoint(0, 1)); + } + painter->fillRect(windowRect, menubargradient); + painter->restore(); + } + break; + case PE_IndicatorToolBarSeparator: + { + QRect rect = option->rect; + shadow.setAlpha(180); + painter->setPen(shadow); + const int margin = 3; + if (option->state & State_Horizontal) { + const int offset = rect.width()/2; + painter->drawLine(rect.bottomLeft().x() + offset, + rect.bottomLeft().y() - margin, + rect.topLeft().x() + offset, + rect.topLeft().y() + margin); + painter->setPen(QPen(option->palette.background().color().light(110))); + painter->drawLine(rect.bottomLeft().x() + offset + 1, + rect.bottomLeft().y() - margin, + rect.topLeft().x() + offset + 1, + rect.topLeft().y() + margin); + } else { //Draw vertical separator + const int offset = rect.height()/2; + painter->setPen(QPen(option->palette.background().color().dark(110))); + painter->drawLine(rect.topLeft().x() + margin , + rect.topLeft().y() + offset, + rect.topRight().x() - margin, + rect.topRight().y() + offset); + painter->setPen(QPen(option->palette.background().color().light(110))); + painter->drawLine(rect.topLeft().x() + margin , + rect.topLeft().y() + offset + 1, + rect.topRight().x() - margin, + rect.topRight().y() + offset + 1); + } + } + break; + case PE_IndicatorToolBarHandle: + painter->save(); + { + QColor gripColor = shadow; + if (d->internalPalette != DotNetStylePrivate::System) + gripColor = shadow.darker(120); + if (option->state & State_Horizontal) { + for (int i = rect.height()/5; i <= 4*(rect.height()/5) ; i+=4) { + int y = rect.topLeft().y() + i + 1; + int x1 = rect.topLeft().x() + 3; + painter->fillRect(x1 + 1, y, 2, 2, Qt::white); + painter->fillRect(x1, y - 1, 2, 2, gripColor); + } + } + else { //vertical toolbar + for (int i = rect.width()/5; i <= 4*(rect.width()/5) ; i+=4) { + int x = rect.topLeft().x() + i + 1; + int y1 = rect.topLeft().y() + 3; + painter->fillRect(x , y1 + 1, 2, 2, Qt::white); + painter->fillRect(x - 1, y1, 2, 2, gripColor); + } + } + } + painter->restore(); + break; + case PE_PanelMenuBar: + break; + default: + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + QWindowsVistaStyle::drawPrimitive(element, option, painter, widget); + else + QWindowsXPStyle::drawPrimitive(element, option, painter, widget); + break; + } +} + +/*! + \reimp + */ +void DotNetStyle::drawControl(ControlElement element, const QStyleOption *option, + QPainter *painter, const QWidget *widget) const +{ + + QColor gradientDark = d->gradientDarkColor(option); + QColor gradientLight = d->gradientLightColor(option); + QColor shadow = d->shadowColor(option); + QRect rect = option->rect; + + switch (element) { +#ifndef QT_NO_MENU + case CE_MenuItem: + painter->save(); + if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) { + int x, y, w, h; + QStyleOptionMenuItem mbiCopy = *menuitem; + painter->fillRect(rect, d->menuBackgroundColor); + painter->fillRect(QRect(0, rect.top(), 25, rect.bottom()), d->menuGradient(option, rect)); + menuitem->rect.getRect(&x, &y, &w, &h); + + int tab = menuitem->tabWidth; + bool dis = !(menuitem->state & State_Enabled); + bool checked = menuitem->checkType != QStyleOptionMenuItem::NotCheckable + ? menuitem->checked : false; + bool act = menuitem->state & State_Selected; + + // windows always has a check column, regardless whether we have an icon or not + int checkcol = qMax(menuitem->maxIconWidth, 20); + if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) { + int yoff = y-1 + h / 2; + painter->setPen(d->menuSeparatorColor); + painter->drawLine(x + 32, yoff, x + w + 6, yoff); + painter->restore(); + return; + } + + QRect vCheckRect = visualRect(option->direction, menuitem->rect, + QRect(menuitem->rect.x(), menuitem->rect.y(), checkcol, menuitem->rect.height())); + vCheckRect.adjust(2, 0, 0, 0); + + if (act) { + painter->setPen(d->highlightOutlineColor(option)); + painter->setBrush(d->highlightBrush(option, false)); + painter->drawRect(option->rect.adjusted(0, 0, -2, -2)); + } + + if (!menuitem->icon.isNull()) { + QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal; + if (act && !dis) + mode = QIcon::Active; + QPixmap pixmap; + if (checked) + pixmap = menuitem->icon.pixmap(pixelMetric(PM_SmallIconSize), mode, QIcon::On); + else + pixmap = menuitem->icon.pixmap(pixelMetric(PM_SmallIconSize), mode); + int pixw = pixmap.width(); + int pixh = pixmap.height(); + QRect pmr(0, 0, pixw, pixh); + pmr.moveCenter(vCheckRect.center()); + painter->setPen(menuitem->palette.text().color()); + painter->drawPixmap(pmr.topLeft(), pixmap); + } else if (checked) { + painter->save(); + painter->setPen(d->highlightOutlineColor(option, act)); + painter->setBrush(d->highlightMenuCheckBrush(option, act)); + painter->drawRect(vCheckRect.adjusted(-1, 1, 0, -3)); + painter->restore(); + + QStyleOptionMenuItem newMi = *menuitem; + newMi.state = State_None; + if (!dis) + newMi.state |= State_Enabled; + if (act) + newMi.state |= State_On; + newMi.rect = visualRect(option->direction, menuitem->rect, + QRect(menuitem->rect.x() + windowsItemFrame, menuitem->rect.y() + windowsItemFrame, + checkcol - 2 * windowsItemFrame, menuitem->rect.height() - 2*windowsItemFrame)); + drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, painter, widget); + } + painter->setPen(menuitem->palette.buttonText().color()); + + QColor discol; + if (dis) { + discol = menuitem->palette.text().color(); + painter->setPen(discol); + } + + int xm = windowsItemFrame + checkcol + windowsItemHMargin; + int xpos = menuitem->rect.x() + xm; + QRect textRect(xpos + 5, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin); + QRect vTextRect = visualRect(option->direction, menuitem->rect, textRect); + QString s = menuitem->text; + + if (!s.isEmpty()) { // draw text + painter->save(); + int t = s.indexOf(QLatin1Char('\t')); + int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine; + if (!styleHint(SH_UnderlineShortcut, menuitem, widget)) + text_flags |= Qt::TextHideMnemonic; + text_flags |= Qt::AlignLeft; + if (t >= 0) { + QRect vShortcutRect = visualRect(option->direction, menuitem->rect, + QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom()))); + if (dis && !act) { + painter->setPen(discol); + } + painter->drawText(vShortcutRect, text_flags, s.mid(t + 1)); + s = s.left(t); + } + QFont font = menuitem->font; + if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem) + font.setBold(true); + painter->setFont(font); + if (dis && !act) { + painter->setPen(discol); + } + painter->drawText(vTextRect, text_flags, s.left(t)); + painter->restore(); + } + if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow + int dim = (h - 2 * windowsItemFrame) / 2; + PrimitiveElement arrow; + arrow = (option->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight; + xpos = x + w - windowsArrowHMargin - windowsItemFrame - dim; + QRect vSubMenuRect = visualRect(option->direction, menuitem->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim)); + QStyleOptionMenuItem newMI = *menuitem; + newMI.rect = vSubMenuRect; + newMI.state = dis ? State_None : State_Enabled; + drawPrimitive(arrow, &newMI, painter, widget); + } + } + painter->restore(); + break; +#endif // QT_NO_MENU + + case CE_MenuEmptyArea: + { + painter->fillRect(option->rect, option->palette.base()); + QLinearGradient grad(QPoint(rect.left() , 0), QPoint(rect.left() + 23, 0)); + grad.setColorAt(0, gradientLight.light(110)); + grad.setColorAt(1, gradientDark); + painter->fillRect(QRect(0, rect.top() + 2, 23, rect.bottom() - 3), grad); + } + break; + case CE_MenuBarItem: + if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) { + QRect rect(QPoint(0, 0), widget->window()->size()); + { + if (widget->window()) + drawPrimitive(PE_Widget, option, painter, widget); + } + if (option->state & (QStyle::State_Sunken | QStyle::State_Selected)) + { + QColor highlight = shadow; + painter->setPen(d->menuFrameColor); + if (option->state & QStyle::State_Sunken) { + + if (d->internalPalette == DotNetStylePrivate::System) + painter->setBrush(Qt::white); + else + painter->setBrush(d->menuGradient(option, option->rect, Qt::Vertical)); + + painter->drawRect(option->rect.adjusted(0, 2, -1, 0)); + //draw shadow behind: + QColor shade = Qt::black; + shade.setAlpha(50); + painter->setBrush(shade); + painter->setPen(Qt::transparent); + QRect shadowRect(option->rect.topRight() + QPoint(0, 4), option->rect.bottomRight() + QPoint(1,0)); + painter->drawRect(shadowRect); + } + else { + painter->setPen(d->highlightOutlineColor(option)); + painter->setBrush(d->highlightBrush(option, false)); + painter->drawRect(option->rect.adjusted(0, 2, -2, -2)); + } + } + QStyleOptionMenuItem mbiCopy = *mbi; + QPalette pal = mbi->palette; + pal.setBrush(QPalette::All, QPalette::ButtonText, mbi->palette.text()); + mbiCopy.palette = pal; + QCommonStyle::drawControl(element, &mbiCopy, painter, widget); + } + break; + case CE_MenuBarEmptyArea: + if (widget->window()) + drawPrimitive(PE_Widget, option, painter, widget); + break; + case CE_DockWidgetTitle: + if (const QDockWidget *dockWidget = qobject_cast<const QDockWidget *>(widget)) { + painter->save(); + if (d->internalPalette == DotNetStylePrivate::System) { + painter->setBrush(option->palette.dark().color().light(130)); + painter->setPen(option->palette.dark().color()); + } else if (d->internalPalette == DotNetStylePrivate::Classic) { + painter->setBrush(option->palette.background().color().dark(108)); + painter->setPen(option->palette.dark().color()); + } else { + painter->setBrush(d->toolbarGradient(option, option->rect, Qt::Horizontal)); + QColor color = d->gradientDarkColor(option).darker(120); + painter->setPen(color); + } + painter->drawRect(rect.adjusted(0, 2, -1, -3)); + + if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) { + QRect titleRect = option->rect.adjusted(6, 2, 0, 0); + int buttonMargin = 4; + int mw = pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt, widget); + if (dwOpt->closable) { + QPixmap pm = standardIcon(QStyle::SP_TitleBarCloseButton, dwOpt, widget).pixmap(10, 10); + titleRect.adjust(0, 0, -pm.size().width() - mw - buttonMargin, 0); + } + if (dwOpt->floatable) { + QPixmap pm = standardIcon(QStyle::SP_TitleBarMaxButton, dwOpt, widget).pixmap(10, 10); + titleRect.adjust(0, 0, -pm.size().width() - mw - buttonMargin, 0); + } + titleRect = visualRect(option->direction, option->rect, titleRect); + + if (!dwOpt->title.isEmpty()) { + QString titleText = painter->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width()); + drawItemText(painter, titleRect, + Qt::AlignLeft | Qt::AlignVCenter, dwOpt->palette, + dwOpt->state & State_Enabled, titleText, + QPalette::WindowText); + } + painter->restore(); + } + break; + } + case CE_ToolBar: + if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar*>(option)) { + painter->save(); + rect.adjust(1, 0, 0, 0); + + if (const QToolBar *tb = qobject_cast<const QToolBar *>(widget)) { + if (option->direction == Qt::LeftToRight) + rect.setRight(tb->childrenRect().right() + 2); + else + rect.setLeft(tb->childrenRect().left() - 2); + } + Qt::Orientation gradientOrientation =(toolbar->toolBarArea == Qt::RightToolBarArea || + toolbar->toolBarArea == Qt::LeftToolBarArea) ? Qt::Vertical : Qt::Horizontal; + QLinearGradient gradient = d->toolbarGradient(toolbar, rect, gradientOrientation); + painter->setBrush(gradient); + painter->setPen(Qt::NoPen); + + bool roundEdges = true; + if (widget && widget->parentWidget()) { + if (const QToolBar *tb = qobject_cast<const QToolBar *>(widget)) { + if (!(tb->childrenRect().width() + 32 < widget->parentWidget()->geometry().width())) { + roundEdges = false; + rect.adjust(-1, 0, 0, 0); + } + } + } + if (roundEdges) { + rect = rect.adjusted(1, 1, -1, 0); + QRegion region = rect; + region -= QRect(rect.left(), rect.bottom(), 2, 1); + region -= QRect(rect.right() - 1, rect.bottom(), 2, 1); + region -= QRect(rect.left(), rect.bottom() - 1, 1, 1); + region -= QRect(rect.right(), rect.bottom() - 1, 1, 1); + region -= QRect(rect.left(), rect.top(), 2, 1); + region -= QRect(rect.right() - 1, rect.top(), 2, 1); + region -= QRect(rect.left(), rect.top() + 1, 1, 1); + region -= QRect(rect.right(), rect.top() + 1, 1, 1); + painter->setClipRegion(region); + + painter->fillRect(rect, gradient); + + painter->setPen(QPen(shadow, 0)); + painter->drawLine(rect.bottomLeft() + QPoint(3,0), rect.bottomRight() - QPoint(2,0)); + painter->drawPoint(rect.bottomRight() - QPoint(1, 1)); + QColor alphashadow = shadow; + alphashadow.setAlpha(128); + painter->setPen(QPen(alphashadow, 0)); + painter->drawLine(rect.topRight() + QPoint(0, 2), rect.bottomRight() - QPoint(0, 2)); + } else { + painter->fillRect(rect, gradient); + } + painter->restore(); + } + break; + default: + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + QWindowsVistaStyle::drawControl(element, option, painter, widget); + else + QWindowsXPStyle::drawControl(element, option, painter, widget); + break; + } +} + +/*! + \reimp + */ +void DotNetStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, + QPainter *painter, const QWidget *widget) const +{ + switch (control) { + case CC_ComboBox: + if (widget && qobject_cast<QToolBar *>(widget->parentWidget())) { + QColor highlightedOutlineColor = d->highlightOutlineColor(option); + if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) + { + bool active = cmb->state & State_Active && + ((cmb->state & State_MouseOver) + || (cmb->state & State_On) + || (cmb->state & State_HasFocus)); + QRect editRect = QWindowsStyle::subControlRect(CC_ComboBox, cmb, SC_ComboBoxEditField, widget).adjusted(0, 0, 3, 1); + QRect rect = option->rect.adjusted(1, 1, -3, -2); + editRect.setLeft(rect.left()); + + if (cmb->subControls & SC_ComboBoxEditField) { + painter->save(); + QBrush editBrush = cmb->palette.brush(QPalette::Base); + painter->setPen(QPen(editBrush.color())); + painter->drawRect(rect); + painter->fillRect(editRect, editBrush); + + if (active) { + QColor highlight = highlightedOutlineColor; + painter->setPen(highlight); + painter->drawRect(rect); + } + painter->restore(); + } + + if (cmb->subControls & SC_ComboBoxArrow) { + State flags = State_None; + + QRect ar = QWindowsStyle::subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget).adjusted(1, 0, -1, 0); + if (active) { + painter->save(); + painter->fillRect(ar, d->highlightBrush(option, cmb->state & State_Sunken)); + painter->setPen(highlightedOutlineColor); + painter->drawLine(ar.topLeft(), ar.bottomLeft()); + painter->restore(); + } + ar.adjust(5, 5, -2, -2); + if (option->state & State_Enabled) + flags |= State_Enabled; + QStyleOption arrowOpt(0); + arrowOpt.rect = ar; + arrowOpt.palette = cmb->palette; + arrowOpt.state = flags; + QWindowsStyle::drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, painter, widget); + } + } + } else { + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + QWindowsVistaStyle::drawComplexControl(control, option, painter, widget); + else + QWindowsXPStyle::drawComplexControl(control, option, painter, widget); + } + break; + + case CC_ToolButton: + if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast<const QStyleOptionToolButton *>(option)) + { + QRect button; + button = subControlRect(control, toolbutton, SC_ToolButton, widget); + if ((widget && qobject_cast<QToolBar*>(widget->parentWidget())) && + ((toolbutton->state & State_MouseOver && toolbutton->state & State_Enabled) + || toolbutton->state & State_On)) { + QLinearGradient menubargradient2(button.topLeft(), button.bottomLeft()); + + bool act = (toolbutton->state & State_Sunken) || (toolbutton->state & State_On); + painter->setPen(d->highlightOutlineColor(option, act)); + painter->setBrush(d->highlightBrush(option, act)); + painter->drawRect(button.adjusted(0, 0, -2, -1)); + + QStyleOptionComplex comp; + comp.init(widget); + comp.rect = button; + QStyleOptionToolButton label = *toolbutton; + int fw = pixelMetric(PM_DefaultFrameWidth, option, widget); + label.rect = button.adjusted(fw, fw, -fw, -fw); + label.features &= ~QStyleOptionToolButton::Arrow; + drawControl(CE_ToolButtonLabel, &label, painter, widget); + + if (toolbutton->subControls & SC_ToolButtonMenu) { + QStyleOption tool = *toolbutton; + tool.rect = QWindowsStyle::subControlRect(control, toolbutton, SC_ToolButtonMenu, widget); + painter->setPen(d->highlightOutlineColor(option, act)); + painter->setBrush(d->highlightBrush(option, toolbutton->activeSubControls & SC_ToolButtonMenu)); + painter->drawRect(tool.rect.adjusted(-2, 0, -1, -1)); + tool.rect.adjust(2, 3, -2, -2); + drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget); + } + } else + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + QWindowsVistaStyle::drawComplexControl(control, option, painter, widget); + else + QWindowsXPStyle::drawComplexControl(control, option, painter, widget); + } + break; + + default: + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + QWindowsVistaStyle::drawComplexControl(control, option, painter, widget); + else + QWindowsXPStyle::drawComplexControl(control, option, painter, widget); + break; + } +} + +/*! + \reimp + */ +QSize DotNetStyle::sizeFromContents(ContentsType type, const QStyleOption *option, + const QSize &size, const QWidget *widget) const +{ + QSize newSize; + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + newSize = QWindowsVistaStyle::sizeFromContents(type, option, size, widget); + else + newSize = QWindowsXPStyle::sizeFromContents(type, option, size, widget); + + switch (type) { + case CT_LineEdit: + if (widget && qobject_cast<QToolBar*>(widget->parentWidget())) { + newSize = QWindowsStyle::sizeFromContents(type, option, size, widget); + newSize += QSize(0, 2); + } + break; + case CT_ComboBox: + if (widget && qobject_cast<QToolBar*>(widget->parentWidget())) { + newSize = QWindowsStyle::sizeFromContents(type, option, size, widget); + newSize += QSize(0, 2); + } + break; + case CT_MenuBarItem: + newSize += QSize(0, 1); + break; + case CT_MenuItem: + if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) { + newSize = QWindowsStyle::sizeFromContents(type, option, size, widget); + if (menuitem->menuItemType == QStyleOptionMenuItem::Separator){ + newSize.setHeight(2); + } else { + newSize.rwidth() += 10; + //ensure menu items have uniform height + if (newSize.height() < 22) + newSize.setHeight(22); + } + } + break; + case CT_Menu: + //work around for a menu frame issue (same as xp style) + newSize = size; + newSize -= QSize(1,2); + break; + default: + break; + } + return newSize; +} + +/*! + \reimp + */ +QRect DotNetStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const +{ + QRect rect; + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + rect = QWindowsVistaStyle::subElementRect(element, option, widget); + else + rect = QWindowsXPStyle::subElementRect(element, option, widget); + if (element == SE_DockWidgetCloseButton || element == SE_DockWidgetFloatButton) + rect.translate(0, 1); + return rect; +} + +/*! + \reimp + */ +QRect DotNetStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option, + SubControl subControl, const QWidget *widget) const +{ + QRect rect; + if (control == CC_ComboBox && widget && qobject_cast<QToolBar*>(widget->parentWidget())) + rect = QWindowsStyle::subControlRect(control, option, subControl, widget); + else if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + rect = QWindowsVistaStyle::subControlRect(control, option, subControl, widget); + else + rect = QWindowsXPStyle::subControlRect(control, option, subControl, widget); + + return rect; +} + +/*! + \reimp + */ +QStyle::SubControl DotNetStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, + const QPoint &pos, const QWidget *widget) const +{ + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + return QWindowsVistaStyle::hitTestComplexControl(control, option, pos, widget); + else + return QWindowsXPStyle::hitTestComplexControl(control, option, pos, widget); +} + +/*! + \reimp + */ +int DotNetStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const +{ + int retval = 0; + + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + retval = QWindowsVistaStyle::pixelMetric(metric, option, widget); + else + retval = QWindowsXPStyle::pixelMetric(metric, option, widget); + + switch (metric) { + case PM_ToolBarItemSpacing: + retval = 2; + break; + case PM_ToolBarIconSize: + retval = 16; + break; + case PM_MenuHMargin: + retval = 1; + break; + case PM_MenuVMargin: + retval = 1; + break; + case PM_MenuBarPanelWidth: + retval = 0; + break; + case PM_MenuPanelWidth: + retval = 1; + break; + case PM_DockWidgetTitleBarButtonMargin: + retval = 6; + break; + case PM_DefaultFrameWidth: + case PM_SpinBoxFrameWidth: + if (widget && qobject_cast<QToolBar*>(widget->parentWidget())) + retval = 2; + break; + case PM_ButtonShiftVertical: + case PM_ButtonShiftHorizontal: + if (widget && qobject_cast<QToolBar*>(widget->parentWidget())) + retval = 0; + break; + default: + break; + } + return retval; +} + +/*! + \reimp + */ +QPalette DotNetStyle::standardPalette() const +{ + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + return QWindowsVistaStyle::standardPalette(); + else + return QWindowsXPStyle::standardPalette(); +} + + +void DotNetStylePrivate::updatePalette() +{ + //Detect color palette + const int maxlength = 256; + WCHAR themeFileName[maxlength]; + WCHAR themeColor[maxlength]; + internalPalette = Classic; + if (pIsAppThemed && pIsAppThemed() && pGetCurrentThemeName(themeFileName, maxlength, themeColor, maxlength, NULL, 0) == S_OK) { + QString name = QString::fromUtf16((ushort *)themeFileName); + QString color = QString::fromUtf16((ushort *)themeColor); + if (theme == DotNetStyle::Standard) { + if (name.endsWith("Luna.msstyles")) { + if (color == "Metallic") + internalPalette = Silver; + else + internalPalette = System; + } + } else { //Office style + if (name.endsWith("Luna.msstyles")) { + if (color == "HomeStead") + internalPalette = Olive; + else if (color == "Metallic") + internalPalette = Silver; + else + internalPalette = Blue; + } else if (name.endsWith("Aero.msstyles")) { + internalPalette = Blue; + } + } + } + + switch (internalPalette) { + case Blue: + menuSeparatorColor = QColor(106, 140, 203); + menuBackgroundColor = QColor(246, 246, 246); + menuFrameColor = QColor(0, 45, 150); + break; + case Silver: + menuSeparatorColor = QColor(110, 109, 143); + menuBackgroundColor = QColor(254, 250, 255); + menuFrameColor = QColor(124, 124, 148); + break; + case Olive: + menuSeparatorColor = QColor(96, 128, 88); + menuBackgroundColor = QColor(244, 244, 238); + menuFrameColor = QColor(117, 141, 94); + break; + default: + menuFrameColor = currentPal.dark().color().lighter(108); + menuSeparatorColor = currentPal.background().color().darker(110); + menuBackgroundColor = currentPal.light().color(); + menuBackgroundColor.setHsv( + menuBackgroundColor.hue(), + 3 * menuBackgroundColor.saturation()/8 , + 250); + break; + } +} + +/*! + \reimp + */ +void DotNetStyle::polish(QApplication *app) +{ + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + QWindowsVistaStyle::polish(app); + else + QWindowsXPStyle::polish(app); + d->currentPal = app->palette(); + d->updatePalette(); +} + +/*! + \reimp + */ +void DotNetStyle::unpolish(QApplication *app) +{ + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + QWindowsVistaStyle::unpolish(app); + else + QWindowsXPStyle::unpolish(app); +} + +/*! + \reimp + */ +void DotNetStyle::polish(QWidget *widget) +{ + if (qobject_cast<QMainWindow *>(widget)) + widget->setAttribute(Qt::WA_StyledBackground); + else if (qobject_cast<QLineEdit*>(widget)) + widget->setAttribute(Qt::WA_Hover); + else if (qobject_cast<QComboBox*>(widget)) + widget->setAttribute(Qt::WA_Hover); + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + QWindowsVistaStyle::polish(widget); + else + QWindowsXPStyle::polish(widget); +} + +/*! + \reimp + */ +void DotNetStyle::unpolish(QWidget *widget) +{ + if (qobject_cast<QMainWindow *>(widget)) + widget->setAttribute(Qt::WA_StyledBackground, false); + else if (qobject_cast<QLineEdit*>(widget)) + widget->setAttribute(Qt::WA_Hover, false); + else if (qobject_cast<QComboBox*>(widget)) + widget->setAttribute(Qt::WA_Hover, false); + + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + QWindowsVistaStyle::unpolish(widget); + else + QWindowsXPStyle::unpolish(widget); +} + +/*! + \reimp + */ +void DotNetStyle::polish(QPalette &pal) +{ + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + QWindowsVistaStyle::polish(pal); + else + QWindowsXPStyle::polish(pal); +} + +/*! + \reimp + */ +QPixmap DotNetStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, + const QWidget *widget) const +{ + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + return QWindowsVistaStyle::standardPixmap(standardPixmap, opt, widget); + else + return QWindowsXPStyle::standardPixmap(standardPixmap, opt, widget); +} + +/*! + \reimp +*/ +int DotNetStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, + QStyleHintReturn *returnData) const +{ + int ret = 0; + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + ret = QWindowsVistaStyle::styleHint(hint, option, widget, returnData); + else + ret = QWindowsXPStyle::styleHint(hint, option, widget, returnData); + return ret; +} + +#endif //USE_DOTNET_STYLE |