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);
1132 QWindowsStyle::drawPrimitive(pe, option, p);
1136 int themeNumber = -1;
1139 QRect rect = option->rect;
1140 State flags = option->state;
1141 bool hMirrored =
false;
1142 bool vMirrored =
false;
1143 bool noBorder =
false;
1144 bool noContent =
false;
1149 case PE_FrameTabBarBase:
1150 if (
const QStyleOptionTabBarBase *tbb
1151 = qstyleoption_cast<
const QStyleOptionTabBarBase *>(option)) {
1153 switch (tbb->shape) {
1154 case QTabBar::RoundedNorth:
1155 p->setPen(QPen(tbb->palette.dark(), 0));
1156 p->drawLine(tbb->rect.topLeft(), tbb->rect.topRight());
1158 case QTabBar::RoundedWest:
1159 p->setPen(QPen(tbb->palette.dark(), 0));
1160 p->drawLine(tbb->rect.left(), tbb->rect.top(), tbb->rect.left(), tbb->rect.bottom());
1162 case QTabBar::RoundedSouth:
1163 p->setPen(QPen(tbb->palette.dark(), 0));
1164 p->drawLine(tbb->rect.left(), tbb->rect.top(),
1165 tbb->rect.right(), tbb->rect.top());
1167 case QTabBar::RoundedEast:
1168 p->setPen(QPen(tbb->palette.dark(), 0));
1169 p->drawLine(tbb->rect.topLeft(), tbb->rect.bottomLeft());
1171 case QTabBar::TriangularNorth:
1172 case QTabBar::TriangularEast:
1173 case QTabBar::TriangularWest:
1174 case QTabBar::TriangularSouth:
1176 QWindowsStyle::drawPrimitive(pe, option, p);
1183 case PE_PanelButtonBevel:
1184 themeNumber = QWindowsXPStylePrivate::ButtonTheme;
1185 partId = BP_PUSHBUTTON;
1186 if (!(flags & State_Enabled))
1187 stateId = PBS_DISABLED;
1188 else if ((flags & State_Sunken) || (flags & State_On))
1189 stateId = PBS_PRESSED;
1190 else if (flags & State_MouseOver)
1195 stateId = PBS_NORMAL;
1198 case PE_PanelButtonTool:
1204 themeNumber = QWindowsXPStylePrivate::ToolBarTheme;
1206 if (!(flags & State_Enabled))
1207 stateId = TS_DISABLED;
1208 else if (flags & State_Sunken)
1209 stateId = TS_PRESSED;
1210 else if (flags & State_MouseOver)
1211 stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT;
1212 else if (flags & State_On)
1213 stateId = TS_CHECKED;
1214 else if (!(flags & State_AutoRaise))
1217 stateId = TS_NORMAL;
1220 case PE_IndicatorButtonDropDown:
1221 themeNumber = QWindowsXPStylePrivate::ToolBarTheme;
1222 partId = TP_SPLITBUTTONDROPDOWN;
1223 if (!(flags & State_Enabled))
1224 stateId = TS_DISABLED;
1225 else if (flags & State_Sunken)
1226 stateId = TS_PRESSED;
1227 else if (flags & State_MouseOver)
1228 stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT;
1229 else if (flags & State_On)
1230 stateId = TS_CHECKED;
1231 else if (!(flags & State_AutoRaise))
1234 stateId = TS_NORMAL;
1235 if (option->direction == Qt::RightToLeft)
1239 case PE_IndicatorCheckBox:
1240 themeNumber = QWindowsXPStylePrivate::ButtonTheme;
1241 partId = BP_CHECKBOX;
1242 if (!(flags & State_Enabled))
1243 stateId = CBS_UNCHECKEDDISABLED;
1244 else if (flags & State_Sunken)
1245 stateId = CBS_UNCHECKEDPRESSED;
1246 else if (flags & State_MouseOver)
1247 stateId = CBS_UNCHECKEDHOT;
1249 stateId = CBS_UNCHECKEDNORMAL;
1251 if (flags & State_On)
1252 stateId += CBS_CHECKEDNORMAL-1;
1253 else if (flags & State_NoChange)
1254 stateId += CBS_MIXEDNORMAL-1;
1258 case PE_IndicatorRadioButton:
1259 themeNumber = QWindowsXPStylePrivate::ButtonTheme;
1260 partId = BP_RADIOBUTTON;
1261 if (!(flags & State_Enabled))
1262 stateId = RBS_UNCHECKEDDISABLED;
1263 else if (flags & State_Sunken)
1264 stateId = RBS_UNCHECKEDPRESSED;
1265 else if (flags & State_MouseOver)
1266 stateId = RBS_UNCHECKEDHOT;
1268 stateId = RBS_UNCHECKEDNORMAL;
1270 if (flags & State_On)
1271 stateId += RBS_CHECKEDNORMAL-1;
1274 case PE_IndicatorDockWidgetResizeHandle:
1279 if (flags & State_Raised)
1281 themeNumber = QWindowsXPStylePrivate::ListViewTheme;
1282 partId = LVP_LISTGROUP;
1283 XPThemeData theme(option->window,
nullptr, themeNumber, partId);
1285 if (!(flags & State_Enabled))
1286 stateId = ETS_DISABLED;
1288 stateId = ETS_NORMAL;
1290 if (GetThemeEnumValue(theme.handle(), partId, stateId, TMT_BGTYPE, &fillType) == S_OK) {
1291 if (fillType == BT_BORDERFILL) {
1293 GetThemeColor(theme.handle(), partId, stateId, TMT_BORDERCOLOR, &bcRef);
1294 QColor bordercolor(qRgb(GetRValue(bcRef), GetGValue(bcRef), GetBValue(bcRef)));
1295 QPen oldPen = p->pen();
1300 p->setPen(QPen(option->palette.base().color(), 0));
1301 const qreal dpi = QStyleHelper::dpi(option);
1302 const auto topLevelAdjustment = QStyleHelper::dpiScaled(0.5, dpi);
1303 const auto bottomRightAdjustment = QStyleHelper::dpiScaled(-1, dpi);
1304 p->drawRect(QRectF(option->rect).adjusted(topLevelAdjustment, topLevelAdjustment,
1305 bottomRightAdjustment, bottomRightAdjustment));
1307 p->setPen(QPen(bordercolor, 0));
1308 p->drawRect(QRectF(option->rect).adjusted(0, 0, -topLevelAdjustment, -topLevelAdjustment));
1312 if (fillType == BT_NONE)
1317 case PE_FrameLineEdit: {
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332 if (qstyleoption_cast<
const QStyleOptionFrame *>(option)) {
1333 themeNumber = QWindowsXPStylePrivate::EditTheme;
1334 partId = EP_EDITTEXT;
1336 if (!(flags & State_Enabled))
1337 stateId = ETS_DISABLED;
1339 stateId = ETS_NORMAL;
1344 case PE_PanelLineEdit:
1345 if (
const QStyleOptionFrame *panel = qstyleoption_cast<
const QStyleOptionFrame *>(option)) {
1346 themeNumber = QWindowsXPStylePrivate::EditTheme;
1347 partId = EP_EDITTEXT;
1349 bool isEnabled = flags & State_Enabled;
1351 stateId = isEnabled ? ETS_NORMAL : ETS_DISABLED;
1354
1355{
1356 XPThemeData theme(
nullptr, p, themeNumber, partId, stateId, rect);
1358 QWindowsStyle::drawPrimitive(pe, option, p);
1362 GetThemeEnumValue(theme.handle(), partId, stateId, TMT_BGTYPE, &bgType);
1363 if ( bgType == BT_IMAGEFILE ) {
1364 theme.mirrorHorizontally = hMirrored;
1365 theme.mirrorVertically = vMirrored;
1366 theme.noBorder = noBorder;
1367 theme.noContent = noContent;
1368 theme.rotate = rotate;
1369 d->drawBackground(theme);
1371 QBrush fillColor = option->palette.brush(QPalette::Base);
1374 PROPERTYORIGIN origin = PO_NOTFOUND;
1375 GetThemePropertyOrigin(theme.handle(), theme
.partId, theme
.stateId, TMT_FILLCOLOR, &origin);
1377 if ((origin == PO_PART || origin == PO_STATE)) {
1379 GetThemeColor(theme.handle(), partId, stateId, TMT_FILLCOLOR, &bgRef);
1380 fillColor = QBrush(qRgb(GetRValue(bgRef), GetGValue(bgRef), GetBValue(bgRef)));
1383 p->fillRect(option->rect, fillColor);
1387 if (panel->lineWidth > 0)
1388 proxy()->drawPrimitive(PE_FrameLineEdit, panel, p);
1393 case PE_FrameTabWidget:
1394 if (
const QStyleOptionTabWidgetFrame *tab = qstyleoption_cast<
const QStyleOptionTabWidgetFrame *>(option))
1396 themeNumber = QWindowsXPStylePrivate::TabTheme;
1399 if (option->window) {
1400 bool useGradient =
true;
1401 const int maxlength = 256;
1402 wchar_t themeFileName[maxlength];
1403 wchar_t themeColor[maxlength];
1405 if (GetCurrentThemeName(themeFileName, maxlength, themeColor, maxlength,
nullptr, 0) == S_OK) {
1406 wchar_t *offset =
nullptr;
1407 if ((offset = wcsrchr(themeFileName, QChar(QLatin1Char(
'\\')).unicode())) !=
nullptr) {
1409 if (!lstrcmp(offset, L"Luna.msstyles") && !lstrcmp(offset, L"Metallic")) {
1410 useGradient =
false;
1417 QStyleOptionTabWidgetFrame frameOpt = *tab;
1420 QRect contentsRect = subElementRect(SE_TabWidgetTabContents, &frameOpt);
1421 QRegion reg = option->rect;
1422 reg -= contentsRect;
1423 p->setClipRegion(reg);
1424 XPThemeData theme(option->window, p, themeNumber, partId, stateId, rect);
1425 theme.mirrorHorizontally = hMirrored;
1426 theme.mirrorVertically = vMirrored;
1427 d->drawBackground(theme);
1428 p->setClipRect(contentsRect);
1432 switch (tab->shape) {
1433 case QTabBar::RoundedNorth:
1434 case QTabBar::TriangularNorth:
1436 case QTabBar::RoundedSouth:
1437 case QTabBar::TriangularSouth:
1440 case QTabBar::RoundedEast:
1441 case QTabBar::TriangularEast:
1444 case QTabBar::RoundedWest:
1445 case QTabBar::TriangularWest:
1457 p->setPen(option->palette.dark().color());
1458 p->drawRect(rect.adjusted(0, 0, -1, -1));
1462 case PE_PanelMenuBar:
1465 case PE_FrameDockWidget:
1466 if (
const QStyleOptionFrame *frm = qstyleoption_cast<
const QStyleOptionFrame *>(option))
1468 themeNumber = QWindowsXPStylePrivate::WindowTheme;
1469 if (flags & State_Active)
1470 stateId = FS_ACTIVE;
1472 stateId = FS_INACTIVE;
1474 int fwidth = proxy()->pixelMetric(PM_DockWidgetFrameWidth, frm);
1476 XPThemeData theme(option->window, p, themeNumber, 0, stateId);
1479 theme.rect = QRect(frm->rect.x(), frm->rect.y(), frm->rect.x()+fwidth, frm->rect.height()-fwidth); theme.partId = WP_SMALLFRAMELEFT;
1480 d->drawBackground(theme);
1481 theme.rect = QRect(frm->rect.width()-fwidth, frm->rect.y(), fwidth, frm->rect.height()-fwidth);
1482 theme.partId = WP_SMALLFRAMERIGHT;
1483 d->drawBackground(theme);
1484 theme.rect = QRect(frm->rect.x(), frm->rect.bottom()-fwidth+1, frm->rect.width(), fwidth);
1485 theme.partId = WP_SMALLFRAMEBOTTOM;
1486 d->drawBackground(theme);
1491 case PE_IndicatorHeaderArrow:
1494 name = QWindowsXPStylePrivate::HeaderTheme;
1495 partId = HP_HEADERSORTARROW;
1496 if (flags & State_Down)
1497 stateId = HSAS_SORTEDDOWN;
1499 stateId = HSAS_SORTEDUP;
1501 if (
const QStyleOptionHeader *header = qstyleoption_cast<
const QStyleOptionHeader *>(option)) {
1503 p->setPen(option->palette.dark().color());
1504 p->translate(0, option->rect.height()/2 - 4);
1505 if (header->sortIndicator & QStyleOptionHeader::SortUp) {
1506 p->drawLine(option->rect.x(), option->rect.y(), option->rect.x()+8, option->rect.y());
1507 p->drawLine(option->rect.x()+1, option->rect.y()+1, option->rect.x()+7, option->rect.y()+1);
1508 p->drawLine(option->rect.x()+2, option->rect.y()+2, option->rect.x()+6, option->rect.y()+2);
1509 p->drawLine(option->rect.x()+3, option->rect.y()+3, option->rect.x()+5, option->rect.y()+3);
1510 p->drawPoint(option->rect.x()+4, option->rect.y()+4);
1511 }
else if (header->sortIndicator & QStyleOptionHeader::SortDown) {
1512 p->drawLine(option->rect.x(), option->rect.y()+4, option->rect.x()+8, option->rect.y()+4);
1513 p->drawLine(option->rect.x()+1, option->rect.y()+3, option->rect.x()+7, option->rect.y()+3);
1514 p->drawLine(option->rect.x()+2, option->rect.y()+2, option->rect.x()+6, option->rect.y()+2);
1515 p->drawLine(option->rect.x()+3, option->rect.y()+1, option->rect.x()+5, option->rect.y()+1);
1516 p->drawPoint(option->rect.x()+4, option->rect.y());
1525 case PE_FrameStatusBarItem:
1526 themeNumber = QWindowsXPStylePrivate::StatusTheme;
1530 case PE_FrameGroupBox:
1531 themeNumber = QWindowsXPStylePrivate::ButtonTheme;
1532 partId = BP_GROUPBOX;
1533 if (!(flags & State_Enabled))
1534 stateId = GBS_DISABLED;
1536 stateId = GBS_NORMAL;
1537 if (
const QStyleOptionFrame *frame = qstyleoption_cast<
const QStyleOptionFrame *>(option)) {
1538 if (frame->features & QStyleOptionFrame::Flat) {
1540 QRect fr = frame->rect;
1541 QPoint p1(fr.x(), fr.y() + 1);
1542 QPoint p2(fr.x() + fr.width(), p1.y() + 1);
1543 rect = QRect(p1, p2);
1549 case PE_IndicatorProgressChunk:
1551 Qt::Orientation orient = Qt::Horizontal;
1552 bool inverted =
false;
1553 if (
const QStyleOptionProgressBar *pb = qstyleoption_cast<
const QStyleOptionProgressBar *>(option)) {
1554 orient = pb->state & QStyle::State_Horizontal ? Qt::Horizontal : Qt::Vertical;
1555 inverted = pb->invertedAppearance;
1557 if (orient == Qt::Horizontal) {
1559 rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.height() );
1560 if (inverted && option->direction == Qt::LeftToRight)
1563 partId = PP_CHUNKVERT;
1564 rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.height());
1566 themeNumber = QWindowsXPStylePrivate::ProgressTheme;
1571 case PE_FrameWindow:
1572 if (
const QStyleOptionFrame *frm = qstyleoption_cast<
const QStyleOptionFrame *>(option))
1574 themeNumber = QWindowsXPStylePrivate::WindowTheme;
1575 if (flags & State_Active)
1576 stateId = FS_ACTIVE;
1578 stateId = FS_INACTIVE;
1580 int fwidth =
int((frm->lineWidth + frm->midLineWidth) / QWindowsStylePrivate::nativeMetricScaleFactor(option));
1582 XPThemeData theme(option->window, p, themeNumber, 0, stateId);
1587 theme.rect = QRect(option->rect.x(), option->rect.y()+fwidth, option->rect.x()+fwidth, option->rect.height()-fwidth);
1588 theme.partId = WP_FRAMELEFT;
1589 if (!d->drawBackground(theme)) {
1590 QWindowsStyle::drawPrimitive(pe, option, p);
1593 theme.rect = QRect(option->rect.width()-fwidth, option->rect.y()+fwidth, fwidth, option->rect.height()-fwidth);
1594 theme.partId = WP_FRAMERIGHT;
1595 if (!d->drawBackground(theme)) {
1596 QWindowsStyle::drawPrimitive(pe, option, p);
1599 theme.rect = QRect(option->rect.x(), option->rect.height()-fwidth, option->rect.width(), fwidth);
1600 theme.partId = WP_FRAMEBOTTOM;
1601 if (!d->drawBackground(theme)) {
1602 QWindowsStyle::drawPrimitive(pe, option, p);
1605 theme.rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.y()+fwidth);
1606 theme.partId = WP_CAPTION;
1607 if (!d->drawBackground(theme))
1608 QWindowsStyle::drawPrimitive(pe, option, p);
1613 case PE_IndicatorBranch:
1615 static const int decoration_size = 9;
1616 int mid_h = option->rect.x() + option->rect.width() / 2;
1617 int mid_v = option->rect.y() + option->rect.height() / 2;
1622 QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern);
1623 if (option->state & State_Item) {
1624 if (option->direction == Qt::RightToLeft)
1625 p->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush);
1627 p->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush);
1629 if (option->state & State_Sibling)
1630 p->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush);
1631 if (option->state & (State_Open | State_Children | State_Item | State_Sibling))
1632 p->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush);
1633 if (option->state & State_Children) {
1634 int delta = decoration_size / 2;
1639 XPThemeData theme(
nullptr, p, QWindowsXPStylePrivate::XpTreeViewTheme);
1640 theme.rect = QRect(bef_h, bef_v, decoration_size, decoration_size);
1641 theme.partId = TVP_GLYPH;
1642 theme.stateId = flags & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED;
1643 d->drawBackground(theme);
1648 case PE_IndicatorToolBarSeparator:
1649 if (option->rect.height() < 3) {
1652 QWindowsStyle::drawPrimitive(pe, option, p);
1655 themeNumber = QWindowsXPStylePrivate::ToolBarTheme;
1656 partId = TP_SEPARATOR;
1658 if (option->state & State_Horizontal)
1659 partId = TP_SEPARATOR;
1661 partId = TP_SEPARATORVERT;
1665 case PE_IndicatorToolBarHandle:
1667 themeNumber = QWindowsXPStylePrivate::RebarTheme;
1668 partId = RP_GRIPPER;
1669 if (option->state & State_Horizontal) {
1670 partId = RP_GRIPPER;
1671 rect.adjust(0, 0, -2, 0);
1674 partId = RP_GRIPPERVERT;
1675 rect.adjust(0, 0, 0, -2);
1679 case PE_IndicatorItemViewItemCheck: {
1680 QStyleOptionButton button;
1681 button.QStyleOption::operator=(*option);
1682 button.state &= ~State_MouseOver;
1683 proxy()->drawPrimitive(PE_IndicatorCheckBox, &button, p);
1691 XPThemeData theme(option->window, p, themeNumber, partId, stateId, rect);
1693 QWindowsStyle::drawPrimitive(pe, option, p);
1696 theme.mirrorHorizontally = hMirrored;
1697 theme.mirrorVertically = vMirrored;
1698 theme.noBorder = noBorder;
1699 theme.noContent = noContent;
1700 theme.rotate = rotate;
1701 d->drawBackground(theme);
1712 QWindowsStyle::drawControl(element, option, p);
1716 QRect rect(option->rect);
1717 State flags = option->state;
1720 bool hMirrored =
false;
1721 bool vMirrored =
false;
1723 int themeNumber = -1;
1729 themeNumber = QWindowsXPStylePrivate::StatusTheme;
1730 partId = SP_GRIPPER;
1731 XPThemeData theme(
nullptr, p, themeNumber, partId);
1732 QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(option)).toSize();
1734 if (
const QStyleOptionSizeGrip *sg = qstyleoption_cast<
const QStyleOptionSizeGrip *>(option)) {
1735 switch (sg->corner) {
1736 case Qt::BottomRightCorner:
1737 rect = QRect(QPoint(rect.right() - size.width(), rect.bottom() - size.height()), size);
1739 case Qt::BottomLeftCorner:
1740 rect = QRect(QPoint(rect.left() + 1, rect.bottom() - size.height()), size);
1743 case Qt::TopRightCorner:
1744 rect = QRect(QPoint(rect.right() - size.width(), rect.top() + 1), size);
1747 case Qt::TopLeftCorner:
1748 rect = QRect(rect.topLeft() + QPoint(1, 1), size);
1749 hMirrored = vMirrored =
true;
1755 case CE_HeaderSection:
1756 themeNumber = QWindowsXPStylePrivate::HeaderTheme;
1757 partId = HP_HEADERITEM;
1758 if (flags & State_Sunken)
1759 stateId = HIS_PRESSED;
1760 else if (flags & State_MouseOver)
1763 stateId = HIS_NORMAL;
1767 p->eraseRect(option->rect);
1770 case CE_PushButtonBevel:
1771 if (
const QStyleOptionButton *btn = qstyleoption_cast<
const QStyleOptionButton *>(option))
1773 themeNumber = QWindowsXPStylePrivate::ButtonTheme;
1774 partId = BP_PUSHBUTTON;
1775 bool justFlat = ((btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken)))
1776 || ((btn->features & QStyleOptionButton::CommandLinkButton)
1777 && !(flags & State_MouseOver)
1778 && !(btn->features & QStyleOptionButton::DefaultButton));
1779 if (!(flags & State_Enabled) && !(btn->features & QStyleOptionButton::Flat))
1780 stateId = PBS_DISABLED;
1783 else if (flags & (State_Sunken | State_On))
1784 stateId = PBS_PRESSED;
1785 else if (flags & State_MouseOver)
1787 else if (btn->features & QStyleOptionButton::DefaultButton)
1788 stateId = PBS_DEFAULTED;
1790 stateId = PBS_NORMAL;
1793 XPThemeData theme(option->window, p, themeNumber, partId, stateId, rect);
1794 d->drawBackground(theme);
1797 if (btn->features & QStyleOptionButton::HasMenu) {
1798 int mbiw = 0, mbih = 0;
1800 QWindowsXPStylePrivate::ToolBarTheme,
1801 TP_SPLITBUTTONDROPDOWN);
1803 const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(option)).toSize();
1804 mbiw = size.width();
1805 mbih = size.height();
1808 QRect ir = btn->rect;
1809 QStyleOptionButton newBtn = *btn;
1810 newBtn.rect = QRect(ir.right() - mbiw - 1, 1 + (ir.height()/2) - (mbih/2), mbiw, mbih);
1811 proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p);
1817 if (
const QStyleOptionTab *tab = qstyleoption_cast<
const QStyleOptionTab *>(option))
1819 stateId = tab->state & State_Enabled ? TIS_NORMAL : TIS_DISABLED;
1823 case CE_TabBarTabShape:
1824 if (
const QStyleOptionTab *tab = qstyleoption_cast<
const QStyleOptionTab *>(option))
1826 themeNumber = QWindowsXPStylePrivate::TabTheme;
1827 bool isDisabled = !(tab->state & State_Enabled);
1828 bool hasFocus = tab->state & State_HasFocus;
1829 bool isHot = tab->state & State_MouseOver;
1830 bool selected = tab->state & State_Selected;
1831 bool lastTab = tab->position == QStyleOptionTab::End;
1832 bool firstTab = tab->position == QStyleOptionTab::Beginning;
1833 bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
1834 bool leftAligned = proxy()->styleHint(SH_TabBar_Alignment, tab) == Qt::AlignLeft;
1835 bool centerAligned = proxy()->styleHint(SH_TabBar_Alignment, tab) == Qt::AlignCenter;
1836 int borderThickness = proxy()->pixelMetric(PM_DefaultFrameWidth, option);
1837 int tabOverlap = proxy()->pixelMetric(PM_TabBarTabOverlap, option);
1840 stateId = TIS_DISABLED;
1842 stateId = TIS_SELECTED;
1844 stateId = TIS_FOCUSED;
1848 stateId = TIS_NORMAL;
1851 if (firstTab || onlyOne) {
1853 partId = TABP_TABITEMLEFTEDGE;
1854 }
else if (centerAligned) {
1855 partId = TABP_TABITEM;
1857 partId = TABP_TABITEMRIGHTEDGE;
1860 partId = TABP_TABITEM;
1863 if (tab->direction == Qt::RightToLeft
1864 && (tab->shape == QTabBar::RoundedNorth
1865 || tab->shape == QTabBar::RoundedSouth)) {
1866 bool temp = firstTab;
1870 bool begin = firstTab || onlyOne;
1871 bool end = lastTab || onlyOne;
1872 switch (tab->shape) {
1873 case QTabBar::RoundedNorth:
1875 rect.adjust(begin ? 0 : -tabOverlap, 0, end ? 0 : tabOverlap, borderThickness);
1877 rect.adjust(begin? tabOverlap : 0, tabOverlap, end ? -tabOverlap : 0, 0);
1879 case QTabBar::RoundedSouth:
1883 rect.adjust(begin ? 0 : -tabOverlap , -borderThickness, end ? 0 : tabOverlap, 0);
1885 rect.adjust(begin ? tabOverlap : 0, 0, end ? -tabOverlap : 0 , -tabOverlap);
1887 case QTabBar::RoundedEast:
1890 rect.adjust(-borderThickness, begin ? 0 : -tabOverlap, 0, end ? 0 : tabOverlap);
1892 rect.adjust(0, begin ? tabOverlap : 0, -tabOverlap, end ? -tabOverlap : 0);
1895 case QTabBar::RoundedWest:
1899 rect.adjust(0, begin ? 0 : -tabOverlap, borderThickness, end ? 0 : tabOverlap);
1901 rect.adjust(tabOverlap, begin ? tabOverlap : 0, 0, end ? -tabOverlap : 0);
1910 switch (tab->shape) {
1911 case QTabBar::RoundedNorth:
1912 rect.adjust(0,0, 0,-1);
1914 case QTabBar::RoundedSouth:
1915 rect.adjust(0,1, 0,0);
1917 case QTabBar::RoundedEast:
1918 rect.adjust( 1,0, 0,0);
1920 case QTabBar::RoundedWest:
1921 rect.adjust(0,0, -1,0);
1930 case CE_ProgressBarGroove:
1932 Qt::Orientation orient = Qt::Horizontal;
1933 if (
const QStyleOptionProgressBar *pb = qstyleoption_cast<
const QStyleOptionProgressBar *>(option))
1934 orient = pb->state & QStyle::State_Horizontal ? Qt::Horizontal : Qt::Vertical;
1935 partId = (orient == Qt::Horizontal) ? PP_BAR : PP_BARVERT;
1936 themeNumber = QWindowsXPStylePrivate::ProgressTheme;
1941 case CE_MenuEmptyArea:
1943 if (
const QStyleOptionMenuItem *menuitem = qstyleoption_cast<
const QStyleOptionMenuItem *>(option))
1945 int tab = menuitem->tabWidth;
1946 bool dis = !(menuitem->state & State_Enabled);
1947 bool act = menuitem->state & State_Selected;
1948 bool checkable = menuitem->menuHasCheckableItems;
1949 bool checked = checkable ? menuitem->checked :
false;
1952 int checkcol = qMax(menuitem->maxIconWidth, 12);
1955 rect.getRect(&x, &y, &w, &h);
1957 QBrush fill = menuitem->palette.brush(act ? QPalette::Highlight : QPalette::Button);
1958 p->fillRect(rect, fill);
1960 if (element == CE_MenuEmptyArea)
1964 if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) {
1965 int yoff = y-1 + h / 2;
1966 p->setPen(menuitem->palette.dark().color());
1967 p->drawLine(x, yoff, x+w, yoff);
1969 p->setPen(menuitem->palette.light().color());
1970 p->drawLine(x, yoff, x+w, yoff);
1977 if (!menuitem->icon.isNull()) {
1978 QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
1980 mode = QIcon::Active;
1981 QPixmap pixmap = checked ?
1982 menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option), mode, QIcon::On) :
1983 menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option), mode);
1984 const int pixw = pixmap.width() / pixmap.devicePixelRatio();
1985 const int pixh = pixmap.height() / pixmap.devicePixelRatio();
1986 QRect iconRect(0, 0, pixw, pixh);
1987 iconRect.moveCenter(QRect(xpos, y, checkcol, h).center());
1988 QRect vIconRect = visualRect(option->direction, option->rect, iconRect);
1989 p->setPen(menuitem->palette.text().color());
1990 p->setBrush(Qt::NoBrush);
1992 p->drawRect(vIconRect.adjusted(-1, -1, 0, 0));
1993 p->drawPixmap(vIconRect.topLeft(), pixmap);
1996 }
else if (checked) {
1997 QStyleOptionMenuItem newMi = *menuitem;
1998 newMi.state = State_None;
2000 newMi.state |= State_Enabled;
2002 newMi.state |= State_On;
2008 newMi.rect = visualRect(option->direction, option->rect, checkMarkRect);
2009 proxy()->drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p);
2012 QColor textColor = dis ? menuitem->palette.text().color() :
2013 act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color();
2014 p->setPen(textColor);
2018 xpos = menuitem->rect.x() + xm;
2020 QRect vTextRect = visualRect(option->direction, option->rect, textRect);
2021 QString s = menuitem->text;
2024 int t = s.indexOf(QLatin1Char(
'\t'));
2025 int text_flags = Qt::AlignVCenter|Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine | Qt::AlignLeft;
2026 if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem))
2027 text_flags |= Qt::TextHideMnemonic;
2030 QRect vShortcutRect = visualRect(option->direction, option->rect, QRect(textRect.topRight(), menuitem->rect.bottomRight()));
2031 if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option)) {
2032 p->setPen(menuitem->palette.light().color());
2033 p->drawText(vShortcutRect.adjusted(1,1,1,1), text_flags, s.mid(t + 1));
2034 p->setPen(textColor);
2036 p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
2039 QFont font = menuitem->font;
2040 if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
2043 if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option)) {
2044 p->setPen(menuitem->palette.light().color());
2045 p->drawText(vTextRect.adjusted(1,1,1,1), text_flags, s.left(t));
2046 p->setPen(textColor);
2048 p->drawText(vTextRect, text_flags, s);
2053 if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {
2054 int dim = (h - 2) / 2;
2055 PrimitiveElement arrow;
2056 arrow = (option->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
2058 QRect vSubMenuRect = visualRect(option->direction, option->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
2059 QStyleOptionMenuItem newMI = *menuitem;
2060 newMI.rect = vSubMenuRect;
2061 newMI.state = dis ? State_None : State_Enabled;
2063 newMI.palette.setColor(QPalette::ButtonText, newMI.palette.highlightedText().color());
2064 proxy()->drawPrimitive(arrow, &newMI, p);
2069 case CE_MenuBarItem:
2070 if (
const QStyleOptionMenuItem *mbi = qstyleoption_cast<
const QStyleOptionMenuItem *>(option))
2072 if (mbi->menuItemType == QStyleOptionMenuItem::DefaultItem)
2075 bool act = mbi->state & State_Selected;
2076 bool dis = !(mbi->state & State_Enabled);
2078 QBrush fill = mbi->palette.brush(act ? QPalette::Highlight : QPalette::Button);
2079 QPalette::ColorRole textRole = dis ? QPalette::Text:
2080 act ? QPalette::HighlightedText : QPalette::ButtonText;
2081 QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option), QIcon::Normal);
2083 uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
2084 if (!proxy()->styleHint(SH_UnderlineShortcut, mbi))
2085 alignment |= Qt::TextHideMnemonic;
2087 p->fillRect(rect, fill);
2089 drawItemPixmap(p, mbi->rect, alignment, pix);
2091 drawItemText(p, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole);
2094#if 0
&& QT_CONFIG(dockwidget)
2095 case CE_DockWidgetTitle:
2096 if (
const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<
const QStyleOptionDockWidget *>(option))
2098 int buttonMargin = 4;
2099 int mw = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt);
2100 int fw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, dwOpt);
2101 bool isFloating =
false;
2102 bool isActive = dwOpt->state & State_Active;
2104 const bool verticalTitleBar = dwOpt->verticalTitleBar;
2106 if (verticalTitleBar) {
2107 rect = rect.transposed();
2109 p->translate(rect.left() - 1, rect.top() + rect.width());
2111 p->translate(-rect.left() + 1, -rect.top());
2113 QRect r = rect.adjusted(0, 2, -1, -3);
2114 QRect titleRect = r;
2116 if (dwOpt->closable) {
2117 QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarCloseButton, dwOpt).actualSize(QSize(10, 10));
2118 titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
2121 if (dwOpt->floatable) {
2122 QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarMaxButton, dwOpt).actualSize(QSize(10, 10));
2123 titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
2127 titleRect.adjust(0, -fw, 0, 0);
2128 if (option->window && option->window->icon().cacheKey() != QApplication::windowIcon().cacheKey())
2129 titleRect.adjust(titleRect.height() + mw, 0, 0, 0);
2131 titleRect.adjust(mw, 0, 0, 0);
2132 if (!dwOpt->floatable && !dwOpt->closable)
2133 titleRect.adjust(0, 0, -mw, 0);
2136 if (!verticalTitleBar)
2137 titleRect = visualRect(dwOpt->direction, r, titleRect);
2140 QPen oldPen = p->pen();
2141 QString titleText = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width());
2142 p->setPen(dwOpt->palette.color(QPalette::Dark));
2145 if (!titleText.isEmpty()) {
2146 drawItemText(p, titleRect,
2147 Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, dwOpt->palette,
2148 dwOpt->state & State_Enabled, titleText,
2149 QPalette::WindowText);
2154 themeNumber = QWindowsXPStylePrivate::WindowTheme;
2156 stateId = CS_ACTIVE;
2158 stateId = CS_INACTIVE;
2160 int titleHeight = rect.height() - 2;
2161 rect = rect.adjusted(-fw, -fw, fw, 0);
2163 XPThemeData theme(option->window, p, themeNumber, 0, stateId);
2164 if (!theme.isValid())
2169 theme.partId = WP_SMALLCAPTION;
2170 d->drawBackground(theme);
2174 QIcon ico = option->window->icon();
2175 bool hasIcon = (ico.cacheKey() != QApplication::windowIcon().cacheKey());
2177 QPixmap pxIco = ico.pixmap(titleHeight);
2178 if (!verticalTitleBar && dwOpt->direction == Qt::RightToLeft)
2179 p->drawPixmap(rect.width() - titleHeight - pxIco.width(), rect.bottom() - titleHeight - 2, pxIco);
2181 p->drawPixmap(fw, rect.bottom() - titleHeight - 2, pxIco);
2183 if (!dwOpt->title.isEmpty()) {
2184 QPen oldPen = p->pen();
2185 QFont oldFont = p->font();
2186 QFont titleFont = oldFont;
2187 titleFont.setBold(
true);
2188 p->setFont(titleFont);
2190 = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width());
2192 int result = TST_NONE;
2193 GetThemeEnumValue(theme.handle(), WP_SMALLCAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWTYPE, &result);
2194 if (result != TST_NONE) {
2195 COLORREF textShadowRef;
2196 GetThemeColor(theme.handle(), WP_SMALLCAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWCOLOR, &textShadowRef);
2197 QColor textShadow = qRgb(GetRValue(textShadowRef), GetGValue(textShadowRef), GetBValue(textShadowRef));
2198 p->setPen(textShadow);
2199 drawItemText(p, titleRect.adjusted(1, 1, 1, 1),
2200 Qt::AlignLeft | Qt::AlignBottom, dwOpt->palette,
2201 dwOpt->state & State_Enabled, titleText);
2204 COLORREF captionText = GetSysColor(isActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT);
2205 QColor textColor = qRgb(GetRValue(captionText), GetGValue(captionText), GetBValue(captionText));
2206 p->setPen(textColor);
2207 drawItemText(p, titleRect,
2208 Qt::AlignLeft | Qt::AlignBottom, dwOpt->palette,
2209 dwOpt->state & State_Enabled, titleText);
2210 p->setFont(oldFont);
2220#if 0
&& QT_CONFIG(rubberband)
2222 if (qstyleoption_cast<
const QStyleOptionRubberBand *>(option)) {
2223 QColor highlight = option->palette.color(QPalette::Active, QPalette::Highlight).toRgb();
2225 p->setPen(highlight.darker(120));
2226 QColor dimHighlight(qMin(highlight.red()/2 + 110, 255),
2227 qMin(highlight.green()/2 + 110, 255),
2228 qMin(highlight.blue()/2 + 110, 255),
2231 p->setBrush(dimHighlight);
2232 p->drawRect(option->rect.adjusted(0, 0, -1, -1));
2238 case CE_HeaderEmptyArea:
2239 if (option->state & State_Horizontal)
2241 themeNumber = QWindowsXPStylePrivate::HeaderTheme;
2242 stateId = HIS_NORMAL;
2245 QWindowsStyle::drawControl(CE_HeaderEmptyArea, option, p);
2253 XPThemeData theme(option->window, p, themeNumber, partId, stateId, rect);
2255 QWindowsStyle::drawControl(element, option, p);
2259 theme.rotate = rotate;
2260 theme.mirrorHorizontally = hMirrored;
2261 theme.mirrorVertically = vMirrored;
2262 d->drawBackground(theme);
2346 QWindowsStyle::drawComplexControl(cc, option, p);
2350 State flags = option->state;
2351 SubControls sub = option->subControls;
2352 QRect r = option->rect;
2356 if (option->window && option->window->isActive())
2357 flags |= State_MouseOver;
2362 if (
const QStyleOptionSpinBox *sb = qstyleoption_cast<
const QStyleOptionSpinBox *>(option))
2364 XPThemeData theme(option->window, p, QWindowsXPStylePrivate::SpinTheme);
2366 if (sb->frame && (sub & SC_SpinBoxFrame)) {
2367 partId = EP_EDITTEXT;
2368 if (!(flags & State_Enabled))
2369 stateId = ETS_DISABLED;
2370 else if (flags & State_HasFocus)
2371 stateId = ETS_FOCUSED;
2373 stateId = ETS_NORMAL;
2375 XPThemeData ftheme(option->window, p, QWindowsXPStylePrivate::EditTheme,
2376 partId, stateId, r);
2377 ftheme.noContent =
true;
2378 d->drawBackground(ftheme);
2380 if (sub & SC_SpinBoxUp) {
2381 theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp);
2383 if (!(sb->stepEnabled & QStyleOptionSpinBox::StepUpEnabled) || !(flags & State_Enabled))
2384 stateId = UPS_DISABLED;
2385 else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken))
2386 stateId = UPS_PRESSED;
2387 else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_MouseOver))
2390 stateId = UPS_NORMAL;
2393 d->drawBackground(theme);
2395 if (sub & SC_SpinBoxDown) {
2396 theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown);
2398 if (!(sb->stepEnabled & QStyleOptionSpinBox::StepDownEnabled) || !(flags & State_Enabled))
2399 stateId = DNS_DISABLED;
2400 else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken))
2401 stateId = DNS_PRESSED;
2402 else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_MouseOver))
2405 stateId = DNS_NORMAL;
2408 d->drawBackground(theme);
2414 case CC_SearchField:
2415 if (
const QStyleOptionSearchField *sf = qstyleoption_cast<
const QStyleOptionSearchField *>(option))
2417 if (sf->frame && (sub & SC_SearchFieldFrame)) {
2418 partId = EP_EDITBORDER_NOSCROLL;
2419 if (!(flags & State_Enabled))
2420 stateId = ETS_DISABLED;
2421 else if (flags & State_MouseOver)
2423 else if (flags & State_HasFocus)
2424 stateId = ETS_FOCUSED;
2426 stateId = ETS_NORMAL;
2429 QWindowsXPStylePrivate::EditTheme,
2430 partId, stateId, r);
2432 d->drawBackground(theme);
2439 if (
const QStyleOptionComboBox *cmb = qstyleoption_cast<
const QStyleOptionComboBox *>(option))
2441 if (cmb->editable) {
2442 if (sub & SC_ComboBoxEditField) {
2443 partId = EP_EDITBORDER_NOSCROLL;
2444 if (!(flags & State_Enabled))
2445 stateId = ETS_DISABLED;
2446 else if (flags & State_MouseOver)
2448 else if (flags & State_HasFocus)
2449 stateId = ETS_FOCUSED;
2451 stateId = ETS_NORMAL;
2454 QWindowsXPStylePrivate::EditTheme,
2455 partId, stateId, r);
2457 d->drawBackground(theme);
2459 if (sub & SC_ComboBoxArrow) {
2460 QRect subRect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow);
2461 XPThemeData theme(option->window, p, QWindowsXPStylePrivate::ComboboxTheme);
2462 theme.rect = subRect;
2463 partId = option->direction == Qt::RightToLeft ? CP_DROPDOWNBUTTONLEFT : CP_DROPDOWNBUTTONRIGHT;
2465 if (!(cmb->state & State_Enabled))
2466 stateId = CBXS_DISABLED;
2467 else if (cmb->state & State_Sunken || cmb->state & State_On)
2468 stateId = CBXS_PRESSED;
2469 else if (cmb->state & State_MouseOver && option->activeSubControls & SC_ComboBoxArrow)
2472 stateId = CBXS_NORMAL;
2476 d->drawBackground(theme);
2480 if (sub & SC_ComboBoxFrame) {
2481 XPThemeData theme(option->window, p, QWindowsXPStylePrivate::ComboboxTheme);
2482 theme.rect = option->rect;
2483 theme.partId = CP_READONLY;
2484 if (!(cmb->state & State_Enabled))
2485 theme.stateId = CBXS_DISABLED;
2486 else if (cmb->state & State_Sunken || cmb->state & State_On)
2487 theme.stateId = CBXS_PRESSED;
2488 else if (cmb->state & State_MouseOver)
2489 theme.stateId = CBXS_HOT;
2491 theme.stateId = CBXS_NORMAL;
2492 d->drawBackground(theme);
2494 if (sub & SC_ComboBoxArrow) {
2495 XPThemeData theme(option->window, p, QWindowsXPStylePrivate::ComboboxTheme);
2496 theme.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow);
2497 theme.partId = option->direction == Qt::RightToLeft ? CP_DROPDOWNBUTTONLEFT : CP_DROPDOWNBUTTONRIGHT;
2498 if (!(cmb->state & State_Enabled))
2499 theme.stateId = CBXS_DISABLED;
2501 theme.stateId = CBXS_NORMAL;
2502 d->drawBackground(theme);
2504 if ((sub & SC_ComboBoxEditField) && (flags & State_HasFocus)) {
2505 QStyleOptionFocusRect fropt;
2506 fropt.QStyleOption::operator=(*cmb);
2507 fropt.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxEditField);
2508 proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p);
2515 if (
const QStyleOptionSlider *scrollbar = qstyleoption_cast<
const QStyleOptionSlider *>(option))
2517 XPThemeData theme(option->window, p, QWindowsXPStylePrivate::ScrollBarTheme);
2518 bool maxedOut = (scrollbar->maximum == scrollbar->minimum);
2520 flags &= ~State_Enabled;
2522 bool isHorz = flags & State_Horizontal;
2523 bool isRTL = option->direction == Qt::RightToLeft;
2524 if (sub & SC_ScrollBarAddLine) {
2525 theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine);
2526 partId = SBP_ARROWBTN;
2527 if (!(flags & State_Enabled))
2528 stateId = (isHorz ? (isRTL ? ABS_LEFTDISABLED : ABS_RIGHTDISABLED) : ABS_DOWNDISABLED);
2529 else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_Sunken))
2530 stateId = (isHorz ? (isRTL ? ABS_LEFTPRESSED : ABS_RIGHTPRESSED) : ABS_DOWNPRESSED);
2531 else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_MouseOver))
2532 stateId = (isHorz ? (isRTL ? ABS_LEFTHOT : ABS_RIGHTHOT) : ABS_DOWNHOT);
2534 stateId = (isHorz ? (isRTL ? ABS_LEFTNORMAL : ABS_RIGHTNORMAL) : ABS_DOWNNORMAL);
2537 d->drawBackground(theme);
2539 if (sub & SC_ScrollBarSubLine) {
2540 theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine);
2541 partId = SBP_ARROWBTN;
2542 if (!(flags & State_Enabled))
2543 stateId = (isHorz ? (isRTL ? ABS_RIGHTDISABLED : ABS_LEFTDISABLED) : ABS_UPDISABLED);
2544 else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_Sunken))
2545 stateId = (isHorz ? (isRTL ? ABS_RIGHTPRESSED : ABS_LEFTPRESSED) : ABS_UPPRESSED);
2546 else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_MouseOver))
2547 stateId = (isHorz ? (isRTL ? ABS_RIGHTHOT : ABS_LEFTHOT) : ABS_UPHOT);
2549 stateId = (isHorz ? (isRTL ? ABS_RIGHTNORMAL : ABS_LEFTNORMAL) : ABS_UPNORMAL);
2552 d->drawBackground(theme);
2555 if (sub & SC_ScrollBarSlider) {
2556 theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider);
2557 theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage));
2558 theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage));
2559 partId = scrollbar->orientation == Qt::Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
2560 stateId = SCRBS_DISABLED;
2563 d->drawBackground(theme);
2566 if (sub & SC_ScrollBarSubPage) {
2567 theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage);
2568 partId = flags & State_Horizontal ? SBP_UPPERTRACKHORZ : SBP_UPPERTRACKVERT;
2569 if (!(flags & State_Enabled))
2570 stateId = SCRBS_DISABLED;
2571 else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_Sunken))
2572 stateId = SCRBS_PRESSED;
2573 else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_MouseOver))
2574 stateId = SCRBS_HOT;
2576 stateId = SCRBS_NORMAL;
2579 d->drawBackground(theme);
2581 if (sub & SC_ScrollBarAddPage) {
2582 theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage);
2583 partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
2584 if (!(flags & State_Enabled))
2585 stateId = SCRBS_DISABLED;
2586 else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_Sunken))
2587 stateId = SCRBS_PRESSED;
2588 else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_MouseOver))
2589 stateId = SCRBS_HOT;
2591 stateId = SCRBS_NORMAL;
2594 d->drawBackground(theme);
2596 if (sub & SC_ScrollBarSlider) {
2602 const int extentForButton = proxy()->pixelMetric(PM_ScrollBarExtent, scrollbar);
2603 QSize extend(extentForButton, 0);
2604 if (scrollbar->orientation == Qt::Vertical)
2608 rect.setSize(rect.size() + 2 * extend);
2610 p->translate(-extend.width(), -extend.height());
2613 if (!(flags & State_Enabled))
2614 stateId = SCRBS_DISABLED;
2615 else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_Sunken))
2616 stateId = SCRBS_PRESSED;
2617 else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_MouseOver))
2618 stateId = SCRBS_HOT;
2620 stateId = SCRBS_NORMAL;
2623 theme.partId = flags & State_Horizontal ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT;
2625 d->drawBackground(theme);
2627 const QRect gripperBounds = QWindowsXPStylePrivate::scrollBarGripperBounds(flags, &theme);
2629 if (!gripperBounds.isEmpty()) {
2631 theme.rect = gripperBounds;
2632 p->setClipRegion(d->region(theme));
2633 d->drawBackground(theme);
2643 if (
const QStyleOptionSlider *slider = qstyleoption_cast<
const QStyleOptionSlider *>(option))
2645 XPThemeData theme(option->window, p, QWindowsXPStylePrivate::TrackBarTheme);
2646 QRect slrect = slider->rect;
2647 QRegion tickreg = slrect;
2648 if (sub & SC_SliderGroove) {
2649 theme.rect = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove);
2650 if (slider->orientation == Qt::Horizontal) {
2652 stateId = TRS_NORMAL;
2653 theme.rect = QRect(slrect.left(), theme.rect.center().y() - 2, slrect.width(), 4);
2655 partId = TKP_TRACKVERT;
2656 stateId = TRVS_NORMAL;
2657 theme.rect = QRect(theme.rect.center().x() - 2, slrect.top(), 4, slrect.height());
2661 d->drawBackground(theme);
2662 tickreg -= theme.rect;
2664 if (sub & SC_SliderTickmarks) {
2665 int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider);
2666 int ticks = slider->tickPosition;
2667 int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider);
2668 int len = proxy()->pixelMetric(PM_SliderLength, slider);
2669 int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider);
2670 int interval = slider->tickInterval;
2671 if (interval <= 0) {
2672 interval = slider->singleStep;
2673 if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval,
2675 - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
2677 interval = slider->pageStep;
2681 int fudge = len / 2;
2683 int bothOffset = (ticks & QStyleOptionSlider::TicksAbove && ticks & QStyleOptionSlider::TicksBelow) ? 1 : 0;
2684 p->setPen(d->sliderTickColor);
2685 QVarLengthArray<QLine, 32> lines;
2686 int v = slider->minimum;
2687 while (v <= slider->maximum + 1) {
2688 if (v == slider->maximum + 1 && interval == 1)
2690 const int v_ = qMin(v, slider->maximum);
2691 int tickLength = (v_ == slider->minimum || v_ >= slider->maximum) ? 4 : 3;
2692 pos = QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
2693 v_, available) + fudge;
2694 if (slider->orientation == Qt::Horizontal) {
2695 if (ticks & QStyleOptionSlider::TicksAbove)
2696 lines.append(QLine(pos, tickOffset - 1 - bothOffset,
2697 pos, tickOffset - 1 - bothOffset - tickLength));
2699 if (ticks & QStyleOptionSlider::TicksBelow)
2700 lines.append(QLine(pos, tickOffset + thickness + bothOffset,
2701 pos, tickOffset + thickness + bothOffset + tickLength));
2703 if (ticks & QStyleOptionSlider::TicksAbove)
2704 lines.append(QLine(tickOffset - 1 - bothOffset, pos,
2705 tickOffset - 1 - bothOffset - tickLength, pos));
2707 if (ticks & QStyleOptionSlider::TicksBelow)
2708 lines.append(QLine(tickOffset + thickness + bothOffset, pos,
2709 tickOffset + thickness + bothOffset + tickLength, pos));
2712 int nextInterval = v + interval;
2713 if (nextInterval < v)
2717 if (!lines.isEmpty()) {
2719 p->translate(slrect.topLeft());
2720 p->drawLines(lines.constData(), lines.size());
2724 if (sub & SC_SliderHandle) {
2725 theme.rect = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle);
2726 if (slider->orientation == Qt::Horizontal) {
2727 if (slider->tickPosition == QStyleOptionSlider::TicksAbove)
2728 partId = TKP_THUMBTOP;
2729 else if (slider->tickPosition == QStyleOptionSlider::TicksBelow)
2730 partId = TKP_THUMBBOTTOM;
2734 if (!(slider->state & State_Enabled))
2735 stateId = TUS_DISABLED;
2736 else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_Sunken))
2737 stateId = TUS_PRESSED;
2738 else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_MouseOver))
2740 else if (flags & State_HasFocus)
2741 stateId = TUS_FOCUSED;
2743 stateId = TUS_NORMAL;
2745 if (slider->tickPosition == QStyleOptionSlider::TicksLeft)
2746 partId = TKP_THUMBLEFT;
2747 else if (slider->tickPosition == QStyleOptionSlider::TicksRight)
2748 partId = TKP_THUMBRIGHT;
2750 partId = TKP_THUMBVERT;
2752 if (!(slider->state & State_Enabled))
2753 stateId = TUVS_DISABLED;
2754 else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_Sunken))
2755 stateId = TUVS_PRESSED;
2756 else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_MouseOver))
2758 else if (flags & State_HasFocus)
2759 stateId = TUVS_FOCUSED;
2761 stateId = TUVS_NORMAL;
2765 d->drawBackground(theme);
2767 if (sub & SC_SliderGroove && slider->state & State_HasFocus) {
2768 QStyleOptionFocusRect fropt;
2769 fropt.QStyleOption::operator=(*slider);
2770 fropt.rect = subElementRect(SE_SliderFocusRect, slider);
2771 proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p);
2776#if 0
&& QT_CONFIG(toolbutton)
2778 if (
const QStyleOptionToolButton *toolbutton
2779 = qstyleoption_cast<
const QStyleOptionToolButton *>(option)) {
2780 QRect button, menuarea;
2781 button = proxy()->subControlRect(cc, toolbutton, SC_ToolButton);
2782 menuarea = proxy()->subControlRect(cc, toolbutton, SC_ToolButtonMenu);
2784 State bflags = toolbutton->state & ~State_Sunken;
2785 State mflags = bflags;
2786 bool autoRaise = flags & State_AutoRaise;
2788 if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) {
2789 bflags &= ~State_Raised;
2793 if (toolbutton->state & State_Sunken) {
2794 if (toolbutton->activeSubControls & SC_ToolButton) {
2795 bflags |= State_Sunken;
2796 mflags |= State_MouseOver | State_Sunken;
2797 }
else if (toolbutton->activeSubControls & SC_ToolButtonMenu) {
2798 mflags |= State_Sunken;
2799 bflags |= State_MouseOver;
2803 QStyleOption tool = *toolbutton;
2804 if (toolbutton->subControls & SC_ToolButton) {
2805 if (flags & (State_Sunken | State_On | State_Raised) || !autoRaise) {
2806 if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup && autoRaise) {
2807 XPThemeData theme(option->window, p, QWindowsXPStylePrivate::ToolBarTheme);
2808 theme.partId = TP_SPLITBUTTON;
2809 theme.rect = button;
2810 if (!(bflags & State_Enabled))
2811 stateId = TS_DISABLED;
2812 else if (bflags & State_Sunken)
2813 stateId = TS_PRESSED;
2814 else if (bflags & State_MouseOver || !(flags & State_AutoRaise))
2815 stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT;
2816 else if (bflags & State_On)
2817 stateId = TS_CHECKED;
2819 stateId = TS_NORMAL;
2820 if (option->direction == Qt::RightToLeft)
2821 theme.mirrorHorizontally =
true;
2822 theme.stateId = stateId;
2823 d->drawBackground(theme);
2825 tool.rect = option->rect;
2826 tool.state = bflags;
2828 proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p);
2830 proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p);
2835 if (toolbutton->state & State_HasFocus) {
2836 QStyleOptionFocusRect fr;
2837 fr.QStyleOption::operator=(*toolbutton);
2838 fr.rect.adjust(3, 3, -3, -3);
2839 if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup)
2840 fr.rect.adjust(0, 0, -proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator,
2842 proxy()->drawPrimitive(PE_FrameFocusRect, &fr, p);
2844 QStyleOptionToolButton label = *toolbutton;
2845 label.state = bflags;
2848 label.state &= ~State_Sunken;
2849 label.rect = button.adjusted(fw, fw, -fw, -fw);
2850 proxy()->drawControl(CE_ToolButtonLabel, &label, p);
2852 if (toolbutton->subControls & SC_ToolButtonMenu) {
2853 tool.rect = menuarea;
2854 tool.state = mflags;
2856 proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, p);
2858 tool.state = mflags;
2859 menuarea.adjust(-2, 0, 0, 0);
2861 if ((bflags & State_Sunken) != (mflags & State_Sunken)){
2863 p->setClipRect(menuarea);
2864 tool.rect = option->rect;
2865 proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p);
2870 p->setPen(option->palette.dark().color());
2871 p->drawLine(menuarea.left(), menuarea.top() + 3,
2872 menuarea.left(), menuarea.bottom() - 3);
2873 p->setPen(option->palette.light().color());
2874 p->drawLine(menuarea.left() - 1, menuarea.top() + 3,
2875 menuarea.left() - 1, menuarea.bottom() - 3);
2877 tool.rect = menuarea.adjusted(2, 3, -2, -1);
2878 proxy()->drawPrimitive(PE_IndicatorArrowDown, &tool, p);
2881 }
else if (toolbutton->features & QStyleOptionToolButton::HasMenu) {
2882 int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton);
2883 QRect ir = toolbutton->rect;
2884 QStyleOptionToolButton newBtn = *toolbutton;
2885 newBtn.rect = QRect(ir.right() + 4 - mbi, ir.height() - mbi + 4, mbi - 5, mbi - 5);
2886 proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p);
2894 if (
const QStyleOptionTitleBar *tb = qstyleoption_cast<
const QStyleOptionTitleBar *>(option))
2896 const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(option);
2897 bool isActive = tb->titleBarState & QStyle::State_Active;
2898 XPThemeData theme(option->window, p, QWindowsXPStylePrivate::WindowTheme);
2899 if (sub & SC_TitleBarLabel) {
2901 partId = (tb->titleBarState & Qt::WindowMinimized) ? WP_MINCAPTION : WP_CAPTION;
2902 theme.rect = option->rect;
2903 if (!(option->state & QStyle::State_Enabled))
2904 stateId = CS_DISABLED;
2906 stateId = CS_ACTIVE;
2908 stateId = CS_INACTIVE;
2912 d->drawBackground(theme);
2914 QRect ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarLabel);
2917 GetThemeEnumValue(theme.handle(), WP_CAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWTYPE, &result);
2919 COLORREF textShadowRef;
2920 GetThemeColor(theme.handle(), WP_CAPTION, isActive ? CS_ACTIVE : CS_INACTIVE,
TMT_TEXTSHADOWCOLOR, &textShadowRef);
2921 QColor textShadow = qRgb(GetRValue(textShadowRef), GetGValue(textShadowRef), GetBValue(textShadowRef));
2922 p->setPen(textShadow);
2923 p->drawText(
int(ir.x() + 3 * factor),
int(ir.y() + 2 * factor),
2924 int(ir.width() - 1 * factor), ir.height(),
2925 Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text);
2927 COLORREF captionText = GetSysColor(isActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT);
2928 QColor textColor = qRgb(GetRValue(captionText), GetGValue(captionText), GetBValue(captionText));
2929 p->setPen(textColor);
2930 p->drawText(
int(ir.x() + 2 * factor),
int(ir.y() + 1 * factor),
2931 int(ir.width() - 2 * factor), ir.height(),
2932 Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text);
2934 if (sub & SC_TitleBarSysMenu && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
2935 theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarSysMenu);
2936 partId = WP_SYSBUTTON;
2937 if (!(option->state & QStyle::State_Enabled) || !isActive)
2938 stateId = SBS_DISABLED;
2939 else if (option->activeSubControls == SC_TitleBarSysMenu && (option->state & State_Sunken))
2940 stateId = SBS_PUSHED;
2941 else if (option->activeSubControls == SC_TitleBarSysMenu && (option->state & State_MouseOver))
2944 stateId = SBS_NORMAL;
2945 if (!tb->icon.isNull()) {
2946 tb->icon.paint(p, theme.rect);
2950 if (theme.size().isEmpty()) {
2951 int iconSize = proxy()->pixelMetric(PM_SmallIconSize, tb);
2952 QPixmap pm = proxy()->standardIcon(SP_TitleBarMenuButton, tb).pixmap(iconSize, iconSize);
2954 drawItemPixmap(p, theme.rect, Qt::AlignCenter, pm);
2957 d->drawBackground(theme);
2962 if (sub & SC_TitleBarMinButton && tb->titleBarFlags & Qt::WindowMinimizeButtonHint
2963 && !(tb->titleBarState & Qt::WindowMinimized)) {
2964 populateTitleBarButtonTheme(proxy(), option, SC_TitleBarMinButton, isActive, WP_MINBUTTON, &theme);
2965 d->drawBackground(theme);
2967 if (sub & SC_TitleBarMaxButton && tb->titleBarFlags & Qt::WindowMaximizeButtonHint
2968 && !(tb->titleBarState & Qt::WindowMaximized)) {
2969 populateTitleBarButtonTheme(proxy(), option, SC_TitleBarMaxButton, isActive, WP_MAXBUTTON, &theme);
2970 d->drawBackground(theme);
2972 if (sub & SC_TitleBarContextHelpButton
2973 && tb->titleBarFlags & Qt::WindowContextHelpButtonHint) {
2974 populateTitleBarButtonTheme(proxy(), option, SC_TitleBarContextHelpButton, isActive, WP_HELPBUTTON, &theme);
2975 d->drawBackground(theme);
2977 bool drawNormalButton = (sub & SC_TitleBarNormalButton)
2978 && (((tb->titleBarFlags & Qt::WindowMinimizeButtonHint)
2979 && (tb->titleBarState & Qt::WindowMinimized))
2980 || ((tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
2981 && (tb->titleBarState & Qt::WindowMaximized)));
2982 if (drawNormalButton) {
2983 populateTitleBarButtonTheme(proxy(), option, SC_TitleBarNormalButton, isActive, WP_RESTOREBUTTON, &theme);
2984 d->drawBackground(theme);
2986 if (sub & SC_TitleBarShadeButton && tb->titleBarFlags & Qt::WindowShadeButtonHint
2987 && !(tb->titleBarState & Qt::WindowMinimized)) {
2988 populateTitleBarButtonTheme(proxy(), option, SC_TitleBarShadeButton, isActive, WP_MINBUTTON, &theme);
2989 d->drawBackground(theme);
2991 if (sub & SC_TitleBarUnshadeButton && tb->titleBarFlags & Qt::WindowShadeButtonHint
2992 && tb->titleBarState & Qt::WindowMinimized) {
2993 populateTitleBarButtonTheme(proxy(), option, SC_TitleBarUnshadeButton, isActive, WP_RESTOREBUTTON, &theme);
2994 d->drawBackground(theme);
2996 if (sub & SC_TitleBarCloseButton && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
2997 populateTitleBarButtonTheme(proxy(), option, SC_TitleBarCloseButton, isActive, WP_CLOSEBUTTON, &theme);
2998 d->drawBackground(theme);
3004#if 0
&& QT_CONFIG(mdiarea)
3005 case CC_MdiControls:
3007 XPThemeData theme(option->window, p, QWindowsXPStylePrivate::WindowTheme, WP_MDICLOSEBUTTON, CBS_NORMAL);
3008 if (Q_UNLIKELY(!theme.isValid()))
3011 if (option->subControls.testFlag(SC_MdiCloseButton)) {
3012 populateMdiButtonTheme(proxy(), option, SC_MdiCloseButton, WP_MDICLOSEBUTTON, &theme);
3013 d->drawBackground(theme, mdiButtonCorrectionFactor(theme));
3015 if (option->subControls.testFlag(SC_MdiNormalButton)) {
3016 populateMdiButtonTheme(proxy(), option, SC_MdiNormalButton, WP_MDIRESTOREBUTTON, &theme);
3017 d->drawBackground(theme, mdiButtonCorrectionFactor(theme));
3019 if (option->subControls.testFlag(QStyle::SC_MdiMinButton)) {
3020 populateMdiButtonTheme(proxy(), option, SC_MdiMinButton, WP_MDIMINBUTTON, &theme);
3021 d->drawBackground(theme, mdiButtonCorrectionFactor(theme));
3026#if 0
&& QT_CONFIG(dial)
3028 if (
const QStyleOptionSlider *dial = qstyleoption_cast<
const QStyleOptionSlider *>(option))
3029 QStyleHelper::drawDial(dial, p);
3033 QWindowsStyle::drawComplexControl(cc, option, p);
3220 SubControl subControl)
const
3222 if (!QWindowsXPStylePrivate::useXP())
3223 return QWindowsStyle::subControlRect(cc, option, subControl);
3229 rect = visualRect(option->direction, option->rect,
3230 QWindowsStyle::subControlRect(cc, option, subControl));
3231 if (subControl == QStyle::SC_GroupBoxContents) {
3234 rect.adjust(9, 9, -9, -9);
3238 if (
const QStyleOptionTitleBar *tb = qstyleoption_cast<
const QStyleOptionTitleBar *>(option)) {
3239 if (!buttonVisible(subControl, tb))
3241 const bool isToolTitle =
false;
3242 const int height = tb->rect.height();
3243 const int width = tb->rect.width();
3244 const int buttonMargin =
int(QStyleHelper::dpiScaled(4, option));
3245 const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(option);
3246 int buttonHeight = qRound(qreal(GetSystemMetrics(SM_CYSIZE)) * factor)
3248 int buttonWidth = qRound(qreal(GetSystemMetrics(SM_CXSIZE)) * factor)
3250 const int delta = buttonWidth + 2;
3251 int controlTop = option->rect.bottom() - buttonHeight - 2;
3252 const int frameWidth = proxy()->pixelMetric(PM_MdiSubWindowFrameWidth, option);
3253 const bool sysmenuHint = (tb->titleBarFlags & Qt::WindowSystemMenuHint) != 0;
3254 const bool minimizeHint = (tb->titleBarFlags & Qt::WindowMinimizeButtonHint) != 0;
3255 const bool maximizeHint = (tb->titleBarFlags & Qt::WindowMaximizeButtonHint) != 0;
3256 const bool contextHint = (tb->titleBarFlags & Qt::WindowContextHelpButtonHint) != 0;
3257 const bool shadeHint = (tb->titleBarFlags & Qt::WindowShadeButtonHint) != 0;
3258 bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
3259 bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
3262 switch (subControl) {
3263 case SC_TitleBarLabel:
3264 rect = QRect(frameWidth, 0, width - (buttonWidth + frameWidth + 10), height);
3267 rect.adjust(0, 0, -buttonWidth - 3, 0);
3269 if (minimizeHint || maximizeHint)
3270 rect.adjust(0, 0, -buttonWidth - 2, 0);
3273 const int leftOffset = height - 8;
3274 rect.adjust(leftOffset, 0, 0, 0);
3277 rect.adjust(0, 0, -buttonWidth - 2, 0);
3279 rect.adjust(0, 0, -buttonWidth - 2, 0);
3281 rect.adjust(0, 0, -buttonWidth - 2, 0);
3283 rect.adjust(0, 0, -buttonWidth - 2, 0);
3287 case SC_TitleBarContextHelpButton:
3288 if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
3291 case SC_TitleBarMinButton:
3292 if (!isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
3294 else if (subControl == SC_TitleBarMinButton)
3297 case SC_TitleBarNormalButton:
3298 if (isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
3300 else if (isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
3302 else if (subControl == SC_TitleBarNormalButton)
3305 case SC_TitleBarMaxButton:
3306 if (!isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
3308 else if (subControl == SC_TitleBarMaxButton)
3311 case SC_TitleBarShadeButton:
3312 if (!isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
3314 else if (subControl == SC_TitleBarShadeButton)
3317 case SC_TitleBarUnshadeButton:
3318 if (isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
3320 else if (subControl == SC_TitleBarUnshadeButton)
3323 case SC_TitleBarCloseButton:
3324 if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
3326 else if (subControl == SC_TitleBarCloseButton)
3329 rect.setRect(width - offset - controlTop + 1, controlTop,
3330 buttonWidth, buttonHeight);
3333 case SC_TitleBarSysMenu:
3335 const int controlTop = 6;
3336 const int controlHeight = height - controlTop - 3;
3337 const int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, option);
3338 QSize iconSize = tb->icon.actualSize(QSize(iconExtent, iconExtent));
3339 if (tb->icon.isNull())
3340 iconSize = QSize(controlHeight, controlHeight);
3341 int hPad = (controlHeight - iconSize.height())/2;
3342 int vPad = (controlHeight - iconSize.width())/2;
3343 rect = QRect(frameWidth + hPad, controlTop + vPad, iconSize.width(), iconSize.height());
3352 if (
const QStyleOptionComboBox *cmb = qstyleoption_cast<
const QStyleOptionComboBox *>(option)) {
3353 const int x = cmb->rect.x(), y = cmb->rect.y(), wi = cmb->rect.width(), he = cmb->rect.height();
3354 const int xpos = x + wi - qRound(QStyleHelper::dpiScaled(1 + 16, option));
3356 switch (subControl) {
3357 case SC_ComboBoxFrame:
3361 case SC_ComboBoxArrow: {
3362 const qreal dpi = QStyleHelper::dpi(option);
3363 rect = QRect(xpos, y + qRound(QStyleHelper::dpiScaled(1, dpi)),
3364 qRound(QStyleHelper::dpiScaled(16, dpi)),
3365 he - qRound(QStyleHelper::dpiScaled(2, dpi)));
3369 case SC_ComboBoxEditField: {
3370 const qreal dpi = QStyleHelper::dpi(option);
3371 const int frame = qRound(QStyleHelper::dpiScaled(2, dpi));
3372 rect = QRect(x + frame, y + frame,
3373 wi - qRound(QStyleHelper::dpiScaled(3 + 16, dpi)),
3374 he - qRound(QStyleHelper::dpiScaled(4, dpi)));
3378 case SC_ComboBoxListBoxPopup:
3387#if 0
&& QT_CONFIG(mdiarea)
3388 case CC_MdiControls:
3390 int numSubControls = 0;
3391 if (option->subControls & SC_MdiCloseButton)
3393 if (option->subControls & SC_MdiMinButton)
3395 if (option->subControls & SC_MdiNormalButton)
3397 if (numSubControls == 0)
3400 int buttonWidth = option->rect.width() / numSubControls;
3402 switch (subControl) {
3403 case SC_MdiCloseButton:
3405 if (numSubControls == 1)
3407 offset += buttonWidth;
3409 case SC_MdiNormalButton:
3413 if (numSubControls == 1 || (numSubControls == 2 && !(option->subControls & SC_MdiMinButton)))
3415 if (option->subControls & SC_MdiNormalButton)
3416 offset += buttonWidth;
3421 rect = QRect(offset, 0, buttonWidth, option->rect.height());
3427 rect = visualRect(option->direction, option->rect,
3428 QWindowsStyle::subControlRect(cc, option, subControl));
3431 return visualRect(option->direction, option->rect, rect);
3717 const QStyleOption *option)
const
3720 return QWindowsStyle::standardIcon(standardIcon, option);
3723 QWindowsXPStylePrivate *d =
const_cast<QWindowsXPStylePrivate*>(d_func());
3724 switch (standardIcon) {
3725 case SP_TitleBarMaxButton:
3726 if (qstyleoption_cast<
const QStyleOptionDockWidget *>(option))
3728 if (d->dockFloat.isNull()) {
3729 XPThemeData themeSize(
nullptr,
nullptr, QWindowsXPStylePrivate::WindowTheme,
3730 WP_SMALLCLOSEBUTTON, CBS_NORMAL);
3731 XPThemeData theme(
nullptr,
nullptr, QWindowsXPStylePrivate::WindowTheme,
3732 WP_MAXBUTTON, MAXBS_NORMAL);
3733 if (theme.isValid()) {
3734 const QSize size = (themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(option)).toSize();
3736 pm.fill(Qt::transparent);
3739 theme.rect = QRect(QPoint(0, 0), size);
3740 d->drawBackground(theme);
3741 d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::Off);
3742 pm.fill(Qt::transparent);
3743 theme.stateId = MAXBS_PUSHED;
3744 d->drawBackground(theme);
3745 d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::On);
3746 pm.fill(Qt::transparent);
3747 theme.stateId = MAXBS_HOT;
3748 d->drawBackground(theme);
3749 d->dockFloat.addPixmap(pm, QIcon::Active, QIcon::Off);
3750 pm.fill(Qt::transparent);
3751 theme.stateId = MAXBS_INACTIVE;
3752 d->drawBackground(theme);
3753 d->dockFloat.addPixmap(pm, QIcon::Disabled, QIcon::Off);
3756 if (widget && widget->isWindow())
3757 return d->dockFloat;
3761 case SP_TitleBarCloseButton:
3762 if (qstyleoption_cast<
const QStyleOptionDockWidget *>(option))
3764 if (d->dockClose.isNull()) {
3765 XPThemeData theme(
nullptr,
nullptr, QWindowsXPStylePrivate::WindowTheme,
3766 WP_SMALLCLOSEBUTTON, CBS_NORMAL);
3767 if (theme.isValid()) {
3768 const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(option)).toSize();
3770 pm.fill(Qt::transparent);
3773 theme.partId = WP_CLOSEBUTTON;
3774 theme.rect = QRect(QPoint(0, 0), size);
3775 d->drawBackground(theme);
3776 d->dockClose.addPixmap(pm, QIcon::Normal, QIcon::Off);
3777 pm.fill(Qt::transparent);
3778 theme.stateId = CBS_PUSHED;
3779 d->drawBackground(theme);
3780 d->dockClose.addPixmap(pm, QIcon::Normal, QIcon::On);
3781 pm.fill(Qt::transparent);
3782 theme.stateId = CBS_HOT;
3783 d->drawBackground(theme);
3784 d->dockClose.addPixmap(pm, QIcon::Active, QIcon::Off);
3785 pm.fill(Qt::transparent);
3786 theme.stateId = CBS_INACTIVE;
3787 d->drawBackground(theme);
3788 d->dockClose.addPixmap(pm, QIcon::Disabled, QIcon::Off);
3791 if (widget && widget->isWindow())
3792 return d->dockClose;
3795 case SP_TitleBarNormalButton:
3796 if (qstyleoption_cast<
const QStyleOptionDockWidget *>(option))
3798 if (d->dockFloat.isNull()) {
3799 XPThemeData themeSize(
nullptr,
nullptr, QWindowsXPStylePrivate::WindowTheme,
3800 WP_SMALLCLOSEBUTTON, CBS_NORMAL);
3801 XPThemeData theme(
nullptr,
nullptr, QWindowsXPStylePrivate::WindowTheme,
3802 WP_RESTOREBUTTON, RBS_NORMAL);
3803 if (theme.isValid()) {
3804 const QSize size = (themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(option)).toSize();
3806 pm.fill(Qt::transparent);
3809 theme.rect = QRect(QPoint(0, 0), size);
3810 d->drawBackground(theme);
3811 d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::Off);
3812 pm.fill(Qt::transparent);
3813 theme.stateId = RBS_PUSHED;
3814 d->drawBackground(theme);
3815 d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::On);
3816 pm.fill(Qt::transparent);
3817 theme.stateId = RBS_HOT;
3818 d->drawBackground(theme);
3819 d->dockFloat.addPixmap(pm, QIcon::Active, QIcon::Off);
3820 pm.fill(Qt::transparent);
3821 theme.stateId = RBS_INACTIVE;
3822 d->drawBackground(theme);
3823 d->dockFloat.addPixmap(pm, QIcon::Disabled, QIcon::Off);
3826 if (widget && widget->isWindow())
3827 return d->dockFloat;
3835 return QWindowsStyle::standardIcon(standardIcon, option);