📄 qwindowsvistastyle.cpp
字号:
} else { _running = false; } drawBlendedImage(painter, option->rect, alpha);}/*! \reimp * * Animations are used for some state transitions on specific widgets. * * Only one running animation can exist for a widget at any specific time. * Animations can be added through QWindowsVistaStylePrivate::startAnimation(Animation *) * and any existing animation on a widget can be retrieved with * QWindowsVistaStylePrivate::widgetAnimation(Widget *). * * Once an animation has been started, QWindowsVistaStylePrivate::timerEvent(QTimerEvent *) * will continuously call update() on the widget until it is stopped, meaning that drawPrimitive * will be called many times until the transition has completed. During this time, the result * will be retrieved by the Animation::paint(...) function and not by the style itself. * * To determine if a transition should occur, the style needs to know the previous state of the * widget as well as the current one. This is solved by updating dynamic properties on the widget * every time the function is called. * * Transitions interrupting existing transitions should always be smooth, so whenever a hover-transition * is started on a pulsating button, it uses the current frame of the pulse-animation as the * starting image for the hover transition. * */void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const{ QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func()); int state = option->state; if (!QWindowsVistaStylePrivate::useVista()) { QWindowsStyle::drawPrimitive(element, option, painter, widget); return; } QRect oldRect; QRect newRect; if (widget && d->transitionsEnabled()) { /* all widgets that supports state transitions : */ if ((qobject_cast<const QLineEdit*>(widget) && element == PE_FrameLineEdit) || (qobject_cast<const QRadioButton*>(widget)&& element == PE_IndicatorRadioButton) || (qobject_cast<const QCheckBox*>(widget) && element == PE_IndicatorCheckBox) || (qobject_cast<const QGroupBox *>(widget)&& element == PE_IndicatorCheckBox) || (qobject_cast<const QToolButton*>(widget) && element == PE_PanelButtonBevel) ) { // Retrieve and update the dynamic properties tracking // the previous state of the widget: QWidget *w = const_cast<QWidget *> (widget); int oldState = w->property("_q_stylestate").toInt(); oldRect = w->property("_q_stylerect").toRect(); newRect = w->rect(); w->setProperty("_q_stylestate", (int)option->state); w->setProperty("_q_stylerect", w->rect()); bool doTransition = ((state & State_Sunken) != (oldState & State_Sunken) || (state & State_On) != (oldState & State_On) || (state & State_MouseOver) != (oldState & State_MouseOver)); if (oldRect != newRect || (state & State_Enabled) != (oldState & State_Enabled) || (state & State_Active) != (oldState & State_Active)) d->stopAnimation(widget); if (const QLineEdit *edit = qobject_cast<const QLineEdit *>(widget)) if (edit->isReadOnly() && element == PE_FrameLineEdit) // Do not animate read only line edits doTransition = false; if (doTransition) { // We create separate images for the initial and final transition states and store them in the // Transition object. QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); QStyleOption opt = *option; opt.rect.setRect(0, 0, option->rect.width(), option->rect.height()); opt.state = (QStyle::State)oldState; startImage.fill(0); QPainter startPainter(&startImage); Animation *anim = d->widgetAnimation(widget); Transition *t = new Transition; t->setWidget(w); // If we have a running animation on the widget already, we will use that to paint the initial // state of the new transition, this ensures a smooth transition from a current animation such as a // pulsating default button into the intended target state. if (!anim) drawPrimitive(element, &opt, &startPainter, 0); // Note that the widget pointer is intentionally 0 else // this ensures that we do not recurse in the animation logic above anim->paint(&startPainter, &opt); d->startAnimation(t); t->setStartImage(startImage); // The end state of the transition is simply the result we would have painted // if the style was not animated. QPainter endPainter(&endImage); endImage.fill(0); QStyleOption opt2 = opt; opt2.state = option->state; drawPrimitive(element, &opt2, &endPainter, 0); // Note that the widget pointer is intentionally 0 // this ensures that we do not recurse in the animation logic above t->setEndImage(endImage); HTHEME theme; int partId; int duration; int fromState = 0; int toState = 0; //translate state flags to UXTHEME states : if (element == PE_FrameLineEdit) { theme = pOpenThemeData(0, L"Edit"); partId = EP_EDITBORDER_NOSCROLL; if (oldState & State_MouseOver) fromState = ETS_HOT; else if (oldState & State_HasFocus) fromState = ETS_FOCUSED; else fromState = ETS_NORMAL; if (state & State_MouseOver) toState = ETS_HOT; else if (state & State_HasFocus) toState = ETS_FOCUSED; else toState = ETS_NORMAL; } else { theme = pOpenThemeData(0, L"Button"); if (element == PE_IndicatorRadioButton) partId = BP_RADIOBUTTON; else if (element == PE_IndicatorCheckBox) partId = BP_CHECKBOX; else partId = BP_PUSHBUTTON; fromState = buttonStateId(oldState, partId); toState = buttonStateId(option->state, partId); } // Retrieve the transition time between the states from the system. if (theme && pGetThemeTransitionDuration(theme, partId, fromState, toState, TMT_TRANSITIONDURATIONS, &duration) == S_OK) { t->setDuration(duration); } t->setStartTime(QTime::currentTime()); } } } // End of animation part QRect rect = option->rect; switch (element) { case PE_IndicatorHeaderArrow: if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { int stateId = HSAS_SORTEDDOWN; if (header->sortIndicator & QStyleOptionHeader::SortDown) stateId = HSAS_SORTEDUP; //note that the uxtheme sort down indicator is the inverse of ours XPThemeData theme(widget, painter, QLatin1String("HEADER"), HP_HEADERSORTARROW, stateId, option->rect); d->drawBackground(theme); } break; case PE_IndicatorBranch: { //enable vista explorer style tree branches for tree views if (!qobject_cast<const QTreeView *>(widget)) { QWindowsXPStyle::drawPrimitive(element, option, painter, widget); return; } if (!d->treeViewHelper) { d->treeViewHelper = new QWidget(0); pSetWindowTheme(d->treeViewHelper ->winId(), L"explorer", NULL); } XPThemeData theme(d->treeViewHelper, painter, QLatin1String("TREEVIEW")); static const int decoration_size = 16; int mid_h = option->rect.x() + option->rect.width() / 2; int mid_v = option->rect.y() + option->rect.height() / 2; int bef_h = mid_h; int bef_v = mid_v; int aft_h = mid_h; int aft_v = mid_v; if (option->state & State_Children) { int delta = decoration_size / 2; theme.rect = QRect(bef_h - delta, bef_v - delta, decoration_size, decoration_size); theme.partId = option->state & State_MouseOver ? TVP_HOTGLYPH : TVP_GLYPH; theme.stateId = option->state & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED; d->drawBackground(theme); bef_h -= delta + 2; bef_v -= delta + 2; aft_h += delta - 2; aft_v += delta - 2; }#if 0 QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern); if (option->state & State_Item) { if (option->direction == Qt::RightToLeft) painter->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush); else painter->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush); } if (option->state & State_Sibling && option->rect.bottom() > aft_v) painter->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush); if (option->state & (State_Open | State_Children | State_Item | State_Sibling) && (bef_v > option->rect.y())) painter->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush);#endif } break; case PE_PanelButtonBevel: case PE_IndicatorCheckBox: case PE_IndicatorRadioButton: { if (Animation *a = d->widgetAnimation(widget)) { a->paint(painter, option); } else { QWindowsXPStyle::drawPrimitive(element, option, painter, widget); } } break; case PE_IndicatorToolBarHandle: { XPThemeData theme; if (option->state & State_Horizontal) theme = XPThemeData(widget, painter, QLatin1String("REBAR"), RP_GRIPPER, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2)); else theme = XPThemeData(widget, painter, QLatin1String("REBAR"), RP_GRIPPERVERT, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2)); d->drawBackground(theme); } break; case PE_FrameMenu: { int stateId = option->state & State_Active ? MB_ACTIVE : MB_INACTIVE; XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_POPUPBORDERS, stateId, option->rect); d->drawBackground(theme); } break; case PE_Frame: if (const QTextEdit *edit = qobject_cast<const QTextEdit*>(widget)) { int stateId = ETS_NORMAL; if (!(state & State_Enabled)) stateId = ETS_DISABLED; else if (edit->isReadOnly()) stateId = ETS_READONLY; else if (state & State_HasFocus) stateId = ETS_SELECTED; XPThemeData theme(widget, painter, QLatin1String("EDIT"), EP_EDITBORDER_HVSCROLL, stateId, option->rect); d->drawBackground(theme); } else QWindowsXPStyle::drawPrimitive(element, option, painter, widget); break; case PE_PanelLineEdit: if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) { QBrush bg; bool usePalette = false; bool isEnabled = option->state & State_Enabled; uint resolve_mask = panel->palette.resolve(); if (resolve_mask & (1 << QPalette::Base)) { // Base color is set for this widget, so use it bg = panel->palette.brush(QPalette::Base); usePalette = true; } if (usePalette) { painter->fillRect(panel->rect, bg); } else { int partId = EP_BACKGROUND;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -