void Style::drawHeader(const QStyleOption *option, QPainter *painter, const QWidget *widget) const { ASSURE_OPTION(header, Header); if (appType == GTK) const_cast<QStyleOption*>(option)->palette = qApp->palette(); // init // const QRegion clipRegion = painter->clipRegion(); // painter->setClipRect(RECT/*, Qt::IntersectClip*/); // base drawHeaderSection(header, painter, widget); // label drawHeaderLabel(header, painter, widget); // sort Indicator on sorting or (inverted) on hovered headers if (header->sortIndicator != QStyleOptionHeader::None) { QStyleOptionHeader subopt = *header; subopt.rect = subElementRect(SE_HeaderArrow, option, widget); drawHeaderArrow(&subopt, painter, widget); } // painter->setClipRegion(clipRegion); }
void Style::drawSpinBox(const QStyleOptionComplex * option, QPainter * painter, const QWidget * widget) const { ASSURE_OPTION(sb, SpinBox); OPT_ENABLED QStyleOptionSpinBox copy = *sb; // this doesn't work (for the moment, i assume...) // isEnabled = isEnabled && !(option->state & State_ReadOnly); if (isEnabled) if (const QAbstractSpinBox *box = qobject_cast<const QAbstractSpinBox*>(widget)) { isEnabled = isEnabled && !box->isReadOnly(); if (!isEnabled) copy.state &= ~State_Enabled; } if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) drawLineEdit(©, painter, widget); if (!isEnabled) return; // why bother the user with elements he can't use... ;) painter->setPen(Qt::NoPen); drawSBArrow(SC_SpinBoxUp, painter, ©, widget, this); copy.rect = RECT; copy.subControls = sb->subControls; drawSBArrow(SC_SpinBoxDown, painter, ©, widget, this); }
void Style::drawTab(const QStyleOption *option, QPainter *painter, const QWidget *widget) const { ASSURE_OPTION(tab, Tab); // do we have to exclude the scrollers? bool needRestore = false; if (widget && qobject_cast<const QTabBar*>(widget)) { QRegion clipRgn = painter->clipRegion(); if (clipRgn.isEmpty()) clipRgn = RECT; QList<QToolButton*> buttons = widget->findChildren<QToolButton*>(); foreach (QToolButton* button, buttons) { if (button->isVisible()) clipRgn -= QRect(button->pos(), button->size()); } if (!clipRgn.isEmpty()) { painter->save(); needRestore = true; painter->setClipRegion(clipRgn); } }
void Style::drawSpinBox(const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const { ASSURE_OPTION(sb, SpinBox); OPT_ENABLED SAVE_PAINTER(Pen|Brush|Alias); QStyleOptionSpinBox copy = *sb; // this doesn't work (for the moment, i assume...) // isEnabled = isEnabled && !(option->state & State_ReadOnly); if (isEnabled) if (const QAbstractSpinBox *box = qobject_cast<const QAbstractSpinBox*>(widget)) { isEnabled = isEnabled && !box->isReadOnly(); if (!isEnabled) copy.state &= ~State_Enabled; } if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) drawLineEditFrame(©, painter, widget); if (!isEnabled) { RESTORE_PAINTER return; // why bother the user with elements he can't use... ;) }
void Style::drawComboBoxLabel(const QStyleOption *option, QPainter *painter, const QWidget *widget) const { ASSURE_OPTION(cb, ComboBox); OPT_ENABLED QRect editRect = subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, widget); painter->save(); painter->setClipRect(editRect); if (!(cb->currentIcon.isNull() || cb->iconSize.isNull())) { // icon =============================================== QIcon::Mode mode = isEnabled ? QIcon::Normal : QIcon::Disabled; QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, mode); QRect iconRect(editRect); iconRect.setWidth(cb->iconSize.width() + 4); iconRect = alignedRect( cb->direction, Qt::AlignLeft | Qt::AlignVCenter, iconRect.size(), editRect); // if (cb->editable) // painter->fillRect(iconRect, opt->palette.brush(QPalette::Base)); drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap); if (cb->direction == Qt::LeftToRight) editRect.setLeft(editRect.left() + cb->iconSize.width() + 4); else editRect.setRight(editRect.right() - (cb->iconSize.width() + 4)); } if (!cb->currentText.isEmpty() && !cb->editable) { // text ================================================== if (cb->frame) { OPT_FOCUS if (animStep < 0) { OPT_HOVER animStep = hover ? 6 : 0; } else { if (const QComboBox* combo = qobject_cast<const QComboBox*>(widget)) if (combo->view() && ((QWidget*)(combo->view()))->isVisible()) animStep = 6; } editRect.adjust(F(3),0, -F(3), -F(1)*(config.chooser.layer != Sunken)); // trick btnFg const int btn_layer = config.btn.layer; config.btn.layer = config.chooser.layer; painter->setPen(btnFg(PAL, isEnabled, hasFocus, animStep)); config.btn.layer = btn_layer; } int tf = Qt::AlignCenter; if ( !((cb->subControls & SC_ComboBoxFrame) && cb->frame) ) tf = Qt::AlignVCenter | (cb->direction == Qt::LeftToRight ? Qt::AlignLeft : Qt::AlignRight); drawItemText(painter, editRect, tf, PAL, isEnabled, cb->currentText); }
void Style::drawTabWidget(const QStyleOption *option, QPainter *painter, const QWidget *widget) const { ASSURE_OPTION(twf, TabWidgetFrame); SAVE_PAINTER(Pen); QStyleOptionTabBarBaseV2 tbb; if (widget) tbb.initFrom(widget); else tbb.QStyleOption::operator=(*twf); tbb.shape = twf->shape; tbb.rect = twf->rect; if HAVE_OPTION(twf2, TabWidgetFrameV2) { tbb.selectedTabRect = twf2->selectedTabRect; } #define SET_BASE_HEIGHT(_o_) \ baseHeight = twf->tabBarSize._o_(); \ if (!baseHeight) { \ RESTORE_PAINTER; return; \ } /* no base -> no tabbing -> no bottom border either. period.*/\ if (baseHeight < 0) \ baseHeight = pixelMetric( PM_TabBarBaseHeight, option, widget ) int baseHeight; painter->setPen(FRAME_PEN); switch (twf->shape) { case QTabBar::RoundedNorth: case QTabBar::TriangularNorth: SET_BASE_HEIGHT(height); tbb.rect.setHeight(baseHeight); painter->drawLine(RECT.bottomLeft(), RECT.bottomRight()); break; case QTabBar::RoundedSouth: case QTabBar::TriangularSouth: SET_BASE_HEIGHT(height); tbb.rect.setTop(tbb.rect.bottom()-baseHeight); painter->drawLine(RECT.topLeft(), RECT.topRight()); break; case QTabBar::RoundedEast: case QTabBar::TriangularEast: SET_BASE_HEIGHT(width); tbb.rect.setLeft(tbb.rect.right()-baseHeight); painter->drawLine(RECT.topLeft(), RECT.bottomLeft()); break; case QTabBar::RoundedWest: case QTabBar::TriangularWest: SET_BASE_HEIGHT(width); tbb.rect.setWidth(baseHeight); painter->drawLine(RECT.topRight(), RECT.bottomRight()); break; } #undef SET_BASE_HEIGHT // the "frame" // the bar drawTabBar(&tbb, painter, widget); RESTORE_PAINTER }
void Style::drawDockTitle(const QStyleOption *option, QPainter *painter, const QWidget *widget) const { ASSURE_OPTION(dock, DockWidget); SAVE_PAINTER(Pen|Brush|Alias|Font); const bool floating = widget && widget->isWindow(); QRect rect = RECT; if (!dock->title.isEmpty()) { OPT_ENABLED const int bo = 16 + F(6); bool verticalTitleBar = false; if HAVE_OPTION(dock2, DockWidgetV2) { verticalTitleBar = dock2->verticalTitleBar; } if (verticalTitleBar) { int y = rect.y() + rect.height(); rect.setRect(0, 0, rect.height(), rect.width()); QMatrix m; m.translate(0, y); m.rotate(-90); painter->setMatrix(m, true); rect.adjust(0, dock->closable ? bo : F(4), 0, dock->closable ? -bo : -F(4)); } else { rect.adjust(dock->closable ? bo : F(4), 0, dock->closable ? -bo : -F(4), 0); } // text const int itemtextopts = Qt::AlignCenter | Qt::TextSingleLine | Qt::TextHideMnemonic; QPalette::ColorRole bg = widget ? widget->backgroundRole() : QPalette::Window; QPalette::ColorRole fg = widget ? widget->foregroundRole() : QPalette::WindowText; setBold(painter, dock->title, rect.width()); if (floating && widget->isActiveWindow()) painter->setPen(COLOR(fg)); else painter->setPen(FX::blend(COLOR(bg), COLOR(fg), 2, 1+isEnabled)); drawItemText(painter, rect, itemtextopts, PAL, isEnabled, dock->title, QPalette::NoRole, &rect); if (option->direction == Qt::LeftToRight) rect.setRect(rect.x() - F(8), rect.y(), F(8), rect.height()); else rect.setRect(rect.right(), rect.y(), F(8), rect.height()); }
void Style::drawGroupBox(const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const { ASSURE_OPTION(groupBox, GroupBox); OPT_ENABLED // Frame if (groupBox->subControls & QStyle::SC_GroupBoxFrame) { QStyleOptionFrameV2 frame; frame.QStyleOption::operator=(*groupBox); frame.features = groupBox->features; frame.lineWidth = groupBox->lineWidth; frame.midLineWidth = groupBox->midLineWidth; frame.rect = subControlRect(CC_GroupBox, option, SC_GroupBoxFrame, widget); drawGroupBoxFrame(&frame, painter, widget); } // Title if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) { QColor textColor = groupBox->textColor; QPalette::ColorRole role = QPalette::WindowText; // NOTICE, WORKAROUND: groupBox->textColor is black by def. and should be invalid - but it's not // so assuming everything is optimized for a black on white world, we assume the // CUSTOM groupBox->textColor to be only valid if it's != Qt::black // THIS IS A HACK! if (textColor.isValid() && textColor != Qt::black) { if (!isEnabled) textColor.setAlpha(48); painter->setPen(textColor); role = QPalette::NoRole; } setTitleFont(painter, groupBox->text, RECT.width()); QStyleOptionGroupBox copy = *groupBox; copy.fontMetrics = QFontMetrics(painter->font()); QRect textRect = subControlRect(CC_GroupBox, ©, SC_GroupBoxLabel, widget); drawItemText(painter, textRect, BESPIN_MNEMONIC, groupBox->palette, isEnabled, groupBox->text, role); if (groupBox->features & QStyleOptionFrameV2::Flat) { Tile::PosFlags pf = Tile::Center; if (option->direction == Qt::LeftToRight) { textRect.setLeft(RECT.left()); textRect.setRight(textRect.right() + (RECT.right()-textRect.right())/2); pf |= Tile::Right; } else { textRect.setRight(RECT.right()); textRect.setLeft(textRect.left() - (textRect.left() - RECT.left())/2); pf |= Tile::Left; } shadows.line[0][Sunken].render(textRect, painter, pf, true); // const int x = textRect.right(); // textRect.setRight(RECT.right()); textRect.setLeft(x); // shadows.line[0][Sunken].render(textRect, painter, Tile::Center | Tile::Right, true); } else if (config.groupBoxMode) { const int x = textRect.width()/8; textRect.adjust(x,0,-x,0); shadows.line[0][Sunken].render(textRect, painter, Tile::Full, true); } } // Checkbox // TODO: doesn't hover - yet. if (groupBox->subControls & SC_GroupBoxCheckBox) { QStyleOptionButton box; box.QStyleOption::operator=(*groupBox); box.rect = subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget); // box.state |= State_HasFocus; // focus to signal this to the user if (groupBox->activeSubControls & SC_GroupBoxCheckBox) box.state |= State_MouseOver; drawRadio(&box, painter, 0L); } }
void Style::drawSlider(const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const { ASSURE_OPTION(slider, Slider); OPT_SUNKEN OPT_ENABLED OPT_HOVER if (isEnabled && slider->subControls & SC_SliderTickmarks) { int ticks = slider->tickPosition; if (ticks != QSlider::NoTicks) { int available = pixelMetric(PM_SliderSpaceAvailable, slider, widget); int interval = slider->tickInterval; if (interval < 1) interval = slider->pageStep; if (interval) { // const int thickness = pixelMetric(PM_SliderControlThickness, slider, widget); const int len = pixelMetric(PM_SliderLength, slider, widget); const int fudge = len / 2; int pos, v = slider->minimum, nextInterval; // Since there is no subrect for tickmarks do a translation here. painter->save(); painter->translate(RECT.x(), RECT.y()); #define DRAW_TICKS(_X1_, _Y1_, _X2_, _Y2_) \ while (v <= slider->maximum) { \ pos = sliderPositionFromValue(slider->minimum, slider->maximum, v, available) + fudge;\ painter->drawLine(_X1_, _Y1_, _X2_, _Y2_);\ nextInterval = v + interval;\ if (nextInterval < v) break;\ v = nextInterval; \ } // skip semicolon painter->setPen(Colors::mid(BGCOLOR, FGCOLOR, 3,1)); if (slider->orientation == Qt::Horizontal) { const int y = RECT.height()/2; if (ticks == QSlider::TicksAbove) { DRAW_TICKS(pos, 0, pos, y); } else if (ticks == QSlider::TicksBelow) { DRAW_TICKS(pos, y, pos, RECT.height()); } else { DRAW_TICKS(pos, RECT.y(), pos, RECT.height()); } } else { const int x = RECT.width()/2; if (ticks == QSlider::TicksAbove) { DRAW_TICKS(0, pos, x, pos); } else if (ticks == QSlider::TicksBelow) { DRAW_TICKS(x, pos, RECT.width(), pos); } else { DRAW_TICKS(0, pos, RECT.width(), pos); } } painter->restore(); } } } QRect groove = subControlRect(CC_Slider, slider, SC_SliderGroove, widget); QRect handle = subControlRect(CC_Slider, slider, SC_SliderHandle, widget); isEnabled = isEnabled && (slider->maximum > slider->minimum); hover = isEnabled && (appType == GTK || (hover && (slider->activeSubControls & SC_SliderHandle))); sunken = sunken && (slider->activeSubControls & SC_SliderHandle); // const int ground = 0; // groove if ((slider->subControls & SC_SliderGroove) && groove.isValid()) { QStyleOption grooveOpt = *option; grooveOpt.rect = groove; const Groove::Mode gType = config.scroll.groove; if (gType) config.scroll.groove = Groove::Groove; drawScrollBarGroove(&grooveOpt, painter, widget); config.scroll.groove = gType; #if 1 // thermometer, #2 if (slider->minimum > -1 && (slider->maximum - slider->minimum) > 20 && slider->sliderPosition != slider->minimum) { SAVE_PEN; bool hadAntiAlias = painter->testRenderHint(QPainter::Antialiasing); painter->setRenderHint( QPainter::Antialiasing, gType ); painter->setPen(QPen(CCOLOR(scroll._, Fg), gType ? F(3) : F(1), Qt::SolidLine, Qt::RoundCap)); if ( slider->orientation == Qt::Horizontal ) { const int y = groove.center().y() + (gType ? 1 : 0); bool ltr = slider->direction == Qt::LeftToRight; if (slider->upsideDown) ltr = !ltr; const int x2 = ltr ? groove.left() + F(5) : groove.right() - F(5); painter->drawLine(handle.center().x(), y, x2, y); } else { const int x = groove.center().x(); const int y2 = slider->upsideDown ? groove.bottom() - F(5) : groove.top() + F(5); painter->drawLine(x, handle.center().y(), x, y2); } painter->setRenderHint( QPainter::Antialiasing, hadAntiAlias ); RESTORE_PEN; } #endif } // int direction = 0; // if (slider->orientation == Qt::Vertical) // ++direction; // handle ====================================== if (slider->subControls & SC_SliderHandle) { int step = 0; if (sunken) step = 6; else if (isEnabled) { const Animator::ComplexInfo *info = Animator::HoverComplex::info(widget, slider->activeSubControls & SC_SliderHandle); if (info && ( info->fades[Animator::In] & SC_SliderHandle || info->fades[Animator::Out] & SC_SliderHandle )) step = info->step(SC_SliderHandle); if (hover && !step) step = 6; } drawSliderHandle(handle, option, painter, step); } }
void Style::drawDial(const QStyleOptionComplex *option, QPainter *painter, const QWidget *) const { ASSURE_OPTION(dial, Slider); OPT_ENABLED OPT_HOVER OPT_FOCUS painter->save(); QRect rect = RECT; if (rect.width() > rect.height()) { rect.setLeft(rect.x()+(rect.width()-rect.height())/2); rect.setWidth(rect.height()); } else { rect.setTop(rect.y()+(rect.height()-rect.width())/2); rect.setHeight(rect.width()); } int d = qMin(2*rect.width()/5, Dpi::target.SliderThickness); int r; // angle calculation from qcommonstyle.cpp (c) Trolltech 1992-2007, ASA. float a; if (dial->maximum == dial->minimum) a = M_PI / 2; else if (dial->dialWrapping) a = M_PI * 3 / 2 - (dial->sliderValue - dial->minimum) * 2 * M_PI / (dial->maximum - dial->minimum); else a = (M_PI * 8 - (dial->sliderValue - dial->minimum) * 10 * M_PI / (dial->maximum - dial->minimum)) / 6; QPoint cp = rect.center(); // fallback for small dials ============================ bool small(rect.width() < 8*Dpi::target.SliderThickness/3); if ( small ) { painter->setRenderHint( QPainter::Antialiasing ); painter->setPen(Qt::NoPen); painter->setBrush(QColor(0,0,0,50)); painter->drawEllipse(rect); rect.adjust(F(2), F(1), -F(2), -F(2)); painter->setBrushOrigin(rect.topLeft()); const QPixmap &fill = Gradients::pix(FCOLOR(Window), rect.height(), Qt::Vertical, GRAD(scroll)); painter->setBrush(fill); painter->drawEllipse(rect); QColor c = hasFocus ? FCOLOR(Highlight) : FCOLOR(WindowText); if (!hover) c = Colors::mid(FCOLOR(Window), c, 1, 1+isEnabled); d = qMax(F(3), d/4); r = (rect.width()-d)/2; cp += QPoint((int)(r * cos(a)), -(int)(r * sin(a))); painter->setPen(QPen(c, d, Qt::SolidLine, Qt::RoundCap)); painter->drawPoint(cp); } // the value ============================================== QFont fnt = painter->font(); int h = rect.height()/2; h -= 2 * (h - qMin(h, painter->fontMetrics().xHeight())) / 3; fnt.setPixelSize( h ); painter->setFont(fnt); painter->setBrush(Qt::NoBrush); painter->setPen(Colors::mid(PAL.background().color(), PAL.foreground().color(),!hasFocus,2)); drawItemText(painter, rect, Qt::AlignCenter, PAL, isEnabled, QString::number(dial->sliderValue)); if (small) { painter->restore(); return; } r = (rect.width()-d)/2; cp += QPoint((int)(r * cos(a)), -(int)(r * sin(a))); // the huge ring ======================================= r = d/2; rect.adjust(r,r,-r,-r); painter->setPen(FCOLOR(Window).dark(115)); painter->setRenderHint( QPainter::Antialiasing ); painter->drawEllipse(rect); rect.translate(0, 1); painter->setPen(FCOLOR(Window).light(108)); painter->drawEllipse(rect); // the drop =========================== rect = QRect(0,0,d,d); rect.moveCenter(cp); drawSliderHandle(rect, option, painter, hover * 6); painter->restore(); }
void Style::drawTabBar(const QStyleOption *option, QPainter *painter, const QWidget *widget) const { ASSURE_OPTION(tbb, TabBarBase); if (!config.invert.headers) { if (tbb->selectedTabRect.isEmpty()) return; // only paint tab shapes if HAVE_OPTION(tbb2, TabBarBaseV2) { if (tbb2->documentMode) { return; // useless and adds confliciting horizintal lines } } SAVE_PAINTER(Pen|Alias); painter->setRenderHint(QPainter::Antialiasing, false); painter->setPen(QPen(FRAME_COLOR, FRAME_STROKE_WIDTH)); switch (tbb->shape) { case QTabBar::RoundedNorth: case QTabBar::TriangularNorth: painter->drawLine(RECT.x(), RECT.bottom(), tbb->selectedTabRect.x(), RECT.bottom()); painter->drawLine(tbb->selectedTabRect.right(), RECT.bottom(), RECT.right(), RECT.bottom()); break; case QTabBar::RoundedSouth: case QTabBar::TriangularSouth: painter->drawLine(RECT.x(), RECT.top(), tbb->selectedTabRect.x(), RECT.top()); painter->drawLine(tbb->selectedTabRect.right(), RECT.top(), RECT.right(), RECT.top()); break; case QTabBar::RoundedEast: case QTabBar::TriangularEast: painter->drawLine(RECT.x(), RECT.y(), RECT.x(), tbb->selectedTabRect.y()); painter->drawLine(RECT.x(), tbb->selectedTabRect.bottom(), RECT.x(), RECT.bottom()); break; case QTabBar::RoundedWest: case QTabBar::TriangularWest: painter->drawLine(RECT.right(), RECT.y(), RECT.right(), tbb->selectedTabRect.y()); painter->drawLine(RECT.right(), tbb->selectedTabRect.bottom(), RECT.right(), RECT.bottom()); break; } RESTORE_PAINTER return; } QWidget *win = 0; if (widget) { if (widget->parentWidget() && qobject_cast<QTabWidget*>(widget->parentWidget())) { if (widget->parentWidget()->style() == this) { return; // otherwise it's a proxystyle like on konqueror / kdevelop... } } else if (qobject_cast<const QTabBar*>(widget) || (appType == KDevelop && widget->inherits("QLabel"))) { return; // usually we alter the paintevent by eventfiltering } win = widget->window(); } else { if (painter->device()->devType() == QInternal::Widget) widget = static_cast<QWidget*>(painter->device()); else { QPaintDevice *dev = QPainter::redirected(painter->device()); if (dev && dev->devType() == QInternal::Widget) widget = static_cast<QWidget*>(dev); } if ( widget ) win = widget->window(); } QRect winRect; if (win) { winRect = win->rect(); winRect.moveTopLeft(widget->mapFrom(win, winRect.topLeft())); } // else // winRect = tbb->tabBarRect; // we set this from the eventfilter QEvent::Paint SAVE_PAINTER(Pen|Brush|Alias); painter->setBrush(PAL.color(QPalette::Active, QPalette::WindowText)); painter->setPen(Qt::NoPen); // TODO: half rounded rect? if (RECT.x() == winRect.x() || RECT.y() == winRect.y() || RECT.right() == winRect.right() || RECT.bottom() == winRect.bottom()) { painter->setRenderHint(QPainter::Antialiasing, false); painter->drawRect(RECT); } else { painter->setRenderHint(QPainter::Antialiasing, true); const int rnd = qMin(config.frame.roundness, verticalTabs(tbb->shape) ? RECT.width()/2 : RECT.height()/2); painter->drawRoundedRect(RECT, rnd, rnd); } RESTORE_PAINTER }
void Style::drawComboBox(const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const { ASSURE_OPTION(cmb, ComboBox); B_STATES if ( widget && widget->inherits("WebView") ) { if (!(config.btn.backLightHover || cmb->editable)) { // paints hardcoded black text bypassing the style?! grrr... QStyleOptionComboBox *_cmb = const_cast<QStyleOptionComboBox*>(cmb); _cmb->palette.setColor(config.btn.std_role[Bg], QColor(230,230,230,255)); _cmb->palette.setColor(config.btn.active_role[Bg], QColor(255,255,255,255)); } widget = 0; } const int f1 = F(1), f2 = F(2); QRect ar; const QComboBox *combo = widget ? qobject_cast<const QComboBox*>(widget) : 0; QColor c = CONF_COLOR(btn.std, Bg); const bool listShown = combo && combo->view() && ((QWidget*)(combo->view()))->isVisible(); if (listShown) // this messes up hover hover = hover || QRect(widget->mapToGlobal(RECT.topLeft()), RECT.size()).contains(QCursor::pos()); if (isEnabled && (cmb->subControls & SC_ComboBoxArrow) && (!combo || combo->count() > 0)) { // do we have an arrow? ar = subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget); ar.setBottom(ar.bottom()-f2); } // the frame if ((cmb->subControls & SC_ComboBoxFrame) && cmb->frame) { if (cmb->editable) drawLineEdit(option, painter, widget, false); else { if (!ar.isNull()) { animStep = (appType == GTK || !widget) ? 6*hover : Animator::Hover::step(widget); if (listShown) animStep = 6; int btn_layer = config.btn.layer; Gradients::Type btn_grd = config.btn.gradient; config.btn.round = !config.btn.round; const bool comboNotSmallerThanTool = config.chooser.layer == Raised || config.chooser.layer == Inlay || config.btn.tool.frame == Sunken || config.btn.tool.frame == Relief; if (comboNotSmallerThanTool && widget && qobject_cast<QToolBar*>(widget->parentWidget())) { GRAD(btn) = GRAD(btn.tool); config.btn.layer = config.btn.tool.frame; } else { GRAD(btn) = GRAD(chooser); config.btn.layer = config.chooser.layer; } drawButtonFrame(option, painter, widget, animStep); config.btn.round = !config.btn.round; config.btn.layer = btn_layer; config.btn.gradient = btn_grd; } else shadows.sunken[!config.btn.round][isEnabled].render(RECT, painter); } } // the arrow if (!ar.isNull()) { if (!(ar.width()%2) ) ar.setWidth(ar.width()-1); const int dy = ar.height()/4; QRect rect = ar.adjusted(0, dy, 0, -dy); Navi::Direction dir = Navi::S; bool upDown = false; if (listShown) dir = (config.leftHanded) ? Navi::E : Navi::W; else if (combo) { if (combo->currentIndex() == 0) dir = Navi::S; else if (combo->currentIndex() == combo->count()-1) dir = Navi::N; else upDown = true; } painter->save(); painter->setPen(Qt::NoPen); if (cmb->editable) { if (upDown || dir == Navi::N) dir = Navi::S; upDown = false; // shall never look like spinbox! hover = hover && (cmb->activeSubControls == SC_ComboBoxArrow); if (!sunken) { painter->setBrush(FCOLOR(Base).dark(105)); rect.translate(0, f2); drawArrow(dir, rect, painter); rect.translate(0, -f2); } if (hover || listShown) painter->setBrush(FCOLOR(Highlight)); else painter->setBrush( Colors::mid(FCOLOR(Base), FCOLOR(Text)) ); } else if (config.btn.backLightHover) painter->setBrush(Colors::mid(c, CONF_COLOR(btn.std, Fg), 6-animStep, 3+animStep)); else { c = Colors::mid(c, CONF_COLOR(btn.active, Bg)); c = Colors::mid(c, CONF_COLOR(btn.active, Bg), 6-animStep, animStep); masks.rect[!config.btn.round].render(ar, painter, GRAD(chooser), ori[1], c, RECT.height()-f2, QPoint(0, ar.y() - RECT.y()) ); painter->setBrush(Colors::mid(c, CONF_COLOR(btn.active, Fg), 1,2)); } if (upDown) { rect.setBottom(rect.y() + rect.height()/2); rect.translate(0, -1); drawArrow(Navi::N, rect, painter); rect.translate(0, rect.height()); drawArrow(Navi::S, rect, painter); } else { if (dir == Navi::N) // loooks unbalanced otherwise rect.translate(0, -f1); drawArrow(dir, rect, painter); } painter->restore(); } }
void Style::drawSlider(const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const { ASSURE_OPTION(slider, Slider); SAVE_PAINTER(Pen|Brush|Alias); OPT_SUNKEN OPT_ENABLED OPT_HOVER OPT_FOCUS QRect groove = subControlRect(CC_Slider, slider, SC_SliderGroove, widget); QRect handle = subControlRect(CC_Slider, slider, SC_SliderHandle, widget); isEnabled = isEnabled && (slider->maximum > slider->minimum); hover = isEnabled && (appType == GTK || (hover && (slider->activeSubControls & SC_SliderHandle))); sunken = sunken && (slider->activeSubControls & SC_SliderHandle); int radius; // groove if ((slider->subControls & SC_SliderGroove) && groove.isValid()) { painter->setPen(Qt::NoPen); painter->setRenderHint(QPainter::Antialiasing, true); // thermometer if (slider->minimum > -1 && slider->sliderPosition != slider->minimum) { painter->setBrush(THERMOMETER_COLOR); QRect thermometer = groove; if (slider->orientation == Qt::Horizontal) thermometer.adjust(0, thermometer.height()/THERMOMETER_FACTOR, 0, -thermometer.height()/THERMOMETER_FACTOR); else thermometer.adjust(thermometer.width()/THERMOMETER_FACTOR, 0, -thermometer.width()/THERMOMETER_FACTOR, 0); radius = qMin(thermometer.width(), thermometer.height())/2; const QPoint c = handle.center(); if ( slider->orientation == Qt::Horizontal ) { bool ltr = slider->direction == Qt::LeftToRight; if (slider->upsideDown) ltr = !ltr; if (ltr) { groove.setLeft(c.x()); thermometer.setRight(c.x()); } else { groove.setRight(c.x()); thermometer.setLeft(handle.left()); } } else { if (slider->upsideDown) { groove.setBottom(c.y()); thermometer.setTop(c.y()); } else { groove.setTop(c.y()); thermometer.setBottom(handle.bottom()); } } painter->drawRoundedRect(thermometer, radius, radius); } if (slider->sliderPosition != slider->maximum || slider->minimum < 0 ) { radius = qMin(groove.width(), groove.height())/2; painter->setBrush(GROOVE_COLOR); painter->drawRoundedRect(groove, radius, radius); } painter->setRenderHint(QPainter::Antialiasing, false); } // tickmarks - we paint a centered dotline, no stupid above/below/both nonsense if (isEnabled && (slider->subControls & SC_SliderTickmarks) && slider->tickPosition != QSlider::NoTicks) { int interval = slider->tickInterval; if (interval < 1) interval = slider->pageStep; if (interval > 0) { QPen oldPen = painter->pen(); const qreal pw = F(1); QPen pen(FCOLOR(Window), pw); interval = (slider->maximum - slider->minimum) / interval; const int s = (slider->orientation == Qt::Horizontal) ? RECT.width() - handle.width() : RECT.height() - handle.height(); qreal space = s/(pw*interval) - 1.0f; pen.setDashPattern(QVector<qreal>() << 1.0f << space); space /= 2.0f; pen.setDashOffset(space - 0.5f + handle.width()*0.5f); painter->setPen(pen); QPoint c = groove.center(); if (slider->orientation == Qt::Horizontal) painter->drawLine(RECT.x() + space, c.y(), RECT.right() - space, c.y()); else painter->drawLine(c.x(), RECT.y() + space, c.x(), RECT.bottom() - space); painter->setPen(oldPen); } } // handle ====================================== if (isEnabled && (slider->subControls & SC_SliderHandle)) { int step = 0; if (sunken) step = 6; else if (isEnabled) { const Animator::ComplexInfo *info = Animator::HoverComplex::info(widget, slider->activeSubControls & SC_SliderHandle); if (info && ( info->fades[Animator::In] & SC_SliderHandle || info->fades[Animator::Out] & SC_SliderHandle )) step = info->step(SC_SliderHandle); if (hover && !step) step = 6; } drawSliderHandle(handle, option, painter, step); } RESTORE_PAINTER }
void Style::drawDial(const QStyleOptionComplex *option, QPainter *painter, const QWidget *) const { ASSURE_OPTION(dial, Slider); OPT_ENABLED OPT_HOVER OPT_FOCUS SAVE_PAINTER(Pen|Brush|Alias|Font); QRect rect = RECT; if (rect.width() > rect.height()) { rect.setLeft(rect.x()+(rect.width()-rect.height())/2); rect.setWidth(rect.height()); } else { rect.setTop(rect.y()+(rect.height()-rect.width())/2); rect.setHeight(rect.width()); } int d = qMin(2*rect.width()/5, config.slider.thickness); int r = (rect.width()-d)/2; // angle calculation from qcommonstyle.cpp (c) Trolltech 1992-2007, ASA. float a; if (dial->maximum == dial->minimum) a = M_PI / 2; else if (dial->dialWrapping) a = M_PI * 3 / 2 - (dial->sliderValue - dial->minimum) * 2 * M_PI / (dial->maximum - dial->minimum); else a = (M_PI * 8 - (dial->sliderValue - dial->minimum) * 10 * M_PI / (dial->maximum - dial->minimum)) / 6; QPoint cp = rect.center() + QPoint(qRound(r * cos(a)), -qRound(r * sin(a))); // the huge ring ======================================= r = d/2+1; rect.adjust(r,r,-r,-r); painter->setBrush(Qt::NoBrush); painter->setRenderHint( QPainter::Antialiasing ); const int start = -(dial->dialWrapping ? 90 : 120)*16; const int span = -16*(dial->dialWrapping ? 360 : 300)*(dial->sliderValue - dial->minimum)/(dial->maximum - dial->minimum); QPen pen; if (dial->sliderValue != dial->maximum) { QPen pen(GROOVE_COLOR, d); pen.setCapStyle(Qt::RoundCap); painter->setPen(pen); painter->drawArc(rect, start + span, -((dial->dialWrapping ? 360 : 300)*16 + span)); } if (dial->sliderValue != dial->minimum) { QPen pen(THERMOMETER_COLOR, d - 2*(d/THERMOMETER_FACTOR)); pen.setCapStyle(Qt::RoundCap); painter->setPen(pen); painter->drawArc(rect, start, span); } // the value ============================================== QFont fnt = painter->font(); int h = rect.height()/2; h -= 2 * (h - qMin(h, painter->fontMetrics().xHeight())) / 3; fnt.setPixelSize( h ); painter->setFont(fnt); painter->setPen(FX::blend(PAL.background().color(), PAL.foreground().color(),!hasFocus,2)); drawItemText(painter, rect, Qt::AlignCenter, PAL, isEnabled, QString::number(dial->sliderValue)); // the drop =========================== if (isEnabled) { rect = QRect(0,0,d,d); rect.moveCenter(cp); drawSliderHandle(rect, option, painter, hover * 6); } RESTORE_PAINTER }
void Style::drawComboBox(const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const { ASSURE_OPTION(cmb, ComboBox); OPT_ENABLED OPT_HOVER OPT_FOCUS SAVE_PAINTER(Pen|Brush|Alias); if ( widget && widget->inherits("WebView") ) { // paints hardcoded black text bypassing the style?! grrr... const_cast<QStyleOptionComboBox*>(cmb)->palette.setColor(QPalette::Window, QColor(230,230,230,255)); widget = 0; } animStep = !widget ? MAX_STEPS*hover : Animator::Hover::step(widget); QRect ar; const QComboBox *combo = widget ? qobject_cast<const QComboBox*>(widget) : NULL; if ((cmb->subControls & SC_ComboBoxArrow) && (!combo || combo->count() > 0)) { // do we have an arrow? ar = subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget); const int dx = (F(2) & ~1) / 2; ar.translate(cmb->direction == Qt::LeftToRight ? -dx : dx, 0); } const bool listShown = combo && combo->view() && ((QWidget*)(combo->view()))->isVisible(); if (listShown) { // this messes up hover hover = hover || QRect(widget->mapToGlobal(RECT.topLeft()), RECT.size()).contains(QCursor::pos()); // TODO Qt5, avoid asking for the cursor pos animStep = MAX_STEPS; } QColor c = hasFocus ? FCOLOR(Highlight) : (cmb->editable ? FCOLOR(Text) : FCOLOR(WindowText)); if (cmb->editable) { drawLineEditFrame(option, painter, widget); c = FX::blend(FCOLOR(Base), c, MAX_STEPS, 1 + 2*animStep); } else { const int icon = cmb->currentIcon.isNull() ? 0 : cmb->iconSize.width() + F(4); QFont fnt(painter->font()); fnt.setBold(true); int text = QFontMetrics(fnt).width(cmb->currentText); if (text) text += F(4); if (!(text+icon)) // webkit etc. text = ar.left() - (F(16) + RECT.x()); painter->setRenderHint(QPainter::Antialiasing, true); painter->setPen(QPen(hasFocus ? FCOLOR(Highlight) : FX::blend(FCOLOR(Window), c, 4, 1), FRAME_STROKE)); painter->setBrush(Qt::NoBrush); const int y = ar.y() + ar.height()/2; const int da = animStep * 168 / MAX_STEPS; if (option->direction == Qt::LeftToRight) { DRAW_SEGMENT(ar, 16*(120 - da/2), 16*(192+da)); painter->drawLine(RECT.x() + icon + text + F(6), y, ar.left()-F(2), y); } else { DRAW_SEGMENT(ar, 16*(30 + da/2), -16*(192+da)); painter->drawLine(RECT.right() - (icon + text + F(6)), y, ar.right()+F(2), y); } c = FX::blend(FCOLOR(Window), FCOLOR(WindowText), MAX_STEPS - animStep, 1 + animStep); } if (!isEnabled) { RESTORE_PAINTER return; }