Chris@668: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@668: Chris@668: /* Chris@668: Vect Chris@668: An experimental audio player for plural recordings of a work Chris@668: Centre for Digital Music, Queen Mary, University of London. Chris@668: Chris@668: This file is based on Rosegarden, a MIDI and audio sequencer and Chris@668: musical notation editor. Copyright 2000-2018 the Rosegarden Chris@668: development team. Thorn style developed in stylesheet form by Chris@668: D. Michael McIntyre and reimplemented as a class by David Faure. Chris@668: Chris@668: This program is free software; you can redistribute it and/or Chris@668: modify it under the terms of the GNU General Public License as Chris@668: published by the Free Software Foundation; either version 2 of the Chris@668: License, or (at your option) any later version. See the file Chris@668: COPYING included with this distribution for more information. Chris@668: */ Chris@668: Chris@668: #include "ThornStyle.h" Chris@668: #include "AppEventFilter.h" Chris@668: Chris@668: #include "base/ResourceFinder.h" Chris@668: #include "widgets/IconLoader.h" Chris@668: Chris@668: #include Chris@668: #include Chris@668: #include Chris@668: #include Chris@668: #include Chris@668: #include Chris@668: #include Chris@668: #include Chris@668: #include Chris@668: #include Chris@668: #include Chris@668: #include Chris@668: #include Chris@668: #include Chris@668: #include Chris@668: #include Chris@668: #include Chris@668: #include Chris@668: #include Chris@668: #include Chris@668: #include Chris@668: #include Chris@668: Chris@668: // Silence gcc compiler warnings due to the switches below not covering all cases, on purpose Chris@668: #pragma GCC diagnostic push Chris@668: #pragma GCC diagnostic ignored "-Wswitch-enum" Chris@668: Chris@668: static QPixmap loadPix(const QString &name) Chris@668: { Chris@668: QPixmap pix(name); Chris@668: if (pix.isNull()) { Chris@668: qWarning() << "Pixmap not found:" << name; Chris@668: Q_ASSERT(0); Chris@668: } Chris@668: return pix; Chris@668: } Chris@668: Chris@668: Q_GLOBAL_STATIC(AppEventFilter, s_eventFilter) // created on demand in setEnabled Chris@668: Chris@668: //////////////////////////////////////////////////////////////////////////////////////////////////////// Chris@668: Chris@668: ThornStyle::ThornStyle() Chris@668: // We could load these on demand, but the mainwindow needs most of them already anyway Chris@668: : m_horizontalToolbarSeparatorPixmap(loadPix(":/icons/style/htoolbar-separator.png")), Chris@668: m_verticalToolbarSeparatorPixmap(loadPix(":/icons/style/vtoolbar-separator.png")), Chris@668: m_checkboxUncheckedPixmap(loadPix(":/icons/style/checkbox_unchecked.png")), Chris@668: m_checkboxUncheckedHoverPixmap(loadPix(":/icons/style/checkbox_unchecked_hover.png")), Chris@668: m_checkboxUncheckedDisabledPixmap(loadPix(":/icons/style/checkbox_disabled.png")), Chris@668: m_checkboxUncheckedPressedPixmap(loadPix(":/icons/style/checkbox_unchecked_pressed.png")), Chris@668: m_checkboxCheckedPixmap(loadPix(":/icons/style/checkbox_checked.png")), Chris@668: m_checkboxCheckedHoverPixmap(loadPix(":/icons/style/checkbox_checked_hover.png")), Chris@668: m_checkboxCheckedDisabledPixmap(loadPix(":/icons/style/checkbox_checked_disabled.png")), Chris@668: m_checkboxCheckedPressedPixmap(loadPix(":/icons/style/checkbox_checked_pressed.png")), Chris@668: m_checkboxIndeterminatePixmap(loadPix(":/icons/style/checkbox_indeterminate.png")), Chris@668: m_checkboxIndeterminateHoverPixmap(loadPix(":/icons/style/checkbox_indeterminate_hover.png")), Chris@668: //m_checkboxIndeterminateDisabledPixmap(loadPix(":/icons/style/checkbox_indeterminate_disabled.png")), Chris@668: m_checkboxIndeterminatePressedPixmap(loadPix(":/icons/style/checkbox_indeterminate_pressed.png")), Chris@668: m_radiobuttonUncheckedPixmap(loadPix(":/icons/style/radiobutton_unchecked.png")), Chris@668: m_radiobuttonUncheckedHoverPixmap(loadPix(":/icons/style/radiobutton_unchecked_hover.png")), Chris@668: m_radiobuttonUncheckedDisabledPixmap(loadPix(":/icons/style/radiobutton_unchecked_disabled.png")), Chris@668: m_radiobuttonUncheckedPressedPixmap(loadPix(":/icons/style/radiobutton_unchecked_pressed.png")), Chris@668: m_radiobuttonCheckedPixmap(loadPix(":/icons/style/radiobutton_checked.png")), Chris@668: m_radiobuttonCheckedHoverPixmap(loadPix(":/icons/style/radiobutton_checked_hover.png")), Chris@668: m_radiobuttonCheckedDisabledPixmap(loadPix(":/icons/style/radiobutton_checked_disabled.png")), Chris@668: m_radiobuttonCheckedPressedPixmap(loadPix(":/icons/style/radiobutton_checked_pressed.png")), Chris@668: m_arrowDownSmallPixmap(loadPix(":/icons/style/arrow-down-small.png")), Chris@668: m_arrowDownSmallInvertedPixmap(loadPix(":/icons/style/arrow-down-small-inverted.png")), Chris@668: m_arrowUpSmallPixmap(loadPix(":/icons/style/arrow-up-small.png")), Chris@668: m_arrowUpSmallInvertedPixmap(loadPix(":/icons/style/arrow-up-small-inverted.png")), Chris@668: m_arrowLeftPixmap(":/icons/style/arrow-left.png"), Chris@668: m_arrowRightPixmap(":/icons/style/arrow-right.png"), Chris@668: m_arrowUpPixmap(":/icons/style/arrow-up.png"), Chris@668: m_arrowDownPixmap(":/icons/style/arrow-down.png"), Chris@668: m_spinupPixmap(":/icons/style/spinup.png"), Chris@668: m_spinupHoverPixmap(":/icons/style/spinup_hover.png"), Chris@668: m_spinupOffPixmap(":/icons/style/spinup_off.png"), Chris@668: m_spinupPressedPixmap(":/icons/style/spinup_pressed.png"), Chris@668: m_spindownPixmap(":/icons/style/spindown.png"), Chris@668: m_spindownHoverPixmap(":/icons/style/spindown_hover.png"), Chris@668: m_spindownOffPixmap(":/icons/style/spindown_off.png"), Chris@668: m_spindownPressedPixmap(":/icons/style/spindown_pressed.png"), Chris@668: m_titleClosePixmap(":/icons/style/title-close.png"), Chris@668: m_titleUndockPixmap(":/icons/style/title-undock.png") Chris@668: { Chris@668: // Qt 5 removes QPlastiqueStyle and defaults to a new style called "Fusion." Chris@668: // This style forces combo boxes to do bad things. Chris@668: // I concluded that using "windows" as a base style causes an acceptable amount Chris@668: // of damage while leaving things largely intact. Chris@668: setBaseStyle(QStyleFactory::create("windows")); Chris@668: Chris@668: m_standardPalette.setColor(QPalette::Window, QColor(0x30, 0x30, 0x30)); Chris@668: Chris@668: // QLabel { color: white } Chris@668: m_standardPalette.setColor(QPalette::WindowText, Qt::white); Chris@668: Chris@668: // QListView, QTableView, QTreeView, QLineEdit... : Chris@668: // background-color: #FFFFFF; Chris@668: // color: #000000; Chris@668: // selection-background-color: #80AFFF; Chris@668: // selection-color: #FFFFFF; Chris@668: m_standardPalette.setColor(QPalette::Base, Qt::white); Chris@668: m_standardPalette.setColor(QPalette::Text, Qt::black); Chris@668: m_standardPalette.setColor(QPalette::Highlight, QColor(0x80, 0xAF, 0xFF)); Chris@668: m_standardPalette.setColor(QPalette::HighlightedText, Qt::white); Chris@668: Chris@668: // for QPushButton but also QMenu Chris@668: const QColor buttonColor = QColor(0xEE, 0xEE, 0xEE); Chris@668: m_standardPalette.setColor(QPalette::Button, buttonColor); Chris@668: m_standardPalette.setColor(QPalette::ButtonText, Qt::black); // enabled button texts and menu items Chris@668: Chris@668: // alternate-background-color: #EEEEFF; Chris@668: m_standardPalette.setColor(QPalette::AlternateBase, QColor(0xEE, 0xEE, 0xFF)); Chris@668: Chris@668: // QToolTip { background-color: #fffbd4; color: #000000; + some awful pixmap hack } Chris@668: m_standardPalette.setColor(QPalette::ToolTipBase, QColor(0xFF, 0xFB, 0xD4)); Chris@668: m_standardPalette.setColor(QPalette::ToolTipText, Qt::black); Chris@668: } Chris@668: Chris@668: ThornStyle::~ThornStyle() Chris@668: { Chris@668: } Chris@668: Chris@668: QIcon ThornStyle::standardIcon(QStyle::StandardPixmap standardIcon, const QStyleOption *option, const QWidget *parent) const Chris@668: { Chris@668: IconLoader loader; Chris@668: Chris@668: // NOTE: see src/gui/styles/qcommonstyle.cpp in the Qt source for examples Chris@668: // of how to extend this whenever more custom icons are called for Chris@668: switch (standardIcon) { Chris@668: Chris@668: // custom icons for QMessageBox Chris@668: case SP_MessageBoxInformation: Chris@668: return loader.load("style/messagebox-information"); Chris@668: Chris@668: case SP_MessageBoxWarning: Chris@668: return loader.load("style/warning"); Chris@668: Chris@668: case SP_MessageBoxCritical: Chris@668: return loader.load("style/messagebox-critical"); Chris@668: Chris@668: case SP_MessageBoxQuestion: Chris@668: return loader.load("style/messagebox-question"); Chris@668: Chris@668: case SP_TitleBarNormalButton: Chris@668: return m_titleUndockPixmap; Chris@668: Chris@668: case SP_DockWidgetCloseButton: Chris@668: case SP_TitleBarCloseButton: Chris@668: return m_titleClosePixmap; Chris@668: Chris@668: default: Chris@668: // let the base class handle the rest Chris@668: return QProxyStyle::standardPixmap(standardIcon, option, parent); Chris@668: } Chris@668: } Chris@668: Chris@668: QSize ThornStyle::pixmapSize(const QPixmap &pixmap) const Chris@668: { Chris@668: #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) Chris@668: return QSize(int(round(pixmap.width() / pixmap.devicePixelRatio())), Chris@668: int(round(pixmap.height() / pixmap.devicePixelRatio()))); Chris@668: #else Chris@668: return pixmap.size(); Chris@668: #endif Chris@668: } Chris@668: Chris@668: static bool s_thornStyleEnabled = false; Chris@668: Chris@668: // This method currently only supports being called once Chris@668: void ThornStyle::setEnabled(bool b) Chris@668: { Chris@668: s_thornStyleEnabled = b; Chris@668: if (b) { Chris@668: qApp->installEventFilter(s_eventFilter()); Chris@668: } Chris@668: } Chris@668: Chris@668: bool ThornStyle::isEnabled() Chris@668: { Chris@668: return s_thornStyleEnabled; Chris@668: } Chris@668: Chris@668: QPalette ThornStyle::standardPalette() const Chris@668: { Chris@668: return m_standardPalette; Chris@668: } Chris@668: Chris@668: int ThornStyle::styleHint(QStyle::StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const Chris@668: { Chris@668: switch (hint) { Chris@668: case SH_EtchDisabledText: Chris@668: return 0; Chris@668: case SH_Table_GridLineColor: Chris@668: // QTableView { gridline-color: #202020; } Chris@668: return qRgb(0x20, 0x20, 0x20); Chris@668: case SH_GroupBox_TextLabelColor: Chris@668: // QGroupBox::title { color: #FFFFFF; } Chris@668: // QGroupBox::title:!enabled { color: #000000; } Chris@668: // but it was etched; plain black is unreadable, so let's use another color now Chris@668: return option->state & State_Enabled ? qRgb(0xFF, 0xFF, 0xFF) : qRgb(0xAA, 0xAA, 0xAA); Chris@668: case SH_DialogButtonBox_ButtonsHaveIcons: Chris@668: return 0; Chris@668: case SH_DockWidget_ButtonsHaveFrame: Chris@668: return 1; Chris@668: default: Chris@668: break; Chris@668: } Chris@668: return QProxyStyle::styleHint(hint, option, widget, returnData); Chris@668: } Chris@668: Chris@668: int ThornStyle::pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option, const QWidget *widget) const Chris@668: { Chris@668: switch (metric) { Chris@668: case PM_SplitterWidth: //fall-through Chris@668: case PM_DockWidgetSeparatorExtent: Chris@668: // QMainWindow::separator { height: 5px; } Chris@668: return 5; Chris@668: case PM_TabBarScrollButtonWidth: Chris@668: // QTabBar::scroller { /* the width of the scroll buttons */ width: 13px; } Chris@668: return 13; Chris@668: case PM_TabBarBaseOverlap: Chris@668: return 0; Chris@668: case PM_ToolBarHandleExtent: // Horizontal toolbar: width of the handle. Vertical toolbar: height of the handle Chris@668: if (option->state & State_Horizontal) Chris@668: return m_horizontalToolbarSeparatorPixmap.width(); Chris@668: else Chris@668: return m_verticalToolbarSeparatorPixmap.height(); Chris@668: case PM_ExclusiveIndicatorWidth: Chris@668: return m_radiobuttonUncheckedPixmap.width(); Chris@668: case PM_ExclusiveIndicatorHeight: Chris@668: return m_radiobuttonUncheckedPixmap.height(); Chris@668: case PM_IndicatorWidth: Chris@668: return m_checkboxUncheckedPixmap.width(); Chris@668: case PM_IndicatorHeight: Chris@668: return m_checkboxUncheckedPixmap.height(); Chris@668: case PM_MenuPanelWidth: Chris@668: return 1; Chris@668: case PM_MenuBarHMargin: Chris@668: // QMenuBar { padding: 4px; } Chris@668: return 4; Chris@668: case PM_MenuBarItemSpacing: Chris@668: // QMenuBar::item { spacing: 3px; padding: 1px 4px; } Chris@668: return 4; Chris@668: case PM_ScrollBarExtent: { Chris@668: QWidget *parent = widget ? widget->parentWidget() : nullptr; Chris@668: QWidget *combo = parent ? parent->parentWidget() : nullptr; Chris@668: if (qobject_cast(combo)) { Chris@668: // QComboBox QAbstractItemView QScrollBar:vertical { width: 12px; } Chris@668: return 12; Chris@668: } Chris@668: // QScrollBar:horizontal { height: 16px; } Chris@668: // QScrollBar:vertical { width: 16px; } Chris@668: return 16; Chris@668: } Chris@668: case PM_ToolBarItemSpacing: Chris@668: return 0; Chris@668: case PM_ToolBarItemMargin: Chris@668: case PM_ToolBarFrameWidth: Chris@668: return 0; Chris@668: case PM_DefaultFrameWidth: Chris@668: return 2; Chris@668: case PM_SpinBoxFrameWidth: Chris@668: return 2; Chris@668: case PM_DockWidgetTitleBarButtonMargin: Chris@668: // icon size is 16x16 but somehow the buttons ended up 13x13 Chris@668: return -1; Chris@668: case PM_DockWidgetTitleMargin: // space above and below the title Chris@668: return 0; Chris@668: case PM_DockWidgetFrameWidth: Chris@668: // QDockWidget { border: none; } Chris@668: return 0; Chris@668: case PM_SmallIconSize: Chris@668: return 16; Chris@668: default: Chris@668: return QProxyStyle::pixelMetric(metric, option, widget); Chris@668: } Chris@668: } Chris@668: Chris@668: void ThornStyle::drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const Chris@668: { Chris@668: switch (element) { Chris@668: case PE_IndicatorDockWidgetResizeHandle: Chris@668: // QMainWindow::separator:hover { background-color: #CCDFFF; } Chris@668: if (option->state & QStyle::State_MouseOver) { Chris@668: painter->fillRect(option->rect, QColor(0xCC, 0xDF, 0xFF)); Chris@668: return; Chris@668: } Chris@668: break; Chris@668: case PE_FrameTabWidget: // The tab widget frame Chris@668: // QTabWidget::pane { border: 2px solid #BBBBBB; border-radius: 4px; padding: 2px; // and background: #404040; Chris@668: painter->save(); Chris@668: painter->setPen(QPen(QColor(0xBB, 0xBB, 0xBB), 2)); Chris@668: painter->setBrush(QColor(0x40, 0x40, 0x40)); Chris@668: painter->setRenderHint(QPainter::Antialiasing); Chris@668: painter->drawRoundedRect(option->rect.adjusted(2, 2, -2, -2), 4, 4); Chris@668: painter->restore(); Chris@668: return; Chris@668: case PE_FrameGroupBox: // same as above but not the background, already done Chris@668: // QGroupBox { background: #404040; color: #FFFFFF; border: 2px solid #BBBBBB; border-radius: 4px; } Chris@668: painter->save(); Chris@668: painter->setPen(QPen(QColor(0xBB, 0xBB, 0xBB), 2)); Chris@668: painter->setRenderHint(QPainter::Antialiasing); Chris@668: painter->drawRoundedRect(option->rect.adjusted(2, 2, -2, -2), 4, 4); Chris@668: painter->restore(); Chris@668: return; Chris@668: case PE_IndicatorToolBarHandle: { Chris@668: // top or bottom: image: url(:/icons/style/htoolbar-separator.png); Chris@668: // left or right: image: url(:icons/style/vtoolbar-separator.png); Chris@668: QPixmap pixmap = option->state & State_Horizontal ? m_horizontalToolbarSeparatorPixmap : m_verticalToolbarSeparatorPixmap; Chris@668: const QRect rect = alignedRect(Qt::LayoutDirectionAuto, Qt::AlignCenter, option->rect.size(), option->rect); Chris@668: painter->drawPixmap(rect, pixmap); Chris@668: return; Chris@668: } Chris@668: case PE_PanelMenu: Chris@668: // QMenu { background-color: #EEEEEE; border: 1px solid black; } Chris@668: painter->fillRect(option->rect, QColor(0xEE, 0xEE, 0xEE)); Chris@668: return; Chris@668: case PE_FrameMenu: Chris@668: painter->setPen(Qt::black); Chris@668: painter->drawRect(option->rect.adjusted(0, 0, -1, -1)); Chris@668: return; Chris@668: case PE_FrameDockWidget: // only called when the dockwidget is floating Chris@668: // QDockWidget { border: none; } Chris@668: return; Chris@668: case PE_PanelStatusBar: // no frame around the statusbar Chris@668: case PE_FrameStatusBarItem: // no frame around the statusbar items Chris@668: return; Chris@668: case PE_PanelLineEdit: Chris@668: // QLineEdit { border: 1px solid #AAAAAA; background-color: #FFFFFF; } Chris@668: if (const QStyleOptionFrame *frame = qstyleoption_cast(option)) { Chris@668: if (frame->lineWidth > 0) // i.e. not inside QSpinBox Chris@668: painter->setPen(QColor(0xAA, 0xAA, 0xAA)); Chris@668: else Chris@668: painter->setPen(Qt::NoPen); Chris@668: painter->setBrush(Qt::white); Chris@668: painter->drawRect(option->rect.adjusted(0, 0, -1, -1)); Chris@668: } Chris@668: return; Chris@668: case PE_IndicatorMenuCheckMark: Chris@668: return; // done in CE_MenuItem Chris@668: case PE_IndicatorCheckBox: Chris@668: case PE_IndicatorRadioButton: { Chris@668: const bool checked = !(option->state & State_Off); Chris@668: const bool disabled = !(option->state & State_Enabled); Chris@668: const bool pressed = option->state & State_Sunken; Chris@668: const bool hover = option->state & State_MouseOver; Chris@668: QPixmap pixmap; Chris@668: if (element == PE_IndicatorCheckBox) { Chris@668: if (option->state & State_NoChange) { Chris@668: // missing icon for disabled Chris@668: if (pressed) Chris@668: pixmap = m_checkboxIndeterminatePressedPixmap; Chris@668: else if (hover) Chris@668: pixmap = m_checkboxIndeterminateHoverPixmap; Chris@668: else Chris@668: pixmap = m_checkboxIndeterminatePixmap; Chris@668: } else { Chris@668: if (disabled) { Chris@668: pixmap = checked ? m_checkboxCheckedDisabledPixmap : m_checkboxUncheckedDisabledPixmap; Chris@668: } else { Chris@668: if (pressed) Chris@668: pixmap = checked ? m_checkboxCheckedPressedPixmap : m_checkboxUncheckedPressedPixmap; Chris@668: else if (hover) Chris@668: pixmap = checked ? m_checkboxCheckedHoverPixmap : m_checkboxUncheckedHoverPixmap; Chris@668: else Chris@668: pixmap = checked ? m_checkboxCheckedPixmap : m_checkboxUncheckedPixmap; Chris@668: } Chris@668: } Chris@668: } else { Chris@668: if (disabled) { Chris@668: pixmap = checked ? m_radiobuttonCheckedDisabledPixmap : m_radiobuttonUncheckedDisabledPixmap; Chris@668: } else { Chris@668: if (pressed) Chris@668: pixmap = checked ? m_radiobuttonCheckedPressedPixmap : m_radiobuttonUncheckedPressedPixmap; Chris@668: else if (hover) Chris@668: pixmap = checked ? m_radiobuttonCheckedHoverPixmap : m_radiobuttonUncheckedHoverPixmap; Chris@668: else Chris@668: pixmap = checked ? m_radiobuttonCheckedPixmap : m_radiobuttonUncheckedPixmap; Chris@668: } Chris@668: } Chris@668: QRect pmr(QPoint(0, 0), pixmapSize(pixmap)); Chris@668: pmr.moveCenter(option->rect.center()); Chris@668: painter->drawPixmap(pmr.topLeft(), pixmap); Chris@668: return; Chris@668: } Chris@668: case PE_IndicatorHeaderArrow: Chris@668: // QHeaderView::down-arrow / QHeaderView::up-arrow Chris@668: if (const QStyleOptionHeader *header = qstyleoption_cast(option)) { Chris@668: const bool up = (header->sortIndicator & QStyleOptionHeader::SortUp); Chris@668: const QPixmap pixmap = up ? m_arrowUpSmallInvertedPixmap : m_arrowDownSmallInvertedPixmap; Chris@668: painter->drawPixmap(option->rect.topLeft(), pixmap); Chris@668: } Chris@668: return; Chris@668: case PE_IndicatorArrowUp: Chris@668: case PE_IndicatorArrowDown: Chris@668: case PE_IndicatorArrowLeft: Chris@668: case PE_IndicatorArrowRight: { Chris@668: QPixmap pixmap; Chris@668: if (element == PE_IndicatorArrowLeft) Chris@668: pixmap = m_arrowLeftPixmap; Chris@668: else if (element == PE_IndicatorArrowRight) Chris@668: pixmap = m_arrowRightPixmap; Chris@668: else if (element == PE_IndicatorArrowUp) Chris@668: pixmap = m_arrowUpPixmap; Chris@668: else if (element == PE_IndicatorArrowDown) Chris@668: pixmap = m_arrowDownPixmap; Chris@668: // Scale the pixmap to the desired rect (for scrollbars the pixmap is 12x12 but the rect is 8x8) Chris@668: pixmap = pixmap.scaled(option->rect.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation); Chris@668: // In case the scaling didn't occupy the full height (due to aspect ratio), center the resulting pixmap (eg: toolbutton menu indicator) Chris@668: const QRect drawRect = alignedRect(option->direction, Qt::AlignCenter, pixmap.size(), option->rect); Chris@668: painter->drawPixmap(drawRect.topLeft(), pixmap); Chris@668: } Chris@668: return; Chris@668: case PE_PanelButtonTool: Chris@668: if (widget && widget->inherits("QDockWidgetTitleButton")) { Chris@668: // QDockWidget::close-button, QDockWidget::float-button { Chris@668: // border: 1px solid #AAAAAA; Chris@668: // border-radius: 3px; Chris@668: // background-color: qlineargradient(x1:0, y1:1, x2:0, y2:0, stop:0 #999999, stop:1 #DDDDDD); Chris@668: //} Chris@668: painter->save(); Chris@668: painter->setPen(QPen(QColor(0xAA, 0xAA, 0xAA))); Chris@668: QLinearGradient gradient; Chris@668: gradient.setStart(0, 0); Chris@668: gradient.setFinalStop(0, option->rect.height()); Chris@668: gradient.setColorAt(0, QColor(0xDD, 0xDD, 0xDD)); Chris@668: gradient.setColorAt(1, QColor(0x99, 0x99, 0x99)); Chris@668: painter->setBrush(gradient); Chris@668: painter->setRenderHint(QPainter::Antialiasing); Chris@668: painter->drawRoundedRect(option->rect.adjusted(1, 1, -1, -1), 3, 3); Chris@668: painter->restore(); Chris@668: } Chris@668: else if ((option->state & State_On) || (option->state & State_Sunken)) { Chris@668: // QToolButton::pressed, QToolButton::checked { border: 1px solid #AAAAAA; border-radius: 2px; Chris@668: // background-color: qlineargradient(x1:0, y1:1, x2:0, y2:0, stop:0 #E0E0E0, stop:1 #EEEEEE); } Chris@668: painter->save(); Chris@668: painter->setPen(QPen(QColor(0xAA, 0xAA, 0xAA))); Chris@668: QLinearGradient gradient; Chris@668: gradient.setStart(0, 0); Chris@668: gradient.setFinalStop(0, option->rect.height()); Chris@668: gradient.setColorAt(0, QColor(0xEE, 0xEE, 0xEE)); Chris@668: gradient.setColorAt(1, QColor(0xE0, 0xE0, 0xE0)); Chris@668: painter->setBrush(gradient); Chris@668: painter->setRenderHint(QPainter::Antialiasing); Chris@668: painter->drawRoundedRect(option->rect.adjusted(0, 0, -1, -1), 2, 2); Chris@668: painter->restore(); Chris@668: } Chris@668: else if ((option->state & State_MouseOver) && (option->state & State_Enabled)) { Chris@668: // QToolButton::enabled:hover { border: 1px solid #AAAAAA; border-radius: 2px; background-color: #CCDFFF; } Chris@668: painter->save(); Chris@668: painter->setPen(QPen(QColor(0xAA, 0xAA, 0xAA))); Chris@668: painter->setBrush(QColor(0xCC, 0xDF, 0xFF)); Chris@668: painter->setRenderHint(QPainter::Antialiasing); Chris@668: painter->drawRoundedRect(option->rect.adjusted(0, 0, -1, -1), 2, 2); Chris@668: painter->restore(); Chris@668: } Chris@668: return; Chris@668: case PE_IndicatorProgressChunk: Chris@668: if (const QStyleOptionProgressBar *pb = qstyleoption_cast(option)) { Chris@668: QStyleOptionProgressBar copy = *pb; Chris@668: // QProgressBar::chunk { background-color: #D6E8FB; } Chris@668: copy.palette.setColor(QPalette::Highlight, QColor(0xD6, 0xE8, 0xFB)); // qwindowsstyle.cpp uses Highlight Chris@668: QProxyStyle::drawPrimitive(element, ©, painter, widget); Chris@668: } Chris@668: return; Chris@668: default: Chris@668: break; Chris@668: } Chris@668: QProxyStyle::drawPrimitive(element, option, painter, widget); Chris@668: } Chris@668: Chris@668: void ThornStyle::drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const Chris@668: { Chris@668: switch (element) { Chris@668: case CE_Splitter: // currently unused, but consistent with PE_IndicatorDockWidgetResizeHandle Chris@668: if (option->state & QStyle::State_MouseOver) { Chris@668: painter->fillRect(option->rect, QColor(0xCC, 0xDF, 0xFF)); Chris@668: return; Chris@668: } Chris@668: break; Chris@668: case CE_TabBarTab: Chris@668: /* border: 1px solid #AAAAAA; Chris@668: background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 #999999, stop:1 #DDDDDD); Chris@668: color: #000000; Chris@668: border-bottom-color: #BBBBBB; // same as the pane color Chris@668: border-top-left-radius: 4px; Chris@668: border-top-right-radius: 4px; Chris@668: */ Chris@668: if (const QStyleOptionTab *tab = qstyleoption_cast(option)) { Chris@668: QRect tabRect = tab->rect; Chris@668: QColor borderColor; Chris@668: QLinearGradient gradient(0, 0, 0, tab->rect.height()); Chris@668: const bool selected = tab->state & State_Selected; Chris@668: if (selected) { Chris@668: // QTabBar::tab:top:selected said Chris@668: // background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 #E0E0E0, stop:1 #EEEEEE); Chris@668: gradient.setColorAt(0, QColor(0xE0, 0xE0, 0xE0)); Chris@668: gradient.setColorAt(1, QColor(0xEE, 0xEE, 0xEE)); Chris@668: // border: 1px solid #E0E0E0; Chris@668: borderColor = QColor(0xE0, 0xE0, 0xE0); Chris@668: } else { Chris@668: gradient.setColorAt(0, QColor(0x99, 0x99, 0x99)); Chris@668: gradient.setColorAt(1, QColor(0xDD, 0xDD, 0xDD)); Chris@668: borderColor = QColor(0xAA, 0xAA, 0xAA); Chris@668: } Chris@668: Chris@668: QRect roundedRect; Chris@668: // Ruse: we draw a rounded rect that is too big at the bottom (or top, for South), but clipped, so that it looks square Chris@668: switch (tab->shape) { Chris@668: case QTabBar::RoundedNorth: Chris@668: case QTabBar::TriangularNorth: Chris@668: if (!selected) { Chris@668: // QTabBar::tab:top:!selected { margin-top: 2px; } Chris@668: tabRect.adjust(0, 2, 0, 0); Chris@668: } Chris@668: roundedRect = tabRect.adjusted(0, 0, 0, 5); Chris@668: break; Chris@668: case QTabBar::RoundedSouth: Chris@668: case QTabBar::TriangularSouth: Chris@668: if (!selected) { Chris@668: // QTabBar::tab:bottom:!selected { margin-bottom: 2px } Chris@668: tabRect.adjust(0, 0, 0, -2); Chris@668: } Chris@668: roundedRect = tabRect.adjusted(0, -5, 0, 0); Chris@668: break; Chris@668: default: Chris@668: qWarning() << "Vertical tabbars not implemented yet, call David"; Chris@668: } Chris@668: Chris@668: // Draw tab shape Chris@668: painter->save(); Chris@668: painter->setClipRect(tabRect); Chris@668: painter->setPen(borderColor); Chris@668: painter->setBrush(gradient); Chris@668: painter->setRenderHint(QPainter::Antialiasing); Chris@668: painter->drawRoundedRect(roundedRect, 4, 4); Chris@668: painter->restore(); Chris@668: Chris@668: // Draw tab text Chris@668: QStyleOptionTab modifiedOption = *tab; Chris@668: modifiedOption.palette.setColor(QPalette::WindowText, Qt::black); Chris@668: QProxyStyle::drawControl(CE_TabBarTabLabel, &modifiedOption, painter, widget); Chris@668: } Chris@668: return; Chris@668: case CE_ToolBar: Chris@668: { Chris@668: /* Chris@668: top or bottom: background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 #999999, stop:1 #DDDDDD) Chris@668: left or right: background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #DDDDDD, stop:1 #999999) Chris@668: */ Chris@668: QLinearGradient gradient; Chris@668: if (option->state & State_Horizontal) { Chris@668: gradient.setStart(0, 0); Chris@668: gradient.setFinalStop(0, option->rect.height()); Chris@668: } else { Chris@668: gradient.setStart(0, 0); Chris@668: gradient.setFinalStop(option->rect.width(), 0); Chris@668: } Chris@668: gradient.setColorAt(0, QColor(0xDD, 0xDD, 0xDD)); Chris@668: gradient.setColorAt(1, QColor(0x99, 0x99, 0x99)); Chris@668: painter->fillRect(option->rect, gradient); Chris@668: } Chris@668: return; Chris@668: case CE_PushButtonBevel: Chris@668: painter->save(); Chris@668: painter->setRenderHint(QPainter::Antialiasing); Chris@668: if (option->state & State_MouseOver) { Chris@668: // QPushButton:hover { border: 1px solid #AAAAAA; border-radius: 3px; background-color: #DDEFFF; } Chris@668: painter->setPen(QPen(QColor(0xAA, 0xAA, 0xAA))); Chris@668: painter->setBrush(QColor(0xDD, 0xEF, 0xFF)); Chris@668: } else if ((option->state & State_On) || (option->state & State_Sunken)) { Chris@668: // QPushButton::checked, QPushButton::pressed { border: 1px solid #AAAAAA; border-radius: 2px; background-color: qlineargradient(x1:0, y1:1, x2:0, y2:0, stop:0 #E0E0EA, stop:1 #BBCFFF); } Chris@668: QLinearGradient gradient; Chris@668: gradient.setStart(0, 0); Chris@668: gradient.setFinalStop(0, option->rect.height()); Chris@668: gradient.setColorAt(0, QColor(0xE0, 0xE0, 0xEA)); Chris@668: gradient.setColorAt(1, QColor(0xBB, 0xCF, 0xFF)); Chris@668: painter->setPen(QPen(QColor(0xAA, 0xAA, 0xAA))); Chris@668: painter->setBrush(gradient); Chris@668: } else { Chris@668: // QPushButton::enabled { border: 1px solid #AAAAAA; border-radius: 3px; background-color: qlineargradient(x1:0, y1:1, x2:0, y2:0, stop:0 #999999, stop:1 #DDDDDD); } Chris@668: // QPushButton::!enabled { border: 1px solid #808080; + same background as Qt does the sunken effect on these, and that looks fine. } Chris@668: QLinearGradient gradient; Chris@668: gradient.setStart(0, 0); Chris@668: gradient.setFinalStop(0, option->rect.height()); Chris@668: gradient.setColorAt(0, QColor(0xDD, 0xDD, 0xDD)); Chris@668: gradient.setColorAt(1, QColor(0x99, 0x99, 0x99)); Chris@668: if (option->state & State_Enabled) Chris@668: painter->setPen(QPen(QColor(0xAA, 0xAA, 0xAA))); Chris@668: else Chris@668: painter->setPen(QPen(QColor(0x80, 0x80, 0x80))); Chris@668: painter->setBrush(gradient); Chris@668: } Chris@668: painter->drawRoundedRect(option->rect.adjusted(0, 0, -1, -1), 3, 3); Chris@668: painter->restore(); Chris@668: return; Chris@668: case CE_MenuItem: Chris@668: if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast(option)) { Chris@668: int x, y, w, h; Chris@668: menuitem->rect.getRect(&x, &y, &w, &h); Chris@668: const bool checked = menuitem->checkType != QStyleOptionMenuItem::NotCheckable ? menuitem->checked : false; Chris@668: const bool selected = menuitem->state & State_Selected; Chris@668: const bool disabled = !(menuitem->state & State_Enabled); Chris@668: Chris@668: QColor textColor; Chris@668: if (selected) { Chris@668: // QMenu::item:selected { background-color: #80AFFF; } Chris@668: const QColor fill(0x80, 0xAF, 0xFF); Chris@668: painter->fillRect(menuitem->rect.adjusted(0, 0, -1, 0), fill); Chris@668: Chris@668: // QMenu::item:selected { color: #FFFFFF; } Chris@668: textColor = QColor(0xFF, 0xFF, 0xFF); Chris@668: } else { Chris@668: if (disabled) { Chris@668: // QMenu::item:!enabled { color: #AAAAAA; } Chris@668: textColor = QColor(0xAA, 0xAA, 0xAA); Chris@668: } else { Chris@668: // QMenu::item:enabled { color: #000000; } Chris@668: textColor = Qt::black; Chris@668: } Chris@668: } Chris@668: Chris@668: if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) { Chris@668: /* QMenu::separator { Chris@668: height: 2px; Chris@668: background: #AAAAAA; Chris@668: margin-left: 10px; Chris@668: margin-right: 5px; Chris@668: } */ Chris@668: const int yoff = y-1 + h / 2; Chris@668: painter->fillRect(x + 10, yoff, w - 15, 2, QColor(0xAA, 0xAA, 0xAA)); Chris@668: return; Chris@668: } Chris@668: Chris@668: // taken from qwindowsstyle.cpp, and modified (due to the width of the checkmarks) Chris@668: Chris@668: const bool checkable = menuitem->checkType != QStyleOptionMenuItem::NotCheckable; Chris@668: const int checkcol = qMax(menuitem->maxIconWidth, m_checkboxCheckedPixmap.width() + 4); Chris@668: const QRect vCheckRect = visualRect(option->direction, menuitem->rect, QRect(menuitem->rect.x(), menuitem->rect.y(), checkcol, menuitem->rect.height())); Chris@668: Chris@668: // Draw icon or checkmark Chris@668: QPixmap pixmap; Chris@668: if (!menuitem->icon.isNull()) { Chris@668: QIcon::Mode mode = disabled ? QIcon::Disabled : QIcon::Normal; Chris@668: if (selected && !disabled) Chris@668: mode = QIcon::Active; Chris@668: if (checked) Chris@668: pixmap = menuitem->icon.pixmap(pixelMetric(PM_SmallIconSize, option, widget), mode, QIcon::On); Chris@668: else Chris@668: pixmap = menuitem->icon.pixmap(pixelMetric(PM_SmallIconSize, option, widget), mode); Chris@668: } else if (checkable) { Chris@668: if (!selected) { Chris@668: if (menuitem->checkType & QStyleOptionMenuItem::Exclusive) { Chris@668: pixmap = menuitem->checked ? m_radiobuttonCheckedPixmap : m_radiobuttonUncheckedPixmap; Chris@668: } else { Chris@668: pixmap = menuitem->checked ? m_checkboxCheckedPixmap : m_checkboxUncheckedPixmap; Chris@668: } Chris@668: } else { Chris@668: if (menuitem->checkType & QStyleOptionMenuItem::Exclusive) { Chris@668: pixmap = menuitem->checked ? m_radiobuttonCheckedHoverPixmap : m_radiobuttonUncheckedHoverPixmap; Chris@668: } else { Chris@668: pixmap = menuitem->checked ? m_checkboxCheckedHoverPixmap : m_checkboxUncheckedHoverPixmap; Chris@668: } Chris@668: } Chris@668: } Chris@668: QRect pmr(QPoint(0, 0), pixmapSize(pixmap)); Chris@668: pmr.moveCenter(vCheckRect.center()); Chris@668: painter->setPen(menuitem->palette.text().color()); Chris@668: painter->drawPixmap(pmr.topLeft(), pixmap); Chris@668: Chris@668: const int itemFrame = 2; Chris@668: const int itemHMargin = 2; Chris@668: const int itemVMargin = 2; Chris@668: const int rightBorder = 15; Chris@668: const int arrowHMargin = 6; Chris@668: const int xm = itemFrame + checkcol + itemHMargin; Chris@668: const int xpos = menuitem->rect.x() + xm; Chris@668: painter->setPen(textColor); Chris@668: QRect textRect(xpos, y + itemVMargin, Chris@668: w - xm - rightBorder - menuitem->tabWidth + 1, h - 2 * itemVMargin); Chris@668: QRect vTextRect = visualRect(option->direction, menuitem->rect, textRect); Chris@668: QString s(menuitem->text); Chris@668: if (!s.isEmpty()) { // draw text Chris@668: int t = s.indexOf(QLatin1Char('\t')); Chris@668: int text_flags = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine; Chris@668: if (!styleHint(SH_UnderlineShortcut, menuitem, widget)) Chris@668: text_flags |= Qt::TextHideMnemonic; Chris@668: if (t >= 0) { Chris@668: QRect vShortcutRect = visualRect(option->direction, menuitem->rect, Chris@668: QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom()))); Chris@668: const QString textToDraw = s.mid(t + 1); Chris@668: painter->drawText(vShortcutRect, text_flags, textToDraw); Chris@668: s = s.left(t); Chris@668: } Chris@668: QFont font = menuitem->font; Chris@668: if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem) Chris@668: font.setBold(true); Chris@668: painter->setFont(font); Chris@668: const QString textToDraw = s.left(t); Chris@668: painter->drawText(vTextRect, text_flags, textToDraw); Chris@668: } Chris@668: if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) { // draw sub menu arrow Chris@668: const int dim = (h - 2 * itemFrame) / 2; Chris@668: const PrimitiveElement arrow = (option->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight; Chris@668: const int submenuXPos = x + w - arrowHMargin - itemFrame - dim; Chris@668: const QRect vSubMenuRect = visualRect(option->direction, menuitem->rect, QRect(submenuXPos, y + h / 2 - dim / 2, dim, dim)); Chris@668: QStyleOptionMenuItem newMI = *menuitem; Chris@668: newMI.rect = vSubMenuRect; Chris@668: newMI.state = disabled ? State_None : State_Enabled; Chris@668: if (selected) { Chris@668: newMI.palette.setColor(QPalette::ButtonText, textColor); Chris@668: } Chris@668: QProxyStyle::drawPrimitive(arrow, &newMI, painter, widget); Chris@668: } Chris@668: } Chris@668: return; Chris@668: case CE_CheckBoxLabel: Chris@668: case CE_RadioButtonLabel: Chris@668: if (const QStyleOptionButton *btn = qstyleoption_cast(option)) { Chris@668: QStyleOptionButton modifiedOption = *btn; Chris@668: const bool disabled = !(option->state & State_Enabled); Chris@668: // QCheckBox:!enabled { color: #000000; } Chris@668: // QCheckBox:enabled { color: #FFFFFF } Chris@668: modifiedOption.palette.setColor(QPalette::WindowText, disabled ? Qt::black : Qt::white); Chris@668: QProxyStyle::drawControl(element, &modifiedOption, painter, widget); Chris@668: } Chris@668: return; Chris@668: case CE_ComboBoxLabel: Chris@668: if (option->state & State_Enabled) { Chris@668: painter->setPen(Qt::black); Chris@668: } else { Chris@668: // disabled text light enough to be legible but not as stark as white Chris@668: painter->setPen(QColor(0xEE, 0xEE, 0xEE)); Chris@668: } Chris@668: QCommonStyle::drawControl(element, option, painter, widget); Chris@668: return; Chris@668: case CE_Header: Chris@668: // Copied straight from qwindowsstyle.cpp because the subElementRect calls don't use proxy()->. Chris@668: if (const QStyleOptionHeader *header = qstyleoption_cast(option)) { Chris@668: QRegion clipRegion = painter->clipRegion(); Chris@668: painter->setClipRect(option->rect); Chris@668: drawControl(CE_HeaderSection, header, painter, widget); Chris@668: QStyleOptionHeader subopt = *header; Chris@668: subopt.rect = subElementRect(SE_HeaderLabel, header, widget); Chris@668: if (subopt.rect.isValid()) { Chris@668: subopt.palette.setColor(QPalette::ButtonText, Qt::white); // QHeaderView::section { color: #FFFFFF; } Chris@668: drawControl(CE_HeaderLabel, &subopt, painter, widget); Chris@668: } Chris@668: if (header->sortIndicator != QStyleOptionHeader::None) { Chris@668: subopt.rect = subElementRect(SE_HeaderArrow, option, widget); Chris@668: drawPrimitive(PE_IndicatorHeaderArrow, &subopt, painter, widget); Chris@668: } Chris@668: painter->setClipRegion(clipRegion); Chris@668: } Chris@668: return; Chris@668: case CE_HeaderSection: Chris@668: if (const QStyleOptionHeader *header = qstyleoption_cast(option)) { Chris@668: // QHeaderView::section { background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 #707070, stop:1 #808080); } Chris@668: QLinearGradient gradient; Chris@668: gradient.setStart(0, 0); Chris@668: gradient.setFinalStop(0, option->rect.height()); Chris@668: gradient.setColorAt(0, QColor(0x80, 0x80, 0x80)); Chris@668: gradient.setColorAt(1, QColor(0x70, 0x70, 0x70)); Chris@668: painter->setBrush(gradient); Chris@668: // border: 1px solid #AAAAAA; Chris@668: painter->setPen(QPen(QColor(0xAA, 0xAA, 0xAA))); Chris@668: painter->drawRect(header->rect); Chris@668: // Not converted, not sure what it did: padding-left: 4px; padding-right: 1em; Chris@668: } Chris@668: return; Chris@668: case CE_MenuBarItem: Chris@668: if (const QStyleOptionMenuItem *m = qstyleoption_cast(option)) { Chris@668: QStyleOptionMenuItem modifiedOption(*m); Chris@668: if (option->state & State_Selected) { Chris@668: // QMenuBar::item:selected { background-color: #80AFFF; } Chris@668: modifiedOption.palette.setColor(QPalette::Button, QColor(0x80, 0xAF, 0xFF)); Chris@668: } else if (option->state & State_Sunken) { Chris@668: // QMenuBar::item:pressed { background-color: #BBCEFF; } Chris@668: modifiedOption.palette.setColor(QPalette::Button, QColor(0xBB, 0xCE, 0xFF)); Chris@668: } else { Chris@668: // QMenuBar { background-color: #404040; } Chris@668: modifiedOption.palette.setColor(QPalette::Button, QColor(0x40, 0x40, 0x40)); Chris@668: } Chris@668: // QMenuBar::item:selected { color: #FFFFFF; } Chris@668: // QMenuBar::item { color: #FFFFFF; } Chris@668: modifiedOption.palette.setColor(QPalette::ButtonText, Qt::white); Chris@668: Chris@668: QProxyStyle::drawControl(element, &modifiedOption, painter, widget); Chris@668: } Chris@668: return; Chris@668: case CE_MenuBarEmptyArea: Chris@668: // QMenuBar { background-color: #404040; } Chris@668: painter->fillRect(option->rect, QColor(0x40, 0x40, 0x40)); Chris@668: return; Chris@668: case CE_ScrollBarSubLine: Chris@668: case CE_ScrollBarAddLine: Chris@668: { Chris@668: // QScrollBar::add-line:horizontal { border: 2px solid #404040; background: #808080; } but the 2px border didn't appear Chris@668: painter->fillRect(option->rect, QColor(0x80, 0x80, 0x80)); Chris@668: // taken from qwindowsstyle.cpp Chris@668: PrimitiveElement arrow; Chris@668: if (option->state & State_Horizontal) { Chris@668: if (element == CE_ScrollBarAddLine) Chris@668: arrow = option->direction == Qt::LeftToRight ? PE_IndicatorArrowRight : PE_IndicatorArrowLeft; Chris@668: else Chris@668: arrow = option->direction == Qt::LeftToRight ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight; Chris@668: } else { Chris@668: if (element == CE_ScrollBarAddLine) Chris@668: arrow = PE_IndicatorArrowDown; Chris@668: else Chris@668: arrow = PE_IndicatorArrowUp; Chris@668: } Chris@668: QStyleOption arrowOpt = *option; Chris@668: // QScrollBar:*-arrow { width: 8px; height 8px; } Chris@668: arrowOpt.rect = alignedRect(option->direction, Qt::AlignCenter, QSize(8, 8), option->rect); Chris@668: drawPrimitive(arrow, &arrowOpt, painter, widget); Chris@668: } Chris@668: return; Chris@668: case CE_ScrollBarSubPage: Chris@668: case CE_ScrollBarAddPage: Chris@668: // Nothing to be done, CC_ScrollBar did the full fillRect() Chris@668: return; Chris@668: case CE_ScrollBarSlider: Chris@668: { Chris@668: // QScrollBar::handle:horizontal { background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 #999999, stop:1 #DDDDDD); } Chris@668: // QScrollBar::handle:vertical { background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #DDDDDD, stop:1 #999999); } Chris@668: QLinearGradient gradient; Chris@668: gradient.setStart(0, 0); Chris@668: if (option->state & State_Horizontal) Chris@668: gradient.setFinalStop(0, option->rect.height()); Chris@668: else Chris@668: gradient.setFinalStop(option->rect.width(), 0); Chris@668: gradient.setColorAt(0, QColor(0xDD, 0xDD, 0xDD)); Chris@668: gradient.setColorAt(1, QColor(0x99, 0x99, 0x99)); Chris@668: painter->fillRect(option->rect, gradient); Chris@668: } Chris@668: return; Chris@668: case CE_DockWidgetTitle: // titlebar on floating dock widgets Chris@668: if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast(option)) { Chris@668: const bool active = dwOpt->state & State_Active; Chris@668: const bool floating = dwOpt->movable && (dwOpt->state & State_Window); Chris@668: QStyleOptionDockWidget copy = *dwOpt; Chris@668: copy.palette.setColor(QPalette::Dark, Qt::transparent); // QCommonStyle draws a border around the title with this color, we don't want it Chris@668: if (floating && !active) Chris@668: copy.palette.setColor(QPalette::WindowText, QColor(0xAA, 0xAA, 0xAA)); Chris@668: else Chris@668: copy.palette.setColor(QPalette::WindowText, Qt::white); Chris@668: // Don't use QWindowsStyle for this, it uses black for the floating && !active case, cached from the initial app palette. Chris@668: QCommonStyle::drawControl(element, ©, painter, widget); Chris@668: } Chris@668: return; Chris@668: case CE_ProgressBarGroove: Chris@668: if (const QStyleOptionProgressBar *pb = qstyleoption_cast(option)) { Chris@668: // QProgressBar { background: #FFFFFF; border: 1px solid #AAAAAA; border-radius: 3px; } Chris@668: painter->save(); Chris@668: painter->setBrush(Qt::white); Chris@668: painter->setPen(QColor(0xAA, 0xAA, 0xAA)); Chris@668: painter->drawRoundedRect(pb->rect.adjusted(0, 0, -1, -1), 3, 3); Chris@668: painter->restore(); Chris@668: } Chris@668: return; Chris@668: case CE_ProgressBarLabel: Chris@668: if (const QStyleOptionProgressBar *pb = qstyleoption_cast(option)) { Chris@668: // QProgressBar { color: #000000; text-align: center; } Chris@668: QStyleOptionProgressBar copy = *pb; Chris@668: copy.palette.setColor(QPalette::HighlightedText, Qt::black); Chris@668: QProxyStyle::drawControl(element, ©, painter, widget); Chris@668: } Chris@668: return; Chris@668: default: Chris@668: break; Chris@668: } Chris@668: QProxyStyle::drawControl(element, option, painter, widget); Chris@668: } Chris@668: Chris@668: void ThornStyle::drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const Chris@668: { Chris@668: switch (control) { Chris@668: case CC_ScrollBar: Chris@668: if (const QStyleOptionSlider *scrollBar = qstyleoption_cast(option)) { Chris@668: // QScrollBar { border: 2px solid #404040; background-color: none; } Chris@668: // QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal { background: #404040; } Chris@668: // Done here by filling the whole scrollbar, and moving the subcontrols by 2 pixels, then drawing nothing for AddPage/SubPage Chris@668: painter->fillRect(scrollBar->rect, QColor(0x40, 0x40, 0x40)); Chris@668: } Chris@668: break; // let the base class do the rest Chris@668: case CC_Slider: Chris@668: if (const QStyleOptionSlider *slider = qstyleoption_cast(option)) { Chris@668: const QRect groove = subControlRect(CC_Slider, slider, SC_SliderGroove, widget); Chris@668: const QRect handle = subControlRect(CC_Slider, slider, SC_SliderHandle, widget); Chris@668: if ((slider->subControls & SC_SliderGroove) && groove.isValid()) { Chris@668: // QSlider::groove:horizontal { background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #E0E0E0, stop:1 #EEEEEE); } Chris@668: QLinearGradient gradient; Chris@668: gradient.setStart(0, 0); Chris@668: if (option->state & State_Horizontal) Chris@668: gradient.setFinalStop(0, option->rect.height()); Chris@668: else Chris@668: gradient.setFinalStop(option->rect.width(), 0); Chris@668: gradient.setColorAt(0, QColor(0xE0, 0xE0, 0xE0)); Chris@668: gradient.setColorAt(1, QColor(0xEE, 0xEE, 0xEE)); Chris@668: painter->fillRect(groove, gradient); Chris@668: } Chris@668: #if 0 // no tickmarks Chris@668: if (slider->subControls & SC_SliderTickmarks) { Chris@668: QStyleOptionSlider tmpSlider = *slider; Chris@668: tmpSlider.subControls = SC_SliderTickmarks; Chris@668: QCommonStyle::drawComplexControl(control, &tmpSlider, painter, widget); Chris@668: } Chris@668: #endif Chris@668: if (slider->subControls & SC_SliderHandle) { Chris@668: // QSlider::handle:horizontal { background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #b4b4b4, stop:1 #8f8f8f); Chris@668: // border: 1px solid #5c5c5c; border-radius: 3px; } Chris@668: QLinearGradient gradient; Chris@668: gradient.setStart(0, 0); Chris@668: gradient.setFinalStop(option->rect.width(), option->rect.height()); Chris@668: gradient.setColorAt(0, QColor(0xB4, 0xB4, 0xB4)); Chris@668: gradient.setColorAt(1, QColor(0x8F, 0x8F, 0x8F)); Chris@668: painter->setPen(QColor(0x5C, 0x5C, 0x5C)); Chris@668: painter->setBrush(gradient); Chris@668: painter->setRenderHint(QPainter::Antialiasing); Chris@668: painter->drawRoundedRect(handle, 3, 3); Chris@668: } Chris@668: } Chris@668: return; Chris@668: case CC_GroupBox: Chris@668: if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast(option)) { Chris@668: QStyleOptionGroupBox copy = *groupBox; Chris@668: // QGroupBox::title { subcontrol-position: top center; } Chris@668: copy.textAlignment = Qt::AlignHCenter; Chris@668: Chris@668: // Draw frame Chris@668: QRect textRect = subControlRect(CC_GroupBox, ©, SC_GroupBoxLabel, widget); Chris@668: QRect checkBoxRect = subControlRect(CC_GroupBox, ©, SC_GroupBoxCheckBox, widget); Chris@668: if (groupBox->subControls & QStyle::SC_GroupBoxFrame) { Chris@668: QStyleOptionFrame frame; Chris@668: frame.QStyleOption::operator=(*groupBox); Chris@668: #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) Chris@668: frame.features = groupBox->features; Chris@668: #endif Chris@668: frame.lineWidth = groupBox->lineWidth; Chris@668: frame.midLineWidth = groupBox->midLineWidth; Chris@668: frame.rect = subControlRect(CC_GroupBox, ©, SC_GroupBoxFrame, widget); Chris@668: painter->save(); Chris@668: Chris@668: QRegion region(groupBox->rect); Chris@668: if (!groupBox->text.isEmpty()) { Chris@668: bool ltr = groupBox->direction == Qt::LeftToRight; Chris@668: QRect finalRect; Chris@668: if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox) { Chris@668: finalRect = checkBoxRect.united(textRect); Chris@668: finalRect.adjust(ltr ? -4 : 0, 0, ltr ? 0 : 4, 0); Chris@668: } else { Chris@668: finalRect = textRect; Chris@668: } Chris@668: region -= finalRect; Chris@668: } Chris@668: Chris@668: // Draw background without clipping Chris@668: painter->setPen(Qt::NoPen); Chris@668: painter->setBrush(QColor(0x40, 0x40, 0x40)); Chris@668: painter->drawRoundedRect(frame.rect.adjusted(2, 2, -2, -2), 4, 4); Chris@668: Chris@668: painter->setClipRegion(region); Chris@668: // Draw frame with clipping Chris@668: drawPrimitive(PE_FrameGroupBox, &frame, painter, widget); Chris@668: painter->restore(); Chris@668: } Chris@668: Chris@668: copy.subControls &= ~SC_GroupBoxFrame; Chris@668: QProxyStyle::drawComplexControl(control, ©, painter, widget); Chris@668: } Chris@668: return; Chris@668: case CC_ToolButton: Chris@668: if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast(option)) { Chris@668: QRect button = subControlRect(control, toolbutton, SC_ToolButton, widget); Chris@668: QRect menuarea = subControlRect(control, toolbutton, SC_ToolButtonMenu, widget); Chris@668: State bflags = toolbutton->state & ~State_Sunken; Chris@668: Chris@668: /*if (bflags & State_AutoRaise) { Chris@668: if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) { Chris@668: bflags &= ~State_Raised; Chris@668: } Chris@668: }*/ Chris@668: State mflags = bflags; Chris@668: if (toolbutton->state & State_Sunken) { Chris@668: if (toolbutton->activeSubControls & SC_ToolButton) Chris@668: bflags |= State_Sunken; Chris@668: else // added this "else" so that the down arrow only shifts by +1,+1 when actually clicking on it, not when clicking on the main toolbutton Chris@668: mflags |= State_Sunken; Chris@668: } Chris@668: Chris@668: QStyleOption tool = *toolbutton; Chris@668: if (toolbutton->subControls & SC_ToolButton) { Chris@668: tool.rect = button; Chris@668: tool.state = bflags; Chris@668: drawPrimitive(PE_PanelButtonTool, &tool, painter, widget); Chris@668: } Chris@668: QStyleOptionToolButton label = *toolbutton; Chris@668: label.state = bflags; Chris@668: int fw = pixelMetric(PM_DefaultFrameWidth, option, widget); Chris@668: label.rect = button.adjusted(fw, fw, -fw, -fw); Chris@668: // QToolButton { color: #FFFFFF; } Chris@668: label.palette.setColor(QPalette::ButtonText, Qt::white); Chris@668: drawControl(CE_ToolButtonLabel, &label, painter, widget); Chris@668: Chris@668: if (mflags & State_Sunken) { Chris@668: // QToolButton::menu-arrow:open { top: 1px; left: 1px; /* shift it a bit */ } Chris@668: painter->translate(1, 1); Chris@668: } Chris@668: if (toolbutton->subControls & SC_ToolButtonMenu) { // popupMode == QToolButton::MenuButtonPopup Chris@668: tool.rect = menuarea; Chris@668: tool.state = mflags; Chris@668: drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget); Chris@668: } else if (toolbutton->features & QStyleOptionToolButton::HasMenu) { // InstantPopup, like QPushButton menu Chris@668: // "the arrow on tool buttons with menus in InstantPopup mode is intentionally styled out of existence" Chris@668: } Chris@668: } Chris@668: return; Chris@668: case CC_ComboBox: Chris@668: if (const QStyleOptionComboBox *cmb = qstyleoption_cast(option)) { Chris@668: if ((cmb->subControls & SC_ComboBoxFrame)) { Chris@668: // QComboBox { border: 1px solid #AAAAAA; border-radius: 3px; } Chris@668: // QComboBox::!enabled { border: 1px solid #808080; border-radius: 3px; } Chris@668: if (option->state & State_Enabled) Chris@668: painter->setPen(QColor(0xAA, 0xAA, 0xAA)); Chris@668: else Chris@668: painter->setPen(QColor(0x80, 0x80, 0x80)); Chris@668: Chris@668: if (option->state & State_MouseOver) { Chris@668: // QComboBox:hover { background-color: #CCDFFF; } Chris@668: painter->setBrush(QColor(0xCC, 0xDF, 0xFF)); Chris@668: } else if (cmb->editable) { Chris@668: // QComboBox::editable { background-color: #FFFFFF; } Chris@668: painter->setBrush(Qt::white); Chris@668: } else { Chris@668: // QComboBox::!editable { background-color: qlineargradient(x1:0, y1:1, x2:0, y2:0, stop:0 #999999, stop:1 #DDDDDD); } Chris@668: // QComboBox::!editable::on { background-color: qlineargradient(x1:0, y1:1, x2:0, y2:0, stop:0 #E0E0E0, stop:1 #EEEEEE); } Chris@668: QLinearGradient gradient; Chris@668: gradient.setStart(0, 0); Chris@668: gradient.setFinalStop(0, option->rect.height()); Chris@668: if (option->state & State_On) { Chris@668: gradient.setColorAt(0, QColor(0xEE, 0xEE, 0xEE)); Chris@668: gradient.setColorAt(1, QColor(0xE0, 0xE0, 0xE0)); Chris@668: } else { Chris@668: if (qobject_cast(widget->parentWidget())) { Chris@668: gradient.setColorAt(0, QColor(0xEE, 0xEE, 0xEE)); Chris@668: gradient.setColorAt(1, QColor(0xDD, 0xDD, 0xDD)); Chris@668: } else { Chris@668: gradient.setColorAt(0, QColor(0xDD, 0xDD, 0xDD)); Chris@668: gradient.setColorAt(1, QColor(0x99, 0x99, 0x99)); Chris@668: } Chris@668: } Chris@668: painter->setBrush(gradient); Chris@668: } Chris@668: painter->setRenderHint(QPainter::Antialiasing); Chris@668: painter->drawRoundedRect(option->rect, 3, 3); Chris@668: } Chris@668: if (cmb->subControls & SC_ComboBoxArrow) { Chris@668: // from qwindowsstyle.cpp, without the rect around the arrow Chris@668: State flags = State_None; Chris@668: QRect ar = subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget); Chris@668: bool sunkenArrow = cmb->activeSubControls == SC_ComboBoxArrow Chris@668: && cmb->state & State_Sunken; Chris@668: ar.adjust(2, 2, -2, -2); Chris@668: if (option->state & State_Enabled) Chris@668: flags |= State_Enabled; Chris@668: if (option->state & State_HasFocus) Chris@668: flags |= State_HasFocus; Chris@668: Chris@668: if (sunkenArrow) Chris@668: flags |= State_Sunken; Chris@668: QStyleOption arrowOpt = *cmb; Chris@668: arrowOpt.rect = ar.adjusted(1, 1, -1, -1); Chris@668: arrowOpt.state = flags; Chris@668: drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, painter, widget); Chris@668: } Chris@668: #if 0 Chris@668: if (cmb->subControls & SC_ComboBoxEditField) { Chris@668: QRect re = subControlRect(CC_ComboBox, cmb, SC_ComboBoxEditField, widget); Chris@668: if (cmb->state & State_HasFocus && !cmb->editable) Chris@668: p->fillRect(re.x(), re.y(), re.width(), re.height(), Chris@668: cmb->palette.brush(QPalette::Highlight)); Chris@668: } Chris@668: #endif Chris@668: } Chris@668: return; Chris@668: case CC_SpinBox: Chris@668: if (const QStyleOptionSpinBox *sb = qstyleoption_cast(option)) { Chris@668: bool enabled = option->state & State_Enabled; Chris@668: painter->setRenderHint(QPainter::Antialiasing); Chris@668: QPainterPath framePath; Chris@668: // Draw background color (white), clipped to the rounded rect frame, Chris@668: // without drawing that frame yet (we'll do that last). Chris@668: // That same clipping will be useful for the round corner of the up/down buttons Chris@668: QRect frameRect = subControlRect(CC_SpinBox, sb, SC_SpinBoxFrame, widget).adjusted(2, 2, -2, -2); Chris@668: framePath.addRoundedRect(frameRect, 4, 4); Chris@668: painter->setClipPath(framePath); Chris@668: painter->fillRect(frameRect, sb->palette.brush(QPalette::Base)); Chris@668: const QRect spinupRect = subControlRect(CC_SpinBox, sb, SC_SpinBoxUp, widget); Chris@668: QLinearGradient gradient; Chris@668: gradient.setColorAt(0, QColor(0xDD, 0xDD, 0xDD)); Chris@668: gradient.setColorAt(1, QColor(0x99, 0x99, 0x99)); Chris@668: painter->setPen(QColor(0xAA, 0xAA, 0xAA)); Chris@668: if (sb->subControls & SC_SpinBoxUp) { Chris@668: gradient.setStart(spinupRect.topLeft()); Chris@668: gradient.setFinalStop(spinupRect.bottomLeft()); Chris@668: if (sb->activeSubControls == SC_SpinBoxUp && !(option->state & State_Sunken)) Chris@668: painter->setBrush(QColor(0xDD, 0xEF, 0xFF)); Chris@668: else Chris@668: painter->setBrush(gradient); Chris@668: painter->drawRect(spinupRect); Chris@668: Chris@668: QPixmap pixmap = enabled ? m_arrowUpSmallPixmap Chris@668: : m_arrowUpSmallInvertedPixmap; // off state when value is max Chris@668: pixmap = pixmap.scaled(QSize(7, 7), Qt::KeepAspectRatio, Qt::SmoothTransformation); // TODO: edit the PNGs instead, would be faster Chris@668: const QRect drawRect = alignedRect(option->direction, Qt::AlignCenter, pixmap.size(), spinupRect); Chris@668: painter->drawPixmap(drawRect.topLeft(), pixmap); Chris@668: } Chris@668: if (sb->subControls & SC_SpinBoxDown) { Chris@668: const QRect spindownRect = subControlRect(CC_SpinBox, sb, SC_SpinBoxDown, widget); Chris@668: gradient.setStart(spindownRect.topLeft()); Chris@668: gradient.setFinalStop(spindownRect.bottomLeft()); Chris@668: if (sb->activeSubControls == SC_SpinBoxDown && (option->state & State_MouseOver)) Chris@668: painter->setBrush(QColor(0xDD, 0xEF, 0xFF)); Chris@668: else Chris@668: painter->setBrush(gradient); Chris@668: painter->drawRect(spindownRect); Chris@668: Chris@668: QPixmap pixmap = enabled ? m_arrowDownSmallPixmap Chris@668: : m_arrowDownSmallInvertedPixmap; // off state when value is max Chris@668: pixmap = pixmap.scaled(QSize(7, 7), Qt::KeepAspectRatio, Qt::SmoothTransformation); // TODO: edit the PNGs instead, would be faster Chris@668: const QRect drawRect = alignedRect(option->direction, Qt::AlignCenter, pixmap.size(), spindownRect); Chris@668: painter->drawPixmap(drawRect.topLeft(), pixmap); Chris@668: } Chris@668: painter->setClipping(false); Chris@668: painter->setBrush(Qt::NoBrush); Chris@668: painter->setPen(QColor(0xB0, 0xB0, 0xB0)); // grabbed in frame.png Chris@668: painter->drawRoundedRect(frameRect, 4, 4); Chris@668: } Chris@668: return; Chris@668: default: Chris@668: break; Chris@668: } Chris@668: QProxyStyle::drawComplexControl(control, option, painter, widget); Chris@668: } Chris@668: Chris@668: QSize ThornStyle::sizeFromContents(QStyle::ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const Chris@668: { Chris@668: QSize sz = QProxyStyle::sizeFromContents(type, option, size, widget); Chris@668: switch (type) { Chris@668: case CT_LineEdit: Chris@668: // Reduce size of lineedits, to make the NameSetEditor more compact (in the BankEditorDialog) Chris@668: sz -= QSize(2, 2); Chris@668: break; Chris@668: case CT_SpinBox: Chris@668: if (const QStyleOptionSpinBox *vopt = qstyleoption_cast(option)) { Chris@668: // Add button + frame widths Chris@668: const int buttonWidth = m_spinupPixmap.width(); Chris@668: const int fw = vopt->frame ? pixelMetric(PM_SpinBoxFrameWidth, vopt, widget) : 0; Chris@668: sz += QSize(buttonWidth + 2*fw, 2*fw); Chris@668: } Chris@668: break; Chris@668: default: Chris@668: break; Chris@668: } Chris@668: return sz; Chris@668: } Chris@668: Chris@668: QRect ThornStyle::subElementRect(QStyle::SubElement element, const QStyleOption *option, const QWidget *widget) const Chris@668: { Chris@668: QRect rect = QProxyStyle::subElementRect(element, option, widget); Chris@668: switch (element) { Chris@668: case SE_TabWidgetTabBar: Chris@668: // QTabWidget::tab-bar { left: 5px; /* move to the right by 5px */ } Chris@668: return rect.translated(5, 0); Chris@668: case SE_TabWidgetTabPane: Chris@668: return rect; Chris@668: case SE_TabWidgetTabContents: Chris@668: return rect.adjusted(2, 2, -2, -2); Chris@668: case SE_HeaderArrow: { Chris@668: const QSize size = pixmapSize(m_arrowUpSmallInvertedPixmap); Chris@668: QRect sectionRect = option->rect.adjusted(0, 0, -5, 0); Chris@668: const QRect ret = alignedRect(option->direction, Qt::AlignRight | Qt::AlignVCenter, size, sectionRect); Chris@668: return ret; Chris@668: } Chris@668: case SE_ToolBarHandle: Chris@668: if (const QStyleOptionToolBar *tbopt = qstyleoption_cast(option)) { Chris@668: // initially from qcommonstyle.cpp Chris@668: if (tbopt->features & QStyleOptionToolBar::Movable) { Chris@668: const QToolBar *tb = qobject_cast(widget); Chris@668: const int margin = 1; Chris@668: const int handleExtent = pixelMetric(QStyle::PM_ToolBarHandleExtent, option, tb); Chris@668: QRect ret; Chris@668: if (tbopt->state & QStyle::State_Horizontal) { Chris@668: ret = QRect(margin, margin, handleExtent, tbopt->rect.height() - 2*margin); Chris@668: ret = QStyle::visualRect(tbopt->direction, tbopt->rect, ret); Chris@668: } else { Chris@668: ret = QRect(margin, margin, tbopt->rect.width() - 2*margin, handleExtent); Chris@668: } Chris@668: return ret; Chris@668: } Chris@668: } Chris@668: break; Chris@668: default: Chris@668: break; Chris@668: } Chris@668: Chris@668: return rect; Chris@668: } Chris@668: Chris@668: QRect ThornStyle::subControlRect(QStyle::ComplexControl cc, const QStyleOptionComplex *option, QStyle::SubControl sc, const QWidget *widget) const Chris@668: { Chris@668: switch (cc) { Chris@668: case CC_ScrollBar: Chris@668: if (const QStyleOptionSlider *scrollBar = qstyleoption_cast(option)) { Chris@668: QStyleOptionSlider copy = *scrollBar; Chris@668: // QScrollBar said { border: 2px solid #404040; } Chris@668: // We draw that border by filling everything and reducing the available size for contents Chris@668: copy.rect.adjust(2, 2, -2, -2); Chris@668: return QProxyStyle::subControlRect(cc, ©, sc, widget).adjusted(2, 2, 2, 2); Chris@668: } Chris@668: break; Chris@668: case CC_Slider: Chris@668: if (const QStyleOptionSlider *slider = qstyleoption_cast(option)) { Chris@668: //QSlider::groove:horizontal { height: 5px; } Chris@668: const int grooveThickness = 5; Chris@668: QRect ret; Chris@668: Chris@668: switch (sc) { Chris@668: case SC_SliderHandle: { Chris@668: int sliderPos = 0; Chris@668: // QSlider::handle:horizontal { width: 8px; }, but this needs to be 9 to look like the old qss for some reason Chris@668: int len = 9; Chris@668: bool horizontal = slider->orientation == Qt::Horizontal; Chris@668: sliderPos = sliderPositionFromValue(slider->minimum, slider->maximum, Chris@668: slider->sliderPosition, Chris@668: (horizontal ? slider->rect.width() Chris@668: : slider->rect.height()) - len, Chris@668: slider->upsideDown); Chris@668: if (horizontal) { Chris@668: ret.setRect(slider->rect.x() + sliderPos, slider->rect.y() + 1, len, slider->rect.height() - 2); Chris@668: } else { Chris@668: ret.setRect(slider->rect.x() + 1, slider->rect.y() + sliderPos, slider->rect.width() - 2, len); Chris@668: } Chris@668: //qDebug() << "ret=" << ret; Chris@668: break; Chris@668: } Chris@668: case SC_SliderGroove: Chris@668: if (slider->orientation == Qt::Horizontal) { Chris@668: const int yOff = (slider->rect.height() - grooveThickness ) / 2; Chris@668: ret.setRect(slider->rect.x(), slider->rect.y() + yOff, Chris@668: slider->rect.width(), grooveThickness); Chris@668: } else { Chris@668: const int xOff = (slider->rect.width() - grooveThickness ) / 2; Chris@668: ret.setRect(slider->rect.x() + xOff, slider->rect.y(), Chris@668: grooveThickness, slider->rect.height()); Chris@668: } Chris@668: break; Chris@668: default: Chris@668: break; Chris@668: } Chris@668: return visualRect(slider->direction, slider->rect, ret); Chris@668: } Chris@668: break; Chris@668: case CC_SpinBox: Chris@668: if (const QStyleOptionSpinBox *sb = qstyleoption_cast(option)) { Chris@668: const int fw = 3; // frame width Chris@668: const int buttonTopBottomMargin = fw - 1; Chris@668: const QSize buttonSize(18, (sb->rect.height() - buttonTopBottomMargin) / 2 - 1); Chris@668: const int x = sb->rect.x() + sb->rect.width() - fw - buttonSize.width(); Chris@668: const int y = sb->rect.y() + buttonTopBottomMargin; Chris@668: QRect ret; Chris@668: switch (sc) { Chris@668: case SC_SpinBoxFrame: Chris@668: return sb->rect; Chris@668: case SC_SpinBoxUp: Chris@668: if (sb->buttonSymbols == QAbstractSpinBox::NoButtons) Chris@668: return QRect(); Chris@668: ret = QRect(x, y, buttonSize.width(), buttonSize.height()); Chris@668: break; Chris@668: case SC_SpinBoxDown: Chris@668: if (sb->buttonSymbols == QAbstractSpinBox::NoButtons) Chris@668: return QRect(); Chris@668: ret = QRect(x, sb->rect.height() - buttonTopBottomMargin - buttonSize.height(), buttonSize.width(), buttonSize.height()); Chris@668: break; Chris@668: case SC_SpinBoxEditField: Chris@668: if (sb->buttonSymbols == QAbstractSpinBox::NoButtons) { Chris@668: ret = QRect(sb->rect.x() + fw, fw, sb->rect.width() - 2*fw, sb->rect.height() - 2*fw); Chris@668: } else { Chris@668: ret = QRect(sb->rect.x() + fw, fw, x - fw, sb->rect.height() - 2*fw); Chris@668: } Chris@668: break; Chris@668: default: Chris@668: break; Chris@668: } Chris@668: return visualRect(sb->direction, sb->rect, ret); Chris@668: } Chris@668: break; Chris@668: default: Chris@668: break; Chris@668: } Chris@668: Chris@668: return QProxyStyle::subControlRect(cc, option, sc, widget); Chris@668: } Chris@668: Chris@668: #pragma GCC diagnostic pop