702 qreal additionalDevicePixelRatio,
703 qreal correctionFactor)
705 QPainter *painter = themeData.painter;
706 QRectF rectF = scaleRect(QRectF(themeData.rect), additionalDevicePixelRatio);
708 if ((themeData.rotate + 90) % 180 == 0) {
709 rectF = QRectF(0, 0, rectF.height(), rectF.width());
713 const bool hasCorrectionFactor = !qFuzzyCompare(correctionFactor, qreal(1));
714 QRect rect = rectF.toRect();
715 QRect drawRect = hasCorrectionFactor
716 ? QRectF(rectF.topLeft() / correctionFactor, rectF.size() / correctionFactor).toRect() : rect;
719 int w = rect.width();
720 int h = rect.height();
724 bool stateHasData =
true;
725 bool hasAlpha =
false;
726 bool partIsTransparent;
727 bool potentialInvalidAlpha;
729 QString pixmapCacheKey = QStringLiteral(
"$qt_xp_");
730 pixmapCacheKey.append(themeName(themeData.theme));
731 pixmapCacheKey.append(QLatin1Char(
'p'));
732 pixmapCacheKey.append(QString::number(partId));
733 pixmapCacheKey.append(QLatin1Char(
's'));
734 pixmapCacheKey.append(QString::number(stateId));
735 pixmapCacheKey.append(QLatin1Char(
's'));
736 pixmapCacheKey.append(themeData.noBorder ? QLatin1Char(
'0') : QLatin1Char(
'1'));
737 pixmapCacheKey.append(QLatin1Char(
'b'));
738 pixmapCacheKey.append(themeData.noContent ? QLatin1Char(
'0') : QLatin1Char(
'1'));
739 pixmapCacheKey.append(QString::number(w));
740 pixmapCacheKey.append(QLatin1Char(
'w'));
741 pixmapCacheKey.append(QString::number(h));
742 pixmapCacheKey.append(QLatin1Char(
'h'));
743 pixmapCacheKey.append(QString::number(additionalDevicePixelRatio));
744 pixmapCacheKey.append(QLatin1Char(
'd'));
745 if (hasCorrectionFactor) {
746 pixmapCacheKey.append(QLatin1Char(
'c'));
747 pixmapCacheKey.append(QString::number(correctionFactor));
750 QPixmap cachedPixmap;
754 bool haveCachedPixmap =
false;
762 haveCachedPixmap = QPixmapCache::find(pixmapCacheKey, &cachedPixmap);
766 ::snprintf(buf,
sizeof(buf),
"+ Pixmap(%3d, %3d) ]", w, h);
767 printf(
"---[ CACHED %s--------> Name(%-10s) Part(%d) State(%d)\n",
768 haveCachedPixmap ? buf :
"]-------------------",
769 qPrintable(themeData.name), themeData.partId, themeData.stateId);
773 BOOL tmt_borderonly =
false;
774 COLORREF tmt_transparentcolor = 0x0;
775 PROPERTYORIGIN proporigin = PO_NOTFOUND;
776 GetThemeBool(themeData.handle(), themeData
.partId, themeData
.stateId, TMT_BORDERONLY, &tmt_borderonly);
777 GetThemeColor(themeData.handle(), themeData
.partId, themeData
.stateId, TMT_TRANSPARENTCOLOR, &tmt_transparentcolor);
778 GetThemePropertyOrigin(themeData.handle(), themeData
.partId, themeData
.stateId, TMT_CAPTIONMARGINS, &proporigin);
782 potentialInvalidAlpha =
false;
783 GetThemePropertyOrigin(themeData.handle(), themeData
.partId, themeData
.stateId, TMT_GLYPHTYPE, &proporigin);
784 if (proporigin == PO_PART || proporigin == PO_STATE) {
785 int tmt_glyphtype = GT_NONE;
786 GetThemeEnumValue(themeData.handle(), themeData
.partId, themeData
.stateId, TMT_GLYPHTYPE, &tmt_glyphtype);
787 potentialInvalidAlpha = partIsTransparent && tmt_glyphtype == GT_IMAGEGLYPH;
791 printf(
"---[ NOT CACHED ]-----------------------> Name(%-10s) Part(%d) State(%d)\n",
792 qPrintable(themeData.name), themeData.partId, themeData.stateId);
793 printf(
"-->partIsTransparen = %d\n", partIsTransparent);
794 printf(
"-->potentialInvalidAlpha = %d\n", potentialInvalidAlpha);
795 showProperties(themeData);
798 bool wasAlphaSwapped =
false;
799 bool wasAlphaFixed =
false;
805 bool addBorderContentClipping =
false;
807 QRect area = drawRect;
808 if (themeData.noBorder || themeData.noContent) {
815 PROPERTYORIGIN origin = PO_NOTFOUND;
816 GetThemePropertyOrigin(themeData.handle(), themeData
.partId, themeData
.stateId, TMT_BORDERSIZE, &origin);
817 GetThemeInt(themeData.handle(), themeData
.partId, themeData
.stateId, TMT_BORDERSIZE, &borderSize);
818 borderSize *= additionalDevicePixelRatio;
821 if ((origin == PO_CLASS || origin == PO_PART || origin == PO_STATE) && borderSize > 0) {
822 if (themeData.noBorder) {
824 area = area.adjusted(-borderSize, -borderSize, borderSize, borderSize);
828 if (themeData.noContent) {
829 QRegion content = area.adjusted(borderSize, borderSize, -borderSize, -borderSize);
830 extraClip ^= content;
833 addBorderContentClipping = (themeData.noBorder | themeData.noContent);
837 if (!haveCachedPixmap) {
838 if (!buffer(drawRect.width(), drawRect.height()))
840 HDC dc = bufferHDC();
845 memset(bufferPixels, 0x00, bufferW * drawRect.height() * 4);
849 int dx = area.x() - drawRect.x();
850 int dy = area.y() - drawRect.y();
855 DTBGOPTS drawOptions;
856 drawOptions.dwSize =
sizeof(drawOptions);
857 drawOptions.rcClip = themeData.toRECT(rect);
858 drawOptions.dwFlags = DTBG_CLIPRECT
859 | (themeData.noBorder ? DTBG_OMITBORDER : 0)
860 | (themeData.noContent ? DTBG_OMITCONTENT : 0);
863 RECT wRect(themeData.toRECT(area));
864 DrawThemeBackgroundEx(themeData.handle(), dc, themeData
.partId, themeData
.stateId, &wRect, &drawOptions);
871 memset(
static_cast<
void *>(&data), 0,
sizeof(data));
873 alphaCache.insert(key, data);
876 hasAlpha = hasAlphaChannel(rect);
877 if (!hasAlpha && partIsTransparent)
878 potentialInvalidAlpha =
true;
879#if defined(DEBUG_XP_STYLE) && 1
880 dumpNativeDIB(drawRect.width(), drawRect.height());
885 if (potentialInvalidAlpha)
886 wasAlphaFixed = fixAlphaChannel(drawRect);
888 QImage::Format format;
889 if ((partIsTransparent && !wasAlphaSwapped) || (!partIsTransparent && hasAlpha)) {
890 format = QImage::Format_ARGB32_Premultiplied;
892 }
else if (wasAlphaSwapped) {
893 format = QImage::Format_ARGB32_Premultiplied;
896 format = QImage::Format_RGB32;
901 swapAlphaChannel(rect,
true);
904#if defined(DEBUG_XP_STYLE) && 1
905 printf(
"Image format is: %s\n", alphaType == RealAlpha ?
"Real Alpha" : alphaType == MaskAlpha ?
"Masked Alpha" :
"No Alpha");
907 img = QImage(bufferPixels, bufferW, bufferH, format);
908 if (hasCorrectionFactor)
909 img = img.scaled(w, h, Qt::KeepAspectRatio, Qt::SmoothTransformation);
910 img.setDevicePixelRatio(additionalDevicePixelRatio);
914 bool useRegion = partIsTransparent && !hasAlpha && !wasAlphaSwapped;
919 newRegion = region(themeData);
920 oldRegion = painter->clipRegion();
921 painter->setClipRegion(newRegion);
922#if defined(DEBUG_XP_STYLE) && 0
923 printf(
"Using region:\n");
924 for (
const QRect &r : newRegion)
925 printf(
" (%d, %d, %d, %d)\n", r.x(), r.y(), r.right(), r.bottom());
929 if (addBorderContentClipping)
930 painter->setClipRegion(scaleRegion(extraClip, 1.0 / additionalDevicePixelRatio), Qt::IntersectClip);
932 if (!themeData.mirrorHorizontally && !themeData.mirrorVertically && !themeData.rotate) {
933 if (!haveCachedPixmap)
934 painter->drawImage(themeData.rect, img, rect);
936 painter->drawPixmap(themeData.rect, cachedPixmap);
944 if (!haveCachedPixmap)
945 imgCopy = img.copy(rect);
947 imgCopy = cachedPixmap.toImage();
949 if (themeData.rotate) {
950 QTransform rotMatrix;
951 rotMatrix.rotate(themeData.rotate);
952 imgCopy = imgCopy.transformed(rotMatrix);
954 static constexpr Qt::Orientation none = Qt::Orientation(0);
955 const auto orientation = (themeData.mirrorHorizontally ? Qt::Horizontal : none)
956 | (themeData.mirrorVertically ? Qt::Vertical : none);
958 imgCopy.flip(orientation);
959 painter->drawImage(themeData.rect, imgCopy);
962 if (useRegion || addBorderContentClipping) {
963 if (oldRegion.isEmpty())
964 painter->setClipping(
false);
966 painter->setClipRegion(oldRegion);
970 if (!haveCachedPixmap && w && h) {
971 QPixmap pix = QPixmap::fromImage(img).copy(rect);
972 QPixmapCache::insert(pixmapCacheKey, pix);
974 printf(
"+++Adding pixmap to cache, size(%d, %d), wasAlphaSwapped(%d), wasAlphaFixed(%d), name(%s)\n",
975 w, h, wasAlphaSwapped, wasAlphaFixed, qPrintable(pixmapCacheKey));
981 memset(
static_cast<
void *>(&data), 0,
sizeof(data));
988 alphaCache.insert(key, data);
1131 QWindowsStyle::drawPrimitive(pe, option, p);
1135 int themeNumber = -1;
1138 QRect rect = option->rect;
1139 State flags = option->state;
1140 bool hMirrored =
false;
1141 bool vMirrored =
false;
1142 bool noBorder =
false;
1143 bool noContent =
false;
1148 case PE_FrameTabBarBase:
1149 if (
const QStyleOptionTabBarBase *tbb
1150 = qstyleoption_cast<
const QStyleOptionTabBarBase *>(option)) {
1152 switch (tbb->shape) {
1153 case QTabBar::RoundedNorth:
1154 p->setPen(QPen(tbb->palette.dark(), 0));
1155 p->drawLine(tbb->rect.topLeft(), tbb->rect.topRight());
1157 case QTabBar::RoundedWest:
1158 p->setPen(QPen(tbb->palette.dark(), 0));
1159 p->drawLine(tbb->rect.left(), tbb->rect.top(), tbb->rect.left(), tbb->rect.bottom());
1161 case QTabBar::RoundedSouth:
1162 p->setPen(QPen(tbb->palette.dark(), 0));
1163 p->drawLine(tbb->rect.left(), tbb->rect.top(),
1164 tbb->rect.right(), tbb->rect.top());
1166 case QTabBar::RoundedEast:
1167 p->setPen(QPen(tbb->palette.dark(), 0));
1168 p->drawLine(tbb->rect.topLeft(), tbb->rect.bottomLeft());
1170 case QTabBar::TriangularNorth:
1171 case QTabBar::TriangularEast:
1172 case QTabBar::TriangularWest:
1173 case QTabBar::TriangularSouth:
1175 QWindowsStyle::drawPrimitive(pe, option, p);
1182 case PE_PanelButtonBevel:
1183 themeNumber = QWindowsXPStylePrivate::ButtonTheme;
1184 partId = BP_PUSHBUTTON;
1185 if (!(flags & State_Enabled))
1186 stateId = PBS_DISABLED;
1187 else if ((flags & State_Sunken) || (flags & State_On))
1188 stateId = PBS_PRESSED;
1189 else if (flags & State_MouseOver)
1194 stateId = PBS_NORMAL;
1197 case PE_PanelButtonTool:
1203 themeNumber = QWindowsXPStylePrivate::ToolBarTheme;
1205 if (!(flags & State_Enabled))
1206 stateId = TS_DISABLED;
1207 else if (flags & State_Sunken)
1208 stateId = TS_PRESSED;
1209 else if (flags & State_MouseOver)
1210 stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT;
1211 else if (flags & State_On)
1212 stateId = TS_CHECKED;
1213 else if (!(flags & State_AutoRaise))
1216 stateId = TS_NORMAL;
1219 case PE_IndicatorButtonDropDown:
1220 themeNumber = QWindowsXPStylePrivate::ToolBarTheme;
1221 partId = TP_SPLITBUTTONDROPDOWN;
1222 if (!(flags & State_Enabled))
1223 stateId = TS_DISABLED;
1224 else if (flags & State_Sunken)
1225 stateId = TS_PRESSED;
1226 else if (flags & State_MouseOver)
1227 stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT;
1228 else if (flags & State_On)
1229 stateId = TS_CHECKED;
1230 else if (!(flags & State_AutoRaise))
1233 stateId = TS_NORMAL;
1234 if (option->direction == Qt::RightToLeft)
1238 case PE_IndicatorCheckBox:
1239 themeNumber = QWindowsXPStylePrivate::ButtonTheme;
1240 partId = BP_CHECKBOX;
1241 if (!(flags & State_Enabled))
1242 stateId = CBS_UNCHECKEDDISABLED;
1243 else if (flags & State_Sunken)
1244 stateId = CBS_UNCHECKEDPRESSED;
1245 else if (flags & State_MouseOver)
1246 stateId = CBS_UNCHECKEDHOT;
1248 stateId = CBS_UNCHECKEDNORMAL;
1250 if (flags & State_On)
1251 stateId += CBS_CHECKEDNORMAL-1;
1252 else if (flags & State_NoChange)
1253 stateId += CBS_MIXEDNORMAL-1;
1257 case PE_IndicatorRadioButton:
1258 themeNumber = QWindowsXPStylePrivate::ButtonTheme;
1259 partId = BP_RADIOBUTTON;
1260 if (!(flags & State_Enabled))
1261 stateId = RBS_UNCHECKEDDISABLED;
1262 else if (flags & State_Sunken)
1263 stateId = RBS_UNCHECKEDPRESSED;
1264 else if (flags & State_MouseOver)
1265 stateId = RBS_UNCHECKEDHOT;
1267 stateId = RBS_UNCHECKEDNORMAL;
1269 if (flags & State_On)
1270 stateId += RBS_CHECKEDNORMAL-1;
1273 case PE_IndicatorDockWidgetResizeHandle:
1278 if (flags & State_Raised)
1280 themeNumber = QWindowsXPStylePrivate::ListViewTheme;
1281 partId = LVP_LISTGROUP;
1282 XPThemeData theme(option->window,
nullptr, themeNumber, partId);
1284 if (!(flags & State_Enabled))
1285 stateId = ETS_DISABLED;
1287 stateId = ETS_NORMAL;
1289 if (GetThemeEnumValue(theme.handle(), partId, stateId, TMT_BGTYPE, &fillType) == S_OK) {
1290 if (fillType == BT_BORDERFILL) {
1292 GetThemeColor(theme.handle(), partId, stateId, TMT_BORDERCOLOR, &bcRef);
1293 QColor bordercolor(qRgb(GetRValue(bcRef), GetGValue(bcRef), GetBValue(bcRef)));
1294 QPen oldPen = p->pen();
1299 p->setPen(QPen(option->palette.base().color(), 0));
1300 const qreal dpi = QStyleHelper::dpi(option);
1301 const auto topLevelAdjustment = QStyleHelper::dpiScaled(0.5, dpi);
1302 const auto bottomRightAdjustment = QStyleHelper::dpiScaled(-1, dpi);
1303 p->drawRect(QRectF(option->rect).adjusted(topLevelAdjustment, topLevelAdjustment,
1304 bottomRightAdjustment, bottomRightAdjustment));
1306 p->setPen(QPen(bordercolor, 0));
1307 p->drawRect(QRectF(option->rect).adjusted(0, 0, -topLevelAdjustment, -topLevelAdjustment));
1311 if (fillType == BT_NONE)
1316 case PE_FrameLineEdit: {
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331 if (qstyleoption_cast<
const QStyleOptionFrame *>(option)) {
1332 themeNumber = QWindowsXPStylePrivate::EditTheme;
1333 partId = EP_EDITTEXT;
1335 if (!(flags & State_Enabled))
1336 stateId = ETS_DISABLED;
1338 stateId = ETS_NORMAL;
1343 case PE_PanelLineEdit:
1344 if (
const QStyleOptionFrame *panel = qstyleoption_cast<
const QStyleOptionFrame *>(option)) {
1345 themeNumber = QWindowsXPStylePrivate::EditTheme;
1346 partId = EP_EDITTEXT;
1348 bool isEnabled = flags & State_Enabled;
1350 stateId = isEnabled ? ETS_NORMAL : ETS_DISABLED;
1353
1354{
1355 XPThemeData theme(
nullptr, p, themeNumber, partId, stateId, rect);
1357 QWindowsStyle::drawPrimitive(pe, option, p);
1361 GetThemeEnumValue(theme.handle(), partId, stateId, TMT_BGTYPE, &bgType);
1362 if ( bgType == BT_IMAGEFILE ) {
1363 theme.mirrorHorizontally = hMirrored;
1364 theme.mirrorVertically = vMirrored;
1365 theme.noBorder = noBorder;
1366 theme.noContent = noContent;
1367 theme.rotate = rotate;
1368 d->drawBackground(theme);
1370 QBrush fillColor = option->palette.brush(QPalette::Base);
1373 PROPERTYORIGIN origin = PO_NOTFOUND;
1374 GetThemePropertyOrigin(theme.handle(), theme
.partId, theme
.stateId, TMT_FILLCOLOR, &origin);
1376 if ((origin == PO_PART || origin == PO_STATE)) {
1378 GetThemeColor(theme.handle(), partId, stateId, TMT_FILLCOLOR, &bgRef);
1379 fillColor = QBrush(qRgb(GetRValue(bgRef), GetGValue(bgRef), GetBValue(bgRef)));
1382 p->fillRect(option->rect, fillColor);
1386 if (panel->lineWidth > 0)
1387 proxy()->drawPrimitive(PE_FrameLineEdit, panel, p);
1392 case PE_FrameTabWidget:
1393 if (
const QStyleOptionTabWidgetFrame *tab = qstyleoption_cast<
const QStyleOptionTabWidgetFrame *>(option))
1395 themeNumber = QWindowsXPStylePrivate::TabTheme;
1398 if (option->window) {
1399 bool useGradient =
true;
1400 const int maxlength = 256;
1401 wchar_t themeFileName[maxlength];
1402 wchar_t themeColor[maxlength];
1404 if (GetCurrentThemeName(themeFileName, maxlength, themeColor, maxlength,
nullptr, 0) == S_OK) {
1405 wchar_t *offset =
nullptr;
1406 if ((offset = wcsrchr(themeFileName, QChar(QLatin1Char(
'\\')).unicode())) !=
nullptr) {
1408 if (!lstrcmp(offset, L"Luna.msstyles") && !lstrcmp(offset, L"Metallic")) {
1409 useGradient =
false;
1416 QStyleOptionTabWidgetFrame frameOpt = *tab;
1419 QRect contentsRect = subElementRect(SE_TabWidgetTabContents, &frameOpt);
1420 QRegion reg = option->rect;
1421 reg -= contentsRect;
1422 p->setClipRegion(reg);
1423 XPThemeData theme(option->window, p, themeNumber, partId, stateId, rect);
1424 theme.mirrorHorizontally = hMirrored;
1425 theme.mirrorVertically = vMirrored;
1426 d->drawBackground(theme);
1427 p->setClipRect(contentsRect);
1431 switch (tab->shape) {
1432 case QTabBar::RoundedNorth:
1433 case QTabBar::TriangularNorth:
1435 case QTabBar::RoundedSouth:
1436 case QTabBar::TriangularSouth:
1439 case QTabBar::RoundedEast:
1440 case QTabBar::TriangularEast:
1443 case QTabBar::RoundedWest:
1444 case QTabBar::TriangularWest:
1456 p->setPen(option->palette.dark().color());
1457 p->drawRect(rect.adjusted(0, 0, -1, -1));
1461 case PE_PanelMenuBar:
1464 case PE_FrameDockWidget:
1465 if (
const QStyleOptionFrame *frm = qstyleoption_cast<
const QStyleOptionFrame *>(option))
1467 themeNumber = QWindowsXPStylePrivate::WindowTheme;
1468 if (flags & State_Active)
1469 stateId = FS_ACTIVE;
1471 stateId = FS_INACTIVE;
1473 int fwidth = proxy()->pixelMetric(PM_DockWidgetFrameWidth, frm);
1475 XPThemeData theme(option->window, p, themeNumber, 0, stateId);
1478 theme.rect = QRect(frm->rect.x(), frm->rect.y(), frm->rect.x()+fwidth, frm->rect.height()-fwidth); theme.partId = WP_SMALLFRAMELEFT;
1479 d->drawBackground(theme);
1480 theme.rect = QRect(frm->rect.width()-fwidth, frm->rect.y(), fwidth, frm->rect.height()-fwidth);
1481 theme.partId = WP_SMALLFRAMERIGHT;
1482 d->drawBackground(theme);
1483 theme.rect = QRect(frm->rect.x(), frm->rect.bottom()-fwidth+1, frm->rect.width(), fwidth);
1484 theme.partId = WP_SMALLFRAMEBOTTOM;
1485 d->drawBackground(theme);
1490 case PE_IndicatorHeaderArrow:
1493 name = QWindowsXPStylePrivate::HeaderTheme;
1494 partId = HP_HEADERSORTARROW;
1495 if (flags & State_Down)
1496 stateId = HSAS_SORTEDDOWN;
1498 stateId = HSAS_SORTEDUP;
1500 if (
const QStyleOptionHeader *header = qstyleoption_cast<
const QStyleOptionHeader *>(option)) {
1502 p->setPen(option->palette.dark().color());
1503 p->translate(0, option->rect.height()/2 - 4);
1504 if (header->sortIndicator & QStyleOptionHeader::SortUp) {
1505 p->drawLine(option->rect.x(), option->rect.y(), option->rect.x()+8, option->rect.y());
1506 p->drawLine(option->rect.x()+1, option->rect.y()+1, option->rect.x()+7, option->rect.y()+1);
1507 p->drawLine(option->rect.x()+2, option->rect.y()+2, option->rect.x()+6, option->rect.y()+2);
1508 p->drawLine(option->rect.x()+3, option->rect.y()+3, option->rect.x()+5, option->rect.y()+3);
1509 p->drawPoint(option->rect.x()+4, option->rect.y()+4);
1510 }
else if (header->sortIndicator & QStyleOptionHeader::SortDown) {
1511 p->drawLine(option->rect.x(), option->rect.y()+4, option->rect.x()+8, option->rect.y()+4);
1512 p->drawLine(option->rect.x()+1, option->rect.y()+3, option->rect.x()+7, option->rect.y()+3);
1513 p->drawLine(option->rect.x()+2, option->rect.y()+2, option->rect.x()+6, option->rect.y()+2);
1514 p->drawLine(option->rect.x()+3, option->rect.y()+1, option->rect.x()+5, option->rect.y()+1);
1515 p->drawPoint(option->rect.x()+4, option->rect.y());
1524 case PE_FrameStatusBarItem:
1525 themeNumber = QWindowsXPStylePrivate::StatusTheme;
1529 case PE_FrameGroupBox:
1530 themeNumber = QWindowsXPStylePrivate::ButtonTheme;
1531 partId = BP_GROUPBOX;
1532 if (!(flags & State_Enabled))
1533 stateId = GBS_DISABLED;
1535 stateId = GBS_NORMAL;
1536 if (
const QStyleOptionFrame *frame = qstyleoption_cast<
const QStyleOptionFrame *>(option)) {
1537 if (frame->features & QStyleOptionFrame::Flat) {
1539 QRect fr = frame->rect;
1540 QPoint p1(fr.x(), fr.y() + 1);
1541 QPoint p2(fr.x() + fr.width(), p1.y() + 1);
1542 rect = QRect(p1, p2);
1548 case PE_IndicatorProgressChunk:
1550 Qt::Orientation orient = Qt::Horizontal;
1551 bool inverted =
false;
1552 if (
const QStyleOptionProgressBar *pb = qstyleoption_cast<
const QStyleOptionProgressBar *>(option)) {
1553 orient = pb->state & QStyle::State_Horizontal ? Qt::Horizontal : Qt::Vertical;
1554 inverted = pb->invertedAppearance;
1556 if (orient == Qt::Horizontal) {
1558 rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.height() );
1559 if (inverted && option->direction == Qt::LeftToRight)
1562 partId = PP_CHUNKVERT;
1563 rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.height());
1565 themeNumber = QWindowsXPStylePrivate::ProgressTheme;
1570 case PE_FrameWindow:
1571 if (
const QStyleOptionFrame *frm = qstyleoption_cast<
const QStyleOptionFrame *>(option))
1573 themeNumber = QWindowsXPStylePrivate::WindowTheme;
1574 if (flags & State_Active)
1575 stateId = FS_ACTIVE;
1577 stateId = FS_INACTIVE;
1579 int fwidth =
int((frm->lineWidth + frm->midLineWidth) / QWindowsStylePrivate::nativeMetricScaleFactor(option));
1581 XPThemeData theme(option->window, p, themeNumber, 0, stateId);
1586 theme.rect = QRect(option->rect.x(), option->rect.y()+fwidth, option->rect.x()+fwidth, option->rect.height()-fwidth);
1587 theme.partId = WP_FRAMELEFT;
1588 if (!d->drawBackground(theme)) {
1589 QWindowsStyle::drawPrimitive(pe, option, p);
1592 theme.rect = QRect(option->rect.width()-fwidth, option->rect.y()+fwidth, fwidth, option->rect.height()-fwidth);
1593 theme.partId = WP_FRAMERIGHT;
1594 if (!d->drawBackground(theme)) {
1595 QWindowsStyle::drawPrimitive(pe, option, p);
1598 theme.rect = QRect(option->rect.x(), option->rect.height()-fwidth, option->rect.width(), fwidth);
1599 theme.partId = WP_FRAMEBOTTOM;
1600 if (!d->drawBackground(theme)) {
1601 QWindowsStyle::drawPrimitive(pe, option, p);
1604 theme.rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.y()+fwidth);
1605 theme.partId = WP_CAPTION;
1606 if (!d->drawBackground(theme))
1607 QWindowsStyle::drawPrimitive(pe, option, p);
1612 case PE_IndicatorBranch:
1614 static const int decoration_size = 9;
1615 int mid_h = option->rect.x() + option->rect.width() / 2;
1616 int mid_v = option->rect.y() + option->rect.height() / 2;
1621 QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern);
1622 if (option->state & State_Item) {
1623 if (option->direction == Qt::RightToLeft)
1624 p->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush);
1626 p->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush);
1628 if (option->state & State_Sibling)
1629 p->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush);
1630 if (option->state & (State_Open | State_Children | State_Item | State_Sibling))
1631 p->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush);
1632 if (option->state & State_Children) {
1633 int delta = decoration_size / 2;
1638 XPThemeData theme(
nullptr, p, QWindowsXPStylePrivate::XpTreeViewTheme);
1639 theme.rect = QRect(bef_h, bef_v, decoration_size, decoration_size);
1640 theme.partId = TVP_GLYPH;
1641 theme.stateId = flags & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED;
1642 d->drawBackground(theme);
1647 case PE_IndicatorToolBarSeparator:
1648 if (option->rect.height() < 3) {
1651 QWindowsStyle::drawPrimitive(pe, option, p);
1654 themeNumber = QWindowsXPStylePrivate::ToolBarTheme;
1655 partId = TP_SEPARATOR;
1657 if (option->state & State_Horizontal)
1658 partId = TP_SEPARATOR;
1660 partId = TP_SEPARATORVERT;
1664 case PE_IndicatorToolBarHandle:
1666 themeNumber = QWindowsXPStylePrivate::RebarTheme;
1667 partId = RP_GRIPPER;
1668 if (option->state & State_Horizontal) {
1669 partId = RP_GRIPPER;
1670 rect.adjust(0, 0, -2, 0);
1673 partId = RP_GRIPPERVERT;
1674 rect.adjust(0, 0, 0, -2);
1678 case PE_IndicatorItemViewItemCheck: {
1679 QStyleOptionButton button;
1680 button.QStyleOption::operator=(*option);
1681 button.state &= ~State_MouseOver;
1682 proxy()->drawPrimitive(PE_IndicatorCheckBox, &button, p);
1690 XPThemeData theme(option->window, p, themeNumber, partId, stateId, rect);
1692 QWindowsStyle::drawPrimitive(pe, option, p);
1695 theme.mirrorHorizontally = hMirrored;
1696 theme.mirrorVertically = vMirrored;
1697 theme.noBorder = noBorder;
1698 theme.noContent = noContent;
1699 theme.rotate = rotate;
1700 d->drawBackground(theme);
1711 QWindowsStyle::drawControl(element, option, p);
1715 QRect rect(option->rect);
1716 State flags = option->state;
1719 bool hMirrored =
false;
1720 bool vMirrored =
false;
1722 int themeNumber = -1;
1728 themeNumber = QWindowsXPStylePrivate::StatusTheme;
1729 partId = SP_GRIPPER;
1730 XPThemeData theme(
nullptr, p, themeNumber, partId);
1731 QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(option)).toSize();
1733 if (
const QStyleOptionSizeGrip *sg = qstyleoption_cast<
const QStyleOptionSizeGrip *>(option)) {
1734 switch (sg->corner) {
1735 case Qt::BottomRightCorner:
1736 rect = QRect(QPoint(rect.right() - size.width(), rect.bottom() - size.height()), size);
1738 case Qt::BottomLeftCorner:
1739 rect = QRect(QPoint(rect.left() + 1, rect.bottom() - size.height()), size);
1742 case Qt::TopRightCorner:
1743 rect = QRect(QPoint(rect.right() - size.width(), rect.top() + 1), size);
1746 case Qt::TopLeftCorner:
1747 rect = QRect(rect.topLeft() + QPoint(1, 1), size);
1748 hMirrored = vMirrored =
true;
1754 case CE_HeaderSection:
1755 themeNumber = QWindowsXPStylePrivate::HeaderTheme;
1756 partId = HP_HEADERITEM;
1757 if (flags & State_Sunken)
1758 stateId = HIS_PRESSED;
1759 else if (flags & State_MouseOver)
1762 stateId = HIS_NORMAL;
1766 p->eraseRect(option->rect);
1769 case CE_PushButtonBevel:
1770 if (
const QStyleOptionButton *btn = qstyleoption_cast<
const QStyleOptionButton *>(option))
1772 themeNumber = QWindowsXPStylePrivate::ButtonTheme;
1773 partId = BP_PUSHBUTTON;
1774 bool justFlat = ((btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken)))
1775 || ((btn->features & QStyleOptionButton::CommandLinkButton)
1776 && !(flags & State_MouseOver)
1777 && !(btn->features & QStyleOptionButton::DefaultButton));
1778 if (!(flags & State_Enabled) && !(btn->features & QStyleOptionButton::Flat))
1779 stateId = PBS_DISABLED;
1782 else if (flags & (State_Sunken | State_On))
1783 stateId = PBS_PRESSED;
1784 else if (flags & State_MouseOver)
1786 else if (btn->features & QStyleOptionButton::DefaultButton)
1787 stateId = PBS_DEFAULTED;
1789 stateId = PBS_NORMAL;
1792 XPThemeData theme(option->window, p, themeNumber, partId, stateId, rect);
1793 d->drawBackground(theme);
1796 if (btn->features & QStyleOptionButton::HasMenu) {
1797 int mbiw = 0, mbih = 0;
1799 QWindowsXPStylePrivate::ToolBarTheme,
1800 TP_SPLITBUTTONDROPDOWN);
1802 const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(option)).toSize();
1803 mbiw = size.width();
1804 mbih = size.height();
1807 QRect ir = btn->rect;
1808 QStyleOptionButton newBtn = *btn;
1809 newBtn.rect = QRect(ir.right() - mbiw - 1, 1 + (ir.height()/2) - (mbih/2), mbiw, mbih);
1810 proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p);
1816 if (
const QStyleOptionTab *tab = qstyleoption_cast<
const QStyleOptionTab *>(option))
1818 stateId = tab->state & State_Enabled ? TIS_NORMAL : TIS_DISABLED;
1822 case CE_TabBarTabShape:
1823 if (
const QStyleOptionTab *tab = qstyleoption_cast<
const QStyleOptionTab *>(option))
1825 themeNumber = QWindowsXPStylePrivate::TabTheme;
1826 bool isDisabled = !(tab->state & State_Enabled);
1827 bool hasFocus = tab->state & State_HasFocus;
1828 bool isHot = tab->state & State_MouseOver;
1829 bool selected = tab->state & State_Selected;
1830 bool lastTab = tab->position == QStyleOptionTab::End;
1831 bool firstTab = tab->position == QStyleOptionTab::Beginning;
1832 bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
1833 bool leftAligned = proxy()->styleHint(SH_TabBar_Alignment, tab) == Qt::AlignLeft;
1834 bool centerAligned = proxy()->styleHint(SH_TabBar_Alignment, tab) == Qt::AlignCenter;
1835 int borderThickness = proxy()->pixelMetric(PM_DefaultFrameWidth, option);
1836 int tabOverlap = proxy()->pixelMetric(PM_TabBarTabOverlap, option);
1839 stateId = TIS_DISABLED;
1841 stateId = TIS_SELECTED;
1843 stateId = TIS_FOCUSED;
1847 stateId = TIS_NORMAL;
1850 if (firstTab || onlyOne) {
1852 partId = TABP_TABITEMLEFTEDGE;
1853 }
else if (centerAligned) {
1854 partId = TABP_TABITEM;
1856 partId = TABP_TABITEMRIGHTEDGE;
1859 partId = TABP_TABITEM;
1862 if (tab->direction == Qt::RightToLeft
1863 && (tab->shape == QTabBar::RoundedNorth
1864 || tab->shape == QTabBar::RoundedSouth)) {
1865 bool temp = firstTab;
1869 bool begin = firstTab || onlyOne;
1870 bool end = lastTab || onlyOne;
1871 switch (tab->shape) {
1872 case QTabBar::RoundedNorth:
1874 rect.adjust(begin ? 0 : -tabOverlap, 0, end ? 0 : tabOverlap, borderThickness);
1876 rect.adjust(begin? tabOverlap : 0, tabOverlap, end ? -tabOverlap : 0, 0);
1878 case QTabBar::RoundedSouth:
1882 rect.adjust(begin ? 0 : -tabOverlap , -borderThickness, end ? 0 : tabOverlap, 0);
1884 rect.adjust(begin ? tabOverlap : 0, 0, end ? -tabOverlap : 0 , -tabOverlap);
1886 case QTabBar::RoundedEast:
1889 rect.adjust(-borderThickness, begin ? 0 : -tabOverlap, 0, end ? 0 : tabOverlap);
1891 rect.adjust(0, begin ? tabOverlap : 0, -tabOverlap, end ? -tabOverlap : 0);
1894 case QTabBar::RoundedWest:
1898 rect.adjust(0, begin ? 0 : -tabOverlap, borderThickness, end ? 0 : tabOverlap);
1900 rect.adjust(tabOverlap, begin ? tabOverlap : 0, 0, end ? -tabOverlap : 0);
1909 switch (tab->shape) {
1910 case QTabBar::RoundedNorth:
1911 rect.adjust(0,0, 0,-1);
1913 case QTabBar::RoundedSouth:
1914 rect.adjust(0,1, 0,0);
1916 case QTabBar::RoundedEast:
1917 rect.adjust( 1,0, 0,0);
1919 case QTabBar::RoundedWest:
1920 rect.adjust(0,0, -1,0);
1929 case CE_ProgressBarGroove:
1931 Qt::Orientation orient = Qt::Horizontal;
1932 if (
const QStyleOptionProgressBar *pb = qstyleoption_cast<
const QStyleOptionProgressBar *>(option))
1933 orient = pb->state & QStyle::State_Horizontal ? Qt::Horizontal : Qt::Vertical;
1934 partId = (orient == Qt::Horizontal) ? PP_BAR : PP_BARVERT;
1935 themeNumber = QWindowsXPStylePrivate::ProgressTheme;
1940 case CE_MenuEmptyArea:
1942 if (
const QStyleOptionMenuItem *menuitem = qstyleoption_cast<
const QStyleOptionMenuItem *>(option))
1944 int tab = menuitem->tabWidth;
1945 bool dis = !(menuitem->state & State_Enabled);
1946 bool act = menuitem->state & State_Selected;
1947 bool checkable = menuitem->menuHasCheckableItems;
1948 bool checked = checkable ? menuitem->checked :
false;
1951 int checkcol = qMax(menuitem->maxIconWidth, 12);
1954 rect.getRect(&x, &y, &w, &h);
1956 QBrush fill = menuitem->palette.brush(act ? QPalette::Highlight : QPalette::Button);
1957 p->fillRect(rect, fill);
1959 if (element == CE_MenuEmptyArea)
1963 if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) {
1964 int yoff = y-1 + h / 2;
1965 p->setPen(menuitem->palette.dark().color());
1966 p->drawLine(x, yoff, x+w, yoff);
1968 p->setPen(menuitem->palette.light().color());
1969 p->drawLine(x, yoff, x+w, yoff);
1976 if (!menuitem->icon.isNull()) {
1977 QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
1979 mode = QIcon::Active;
1980 QPixmap pixmap = checked ?
1981 menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option), mode, QIcon::On) :
1982 menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option), mode);
1983 const int pixw = pixmap.width() / pixmap.devicePixelRatio();
1984 const int pixh = pixmap.height() / pixmap.devicePixelRatio();
1985 QRect iconRect(0, 0, pixw, pixh);
1986 iconRect.moveCenter(QRect(xpos, y, checkcol, h).center());
1987 QRect vIconRect = visualRect(option->direction, option->rect, iconRect);
1988 p->setPen(menuitem->palette.text().color());
1989 p->setBrush(Qt::NoBrush);
1991 p->drawRect(vIconRect.adjusted(-1, -1, 0, 0));
1992 p->drawPixmap(vIconRect.topLeft(), pixmap);
1995 }
else if (checked) {
1996 QStyleOptionMenuItem newMi = *menuitem;
1997 newMi.state = State_None;
1999 newMi.state |= State_Enabled;
2001 newMi.state |= State_On;
2007 newMi.rect = visualRect(option->direction, option->rect, checkMarkRect);
2008 proxy()->drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p);
2011 QColor textColor = dis ? menuitem->palette.text().color() :
2012 act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color();
2013 p->setPen(textColor);
2017 xpos = menuitem->rect.x() + xm;
2019 QRect vTextRect = visualRect(option->direction, option->rect, textRect);
2020 QString s = menuitem->text;
2023 int t = s.indexOf(QLatin1Char(
'\t'));
2024 int text_flags = Qt::AlignVCenter|Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine | Qt::AlignLeft;
2025 if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem))
2026 text_flags |= Qt::TextHideMnemonic;
2029 QRect vShortcutRect = visualRect(option->direction, option->rect, QRect(textRect.topRight(), menuitem->rect.bottomRight()));
2030 if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option)) {
2031 p->setPen(menuitem->palette.light().color());
2032 p->drawText(vShortcutRect.adjusted(1,1,1,1), text_flags, s.mid(t + 1));
2033 p->setPen(textColor);
2035 p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
2038 QFont font = menuitem->font;
2039 if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
2042 if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option)) {
2043 p->setPen(menuitem->palette.light().color());
2044 p->drawText(vTextRect.adjusted(1,1,1,1), text_flags, s.left(t));
2045 p->setPen(textColor);
2047 p->drawText(vTextRect, text_flags, s);
2052 if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {
2053 int dim = (h - 2) / 2;
2054 PrimitiveElement arrow;
2055 arrow = (option->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
2057 QRect vSubMenuRect = visualRect(option->direction, option->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
2058 QStyleOptionMenuItem newMI = *menuitem;
2059 newMI.rect = vSubMenuRect;
2060 newMI.state = dis ? State_None : State_Enabled;
2062 newMI.palette.setColor(QPalette::ButtonText, newMI.palette.highlightedText().color());
2063 proxy()->drawPrimitive(arrow, &newMI, p);
2068 case CE_MenuBarItem:
2069 if (
const QStyleOptionMenuItem *mbi = qstyleoption_cast<
const QStyleOptionMenuItem *>(option))
2071 if (mbi->menuItemType == QStyleOptionMenuItem::DefaultItem)
2074 bool act = mbi->state & State_Selected;
2075 bool dis = !(mbi->state & State_Enabled);
2077 QBrush fill = mbi->palette.brush(act ? QPalette::Highlight : QPalette::Button);
2078 QPalette::ColorRole textRole = dis ? QPalette::Text:
2079 act ? QPalette::HighlightedText : QPalette::ButtonText;
2080 QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option), QIcon::Normal);
2082 uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
2083 if (!proxy()->styleHint(SH_UnderlineShortcut, mbi))
2084 alignment |= Qt::TextHideMnemonic;
2086 p->fillRect(rect, fill);
2088 drawItemPixmap(p, mbi->rect, alignment, pix);
2090 drawItemText(p, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole);
2093#if 0
&& QT_CONFIG(dockwidget)
2094 case CE_DockWidgetTitle:
2095 if (
const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<
const QStyleOptionDockWidget *>(option))
2097 int buttonMargin = 4;
2098 int mw = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt);
2099 int fw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, dwOpt);
2100 bool isFloating =
false;
2101 bool isActive = dwOpt->state & State_Active;
2103 const bool verticalTitleBar = dwOpt->verticalTitleBar;
2105 if (verticalTitleBar) {
2106 rect = rect.transposed();
2108 p->translate(rect.left() - 1, rect.top() + rect.width());
2110 p->translate(-rect.left() + 1, -rect.top());
2112 QRect r = rect.adjusted(0, 2, -1, -3);
2113 QRect titleRect = r;
2115 if (dwOpt->closable) {
2116 QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarCloseButton, dwOpt).actualSize(QSize(10, 10));
2117 titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
2120 if (dwOpt->floatable) {
2121 QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarMaxButton, dwOpt).actualSize(QSize(10, 10));
2122 titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
2126 titleRect.adjust(0, -fw, 0, 0);
2127 if (option->window && option->window->icon().cacheKey() != QApplication::windowIcon().cacheKey())
2128 titleRect.adjust(titleRect.height() + mw, 0, 0, 0);
2130 titleRect.adjust(mw, 0, 0, 0);
2131 if (!dwOpt->floatable && !dwOpt->closable)
2132 titleRect.adjust(0, 0, -mw, 0);
2135 if (!verticalTitleBar)
2136 titleRect = visualRect(dwOpt->direction, r, titleRect);
2139 QPen oldPen = p->pen();
2140 QString titleText = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width());
2141 p->setPen(dwOpt->palette.color(QPalette::Dark));
2144 if (!titleText.isEmpty()) {
2145 drawItemText(p, titleRect,
2146 Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, dwOpt->palette,
2147 dwOpt->state & State_Enabled, titleText,
2148 QPalette::WindowText);
2153 themeNumber = QWindowsXPStylePrivate::WindowTheme;
2155 stateId = CS_ACTIVE;
2157 stateId = CS_INACTIVE;
2159 int titleHeight = rect.height() - 2;
2160 rect = rect.adjusted(-fw, -fw, fw, 0);
2162 XPThemeData theme(option->window, p, themeNumber, 0, stateId);
2163 if (!theme.isValid())
2168 theme.partId = WP_SMALLCAPTION;
2169 d->drawBackground(theme);
2173 QIcon ico = option->window->icon();
2174 bool hasIcon = (ico.cacheKey() != QApplication::windowIcon().cacheKey());
2176 QPixmap pxIco = ico.pixmap(titleHeight);
2177 if (!verticalTitleBar && dwOpt->direction == Qt::RightToLeft)
2178 p->drawPixmap(rect.width() - titleHeight - pxIco.width(), rect.bottom() - titleHeight - 2, pxIco);
2180 p->drawPixmap(fw, rect.bottom() - titleHeight - 2, pxIco);
2182 if (!dwOpt->title.isEmpty()) {
2183 QPen oldPen = p->pen();
2184 QFont oldFont = p->font();
2185 QFont titleFont = oldFont;
2186 titleFont.setBold(
true);
2187 p->setFont(titleFont);
2189 = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width());
2191 int result = TST_NONE;
2192 GetThemeEnumValue(theme.handle(), WP_SMALLCAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWTYPE, &result);
2193 if (result != TST_NONE) {
2194 COLORREF textShadowRef;
2195 GetThemeColor(theme.handle(), WP_SMALLCAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWCOLOR, &textShadowRef);
2196 QColor textShadow = qRgb(GetRValue(textShadowRef), GetGValue(textShadowRef), GetBValue(textShadowRef));
2197 p->setPen(textShadow);
2198 drawItemText(p, titleRect.adjusted(1, 1, 1, 1),
2199 Qt::AlignLeft | Qt::AlignBottom, dwOpt->palette,
2200 dwOpt->state & State_Enabled, titleText);
2203 COLORREF captionText = GetSysColor(isActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT);
2204 QColor textColor = qRgb(GetRValue(captionText), GetGValue(captionText), GetBValue(captionText));
2205 p->setPen(textColor);
2206 drawItemText(p, titleRect,
2207 Qt::AlignLeft | Qt::AlignBottom, dwOpt->palette,
2208 dwOpt->state & State_Enabled, titleText);
2209 p->setFont(oldFont);
2219#if 0
&& QT_CONFIG(rubberband)
2221 if (qstyleoption_cast<
const QStyleOptionRubberBand *>(option)) {
2222 QColor highlight = option->palette.color(QPalette::Active, QPalette::Highlight).toRgb();
2224 p->setPen(highlight.darker(120));
2225 QColor dimHighlight(qMin(highlight.red()/2 + 110, 255),
2226 qMin(highlight.green()/2 + 110, 255),
2227 qMin(highlight.blue()/2 + 110, 255),
2230 p->setBrush(dimHighlight);
2231 p->drawRect(option->rect.adjusted(0, 0, -1, -1));
2237 case CE_HeaderEmptyArea:
2238 if (option->state & State_Horizontal)
2240 themeNumber = QWindowsXPStylePrivate::HeaderTheme;
2241 stateId = HIS_NORMAL;
2244 QWindowsStyle::drawControl(CE_HeaderEmptyArea, option, p);
2252 XPThemeData theme(option->window, p, themeNumber, partId, stateId, rect);
2254 QWindowsStyle::drawControl(element, option, p);
2258 theme.rotate = rotate;
2259 theme.mirrorHorizontally = hMirrored;
2260 theme.mirrorVertically = vMirrored;
2261 d->drawBackground(theme);
2345 QWindowsStyle::drawComplexControl(cc, option, p);
2349 State flags = option->state;
2350 SubControls sub = option->subControls;
2351 QRect r = option->rect;
2355 if (option->window && option->window->isActive())
2356 flags |= State_MouseOver;
2361 if (
const QStyleOptionSpinBox *sb = qstyleoption_cast<
const QStyleOptionSpinBox *>(option))
2363 XPThemeData theme(option->window, p, QWindowsXPStylePrivate::SpinTheme);
2365 if (sb->frame && (sub & SC_SpinBoxFrame)) {
2366 partId = EP_EDITTEXT;
2367 if (!(flags & State_Enabled))
2368 stateId = ETS_DISABLED;
2369 else if (flags & State_HasFocus)
2370 stateId = ETS_FOCUSED;
2372 stateId = ETS_NORMAL;
2374 XPThemeData ftheme(option->window, p, QWindowsXPStylePrivate::EditTheme,
2375 partId, stateId, r);
2376 ftheme.noContent =
true;
2377 d->drawBackground(ftheme);
2379 if (sub & SC_SpinBoxUp) {
2380 theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp);
2382 if (!(sb->stepEnabled & QStyleOptionSpinBox::StepUpEnabled) || !(flags & State_Enabled))
2383 stateId = UPS_DISABLED;
2384 else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken))
2385 stateId = UPS_PRESSED;
2386 else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_MouseOver))
2389 stateId = UPS_NORMAL;
2392 d->drawBackground(theme);
2394 if (sub & SC_SpinBoxDown) {
2395 theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown);
2397 if (!(sb->stepEnabled & QStyleOptionSpinBox::StepDownEnabled) || !(flags & State_Enabled))
2398 stateId = DNS_DISABLED;
2399 else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken))
2400 stateId = DNS_PRESSED;
2401 else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_MouseOver))
2404 stateId = DNS_NORMAL;
2407 d->drawBackground(theme);
2413 case CC_SearchField:
2414 if (
const QStyleOptionSearchField *sf = qstyleoption_cast<
const QStyleOptionSearchField *>(option))
2416 if (sf->frame && (sub & SC_SearchFieldFrame)) {
2417 partId = EP_EDITBORDER_NOSCROLL;
2418 if (!(flags & State_Enabled))
2419 stateId = ETS_DISABLED;
2420 else if (flags & State_MouseOver)
2422 else if (flags & State_HasFocus)
2423 stateId = ETS_FOCUSED;
2425 stateId = ETS_NORMAL;
2428 QWindowsXPStylePrivate::EditTheme,
2429 partId, stateId, r);
2431 d->drawBackground(theme);
2438 if (
const QStyleOptionComboBox *cmb = qstyleoption_cast<
const QStyleOptionComboBox *>(option))
2440 if (cmb->editable) {
2441 if (sub & SC_ComboBoxEditField) {
2442 partId = EP_EDITBORDER_NOSCROLL;
2443 if (!(flags & State_Enabled))
2444 stateId = ETS_DISABLED;
2445 else if (flags & State_MouseOver)
2447 else if (flags & State_HasFocus)
2448 stateId = ETS_FOCUSED;
2450 stateId = ETS_NORMAL;
2453 QWindowsXPStylePrivate::EditTheme,
2454 partId, stateId, r);
2456 d->drawBackground(theme);
2458 if (sub & SC_ComboBoxArrow) {
2459 QRect subRect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow);
2460 XPThemeData theme(option->window, p, QWindowsXPStylePrivate::ComboboxTheme);
2461 theme.rect = subRect;
2462 partId = option->direction == Qt::RightToLeft ? CP_DROPDOWNBUTTONLEFT : CP_DROPDOWNBUTTONRIGHT;
2464 if (!(cmb->state & State_Enabled))
2465 stateId = CBXS_DISABLED;
2466 else if (cmb->state & State_Sunken || cmb->state & State_On)
2467 stateId = CBXS_PRESSED;
2468 else if (cmb->state & State_MouseOver && option->activeSubControls & SC_ComboBoxArrow)
2471 stateId = CBXS_NORMAL;
2475 d->drawBackground(theme);
2479 if (sub & SC_ComboBoxFrame) {
2480 XPThemeData theme(option->window, p, QWindowsXPStylePrivate::ComboboxTheme);
2481 theme.rect = option->rect;
2482 theme.partId = CP_READONLY;
2483 if (!(cmb->state & State_Enabled))
2484 theme.stateId = CBXS_DISABLED;
2485 else if (cmb->state & State_Sunken || cmb->state & State_On)
2486 theme.stateId = CBXS_PRESSED;
2487 else if (cmb->state & State_MouseOver)
2488 theme.stateId = CBXS_HOT;
2490 theme.stateId = CBXS_NORMAL;
2491 d->drawBackground(theme);
2493 if (sub & SC_ComboBoxArrow) {
2494 XPThemeData theme(option->window, p, QWindowsXPStylePrivate::ComboboxTheme);
2495 theme.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow);
2496 theme.partId = option->direction == Qt::RightToLeft ? CP_DROPDOWNBUTTONLEFT : CP_DROPDOWNBUTTONRIGHT;
2497 if (!(cmb->state & State_Enabled))
2498 theme.stateId = CBXS_DISABLED;
2500 theme.stateId = CBXS_NORMAL;
2501 d->drawBackground(theme);
2503 if ((sub & SC_ComboBoxEditField) && (flags & State_HasFocus)) {
2504 QStyleOptionFocusRect fropt;
2505 fropt.QStyleOption::operator=(*cmb);
2506 fropt.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxEditField);
2507 proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p);
2514 if (
const QStyleOptionSlider *scrollbar = qstyleoption_cast<
const QStyleOptionSlider *>(option))
2516 XPThemeData theme(option->window, p, QWindowsXPStylePrivate::ScrollBarTheme);
2517 bool maxedOut = (scrollbar->maximum == scrollbar->minimum);
2519 flags &= ~State_Enabled;
2521 bool isHorz = flags & State_Horizontal;
2522 bool isRTL = option->direction == Qt::RightToLeft;
2523 if (sub & SC_ScrollBarAddLine) {
2524 theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine);
2525 partId = SBP_ARROWBTN;
2526 if (!(flags & State_Enabled))
2527 stateId = (isHorz ? (isRTL ? ABS_LEFTDISABLED : ABS_RIGHTDISABLED) : ABS_DOWNDISABLED);
2528 else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_Sunken))
2529 stateId = (isHorz ? (isRTL ? ABS_LEFTPRESSED : ABS_RIGHTPRESSED) : ABS_DOWNPRESSED);
2530 else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_MouseOver))
2531 stateId = (isHorz ? (isRTL ? ABS_LEFTHOT : ABS_RIGHTHOT) : ABS_DOWNHOT);
2533 stateId = (isHorz ? (isRTL ? ABS_LEFTNORMAL : ABS_RIGHTNORMAL) : ABS_DOWNNORMAL);
2536 d->drawBackground(theme);
2538 if (sub & SC_ScrollBarSubLine) {
2539 theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine);
2540 partId = SBP_ARROWBTN;
2541 if (!(flags & State_Enabled))
2542 stateId = (isHorz ? (isRTL ? ABS_RIGHTDISABLED : ABS_LEFTDISABLED) : ABS_UPDISABLED);
2543 else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_Sunken))
2544 stateId = (isHorz ? (isRTL ? ABS_RIGHTPRESSED : ABS_LEFTPRESSED) : ABS_UPPRESSED);
2545 else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_MouseOver))
2546 stateId = (isHorz ? (isRTL ? ABS_RIGHTHOT : ABS_LEFTHOT) : ABS_UPHOT);
2548 stateId = (isHorz ? (isRTL ? ABS_RIGHTNORMAL : ABS_LEFTNORMAL) : ABS_UPNORMAL);
2551 d->drawBackground(theme);
2554 if (sub & SC_ScrollBarSlider) {
2555 theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider);
2556 theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage));
2557 theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage));
2558 partId = scrollbar->orientation == Qt::Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
2559 stateId = SCRBS_DISABLED;
2562 d->drawBackground(theme);
2565 if (sub & SC_ScrollBarSubPage) {
2566 theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage);
2567 partId = flags & State_Horizontal ? SBP_UPPERTRACKHORZ : SBP_UPPERTRACKVERT;
2568 if (!(flags & State_Enabled))
2569 stateId = SCRBS_DISABLED;
2570 else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_Sunken))
2571 stateId = SCRBS_PRESSED;
2572 else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_MouseOver))
2573 stateId = SCRBS_HOT;
2575 stateId = SCRBS_NORMAL;
2578 d->drawBackground(theme);
2580 if (sub & SC_ScrollBarAddPage) {
2581 theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage);
2582 partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
2583 if (!(flags & State_Enabled))
2584 stateId = SCRBS_DISABLED;
2585 else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_Sunken))
2586 stateId = SCRBS_PRESSED;
2587 else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_MouseOver))
2588 stateId = SCRBS_HOT;
2590 stateId = SCRBS_NORMAL;
2593 d->drawBackground(theme);
2595 if (sub & SC_ScrollBarSlider) {
2601 const int extentForButton = proxy()->pixelMetric(PM_ScrollBarExtent, scrollbar);
2602 QSize extend(extentForButton, 0);
2603 if (scrollbar->orientation == Qt::Vertical)
2607 rect.setSize(rect.size() + 2 * extend);
2609 p->translate(-extend.width(), -extend.height());
2612 if (!(flags & State_Enabled))
2613 stateId = SCRBS_DISABLED;
2614 else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_Sunken))
2615 stateId = SCRBS_PRESSED;
2616 else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_MouseOver))
2617 stateId = SCRBS_HOT;
2619 stateId = SCRBS_NORMAL;
2622 theme.partId = flags & State_Horizontal ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT;
2624 d->drawBackground(theme);
2626 const QRect gripperBounds = QWindowsXPStylePrivate::scrollBarGripperBounds(flags, &theme);
2628 if (!gripperBounds.isEmpty()) {
2630 theme.rect = gripperBounds;
2631 p->setClipRegion(d->region(theme));
2632 d->drawBackground(theme);
2642 if (
const QStyleOptionSlider *slider = qstyleoption_cast<
const QStyleOptionSlider *>(option))
2644 XPThemeData theme(option->window, p, QWindowsXPStylePrivate::TrackBarTheme);
2645 QRect slrect = slider->rect;
2646 QRegion tickreg = slrect;
2647 if (sub & SC_SliderGroove) {
2648 theme.rect = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove);
2649 if (slider->orientation == Qt::Horizontal) {
2651 stateId = TRS_NORMAL;
2652 theme.rect = QRect(slrect.left(), theme.rect.center().y() - 2, slrect.width(), 4);
2654 partId = TKP_TRACKVERT;
2655 stateId = TRVS_NORMAL;
2656 theme.rect = QRect(theme.rect.center().x() - 2, slrect.top(), 4, slrect.height());
2660 d->drawBackground(theme);
2661 tickreg -= theme.rect;
2663 if (sub & SC_SliderTickmarks) {
2664 int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider);
2665 int ticks = slider->tickPosition;
2666 int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider);
2667 int len = proxy()->pixelMetric(PM_SliderLength, slider);
2668 int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider);
2669 int interval = slider->tickInterval;
2670 if (interval <= 0) {
2671 interval = slider->singleStep;
2672 if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval,
2674 - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
2676 interval = slider->pageStep;
2680 int fudge = len / 2;
2682 int bothOffset = (ticks & QStyleOptionSlider::TicksAbove && ticks & QStyleOptionSlider::TicksBelow) ? 1 : 0;
2683 p->setPen(d->sliderTickColor);
2684 QVarLengthArray<QLine, 32> lines;
2685 int v = slider->minimum;
2686 while (v <= slider->maximum + 1) {
2687 if (v == slider->maximum + 1 && interval == 1)
2689 const int v_ = qMin(v, slider->maximum);
2690 int tickLength = (v_ == slider->minimum || v_ >= slider->maximum) ? 4 : 3;
2691 pos = QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
2692 v_, available) + fudge;
2693 if (slider->orientation == Qt::Horizontal) {
2694 if (ticks & QStyleOptionSlider::TicksAbove)
2695 lines.append(QLine(pos, tickOffset - 1 - bothOffset,
2696 pos, tickOffset - 1 - bothOffset - tickLength));
2698 if (ticks & QStyleOptionSlider::TicksBelow)
2699 lines.append(QLine(pos, tickOffset + thickness + bothOffset,
2700 pos, tickOffset + thickness + bothOffset + tickLength));
2702 if (ticks & QStyleOptionSlider::TicksAbove)
2703 lines.append(QLine(tickOffset - 1 - bothOffset, pos,
2704 tickOffset - 1 - bothOffset - tickLength, pos));
2706 if (ticks & QStyleOptionSlider::TicksBelow)
2707 lines.append(QLine(tickOffset + thickness + bothOffset, pos,
2708 tickOffset + thickness + bothOffset + tickLength, pos));
2711 int nextInterval = v + interval;
2712 if (nextInterval < v)
2716 if (!lines.isEmpty()) {
2718 p->translate(slrect.topLeft());
2719 p->drawLines(lines.constData(), lines.size());
2723 if (sub & SC_SliderHandle) {
2724 theme.rect = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle);
2725 if (slider->orientation == Qt::Horizontal) {
2726 if (slider->tickPosition == QStyleOptionSlider::TicksAbove)
2727 partId = TKP_THUMBTOP;
2728 else if (slider->tickPosition == QStyleOptionSlider::TicksBelow)
2729 partId = TKP_THUMBBOTTOM;
2733 if (!(slider->state & State_Enabled))
2734 stateId = TUS_DISABLED;
2735 else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_Sunken))
2736 stateId = TUS_PRESSED;
2737 else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_MouseOver))
2739 else if (flags & State_HasFocus)
2740 stateId = TUS_FOCUSED;
2742 stateId = TUS_NORMAL;
2744 if (slider->tickPosition == QStyleOptionSlider::TicksLeft)
2745 partId = TKP_THUMBLEFT;
2746 else if (slider->tickPosition == QStyleOptionSlider::TicksRight)
2747 partId = TKP_THUMBRIGHT;
2749 partId = TKP_THUMBVERT;
2751 if (!(slider->state & State_Enabled))
2752 stateId = TUVS_DISABLED;
2753 else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_Sunken))
2754 stateId = TUVS_PRESSED;
2755 else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_MouseOver))
2757 else if (flags & State_HasFocus)
2758 stateId = TUVS_FOCUSED;
2760 stateId = TUVS_NORMAL;
2764 d->drawBackground(theme);
2766 if (sub & SC_SliderGroove && slider->state & State_HasFocus) {
2767 QStyleOptionFocusRect fropt;
2768 fropt.QStyleOption::operator=(*slider);
2769 fropt.rect = subElementRect(SE_SliderFocusRect, slider);
2770 proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p);
2775#if 0
&& QT_CONFIG(toolbutton)
2777 if (
const QStyleOptionToolButton *toolbutton
2778 = qstyleoption_cast<
const QStyleOptionToolButton *>(option)) {
2779 QRect button, menuarea;
2780 button = proxy()->subControlRect(cc, toolbutton, SC_ToolButton);
2781 menuarea = proxy()->subControlRect(cc, toolbutton, SC_ToolButtonMenu);
2783 State bflags = toolbutton->state & ~State_Sunken;
2784 State mflags = bflags;
2785 bool autoRaise = flags & State_AutoRaise;
2787 if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) {
2788 bflags &= ~State_Raised;
2792 if (toolbutton->state & State_Sunken) {
2793 if (toolbutton->activeSubControls & SC_ToolButton) {
2794 bflags |= State_Sunken;
2795 mflags |= State_MouseOver | State_Sunken;
2796 }
else if (toolbutton->activeSubControls & SC_ToolButtonMenu) {
2797 mflags |= State_Sunken;
2798 bflags |= State_MouseOver;
2802 QStyleOption tool = *toolbutton;
2803 if (toolbutton->subControls & SC_ToolButton) {
2804 if (flags & (State_Sunken | State_On | State_Raised) || !autoRaise) {
2805 if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup && autoRaise) {
2806 XPThemeData theme(option->window, p, QWindowsXPStylePrivate::ToolBarTheme);
2807 theme.partId = TP_SPLITBUTTON;
2808 theme.rect = button;
2809 if (!(bflags & State_Enabled))
2810 stateId = TS_DISABLED;
2811 else if (bflags & State_Sunken)
2812 stateId = TS_PRESSED;
2813 else if (bflags & State_MouseOver || !(flags & State_AutoRaise))
2814 stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT;
2815 else if (bflags & State_On)
2816 stateId = TS_CHECKED;
2818 stateId = TS_NORMAL;
2819 if (option->direction == Qt::RightToLeft)
2820 theme.mirrorHorizontally =
true;
2821 theme.stateId = stateId;
2822 d->drawBackground(theme);
2824 tool.rect = option->rect;
2825 tool.state = bflags;
2827 proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p);
2829 proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p);
2834 if (toolbutton->state & State_HasFocus) {
2835 QStyleOptionFocusRect fr;
2836 fr.QStyleOption::operator=(*toolbutton);
2837 fr.rect.adjust(3, 3, -3, -3);
2838 if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup)
2839 fr.rect.adjust(0, 0, -proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator,
2841 proxy()->drawPrimitive(PE_FrameFocusRect, &fr, p);
2843 QStyleOptionToolButton label = *toolbutton;
2844 label.state = bflags;
2847 label.state &= ~State_Sunken;
2848 label.rect = button.adjusted(fw, fw, -fw, -fw);
2849 proxy()->drawControl(CE_ToolButtonLabel, &label, p);
2851 if (toolbutton->subControls & SC_ToolButtonMenu) {
2852 tool.rect = menuarea;
2853 tool.state = mflags;
2855 proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, p);
2857 tool.state = mflags;
2858 menuarea.adjust(-2, 0, 0, 0);
2860 if ((bflags & State_Sunken) != (mflags & State_Sunken)){
2862 p->setClipRect(menuarea);
2863 tool.rect = option->rect;
2864 proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p);
2869 p->setPen(option->palette.dark().color());
2870 p->drawLine(menuarea.left(), menuarea.top() + 3,
2871 menuarea.left(), menuarea.bottom() - 3);
2872 p->setPen(option->palette.light().color());
2873 p->drawLine(menuarea.left() - 1, menuarea.top() + 3,
2874 menuarea.left() - 1, menuarea.bottom() - 3);
2876 tool.rect = menuarea.adjusted(2, 3, -2, -1);
2877 proxy()->drawPrimitive(PE_IndicatorArrowDown, &tool, p);
2880 }
else if (toolbutton->features & QStyleOptionToolButton::HasMenu) {
2881 int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton);
2882 QRect ir = toolbutton->rect;
2883 QStyleOptionToolButton newBtn = *toolbutton;
2884 newBtn.rect = QRect(ir.right() + 4 - mbi, ir.height() - mbi + 4, mbi - 5, mbi - 5);
2885 proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p);
2893 if (
const QStyleOptionTitleBar *tb = qstyleoption_cast<
const QStyleOptionTitleBar *>(option))
2895 const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(option);
2896 bool isActive = tb->titleBarState & QStyle::State_Active;
2897 XPThemeData theme(option->window, p, QWindowsXPStylePrivate::WindowTheme);
2898 if (sub & SC_TitleBarLabel) {
2900 partId = (tb->titleBarState & Qt::WindowMinimized) ? WP_MINCAPTION : WP_CAPTION;
2901 theme.rect = option->rect;
2902 if (!(option->state & QStyle::State_Enabled))
2903 stateId = CS_DISABLED;
2905 stateId = CS_ACTIVE;
2907 stateId = CS_INACTIVE;
2911 d->drawBackground(theme);
2913 QRect ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarLabel);
2916 GetThemeEnumValue(theme.handle(), WP_CAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWTYPE, &result);
2918 COLORREF textShadowRef;
2919 GetThemeColor(theme.handle(), WP_CAPTION, isActive ? CS_ACTIVE : CS_INACTIVE,
TMT_TEXTSHADOWCOLOR, &textShadowRef);
2920 QColor textShadow = qRgb(GetRValue(textShadowRef), GetGValue(textShadowRef), GetBValue(textShadowRef));
2921 p->setPen(textShadow);
2922 p->drawText(
int(ir.x() + 3 * factor),
int(ir.y() + 2 * factor),
2923 int(ir.width() - 1 * factor), ir.height(),
2924 Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text);
2926 COLORREF captionText = GetSysColor(isActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT);
2927 QColor textColor = qRgb(GetRValue(captionText), GetGValue(captionText), GetBValue(captionText));
2928 p->setPen(textColor);
2929 p->drawText(
int(ir.x() + 2 * factor),
int(ir.y() + 1 * factor),
2930 int(ir.width() - 2 * factor), ir.height(),
2931 Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text);
2933 if (sub & SC_TitleBarSysMenu && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
2934 theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarSysMenu);
2935 partId = WP_SYSBUTTON;
2936 if (!(option->state & QStyle::State_Enabled) || !isActive)
2937 stateId = SBS_DISABLED;
2938 else if (option->activeSubControls == SC_TitleBarSysMenu && (option->state & State_Sunken))
2939 stateId = SBS_PUSHED;
2940 else if (option->activeSubControls == SC_TitleBarSysMenu && (option->state & State_MouseOver))
2943 stateId = SBS_NORMAL;
2944 if (!tb->icon.isNull()) {
2945 tb->icon.paint(p, theme.rect);
2949 if (theme.size().isEmpty()) {
2950 int iconSize = proxy()->pixelMetric(PM_SmallIconSize, tb);
2951 QPixmap pm = proxy()->standardIcon(SP_TitleBarMenuButton, tb).pixmap(iconSize, iconSize);
2953 drawItemPixmap(p, theme.rect, Qt::AlignCenter, pm);
2956 d->drawBackground(theme);
2961 if (sub & SC_TitleBarMinButton && tb->titleBarFlags & Qt::WindowMinimizeButtonHint
2962 && !(tb->titleBarState & Qt::WindowMinimized)) {
2963 populateTitleBarButtonTheme(proxy(), option, SC_TitleBarMinButton, isActive, WP_MINBUTTON, &theme);
2964 d->drawBackground(theme);
2966 if (sub & SC_TitleBarMaxButton && tb->titleBarFlags & Qt::WindowMaximizeButtonHint
2967 && !(tb->titleBarState & Qt::WindowMaximized)) {
2968 populateTitleBarButtonTheme(proxy(), option, SC_TitleBarMaxButton, isActive, WP_MAXBUTTON, &theme);
2969 d->drawBackground(theme);
2971 if (sub & SC_TitleBarContextHelpButton
2972 && tb->titleBarFlags & Qt::WindowContextHelpButtonHint) {
2973 populateTitleBarButtonTheme(proxy(), option, SC_TitleBarContextHelpButton, isActive, WP_HELPBUTTON, &theme);
2974 d->drawBackground(theme);
2976 bool drawNormalButton = (sub & SC_TitleBarNormalButton)
2977 && (((tb->titleBarFlags & Qt::WindowMinimizeButtonHint)
2978 && (tb->titleBarState & Qt::WindowMinimized))
2979 || ((tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
2980 && (tb->titleBarState & Qt::WindowMaximized)));
2981 if (drawNormalButton) {
2982 populateTitleBarButtonTheme(proxy(), option, SC_TitleBarNormalButton, isActive, WP_RESTOREBUTTON, &theme);
2983 d->drawBackground(theme);
2985 if (sub & SC_TitleBarShadeButton && tb->titleBarFlags & Qt::WindowShadeButtonHint
2986 && !(tb->titleBarState & Qt::WindowMinimized)) {
2987 populateTitleBarButtonTheme(proxy(), option, SC_TitleBarShadeButton, isActive, WP_MINBUTTON, &theme);
2988 d->drawBackground(theme);
2990 if (sub & SC_TitleBarUnshadeButton && tb->titleBarFlags & Qt::WindowShadeButtonHint
2991 && tb->titleBarState & Qt::WindowMinimized) {
2992 populateTitleBarButtonTheme(proxy(), option, SC_TitleBarUnshadeButton, isActive, WP_RESTOREBUTTON, &theme);
2993 d->drawBackground(theme);
2995 if (sub & SC_TitleBarCloseButton && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
2996 populateTitleBarButtonTheme(proxy(), option, SC_TitleBarCloseButton, isActive, WP_CLOSEBUTTON, &theme);
2997 d->drawBackground(theme);
3003#if 0
&& QT_CONFIG(mdiarea)
3004 case CC_MdiControls:
3006 XPThemeData theme(option->window, p, QWindowsXPStylePrivate::WindowTheme, WP_MDICLOSEBUTTON, CBS_NORMAL);
3007 if (Q_UNLIKELY(!theme.isValid()))
3010 if (option->subControls.testFlag(SC_MdiCloseButton)) {
3011 populateMdiButtonTheme(proxy(), option, SC_MdiCloseButton, WP_MDICLOSEBUTTON, &theme);
3012 d->drawBackground(theme, mdiButtonCorrectionFactor(theme));
3014 if (option->subControls.testFlag(SC_MdiNormalButton)) {
3015 populateMdiButtonTheme(proxy(), option, SC_MdiNormalButton, WP_MDIRESTOREBUTTON, &theme);
3016 d->drawBackground(theme, mdiButtonCorrectionFactor(theme));
3018 if (option->subControls.testFlag(QStyle::SC_MdiMinButton)) {
3019 populateMdiButtonTheme(proxy(), option, SC_MdiMinButton, WP_MDIMINBUTTON, &theme);
3020 d->drawBackground(theme, mdiButtonCorrectionFactor(theme));
3025#if 0
&& QT_CONFIG(dial)
3027 if (
const QStyleOptionSlider *dial = qstyleoption_cast<
const QStyleOptionSlider *>(option))
3028 QStyleHelper::drawDial(dial, p);
3032 QWindowsStyle::drawComplexControl(cc, option, p);
3219 SubControl subControl)
const
3221 if (!QWindowsXPStylePrivate::useXP())
3222 return QWindowsStyle::subControlRect(cc, option, subControl);
3228 rect = visualRect(option->direction, option->rect,
3229 QWindowsStyle::subControlRect(cc, option, subControl));
3230 if (subControl == QStyle::SC_GroupBoxContents) {
3233 rect.adjust(9, 9, -9, -9);
3237 if (
const QStyleOptionTitleBar *tb = qstyleoption_cast<
const QStyleOptionTitleBar *>(option)) {
3238 if (!buttonVisible(subControl, tb))
3240 const bool isToolTitle =
false;
3241 const int height = tb->rect.height();
3242 const int width = tb->rect.width();
3243 const int buttonMargin =
int(QStyleHelper::dpiScaled(4, option));
3244 const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(option);
3245 int buttonHeight = qRound(qreal(GetSystemMetrics(SM_CYSIZE)) * factor)
3247 int buttonWidth = qRound(qreal(GetSystemMetrics(SM_CXSIZE)) * factor)
3249 const int delta = buttonWidth + 2;
3250 int controlTop = option->rect.bottom() - buttonHeight - 2;
3251 const int frameWidth = proxy()->pixelMetric(PM_MdiSubWindowFrameWidth, option);
3252 const bool sysmenuHint = (tb->titleBarFlags & Qt::WindowSystemMenuHint) != 0;
3253 const bool minimizeHint = (tb->titleBarFlags & Qt::WindowMinimizeButtonHint) != 0;
3254 const bool maximizeHint = (tb->titleBarFlags & Qt::WindowMaximizeButtonHint) != 0;
3255 const bool contextHint = (tb->titleBarFlags & Qt::WindowContextHelpButtonHint) != 0;
3256 const bool shadeHint = (tb->titleBarFlags & Qt::WindowShadeButtonHint) != 0;
3257 bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
3258 bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
3261 switch (subControl) {
3262 case SC_TitleBarLabel:
3263 rect = QRect(frameWidth, 0, width - (buttonWidth + frameWidth + 10), height);
3266 rect.adjust(0, 0, -buttonWidth - 3, 0);
3268 if (minimizeHint || maximizeHint)
3269 rect.adjust(0, 0, -buttonWidth - 2, 0);
3272 const int leftOffset = height - 8;
3273 rect.adjust(leftOffset, 0, 0, 0);
3276 rect.adjust(0, 0, -buttonWidth - 2, 0);
3278 rect.adjust(0, 0, -buttonWidth - 2, 0);
3280 rect.adjust(0, 0, -buttonWidth - 2, 0);
3282 rect.adjust(0, 0, -buttonWidth - 2, 0);
3286 case SC_TitleBarContextHelpButton:
3287 if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
3290 case SC_TitleBarMinButton:
3291 if (!isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
3293 else if (subControl == SC_TitleBarMinButton)
3296 case SC_TitleBarNormalButton:
3297 if (isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
3299 else if (isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
3301 else if (subControl == SC_TitleBarNormalButton)
3304 case SC_TitleBarMaxButton:
3305 if (!isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
3307 else if (subControl == SC_TitleBarMaxButton)
3310 case SC_TitleBarShadeButton:
3311 if (!isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
3313 else if (subControl == SC_TitleBarShadeButton)
3316 case SC_TitleBarUnshadeButton:
3317 if (isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
3319 else if (subControl == SC_TitleBarUnshadeButton)
3322 case SC_TitleBarCloseButton:
3323 if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
3325 else if (subControl == SC_TitleBarCloseButton)
3328 rect.setRect(width - offset - controlTop + 1, controlTop,
3329 buttonWidth, buttonHeight);
3332 case SC_TitleBarSysMenu:
3334 const int controlTop = 6;
3335 const int controlHeight = height - controlTop - 3;
3336 const int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, option);
3337 QSize iconSize = tb->icon.actualSize(QSize(iconExtent, iconExtent));
3338 if (tb->icon.isNull())
3339 iconSize = QSize(controlHeight, controlHeight);
3340 int hPad = (controlHeight - iconSize.height())/2;
3341 int vPad = (controlHeight - iconSize.width())/2;
3342 rect = QRect(frameWidth + hPad, controlTop + vPad, iconSize.width(), iconSize.height());
3351 if (
const QStyleOptionComboBox *cmb = qstyleoption_cast<
const QStyleOptionComboBox *>(option)) {
3352 const int x = cmb->rect.x(), y = cmb->rect.y(), wi = cmb->rect.width(), he = cmb->rect.height();
3353 const int xpos = x + wi - qRound(QStyleHelper::dpiScaled(1 + 16, option));
3355 switch (subControl) {
3356 case SC_ComboBoxFrame:
3360 case SC_ComboBoxArrow: {
3361 const qreal dpi = QStyleHelper::dpi(option);
3362 rect = QRect(xpos, y + qRound(QStyleHelper::dpiScaled(1, dpi)),
3363 qRound(QStyleHelper::dpiScaled(16, dpi)),
3364 he - qRound(QStyleHelper::dpiScaled(2, dpi)));
3368 case SC_ComboBoxEditField: {
3369 const qreal dpi = QStyleHelper::dpi(option);
3370 const int frame = qRound(QStyleHelper::dpiScaled(2, dpi));
3371 rect = QRect(x + frame, y + frame,
3372 wi - qRound(QStyleHelper::dpiScaled(3 + 16, dpi)),
3373 he - qRound(QStyleHelper::dpiScaled(4, dpi)));
3377 case SC_ComboBoxListBoxPopup:
3386#if 0
&& QT_CONFIG(mdiarea)
3387 case CC_MdiControls:
3389 int numSubControls = 0;
3390 if (option->subControls & SC_MdiCloseButton)
3392 if (option->subControls & SC_MdiMinButton)
3394 if (option->subControls & SC_MdiNormalButton)
3396 if (numSubControls == 0)
3399 int buttonWidth = option->rect.width() / numSubControls;
3401 switch (subControl) {
3402 case SC_MdiCloseButton:
3404 if (numSubControls == 1)
3406 offset += buttonWidth;
3408 case SC_MdiNormalButton:
3412 if (numSubControls == 1 || (numSubControls == 2 && !(option->subControls & SC_MdiMinButton)))
3414 if (option->subControls & SC_MdiNormalButton)
3415 offset += buttonWidth;
3420 rect = QRect(offset, 0, buttonWidth, option->rect.height());
3426 rect = visualRect(option->direction, option->rect,
3427 QWindowsStyle::subControlRect(cc, option, subControl));
3430 return visualRect(option->direction, option->rect, rect);
3716 const QStyleOption *option)
const
3719 return QWindowsStyle::standardIcon(standardIcon, option);
3722 QWindowsXPStylePrivate *d =
const_cast<QWindowsXPStylePrivate*>(d_func());
3723 switch (standardIcon) {
3724 case SP_TitleBarMaxButton:
3725 if (qstyleoption_cast<
const QStyleOptionDockWidget *>(option))
3727 if (d->dockFloat.isNull()) {
3728 XPThemeData themeSize(
nullptr,
nullptr, QWindowsXPStylePrivate::WindowTheme,
3729 WP_SMALLCLOSEBUTTON, CBS_NORMAL);
3730 XPThemeData theme(
nullptr,
nullptr, QWindowsXPStylePrivate::WindowTheme,
3731 WP_MAXBUTTON, MAXBS_NORMAL);
3732 if (theme.isValid()) {
3733 const QSize size = (themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(option)).toSize();
3735 pm.fill(Qt::transparent);
3738 theme.rect = QRect(QPoint(0, 0), size);
3739 d->drawBackground(theme);
3740 d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::Off);
3741 pm.fill(Qt::transparent);
3742 theme.stateId = MAXBS_PUSHED;
3743 d->drawBackground(theme);
3744 d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::On);
3745 pm.fill(Qt::transparent);
3746 theme.stateId = MAXBS_HOT;
3747 d->drawBackground(theme);
3748 d->dockFloat.addPixmap(pm, QIcon::Active, QIcon::Off);
3749 pm.fill(Qt::transparent);
3750 theme.stateId = MAXBS_INACTIVE;
3751 d->drawBackground(theme);
3752 d->dockFloat.addPixmap(pm, QIcon::Disabled, QIcon::Off);
3755 if (widget && widget->isWindow())
3756 return d->dockFloat;
3760 case SP_TitleBarCloseButton:
3761 if (qstyleoption_cast<
const QStyleOptionDockWidget *>(option))
3763 if (d->dockClose.isNull()) {
3764 XPThemeData theme(
nullptr,
nullptr, QWindowsXPStylePrivate::WindowTheme,
3765 WP_SMALLCLOSEBUTTON, CBS_NORMAL);
3766 if (theme.isValid()) {
3767 const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(option)).toSize();
3769 pm.fill(Qt::transparent);
3772 theme.partId = WP_CLOSEBUTTON;
3773 theme.rect = QRect(QPoint(0, 0), size);
3774 d->drawBackground(theme);
3775 d->dockClose.addPixmap(pm, QIcon::Normal, QIcon::Off);
3776 pm.fill(Qt::transparent);
3777 theme.stateId = CBS_PUSHED;
3778 d->drawBackground(theme);
3779 d->dockClose.addPixmap(pm, QIcon::Normal, QIcon::On);
3780 pm.fill(Qt::transparent);
3781 theme.stateId = CBS_HOT;
3782 d->drawBackground(theme);
3783 d->dockClose.addPixmap(pm, QIcon::Active, QIcon::Off);
3784 pm.fill(Qt::transparent);
3785 theme.stateId = CBS_INACTIVE;
3786 d->drawBackground(theme);
3787 d->dockClose.addPixmap(pm, QIcon::Disabled, QIcon::Off);
3790 if (widget && widget->isWindow())
3791 return d->dockClose;
3794 case SP_TitleBarNormalButton:
3795 if (qstyleoption_cast<
const QStyleOptionDockWidget *>(option))
3797 if (d->dockFloat.isNull()) {
3798 XPThemeData themeSize(
nullptr,
nullptr, QWindowsXPStylePrivate::WindowTheme,
3799 WP_SMALLCLOSEBUTTON, CBS_NORMAL);
3800 XPThemeData theme(
nullptr,
nullptr, QWindowsXPStylePrivate::WindowTheme,
3801 WP_RESTOREBUTTON, RBS_NORMAL);
3802 if (theme.isValid()) {
3803 const QSize size = (themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(option)).toSize();
3805 pm.fill(Qt::transparent);
3808 theme.rect = QRect(QPoint(0, 0), size);
3809 d->drawBackground(theme);
3810 d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::Off);
3811 pm.fill(Qt::transparent);
3812 theme.stateId = RBS_PUSHED;
3813 d->drawBackground(theme);
3814 d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::On);
3815 pm.fill(Qt::transparent);
3816 theme.stateId = RBS_HOT;
3817 d->drawBackground(theme);
3818 d->dockFloat.addPixmap(pm, QIcon::Active, QIcon::Off);
3819 pm.fill(Qt::transparent);
3820 theme.stateId = RBS_INACTIVE;
3821 d->drawBackground(theme);
3822 d->dockFloat.addPixmap(pm, QIcon::Disabled, QIcon::Off);
3825 if (widget && widget->isWindow())
3826 return d->dockFloat;
3834 return QWindowsStyle::standardIcon(standardIcon, option);