Qt 4.8
qmacstyle_mac.mm
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 /*
43  Note: The qdoc comments for QMacStyle are contained in
44  .../doc/src/qstyles.qdoc.
45 */
46 
47 #include "qmacstyle_mac.h"
48 
49 #if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
50 #define QMAC_QAQUASTYLE_SIZE_CONSTRAIN
51 //#define DEBUG_SIZE_CONSTRAINT
52 
53 #include <private/qapplication_p.h>
54 #include <private/qcombobox_p.h>
55 #include <private/qmacstylepixmaps_mac_p.h>
56 #include <private/qpaintengine_mac_p.h>
57 #include <private/qpainter_p.h>
58 #include <private/qprintengine_mac_p.h>
59 #include <qapplication.h>
60 #include <qbitmap.h>
61 #include <qcheckbox.h>
62 #include <qcombobox.h>
63 #include <qdialogbuttonbox.h>
64 #include <qdockwidget.h>
65 #include <qevent.h>
66 #include <qfocusframe.h>
67 #include <qformlayout.h>
68 #include <qgroupbox.h>
69 #include <qhash.h>
70 #include <qheaderview.h>
71 #include <qlayout.h>
72 #include <qlineedit.h>
73 #include <qlistview.h>
74 #include <qmainwindow.h>
75 #include <qmap.h>
76 #include <qmenubar.h>
77 #include <qpaintdevice.h>
78 #include <qpainter.h>
79 #include <qpixmapcache.h>
80 #include <qpointer.h>
81 #include <qprogressbar.h>
82 #include <qpushbutton.h>
83 #include <qradiobutton.h>
84 #include <qrubberband.h>
85 #include <qsizegrip.h>
86 #include <qspinbox.h>
87 #include <qsplitter.h>
88 #include <qstyleoption.h>
89 #include <qtextedit.h>
90 #include <qtextstream.h>
91 #include <qtoolbar.h>
92 #include <qtoolbutton.h>
93 #include <qtreeview.h>
94 #include <qtableview.h>
95 #include <qwizard.h>
96 #include <qdebug.h>
97 #include <qlibrary.h>
98 #include <qdatetimeedit.h>
99 #include <qmath.h>
100 #include <QtGui/qgraphicsproxywidget.h>
101 #include <QtGui/qgraphicsview.h>
102 #include <private/qt_cocoa_helpers_mac_p.h>
103 #include "qmacstyle_mac_p.h"
104 #include <private/qstylehelper_p.h>
105 
107 
108 // The following constants are used for adjusting the size
109 // of push buttons so that they are drawn inside their bounds.
114 const int QMacStylePrivate::MiniButtonH = 26;
115 const int QMacStylePrivate::SmallButtonH = 30;
116 const int QMacStylePrivate::BevelButtonW = 50;
117 const int QMacStylePrivate::BevelButtonH = 22;
119 
120 // These colors specify the titlebar gradient colors on
121 // Leopard. Ideally we should get them from the system.
122 static const QColor titlebarGradientActiveBegin(220, 220, 220);
123 static const QColor titlebarGradientActiveEnd(151, 151, 151);
124 static const QColor titlebarSeparatorLineActive(111, 111, 111);
125 static const QColor titlebarGradientInactiveBegin(241, 241, 241);
126 static const QColor titlebarGradientInactiveEnd(207, 207, 207);
127 static const QColor titlebarSeparatorLineInactive(131, 131, 131);
128 
129 // Gradient colors used for the dock widget title bar and
130 // non-unifed tool bar bacground.
131 static const QColor mainWindowGradientBegin(240, 240, 240);
132 static const QColor mainWindowGradientEnd(200, 200, 200);
133 
134 static const int DisclosureOffset = 4;
135 
136 // Resolve these at run-time, since the functions was moved in Leopard.
137 typedef HIRect * (*PtrHIShapeGetBounds)(HIShapeRef, HIRect *);
139 
140 static int closeButtonSize = 12;
141 
142 extern QRegion qt_mac_convert_mac_region(RgnHandle); //qregion_mac.cpp
143 
144 static bool isVerticalTabs(const QTabBar::Shape shape) {
145  return (shape == QTabBar::RoundedEast
146  || shape == QTabBar::TriangularEast
147  || shape == QTabBar::RoundedWest
148  || shape == QTabBar::TriangularWest);
149 }
150 
151 void drawTabCloseButton(QPainter *p, bool hover, bool active, bool selected)
152 {
153  // draw background circle
156  QColor background;
157  if (hover) {
158  background = QColor(124, 124, 124);
159  } else {
160  if (active) {
161  if (selected)
162  background = QColor(104, 104, 104);
163  else
164  background = QColor(83, 83, 83);
165  } else {
166  if (selected)
167  background = QColor(144, 144, 144);
168  else
169  background = QColor(114, 114, 114);
170  }
171  }
173  p->setBrush(background);
174  p->drawEllipse(rect);
175 
176  // draw cross
177  int min = 3;
178  int max = 9;
179  QPen crossPen;
180  crossPen.setColor(QColor(194, 194, 194));
181  crossPen.setWidthF(1.3);
182  crossPen.setCapStyle(Qt::FlatCap);
183  p->setPen(crossPen);
184  p->drawLine(min, min, max, max);
185  p->drawLine(min, max, max, min);
186 }
187 
189 {
190  if (isVerticalTabs(shape)) {
191  int newX, newY, newRot;
192  if (shape == QTabBar::RoundedEast
193  || shape == QTabBar::TriangularEast) {
194  newX = tabRect.width();
195  newY = tabRect.y();
196  newRot = 90;
197  } else {
198  newX = 0;
199  newY = tabRect.y() + tabRect.height();
200  newRot = -90;
201  }
202  tabRect.setRect(0, 0, tabRect.height(), tabRect.width());
203  QMatrix m;
204  m.translate(newX, newY);
205  m.rotate(newRot);
206  p->setMatrix(m, true);
207  }
208  return tabRect;
209 }
210 
211 void drawTabShape(QPainter *p, const QStyleOptionTabV3 *tabOpt)
212 {
213  QRect r = tabOpt->rect;
214  p->translate(tabOpt->rect.x(), tabOpt->rect.y());
215  r.moveLeft(0);
216  r.moveTop(0);
217  QRect tabRect = rotateTabPainter(p, tabOpt->shape, r);
218 
219  int width = tabRect.width();
220  int height = 20;
221  bool active = (tabOpt->state & QStyle::State_Active);
222  bool selected = (tabOpt->state & QStyle::State_Selected);
223 
224  if (selected) {
225  QRect rect(1, 0, width - 2, height);
226 
227  // fill body
228  if (active) {
229  int d = (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) ? 16 : 0;
230  p->fillRect(rect, QColor(151 + d, 151 + d, 151 + d));
231  } else {
233  QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
234  gradient.setColorAt(0, QColor(207 + d, 207 + d, 207 + d));
235  gradient.setColorAt(0.5, QColor(206 + d, 206 + d, 206 + d));
236  gradient.setColorAt(1, QColor(201 + d, 201 + d, 201 + d));
237  p->fillRect(rect, gradient);
238  }
239 
240  // draw border
241  QColor borderSides;
242  QColor borderBottom;
243  if (active) {
244  borderSides = QColor(88, 88, 88);
245  borderBottom = QColor(88, 88, 88);
246  } else {
247  borderSides = QColor(121, 121, 121);
248  borderBottom = QColor(116, 116, 116);
249  }
250 
251  p->setPen(borderSides);
252 
253  int bottom = height;
254  // left line
255  p->drawLine(0, 1, 0, bottom-2);
256  // right line
257  p->drawLine(width-1, 1, width-1, bottom-2);
258 
259  // bottom line
260  if (active) {
261  p->setPen(QColor(168, 168, 168));
262  p->drawLine(3, bottom-1, width-3, bottom-1);
263  }
264  p->setPen(borderBottom);
265  p->drawLine(2, bottom, width-2, bottom);
266 
267  int w = 3;
268  QRectF rectangleLeft(1, height - w, w, w);
269  QRectF rectangleRight(width - 2, height - 1, w, w);
270  int startAngle = 180 * 16;
271  int spanAngle = 90 * 16;
273  p->drawArc(rectangleLeft, startAngle, spanAngle);
274  p->drawArc(rectangleRight, startAngle, -spanAngle);
275  } else {
276  // when the mouse is over non selected tabs they get a new color
277  bool hover = (tabOpt->state & QStyle::State_MouseOver);
278  if (hover) {
279  QRect rect(1, 2, width - 1, height - 1);
280  p->fillRect(rect, QColor(110, 110, 110));
281  }
282 
283  // seperator lines between tabs
284  bool west = (tabOpt->shape == QTabBar::RoundedWest || tabOpt->shape == QTabBar::TriangularWest);
285  bool drawOnRight = !west;
286  if ((!drawOnRight && tabOpt->selectedPosition != QStyleOptionTab::NextIsSelected)
287  || (drawOnRight && tabOpt->selectedPosition != QStyleOptionTab::NextIsSelected)) {
288  QColor borderColor;
289  QColor borderHighlightColor;
290  if (active) {
291  borderColor = QColor(64, 64, 64);
292  borderHighlightColor = QColor(140, 140, 140);
293  } else {
294  borderColor = QColor(135, 135, 135);
295  borderHighlightColor = QColor(178, 178, 178);
296  }
297 
298  int x = drawOnRight ? width : 0;
299 
300  // tab seperator line
301  p->setPen(borderColor);
302  p->drawLine(x, 2, x, height + 1);
303 
304  // tab seperator highlight
305  p->setPen(borderHighlightColor);
306  p->drawLine(x-1, 2, x-1, height + 1);
307  p->drawLine(x+1, 2, x+1, height + 1);
308  }
309  }
310 }
311 
312 void drawTabBase(QPainter *p, const QStyleOptionTabBarBaseV2 *tbb, const QWidget *w)
313 {
314  QRect r = tbb->rect;
315  if (isVerticalTabs(tbb->shape)) {
316  r.setWidth(w->width());
317  } else {
318  r.setHeight(w->height());
319  }
320  QRect tabRect = rotateTabPainter(p, tbb->shape, r);
321  int width = tabRect.width();
322  int height = tabRect.height();
323  bool active = (tbb->state & QStyle::State_Active);
324 
325  // top border lines
326  QColor borderHighlightTop;
327  QColor borderTop;
328  if (active) {
329  borderTop = QColor(64, 64, 64);
330  borderHighlightTop = QColor(174, 174, 174);
331  } else {
332  borderTop = QColor(135, 135, 135);
333  borderHighlightTop = QColor(207, 207, 207);
334  }
335  p->setPen(borderHighlightTop);
336  p->drawLine(tabRect.x(), 0, width, 0);
337  p->setPen(borderTop);
338  p->drawLine(tabRect.x(), 1, width, 1);
339 
340  // center block
341  QRect centralRect(tabRect.x(), 2, width, height - 2);
342  if (active) {
343  QColor mainColor = QColor(120, 120, 120);
344  p->fillRect(centralRect, mainColor);
345  } else {
346  QLinearGradient gradient(centralRect.topLeft(), centralRect.bottomLeft());
347  gradient.setColorAt(0, QColor(165, 165, 165));
348  gradient.setColorAt(0.5, QColor(164, 164, 164));
349  gradient.setColorAt(1, QColor(158, 158, 158));
350  p->fillRect(centralRect, gradient);
351  }
352 
353  // bottom border lines
354  QColor borderHighlightBottom;
355  QColor borderBottom;
356  if (active) {
357  borderHighlightBottom = QColor(153, 153, 153);
358  borderBottom = QColor(64, 64, 64);
359  } else {
360  borderHighlightBottom = QColor(177, 177, 177);
361  borderBottom = QColor(127, 127, 127);
362  }
363  p->setPen(borderHighlightBottom);
364  p->drawLine(tabRect.x(), height - 2, width, height - 2);
365  p->setPen(borderBottom);
366  p->drawLine(tabRect.x(), height - 1, width, height - 1);
367 }
368 
369 static int getControlSize(const QStyleOption *option, const QWidget *widget)
370 {
371  if (option) {
372  if (option->state & (QStyle::State_Small | QStyle::State_Mini))
373  return (option->state & QStyle::State_Mini) ? QAquaSizeMini : QAquaSizeSmall;
374  } else if (widget) {
375  switch (QMacStyle::widgetSizePolicy(widget)) {
377  return QAquaSizeSmall;
378  case QMacStyle::SizeMini:
379  return QAquaSizeMini;
380  default:
381  break;
382  }
383  }
384  return QAquaSizeLarge;
385 }
386 
387 
388 static inline bool isTreeView(const QWidget *widget)
389 {
390  return (widget && widget->parentWidget() &&
391  (qobject_cast<const QTreeView *>(widget->parentWidget())
392 #ifdef QT3_SUPPORT
393  || widget->parentWidget()->inherits("Q3ListView")
394 #endif
395  ));
396 }
397 
399 {
400  QString returnText(original.size(), 0);
401  int finalDest = 0;
402  int currPos = 0;
403  int l = original.length();
404  while (l) {
405  if (original.at(currPos) == QLatin1Char('&')
406  && (l == 1 || original.at(currPos + 1) != QLatin1Char('&'))) {
407  ++currPos;
408  --l;
409  if (l == 0)
410  break;
411  }
412  returnText[finalDest] = original.at(currPos);
413  ++currPos;
414  ++finalDest;
415  --l;
416  }
417  returnText.truncate(finalDest);
418  return returnText;
419 }
420 
421 static inline ThemeTabDirection getTabDirection(QTabBar::Shape shape)
422 {
423  ThemeTabDirection ttd;
424  switch (shape) {
427  ttd = kThemeTabSouth;
428  break;
429  default: // Added to remove the warning, since all values are taken care of, really!
432  ttd = kThemeTabNorth;
433  break;
436  ttd = kThemeTabWest;
437  break;
440  ttd = kThemeTabEast;
441  break;
442  }
443  return ttd;
444 }
445 
447 #include "moc_qmacstyle_mac.cpp"
448 #include "moc_qmacstyle_mac_p.cpp"
450 
451 /*****************************************************************************
452  External functions
453  *****************************************************************************/
454 extern CGContextRef qt_mac_cg_context(const QPaintDevice *); //qpaintdevice_mac.cpp
455 extern QRegion qt_mac_convert_mac_region(HIShapeRef); //qregion_mac.cpp
456 void qt_mac_dispose_rgn(RgnHandle r); //qregion_mac.cpp
457 extern QPaintDevice *qt_mac_safe_pdev; //qapplication_mac.cpp
458 
459 /*****************************************************************************
460  QMacCGStyle globals
461  *****************************************************************************/
462 const int qt_mac_hitheme_version = 0; //the HITheme version we speak
463 const int macItemFrame = 2; // menu item frame width
464 const int macItemHMargin = 3; // menu item hor text margin
465 const int macItemVMargin = 2; // menu item ver text margin
466 const int macRightBorder = 12; // right border on mac
467 const ThemeWindowType QtWinType = kThemeDocumentWindow; // Window type we use for QTitleBar.
468 QPixmap *qt_mac_backgroundPattern = 0; // stores the standard widget background.
469 
470 /*****************************************************************************
471  QMacCGStyle utility functions
472  *****************************************************************************/
473 static inline int qt_mac_hitheme_tab_version()
474 {
475  return 1;
476 }
477 
478 static inline HIRect qt_hirectForQRect(const QRect &convertRect, const QRect &rect = QRect())
479 {
480  return CGRectMake(convertRect.x() + rect.x(), convertRect.y() + rect.y(),
481  convertRect.width() - rect.width(), convertRect.height() - rect.height());
482 }
483 
484 static inline const QRect qt_qrectForHIRect(const HIRect &hirect)
485 {
486  return QRect(QPoint(int(hirect.origin.x), int(hirect.origin.y)),
487  QSize(int(hirect.size.width), int(hirect.size.height)));
488 }
489 
490 inline bool qt_mac_is_metal(const QWidget *w)
491 {
492  for (; w; w = w->parentWidget()) {
494  return true;
495  if (w->isWindow() && w->testAttribute(Qt::WA_WState_Created)) { // If not created will fall through to the opaque check and be fine anyway.
497  }
498  if (w->d_func()->isOpaque)
499  break;
500  }
501  return false;
502 }
503 
504 static int qt_mac_aqua_get_metric(ThemeMetric met)
505 {
506  SInt32 ret;
507  GetThemeMetric(met, &ret);
508  return ret;
509 }
510 
512  QAquaWidgetSize sz)
513 {
514  QSize ret(-1, -1);
515  if (sz != QAquaSizeSmall && sz != QAquaSizeLarge && sz != QAquaSizeMini) {
516  qDebug("Not sure how to return this...");
517  return ret;
518  }
520  // If you're using a custom font and it's bigger than the default font,
521  // then no constraints for you. If you are smaller, we can try to help you out
522  QFont font = qt_app_fonts_hash()->value(widg->metaObject()->className(), QFont());
523  if (widg->font().pointSize() > font.pointSize())
524  return ret;
525  }
526 
527  if (ct == QStyle::CT_CustomBase && widg) {
528  if (qobject_cast<const QPushButton *>(widg))
530  else if (qobject_cast<const QRadioButton *>(widg))
532  else if (qobject_cast<const QCheckBox *>(widg))
533  ct = QStyle::CT_CheckBox;
534  else if (qobject_cast<const QComboBox *>(widg))
535  ct = QStyle::CT_ComboBox;
536  else if (qobject_cast<const QToolButton *>(widg))
538  else if (qobject_cast<const QSlider *>(widg))
539  ct = QStyle::CT_Slider;
540  else if (qobject_cast<const QProgressBar *>(widg))
542  else if (qobject_cast<const QLineEdit *>(widg))
543  ct = QStyle::CT_LineEdit;
544  else if (qobject_cast<const QHeaderView *>(widg)
545 #ifdef QT3_SUPPORT
546  || widg->inherits("Q3Header")
547 #endif
548  )
550  else if (qobject_cast<const QMenuBar *>(widg)
551 #ifdef QT3_SUPPORT
552  || widg->inherits("Q3MenuBar")
553 #endif
554  )
555  ct = QStyle::CT_MenuBar;
556  else if (qobject_cast<const QSizeGrip *>(widg))
557  ct = QStyle::CT_SizeGrip;
558  else
559  return ret;
560  }
561 
562  switch (ct) {
563  case QStyle::CT_PushButton: {
564  const QPushButton *psh = qobject_cast<const QPushButton *>(widg);
565  // If this comparison is false, then the widget was not a push button.
566  // This is bad and there's very little we can do since we were requested to find a
567  // sensible size for a widget that pretends to be a QPushButton but is not.
568  if(psh) {
569  QString buttonText = qt_mac_removeMnemonics(psh->text());
570  if (buttonText.contains(QLatin1Char('\n')))
571  ret = QSize(-1, -1);
572  else if (sz == QAquaSizeLarge)
573  ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight));
574  else if (sz == QAquaSizeSmall)
575  ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight));
576  else if (sz == QAquaSizeMini)
577  ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight));
578 
579  if (!psh->icon().isNull()){
580  // If the button got an icon, and the icon is larger than the
581  // button, we can't decide on a default size
582  ret.setWidth(-1);
583  if (ret.height() < psh->iconSize().height())
584  ret.setHeight(-1);
585  }
586  else if (buttonText == QLatin1String("OK") || buttonText == QLatin1String("Cancel")){
587  // Aqua Style guidelines restrict the size of OK and Cancel buttons to 68 pixels.
588  // However, this doesn't work for German, therefore only do it for English,
589  // I suppose it would be better to do some sort of lookups for languages
590  // that like to have really long words.
591  ret.setWidth(77 - 8);
592  }
593  } else {
594  // The only sensible thing to do is to return whatever the style suggests...
595  if (sz == QAquaSizeLarge)
596  ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight));
597  else if (sz == QAquaSizeSmall)
598  ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight));
599  else if (sz == QAquaSizeMini)
600  ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight));
601  else
602  // Since there's no default size we return the large size...
603  ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight));
604  }
605 #if 0 //Not sure we are applying the rules correctly for RadioButtons/CheckBoxes --Sam
606  } else if (ct == QStyle::CT_RadioButton) {
607  QRadioButton *rdo = static_cast<QRadioButton *>(widg);
608  // Exception for case where multiline radio button text requires no size constrainment
609  if (rdo->text().find('\n') != -1)
610  return ret;
611  if (sz == QAquaSizeLarge)
612  ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricRadioButtonHeight));
613  else if (sz == QAquaSizeSmall)
614  ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallRadioButtonHeight));
615  else if (sz == QAquaSizeMini)
616  ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniRadioButtonHeight));
617  } else if (ct == QStyle::CT_CheckBox) {
618  if (sz == QAquaSizeLarge)
619  ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricCheckBoxHeight));
620  else if (sz == QAquaSizeSmall)
621  ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallCheckBoxHeight));
622  else if (sz == QAquaSizeMini)
623  ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniCheckBoxHeight));
624 #endif
625  break;
626  }
627  case QStyle::CT_SizeGrip:
628  if (sz == QAquaSizeLarge || sz == QAquaSizeSmall) {
629  HIRect r;
630  HIPoint p = { 0, 0 };
631  HIThemeGrowBoxDrawInfo gbi;
632  gbi.version = 0;
633  gbi.state = kThemeStateActive;
634  gbi.kind = kHIThemeGrowBoxKindNormal;
635  gbi.direction = QApplication::isRightToLeft() ? kThemeGrowLeft | kThemeGrowDown
636  : kThemeGrowRight | kThemeGrowDown;
637  gbi.size = sz == QAquaSizeSmall ? kHIThemeGrowBoxSizeSmall : kHIThemeGrowBoxSizeNormal;
638  if (HIThemeGetGrowBoxBounds(&p, &gbi, &r) == noErr)
639  ret = QSize(r.size.width, r.size.height);
640  }
641  break;
642  case QStyle::CT_ComboBox:
643  switch (sz) {
644  case QAquaSizeLarge:
645  ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPopupButtonHeight));
646  break;
647  case QAquaSizeSmall:
648  ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPopupButtonHeight));
649  break;
650  case QAquaSizeMini:
651  ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPopupButtonHeight));
652  break;
653  default:
654  break;
655  }
656  break;
658  if (sz == QAquaSizeSmall) {
659  int width = 0, height = 0;
660  if (szHint == QSize(-1, -1)) { //just 'guess'..
661  const QToolButton *bt = qobject_cast<const QToolButton *>(widg);
662  // If this conversion fails then the widget was not what it claimed to be.
663  if(bt) {
664  if (!bt->icon().isNull()) {
665  QSize iconSize = bt->iconSize();
666  QSize pmSize = bt->icon().actualSize(QSize(32, 32), QIcon::Normal);
667  width = qMax(width, qMax(iconSize.width(), pmSize.width()));
668  height = qMax(height, qMax(iconSize.height(), pmSize.height()));
669  }
670  if (!bt->text().isNull() && bt->toolButtonStyle() != Qt::ToolButtonIconOnly) {
671  int text_width = bt->fontMetrics().width(bt->text()),
672  text_height = bt->fontMetrics().height();
674  width = qMax(width, text_width);
675  height += text_height;
676  } else {
677  width += text_width;
678  width = qMax(height, text_height);
679  }
680  }
681  } else {
682  // Let's return the size hint...
683  width = szHint.width();
684  height = szHint.height();
685  }
686  } else {
687  width = szHint.width();
688  height = szHint.height();
689  }
690  width = qMax(20, width + 5); //border
691  height = qMax(20, height + 5); //border
692  ret = QSize(width, height);
693  }
694  break;
695  case QStyle::CT_Slider: {
696  int w = -1;
697  const QSlider *sld = qobject_cast<const QSlider *>(widg);
698  // If this conversion fails then the widget was not what it claimed to be.
699  if(sld) {
700  if (sz == QAquaSizeLarge) {
701  if (sld->orientation() == Qt::Horizontal) {
702  w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight);
703  if (sld->tickPosition() != QSlider::NoTicks)
704  w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight);
705  } else {
706  w = qt_mac_aqua_get_metric(kThemeMetricVSliderWidth);
707  if (sld->tickPosition() != QSlider::NoTicks)
708  w += qt_mac_aqua_get_metric(kThemeMetricVSliderTickWidth);
709  }
710  } else if (sz == QAquaSizeSmall) {
711  if (sld->orientation() == Qt::Horizontal) {
712  w = qt_mac_aqua_get_metric(kThemeMetricSmallHSliderHeight);
713  if (sld->tickPosition() != QSlider::NoTicks)
714  w += qt_mac_aqua_get_metric(kThemeMetricSmallHSliderTickHeight);
715  } else {
716  w = qt_mac_aqua_get_metric(kThemeMetricSmallVSliderWidth);
717  if (sld->tickPosition() != QSlider::NoTicks)
718  w += qt_mac_aqua_get_metric(kThemeMetricSmallVSliderTickWidth);
719  }
720  } else if (sz == QAquaSizeMini) {
721  if (sld->orientation() == Qt::Horizontal) {
722  w = qt_mac_aqua_get_metric(kThemeMetricMiniHSliderHeight);
723  if (sld->tickPosition() != QSlider::NoTicks)
724  w += qt_mac_aqua_get_metric(kThemeMetricMiniHSliderTickHeight);
725  } else {
726  w = qt_mac_aqua_get_metric(kThemeMetricMiniVSliderWidth);
727  if (sld->tickPosition() != QSlider::NoTicks)
728  w += qt_mac_aqua_get_metric(kThemeMetricMiniVSliderTickWidth);
729  }
730  }
731  } else {
732  // This is tricky, we were requested to find a size for a slider which is not
733  // a slider. We don't know if this is vertical or horizontal or if we need to
734  // have tick marks or not.
735  // For this case we will return an horizontal slider without tick marks.
736  w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight);
737  w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight);
738  }
739  if (sld->orientation() == Qt::Horizontal)
740  ret.setHeight(w);
741  else
742  ret.setWidth(w);
743  break;
744  }
745  case QStyle::CT_ProgressBar: {
746  int finalValue = -1;
748  if (const QProgressBar *pb = qobject_cast<const QProgressBar *>(widg))
749  orient = pb->orientation();
750 
751  if (sz == QAquaSizeLarge)
752  finalValue = qt_mac_aqua_get_metric(kThemeMetricLargeProgressBarThickness)
753  + qt_mac_aqua_get_metric(kThemeMetricProgressBarShadowOutset);
754  else
755  finalValue = qt_mac_aqua_get_metric(kThemeMetricNormalProgressBarThickness)
756  + qt_mac_aqua_get_metric(kThemeMetricSmallProgressBarShadowOutset);
757  if (orient == Qt::Horizontal)
758  ret.setHeight(finalValue);
759  else
760  ret.setWidth(finalValue);
761  break;
762  }
763  case QStyle::CT_LineEdit:
764  if (!widg || !qobject_cast<QComboBox *>(widg->parentWidget())) {
765  //should I take into account the font dimentions of the lineedit? -Sam
766  if (sz == QAquaSizeLarge)
767  ret = QSize(-1, 21);
768  else
769  ret = QSize(-1, 19);
770  }
771  break;
773  if (isTreeView(widg))
774  ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricListHeaderHeight));
775  break;
776  case QStyle::CT_MenuBar:
777  if (sz == QAquaSizeLarge) {
778 #ifndef QT_MAC_USE_COCOA
779  SInt16 size;
780  if (!GetThemeMenuBarHeight(&size))
781  ret = QSize(-1, size);
782 #else
783  ret = QSize(-1, [[NSApp mainMenu] menuBarHeight]);
784  // In the qt_mac_set_native_menubar(false) case,
785  // we come it here with a zero-height main menu,
786  // preventing the in-window menu from displaying.
787  // Use 22 pixels for the height, by observation.
788  if (ret.height() <= 0)
789  ret.setHeight(22);
790 #endif
791  }
792  break;
793  default:
794  break;
795  }
796  return ret;
797 }
798 
799 
800 #if defined(QMAC_QAQUASTYLE_SIZE_CONSTRAIN) || defined(DEBUG_SIZE_CONSTRAINT)
801 static QAquaWidgetSize qt_aqua_guess_size(const QWidget *widg, QSize large, QSize small, QSize mini)
802 {
803  if (large == QSize(-1, -1)) {
804  if (small != QSize(-1, -1))
805  return QAquaSizeSmall;
806  if (mini != QSize(-1, -1))
807  return QAquaSizeMini;
808  return QAquaSizeUnknown;
809  } else if (small == QSize(-1, -1)) {
810  if (mini != QSize(-1, -1))
811  return QAquaSizeMini;
812  return QAquaSizeLarge;
813  } else if (mini == QSize(-1, -1)) {
814  return QAquaSizeLarge;
815  }
816 
817 #ifndef QT_NO_MAINWINDOW
818  if (qobject_cast<QDockWidget *>(widg->window()) || !qgetenv("QWIDGET_ALL_SMALL").isNull()) {
819  //if (small.width() != -1 || small.height() != -1)
820  return QAquaSizeSmall;
821  } else if (!qgetenv("QWIDGET_ALL_MINI").isNull()) {
822  return QAquaSizeMini;
823  }
824 #endif
825 
826 #if 0
827  /* Figure out which size we're closer to, I just hacked this in, I haven't
828  tested it as it would probably look pretty strange to have some widgets
829  big and some widgets small in the same window?? -Sam */
830  int large_delta=0;
831  if (large.width() != -1) {
832  int delta = large.width() - widg->width();
833  large_delta += delta * delta;
834  }
835  if (large.height() != -1) {
836  int delta = large.height() - widg->height();
837  large_delta += delta * delta;
838  }
839  int small_delta=0;
840  if (small.width() != -1) {
841  int delta = small.width() - widg->width();
842  small_delta += delta * delta;
843  }
844  if (small.height() != -1) {
845  int delta = small.height() - widg->height();
846  small_delta += delta * delta;
847  }
848  int mini_delta=0;
849  if (mini.width() != -1) {
850  int delta = mini.width() - widg->width();
851  mini_delta += delta * delta;
852  }
853  if (mini.height() != -1) {
854  int delta = mini.height() - widg->height();
855  mini_delta += delta * delta;
856  }
857  if (mini_delta < small_delta && mini_delta < large_delta)
858  return QAquaSizeMini;
859  else if (small_delta < large_delta)
860  return QAquaSizeSmall;
861 #endif
862  return QAquaSizeLarge;
863 }
864 #endif
865 
867  QStyle::ContentsType ct, QSize szHint, QSize *insz) const
868 {
869 #if defined(QMAC_QAQUASTYLE_SIZE_CONSTRAIN) || defined(DEBUG_SIZE_CONSTRAINT)
870  if (option) {
871  if (option->state & QStyle::State_Small)
872  return QAquaSizeSmall;
873  if (option->state & QStyle::State_Mini)
874  return QAquaSizeMini;
875  }
876 
877  if (!widg) {
878  if (insz)
879  *insz = QSize();
880  if (!qgetenv("QWIDGET_ALL_SMALL").isNull())
881  return QAquaSizeSmall;
882  if (!qgetenv("QWIDGET_ALL_MINI").isNull())
883  return QAquaSizeMini;
884  return QAquaSizeUnknown;
885  }
886  QSize large = qt_aqua_get_known_size(ct, widg, szHint, QAquaSizeLarge),
887  small = qt_aqua_get_known_size(ct, widg, szHint, QAquaSizeSmall),
888  mini = qt_aqua_get_known_size(ct, widg, szHint, QAquaSizeMini);
889  bool guess_size = false;
892  if (wsp == QMacStyle::SizeDefault)
893  guess_size = true;
894  else if (wsp == QMacStyle::SizeMini)
895  ret = QAquaSizeMini;
896  else if (wsp == QMacStyle::SizeSmall)
897  ret = QAquaSizeSmall;
898  else if (wsp == QMacStyle::SizeLarge)
899  ret = QAquaSizeLarge;
900  if (guess_size)
901  ret = qt_aqua_guess_size(widg, large, small, mini);
902 
903  QSize *sz = 0;
904  if (ret == QAquaSizeSmall)
905  sz = &small;
906  else if (ret == QAquaSizeLarge)
907  sz = &large;
908  else if (ret == QAquaSizeMini)
909  sz = &mini;
910  if (insz)
911  *insz = sz ? *sz : QSize(-1, -1);
912 #ifdef DEBUG_SIZE_CONSTRAINT
913  if (sz) {
914  const char *size_desc = "Unknown";
915  if (sz == &small)
916  size_desc = "Small";
917  else if (sz == &large)
918  size_desc = "Large";
919  else if (sz == &mini)
920  size_desc = "Mini";
921  qDebug("%s - %s: %s taken (%d, %d) [%d, %d]",
922  widg ? widg->objectName().toLatin1().constData() : "*Unknown*",
923  widg ? widg->metaObject()->className() : "*Unknown*", size_desc, widg->width(), widg->height(),
924  sz->width(), sz->height());
925  }
926 #endif
927  return ret;
928 #else
929  if (insz)
930  *insz = QSize();
931  Q_UNUSED(widg);
932  Q_UNUSED(ct);
933  Q_UNUSED(szHint);
934  return QAquaSizeUnknown;
935 #endif
936 }
937 
943  const HIThemeButtonDrawInfo *bdi) const
944 {
945  HIRect outerBounds = qt_hirectForQRect(btn->rect);
946  // Adjust the bounds to correct for
947  // carbon not calculating the content bounds fully correct
948  if (bdi->kind == kThemePushButton || bdi->kind == kThemePushButtonSmall){
949  outerBounds.origin.y += QMacStylePrivate::PushButtonTopOffset;
950  outerBounds.size.height -= QMacStylePrivate::PushButtonBottomOffset;
951  } else if (bdi->kind == kThemePushButtonMini) {
952  outerBounds.origin.y += QMacStylePrivate::PushButtonTopOffset;
953  }
954 
955  HIRect contentBounds;
956  HIThemeGetButtonContentBounds(&outerBounds, bdi, &contentBounds);
957  return contentBounds;
958 }
959 
965 {
966  QSize csz(0, 0);
967  QSize iconSize = btn->icon.isNull() ? QSize(0, 0)
969  QRect textRect = btn->text.isEmpty() ? QRect(0, 0, 1, 1)
971  csz.setWidth(iconSize.width() + textRect.width()
973  ? q->proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator, btn, 0) : 0));
974  csz.setHeight(qMax(iconSize.height(), textRect.height()));
975  return csz;
976 }
977 
984  HIThemeButtonDrawInfo *bdi,
985  ThemeButtonKind buttonKindToCheck) const
986 {
987  ThemeButtonKind tmp = bdi->kind;
988  bdi->kind = buttonKindToCheck;
989  QSize contentSize = pushButtonSizeFromContents(btn);
990  QRect freeContentRect = qt_qrectForHIRect(pushButtonContentBounds(btn, bdi));
991  bdi->kind = tmp;
992  return freeContentRect.contains(QRect(freeContentRect.x(), freeContentRect.y(),
993  contentSize.width(), contentSize.height()));
994 }
995 
1003  const QWidget *widget,
1004  const ThemeDrawState tds,
1005  HIThemeButtonDrawInfo *bdi) const
1006 {
1007  bool drawColorless = btn->palette.currentColorGroup() == QPalette::Active;
1008  ThemeDrawState tdsModified = tds;
1009  if (btn->state & QStyle::State_On)
1010  tdsModified = kThemeStatePressed;
1011  bdi->version = qt_mac_hitheme_version;
1012  bdi->state = tdsModified;
1013  bdi->value = kThemeButtonOff;
1014 
1015  if (drawColorless && tdsModified == kThemeStateInactive)
1016  bdi->state = kThemeStateActive;
1017  if (btn->state & QStyle::State_HasFocus)
1018  bdi->adornment = kThemeAdornmentFocus;
1019  else
1020  bdi->adornment = kThemeAdornmentNone;
1021 
1022 
1023  if (btn->features & (QStyleOptionButton::Flat)) {
1024  bdi->kind = kThemeBevelButton;
1025  } else {
1026  switch (aquaSizeConstrain(btn, widget)) {
1027  case QAquaSizeSmall:
1028  bdi->kind = kThemePushButtonSmall;
1029  break;
1030  case QAquaSizeMini:
1031  bdi->kind = kThemePushButtonMini;
1032  break;
1033  case QAquaSizeLarge:
1034  // ... We should honor if the user is explicit about using the
1035  // large button. But right now Qt will specify the large button
1036  // as default rather than QAquaSizeUnknown.
1037  // So we treat it like QAquaSizeUnknown
1038  // to get the dynamic choosing of button kind.
1039  case QAquaSizeUnknown:
1040  // Choose the button kind that closest match the button rect, but at the
1041  // same time displays the button contents without clipping.
1042  bdi->kind = kThemeBevelButton;
1044  if (widget && widget->testAttribute(Qt::WA_MacVariableSize)) {
1045  if (btn->rect.height() <= QMacStylePrivate::MiniButtonH){
1046  if (contentFitsInPushButton(btn, bdi, kThemePushButtonMini))
1047  bdi->kind = kThemePushButtonMini;
1048  } else if (btn->rect.height() <= QMacStylePrivate::SmallButtonH){
1049  if (contentFitsInPushButton(btn, bdi, kThemePushButtonSmall))
1050  bdi->kind = kThemePushButtonSmall;
1051  } else if (contentFitsInPushButton(btn, bdi, kThemePushButton)) {
1052  bdi->kind = kThemePushButton;
1053  }
1054  } else {
1055  bdi->kind = kThemePushButton;
1056  }
1057  }
1058  }
1059  }
1060 }
1061 
1062 bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option)
1063 {
1064  QMacStyle *macStyle = qobject_cast<QMacStyle *>(pushButton->style());
1065  if (!macStyle)
1066  return true; // revert to 'flat' behavior if not Mac style
1067  HIThemeButtonDrawInfo bdi;
1068  macStyle->d->initHIThemePushButton(option, pushButton, kThemeStateActive, &bdi);
1069  return bdi.kind == kThemeBevelButton;
1070 }
1071 
1078 void QMacStylePrivate::initComboboxBdi(const QStyleOptionComboBox *combo, HIThemeButtonDrawInfo *bdi,
1079  const QWidget *widget, const ThemeDrawState &tds)
1080 {
1081  bdi->version = qt_mac_hitheme_version;
1082  bdi->adornment = kThemeAdornmentArrowLeftArrow;
1083  bdi->value = kThemeButtonOff;
1084  if (combo->state & QStyle::State_HasFocus)
1085  bdi->adornment = kThemeAdornmentFocus;
1086  bool drawColorless = combo->palette.currentColorGroup() == QPalette::Active && tds == kThemeStateInactive;
1088  bdi->state = kThemeStatePressed;
1089  else if (drawColorless)
1090  bdi->state = kThemeStateActive;
1091  else
1092  bdi->state = tds;
1093 
1094  QAquaWidgetSize aSize = aquaSizeConstrain(combo, widget);
1095  switch (aSize) {
1096  case QAquaSizeMini:
1097  bdi->kind = combo->editable ? ThemeButtonKind(kThemeComboBoxMini)
1098  : ThemeButtonKind(kThemePopupButtonMini);
1099  break;
1100  case QAquaSizeSmall:
1101  bdi->kind = combo->editable ? ThemeButtonKind(kThemeComboBoxSmall)
1102  : ThemeButtonKind(kThemePopupButtonSmall);
1103  break;
1104  case QAquaSizeUnknown:
1105  case QAquaSizeLarge:
1106  // Unless the user explicitly specified large buttons, determine the
1107  // kind by looking at the combox size.
1108  // ... specifying small and mini-buttons it not a current feature of
1109  // Qt (e.g. QWidget::getAttribute(WA_ButtonSize)). But when it is, add
1110  // an extra check here before using the mini and small buttons.
1111  int h = combo->rect.size().height();
1112  if (combo->editable){
1113  if (h < 21)
1114  bdi->kind = kThemeComboBoxMini;
1115  else if (h < 26)
1116  bdi->kind = kThemeComboBoxSmall;
1117  else
1118  bdi->kind = kThemeComboBox;
1119  } else {
1120  // Even if we specify that we want the kThemePopupButton, Carbon
1121  // will use the kThemePopupButtonSmall if the size matches. So we
1122  // do the same size check explicit to have the size of the inner
1123  // text field be correct. Therefore, do this even if the user specifies
1124  // the use of LargeButtons explicit.
1125  if (h < 21)
1126  bdi->kind = kThemePopupButtonMini;
1127  else if (h < 26)
1128  bdi->kind = kThemePopupButtonSmall;
1129  else
1130  bdi->kind = kThemePopupButton;
1131  }
1132  break;
1133  }
1134 }
1135 
1140 HIRect QMacStylePrivate::comboboxInnerBounds(const HIRect &outerBounds, int buttonKind)
1141 {
1142  HIRect innerBounds = outerBounds;
1143  // Carbon draw parts of the view outside the rect.
1144  // So make the rect a bit smaller to compensate
1145  // (I wish HIThemeGetButtonBackgroundBounds worked)
1146  switch (buttonKind){
1147  case kThemePopupButton:
1148  innerBounds.origin.x += 2;
1149  innerBounds.origin.y += 2;
1150  innerBounds.size.width -= 5;
1151  innerBounds.size.height -= 6;
1152  break;
1153  case kThemePopupButtonSmall:
1154  innerBounds.origin.x += 3;
1155  innerBounds.origin.y += 3;
1156  innerBounds.size.width -= 6;
1157  innerBounds.size.height -= 7;
1158  break;
1159  case kThemePopupButtonMini:
1160  innerBounds.origin.x += 2;
1161  innerBounds.origin.y += 2;
1162  innerBounds.size.width -= 5;
1163  innerBounds.size.height -= 6;
1164  break;
1165  case kThemeComboBox:
1166  innerBounds.origin.x += 3;
1167  innerBounds.origin.y += 2;
1168  innerBounds.size.width -= 6;
1169  innerBounds.size.height -= 8;
1170  break;
1171  case kThemeComboBoxSmall:
1172  innerBounds.origin.x += 3;
1173  innerBounds.origin.y += 3;
1174  innerBounds.size.width -= 7;
1175  innerBounds.size.height -= 8;
1176  break;
1177  case kThemeComboBoxMini:
1178  innerBounds.origin.x += 3;
1179  innerBounds.origin.y += 3;
1180  innerBounds.size.width -= 4;
1181  innerBounds.size.height -= 8;
1182  break;
1183  default:
1184  break;
1185  }
1186  return innerBounds;
1187 }
1188 
1193 QRect QMacStylePrivate::comboboxEditBounds(const QRect &outerBounds, const HIThemeButtonDrawInfo &bdi)
1194 {
1195  QRect ret = outerBounds;
1196  switch (bdi.kind){
1197  case kThemeComboBox:
1198  ret.adjust(5, 5, -22, -5);
1199  break;
1200  case kThemeComboBoxSmall:
1201  ret.adjust(4, 6, -20, 0);
1202  ret.setHeight(14);
1203  break;
1204  case kThemeComboBoxMini:
1205  ret.adjust(4, 5, -18, -1);
1206  ret.setHeight(12);
1207  break;
1208  case kThemePopupButton:
1209  ret.adjust(10, 2, -23, -4);
1210  break;
1211  case kThemePopupButtonSmall:
1212  ret.adjust(9, 3, -20, -3);
1213  break;
1214  case kThemePopupButtonMini:
1215  ret.adjust(8, 3, -19, 0);
1216  ret.setHeight(13);
1217  break;
1218  }
1219  return ret;
1220 }
1221 
1227 void QMacStylePrivate::drawCombobox(const HIRect &outerBounds, const HIThemeButtonDrawInfo &bdi, QPainter *p)
1228 {
1229  if (!(bdi.kind == kThemeComboBox && outerBounds.size.height > 28)){
1230  // We have an unscaled combobox, or popup-button; use Carbon directly.
1231  HIRect innerBounds = QMacStylePrivate::comboboxInnerBounds(outerBounds, bdi.kind);
1232  HIThemeDrawButton(&innerBounds, &bdi, QMacCGContext(p), kHIThemeOrientationNormal, 0);
1233  } else {
1234  QPixmap buffer;
1235  QString key = QString(QLatin1String("$qt_cbox%1-%2")).arg(int(bdi.state)).arg(int(bdi.adornment));
1236  if (!QPixmapCache::find(key, buffer)) {
1237  HIRect innerBoundsSmallCombo = {{3, 3}, {29, 25}};
1238  buffer = QPixmap(35, 28);
1239  buffer.fill(Qt::transparent);
1240  QPainter buffPainter(&buffer);
1241  HIThemeDrawButton(&innerBoundsSmallCombo, &bdi, QMacCGContext(&buffPainter), kHIThemeOrientationNormal, 0);
1242  buffPainter.end();
1243  QPixmapCache::insert(key, buffer);
1244  }
1245 
1246  const int bwidth = 20;
1247  const int fwidth = 10;
1248  const int fheight = 10;
1249  int w = qRound(outerBounds.size.width);
1250  int h = qRound(outerBounds.size.height);
1251  int bstart = w - bwidth;
1252  int blower = fheight + 1;
1253  int flower = h - fheight;
1254  int sheight = flower - fheight;
1255  int center = qRound(outerBounds.size.height + outerBounds.origin.y) / 2;
1256 
1257  // Draw upper and lower gap
1258  p->drawPixmap(fwidth, 0, bstart - fwidth, fheight, buffer, fwidth, 0, 1, fheight);
1259  p->drawPixmap(fwidth, flower, bstart - fwidth, fheight, buffer, fwidth, buffer.height() - fheight, 1, fheight);
1260  // Draw left and right gap. Right gap is drawn top and bottom separatly
1261  p->drawPixmap(0, fheight, fwidth, sheight, buffer, 0, fheight, fwidth, 1);
1262  p->drawPixmap(bstart, fheight, bwidth, center - fheight, buffer, buffer.width() - bwidth, fheight - 1, bwidth, 1);
1263  p->drawPixmap(bstart, center, bwidth, sheight / 2, buffer, buffer.width() - bwidth, fheight + 6, bwidth, 1);
1264  // Draw arrow
1265  p->drawPixmap(bstart, center - 4, bwidth - 3, 6, buffer, buffer.width() - bwidth, fheight, bwidth - 3, 6);
1266  // Draw corners
1267  p->drawPixmap(0, 0, fwidth, fheight, buffer, 0, 0, fwidth, fheight);
1268  p->drawPixmap(bstart, 0, bwidth, fheight, buffer, buffer.width() - bwidth, 0, bwidth, fheight);
1269  p->drawPixmap(0, flower, fwidth, fheight, buffer, 0, buffer.height() - fheight, fwidth, fheight);
1270  p->drawPixmap(bstart, h - blower, bwidth, blower, buffer, buffer.width() - bwidth, buffer.height() - blower, bwidth, blower);
1271  }
1272 }
1273 
1278 void QMacStylePrivate::drawTableHeader(const HIRect &outerBounds,
1279  bool drawTopBorder, bool drawLeftBorder, const HIThemeButtonDrawInfo &bdi, QPainter *p)
1280 {
1281  static SInt32 headerHeight = 0;
1282  static OSStatus err = GetThemeMetric(kThemeMetricListHeaderHeight, &headerHeight);
1283  Q_UNUSED(err);
1284 
1285  QPixmap buffer;
1286  QString key = QString(QLatin1String("$qt_tableh%1-%2-%3")).arg(int(bdi.state)).arg(int(bdi.adornment)).arg(int(bdi.value));
1287  if (!QPixmapCache::find(key, buffer)) {
1288  HIRect headerNormalRect = {{0., 0.}, {16., CGFloat(headerHeight)}};
1289  buffer = QPixmap(headerNormalRect.size.width, headerNormalRect.size.height);
1290  buffer.fill(Qt::transparent);
1291  QPainter buffPainter(&buffer);
1292  HIThemeDrawButton(&headerNormalRect, &bdi, QMacCGContext(&buffPainter), kHIThemeOrientationNormal, 0);
1293  buffPainter.end();
1294  QPixmapCache::insert(key, buffer);
1295  }
1296  const int buttonw = qRound(outerBounds.size.width);
1297  const int buttonh = qRound(outerBounds.size.height);
1298  const int framew = 1;
1299  const int frameh_n = 4;
1300  const int frameh_s = 3;
1301  const int transh = buffer.height() - frameh_n - frameh_s;
1302  int center = buttonh - frameh_s - int(transh / 2.0f) + 1; // Align bottom;
1303 
1304  int skipTopBorder = 0;
1305  if (!drawTopBorder)
1306  skipTopBorder = 1;
1307 
1308  p->translate(outerBounds.origin.x, outerBounds.origin.y);
1309 
1310  p->drawPixmap(QRect(QRect(0, -skipTopBorder, buttonw - framew , frameh_n)), buffer, QRect(framew, 0, 1, frameh_n));
1311  p->drawPixmap(QRect(0, buttonh - frameh_s, buttonw - framew, frameh_s), buffer, QRect(framew, buffer.height() - frameh_s, 1, frameh_s));
1312  // Draw upper and lower center blocks
1313  p->drawPixmap(QRect(0, frameh_n - skipTopBorder, buttonw - framew, center - frameh_n + skipTopBorder), buffer, QRect(framew, frameh_n, 1, 1));
1314  p->drawPixmap(QRect(0, center, buttonw - framew, buttonh - center - frameh_s), buffer, QRect(framew, buffer.height() - frameh_s, 1, 1));
1315  // Draw right center block borders
1316  p->drawPixmap(QRect(buttonw - framew, frameh_n - skipTopBorder, framew, center - frameh_n), buffer, QRect(buffer.width() - framew, frameh_n, framew, 1));
1317  p->drawPixmap(QRect(buttonw - framew, center, framew, buttonh - center - 1), buffer, QRect(buffer.width() - framew, buffer.height() - frameh_s, framew, 1));
1318  // Draw right corners
1319  p->drawPixmap(QRect(buttonw - framew, -skipTopBorder, framew, frameh_n), buffer, QRect(buffer.width() - framew, 0, framew, frameh_n));
1320  p->drawPixmap(QRect(buttonw - framew, buttonh - frameh_s, framew, frameh_s), buffer, QRect(buffer.width() - framew, buffer.height() - frameh_s, framew, frameh_s));
1321  // Draw center transition block
1322  p->drawPixmap(QRect(0, center - qRound(transh / 2.0f), buttonw - framew, buffer.height() - frameh_n - frameh_s), buffer, QRect(framew, frameh_n + 1, 1, transh));
1323  // Draw right center transition block border
1324  p->drawPixmap(QRect(buttonw - framew, center - qRound(transh / 2.0f), framew, buffer.height() - frameh_n - frameh_s), buffer, QRect(buffer.width() - framew, frameh_n + 1, framew, transh));
1325  if (drawLeftBorder){
1326  // Draw left center block borders
1327  p->drawPixmap(QRect(0, frameh_n - skipTopBorder, framew, center - frameh_n + skipTopBorder), buffer, QRect(0, frameh_n, framew, 1));
1328  p->drawPixmap(QRect(0, center, framew, buttonh - center - 1), buffer, QRect(0, buffer.height() - frameh_s, framew, 1));
1329  // Draw left corners
1330  p->drawPixmap(QRect(0, -skipTopBorder, framew, frameh_n), buffer, QRect(0, 0, framew, frameh_n));
1331  p->drawPixmap(QRect(0, buttonh - frameh_s, framew, frameh_s), buffer, QRect(0, buffer.height() - frameh_s, framew, frameh_s));
1332  // Draw left center transition block border
1333  p->drawPixmap(QRect(0, center - qRound(transh / 2.0f), framew, buffer.height() - frameh_n - frameh_s), buffer, QRect(0, frameh_n + 1, framew, transh));
1334  }
1335 
1336  p->translate(-outerBounds.origin.x, -outerBounds.origin.y);
1337 }
1338 
1339 /*
1340  Returns cutoff sizes for scroll bars.
1341  thumbIndicatorCutoff is the smallest size where the thumb indicator is drawn.
1342  scrollButtonsCutoff is the smallest size where the up/down buttons is drawn.
1343 */
1346 {
1347  // Mini scroll bars do not exist as of version 10.4.
1348  if (widgetSize == QMacStyle::SizeMini)
1349  return 0;
1350 
1351  const int sizeIndex = (widgetSize == QMacStyle::SizeSmall) ? 1 : 0;
1352  static const int sizeTable[2][2] = { { 61, 56 }, { 49, 44 } };
1353  return sizeTable[sizeIndex][cutoffType];
1354 }
1355 
1357  HIThemeTrackDrawInfo *tdi, const QWidget *needToRemoveMe)
1358 {
1359  memset(tdi, 0, sizeof(HIThemeTrackDrawInfo)); // We don't get it all for some reason or another...
1360  tdi->version = qt_mac_hitheme_version;
1361  tdi->reserved = 0;
1362  tdi->filler1 = 0;
1363  bool isScrollbar = (cc == QStyle::CC_ScrollBar);
1364  switch (aquaSizeConstrain(0, needToRemoveMe)) {
1365  case QAquaSizeUnknown:
1366  case QAquaSizeLarge:
1367  if (isScrollbar)
1368  tdi->kind = kThemeMediumScrollBar;
1369  else
1370  tdi->kind = kThemeMediumSlider;
1371  break;
1372  case QAquaSizeMini:
1373  if (isScrollbar)
1374  tdi->kind = kThemeSmallScrollBar; // should be kThemeMiniScrollBar, but not implemented
1375  else
1376  tdi->kind = kThemeMiniSlider;
1377  break;
1378  case QAquaSizeSmall:
1379  if (isScrollbar)
1380  tdi->kind = kThemeSmallScrollBar;
1381  else
1382  tdi->kind = kThemeSmallSlider;
1383  break;
1384  }
1385  tdi->bounds = qt_hirectForQRect(slider->rect);
1386  tdi->min = slider->minimum;
1387  tdi->max = slider->maximum;
1388  tdi->value = slider->sliderPosition;
1389  tdi->attributes = kThemeTrackShowThumb;
1390  if (slider->upsideDown)
1391  tdi->attributes |= kThemeTrackRightToLeft;
1392  if (slider->orientation == Qt::Horizontal) {
1393  tdi->attributes |= kThemeTrackHorizontal;
1394  if (isScrollbar && slider->direction == Qt::RightToLeft) {
1395  if (!slider->upsideDown)
1396  tdi->attributes |= kThemeTrackRightToLeft;
1397  else
1398  tdi->attributes &= ~kThemeTrackRightToLeft;
1399  }
1400  }
1401 
1402  // Tiger broke reverse scroll bars so put them back and "fake it"
1403  if (isScrollbar && (tdi->attributes & kThemeTrackRightToLeft)) {
1404  tdi->attributes &= ~kThemeTrackRightToLeft;
1405  tdi->value = tdi->max - slider->sliderPosition;
1406  }
1407 
1408  tdi->enableState = (slider->state & QStyle::State_Enabled) ? kThemeTrackActive
1409  : kThemeTrackDisabled;
1410  if (!(slider->state & QStyle::State_Active))
1411  tdi->enableState = kThemeTrackInactive;
1412  if (!isScrollbar) {
1413  if (slider->state & QStyle::QStyle::State_HasFocus)
1414  tdi->attributes |= kThemeTrackHasFocus;
1416  tdi->trackInfo.slider.thumbDir = kThemeThumbPlain;
1417  else if (slider->tickPosition == QSlider::TicksAbove)
1418  tdi->trackInfo.slider.thumbDir = kThemeThumbUpward;
1419  else
1420  tdi->trackInfo.slider.thumbDir = kThemeThumbDownward;
1421  } else {
1422  tdi->trackInfo.scrollbar.viewsize = slider->pageStep;
1423  }
1424 }
1425 #endif
1426 
1428  : timerID(-1), progressFrame(0), q(style), mouseDown(false)
1429 {
1430  defaultButtonStart = CFAbsoluteTimeGetCurrent();
1431  memset(&buttonState, 0, sizeof(ButtonState));
1432 
1433  if (ptrHIShapeGetBounds == 0) {
1434  QLibrary library(QLatin1String("/System/Library/Frameworks/Carbon.framework/Carbon"));
1436  ptrHIShapeGetBounds = reinterpret_cast<PtrHIShapeGetBounds>(library.resolve("HIShapeGetBounds"));
1437  }
1438 
1439 }
1440 
1442 {
1443  if (!w)
1444  return false;
1445 
1446  if (as == AquaPushButton) {
1447  QPushButton *pb = const_cast<QPushButton *>(static_cast<const QPushButton *>(w));
1448  if (w->window()->isActiveWindow() && pb && !mouseDown) {
1449  if (static_cast<const QPushButton *>(w) != defaultButton) {
1450  // Changed on its own, update the value.
1451  const_cast<QMacStylePrivate *>(this)->stopAnimate(as, defaultButton);
1452  const_cast<QMacStylePrivate *>(this)->startAnimate(as, pb);
1453  }
1454  return true;
1455  }
1456  } else if (as == AquaProgressBar) {
1457  if (progressBars.contains((const_cast<QWidget *>(w))))
1458  return true;
1459  }
1460  return false;
1461 }
1462 
1464 {
1465  if (as == AquaPushButton && defaultButton) {
1466  QPushButton *tmp = defaultButton;
1467  defaultButton = 0;
1468  tmp->update();
1469  } else if (as == AquaProgressBar) {
1471  }
1472 }
1473 
1475 {
1476  if (as == AquaPushButton)
1477  defaultButton = static_cast<QPushButton *>(w);
1478  else if (as == AquaProgressBar)
1479  progressBars.append(w);
1481 }
1482 
1484 {
1485  if ((defaultButton || !progressBars.isEmpty()) && timerID <= -1)
1487 }
1488 
1490 {
1491  //already knew of it
1492  if (static_cast<QPushButton*>(w) == defaultButton
1493  || progressBars.contains(static_cast<QProgressBar*>(w)))
1494  return false;
1495 
1496  if (QPushButton *btn = qobject_cast<QPushButton *>(w)) {
1497  btn->installEventFilter(this);
1498  if (btn->isDefault() || (btn->autoDefault() && btn->hasFocus()))
1500  return true;
1501  } else {
1502  bool isProgressBar = (qobject_cast<QProgressBar *>(w)
1503 #ifdef QT3_SUPPORT
1504  || w->inherits("Q3ProgressBar")
1505 #endif
1506  );
1507  if (isProgressBar) {
1508  w->installEventFilter(this);
1510  return true;
1511  }
1512  }
1513  if (w->isWindow()) {
1514  w->installEventFilter(this);
1515  return true;
1516  }
1517  return false;
1518 }
1519 
1521 {
1522  QPushButton *btn = qobject_cast<QPushButton *>(w);
1523  if (btn && btn == defaultButton) {
1525  } else if (qobject_cast<QProgressBar *>(w)
1526 #ifdef QT3_SUPPORT
1527  || w->inherits("Q3ProgressBar")
1528 #endif
1529  ) {
1531  }
1532 }
1533 
1535 {
1536  ThemeDrawState tds = kThemeStateActive;
1537  if (flags & QStyle::State_Sunken) {
1538  tds = kThemeStatePressed;
1539  } else if (flags & QStyle::State_Active) {
1540  if (!(flags & QStyle::State_Enabled))
1541  tds = kThemeStateUnavailable;
1542  } else {
1543  if (flags & QStyle::State_Enabled)
1544  tds = kThemeStateInactive;
1545  else
1546  tds = kThemeStateUnavailableInactive;
1547  }
1548  return tds;
1549 }
1550 
1552 {
1553  int animated = 0;
1557  && doAnimate(AquaPushButton)) {
1558  ++animated;
1559  defaultButton->update();
1560  }
1561  if (!progressBars.isEmpty()) {
1562  int i = 0;
1563  while (i < progressBars.size()) {
1564  QWidget *maybeProgress = progressBars.at(i);
1565  if (!maybeProgress) {
1567  } else {
1568  if (QProgressBar *pb = qobject_cast<QProgressBar *>(maybeProgress)) {
1569  if (pb->maximum() == 0 || (pb->value() > 0 && pb->value() < pb->maximum())) {
1571  pb->update();
1572  }
1573  }
1574 #ifdef QT3_SUPPORT
1575  else {
1576  // Watch me now...
1577  QVariant progress = maybeProgress->property("progress");
1578  QVariant totalSteps = maybeProgress->property("totalSteps");
1579  if (progress.isValid() && totalSteps.isValid()) {
1580  int intProgress = progress.toInt();
1581  int intTotalSteps = totalSteps.toInt();
1582  if (intTotalSteps == 0 || intProgress > 0 && intProgress < intTotalSteps) {
1584  maybeProgress->update();
1585  }
1586  }
1587  }
1588 #endif
1589  ++i;
1590  }
1591  }
1592  if (i > 0) {
1593  ++progressFrame;
1594  animated += i;
1595  }
1596  }
1597  if (animated <= 0) {
1598  killTimer(timerID);
1599  timerID = -1;
1600  }
1601 }
1602 
1604 {
1605  //animate
1606  if (QProgressBar *pb = qobject_cast<QProgressBar *>(o)) {
1607  switch (e->type()) {
1608  default:
1609  break;
1610  case QEvent::Show:
1611  if (!progressBars.contains(pb))
1613  break;
1614  case QEvent::Destroy:
1615  case QEvent::Hide:
1616  progressBars.removeAll(pb);
1617  }
1618  } else if (QPushButton *btn = qobject_cast<QPushButton *>(o)) {
1619  switch (e->type()) {
1620  default:
1621  break;
1622  case QEvent::FocusIn:
1623  if (btn->autoDefault())
1625  break;
1626  case QEvent::Destroy:
1627  case QEvent::Hide:
1628  if (btn == defaultButton)
1630  break;
1632  // It is very confusing to keep the button pulsing, so just stop the animation.
1633  if (static_cast<QMouseEvent *>(e)->button() == Qt::LeftButton)
1634  mouseDown = true;
1636  break;
1638  if (static_cast<QMouseEvent *>(e)->button() == Qt::LeftButton)
1639  mouseDown = false;
1640  // fall through
1641  case QEvent::FocusOut:
1642  case QEvent::Show:
1643  case QEvent::WindowActivate: {
1644  QList<QPushButton *> list = btn->window()->findChildren<QPushButton *>();
1645  for (int i = 0; i < list.size(); ++i) {
1646  QPushButton *pBtn = list.at(i);
1647  if ((e->type() == QEvent::FocusOut
1648  && (pBtn->isDefault() || (pBtn->autoDefault() && pBtn->hasFocus()))
1649  && pBtn != btn)
1650  || ((e->type() == QEvent::Show || e->type() == QEvent::MouseButtonRelease
1651  || e->type() == QEvent::WindowActivate)
1652  && pBtn->isDefault())) {
1653  if (pBtn->window()->isActiveWindow()) {
1655  }
1656  break;
1657  }
1658  }
1659  break; }
1660  }
1661  }
1662  return false;
1663 }
1664 
1666 {
1667  if (as == AquaPushButton) {
1668  } else if (as == AquaProgressBar) {
1669  // something for later...
1670  } else if (as == AquaListViewItemOpen) {
1671  // To be revived later...
1672  }
1673  return true;
1674 }
1675 
1676 void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonDrawInfo *bdi,
1677  QPainter *p, const QStyleOption *opt) const
1678 {
1679  int xoff = 0,
1680  yoff = 0,
1681  extraWidth = 0,
1682  extraHeight = 0,
1683  finalyoff = 0;
1684 
1685  const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt);
1686  int width = int(macRect.size.width) + extraWidth;
1687  int height = int(macRect.size.height) + extraHeight;
1688 
1689  if (width <= 0 || height <= 0)
1690  return; // nothing to draw
1691 
1692  QString key = QLatin1String("$qt_mac_style_ctb_") + QString::number(bdi->kind) + QLatin1Char('_')
1693  + QString::number(bdi->value) + QLatin1Char('_') + QString::number(width)
1694  + QLatin1Char('_') + QString::number(height);
1695  QPixmap pm;
1696  if (!QPixmapCache::find(key, pm)) {
1697  QPixmap activePixmap(width, height);
1698  activePixmap.fill(Qt::transparent);
1699  {
1700  if (combo){
1701  // Carbon combos don't scale. Therefore we draw it
1702  // ourselves, if a scaled version is needed.
1703  QPainter tmpPainter(&activePixmap);
1704  QMacStylePrivate::drawCombobox(macRect, *bdi, &tmpPainter);
1705  }
1706  else {
1707  QMacCGContext cg(&activePixmap);
1708  HIRect newRect = CGRectMake(xoff, yoff, macRect.size.width, macRect.size.height);
1709  HIThemeDrawButton(&newRect, bdi, cg, kHIThemeOrientationNormal, 0);
1710  }
1711  }
1712 
1713  if (!combo && bdi->value == kThemeButtonOff) {
1714  pm = activePixmap;
1715  } else if (combo) {
1716  QImage image = activePixmap.toImage();
1717 
1718  for (int y = 0; y < height; ++y) {
1719  QRgb *scanLine = reinterpret_cast<QRgb *>(image.scanLine(y));
1720 
1721  for (int x = 0; x < width; ++x) {
1722  QRgb &pixel = scanLine[x];
1723 
1724  int darkest = qRed(pixel);
1725  int mid = qGreen(pixel);
1726  int lightest = qBlue(pixel);
1727 
1728  if (darkest > mid)
1729  qSwap(darkest, mid);
1730  if (mid > lightest)
1731  qSwap(mid, lightest);
1732  if (darkest > mid)
1733  qSwap(darkest, mid);
1734 
1735  int gray = (mid + 2 * lightest) / 3;
1736  pixel = qRgba(gray, gray, gray, qAlpha(pixel));
1737  }
1738  }
1739  pm = QPixmap::fromImage(image);
1740  } else {
1741  QImage activeImage = activePixmap.toImage();
1742  QImage colorlessImage;
1743  {
1744  QPixmap colorlessPixmap(width, height);
1745  colorlessPixmap.fill(Qt::transparent);
1746 
1747  QMacCGContext cg(&colorlessPixmap);
1748  HIRect newRect = CGRectMake(xoff, yoff, macRect.size.width, macRect.size.height);
1749  int oldValue = bdi->value;
1750  bdi->value = kThemeButtonOff;
1751  HIThemeDrawButton(&newRect, bdi, cg, kHIThemeOrientationNormal, 0);
1752  bdi->value = oldValue;
1753  colorlessImage = colorlessPixmap.toImage();
1754  }
1755 
1756  for (int y = 0; y < height; ++y) {
1757  QRgb *colorlessScanLine = reinterpret_cast<QRgb *>(colorlessImage.scanLine(y));
1758  const QRgb *activeScanLine = reinterpret_cast<const QRgb *>(activeImage.scanLine(y));
1759 
1760  for (int x = 0; x < width; ++x) {
1761  QRgb &colorlessPixel = colorlessScanLine[x];
1762  QRgb activePixel = activeScanLine[x];
1763 
1764  if (activePixel != colorlessPixel) {
1765  int max = qMax(qMax(qRed(activePixel), qGreen(activePixel)),
1766  qBlue(activePixel));
1767  QRgb newPixel = qRgba(max, max, max, qAlpha(activePixel));
1768  if (qGray(newPixel) < qGray(colorlessPixel)
1769  || qAlpha(newPixel) > qAlpha(colorlessPixel))
1770  colorlessPixel = newPixel;
1771  }
1772  }
1773  }
1774  pm = QPixmap::fromImage(colorlessImage);
1775  }
1776  QPixmapCache::insert(key, pm);
1777  }
1778  p->drawPixmap(int(macRect.origin.x), int(macRect.origin.y) + finalyoff, width, height, pm);
1779 }
1780 
1782  : QWindowsStyle()
1783 {
1784  d = new QMacStylePrivate(this);
1785 }
1786 
1788 {
1789  delete qt_mac_backgroundPattern;
1790  qt_mac_backgroundPattern = 0;
1791  delete d;
1792 }
1793 
1798 {
1799  QPixmap px(4, 4);
1800  QMacCGContext cg(&px);
1801  HIThemeSetFill(kThemeBrushDialogBackgroundActive, 0, cg, kHIThemeOrientationNormal);
1802  const CGRect cgRect = CGRectMake(0, 0, px.width(), px.height());
1803  CGContextFillRect(cg, cgRect);
1804  return px;
1805 }
1806 
1811 void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush)
1812 {
1813  QPoint dummy;
1814  const QPaintDevice *target = painter->device();
1815  const QPaintDevice *redirected = QPainter::redirected(target, &dummy);
1816  const bool usePainter = redirected && redirected != target;
1817 
1818  if (!usePainter && qt_mac_backgroundPattern
1819  && qt_mac_backgroundPattern->cacheKey() == brush.texture().cacheKey()) {
1820 
1821  painter->setClipRegion(rgn);
1822 
1824  CGContextSaveGState(cg);
1825  HIThemeSetFill(kThemeBrushDialogBackgroundActive, 0, cg, kHIThemeOrientationInverted);
1826 
1827  const QVector<QRect> &rects = rgn.rects();
1828  for (int i = 0; i < rects.size(); ++i) {
1829  const QRect rect(rects.at(i));
1830  // Anchor the pattern to the top so it stays put when the window is resized.
1831  CGContextSetPatternPhase(cg, CGSizeMake(rect.width(), rect.height()));
1832  CGRect mac_rect = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
1833  CGContextFillRect(cg, mac_rect);
1834  }
1835 
1836  CGContextRestoreGState(cg);
1837  } else {
1838  const QRect rect(rgn.boundingRect());
1839  painter->setClipRegion(rgn);
1840  painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft());
1841  }
1842 }
1843 
1845 {
1846  if (!qt_mac_backgroundPattern) {
1847  if (!qApp)
1848  return;
1849  qt_mac_backgroundPattern = new QPixmap(d->generateBackgroundPattern());
1850  }
1851 
1852  QColor pc(Qt::black);
1853  pc = qcolorForTheme(kThemeBrushDialogBackgroundActive);
1854  QBrush background(pc, *qt_mac_backgroundPattern);
1855  pal.setBrush(QPalette::All, QPalette::Window, background);
1856  pal.setBrush(QPalette::All, QPalette::Button, background);
1857 
1858  QCFString theme;
1859  const OSErr err = CopyThemeIdentifier(&theme);
1860  if (err == noErr && CFStringCompare(theme, kThemeAppearanceAquaGraphite, 0) == kCFCompareEqualTo) {
1861  pal.setBrush(QPalette::All, QPalette::AlternateBase, QColor(240, 240, 240));
1862  } else {
1863  pal.setBrush(QPalette::All, QPalette::AlternateBase, QColor(237, 243, 254));
1864  }
1865 }
1866 
1868 {
1869 }
1870 
1872 {
1873 }
1874 
1876 {
1877  d->addWidget(w);
1879  // Set a clear brush so that the metal shines through.
1880  QPalette pal = w->palette();
1881  QBrush background(Qt::transparent);
1882  pal.setBrush(QPalette::All, QPalette::Window, background);
1883  pal.setBrush(QPalette::All, QPalette::Button, background);
1884  w->setPalette(pal);
1885  w->setAttribute(Qt::WA_SetPalette, false);
1886  }
1887 
1888  if (qobject_cast<QMenu*>(w) || qobject_cast<QComboBoxPrivateContainer *>(w)) {
1890  if (!w->testAttribute(Qt::WA_SetPalette)) {
1891  QPixmap px(64, 64);
1892  px.fill(Qt::white);
1893  HIThemeMenuDrawInfo mtinfo;
1894  mtinfo.version = qt_mac_hitheme_version;
1895  mtinfo.menuType = kThemeMenuTypePopUp;
1896  HIRect rect = CGRectMake(0, 0, px.width(), px.height());
1897  HIThemeDrawMenuBackground(&rect, &mtinfo, QCFType<CGContextRef>(qt_mac_cg_context(&px)),
1898  kHIThemeOrientationNormal);
1899  QPalette pal = w->palette();
1900  QBrush background(px);
1901  pal.setBrush(QPalette::All, QPalette::Window, background);
1902  pal.setBrush(QPalette::All, QPalette::Button, background);
1903  w->setPalette(pal);
1904  w->setAttribute(Qt::WA_SetPalette, false);
1905  }
1906  }
1907 
1908  if (QTabBar *tb = qobject_cast<QTabBar*>(w)) {
1909  if (tb->documentMode()) {
1911  w->setFont(qt_app_fonts_hash()->value("QSmallFont", QFont()));
1912  QPalette p = w->palette();
1913  p.setColor(QPalette::WindowText, QColor(17, 17, 17));
1914  w->setPalette(p);
1915  }
1916  }
1917 
1919 
1920  if (QRubberBand *rubber = qobject_cast<QRubberBand*>(w)) {
1921  rubber->setWindowOpacity(0.25);
1922  rubber->setAttribute(Qt::WA_PaintOnScreen, false);
1923  rubber->setAttribute(Qt::WA_NoSystemBackground, false);
1924  }
1925 }
1926 
1928 {
1929  d->removeWidget(w);
1930  if ((qobject_cast<QMenu*>(w) || qt_mac_is_metal(w)) && !w->testAttribute(Qt::WA_SetPalette)) {
1931  QPalette pal = qApp->palette(w);
1932  w->setPalette(pal);
1933  w->setAttribute(Qt::WA_SetPalette, false);
1934  w->setWindowOpacity(1.0);
1935  }
1936 
1937  if (QComboBox *combo = qobject_cast<QComboBox *>(w)) {
1938  if (!combo->isEditable()) {
1940  widget->setWindowOpacity(1.0);
1941  }
1942  }
1943 
1944  if (QRubberBand *rubber = ::qobject_cast<QRubberBand*>(w)) {
1945  rubber->setWindowOpacity(1.0);
1946  rubber->setAttribute(Qt::WA_PaintOnScreen, true);
1947  rubber->setAttribute(Qt::WA_NoSystemBackground, true);
1948  }
1949 
1950  if (QFocusFrame *frame = qobject_cast<QFocusFrame *>(w))
1951  frame->setAttribute(Qt::WA_NoSystemBackground, true);
1952 
1954 }
1955 
1956 int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QWidget *widget) const
1957 {
1958  int controlSize = getControlSize(opt, widget);
1959  SInt32 ret = 0;
1960 
1961  switch (metric) {
1964  ret = closeButtonSize;
1965  break;
1966  case PM_ToolBarIconSize:
1968  break;
1969  case PM_FocusFrameVMargin:
1970  case PM_FocusFrameHMargin:
1971  GetThemeMetric(kThemeMetricFocusRectOutset, &ret);
1972  break;
1974  ret = -5;
1975  break;
1977  QSize sz;
1978  ret = d->aquaSizeConstrain(opt, 0, QStyle::CT_PushButton, QSize(-1, -1), &sz);
1979  if (sz == QSize(-1, -1))
1980  ret = 32;
1981  else
1982  ret = sz.height();
1983  break; }
1984  case PM_CheckListButtonSize: {
1985  switch (d->aquaSizeConstrain(opt, widget)) {
1986  case QAquaSizeUnknown:
1987  case QAquaSizeLarge:
1988  GetThemeMetric(kThemeMetricCheckBoxWidth, &ret);
1989  break;
1990  case QAquaSizeMini:
1991  GetThemeMetric(kThemeMetricMiniCheckBoxWidth, &ret);
1992  break;
1993  case QAquaSizeSmall:
1994  GetThemeMetric(kThemeMetricSmallCheckBoxWidth, &ret);
1995  break;
1996  }
1997  break; }
1999  QSize sz;
2000  ret = d->aquaSizeConstrain(opt, 0, QStyle::CT_PushButton, QSize(-1, -1), &sz);
2001  if (sz == QSize(-1, -1))
2002  ret = 70;
2003  else
2004  ret = sz.width();
2005  break; }
2006 
2007  case PM_MenuBarHMargin:
2008  ret = 8;
2009  break;
2010 
2011  case PM_MenuBarVMargin:
2012  ret = 0;
2013  break;
2014 
2016  ret = 5;
2017  break;
2018 
2021  ret = 2;
2022  break;
2023  case PM_MenuScrollerHeight:
2024 #if 0
2025  SInt16 ash, asw;
2026  GetThemeMenuItemExtra(kThemeMenuItemScrollUpArrow, &ash, &asw);
2027  ret = ash;
2028 #else
2029  ret = 15; // I hate having magic numbers in here...
2030 #endif
2031  break;
2032  case PM_DefaultFrameWidth:
2033 #ifndef QT_NO_MAINWINDOW
2034  if (widget && (widget->isWindow() || !widget->parentWidget()
2035  || (qobject_cast<const QMainWindow*>(widget->parentWidget())
2036  && static_cast<QMainWindow *>(widget->parentWidget())->centralWidget() == widget))
2038 #ifdef QT3_SUPPORT
2039  || widget->inherits("QScrollView")
2040 #endif
2041  || widget->inherits("QWorkspaceChild")))
2042  ret = 0;
2043  else
2044 #endif
2045  // The combo box popup has no frame.
2046  if (qstyleoption_cast<const QStyleOptionComboBox *>(opt) != 0)
2047  ret = 0;
2048  // Frame of mac style line edits is two pixels on top and one on the bottom
2049  else if (qobject_cast<const QLineEdit *>(widget) != 0)
2050  ret = 2;
2051  else
2052  ret = 1;
2053  break;
2055  ret = -1;
2056  break;
2057  case PM_ScrollBarSliderMin:
2058  ret = 24;
2059  break;
2060  case PM_SpinBoxFrameWidth:
2061  GetThemeMetric(kThemeMetricEditTextFrameOutset, &ret);
2062  switch (d->aquaSizeConstrain(opt, widget)) {
2063  default:
2064  ret += 2;
2065  break;
2066  case QAquaSizeMini:
2067  ret += 1;
2068  break;
2069  }
2070  break;
2073  ret = 0;
2074  break;
2075  case PM_SliderLength:
2076  ret = 17;
2077  break;
2079  ret = 0;
2080  break;
2081  case PM_TitleBarHeight:
2082  if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
2083  HIThemeWindowDrawInfo wdi;
2084  wdi.version = qt_mac_hitheme_version;
2085  wdi.state = kThemeStateActive;
2086  wdi.windowType = QtWinType;
2087  if (tb->titleBarState)
2088  wdi.attributes = kThemeWindowHasFullZoom | kThemeWindowHasCloseBox
2089  | kThemeWindowHasCollapseBox;
2090  else if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
2091  wdi.attributes = kThemeWindowHasCloseBox;
2092  else
2093  wdi.attributes = 0;
2094  wdi.titleHeight = tb->rect.height();
2095  wdi.titleWidth = tb->rect.width();
2096  QCFType<HIShapeRef> region;
2097  HIRect hirect = qt_hirectForQRect(tb->rect);
2098  if (hirect.size.width <= 0)
2099  hirect.size.width = 100;
2100  if (hirect.size.height <= 0)
2101  hirect.size.height = 30;
2102 
2103  HIThemeGetWindowShape(&hirect, &wdi, kWindowTitleBarRgn, &region);
2104  HIRect rect;
2105  ptrHIShapeGetBounds(region, &rect);
2106  ret = int(rect.size.height);
2107  ret += 4;
2108  }
2109  break;
2110  case PM_TabBarTabVSpace:
2111  ret = 4;
2112  break;
2115  ret = 0;
2116  break;
2117  case PM_TabBarBaseHeight:
2118  ret = 0;
2119  break;
2120  case PM_TabBarTabOverlap:
2121  ret = 0;
2122  break;
2123  case PM_TabBarBaseOverlap:
2124  switch (d->aquaSizeConstrain(opt, widget)) {
2125  case QAquaSizeUnknown:
2126  case QAquaSizeLarge:
2127  ret = 11;
2128  break;
2129  case QAquaSizeSmall:
2130  ret = 8;
2131  break;
2132  case QAquaSizeMini:
2133  ret = 7;
2134  break;
2135  }
2136  break;
2137  case PM_ScrollBarExtent: {
2138  switch (d->aquaSizeConstrain(opt, widget)) {
2139  case QAquaSizeUnknown:
2140  case QAquaSizeLarge:
2141  GetThemeMetric(kThemeMetricScrollBarWidth, &ret);
2142  break;
2143  case QAquaSizeMini:
2144  case QAquaSizeSmall:
2145  GetThemeMetric(kThemeMetricSmallScrollBarWidth, &ret);
2146  break;
2147  }
2148  break; }
2149  case PM_IndicatorHeight: {
2150  switch (d->aquaSizeConstrain(opt, widget)) {
2151  case QAquaSizeUnknown:
2152  case QAquaSizeLarge:
2153  GetThemeMetric(kThemeMetricCheckBoxHeight, &ret);
2154  break;
2155  case QAquaSizeMini:
2156  GetThemeMetric(kThemeMetricMiniCheckBoxHeight, &ret);
2157  break;
2158  case QAquaSizeSmall:
2159  GetThemeMetric(kThemeMetricSmallCheckBoxHeight, &ret);
2160  break;
2161  }
2162  break; }
2163  case PM_IndicatorWidth: {
2164  switch (d->aquaSizeConstrain(opt, widget)) {
2165  case QAquaSizeUnknown:
2166  case QAquaSizeLarge:
2167  GetThemeMetric(kThemeMetricCheckBoxWidth, &ret);
2168  break;
2169  case QAquaSizeMini:
2170  GetThemeMetric(kThemeMetricMiniCheckBoxWidth, &ret);
2171  break;
2172  case QAquaSizeSmall:
2173  GetThemeMetric(kThemeMetricSmallCheckBoxWidth, &ret);
2174  break;
2175  }
2176  ++ret;
2177  break; }
2179  switch (d->aquaSizeConstrain(opt, widget)) {
2180  case QAquaSizeUnknown:
2181  case QAquaSizeLarge:
2182  GetThemeMetric(kThemeMetricRadioButtonHeight, &ret);
2183  break;
2184  case QAquaSizeMini:
2185  GetThemeMetric(kThemeMetricMiniRadioButtonHeight, &ret);
2186  break;
2187  case QAquaSizeSmall:
2188  GetThemeMetric(kThemeMetricSmallRadioButtonHeight, &ret);
2189  break;
2190  }
2191  break; }
2193  switch (d->aquaSizeConstrain(opt, widget)) {
2194  case QAquaSizeUnknown:
2195  case QAquaSizeLarge:
2196  GetThemeMetric(kThemeMetricRadioButtonWidth, &ret);
2197  break;
2198  case QAquaSizeMini:
2199  GetThemeMetric(kThemeMetricMiniRadioButtonWidth, &ret);
2200  break;
2201  case QAquaSizeSmall:
2202  GetThemeMetric(kThemeMetricSmallRadioButtonWidth, &ret);
2203  break;
2204  }
2205  ++ret;
2206  break; }
2207  case PM_MenuVMargin:
2208  ret = 4;
2209  break;
2210  case PM_MenuPanelWidth:
2211  ret = 0;
2212  break;
2214  ret = 0;
2215  break;
2216  case PM_SizeGripSize: {
2217  QAquaWidgetSize aSize;
2218  if (widget && widget->window()->windowType() == Qt::Tool)
2219  aSize = QAquaSizeSmall;
2220  else
2221  aSize = QAquaSizeLarge;
2222  const QSize size = qt_aqua_get_known_size(CT_SizeGrip, widget, QSize(), aSize);
2223  ret = size.width();
2224  break; }
2226  ret = 1;
2227  break;
2229  ret = 2;
2230  break;
2232  ret = 0;
2233  break;
2235  ret = 1;
2236  break;
2238  ret = 11;
2239  break;
2240  case PM_ToolBarItemMargin:
2241  ret = 0;
2242  break;
2243  case PM_ToolBarItemSpacing:
2244  ret = 4;
2245  break;
2246  case PM_SplitterWidth:
2247  ret = qMax(7, QApplication::globalStrut().width());
2248  break;
2249  case PM_LayoutLeftMargin:
2250  case PM_LayoutTopMargin:
2251  case PM_LayoutRightMargin:
2252  case PM_LayoutBottomMargin:
2253  {
2254  bool isWindow = false;
2255  if (opt) {
2256  isWindow = (opt->state & State_Window);
2257  } else if (widget) {
2258  isWindow = widget->isWindow();
2259  }
2260 
2261  if (isWindow) {
2262  bool isMetal = widget && widget->testAttribute(Qt::WA_MacBrushedMetal);
2263  if (isMetal) {
2264  if (metric == PM_LayoutTopMargin) {
2265  return_SIZE(9 /* AHIG */, 6 /* guess */, 6 /* guess */);
2266  } else if (metric == PM_LayoutBottomMargin) {
2267  return_SIZE(18 /* AHIG */, 15 /* guess */, 13 /* guess */);
2268  } else {
2269  return_SIZE(14 /* AHIG */, 11 /* guess */, 9 /* guess */);
2270  }
2271  } else {
2272  /*
2273  AHIG would have (20, 8, 10) here but that makes
2274  no sense. It would also have 14 for the top margin
2275  but this contradicts both Builder and most
2276  applications.
2277  */
2278  return_SIZE(20, 10, 10); // AHIG
2279  }
2280  } else {
2281  // hack to detect QTabWidget
2282  if (widget && widget->parentWidget()
2284  if (metric == PM_LayoutTopMargin) {
2285  /*
2286  Builder would have 14 (= 20 - 6) instead of 12,
2287  but that makes the tab look disproportionate.
2288  */
2289  return_SIZE(12, 6, 6); // guess
2290  } else {
2291  return_SIZE(20 /* Builder */, 8 /* guess */, 8 /* guess */);
2292  }
2293  } else {
2294  /*
2295  Child margins are highly inconsistent in AHIG and Builder.
2296  */
2297  return_SIZE(12, 8, 6); // guess
2298  }
2299  }
2300  }
2303  return -1;
2305  switch (d->aquaSizeConstrain(opt, widget)) {
2306  case QAquaSizeLarge:
2307  case QAquaSizeUnknown:
2308  ret = QWindowsStyle::pixelMetric(metric, opt, widget);
2309  break;
2310  case QAquaSizeSmall:
2311  ret = 20;
2312  break;
2313  case QAquaSizeMini:
2314  ret = 16;
2315  break;
2316  }
2317  break;
2318  case PM_MenuHMargin:
2319  ret = 0;
2320  break;
2321  case PM_ToolBarFrameWidth:
2322  ret = 1;
2323  if (widget) {
2324  if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(widget->parent()))
2325  if (mainWindow->unifiedTitleAndToolBarOnMac())
2326  ret = 0;
2327  }
2328  break;
2329  default:
2330  ret = QWindowsStyle::pixelMetric(metric, opt, widget);
2331  break;
2332  }
2333  return ret;
2334 }
2335 
2337 {
2339  pal.setColor(QPalette::Disabled, QPalette::Dark, QColor(191, 191, 191));
2340  pal.setColor(QPalette::Active, QPalette::Dark, QColor(191, 191, 191));
2341  pal.setColor(QPalette::Inactive, QPalette::Dark, QColor(191, 191, 191));
2342  return pal;
2343 }
2344 
2346  QStyleHintReturn *hret) const
2347 {
2348  SInt32 ret = 0;
2349  switch (sh) {
2350  case SH_Menu_SelectionWrap:
2351  ret = false;
2352  break;
2354  ret = true;
2355  break;
2357  ret = true;
2358  break;
2361  break;
2363  ret = 0;
2364  break;
2366  ret = false;
2367  break;
2368  case SH_TitleBar_AutoRaise:
2369  ret = true;
2370  break;
2372  ret = false;
2373  break;
2375  ret = 100;
2376  break;
2378  extern bool qt_scrollbar_jump_to_pos; //qapplication_mac.cpp
2380  ret = !qt_scrollbar_jump_to_pos;
2381  else
2383  break; }
2385  ret = true;
2386  break;
2388  ret = kBulletUnicode;
2389  break;
2390  /*
2391  case SH_DialogButtons_DefaultButton:
2392  ret = QDialogButtons::Reject;
2393  break;
2394  */
2396  ret = Qt::AlignTop;
2397  break;
2399  if (w && (w->isWindow() || !w->parentWidget() || w->parentWidget()->isWindow())
2400  && (w->inherits("QWorkspaceChild")
2401 #ifdef QT3_SUPPORT
2402  || w->inherits("QScrollView")
2403 #endif
2404  ))
2405  ret = true;
2406  else
2407  ret = QWindowsStyle::styleHint(sh, opt, w, hret);
2408  break;
2410  ret = false;
2411  break;
2412  case SH_Menu_Scrollable:
2413  ret = true;
2414  break;
2416  ret = true;
2417  break;
2419  ret = false;
2420  break;
2422  ret = true;
2423  break;
2426  break;
2428  if (const QStyleOptionTabBarBaseV2 *opt2 = qstyleoption_cast<const QStyleOptionTabBarBaseV2 *>(opt)) {
2429  ret = opt2->documentMode ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease;
2430  } else {
2432  }
2433  break;
2434  case SH_ComboBox_Popup:
2435  if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt))
2436  ret = !cmb->editable;
2437  else
2438  ret = 0;
2439  break;
2441  ret = true;
2442  break;
2444  ret = true;
2445  break;
2447  ret = Qt::AlignRight;
2448  break;
2449  case SH_TabBar_Alignment: {
2450  if (const QTabWidget *tab = qobject_cast<const QTabWidget*>(w)) {
2451  if (tab->documentMode()) {
2452  ret = Qt::AlignLeft;
2453  break;
2454  }
2455  }
2456  if (const QTabBar *tab = qobject_cast<const QTabBar*>(w)) {
2457  if (tab->documentMode()) {
2458  ret = Qt::AlignLeft;
2459  break;
2460  }
2461  }
2462  ret = Qt::AlignCenter;
2463  } break;
2464  case SH_UnderlineShortcut:
2465  ret = false;
2466  break;
2468  ret = 242; // About 95%
2469  break;
2470  case SH_Button_FocusPolicy:
2471  ret = Qt::TabFocus;
2472  break;
2473  case SH_EtchDisabledText:
2474  ret = false;
2475  break;
2476  case SH_FocusFrame_Mask: {
2477  ret = true;
2478  if(QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(hret)) {
2479  const uchar fillR = 192, fillG = 191, fillB = 190;
2480  QImage img;
2481 
2482  QSize pixmapSize = opt->rect.size();
2483  if (pixmapSize.isValid()) {
2484  QPixmap pix(pixmapSize);
2485  pix.fill(QColor(fillR, fillG, fillB));
2486  QPainter pix_paint(&pix);
2487  proxy()->drawControl(CE_FocusFrame, opt, &pix_paint, w);
2488  pix_paint.end();
2489  img = pix.toImage();
2490  }
2491 
2492  const QRgb *sptr = (QRgb*)img.bits(), *srow;
2493  const int sbpl = img.bytesPerLine();
2494  const int w = sbpl/4, h = img.height();
2495 
2496  QImage img_mask(img.width(), img.height(), QImage::Format_ARGB32);
2497  QRgb *dptr = (QRgb*)img_mask.bits(), *drow;
2498  const int dbpl = img_mask.bytesPerLine();
2499 
2500  for (int y = 0; y < h; ++y) {
2501  srow = sptr+((y*sbpl)/4);
2502  drow = dptr+((y*dbpl)/4);
2503  for (int x = 0; x < w; ++x) {
2504  const int diff = (((qRed(*srow)-fillR)*(qRed(*srow)-fillR)) +
2505  ((qGreen(*srow)-fillG)*((qGreen(*srow)-fillG))) +
2506  ((qBlue(*srow)-fillB)*((qBlue(*srow)-fillB))));
2507  (*drow++) = (diff < 100) ? 0xffffffff : 0xff000000;
2508  ++srow;
2509  }
2510  }
2511  QBitmap qmask = QBitmap::fromImage(img_mask);
2512  mask->region = QRegion(qmask);
2513  }
2514  break; }
2515  case SH_TitleBar_NoBorder:
2516  ret = 1;
2517  break;
2518  case SH_RubberBand_Mask:
2519  ret = 0;
2520  break;
2522  ret = Qt::LeftToRight;
2523  break;
2525  ret = Qt::AlignHCenter;
2526  break;
2528  ret = true;
2529  break;
2531  ret = false;
2532  break;
2534  ret = true;
2535  break;
2536  case SH_WindowFrame_Mask:
2537  ret = 1;
2538  if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask *>(hret)) {
2539  mask->region = opt->rect;
2540  mask->region -= QRect(opt->rect.left(), opt->rect.top(), 5, 1);
2541  mask->region -= QRect(opt->rect.left(), opt->rect.top() + 1, 3, 1);
2542  mask->region -= QRect(opt->rect.left(), opt->rect.top() + 2, 2, 1);
2543  mask->region -= QRect(opt->rect.left(), opt->rect.top() + 3, 1, 2);
2544 
2545  mask->region -= QRect(opt->rect.right() - 4, opt->rect.top(), 5, 1);
2546  mask->region -= QRect(opt->rect.right() - 2, opt->rect.top() + 1, 3, 1);
2547  mask->region -= QRect(opt->rect.right() - 1, opt->rect.top() + 2, 2, 1);
2548  mask->region -= QRect(opt->rect.right() , opt->rect.top() + 3, 1, 2);
2549  }
2550  break;
2551  case SH_TabBar_ElideMode:
2552  ret = Qt::ElideRight;
2553  break;
2554  case SH_DialogButtonLayout:
2556  break;
2559  break;
2562  break;
2565  break;
2567  ret = Qt::AlignRight;
2568  break;
2571  break;
2574  break;
2577  break;
2579  ret = false;
2580  break;
2582  ret = false;
2583  break;
2585  ret = false;
2586  break;
2588  ret = true;
2589  break;
2590  case SH_WizardStyle:
2591  ret = QWizard::MacStyle;
2592  break;
2594  ret = false;
2595  break;
2597  ret = true;
2598  break;
2599  case SH_Menu_FadeOutOnHide:
2600  ret = true;
2601  break;
2602  case SH_Menu_Mask:
2603  if (opt) {
2604  if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(hret)) {
2605  ret = true;
2606  HIRect menuRect = CGRectMake(opt->rect.x(), opt->rect.y() + 4,
2607  opt->rect.width(), opt->rect.height() - 8);
2608  HIThemeMenuDrawInfo mdi;
2609  mdi.version = 0;
2610  if (w && qobject_cast<QMenu *>(w->parentWidget()))
2611  mdi.menuType = kThemeMenuTypeHierarchical;
2612  else
2613  mdi.menuType = kThemeMenuTypePopUp;
2614  QCFType<HIShapeRef> shape;
2615  HIThemeGetMenuBackgroundShape(&menuRect, &mdi, &shape);
2616  mask->region = QRegion::fromHIShapeRef(shape);
2617  }
2618  }
2619  break;
2621  ret = true;
2622  break;
2624  ret = QTabBar::LeftSide;
2625  break;
2627  ret = false;
2628  break;
2629  default:
2630  ret = QWindowsStyle::styleHint(sh, opt, w, hret);
2631  break;
2632  }
2633  return ret;
2634 }
2635 
2637  const QStyleOption *opt) const
2638 {
2639  switch (iconMode) {
2640  case QIcon::Disabled: {
2642  int imgh = img.height();
2643  int imgw = img.width();
2644  QRgb pixel;
2645  for (int y = 0; y < imgh; ++y) {
2646  for (int x = 0; x < imgw; ++x) {
2647  pixel = img.pixel(x, y);
2648  img.setPixel(x, y, qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel),
2649  qAlpha(pixel) / 2));
2650  }
2651  }
2652  return QPixmap::fromImage(img);
2653  }
2654  default:
2655  ;
2656  }
2657  return QWindowsStyle::generatedIconPixmap(iconMode, pixmap, opt);
2658 }
2659 
2660 
2662  const QWidget *widget) const
2663 {
2664  // The default implementation of QStyle::standardIconImplementation() is to call standardPixmap()
2665  // I don't want infinite recursion so if we do get in that situation, just return the Window's
2666  // standard pixmap instead (since there is no mac-specific icon then). This should be fine until
2667  // someone changes how Windows standard
2668  // pixmap works.
2669  static bool recursionGuard = false;
2670 
2671  if (recursionGuard)
2672  return QWindowsStyle::standardPixmap(standardPixmap, opt, widget);
2673 
2674  recursionGuard = true;
2675  QIcon icon = standardIconImplementation(standardPixmap, opt, widget);
2676  recursionGuard = false;
2677  int size;
2678  switch (standardPixmap) {
2679  default:
2680  size = 32;
2681  break;
2682  case SP_MessageBoxCritical:
2683  case SP_MessageBoxQuestion:
2685  case SP_MessageBoxWarning:
2686  size = 64;
2687  break;
2688  }
2689  return icon.pixmap(size, size);
2690 }
2691 
2693 {
2694  switch (policy) {
2695  case FocusDefault:
2696  break;
2697  case FocusEnabled:
2698  case FocusDisabled:
2700  break;
2701  }
2702 }
2703 
2705 {
2707 }
2708 
2710 {
2711  QWidget *wadget = const_cast<QWidget *>(widget);
2712  wadget->setAttribute(Qt::WA_MacNormalSize, policy == SizeLarge);
2713  wadget->setAttribute(Qt::WA_MacSmallSize, policy == SizeSmall);
2714  wadget->setAttribute(Qt::WA_MacMiniSize, policy == SizeMini);
2715 }
2716 
2718 {
2719  while (widget) {
2720  if (widget->testAttribute(Qt::WA_MacMiniSize)) {
2721  return SizeMini;
2722  } else if (widget->testAttribute(Qt::WA_MacSmallSize)) {
2723  return SizeSmall;
2724  } else if (widget->testAttribute(Qt::WA_MacNormalSize)) {
2725  return SizeLarge;
2726  }
2727  widget = widget->parentWidget();
2728  }
2729  return SizeDefault;
2730 }
2731 
2733  const QWidget *w) const
2734 {
2735  ThemeDrawState tds = d->getDrawState(opt->state);
2736  QMacCGContext cg(p);
2737  switch (pe) {
2738  case PE_IndicatorArrowUp:
2739  case PE_IndicatorArrowDown:
2741  case PE_IndicatorArrowLeft: {
2742  p->save();
2744  int xOffset = opt->direction == Qt::LeftToRight ? 2 : -1;
2745  QMatrix matrix;
2746  matrix.translate(opt->rect.center().x() + xOffset, opt->rect.center().y() + 2);
2747  QPainterPath path;
2748  switch(pe) {
2749  default:
2750  case PE_IndicatorArrowDown:
2751  break;
2752  case PE_IndicatorArrowUp:
2753  matrix.rotate(180);
2754  break;
2755  case PE_IndicatorArrowLeft:
2756  matrix.rotate(90);
2757  break;
2759  matrix.rotate(-90);
2760  break;
2761  }
2762  path.moveTo(0, 5);
2763  path.lineTo(-4, -3);
2764  path.lineTo(4, -3);
2765  p->setMatrix(matrix);
2766  p->setPen(Qt::NoPen);
2767  p->setBrush(QColor(0, 0, 0, 135));
2768  p->drawPath(path);
2769  p->restore();
2770  break; }
2771  case PE_FrameTabBarBase:
2772  if (const QStyleOptionTabBarBaseV2 *tbb
2773  = qstyleoption_cast<const QStyleOptionTabBarBaseV2 *>(opt)) {
2774  if (tbb->documentMode) {
2775  p->save();
2776  drawTabBase(p, tbb, w);
2777  p->restore();
2778  return;
2779  }
2780 
2781  QRegion region(tbb->rect);
2782  region -= tbb->tabBarRect;
2783  p->save();
2784  p->setClipRegion(region);
2786  twf.QStyleOption::operator=(*tbb);
2787  twf.shape = tbb->shape;
2788  switch (getTabDirection(twf.shape)) {
2789  case kThemeTabNorth:
2790  twf.rect = twf.rect.adjusted(0, 0, 0, 10);
2791  break;
2792  case kThemeTabSouth:
2793  twf.rect = twf.rect.adjusted(0, -10, 0, 0);
2794  break;
2795  case kThemeTabWest:
2796  twf.rect = twf.rect.adjusted(0, 0, 10, 0);
2797  break;
2798  case kThemeTabEast:
2799  twf.rect = twf.rect.adjusted(0, -10, 0, 0);
2800  break;
2801  }
2802  proxy()->drawPrimitive(PE_FrameTabWidget, &twf, p, w);
2803  p->restore();
2804  }
2805  break;
2806  case PE_PanelTipLabel:
2808  break;
2809  case PE_FrameGroupBox:
2810  if (const QStyleOptionFrame *groupBox = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
2811  const QStyleOptionFrameV2 *frame2 = qstyleoption_cast<const QStyleOptionFrameV2 *>(opt);
2812  if (frame2 && frame2->features & QStyleOptionFrameV2::Flat) {
2813  QWindowsStyle::drawPrimitive(pe, groupBox, p, w);
2814  } else {
2815  HIThemeGroupBoxDrawInfo gdi;
2816  gdi.version = qt_mac_hitheme_version;
2817  gdi.state = tds;
2818  if (w && qobject_cast<QGroupBox *>(w->parentWidget()))
2819  gdi.kind = kHIThemeGroupBoxKindSecondary;
2820  else
2821  gdi.kind = kHIThemeGroupBoxKindPrimary;
2822  HIRect hirect = qt_hirectForQRect(opt->rect);
2823  HIThemeDrawGroupBox(&hirect, &gdi, cg, kHIThemeOrientationNormal);
2824  }
2825  }
2826  break;
2828  QPainterPath path;
2829  if (opt->state & State_Horizontal) {
2830  int xpoint = opt->rect.center().x();
2831  path.moveTo(xpoint + 0.5, opt->rect.top() + 1);
2832  path.lineTo(xpoint + 0.5, opt->rect.bottom());
2833  } else {
2834  int ypoint = opt->rect.center().y();
2835  path.moveTo(opt->rect.left() + 2 , ypoint + 0.5);
2836  path.lineTo(opt->rect.right() + 1, ypoint + 0.5);
2837  }
2838  QPainterPathStroker theStroker;
2839  theStroker.setCapStyle(Qt::FlatCap);
2840  theStroker.setDashPattern(QVector<qreal>() << 1 << 2);
2841  path = theStroker.createStroke(path);
2842  p->fillPath(path, QColor(0, 0, 0, 119));
2843  }
2844  break;
2845  case PE_FrameWindow:
2846  break;
2848  // The docwidget resize handle is drawn as a one-pixel wide line.
2849  p->save();
2850  if (opt->state & State_Horizontal) {
2851  p->setPen(QColor(160, 160, 160));
2852  p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
2853  } else {
2854  p->setPen(QColor(145, 145, 145));
2855  p->drawLine(opt->rect.topRight(), opt->rect.bottomRight());
2856  }
2857  p->restore();
2858  } break;
2860  p->save();
2861  QPainterPath path;
2862  int x = opt->rect.x() + 6;
2863  int y = opt->rect.y() + 5;
2864  static const int RectHeight = 2;
2865  if (opt->state & State_Horizontal) {
2866  while (y < opt->rect.height() - RectHeight - 6) {
2867  path.moveTo(x, y);
2868  path.addRect(x, y, RectHeight, RectHeight);
2869  y += 6;
2870  }
2871  } else {
2872  while (x < opt->rect.width() - RectHeight - 6) {
2873  path.moveTo(x, y);
2874  path.addRect(x, y, RectHeight, RectHeight);
2875  x += 6;
2876  }
2877  }
2878  p->setPen(Qt::NoPen);
2879  QColor dark = opt->palette.dark().color();
2880  dark.setAlphaF(0.75);
2881  QColor light = opt->palette.light().color();
2882  light.setAlphaF(0.6);
2883  p->fillPath(path, light);
2884  p->save();
2885  p->translate(1, 1);
2886  p->fillPath(path, dark);
2887  p->restore();
2888  p->translate(3, 3);
2889  p->fillPath(path, light);
2890  p->translate(1, 1);
2891  p->fillPath(path, dark);
2892  p->restore();
2893 
2894  break;
2895  }
2897  if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
2898  // In HITheme, up is down, down is up and hamburgers eat people.
2899  if (header->sortIndicator != QStyleOptionHeader::None)
2900  proxy()->drawPrimitive(
2901  (header->sortIndicator == QStyleOptionHeader::SortDown) ?
2902  PE_IndicatorArrowUp : PE_IndicatorArrowDown, header, p, w);
2903  }
2904  break;
2906  const int checkw = 8;
2907  const int checkh = 8;
2908  const int xoff = qMax(0, (opt->rect.width() - checkw) / 2);
2909  const int yoff = qMax(0, (opt->rect.width() - checkh) / 2);
2910  const int x1 = xoff + opt->rect.x();
2911  const int y1 = yoff + opt->rect.y() + checkw/2;
2912  const int x2 = xoff + opt->rect.x() + checkw/4;
2913  const int y2 = yoff + opt->rect.y() + checkh;
2914  const int x3 = xoff + opt->rect.x() + checkw;
2915  const int y3 = yoff + opt->rect.y();
2916 
2917  QVector<QLineF> a(2);
2918  a << QLineF(x1, y1, x2, y2);
2919  a << QLineF(x2, y2, x3, y3);
2920  if (opt->palette.currentColorGroup() == QPalette::Active) {
2921  if (opt->state & State_On)
2922  p->setPen(QPen(opt->palette.highlightedText().color(), 3));
2923  else
2924  p->setPen(QPen(opt->palette.text().color(), 3));
2925  } else {
2926  p->setPen(QPen(QColor(100, 100, 100), 3));
2927  }
2928  p->save();
2930  p->drawLines(a);
2931  p->restore();
2932  break; }
2937  case PE_IndicatorCheckBox: {
2938  bool drawColorless = (!(opt->state & State_Active))
2940  HIThemeButtonDrawInfo bdi;
2941  bdi.version = qt_mac_hitheme_version;
2942  bdi.state = tds;
2943  if (drawColorless && tds == kThemeStateInactive)
2944  bdi.state = kThemeStateActive;
2945  bdi.adornment = kThemeDrawIndicatorOnly;
2946  if (opt->state & State_HasFocus)
2947  bdi.adornment |= kThemeAdornmentFocus;
2948  bool isRadioButton = (pe == PE_Q3CheckListExclusiveIndicator
2949  || pe == PE_IndicatorRadioButton);
2950  switch (d->aquaSizeConstrain(opt, w)) {
2951  case QAquaSizeUnknown:
2952  case QAquaSizeLarge:
2953  if (isRadioButton)
2954  bdi.kind = kThemeRadioButton;
2955  else
2956  bdi.kind = kThemeCheckBox;
2957  break;
2958  case QAquaSizeMini:
2959  if (isRadioButton)
2960  bdi.kind = kThemeMiniRadioButton;
2961  else
2962  bdi.kind = kThemeMiniCheckBox;
2963  break;
2964  case QAquaSizeSmall:
2965  if (isRadioButton)
2966  bdi.kind = kThemeSmallRadioButton;
2967  else
2968  bdi.kind = kThemeSmallCheckBox;
2969  break;
2970  }
2971  if (opt->state & State_NoChange)
2972  bdi.value = kThemeButtonMixed;
2973  else if (opt->state & State_On)
2974  bdi.value = kThemeButtonOn;
2975  else
2976  bdi.value = kThemeButtonOff;
2977  HIRect macRect;
2979  macRect = qt_hirectForQRect(opt->rect);
2980  else
2981  macRect = qt_hirectForQRect(opt->rect);
2982  if (!drawColorless)
2983  HIThemeDrawButton(&macRect, &bdi, cg, kHIThemeOrientationNormal, 0);
2984  else
2985  d->drawColorlessButton(macRect, &bdi, p, opt);
2986  break; }
2987  case PE_FrameFocusRect:
2988  // Use the our own focus widget stuff.
2989  break;
2990  case PE_IndicatorBranch: {
2991  if (!(opt->state & State_Children))
2992  break;
2993  HIThemeButtonDrawInfo bi;
2994  bi.version = qt_mac_hitheme_version;
2995  bi.state = tds;
2996  if (tds == kThemeStateInactive && opt->palette.currentColorGroup() == QPalette::Active)
2997  bi.state = kThemeStateActive;
2998  if (opt->state & State_Sunken)
2999  bi.state |= kThemeStatePressed;
3000  bi.kind = kThemeDisclosureButton;
3001  if (opt->state & State_Open)
3002  bi.value = kThemeDisclosureDown;
3003  else
3004  bi.value = opt->direction == Qt::LeftToRight ? kThemeDisclosureRight : kThemeDisclosureLeft;
3005  bi.adornment = kThemeAdornmentNone;
3006  HIRect hirect = qt_hirectForQRect(opt->rect.adjusted(DisclosureOffset,0,-DisclosureOffset,0));
3007  HIThemeDrawButton(&hirect, &bi, cg, kHIThemeOrientationNormal, 0);
3008  break; }
3009 
3010  case PE_Frame: {
3011  QPen oldPen = p->pen();
3012  p->setPen(opt->palette.base().color().darker(140));
3013  p->drawRect(opt->rect.adjusted(0, 0, -1, -1));
3014  p->setPen(opt->palette.base().color().darker(180));
3015  p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
3016  p->setPen(oldPen);
3017  break; }
3018 
3019  case PE_FrameLineEdit:
3020  if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
3021  if (frame->state & State_Sunken) {
3022  QColor baseColor(frame->palette.background().color());
3023  HIThemeFrameDrawInfo fdi;
3024  fdi.version = qt_mac_hitheme_version;
3025  fdi.state = tds;
3026  SInt32 frame_size;
3027  if (pe == PE_FrameLineEdit) {
3028  fdi.kind = kHIThemeFrameTextFieldSquare;
3029  GetThemeMetric(kThemeMetricEditTextFrameOutset, &frame_size);
3030  if ((frame->state & State_ReadOnly) || !(frame->state & State_Enabled))
3031  fdi.state = kThemeStateInactive;
3032  } else {
3033  baseColor = QColor(150, 150, 150); //hardcoded since no query function --Sam
3034  fdi.kind = kHIThemeFrameListBox;
3035  GetThemeMetric(kThemeMetricListBoxFrameOutset, &frame_size);
3036  }
3037  fdi.isFocused = (frame->state & State_HasFocus);
3038  int lw = frame->lineWidth;
3039  if (lw <= 0)
3040  lw = proxy()->pixelMetric(PM_DefaultFrameWidth, frame, w);
3041  { //clear to base color
3042  p->save();
3043  p->setPen(QPen(baseColor, lw));
3044  p->setBrush(Qt::NoBrush);
3045  p->drawRect(frame->rect);
3046  p->restore();
3047  }
3048  HIRect hirect = qt_hirectForQRect(frame->rect,
3049  QRect(frame_size, frame_size,
3050  frame_size * 2, frame_size * 2));
3051 
3052  HIThemeDrawFrame(&hirect, &fdi, cg, kHIThemeOrientationNormal);
3053  } else {
3054  QWindowsStyle::drawPrimitive(pe, opt, p, w);
3055  }
3056  }
3057  break;
3058  case PE_PanelLineEdit:
3059  QWindowsStyle::drawPrimitive(pe, opt, p, w);
3060  // Draw the focus frame for widgets other than QLineEdit (e.g. for line edits in Webkit).
3061  // Focus frame is drawn outside the rectangle passed in the option-rect.
3062  if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
3063  if ((opt->state & State_HasFocus) && !qobject_cast<const QLineEdit*>(w)) {
3066  QStyleOptionFrame focusFrame = *panel;
3067  focusFrame.rect = panel->rect.adjusted(-hmargin, -vmargin, hmargin, vmargin);
3068  drawControl(CE_FocusFrame, &focusFrame, p, w);
3069  }
3070  }
3071 
3072  break;
3073  case PE_FrameTabWidget:
3074  if (const QStyleOptionTabWidgetFrame *twf
3075  = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
3076  HIRect hirect = qt_hirectForQRect(twf->rect);
3077  HIThemeTabPaneDrawInfo tpdi;
3078  tpdi.version = qt_mac_hitheme_tab_version();
3079  tpdi.state = tds;
3080  tpdi.direction = getTabDirection(twf->shape);
3081  tpdi.size = kHIThemeTabSizeNormal;
3082  tpdi.kind = kHIThemeTabKindNormal;
3083  tpdi.adornment = kHIThemeTabPaneAdornmentNormal;
3084  HIThemeDrawTabPane(&hirect, &tpdi, cg, kHIThemeOrientationNormal);
3085  }
3086  break;
3087  case PE_PanelScrollAreaCorner: {
3088  const QBrush brush(opt->palette.brush(QPalette::Base));
3089  p->fillRect(opt->rect, brush);
3090  p->setPen(QPen(QColor(217, 217, 217)));
3091  p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
3092  p->drawLine(opt->rect.topLeft(), opt->rect.bottomLeft());
3093  } break;
3094  case PE_FrameStatusBarItem:
3095  break;
3096  case PE_IndicatorTabClose: {
3097  bool hover = (opt->state & State_MouseOver);
3098  bool selected = (opt->state & State_Selected);
3099  bool active = (opt->state & State_Active);
3100  drawTabCloseButton(p, hover, active, selected);
3101  } break;
3102  case PE_PanelStatusBar: {
3104  QWindowsStyle::drawPrimitive(pe, opt, p, w);
3105  break;
3106  }
3107  // Use the Leopard style only if the status bar is the status bar for a
3108  // QMainWindow with a unifed toolbar.
3109  if (w == 0 || w->parent() == 0 || qobject_cast<QMainWindow *>(w->parent()) == 0 ||
3110  qobject_cast<QMainWindow *>(w->parent())->unifiedTitleAndToolBarOnMac() == false ) {
3111  QWindowsStyle::drawPrimitive(pe, opt, p, w);
3112  break;
3113  }
3114 
3115  // Fill the status bar with the titlebar gradient.
3116  QLinearGradient linearGrad(0, opt->rect.top(), 0, opt->rect.bottom());
3117  if (opt->state & QStyle::State_Active) {
3118  linearGrad.setColorAt(0, titlebarGradientActiveBegin);
3119  linearGrad.setColorAt(1, titlebarGradientActiveEnd);
3120  } else {
3121  linearGrad.setColorAt(0, titlebarGradientInactiveBegin);
3122  linearGrad.setColorAt(1, titlebarGradientInactiveEnd);
3123  }
3124  p->fillRect(opt->rect, linearGrad);
3125 
3126  // Draw the black separator line at the top of the status bar.
3127  if (opt->state & QStyle::State_Active)
3129  else
3131  p->drawLine(opt->rect.left(), opt->rect.top(), opt->rect.right(), opt->rect.top());
3132 
3133  break;
3134  }
3135 
3136  default:
3137  QWindowsStyle::drawPrimitive(pe, opt, p, w);
3138  break;
3139  }
3140 }
3141 
3142 static inline QPixmap darkenPixmap(const QPixmap &pixmap)
3143 {
3145  int imgh = img.height();
3146  int imgw = img.width();
3147  int h, s, v, a;
3148  QRgb pixel;
3149  for (int y = 0; y < imgh; ++y) {
3150  for (int x = 0; x < imgw; ++x) {
3151  pixel = img.pixel(x, y);
3152  a = qAlpha(pixel);
3153  QColor hsvColor(pixel);
3154  hsvColor.getHsv(&h, &s, &v);
3155  s = qMin(100, s * 2);
3156  v = v / 2;
3157  hsvColor.setHsv(h, s, v);
3158  pixel = hsvColor.rgb();
3159  img.setPixel(x, y, qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel), a));
3160  }
3161  }
3162  return QPixmap::fromImage(img);
3163 }
3164 
3165 
3166 
3168  const QWidget *w) const
3169 {
3170  ThemeDrawState tds = d->getDrawState(opt->state);
3171  QMacCGContext cg(p);
3172  switch (ce) {
3173  case CE_HeaderSection:
3174  if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
3175  HIThemeButtonDrawInfo bdi;
3176  bdi.version = qt_mac_hitheme_version;
3177  State flags = header->state;
3178  QRect ir = header->rect;
3179  bdi.kind = kThemeListHeaderButton;
3180  bdi.adornment = kThemeAdornmentNone;
3181  bdi.state = kThemeStateActive;
3182 
3183  if (flags & State_On)
3184  bdi.value = kThemeButtonOn;
3185  else
3186  bdi.value = kThemeButtonOff;
3187 
3188  if (header->orientation == Qt::Horizontal){
3189  switch (header->position) {
3191  ir.adjust(-1, -1, 0, 0);
3192  break;
3194  ir.adjust(-1, -1, 0, 0);
3195  break;
3198  ir.adjust(-1, -1, 1, 0);
3199  break;
3200  default:
3201  break;
3202  }
3203 
3204  if (header->position != QStyleOptionHeader::Beginning
3205  && header->position != QStyleOptionHeader::OnlyOneSection) {
3206  bdi.adornment = header->direction == Qt::LeftToRight
3207  ? kThemeAdornmentHeaderButtonLeftNeighborSelected
3208  : kThemeAdornmentHeaderButtonRightNeighborSelected;
3209  }
3210  }
3211 
3212  if (flags & State_Active) {
3213  if (!(flags & State_Enabled))
3214  bdi.state = kThemeStateUnavailable;
3215  else if (flags & State_Sunken)
3216  bdi.state = kThemeStatePressed;
3217  } else {
3218  if (flags & State_Enabled)
3219  bdi.state = kThemeStateInactive;
3220  else
3221  bdi.state = kThemeStateUnavailableInactive;
3222  }
3223 
3224  if (header->sortIndicator != QStyleOptionHeader::None) {
3225  bdi.value = kThemeButtonOn;
3226  if (header->sortIndicator == QStyleOptionHeader::SortDown)
3227  bdi.adornment = kThemeAdornmentHeaderButtonSortUp;
3228  }
3229  if (flags & State_HasFocus)
3230  bdi.adornment = kThemeAdornmentFocus;
3231 
3232  ir = visualRect(header->direction, header->rect, ir);
3233  HIRect bounds = qt_hirectForQRect(ir);
3234 
3235  bool noVerticalHeader = true;
3236  if (w)
3237  if (const QTableView *table = qobject_cast<const QTableView *>(w->parentWidget()))
3238  noVerticalHeader = !table->verticalHeader()->isVisible();
3239 
3240  bool drawTopBorder = header->orientation == Qt::Horizontal;
3241  bool drawLeftBorder = header->orientation == Qt::Vertical
3242  || header->position == QStyleOptionHeader::OnlyOneSection
3243  || (header->position == QStyleOptionHeader::Beginning && noVerticalHeader);
3244  d->drawTableHeader(bounds, drawTopBorder, drawLeftBorder, bdi, p);
3245  }
3246  break;
3247  case CE_HeaderLabel:
3248  if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
3249  QRect textr = header->rect;
3250  if (!header->icon.isNull()) {
3252  if (opt->state & State_Enabled)
3253  mode = QIcon::Normal;
3254  QPixmap pixmap = header->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize), mode);
3255 
3256  QRect pixr = header->rect;
3257  pixr.setY(header->rect.center().y() - (pixmap.height() - 1) / 2);
3258  proxy()->drawItemPixmap(p, pixr, Qt::AlignVCenter, pixmap);
3259  textr.translate(pixmap.width() + 2, 0);
3260  }
3261 
3262  proxy()->drawItemText(p, textr, header->textAlignment | Qt::AlignVCenter, header->palette,
3263  header->state & State_Enabled, header->text, QPalette::ButtonText);
3264  }
3265  break;
3266  case CE_ToolButtonLabel:
3267  if (const QStyleOptionToolButton *tb = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
3268  QStyleOptionToolButton myTb = *tb;
3269  myTb.state &= ~State_AutoRaise;
3270  if (w && qobject_cast<QToolBar *>(w->parentWidget())) {
3271  QRect cr = tb->rect;
3272  int shiftX = 0;
3273  int shiftY = 0;
3274  bool needText = false;
3275  int alignment = 0;
3276  bool down = tb->state & (State_Sunken | State_On);
3277  if (down) {
3278  shiftX = proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, w);
3279  shiftY = proxy()->pixelMetric(PM_ButtonShiftVertical, tb, w);
3280  }
3281  // The down state is special for QToolButtons in a toolbar on the Mac
3282  // The text is a bit bolder and gets a drop shadow and the icons are also darkened.
3283  // This doesn't really fit into any particular case in QIcon, so we
3284  // do the majority of the work ourselves.
3285  if (!(tb->features & QStyleOptionToolButton::Arrow)) {
3286  Qt::ToolButtonStyle tbstyle = tb->toolButtonStyle;
3287  if (tb->icon.isNull() && !tb->text.isEmpty())
3288  tbstyle = Qt::ToolButtonTextOnly;
3289 
3290  switch (tbstyle) {
3291  case Qt::ToolButtonTextOnly: {
3292  needText = true;
3293  alignment = Qt::AlignCenter;
3294  break; }
3298  QRect pr = cr;
3299  QIcon::Mode iconMode = (tb->state & State_Enabled) ? QIcon::Normal
3300  : QIcon::Disabled;
3301  QIcon::State iconState = (tb->state & State_On) ? QIcon::On
3302  : QIcon::Off;
3303  QPixmap pixmap = tb->icon.pixmap(tb->rect.size().boundedTo(tb->iconSize), iconMode, iconState);
3304 
3305  // Draw the text if it's needed.
3306  if (tb->toolButtonStyle != Qt::ToolButtonIconOnly) {
3307  needText = true;
3308  if (tb->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
3309  QMainWindow *mw = qobject_cast<QMainWindow *>(w->window());
3310  if (mw && mw->unifiedTitleAndToolBarOnMac()) {
3311  pr.setHeight(pixmap.size().height());
3312  cr.adjust(0, pr.bottom() + 1, 0, 1);
3313  } else {
3314  pr.setHeight(pixmap.size().height() + 6);
3315  cr.adjust(0, pr.bottom(), 0, -3);
3316  }
3317  alignment |= Qt::AlignCenter;
3318  } else {
3319  pr.setWidth(pixmap.width() + 8);
3320  cr.adjust(pr.right(), 0, 0, 0);
3321  alignment |= Qt::AlignLeft | Qt::AlignVCenter;
3322  }
3323  }
3324  if (opt->state & State_Sunken) {
3325  pr.translate(shiftX, shiftY);
3326  pixmap = darkenPixmap(pixmap);
3327  }
3328  proxy()->drawItemPixmap(p, pr, Qt::AlignCenter, pixmap);
3329  break; }
3330  default:
3331  Q_ASSERT(false);
3332  break;
3333  }
3334 
3335  if (needText) {
3336  QPalette pal = tb->palette;
3338  if (!proxy()->styleHint(SH_UnderlineShortcut, tb, w))
3339  alignment |= Qt::TextHideMnemonic;
3340  if (down)
3341  cr.translate(shiftX, shiftY);
3343  && (tbstyle == Qt::ToolButtonTextOnly
3344  || (tbstyle != Qt::ToolButtonTextOnly && !down))) {
3345  QPen pen = p->pen();
3346  QColor light = down ? Qt::black : Qt::white;
3347  light.setAlphaF(0.375f);
3348  p->setPen(light);
3349  p->drawText(cr.adjusted(0, 1, 0, 1), alignment, tb->text);
3350  p->setPen(pen);
3351  if (down && tbstyle == Qt::ToolButtonTextOnly) {
3352  pal = QApplication::palette("QMenu");
3353  pal.setCurrentColorGroup(tb->palette.currentColorGroup());
3355  }
3356  }
3357  proxy()->drawItemText(p, cr, alignment, pal,
3358  tb->state & State_Enabled, tb->text, role);
3360  (tb->state & State_Sunken)) {
3361  // Draw a "drop shadow" in earlier versions.
3362  proxy()->drawItemText(p, cr.adjusted(0, 1, 0, 1), alignment,
3363  tb->palette, tb->state & State_Enabled, tb->text);
3364  }
3365  }
3366  } else {
3367  QWindowsStyle::drawControl(ce, &myTb, p, w);
3368  }
3369  } else {
3370  QWindowsStyle::drawControl(ce, &myTb, p, w);
3371  }
3372  }
3373  break;
3374  case CE_ToolBoxTabShape:
3375  QCommonStyle::drawControl(ce, opt, p, w);
3376  break;
3377  case CE_PushButtonBevel:
3378  if (const QStyleOptionButton *btn = ::qstyleoption_cast<const QStyleOptionButton *>(opt)) {
3379  if (!(btn->state & (State_Raised | State_Sunken | State_On)))
3380  break;
3381 
3382  if (btn->features & QStyleOptionButton::CommandLinkButton) {
3383  QWindowsStyle::drawControl(ce, opt, p, w);
3384  break;
3385  }
3386 
3387  HIThemeButtonDrawInfo bdi;
3388  d->initHIThemePushButton(btn, w, tds, &bdi);
3389  if (btn->features & QStyleOptionButton::DefaultButton
3391  bdi.adornment |= kThemeAdornmentDefault;
3392  bdi.animation.time.start = d->defaultButtonStart;
3393  bdi.animation.time.current = CFAbsoluteTimeGetCurrent();
3394  if (d->timerID <= -1)
3395  QMetaObject::invokeMethod(d, "startAnimationTimer", Qt::QueuedConnection);
3396  }
3397  // Unlike Carbon, we want the button to always be drawn inside its bounds.
3398  // Therefore, make the button a bit smaller, so that even if it got focus,
3399  // the focus 'shadow' will be inside.
3400  HIRect newRect = qt_hirectForQRect(btn->rect);
3401  if (bdi.kind == kThemePushButton || bdi.kind == kThemePushButtonSmall) {
3402  newRect.origin.x += QMacStylePrivate::PushButtonLeftOffset;
3403  newRect.origin.y += QMacStylePrivate::PushButtonTopOffset;
3404  newRect.size.width -= QMacStylePrivate::PushButtonRightOffset;
3405  newRect.size.height -= QMacStylePrivate::PushButtonBottomOffset;
3406  } else if (bdi.kind == kThemePushButtonMini) {
3407  newRect.origin.x += QMacStylePrivate::PushButtonLeftOffset - 2;
3408  newRect.origin.y += QMacStylePrivate::PushButtonTopOffset;
3409  newRect.size.width -= QMacStylePrivate::PushButtonRightOffset - 4;
3410  }
3411  HIThemeDrawButton(&newRect, &bdi, cg, kHIThemeOrientationNormal, 0);
3412 
3413  if (btn->features & QStyleOptionButton::HasMenu) {
3414  int mbi = proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator, btn, w);
3415  QRect ir = btn->rect;
3416  HIRect arrowRect = CGRectMake(ir.right() - mbi - QMacStylePrivate::PushButtonRightOffset,
3417  ir.height() / 2 - 4, mbi, ir.height() / 2);
3418  bool drawColorless = btn->palette.currentColorGroup() == QPalette::Active;
3419  if (drawColorless && tds == kThemeStateInactive)
3420  tds = kThemeStateActive;
3421 
3422  HIThemePopupArrowDrawInfo pdi;
3423  pdi.version = qt_mac_hitheme_version;
3424  pdi.state = tds;
3425  pdi.orientation = kThemeArrowDown;
3426  if (arrowRect.size.width < 8.)
3427  pdi.size = kThemeArrow5pt;
3428  else
3429  pdi.size = kThemeArrow9pt;
3430  HIThemeDrawPopupArrow(&arrowRect, &pdi, cg, kHIThemeOrientationNormal);
3431  }
3432  }
3433  break;
3434  case CE_PushButtonLabel:
3435  if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
3436  // We really don't want the label to be drawn the same as on
3437  // windows style if it has an icon and text, then it should be more like a
3438  // tab. So, cheat a little here. However, if it *is* only an icon
3439  // the windows style works great, so just use that implementation.
3440  bool hasMenu = btn->features & QStyleOptionButton::HasMenu;
3441  bool hasIcon = !btn->icon.isNull();
3442  bool hasText = !btn->text.isEmpty();
3443  if (!hasIcon && !hasMenu) {
3444  // ### this is really overly difficult, simplify.
3445  // It basically tries to get the right font for "small" and "mini" icons.
3446  QFont oldFont = p->font();
3447  QFont newFont = qt_app_fonts_hash()->value("QPushButton", QFont());
3448  ThemeFontID themeId = kThemePushButtonFont;
3449  if (oldFont == newFont) { // Yes, use HITheme to draw the text for small sizes.
3450  switch (d->aquaSizeConstrain(opt, w)) {
3451  default:
3452  break;
3453  case QAquaSizeSmall:
3454  themeId = kThemeSmallSystemFont;
3455  break;
3456  case QAquaSizeMini:
3457  themeId = kThemeMiniSystemFont;
3458  break;
3459  }
3460  }
3461  if (themeId == kThemePushButtonFont) {
3462  QWindowsStyle::drawControl(ce, btn, p, w);
3463  } else {
3464  p->save();
3465  CGContextSetShouldAntialias(cg, true);
3466  CGContextSetShouldSmoothFonts(cg, true);
3467  HIThemeTextInfo tti;
3468  tti.version = qt_mac_hitheme_version;
3469  tti.state = tds;
3470  QColor textColor = btn->palette.buttonText().color();
3471  CGFloat colorComp[] = { textColor.redF(), textColor.greenF(),
3472  textColor.blueF(), textColor.alphaF() };
3473  CGContextSetFillColorSpace(cg, QCoreGraphicsPaintEngine::macGenericColorSpace());
3474  CGContextSetFillColor(cg, colorComp);
3475  tti.fontID = themeId;
3476  tti.horizontalFlushness = kHIThemeTextHorizontalFlushCenter;
3477  tti.verticalFlushness = kHIThemeTextVerticalFlushCenter;
3478  tti.options = kHIThemeTextBoxOptionNone;
3479  tti.truncationPosition = kHIThemeTextTruncationNone;
3480  tti.truncationMaxLines = 1 + btn->text.count(QLatin1Char('\n'));
3481  QCFString buttonText = qt_mac_removeMnemonics(btn->text);
3482  QRect r = btn->rect;
3483  HIRect bounds = qt_hirectForQRect(r);
3484  HIThemeDrawTextBox(buttonText, &bounds, &tti,
3485  cg, kHIThemeOrientationNormal);
3486  p->restore();
3487  }
3488  } else {
3489  if (hasIcon && !hasText) {
3490  QWindowsStyle::drawControl(ce, btn, p, w);
3491  } else {
3492  QRect freeContentRect = btn->rect;
3493  QRect textRect = itemTextRect(
3494  btn->fontMetrics, freeContentRect, Qt::AlignCenter, btn->state & State_Enabled, btn->text);
3495  if (hasMenu)
3496  textRect.adjust(-1, 0, -1, 0);
3497  // Draw the icon:
3498  if (hasIcon) {
3499  int contentW = textRect.width();
3500  if (hasMenu)
3501  contentW += proxy()->pixelMetric(PM_MenuButtonIndicator) + 4;
3502  QIcon::Mode mode = btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
3503  if (mode == QIcon::Normal && btn->state & State_HasFocus)
3504  mode = QIcon::Active;
3505  // Decide if the icon is should be on or off:
3506  QIcon::State state = QIcon::Off;
3507  if (btn->state & State_On)
3508  state = QIcon::On;
3509  QPixmap pixmap = btn->icon.pixmap(btn->iconSize, mode, state);
3510  contentW += pixmap.width() + QMacStylePrivate::PushButtonContentPadding;
3511  int iconLeftOffset = freeContentRect.x() + (freeContentRect.width() - contentW) / 2;
3512  int iconTopOffset = freeContentRect.y() + (freeContentRect.height() - pixmap.height()) / 2;
3513  QRect iconDestRect(iconLeftOffset, iconTopOffset, pixmap.width(), pixmap.height());
3514  QRect visualIconDestRect = visualRect(btn->direction, freeContentRect, iconDestRect);
3515  proxy()->drawItemPixmap(p, visualIconDestRect, Qt::AlignLeft | Qt::AlignVCenter, pixmap);
3516  int newOffset = iconDestRect.x() + iconDestRect.width()
3518  textRect.adjust(newOffset, 0, newOffset, 0);
3519  }
3520  // Draw the text:
3521  if (hasText) {
3522  textRect = visualRect(btn->direction, freeContentRect, textRect);
3523  proxy()->drawItemText(p, textRect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, btn->palette,
3524  (btn->state & State_Enabled), btn->text, QPalette::ButtonText);
3525  }
3526  }
3527  }
3528  }
3529  break;
3530  case CE_ComboBoxLabel:
3531  if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
3532  QStyleOptionComboBox comboCopy = *cb;
3533  comboCopy.direction = Qt::LeftToRight;
3534  QWindowsStyle::drawControl(CE_ComboBoxLabel, &comboCopy, p, w);
3535  }
3536  break;
3537  case CE_TabBarTabShape:
3538  if (const QStyleOptionTab *tabOpt = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
3539 
3540  if (const QStyleOptionTabV3 *tabOptV3 = qstyleoption_cast<const QStyleOptionTabV3 *>(opt)) {
3541  if (tabOptV3->documentMode) {
3542  p->save();
3543  QRect tabRect = tabOptV3->rect;
3544  drawTabShape(p, tabOptV3);
3545  p->restore();
3546  return;
3547  }
3548  }
3549  HIThemeTabDrawInfo tdi;
3550  tdi.version = 1;
3551  tdi.style = kThemeTabNonFront;
3552  tdi.direction = getTabDirection(tabOpt->shape);
3553  switch (d->aquaSizeConstrain(opt, w)) {
3554  default:
3555  case QAquaSizeUnknown:
3556  case QAquaSizeLarge:
3557  tdi.size = kHIThemeTabSizeNormal;
3558  break;
3559  case QAquaSizeSmall:
3560  tdi.size = kHIThemeTabSizeSmall;
3561  break;
3562  case QAquaSizeMini:
3563  tdi.size = kHIThemeTabSizeMini;
3564  break;
3565  }
3566  bool verticalTabs = tdi.direction == kThemeTabWest || tdi.direction == kThemeTabEast;
3567  QRect tabRect = tabOpt->rect;
3568 
3569  bool selected = tabOpt->state & State_Selected;
3570  if (selected) {
3571  if (!(tabOpt->state & State_Active))
3572  tdi.style = kThemeTabFrontUnavailable;
3573  else if (!(tabOpt->state & State_Enabled))
3574  tdi.style = kThemeTabFrontInactive;
3575  else
3576  tdi.style = kThemeTabFront;
3577  } else if (!(tabOpt->state & State_Active)) {
3578  tdi.style = kThemeTabNonFrontUnavailable;
3579  } else if (!(tabOpt->state & State_Enabled)) {
3580  tdi.style = kThemeTabNonFrontInactive;
3581  } else if (tabOpt->state & State_Sunken) {
3582  tdi.style = kThemeTabFrontInactive; // (should be kThemeTabNonFrontPressed)
3583  }
3584  if (tabOpt->state & State_HasFocus)
3585  tdi.adornment = kHIThemeTabAdornmentFocus;
3586  else
3587  tdi.adornment = kHIThemeTabAdornmentNone;
3588  tdi.kind = kHIThemeTabKindNormal;
3589  if (!verticalTabs)
3590  tabRect.setY(tabRect.y() - 1);
3591  else
3592  tabRect.setX(tabRect.x() - 1);
3593  QStyleOptionTab::TabPosition tp = tabOpt->position;
3594  QStyleOptionTab::SelectedPosition sp = tabOpt->selectedPosition;
3595  if (tabOpt->direction == Qt::RightToLeft && !verticalTabs) {
3598  else if (sp == QStyleOptionTab::PreviousIsSelected)
3600  switch (tp) {
3602  tp = QStyleOptionTab::End;
3603  break;
3604  case QStyleOptionTab::End:
3606  break;
3607  default:
3608  break;
3609  }
3610  }
3611  bool stretchTabs = (!verticalTabs && tabRect.height() > 22) || (verticalTabs && tabRect.width() > 22);
3612 
3613  switch (tp) {
3615  tdi.position = kHIThemeTabPositionFirst;
3616  if (sp != QStyleOptionTab::NextIsSelected || stretchTabs)
3617  tdi.adornment |= kHIThemeTabAdornmentTrailingSeparator;
3618  break;
3620  tdi.position = kHIThemeTabPositionMiddle;
3621  if (selected)
3622  tdi.adornment |= kHIThemeTabAdornmentLeadingSeparator;
3623  if (sp != QStyleOptionTab::NextIsSelected || stretchTabs) // Also when we're selected.
3624  tdi.adornment |= kHIThemeTabAdornmentTrailingSeparator;
3625  break;
3626  case QStyleOptionTab::End:
3627  tdi.position = kHIThemeTabPositionLast;
3628  if (selected)
3629  tdi.adornment |= kHIThemeTabAdornmentLeadingSeparator;
3630  break;
3632  tdi.position = kHIThemeTabPositionOnly;
3633  break;
3634  }
3635  // HITheme doesn't stretch its tabs. Therefore we have to cheat and do the job ourselves.
3636  if (stretchTabs) {
3637  HIRect hirect = CGRectMake(0, 0, 23, 23);
3638  QPixmap pm(23, 23);
3639  pm.fill(Qt::transparent);
3640  {
3641  QMacCGContext pmcg(&pm);
3642  HIThemeDrawTab(&hirect, &tdi, pmcg, kHIThemeOrientationNormal, 0);
3643  }
3644  QStyleHelper::drawBorderPixmap(pm, p, tabRect, 7, 7, 7, 7);
3645  } else {
3646  HIRect hirect = qt_hirectForQRect(tabRect);
3647  HIThemeDrawTab(&hirect, &tdi, cg, kHIThemeOrientationNormal, 0);
3648  }
3649  }
3650  break;
3651  case CE_TabBarTabLabel:
3652  if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
3653  QStyleOptionTabV3 myTab = *tab;
3654  ThemeTabDirection ttd = getTabDirection(myTab.shape);
3655  bool verticalTabs = ttd == kThemeTabWest || ttd == kThemeTabEast;
3656  bool selected = (myTab.state & QStyle::State_Selected);
3657  bool usingModernOSX = QSysInfo::MacintoshVersion > QSysInfo::MV_10_6;
3658 
3659  if (usingModernOSX && selected && !myTab.documentMode)
3661 
3662  // Check to see if we use have the same as the system font
3663  // (QComboMenuItem is internal and should never be seen by the
3664  // outside world, unless they read the source, in which case, it's
3665  // their own fault).
3666  bool nonDefaultFont = p->font() != qt_app_fonts_hash()->value("QComboMenuItem");
3667  if ((usingModernOSX && selected) || verticalTabs || nonDefaultFont || !tab->icon.isNull()
3668  || !myTab.leftButtonSize.isNull() || !myTab.rightButtonSize.isNull()) {
3669  int heightOffset = 0;
3670  if (verticalTabs) {
3671  heightOffset = -1;
3672  } else if (nonDefaultFont) {
3673  if (p->fontMetrics().height() == myTab.rect.height())
3674  heightOffset = 2;
3675  }
3676  myTab.rect.setHeight(myTab.rect.height() + heightOffset);
3677 
3678  if (myTab.documentMode || (usingModernOSX && selected)) {
3679  p->save();
3680  rotateTabPainter(p, myTab.shape, myTab.rect);
3681 
3682  QColor shadowColor = QColor(myTab.documentMode ? Qt::white : Qt::black);
3683  shadowColor.setAlpha(75);
3684  QPalette np = tab->palette;
3685  np.setColor(QPalette::WindowText, shadowColor);
3686 
3687  QRect nr = subElementRect(SE_TabBarTabText, opt, w);
3688  nr.moveTop(-1);
3690  proxy()->drawItemText(p, nr, alignment, np, tab->state & State_Enabled,
3691  tab->text, QPalette::WindowText);
3692  p->restore();
3693  }
3694 
3695  QCommonStyle::drawControl(ce, &myTab, p, w);
3696  } else {
3697  p->save();
3698  CGContextSetShouldAntialias(cg, true);
3699  CGContextSetShouldSmoothFonts(cg, true);
3700  HIThemeTextInfo tti;
3701  tti.version = qt_mac_hitheme_version;
3702  tti.state = tds;
3703  QColor textColor = myTab.palette.windowText().color();
3704  CGFloat colorComp[] = { textColor.redF(), textColor.greenF(),
3705  textColor.blueF(), textColor.alphaF() };
3706  CGContextSetFillColorSpace(cg, QCoreGraphicsPaintEngine::macGenericColorSpace());
3707  CGContextSetFillColor(cg, colorComp);
3708  switch (d->aquaSizeConstrain(opt, w)) {
3709  default:
3710  case QAquaSizeUnknown:
3711  case QAquaSizeLarge:
3712  tti.fontID = kThemeSystemFont;
3713  break;
3714  case QAquaSizeSmall:
3715  tti.fontID = kThemeSmallSystemFont;
3716  break;
3717  case QAquaSizeMini:
3718  tti.fontID = kThemeMiniSystemFont;
3719  break;
3720  }
3721  tti.horizontalFlushness = kHIThemeTextHorizontalFlushCenter;
3722  tti.verticalFlushness = kHIThemeTextVerticalFlushCenter;
3723  tti.options = verticalTabs ? kHIThemeTextBoxOptionStronglyVertical : kHIThemeTextBoxOptionNone;
3724  tti.truncationPosition = kHIThemeTextTruncationNone;
3725  tti.truncationMaxLines = 1 + myTab.text.count(QLatin1Char('\n'));
3726  QCFString tabText = qt_mac_removeMnemonics(myTab.text);
3727  QRect r = myTab.rect.adjusted(0, 0, 0, -1);
3728  HIRect bounds = qt_hirectForQRect(r);
3729  HIThemeDrawTextBox(tabText, &bounds, &tti, cg, kHIThemeOrientationNormal);
3730  p->restore();
3731  }
3732  }
3733  break;
3734  case CE_DockWidgetTitle:
3735  if (const QDockWidget *dockWidget = qobject_cast<const QDockWidget *>(w)) {
3736  bool floating = dockWidget->isFloating();
3737  if (floating) {
3738  ThemeDrawState tds = d->getDrawState(opt->state);
3739  HIThemeWindowDrawInfo wdi;
3740  wdi.version = qt_mac_hitheme_version;
3741  wdi.state = tds;
3742  wdi.windowType = kThemeMovableDialogWindow;
3743  wdi.titleHeight = opt->rect.height();
3744  wdi.titleWidth = opt->rect.width();
3745  wdi.attributes = 0;
3746 
3747  HIRect titleBarRect;
3748  HIRect tmpRect = qt_hirectForQRect(opt->rect);
3749  {
3750  QCFType<HIShapeRef> titleRegion;
3751  QRect newr = opt->rect.adjusted(0, 0, 2, 0);
3752  HIThemeGetWindowShape(&tmpRect, &wdi, kWindowTitleBarRgn, &titleRegion);
3753  ptrHIShapeGetBounds(titleRegion, &tmpRect);
3754  newr.translate(newr.x() - int(tmpRect.origin.x), newr.y() - int(tmpRect.origin.y));
3755  titleBarRect = qt_hirectForQRect(newr);
3756  }
3757  QMacCGContext cg(p);
3758  HIThemeDrawWindowFrame(&titleBarRect, &wdi, cg, kHIThemeOrientationNormal, 0);
3759  } else {
3760  // fill title bar background
3761  QLinearGradient linearGrad(0, opt->rect.top(), 0, opt->rect.bottom());
3762  linearGrad.setColorAt(0, mainWindowGradientBegin);
3763  linearGrad.setColorAt(1, mainWindowGradientEnd);
3764  p->fillRect(opt->rect, linearGrad);
3765 
3766  // draw horizontal lines at top and bottom
3767  p->save();
3769  p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
3771  p->drawLine(opt->rect.bottomLeft(), opt->rect.bottomRight());
3772  p->restore();
3773  }
3774  }
3775 
3776  // Draw the text...
3777  if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) {
3778  if (!dwOpt->title.isEmpty()) {
3779  const QStyleOptionDockWidgetV2 *v2
3781  bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
3782 
3783  QRect titleRect = subElementRect(SE_DockWidgetTitleBarText, opt, w);
3784  if (verticalTitleBar) {
3785  QRect rect = dwOpt->rect;
3786  QRect r = rect;
3787  QSize s = r.size();
3788  s.transpose();
3789  r.setSize(s);
3790 
3791  titleRect = QRect(r.left() + rect.bottom()
3792  - titleRect.bottom(),
3793  r.top() + titleRect.left() - rect.left(),
3794  titleRect.height(), titleRect.width());
3795 
3796  p->translate(r.left(), r.top() + r.width());
3797  p->rotate(-90);
3798  p->translate(-r.left(), -r.top());
3799  }
3800 
3801  QFont oldFont = p->font();
3802  p->setFont(qt_app_fonts_hash()->value("QToolButton", p->font()));
3803  QString text = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight,
3804  titleRect.width());
3805  drawItemText(p, titleRect,
3806  Qt::AlignCenter | Qt::TextShowMnemonic, dwOpt->palette,
3807  dwOpt->state & State_Enabled, text,
3809  p->setFont(oldFont);
3810  }
3811  }
3812  break;
3813  case CE_FocusFrame: {
3814  int xOff = proxy()->pixelMetric(PM_FocusFrameHMargin, opt, w) + 1;
3815  int yOff = proxy()->pixelMetric(PM_FocusFrameVMargin, opt, w) + 1;
3816  HIRect hirect = CGRectMake(xOff+opt->rect.x(), yOff+opt->rect.y(), opt->rect.width() - 2 * xOff,
3817  opt->rect.height() - 2 * yOff);
3818  HIThemeDrawFocusRect(&hirect, true, QMacCGContext(p), kHIThemeOrientationNormal);
3819  break; }
3820  case CE_MenuItem:
3821  case CE_MenuEmptyArea:
3822  if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
3823  p->fillRect(mi->rect, opt->palette.background());
3824  QAquaWidgetSize widgetSize = d->aquaSizeConstrain(opt, w);
3825  int tabwidth = mi->tabWidth;
3826  int maxpmw = mi->maxIconWidth;
3827  bool active = mi->state & State_Selected;
3828  bool enabled = mi->state & State_Enabled;
3829  HIRect menuRect = qt_hirectForQRect(mi->menuRect);
3830  HIRect itemRect = qt_hirectForQRect(mi->rect);
3831  HIThemeMenuItemDrawInfo mdi;
3832  mdi.version = qt_mac_hitheme_version;
3833  mdi.itemType = kThemeMenuItemPlain;
3834  if (!mi->icon.isNull())
3835  mdi.itemType |= kThemeMenuItemHasIcon;
3836  if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
3837  mdi.itemType |= kThemeMenuItemHierarchical | kThemeMenuItemHierBackground;
3838  else
3839  mdi.itemType |= kThemeMenuItemPopUpBackground;
3840  if (enabled)
3841  mdi.state = kThemeMenuActive;
3842  else
3843  mdi.state = kThemeMenuDisabled;
3844  if (active)
3845  mdi.state |= kThemeMenuSelected;
3846  QRect contentRect;
3847  if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
3848  // First arg should be &menurect, but wacky stuff happens then.
3849  HIThemeDrawMenuSeparator(&itemRect, &itemRect, &mdi,
3850  cg, kHIThemeOrientationNormal);
3851  break;
3852  } else {
3853  HIRect cr;
3854  bool needAlpha = mi->palette.color(QPalette::Button) == Qt::transparent;
3855  if (needAlpha) {
3856  needAlpha = true;
3857  CGContextSaveGState(cg);
3858  CGContextSetAlpha(cg, 0.0);
3859  }
3860  HIThemeDrawMenuItem(&menuRect, &itemRect, &mdi,
3861  cg, kHIThemeOrientationNormal, &cr);
3862  if (needAlpha)
3863  CGContextRestoreGState(cg);
3864  if (ce == CE_MenuEmptyArea)
3865  break;
3866  contentRect = qt_qrectForHIRect(cr);
3867  }
3868  int xpos = contentRect.x() + 18;
3869  int checkcol = maxpmw;
3870  if (!enabled)
3871  p->setPen(mi->palette.text().color());
3872  else if (active)
3873  p->setPen(mi->palette.highlightedText().color());
3874  else
3875  p->setPen(mi->palette.buttonText().color());
3876 
3877  if (mi->checked) {
3878  // Use the HIThemeTextInfo foo to draw the check mark correctly, if we do it,
3879  // we somehow need to use a special encoding as it doesn't look right with our
3880  // drawText().
3881  p->save();
3882  CGContextSetShouldAntialias(cg, true);
3883  CGContextSetShouldSmoothFonts(cg, true);
3884  QColor textColor = p->pen().color();
3885  CGFloat colorComp[] = { textColor.redF(), textColor.greenF(),
3886  textColor.blueF(), textColor.alphaF() };
3887  CGContextSetFillColorSpace(cg, QCoreGraphicsPaintEngine::macGenericColorSpace());
3888  CGContextSetFillColor(cg, colorComp);
3889  HIThemeTextInfo tti;
3890  tti.version = qt_mac_hitheme_version;
3891  tti.state = tds;
3892  if (active && enabled)
3893  tti.state = kThemeStatePressed;
3894  switch (widgetSize) {
3895  case QAquaSizeUnknown:
3896  case QAquaSizeLarge:
3897  tti.fontID = kThemeMenuItemMarkFont;
3898  break;
3899  case QAquaSizeSmall:
3900  tti.fontID = kThemeSmallSystemFont;
3901  break;
3902  case QAquaSizeMini:
3903  tti.fontID = kThemeMiniSystemFont;
3904  break;
3905  }
3906  tti.horizontalFlushness = kHIThemeTextHorizontalFlushLeft;
3907  tti.verticalFlushness = kHIThemeTextVerticalFlushCenter;
3908  tti.options = kHIThemeTextBoxOptionNone;
3909  tti.truncationPosition = kHIThemeTextTruncationNone;
3910  tti.truncationMaxLines = 1;
3911  QCFString checkmark;
3912 #if 0
3913  if (mi->checkType == QStyleOptionMenuItem::Exclusive)
3914  checkmark = QString(QChar(kDiamondUnicode));
3915  else
3916 #endif
3917  checkmark = QString(QChar(kCheckUnicode));
3918  int mw = checkcol + macItemFrame;
3919  int mh = contentRect.height() - 2 * macItemFrame;
3920  int xp = contentRect.x();
3921  xp += macItemFrame;
3922  CGFloat outWidth, outHeight, outBaseline;
3923  HIThemeGetTextDimensions(checkmark, 0, &tti, &outWidth, &outHeight,
3924  &outBaseline);
3925  if (widgetSize == QAquaSizeMini)
3926  outBaseline += 1;
3927  QRect r(xp, contentRect.y(), mw, mh);
3928  r.translate(0, p->fontMetrics().ascent() - int(outBaseline) + 1);
3929  HIRect bounds = qt_hirectForQRect(r);
3930  HIThemeDrawTextBox(checkmark, &bounds, &tti,
3931  cg, kHIThemeOrientationNormal);
3932  p->restore();
3933  }
3934  if (!mi->icon.isNull()) {
3935  QIcon::Mode mode = (mi->state & State_Enabled) ? QIcon::Normal
3936  : QIcon::Disabled;
3937  // Always be normal or disabled to follow the Mac style.
3938  int smallIconSize = proxy()->pixelMetric(PM_SmallIconSize);
3939  QSize iconSize(smallIconSize, smallIconSize);
3940  if (const QComboBox *comboBox = qobject_cast<const QComboBox *>(w)) {
3941  iconSize = comboBox->iconSize();
3942  }
3943  QPixmap pixmap = mi->icon.pixmap(iconSize, mode);
3944  int pixw = pixmap.width();
3945  int pixh = pixmap.height();
3946  QRect cr(xpos, contentRect.y(), checkcol, contentRect.height());
3947  QRect pmr(0, 0, pixw, pixh);
3948  pmr.moveCenter(cr.center());
3949  p->drawPixmap(pmr.topLeft(), pixmap);
3950  xpos += pixw + 6;
3951  }
3952 
3953  QString s = mi->text;
3954  if (!s.isEmpty()) {
3955  int t = s.indexOf(QLatin1Char('\t'));
3958  int yPos = contentRect.y();
3959  if (widgetSize == QAquaSizeMini)
3960  yPos += 1;
3961  p->save();
3962  if (t >= 0) {
3963  p->setFont(qt_app_fonts_hash()->value("QMenuItem", p->font()));
3964  int xp = contentRect.right() - tabwidth - macRightBorder
3965  - macItemHMargin - macItemFrame + 1;
3966  p->drawText(xp, yPos, tabwidth, contentRect.height(), text_flags,
3967  s.mid(t + 1));
3968  s = s.left(t);
3969  }
3970 
3971  const int xm = macItemFrame + maxpmw + macItemHMargin;
3972  QFont myFont = mi->font;
3973  // myFont may not have any "hard" flags set. We override
3974  // the point size so that when it is resolved against the device, this font will win.
3975  // This is mainly to handle cases where someone sets the font on the window
3976  // and then the combo inherits it and passes it onward. At that point the resolve mask
3977  // is very, very weak. This makes it stonger.
3978  myFont.setPointSizeF(QFontInfo(mi->font).pointSizeF());
3979  p->setFont(myFont);
3980  p->drawText(xpos, yPos, contentRect.width() - xm - tabwidth + 1,
3981  contentRect.height(), text_flags ^ Qt::AlignRight, s);
3982  p->restore();
3983  }
3984  }
3985  break;
3986  case CE_MenuHMargin:
3987  case CE_MenuVMargin:
3988  case CE_MenuTearoff:
3989  case CE_MenuScroller:
3990  if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
3991  p->fillRect(mi->rect, opt->palette.background());
3992 
3993  HIRect menuRect = qt_hirectForQRect(mi->menuRect);
3994  HIRect itemRect = qt_hirectForQRect(mi->rect);
3995  HIThemeMenuItemDrawInfo mdi;
3996  mdi.version = qt_mac_hitheme_version;
3997  if (!(opt->state & State_Enabled))
3998  mdi.state = kThemeMenuDisabled;
3999  else if (opt->state & State_Selected)
4000  mdi.state = kThemeMenuSelected;
4001  else
4002  mdi.state = kThemeMenuActive;
4003  if (ce == CE_MenuScroller) {
4004  if (opt->state & State_DownArrow)
4005  mdi.itemType = kThemeMenuItemScrollDownArrow;
4006  else
4007  mdi.itemType = kThemeMenuItemScrollUpArrow;
4008  } else {
4009  mdi.itemType = kThemeMenuItemPlain;
4010  }
4011  HIThemeDrawMenuItem(&menuRect, &itemRect, &mdi,
4012  cg,
4013  kHIThemeOrientationNormal, 0);
4014  if (ce == CE_MenuTearoff) {
4015  p->setPen(QPen(mi->palette.dark().color(), 1, Qt::DashLine));
4016  p->drawLine(mi->rect.x() + 2, mi->rect.y() + mi->rect.height() / 2 - 1,
4017  mi->rect.x() + mi->rect.width() - 4,
4018  mi->rect.y() + mi->rect.height() / 2 - 1);
4019  p->setPen(QPen(mi->palette.light().color(), 1, Qt::DashLine));
4020  p->drawLine(mi->rect.x() + 2, mi->rect.y() + mi->rect.height() / 2,
4021  mi->rect.x() + mi->rect.width() - 4,
4022  mi->rect.y() + mi->rect.height() / 2);
4023  }
4024  }
4025  break;
4026  case CE_MenuBarItem:
4027  if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
4028  HIRect menuRect = qt_hirectForQRect(mi->menuRect);
4029  HIRect itemRect = qt_hirectForQRect(mi->rect);
4030 
4031  if ((opt->state & State_Selected) && (opt->state & State_Enabled) && (opt->state & State_Sunken)){
4032  // Draw a selected menu item background:
4033  HIThemeMenuItemDrawInfo mdi;
4034  mdi.version = qt_mac_hitheme_version;
4035  mdi.state = kThemeMenuSelected;
4036  mdi.itemType = kThemeMenuItemPlain;
4037  HIThemeDrawMenuItem(&menuRect, &itemRect, &mdi, cg, kHIThemeOrientationNormal, 0);
4038  } else {
4039  // Draw the toolbar background:
4040  HIThemeMenuBarDrawInfo bdi;
4041  bdi.version = qt_mac_hitheme_version;
4042  bdi.state = kThemeMenuBarNormal;
4043  bdi.attributes = 0;
4044  HIThemeDrawMenuBarBackground(&menuRect, &bdi, cg, kHIThemeOrientationNormal);
4045  }
4046 
4047  if (!mi->icon.isNull()) {
4048  drawItemPixmap(p, mi->rect,
4051  mi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize),
4052  (mi->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled));
4053  } else {
4054  drawItemText(p, mi->rect,
4057  mi->palette, mi->state & State_Enabled,
4058  mi->text, QPalette::ButtonText);
4059  }
4060  }
4061  break;
4062  case CE_MenuBarEmptyArea:
4063  if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
4064  HIThemeMenuBarDrawInfo bdi;
4065  bdi.version = qt_mac_hitheme_version;
4066  bdi.state = kThemeMenuBarNormal;
4067  bdi.attributes = 0;
4068  HIRect hirect = qt_hirectForQRect(mi->rect);
4069  HIThemeDrawMenuBarBackground(&hirect, &bdi, cg,
4070  kHIThemeOrientationNormal);
4071  break;
4072  }
4074  if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
4075  HIThemeTrackDrawInfo tdi;
4076  tdi.version = qt_mac_hitheme_version;
4077  tdi.reserved = 0;
4078  bool isIndeterminate = (pb->minimum == 0 && pb->maximum == 0);
4079  bool vertical = false;
4080  bool inverted = false;
4081  if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
4082  vertical = (pb2->orientation == Qt::Vertical);
4083  inverted = pb2->invertedAppearance;
4084  }
4085  bool reverse = (!vertical && (pb->direction == Qt::RightToLeft));
4086  if (inverted)
4087  reverse = !reverse;
4088  switch (d->aquaSizeConstrain(opt, w)) {
4089  case QAquaSizeUnknown:
4090  case QAquaSizeLarge:
4091  tdi.kind = !isIndeterminate ? kThemeLargeProgressBar
4092  : kThemeLargeIndeterminateBar;
4093  break;
4094  case QAquaSizeMini:
4095  case QAquaSizeSmall:
4096  tdi.kind = !isIndeterminate ? kThemeProgressBar : kThemeIndeterminateBar;
4097  break;
4098  }
4099  tdi.bounds = qt_hirectForQRect(pb->rect);
4100  tdi.max = pb->maximum;
4101  tdi.min = pb->minimum;
4102  tdi.value = pb->progress;
4103  tdi.attributes = vertical ? 0 : kThemeTrackHorizontal;
4104  tdi.trackInfo.progress.phase = d->progressFrame;
4105  if (!(pb->state & State_Active))
4106  tdi.enableState = kThemeTrackInactive;
4107  else if (!(pb->state & State_Enabled))
4108  tdi.enableState = kThemeTrackDisabled;
4109  else
4110  tdi.enableState = kThemeTrackActive;
4111  HIThemeOrientation drawOrientation = kHIThemeOrientationNormal;
4112  if (reverse) {
4113  if (vertical) {
4114  drawOrientation = kHIThemeOrientationInverted;
4115  } else {
4116  CGContextSaveGState(cg);
4117  CGContextTranslateCTM(cg, pb->rect.width(), 0);
4118  CGContextScaleCTM(cg, -1, 1);
4119  }
4120  }
4121  HIThemeDrawTrack(&tdi, 0, cg, drawOrientation);
4122  if (reverse && !vertical)
4123  CGContextRestoreGState(cg);
4124  }
4125  break;
4126  case CE_ProgressBarLabel:
4127  case CE_ProgressBarGroove:
4128  break;
4129  case CE_SizeGrip: {
4130  if (w && w->testAttribute(Qt::WA_MacOpaqueSizeGrip)) {
4131  HIThemeGrowBoxDrawInfo gdi;
4132  gdi.version = qt_mac_hitheme_version;
4133  gdi.state = tds;
4134  gdi.kind = kHIThemeGrowBoxKindNormal;
4135  gdi.direction = kThemeGrowRight | kThemeGrowDown;
4136  gdi.size = kHIThemeGrowBoxSizeNormal;
4137  HIPoint pt = CGPointMake(opt->rect.x(), opt->rect.y());
4138  HIThemeDrawGrowBox(&pt, &gdi, cg, kHIThemeOrientationNormal);
4139  } else {
4140  // It isn't possible to draw a transparent size grip with the
4141  // native API, so we do it ourselves here.
4142  const bool metal = qt_mac_is_metal(w);
4143  QPen lineColor = metal ? QColor(236, 236, 236) : QColor(82, 82, 82, 192);
4144  QPen metalHighlight = QColor(5, 5, 5, 192);
4145  lineColor.setWidth(1);
4146  p->save();
4148  p->setPen(lineColor);
4149  const Qt::LayoutDirection layoutDirection = w ? w->layoutDirection() : qApp->layoutDirection();
4150  const int NumLines = metal ? 4 : 3;
4151  for (int l = 0; l < NumLines; ++l) {
4152  const int offset = (l * 4 + (metal ? 2 : 3));
4153  QPoint start, end;
4154  if (layoutDirection == Qt::LeftToRight) {
4155  start = QPoint(opt->rect.width() - offset, opt->rect.height() - 1);
4156  end = QPoint(opt->rect.width() - 1, opt->rect.height() - offset);
4157  } else {
4158  start = QPoint(offset, opt->rect.height() - 1);
4159  end = QPoint(1, opt->rect.height() - offset);
4160  }
4161  p->drawLine(start, end);
4162  if (metal) {
4163  p->setPen(metalHighlight);
4165  p->drawLine(start + QPoint(0, -1), end + QPoint(0, -1));
4167  p->setPen(lineColor);
4168  }
4169  }
4170  p->restore();
4171  }
4172  break;
4173  }
4174  case CE_Splitter: {
4175  HIThemeSplitterDrawInfo sdi;
4176  sdi.version = qt_mac_hitheme_version;
4177  sdi.state = tds;
4178  sdi.adornment = qt_mac_is_metal(w) ? kHIThemeSplitterAdornmentMetal
4179  : kHIThemeSplitterAdornmentNone;
4180  HIRect hirect = qt_hirectForQRect(opt->rect);
4181  HIThemeDrawPaneSplitter(&hirect, &sdi, cg, kHIThemeOrientationNormal);
4182  break; }
4183  case CE_RubberBand:
4184  if (const QStyleOptionRubberBand *rubber = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
4186  if (!rubber->opaque) {
4187  QColor strokeColor;
4188  // I retrieved these colors from the Carbon-Dev mailing list
4189  strokeColor.setHsvF(0, 0, 0.86, 1.0);
4190  fillColor.setHsvF(0, 0, 0.53, 0.25);
4191  if (opt->rect.width() * opt->rect.height() <= 3) {
4192  p->fillRect(opt->rect, strokeColor);
4193  } else {
4194  QPen oldPen = p->pen();
4195  QBrush oldBrush = p->brush();
4196  QPen pen(strokeColor);
4197  p->setPen(pen);
4198  p->setBrush(fillColor);
4199  p->drawRect(opt->rect.adjusted(0, 0, -1, -1));
4200  p->setPen(oldPen);
4201  p->setBrush(oldBrush);
4202  }
4203  } else {
4204  p->fillRect(opt->rect, fillColor);
4205  }
4206  }
4207  break;
4208  case CE_ToolBar: {
4209  // For unified tool bars, draw nothing.
4210  if (w) {
4211  if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(w->window())) {
4212  if (mainWindow->unifiedTitleAndToolBarOnMac())
4213  break;
4214  }
4215  }
4216 
4217  // draw background gradient
4218  QLinearGradient linearGrad;
4219  if (opt->state & State_Horizontal)
4220  linearGrad = QLinearGradient(0, opt->rect.top(), 0, opt->rect.bottom());
4221  else
4222  linearGrad = QLinearGradient(opt->rect.left(), 0, opt->rect.right(), 0);
4223 
4224  linearGrad.setColorAt(0, mainWindowGradientBegin);
4225  linearGrad.setColorAt(1, mainWindowGradientEnd);
4226  p->fillRect(opt->rect, linearGrad);
4227 
4228  p->save();
4229  if (opt->state & State_Horizontal) {
4231  p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
4233  p->drawLine(opt->rect.bottomLeft(), opt->rect.bottomRight());
4234 
4235  } else {
4237  p->drawLine(opt->rect.topLeft(), opt->rect.bottomLeft());
4239  p->drawLine(opt->rect.topRight(), opt->rect.bottomRight());
4240  }
4241  p->restore();
4242 
4243 
4244  } break;
4245  default:
4246  QWindowsStyle::drawControl(ce, opt, p, w);
4247  break;
4248  }
4249 }
4250 
4251 static void setLayoutItemMargins(int left, int top, int right, int bottom, QRect *rect, Qt::LayoutDirection dir)
4252 {
4253  if (dir == Qt::RightToLeft) {
4254  rect->adjust(-right, top, -left, bottom);
4255  } else {
4256  rect->adjust(left, top, right, bottom);
4257  }
4258 }
4259 
4261  const QWidget *widget) const
4262 {
4263  QRect rect;
4264  int controlSize = getControlSize(opt, widget);
4265 
4266  switch (sr) {
4267  case SE_ItemViewItemText:
4268  if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
4269  int fw = proxy()->pixelMetric(PM_FocusFrameHMargin, opt, widget);
4270  // We add the focusframeargin between icon and text in commonstyle
4271  rect = QCommonStyle::subElementRect(sr, opt, widget);
4272  if (vopt->features & QStyleOptionViewItemV2::HasDecoration)
4273  rect.adjust(-fw, 0, 0, 0);
4274  }
4275  break;
4276  case SE_ToolBoxTabContents:
4277  rect = QCommonStyle::subElementRect(sr, opt, widget);
4278  break;
4279  case SE_PushButtonContents:
4280  if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
4281  // Unlike Carbon, we want the button to always be drawn inside its bounds.
4282  // Therefore, the button is a bit smaller, so that even if it got focus,
4283  // the focus 'shadow' will be inside. Adjust the content rect likewise.
4284  HIThemeButtonDrawInfo bdi;
4285  d->initHIThemePushButton(btn, widget, d->getDrawState(opt->state), &bdi);
4286  HIRect contentRect = d->pushButtonContentBounds(btn, &bdi);
4287  rect = qt_qrectForHIRect(contentRect);
4288  }
4289  break;
4290  case SE_HeaderLabel:
4291  if (qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
4292  rect = QWindowsStyle::subElementRect(sr, opt, widget);
4293  if (widget && widget->height() <= 22){
4294  // We need to allow the text a bit more space when the header is
4295  // small, otherwise it gets clipped:
4296  rect.setY(0);
4297  rect.setHeight(widget->height());
4298  }
4299  }
4300  break;
4301  case SE_ProgressBarGroove:
4302  case SE_ProgressBarLabel:
4303  break;
4305  rect = opt->rect;
4306  break;
4308  HIRect inRect = CGRectMake(opt->rect.x(), opt->rect.y(),
4309  opt->rect.width(), opt->rect.height());
4310  HIThemeButtonDrawInfo bdi;
4311  bdi.version = qt_mac_hitheme_version;
4312  bdi.state = kThemeStateActive;
4313  bdi.kind = kThemeDisclosureButton;
4314  bdi.value = kThemeDisclosureRight;
4315  bdi.adornment = kThemeAdornmentNone;
4316  HIRect contentRect;
4317  HIThemeGetButtonContentBounds(&inRect, &bdi, &contentRect);
4318  QCFType<HIShapeRef> shape;
4319  HIRect outRect;
4320  HIThemeGetButtonShape(&inRect, &bdi, &shape);
4321  ptrHIShapeGetBounds(shape, &outRect);
4322  rect = QRect(int(outRect.origin.x + DisclosureOffset), int(outRect.origin.y),
4323  int(contentRect.origin.x - outRect.origin.x + DisclosureOffset),
4324  int(outRect.size.height));
4325  break;
4326  }
4328  if (const QStyleOptionTabWidgetFrame *twf
4329  = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
4330  switch (twf->shape) {
4331  case QTabBar::RoundedNorth:
4333  rect = QRect(QPoint(0, 0), twf->leftCornerWidgetSize);
4334  break;
4335  case QTabBar::RoundedSouth:
4337  rect = QRect(QPoint(0, twf->rect.height() - twf->leftCornerWidgetSize.height()),
4338  twf->leftCornerWidgetSize);
4339  break;
4340  default:
4341  break;
4342  }
4343  rect = visualRect(twf->direction, twf->rect, rect);
4344  }
4345  break;
4347  if (const QStyleOptionTabWidgetFrame *twf
4348  = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
4349  switch (twf->shape) {
4350  case QTabBar::RoundedNorth:
4352  rect = QRect(QPoint(twf->rect.width() - twf->rightCornerWidgetSize.width(), 0),
4353  twf->rightCornerWidgetSize);
4354  break;
4355  case QTabBar::RoundedSouth:
4357  rect = QRect(QPoint(twf->rect.width() - twf->rightCornerWidgetSize.width(),
4358  twf->rect.height() - twf->rightCornerWidgetSize.height()),
4359  twf->rightCornerWidgetSize);
4360  break;
4361  default:
4362  break;
4363  }
4364  rect = visualRect(twf->direction, twf->rect, rect);
4365  }
4366  break;
4368  rect = QWindowsStyle::subElementRect(sr, opt, widget);
4369  if (const QStyleOptionTabWidgetFrame *twf
4370  = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
4371  if (twf->lineWidth != 0) {
4372  switch (getTabDirection(twf->shape)) {
4373  case kThemeTabNorth:
4374  rect.adjust(+1, +14, -1, -1);
4375  break;
4376  case kThemeTabSouth:
4377  rect.adjust(+1, +1, -1, -14);
4378  break;
4379  case kThemeTabWest:
4380  rect.adjust(+14, +1, -1, -1);
4381  break;
4382  case kThemeTabEast:
4383  rect.adjust(+1, +1, -14, -1);
4384  }
4385  }
4386  }
4387  break;
4388  case SE_LineEditContents:
4389  rect = QWindowsStyle::subElementRect(sr, opt, widget);
4390  if(widget->parentWidget() && qobject_cast<const QComboBox*>(widget->parentWidget()))
4391  rect.adjust(-1, -2, 0, 0);
4392  else
4393  rect.adjust(-1, -1, 0, +1);
4394  break;
4395  case SE_CheckBoxLayoutItem:
4396  rect = opt->rect;
4397  if (controlSize == QAquaSizeLarge) {
4398  setLayoutItemMargins(+2, +3, -9, -4, &rect, opt->direction);
4399  } else if (controlSize == QAquaSizeSmall) {
4400  setLayoutItemMargins(+1, +5, 0 /* fix */, -6, &rect, opt->direction);
4401  } else {
4402  setLayoutItemMargins(0, +7, 0 /* fix */, -6, &rect, opt->direction);
4403  }
4404  break;
4405  case SE_ComboBoxLayoutItem:
4406  if (widget && qobject_cast<QToolBar *>(widget->parentWidget())) {
4407  // Do nothing, because QToolbar needs the entire widget rect.
4408  // Otherwise it will be clipped. Equivalent to
4409  // widget->setAttribute(Qt::WA_LayoutUsesWidgetRect), but without
4410  // all the hassle.
4411  } else {
4412  rect = opt->rect;
4413  if (controlSize == QAquaSizeLarge) {
4414  rect.adjust(+3, +2, -3, -4);
4415  } else if (controlSize == QAquaSizeSmall) {
4416  setLayoutItemMargins(+2, +1, -3, -4, &rect, opt->direction);
4417  } else {
4418  setLayoutItemMargins(+1, 0, -2, 0, &rect, opt->direction);
4419  }
4420  }
4421  break;
4422  case SE_LabelLayoutItem:
4423  rect = opt->rect;
4424  setLayoutItemMargins(+1, 0 /* SHOULD be -1, done for alignment */, 0, 0 /* SHOULD be -1, done for alignment */, &rect, opt->direction);
4425  break;
4426  case SE_ProgressBarLayoutItem: {
4427  rect = opt->rect;
4428  int bottom = SIZE(3, 8, 8);
4429  if (opt->state & State_Horizontal) {
4430  rect.adjust(0, +1, 0, -bottom);
4431  } else {
4432  setLayoutItemMargins(+1, 0, -bottom, 0, &rect, opt->direction);
4433  }
4434  break;
4435  }
4437  if (const QStyleOptionButton *buttonOpt
4438  = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
4439  if ((buttonOpt->features & QStyleOptionButton::Flat))
4440  break; // leave rect alone
4441  }
4442  rect = opt->rect;
4443  if (controlSize == QAquaSizeLarge) {
4444  rect.adjust(+6, +4, -6, -8);
4445  } else if (controlSize == QAquaSizeSmall) {
4446  rect.adjust(+5, +4, -5, -6);
4447  } else {
4448  rect.adjust(+1, 0, -1, -2);
4449  }
4450  break;
4452  rect = opt->rect;
4453  if (controlSize == QAquaSizeLarge) {
4454  setLayoutItemMargins(+2, +2 /* SHOULD BE +3, done for alignment */,
4455  0, -4 /* SHOULD BE -3, done for alignment */, &rect, opt->direction);
4456  } else if (controlSize == QAquaSizeSmall) {
4457  rect.adjust(0, +6, 0 /* fix */, -5);
4458  } else {
4459  rect.adjust(0, +6, 0 /* fix */, -7);
4460  }
4461  break;
4462  case SE_SliderLayoutItem:
4463  if (const QStyleOptionSlider *sliderOpt
4464  = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
4465  rect = opt->rect;
4466  if (sliderOpt->tickPosition == QSlider::NoTicks) {
4467  int above = SIZE(3, 0, 2);
4468  int below = SIZE(4, 3, 0);
4469  if (sliderOpt->orientation == Qt::Horizontal) {
4470  rect.adjust(0, +above, 0, -below);
4471  } else {
4472  rect.adjust(+above, 0, -below, 0); //### Seems that QSlider flip the position of the ticks in reverse mode.
4473  }
4474  } else if (sliderOpt->tickPosition == QSlider::TicksAbove) {
4475  int below = SIZE(3, 2, 0);
4476  if (sliderOpt->orientation == Qt::Horizontal) {
4477  rect.setHeight(rect.height() - below);
4478  } else {
4479  rect.setWidth(rect.width() - below);
4480  }
4481  } else if (sliderOpt->tickPosition == QSlider::TicksBelow) {
4482  int above = SIZE(3, 2, 0);
4483  if (sliderOpt->orientation == Qt::Horizontal) {
4484  rect.setTop(rect.top() + above);
4485  } else {
4486  rect.setLeft(rect.left() + above);
4487  }
4488  }
4489  }
4490  break;
4491  case SE_FrameLayoutItem:
4492  // hack because QStyleOptionFrameV2 doesn't have a frameStyle member
4493  if (const QFrame *frame = qobject_cast<const QFrame *>(widget)) {
4494  rect = opt->rect;
4495  switch (frame->frameStyle() & QFrame::Shape_Mask) {
4496  case QFrame::HLine:
4497  rect.adjust(0, +1, 0, -1);
4498  break;
4499  case QFrame::VLine:
4500  rect.adjust(+1, 0, -1, 0);
4501  break;
4502  default:
4503  ;
4504  }
4505  }
4506  break;
4507  case SE_GroupBoxLayoutItem:
4508  rect = opt->rect;
4509  if (const QStyleOptionGroupBox *groupBoxOpt =
4510  qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
4511  /*
4512  AHIG is very inconsistent when it comes to group boxes.
4513  Basically, we make sure that (non-checkable) group boxes
4514  and tab widgets look good when laid out side by side.
4515  */
4516  if (groupBoxOpt->subControls & (QStyle::SC_GroupBoxCheckBox
4518  int delta;
4519  if (groupBoxOpt->subControls & QStyle::SC_GroupBoxCheckBox) {
4520  delta = SIZE(8, 4, 4); // guess
4521  } else {
4522  delta = SIZE(15, 12, 12); // guess
4523  }
4524  rect.setTop(rect.top() + delta);
4525  }
4526  }
4527  rect.setBottom(rect.bottom() - 1);
4528  break;
4530  if (const QStyleOptionTabWidgetFrame *tabWidgetOpt =
4531  qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
4532  /*
4533  AHIG specifies "12 or 14" as the distance from the window
4534  edge. We choose 14 and since the default top margin is 20,
4535  the overlap is 6.
4536  */
4537  rect = tabWidgetOpt->rect;
4538  if (tabWidgetOpt->shape == QTabBar::RoundedNorth)
4539  rect.setTop(rect.top() + SIZE(6 /* AHIG */, 3 /* guess */, 2 /* AHIG */));
4540  }
4541  break;
4542 #ifndef QT_NO_DOCKWIDGET
4546  case SE_DockWidgetIcon: {
4547  int iconSize = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
4548  int buttonMargin = proxy()->pixelMetric(PM_DockWidgetTitleBarButtonMargin, opt, widget);
4549  QRect srect = opt->rect;
4550 
4551  const QStyleOptionDockWidget *dwOpt
4553  bool canClose = dwOpt == 0 ? true : dwOpt->closable;
4554  bool canFloat = dwOpt == 0 ? false : dwOpt->floatable;
4555  const QStyleOptionDockWidgetV2 *v2
4557  bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
4558 
4559  // If this is a vertical titlebar, we transpose and work as if it was
4560  // horizontal, then transpose again.
4561  if (verticalTitleBar) {
4562  QSize size = srect.size();
4563  size.transpose();
4564  srect.setSize(size);
4565  }
4566 
4567  do {
4568  int right = srect.right();
4569  int left = srect.left();
4570 
4571  QRect closeRect;
4572  if (canClose) {
4574  opt, widget).actualSize(QSize(iconSize, iconSize));
4575  sz += QSize(buttonMargin, buttonMargin);
4576  if (verticalTitleBar)
4577  sz.transpose();
4578  closeRect = QRect(left,
4579  srect.center().y() - sz.height()/2,
4580  sz.width(), sz.height());
4581  left = closeRect.right() + 1;
4582  }
4583  if (sr == SE_DockWidgetCloseButton) {
4584  rect = closeRect;
4585  break;
4586  }
4587 
4588  QRect floatRect;
4589  if (canFloat) {
4591  opt, widget).actualSize(QSize(iconSize, iconSize));
4592  sz += QSize(buttonMargin, buttonMargin);
4593  if (verticalTitleBar)
4594  sz.transpose();
4595  floatRect = QRect(left,
4596  srect.center().y() - sz.height()/2,
4597  sz.width(), sz.height());
4598  left = floatRect.right() + 1;
4599  }
4600  if (sr == SE_DockWidgetFloatButton) {
4601  rect = floatRect;
4602  break;
4603  }
4604 
4605  QRect iconRect;
4606  if (const QDockWidget *dw = qobject_cast<const QDockWidget*>(widget)) {
4607  QIcon icon;
4608  if (dw->isFloating())
4609  icon = dw->windowIcon();
4610  if (!icon.isNull()
4611  && icon.cacheKey() != QApplication::windowIcon().cacheKey()) {
4612  QSize sz = icon.actualSize(QSize(rect.height(), rect.height()));
4613  if (verticalTitleBar)
4614  sz.transpose();
4615  iconRect = QRect(right - sz.width(), srect.center().y() - sz.height()/2,
4616  sz.width(), sz.height());
4617  right = iconRect.left() - 1;
4618  }
4619  }
4620  if (sr == SE_DockWidgetIcon) {
4621  rect = iconRect;
4622  break;
4623  }
4624 
4625  QRect textRect = QRect(left, srect.top(),
4626  right - left, srect.height());
4627  if (sr == SE_DockWidgetTitleBarText) {
4628  rect = textRect;
4629  break;
4630  }
4631  } while (false);
4632 
4633  if (verticalTitleBar) {
4634  rect = QRect(srect.left() + rect.top() - srect.top(),
4635  srect.top() + srect.right() - rect.right(),
4636  rect.height(), rect.width());
4637  } else {
4638  rect = visualRect(opt->direction, srect, rect);
4639  }
4640  break;
4641  }
4642 #endif
4643  default:
4644  rect = QWindowsStyle::subElementRect(sr, opt, widget);
4645  break;
4646  }
4647  return rect;
4648 }
4649 
4650 static inline void drawToolbarButtonArrow(const QRect &toolButtonRect, ThemeDrawState tds, CGContextRef cg)
4651 {
4652  QRect arrowRect = QRect(toolButtonRect.right() - 9, toolButtonRect.bottom() - 9, 7, 5);
4653  HIThemePopupArrowDrawInfo padi;
4654  padi.version = qt_mac_hitheme_version;
4655  padi.state = tds;
4656  padi.orientation = kThemeArrowDown;
4657  padi.size = kThemeArrow7pt;
4658  HIRect hirect = qt_hirectForQRect(arrowRect);
4659  HIThemeDrawPopupArrow(&hirect, &padi, cg, kHIThemeOrientationNormal);
4660 }
4661 
4663  const QWidget *widget) const
4664 {
4665  ThemeDrawState tds = d->getDrawState(opt->state);
4666  QMacCGContext cg(p);
4667  switch (cc) {
4668  case CC_Slider:
4669  case CC_ScrollBar:
4670  if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
4671  HIThemeTrackDrawInfo tdi;
4672  d->getSliderInfo(cc, slider, &tdi, widget);
4673  if (slider->state & State_Sunken) {
4674  if (cc == CC_Slider) {
4675  if (slider->activeSubControls == SC_SliderHandle)
4676  tdi.trackInfo.slider.pressState = kThemeThumbPressed;
4677  else if (slider->activeSubControls == SC_SliderGroove)
4678  tdi.trackInfo.slider.pressState = kThemeLeftTrackPressed;
4679  } else {
4680  if (slider->activeSubControls == SC_ScrollBarSubLine
4681  || slider->activeSubControls == SC_ScrollBarAddLine) {
4682  // This test looks complex but it basically boils down
4683  // to the following: The "RTL look" on the mac also
4684  // changed the directions of the controls, that's not
4685  // what people expect (an arrow is an arrow), so we
4686  // kind of fake and say the opposite button is hit.
4687  // This works great, up until 10.4 which broke the
4688  // scroll bars, so I also have actually do something
4689  // similar when I have an upside down scroll bar
4690  // because on Tiger I only "fake" the reverse stuff.
4691  bool reverseHorizontal = (slider->direction == Qt::RightToLeft
4692  && slider->orientation == Qt::Horizontal);
4693  if ((reverseHorizontal
4694  && slider->activeSubControls == SC_ScrollBarAddLine)
4695  || (!reverseHorizontal
4696  && slider->activeSubControls == SC_ScrollBarSubLine)) {
4697  tdi.trackInfo.scrollbar.pressState = kThemeRightInsideArrowPressed
4698  | kThemeLeftOutsideArrowPressed;
4699  } else {
4700  tdi.trackInfo.scrollbar.pressState = kThemeLeftInsideArrowPressed
4701  | kThemeRightOutsideArrowPressed;
4702  }
4703  } else if (slider->activeSubControls == SC_ScrollBarAddPage) {
4704  tdi.trackInfo.scrollbar.pressState = kThemeRightTrackPressed;
4705  } else if (slider->activeSubControls == SC_ScrollBarSubPage) {
4706  tdi.trackInfo.scrollbar.pressState = kThemeLeftTrackPressed;
4707  } else if (slider->activeSubControls == SC_ScrollBarSlider) {
4708  tdi.trackInfo.scrollbar.pressState = kThemeThumbPressed;
4709  }
4710  }
4711  }
4712  HIRect macRect;
4713  bool tracking = slider->sliderPosition == slider->sliderValue;
4714  if (!tracking) {
4715  // Small optimization, the same as q->subControlRect
4716  QCFType<HIShapeRef> shape;
4717  HIThemeGetTrackThumbShape(&tdi, &shape);
4718  ptrHIShapeGetBounds(shape, &macRect);
4719  tdi.value = slider->sliderValue;
4720  }
4721 
4722  // Remove controls from the scroll bar if it is to short to draw them correctly.
4723  // This is done in two stages: first the thumb indicator is removed when it is
4724  // no longer possible to move it, second the up/down buttons are removed when
4725  // there is not enough space for them.
4726  if (cc == CC_ScrollBar) {
4727  const int scrollBarLength = (slider->orientation == Qt::Horizontal)
4728  ? slider->rect.width() : slider->rect.height();
4729  const QMacStyle::WidgetSizePolicy sizePolicy = widgetSizePolicy(widget);
4730  if (scrollBarLength < scrollButtonsCutoffSize(thumbIndicatorCutoff, sizePolicy))
4731  tdi.attributes &= ~kThemeTrackShowThumb;
4732  if (scrollBarLength < scrollButtonsCutoffSize(scrollButtonsCutoff, sizePolicy))
4733  tdi.enableState = kThemeTrackNothingToScroll;
4734  } else {
4735  if (!(slider->subControls & SC_SliderHandle))
4736  tdi.attributes &= ~kThemeTrackShowThumb;
4737 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
4738  if (!(slider->subControls & SC_SliderGroove))
4739  tdi.attributes |= kThemeTrackHideTrack;
4740 #endif
4741  }
4742 
4743  HIThemeDrawTrack(&tdi, tracking ? 0 : &macRect, cg,
4744  kHIThemeOrientationNormal);
4745  if (cc == CC_Slider && slider->subControls & SC_SliderTickmarks) {
4746  if (qt_mac_is_metal(widget)) {
4747  if (tdi.enableState == kThemeTrackInactive)
4748  tdi.enableState = kThemeTrackActive; // Looks more Cocoa-like
4749  }
4750  int interval = slider->tickInterval;
4751  if (interval == 0) {
4752  interval = slider->pageStep;
4753  if (interval == 0)
4754  interval = slider->singleStep;
4755  if (interval == 0)
4756  interval = 1;
4757  }
4758  int numMarks = 1 + ((slider->maximum - slider->minimum) / interval);
4759 
4760  if (tdi.trackInfo.slider.thumbDir == kThemeThumbPlain) {
4761  // They asked for both, so we'll give it to them.
4762  tdi.trackInfo.slider.thumbDir = kThemeThumbDownward;
4763  HIThemeDrawTrackTickMarks(&tdi, numMarks,
4764  cg,
4765  kHIThemeOrientationNormal);
4766  tdi.trackInfo.slider.thumbDir = kThemeThumbUpward;
4767  HIThemeDrawTrackTickMarks(&tdi, numMarks,
4768  cg,
4769  kHIThemeOrientationNormal);
4770  } else {
4771  HIThemeDrawTrackTickMarks(&tdi, numMarks,
4772  cg,
4773  kHIThemeOrientationNormal);
4774 
4775  }
4776  }
4777  }
4778  break;
4779  case CC_Q3ListView:
4780  if (const QStyleOptionQ3ListView *lv = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt)) {
4781  if (lv->subControls & SC_Q3ListView)
4782  QWindowsStyle::drawComplexControl(cc, lv, p, widget);
4783  if (lv->subControls & (SC_Q3ListViewBranch | SC_Q3ListViewExpand)) {
4784  int y = lv->rect.y();
4785  int h = lv->rect.height();
4786  int x = lv->rect.right() - 10;
4787  for (int i = 1; i < lv->items.size() && y < h; ++i) {
4788  QStyleOptionQ3ListViewItem item = lv->items.at(i);
4789  if (y + item.height > 0 && (item.childCount > 0
4794  QStyleOption treeOpt(0);
4795  treeOpt.rect.setRect(x, y + item.height / 2 - 4, 9, 9);
4796  treeOpt.palette = lv->palette;
4797  treeOpt.state = lv->state;
4798  treeOpt.state |= State_Children;
4799  if (item.state & State_Open)
4800  treeOpt.state |= State_Open;
4801  proxy()->drawPrimitive(PE_IndicatorBranch, &treeOpt, p, widget);
4802  }
4803  y += item.totalHeight;
4804  }
4805  }
4806  }
4807  break;
4808  case CC_SpinBox:
4809  if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
4810  QStyleOptionSpinBox newSB = *sb;
4811  if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) {
4812  SInt32 frame_size;
4813  GetThemeMetric(kThemeMetricEditTextFrameOutset, &frame_size);
4814 
4815  QRect lineeditRect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxEditField, widget);
4816  lineeditRect.adjust(-frame_size, -frame_size, +frame_size, +frame_size);
4817 
4818  HIThemeFrameDrawInfo fdi;
4819  fdi.version = qt_mac_hitheme_version;
4820  fdi.state = ((sb->state & State_ReadOnly) || !(sb->state & State_Enabled)) ? kThemeStateInactive : kThemeStateActive;
4821  fdi.kind = kHIThemeFrameTextFieldSquare;
4822  fdi.isFocused = false;
4823  HIRect hirect = qt_hirectForQRect(lineeditRect);
4824  HIThemeDrawFrame(&hirect, &fdi, cg, kHIThemeOrientationNormal);
4825  }
4826  if (sb->subControls & (SC_SpinBoxUp | SC_SpinBoxDown)) {
4827  HIThemeButtonDrawInfo bdi;
4828  bdi.version = qt_mac_hitheme_version;
4829  QAquaWidgetSize aquaSize = d->aquaSizeConstrain(opt, widget);
4830  switch (aquaSize) {
4831  case QAquaSizeUnknown:
4832  case QAquaSizeLarge:
4833  bdi.kind = kThemeIncDecButton;
4834  break;
4835  case QAquaSizeMini:
4836  bdi.kind = kThemeIncDecButtonMini;
4837  break;
4838  case QAquaSizeSmall:
4839  bdi.kind = kThemeIncDecButtonSmall;
4840  break;
4841  }
4842  if (!(sb->stepEnabled & (QAbstractSpinBox::StepUpEnabled
4844  tds = kThemeStateUnavailable;
4845  if (sb->activeSubControls == SC_SpinBoxDown
4846  && (sb->state & State_Sunken))
4847  tds = kThemeStatePressedDown;
4848  else if (sb->activeSubControls == SC_SpinBoxUp
4849  && (sb->state & State_Sunken))
4850  tds = kThemeStatePressedUp;
4851  bdi.state = tds;
4852  if (!(sb->state & State_Active)
4853  && sb->palette.currentColorGroup() == QPalette::Active
4854  && tds == kThemeStateInactive)
4855  bdi.state = kThemeStateActive;
4856  bdi.value = kThemeButtonOff;
4857  bdi.adornment = kThemeAdornmentNone;
4858 
4859  QRect updown = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxUp, widget);
4860 
4861  updown |= proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxDown, widget);
4862  HIRect newRect = qt_hirectForQRect(updown);
4863  QRect off_rct;
4864  HIRect outRect;
4865  HIThemeGetButtonBackgroundBounds(&newRect, &bdi, &outRect);
4866  off_rct.setRect(int(newRect.origin.x - outRect.origin.x),
4867  int(newRect.origin.y - outRect.origin.y),
4868  int(outRect.size.width - newRect.size.width),
4869  int(outRect.size.height - newRect.size.height));
4870 
4871  newRect = qt_hirectForQRect(updown, off_rct);
4872  HIThemeDrawButton(&newRect, &bdi, cg, kHIThemeOrientationNormal, 0);
4873  }
4874  }
4875  break;
4876  case CC_ComboBox:
4877  if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)){
4878  HIThemeButtonDrawInfo bdi;
4879  d->initComboboxBdi(combo, &bdi, widget, d->getDrawState(opt->state));
4880  bool drawColorless = combo->palette.currentColorGroup() == QPalette::Active && tds == kThemeStateInactive;
4881  if (!drawColorless)
4882  QMacStylePrivate::drawCombobox(qt_hirectForQRect(combo->rect), bdi, p);
4883  else
4884  d->drawColorlessButton(qt_hirectForQRect(combo->rect), &bdi, p, opt);
4885  }
4886  break;
4887  case CC_TitleBar:
4888  if (const QStyleOptionTitleBar *titlebar
4889  = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
4890  if (titlebar->state & State_Active) {
4891  if (titlebar->titleBarState & State_Active)
4892  tds = kThemeStateActive;
4893  else
4894  tds = kThemeStateInactive;
4895  } else {
4896  tds = kThemeStateInactive;
4897  }
4898 
4899  HIThemeWindowDrawInfo wdi;
4900  wdi.version = qt_mac_hitheme_version;
4901  wdi.state = tds;
4902  wdi.windowType = QtWinType;
4903  wdi.titleHeight = titlebar->rect.height();
4904  wdi.titleWidth = titlebar->rect.width();
4905  wdi.attributes = kThemeWindowHasTitleText;
4906  // It seems HIThemeDrawTitleBarWidget is not able to draw a dirty
4907  // close button, so use HIThemeDrawWindowFrame instead.
4908  if (widget && widget->isWindowModified() && titlebar->subControls & SC_TitleBarCloseButton)
4909  wdi.attributes |= kThemeWindowHasCloseBox | kThemeWindowHasDirty;
4910 
4911  HIRect titleBarRect;
4912  HIRect tmpRect = qt_hirectForQRect(titlebar->rect);
4913  {
4914  QCFType<HIShapeRef> titleRegion;
4915  QRect newr = titlebar->rect.adjusted(0, 0, 2, 0);
4916  HIThemeGetWindowShape(&tmpRect, &wdi, kWindowTitleBarRgn, &titleRegion);
4917  ptrHIShapeGetBounds(titleRegion, &tmpRect);
4918  newr.translate(newr.x() - int(tmpRect.origin.x), newr.y() - int(tmpRect.origin.y));
4919  titleBarRect = qt_hirectForQRect(newr);
4920  }
4921  HIThemeDrawWindowFrame(&titleBarRect, &wdi, cg, kHIThemeOrientationNormal, 0);
4922  if (titlebar->subControls & (SC_TitleBarCloseButton
4926  HIThemeWindowWidgetDrawInfo wwdi;
4927  wwdi.version = qt_mac_hitheme_version;
4928  wwdi.widgetState = tds;
4929  if (titlebar->state & State_MouseOver)
4930  wwdi.widgetState = kThemeStateRollover;
4931  wwdi.windowType = QtWinType;
4932  wwdi.attributes = wdi.attributes | kThemeWindowHasFullZoom | kThemeWindowHasCloseBox | kThemeWindowHasCollapseBox;
4933  wwdi.windowState = wdi.state;
4934  wwdi.titleHeight = wdi.titleHeight;
4935  wwdi.titleWidth = wdi.titleWidth;
4936  ThemeDrawState savedControlState = wwdi.widgetState;
4938  ThemeTitleBarWidget tbw = kThemeWidgetCollapseBox;
4939  bool active = titlebar->state & State_Active;
4940  if (qMacVersion() < QSysInfo::MV_10_6) {
4941  int border = 2;
4942  titleBarRect.origin.x += border;
4943  titleBarRect.origin.y -= border;
4944  }
4945 
4946  while (sc <= SC_TitleBarCloseButton) {
4947  if (sc & titlebar->subControls) {
4948  uint tmp = sc;
4949  wwdi.widgetState = savedControlState;
4950  wwdi.widgetType = tbw;
4951  if (sc == SC_TitleBarMinButton)
4952  tmp |= SC_TitleBarNormalButton;
4953  if (active && (titlebar->activeSubControls & tmp)
4954  && (titlebar->state & State_Sunken))
4955  wwdi.widgetState = kThemeStatePressed;
4956  // Draw all sub controllers except the dirty close button
4957  // (it is already handled by HIThemeDrawWindowFrame).
4958  if (!(widget && widget->isWindowModified() && tbw == kThemeWidgetCloseBox)) {
4959  HIThemeDrawTitleBarWidget(&titleBarRect, &wwdi, cg, kHIThemeOrientationNormal);
4960  p->paintEngine()->syncState();
4961  }
4962  }
4963  sc = sc << 1;
4964  tbw = tbw >> 1;
4965  }
4966  }
4967  p->paintEngine()->syncState();
4968  if (titlebar->subControls & SC_TitleBarLabel) {
4969  int iw = 0;
4970  if (!titlebar->icon.isNull()) {
4971  QCFType<HIShapeRef> titleRegion2;
4972  HIThemeGetWindowShape(&titleBarRect, &wdi, kWindowTitleProxyIconRgn,
4973  &titleRegion2);
4974  ptrHIShapeGetBounds(titleRegion2, &tmpRect);
4975  if (tmpRect.size.width != 1) {
4976  int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
4977  iw = titlebar->icon.actualSize(QSize(iconExtent, iconExtent)).width();
4978  }
4979  }
4980  if (!titlebar->text.isEmpty()) {
4981  p->save();
4982  QCFType<HIShapeRef> titleRegion3;
4983  HIThemeGetWindowShape(&titleBarRect, &wdi, kWindowTitleTextRgn, &titleRegion3);
4984  ptrHIShapeGetBounds(titleRegion3, &tmpRect);
4985  p->setClipRect(qt_qrectForHIRect(tmpRect));
4986  QRect br = p->clipRegion().boundingRect();
4987  int x = br.x(),
4988  y = br.y() + (titlebar->rect.height() / 2 - p->fontMetrics().height() / 2);
4989  if (br.width() <= (p->fontMetrics().width(titlebar->text) + iw * 2))
4990  x += iw;
4991  else
4992  x += br.width() / 2 - p->fontMetrics().width(titlebar->text) / 2;
4993  if (iw)
4994  p->drawPixmap(x - iw, y,
4995  titlebar->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize), QIcon::Normal));
4996  drawItemText(p, br, Qt::AlignCenter, opt->palette, tds == kThemeStateActive,
4997  titlebar->text, QPalette::Text);
4998  p->restore();
4999  }
5000  }
5001  }
5002  break;
5003  case CC_GroupBox:
5004  if (const QStyleOptionGroupBox *groupBox
5005  = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
5006 
5007  QStyleOptionGroupBox groupBoxCopy(*groupBox);
5008  if ((widget && !widget->testAttribute(Qt::WA_SetFont))
5010  groupBoxCopy.subControls = groupBoxCopy.subControls & ~SC_GroupBoxLabel;
5011  QWindowsStyle::drawComplexControl(cc, &groupBoxCopy, p, widget);
5012  if (groupBoxCopy.subControls != groupBox->subControls) {
5013  bool checkable = groupBox->subControls & SC_GroupBoxCheckBox;
5014  p->save();
5015  CGContextSetShouldAntialias(cg, true);
5016  CGContextSetShouldSmoothFonts(cg, true);
5017  HIThemeTextInfo tti;
5018  tti.version = qt_mac_hitheme_version;
5019  tti.state = tds;
5020  QColor textColor = groupBox->palette.windowText().color();
5021  CGFloat colorComp[] = { textColor.redF(), textColor.greenF(),
5022  textColor.blueF(), textColor.alphaF() };
5023  CGContextSetFillColorSpace(cg, QCoreGraphicsPaintEngine::macGenericColorSpace());
5024  CGContextSetFillColor(cg, colorComp);
5025  tti.fontID = checkable ? kThemeSystemFont : kThemeSmallSystemFont;
5026  tti.horizontalFlushness = kHIThemeTextHorizontalFlushCenter;
5027  tti.verticalFlushness = kHIThemeTextVerticalFlushCenter;
5028  tti.options = kHIThemeTextBoxOptionNone;
5029  tti.truncationPosition = kHIThemeTextTruncationNone;
5030  tti.truncationMaxLines = 1 + groupBox->text.count(QLatin1Char('\n'));
5031  QCFString groupText = qt_mac_removeMnemonics(groupBox->text);
5032  QRect r = proxy()->subControlRect(CC_GroupBox, groupBox, SC_GroupBoxLabel, widget);
5033  HIRect bounds = qt_hirectForQRect(r);
5034  HIThemeDrawTextBox(groupText, &bounds, &tti, cg, kHIThemeOrientationNormal);
5035  p->restore();
5036  }
5037  }
5038  break;
5039  case CC_ToolButton:
5040  if (const QStyleOptionToolButton *tb
5041  = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
5042  if (widget && qobject_cast<QToolBar *>(widget->parentWidget())) {
5043  if (tb->subControls & SC_ToolButtonMenu) {
5044  QStyleOption arrowOpt(0);
5045  arrowOpt.rect = proxy()->subControlRect(cc, tb, SC_ToolButtonMenu, widget);
5046  arrowOpt.rect.setY(arrowOpt.rect.y() + arrowOpt.rect.height() / 2);
5047  arrowOpt.rect.setHeight(arrowOpt.rect.height() / 2);
5048  arrowOpt.state = tb->state;
5049  arrowOpt.palette = tb->palette;
5050  proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, p, widget);
5051  } else if ((tb->features & QStyleOptionToolButton::HasMenu)
5052  && (tb->toolButtonStyle != Qt::ToolButtonTextOnly && !tb->icon.isNull())) {
5053  drawToolbarButtonArrow(tb->rect, tds, cg);
5054  }
5055  if (tb->state & State_On) {
5057  static QPixmap pm(QLatin1String(":/trolltech/mac/style/images/leopard-unified-toolbar-on.png"));
5059  QStyleHelper::drawBorderPixmap(pm, p, tb->rect, 2, 2, 2, 2);
5060  } else {
5061  QPen oldPen = p->pen();
5062  p->setPen(QColor(0, 0, 0, 0x3a));
5063  p->fillRect(tb->rect.adjusted(1, 1, -1, -1), QColor(0, 0, 0, 0x12));
5064  p->drawLine(tb->rect.left() + 1, tb->rect.top(),
5065  tb->rect.right() - 1, tb->rect.top());
5066  p->drawLine(tb->rect.left() + 1, tb->rect.bottom(),
5067  tb->rect.right() - 1, tb->rect.bottom());
5068  p->drawLine(tb->rect.topLeft(), tb->rect.bottomLeft());
5069  p->drawLine(tb->rect.topRight(), tb->rect.bottomRight());
5070  p->setPen(oldPen);
5071  }
5072  }
5073  proxy()->drawControl(CE_ToolButtonLabel, opt, p, widget);
5074  } else {
5075  ThemeButtonKind bkind = kThemeBevelButton;
5076  switch (d->aquaSizeConstrain(opt, widget)) {
5077  case QAquaSizeUnknown:
5078  case QAquaSizeLarge:
5079  bkind = kThemeBevelButton;
5080  break;
5081  case QAquaSizeMini:
5082  case QAquaSizeSmall:
5083  bkind = kThemeSmallBevelButton;
5084  break;
5085  }
5086 
5087  QRect button, menuarea;
5088  button = proxy()->subControlRect(cc, tb, SC_ToolButton, widget);
5089  menuarea = proxy()->subControlRect(cc, tb, SC_ToolButtonMenu, widget);
5090  State bflags = tb->state,
5091  mflags = tb->state;
5092  if (tb->subControls & SC_ToolButton)
5093  bflags |= State_Sunken;
5094  if (tb->subControls & SC_ToolButtonMenu)
5095  mflags |= State_Sunken;
5096 
5097  if (tb->subControls & SC_ToolButton) {
5098  if (bflags & (State_Sunken | State_On | State_Raised)) {
5099  HIThemeButtonDrawInfo bdi;
5100  bdi.version = qt_mac_hitheme_version;
5101  bdi.state = tds;
5102  bdi.adornment = kThemeAdornmentNone;
5103  bdi.kind = bkind;
5104  bdi.value = kThemeButtonOff;
5105  if (tb->state & State_HasFocus)
5106  bdi.adornment = kThemeAdornmentFocus;
5107  if (tb->state & State_Sunken)
5108  bdi.state = kThemeStatePressed;
5109  if (tb->state & State_On)
5110  bdi.value = kThemeButtonOn;
5111 
5112  QRect off_rct(0, 0, 0, 0);
5113  HIRect myRect, macRect;
5114  myRect = CGRectMake(tb->rect.x(), tb->rect.y(),
5115  tb->rect.width(), tb->rect.height());
5116  HIThemeGetButtonBackgroundBounds(&myRect, &bdi, &macRect);
5117  off_rct.setRect(int(myRect.origin.x - macRect.origin.x),
5118  int(myRect.origin.y - macRect.origin.y),
5119  int(macRect.size.width - myRect.size.width),
5120  int(macRect.size.height - myRect.size.height));
5121 
5122  myRect = qt_hirectForQRect(button, off_rct);
5123  HIThemeDrawButton(&myRect, &bdi, cg, kHIThemeOrientationNormal, 0);
5124  }
5125  }
5126 
5127  if (tb->subControls & SC_ToolButtonMenu) {
5128  HIThemeButtonDrawInfo bdi;
5129  bdi.version = qt_mac_hitheme_version;
5130  bdi.state = tds;
5131  bdi.value = kThemeButtonOff;
5132  bdi.adornment = kThemeAdornmentNone;
5133  bdi.kind = bkind;
5134  if (tb->state & State_HasFocus)
5135  bdi.adornment = kThemeAdornmentFocus;
5136  if (tb->state & (State_On | State_Sunken)
5137  || (tb->activeSubControls & SC_ToolButtonMenu))
5138  bdi.state = kThemeStatePressed;
5139  HIRect hirect = qt_hirectForQRect(menuarea);
5140  HIThemeDrawButton(&hirect, &bdi, cg, kHIThemeOrientationNormal, 0);
5141  QRect r(menuarea.x() + ((menuarea.width() / 2) - 3), menuarea.height() - 8, 8, 8);
5142  HIThemePopupArrowDrawInfo padi;
5143  padi.version = qt_mac_hitheme_version;
5144  padi.state = tds;
5145  padi.orientation = kThemeArrowDown;
5146  padi.size = kThemeArrow7pt;
5147  hirect = qt_hirectForQRect(r);
5148  HIThemeDrawPopupArrow(&hirect, &padi, cg, kHIThemeOrientationNormal);
5149  } else if (tb->features & QStyleOptionToolButton::HasMenu) {
5150  drawToolbarButtonArrow(tb->rect, tds, cg);
5151  }
5152  QRect buttonRect = proxy()->subControlRect(CC_ToolButton, tb, SC_ToolButton, widget);
5153  int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
5154  QStyleOptionToolButton label = *tb;
5155  label.rect = buttonRect.adjusted(fw, fw, -fw, -fw);
5156  proxy()->drawControl(CE_ToolButtonLabel, &label, p, widget);
5157  }
5158  }
5159  break;
5160  case CC_Dial:
5161  if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(opt))
5162  QStyleHelper::drawDial(dial, p);
5163  break;
5164  default:
5165  QWindowsStyle::drawComplexControl(cc, opt, p, widget);
5166  break;
5167  }
5168 }
5169 
5171  const QStyleOptionComplex *opt,
5172  const QPoint &pt, const QWidget *widget) const
5173 {
5175  switch (cc) {
5176  case CC_ComboBox:
5177  if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
5178  sc = QWindowsStyle::hitTestComplexControl(cc, cmb, pt, widget);
5179  if (!cmb->editable && sc != QStyle::SC_None)
5180  sc = SC_ComboBoxArrow; // A bit of a lie, but what we want
5181  }
5182  break;
5183  case CC_Slider:
5184  if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
5185  HIThemeTrackDrawInfo tdi;
5186  d->getSliderInfo(cc, slider, &tdi, widget);
5187  ControlPartCode part;
5188  HIPoint pos = CGPointMake(pt.x(), pt.y());
5189  if (HIThemeHitTestTrack(&tdi, &pos, &part)) {
5190  if (part == kControlPageUpPart || part == kControlPageDownPart)
5191  sc = SC_SliderGroove;
5192  else
5193  sc = SC_SliderHandle;
5194  }
5195  }
5196  break;
5197  case CC_ScrollBar:
5198  if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
5199  HIScrollBarTrackInfo sbi;
5200  sbi.version = qt_mac_hitheme_version;
5201  if (!(sb->state & State_Active))
5202  sbi.enableState = kThemeTrackInactive;
5203  else if (sb->state & State_Enabled)
5204  sbi.enableState = kThemeTrackActive;
5205  else
5206  sbi.enableState = kThemeTrackDisabled;
5207 
5208  // The arrow buttons are not drawn if the scroll bar is to short,
5209  // exclude them from the hit test.
5210  const int scrollBarLength = (sb->orientation == Qt::Horizontal)
5211  ? sb->rect.width() : sb->rect.height();
5212  if (scrollBarLength < scrollButtonsCutoffSize(scrollButtonsCutoff, widgetSizePolicy(widget)))
5213  sbi.enableState = kThemeTrackNothingToScroll;
5214 
5215  sbi.viewsize = sb->pageStep;
5216  HIPoint pos = CGPointMake(pt.x(), pt.y());
5217 
5218  HIRect macSBRect = qt_hirectForQRect(sb->rect);
5219  ControlPartCode part;
5220  bool reverseHorizontal = (sb->direction == Qt::RightToLeft
5221  && sb->orientation == Qt::Horizontal
5222  && (!sb->upsideDown ||
5224  && sb->upsideDown)));
5225  if (HIThemeHitTestScrollBarArrows(&macSBRect, &sbi, sb->orientation == Qt::Horizontal,
5226  &pos, 0, &part)) {
5227  if (part == kControlUpButtonPart)
5228  sc = reverseHorizontal ? SC_ScrollBarAddLine : SC_ScrollBarSubLine;
5229  else if (part == kControlDownButtonPart)
5230  sc = reverseHorizontal ? SC_ScrollBarSubLine : SC_ScrollBarAddLine;
5231  } else {
5232  HIThemeTrackDrawInfo tdi;
5233  d->getSliderInfo(cc, sb, &tdi, widget);
5234  if(tdi.enableState == kThemeTrackInactive)
5235  tdi.enableState = kThemeTrackActive;
5236  if (HIThemeHitTestTrack(&tdi, &pos, &part)) {
5237  if (part == kControlPageUpPart)
5238  sc = reverseHorizontal ? SC_ScrollBarAddPage
5240  else if (part == kControlPageDownPart)
5241  sc = reverseHorizontal ? SC_ScrollBarSubPage
5243  else
5244  sc = SC_ScrollBarSlider;
5245  }
5246  }
5247  }
5248  break;
5249 /*
5250  I don't know why, but we only get kWindowContentRgn here, which isn't what we want at all.
5251  It would be very nice if this would work.
5252  case QStyle::CC_TitleBar:
5253  if (const QStyleOptionTitleBar *tbar = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
5254  HIThemeWindowDrawInfo wdi;
5255  memset(&wdi, 0, sizeof(wdi));
5256  wdi.version = qt_mac_hitheme_version;
5257  wdi.state = kThemeStateActive;
5258  wdi.windowType = QtWinType;
5259  wdi.titleWidth = tbar->rect.width();
5260  wdi.titleHeight = tbar->rect.height();
5261  if (tbar->titleBarState)
5262  wdi.attributes |= kThemeWindowHasFullZoom | kThemeWindowHasCloseBox
5263  | kThemeWindowHasCollapseBox;
5264  else if (tbar->titleBarFlags & Qt::WindowSystemMenuHint)
5265  wdi.attributes |= kThemeWindowHasCloseBox;
5266  QRect tmpRect = tbar->rect;
5267  tmpRect.setHeight(tmpRect.height() + 100);
5268  HIRect hirect = qt_hirectForQRect(tmpRect);
5269  WindowRegionCode hit;
5270  HIPoint hipt = CGPointMake(pt.x(), pt.y());
5271  if (HIThemeGetWindowRegionHit(&hirect, &wdi, &hipt, &hit)) {
5272  switch (hit) {
5273  case kWindowCloseBoxRgn:
5274  sc = QStyle::SC_TitleBarCloseButton;
5275  break;
5276  case kWindowCollapseBoxRgn:
5277  sc = QStyle::SC_TitleBarMinButton;
5278  break;
5279  case kWindowZoomBoxRgn:
5280  sc = QStyle::SC_TitleBarMaxButton;
5281  break;
5282  case kWindowTitleTextRgn:
5283  sc = QStyle::SC_TitleBarLabel;
5284  break;
5285  default:
5286  qDebug("got something else %d", hit);
5287  break;
5288  }
5289  }
5290  }
5291  break;
5292 */
5293  default:
5294  sc = QWindowsStyle::hitTestComplexControl(cc, opt, pt, widget);
5295  break;
5296  }
5297  return sc;
5298 }
5299 
5301  const QWidget *widget) const
5302 {
5303  QRect ret;
5304  switch (cc) {
5305  case CC_Slider:
5306  case CC_ScrollBar:
5307  if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
5308  HIThemeTrackDrawInfo tdi;
5309  d->getSliderInfo(cc, slider, &tdi, widget);
5310  HIRect macRect;
5311  QCFType<HIShapeRef> shape;
5312  bool scrollBar = cc == CC_ScrollBar;
5313  if ((scrollBar && sc == SC_ScrollBarSlider)
5314  || (!scrollBar && sc == SC_SliderHandle)) {
5315  HIThemeGetTrackThumbShape(&tdi, &shape);
5316  ptrHIShapeGetBounds(shape, &macRect);
5317  } else if (!scrollBar && sc == SC_SliderGroove) {
5318  HIThemeGetTrackBounds(&tdi, &macRect);
5319  } else if (sc == SC_ScrollBarGroove) { // Only scroll bar parts available...
5320  HIThemeGetTrackDragRect(&tdi, &macRect);
5321  } else {
5322  ControlPartCode cpc;
5323  if (sc == SC_ScrollBarSubPage || sc == SC_ScrollBarAddPage) {
5324  cpc = sc == SC_ScrollBarSubPage ? kControlPageDownPart
5325  : kControlPageUpPart;
5326  } else {
5327  cpc = sc == SC_ScrollBarSubLine ? kControlUpButtonPart
5328  : kControlDownButtonPart;
5329  if (slider->direction == Qt::RightToLeft
5330  && slider->orientation == Qt::Horizontal) {
5331  if (cpc == kControlDownButtonPart)
5332  cpc = kControlUpButtonPart;
5333  else if (cpc == kControlUpButtonPart)
5334  cpc = kControlDownButtonPart;
5335  }
5336  }
5337  HIThemeGetTrackPartBounds(&tdi, cpc, &macRect);
5338  }
5339  ret = qt_qrectForHIRect(macRect);
5340 
5341  // Tweak: the dark line between the sub/add line buttons belong to only one of the buttons
5342  // when doing hit-testing, but both of them have to repaint it. Extend the rect to cover
5343  // the line in the cases where HIThemeGetTrackPartBounds returns a rect that doesn't.
5344  if (slider->orientation == Qt::Horizontal) {
5345  if (slider->direction == Qt::LeftToRight && sc == SC_ScrollBarSubLine)
5346  ret.adjust(0, 0, 1, 0);
5347  else if (slider->direction == Qt::RightToLeft && sc == SC_ScrollBarAddLine)
5348  ret.adjust(-1, 0, 1, 0);
5349  } else if (sc == SC_ScrollBarAddLine) {
5350  ret.adjust(0, -1, 0, 1);
5351  }
5352  }
5353  break;
5354  case CC_TitleBar:
5355  if (const QStyleOptionTitleBar *titlebar
5356  = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
5357  HIThemeWindowDrawInfo wdi;
5358  memset(&wdi, 0, sizeof(wdi));
5359  wdi.version = qt_mac_hitheme_version;
5360  wdi.state = kThemeStateActive;
5361  wdi.windowType = QtWinType;
5362  wdi.titleHeight = titlebar->rect.height();
5363  wdi.titleWidth = titlebar->rect.width();
5364  wdi.attributes = kThemeWindowHasTitleText;
5365  if (titlebar->subControls & SC_TitleBarCloseButton)
5366  wdi.attributes |= kThemeWindowHasCloseBox;
5367  if (titlebar->subControls & SC_TitleBarMaxButton
5369  wdi.attributes |= kThemeWindowHasFullZoom;
5370  if (titlebar->subControls & SC_TitleBarMinButton)
5371  wdi.attributes |= kThemeWindowHasCollapseBox;
5372  WindowRegionCode wrc = kWindowGlobalPortRgn;
5373 
5374  if (sc == SC_TitleBarCloseButton)
5375  wrc = kWindowCloseBoxRgn;
5376  else if (sc == SC_TitleBarMinButton)
5377  wrc = kWindowCollapseBoxRgn;
5378  else if (sc == SC_TitleBarMaxButton)
5379  wrc = kWindowZoomBoxRgn;
5380  else if (sc == SC_TitleBarLabel)
5381  wrc = kWindowTitleTextRgn;
5382  else if (sc == SC_TitleBarSysMenu)
5383  ret.setRect(-1024, -1024, 10, proxy()->pixelMetric(PM_TitleBarHeight,
5384  titlebar, widget));
5385  if (wrc != kWindowGlobalPortRgn) {
5386  QCFType<HIShapeRef> region;
5387  QRect tmpRect = titlebar->rect;
5388  HIRect titleRect = qt_hirectForQRect(tmpRect);
5389  HIThemeGetWindowShape(&titleRect, &wdi, kWindowTitleBarRgn, &region);
5390  ptrHIShapeGetBounds(region, &titleRect);
5391  CFRelease(region);
5392  tmpRect.translate(tmpRect.x() - int(titleRect.origin.x),
5393  tmpRect.y() - int(titleRect.origin.y));
5394  titleRect = qt_hirectForQRect(tmpRect);
5395  HIThemeGetWindowShape(&titleRect, &wdi, wrc, &region);
5396  ptrHIShapeGetBounds(region, &titleRect);
5397  ret = qt_qrectForHIRect(titleRect);
5398  }
5399  }
5400  break;
5401  case CC_ComboBox:
5402  if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
5403  HIThemeButtonDrawInfo bdi;
5404  d->initComboboxBdi(combo, &bdi, widget, d->getDrawState(opt->state));
5405 
5406  switch (sc) {
5407  case SC_ComboBoxEditField:{
5408  ret = QMacStylePrivate::comboboxEditBounds(combo->rect, bdi);
5409  // hack to posistion the edit feld correctly for QDateTimeEdits
5410  // in calendarPopup mode.
5411  if (qobject_cast<const QDateTimeEdit *>(widget)) {
5412  ret.moveTop(ret.top() - 2);
5413  ret.setHeight(ret.height() +1);
5414  }
5415  break; }
5416  case SC_ComboBoxArrow:{
5417  ret = QMacStylePrivate::comboboxEditBounds(combo->rect, bdi);
5418  ret.setX(ret.x() + ret.width());
5419  ret.setWidth(combo->rect.right() - ret.right());
5420  break; }
5422  if (combo->editable) {
5423  HIRect inner = QMacStylePrivate::comboboxInnerBounds(qt_hirectForQRect(combo->rect), bdi.kind);
5424  QRect editRect = QMacStylePrivate::comboboxEditBounds(combo->rect, bdi);
5425  const int comboTop = combo->rect.top();
5426  ret = QRect(qRound(inner.origin.x),
5427  comboTop,
5428  qRound(inner.origin.x - combo->rect.left() + inner.size.width),
5429  editRect.bottom() - comboTop + 2);
5430  } else {
5431  QRect editRect = QMacStylePrivate::comboboxEditBounds(combo->rect, bdi);
5432  ret = QRect(combo->rect.x() + 4 - 11,
5433  combo->rect.y() + 1,
5434  editRect.width() + 10 + 11,
5435  1);
5436  }
5437  break; }
5438  default:
5439  break;
5440  }
5441  }
5442  break;
5443  case CC_GroupBox:
5444  if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
5445  bool checkable = groupBox->subControls & SC_GroupBoxCheckBox;
5446  bool flat = (groupBox->features & QStyleOptionFrameV2::Flat);
5447  bool hasNoText = !checkable && groupBox->text.isEmpty();
5448  switch (sc) {
5449  case SC_GroupBoxLabel:
5450  case SC_GroupBoxCheckBox: {
5451  // Cheat and use the smaller font if we need to
5452  bool checkable = groupBox->subControls & SC_GroupBoxCheckBox;
5453  bool fontIsSet = (widget && widget->testAttribute(Qt::WA_SetFont))
5455  int tw;
5456  int h;
5457  int margin = flat || hasNoText ? 0 : 12;
5458  ret = groupBox->rect.adjusted(margin, 0, -margin, 0);
5459 
5460  if (!fontIsSet) {
5461  HIThemeTextInfo tti;
5462  tti.version = qt_mac_hitheme_version;
5463  tti.state = kThemeStateActive;
5464  tti.fontID = checkable ? kThemeSystemFont : kThemeSmallSystemFont;
5465  tti.horizontalFlushness = kHIThemeTextHorizontalFlushCenter;
5466  tti.verticalFlushness = kHIThemeTextVerticalFlushCenter;
5467  tti.options = kHIThemeTextBoxOptionNone;
5468  tti.truncationPosition = kHIThemeTextTruncationNone;
5469  tti.truncationMaxLines = 1 + groupBox->text.count(QLatin1Char('\n'));
5470  CGFloat width;
5471  CGFloat height;
5472  QCFString groupText = qt_mac_removeMnemonics(groupBox->text);
5473  HIThemeGetTextDimensions(groupText, 0, &tti, &width, &height, 0);
5474  tw = qRound(width);
5475  h = qCeil(height);
5476  } else {
5477  QFontMetricsF fm = QFontMetricsF(groupBox->fontMetrics);
5478  h = qCeil(fm.height());
5479  tw = qCeil(fm.size(Qt::TextShowMnemonic, groupBox->text).width());
5480  }
5481  ret.setHeight(h);
5482 
5483  QRect labelRect = alignedRect(groupBox->direction, groupBox->textAlignment,
5484  QSize(tw, h), ret);
5485  int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, opt, widget);
5486  bool rtl = groupBox->direction == Qt::RightToLeft;
5487  if (sc == SC_GroupBoxLabel) {
5488  if (checkable) {
5489  int newSum = indicatorWidth + 1;
5490  int newLeft = labelRect.left() + (rtl ? -newSum : newSum);
5491  labelRect.moveLeft(newLeft);
5492  } else if (flat) {
5493  int newLeft = labelRect.left() - (rtl ? 3 : -3);
5494  labelRect.moveLeft(newLeft);
5495  labelRect.moveTop(labelRect.top() + 3);
5496  } else {
5497  int newLeft = labelRect.left() - (rtl ? 3 : 2);
5498  labelRect.moveLeft(newLeft);
5499  labelRect.moveTop(labelRect.top() + 5);
5500  }
5501  ret = labelRect;
5502  }
5503 
5504  if (sc == SC_GroupBoxCheckBox) {
5505  int left = rtl ? labelRect.right() - indicatorWidth : labelRect.left();
5506  ret.setRect(left, ret.top(),
5507  indicatorWidth, proxy()->pixelMetric(PM_IndicatorHeight, opt, widget));
5508  }
5509  break;
5510  }
5511  case SC_GroupBoxContents:
5512  case SC_GroupBoxFrame: {
5513  if (flat) {
5514  ret = QWindowsStyle::subControlRect(cc, groupBox, sc, widget);
5515  break;
5516  }
5517  QFontMetrics fm = groupBox->fontMetrics;
5518  bool checkable = groupBox->subControls & SC_GroupBoxCheckBox;
5519  int yOffset = 3;
5520  if (!checkable) {
5521  if (widget && !widget->testAttribute(Qt::WA_SetFont)
5523  fm = QFontMetrics(qt_app_fonts_hash()->value("QSmallFont", QFont()));
5524  yOffset = 5;
5525  if (hasNoText)
5526  yOffset = -qCeil(QFontMetricsF(fm).height());
5527  }
5528 
5529  ret = opt->rect.adjusted(0, qCeil(QFontMetricsF(fm).height()) + yOffset, 0, 0);
5530  if (sc == SC_GroupBoxContents)
5531  ret.adjust(3, 3, -3, -4); // guess
5532  }
5533  break;
5534  default:
5535  ret = QWindowsStyle::subControlRect(cc, groupBox, sc, widget);
5536  break;
5537  }
5538  }
5539  break;
5540  case CC_SpinBox:
5541  if (const QStyleOptionSpinBox *spin = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
5542  QAquaWidgetSize aquaSize = d->aquaSizeConstrain(spin, widget);
5543  int spinner_w;
5544  int spinBoxSep;
5545  int fw = proxy()->pixelMetric(PM_SpinBoxFrameWidth, spin, widget);
5546  switch (aquaSize) {
5547  default:
5548  case QAquaSizeUnknown:
5549  case QAquaSizeLarge:
5550  spinner_w = 14;
5551  spinBoxSep = 2;
5552  break;
5553  case QAquaSizeSmall:
5554  spinner_w = 12;
5555  spinBoxSep = 2;
5556  break;
5557  case QAquaSizeMini:
5558  spinner_w = 10;
5559  spinBoxSep = 1;
5560  break;
5561  }
5562 
5563  switch (sc) {
5564  case SC_SpinBoxUp:
5565  case SC_SpinBoxDown: {
5566  if (spin->buttonSymbols == QAbstractSpinBox::NoButtons)
5567  break;
5568 
5569  const int y = fw;
5570  const int x = spin->rect.width() - spinner_w;
5571  ret.setRect(x + spin->rect.x(), y + spin->rect.y(), spinner_w, spin->rect.height() - y * 2);
5572  HIThemeButtonDrawInfo bdi;
5573  bdi.version = qt_mac_hitheme_version;
5574  bdi.kind = kThemeIncDecButton;
5575  int hackTranslateX;
5576  switch (aquaSize) {
5577  default:
5578  case QAquaSizeUnknown:
5579  case QAquaSizeLarge:
5580  bdi.kind = kThemeIncDecButton;
5581  hackTranslateX = 0;
5582  break;
5583  case QAquaSizeSmall:
5584  bdi.kind = kThemeIncDecButtonSmall;
5585  hackTranslateX = -2;
5586  break;
5587  case QAquaSizeMini:
5588  bdi.kind = kThemeIncDecButtonMini;
5589  hackTranslateX = -1;
5590  break;
5591  }
5592  bdi.state = kThemeStateActive;
5593  bdi.value = kThemeButtonOff;
5594  bdi.adornment = kThemeAdornmentNone;
5595  HIRect hirect = qt_hirectForQRect(ret);
5596 
5597  HIRect outRect;
5598  HIThemeGetButtonBackgroundBounds(&hirect, &bdi, &outRect);
5599  ret = qt_qrectForHIRect(outRect);
5600  switch (sc) {
5601  case SC_SpinBoxUp:
5602  ret.setHeight(ret.height() / 2);
5603  break;
5604  case SC_SpinBoxDown:
5605  ret.setY(ret.y() + ret.height() / 2);
5606  break;
5607  default:
5608  Q_ASSERT(0);
5609  break;
5610  }
5611  ret.translate(hackTranslateX, 0); // hack: position the buttons correctly (weird that we need this)
5612  ret = visualRect(spin->direction, spin->rect, ret);
5613  break;
5614  }
5615  case SC_SpinBoxEditField:
5616  if (spin->buttonSymbols == QAbstractSpinBox::NoButtons) {
5617  ret.setRect(fw, fw,
5618  spin->rect.width() - fw * 2,
5619  spin->rect.height() - fw * 2);
5620  } else {
5621  ret.setRect(fw, fw,
5622  spin->rect.width() - fw * 2 - spinBoxSep - spinner_w,
5623  spin->rect.height() - fw * 2);
5624  }
5625  ret = visualRect(spin->direction, spin->rect, ret);
5626  break;
5627  default:
5628  ret = QWindowsStyle::subControlRect(cc, spin, sc, widget);
5629  break;
5630  }
5631  }
5632  break;
5633  case CC_ToolButton:
5634  ret = QWindowsStyle::subControlRect(cc, opt, sc, widget);
5635  if (sc == SC_ToolButtonMenu && widget && !qobject_cast<QToolBar*>(widget->parentWidget())) {
5636  ret.adjust(-1, 0, 0, 0);
5637  }
5638  break;
5639  default:
5640  ret = QWindowsStyle::subControlRect(cc, opt, sc, widget);
5641  break;
5642  }
5643  return ret;
5644 }
5645 
5647  const QSize &csz, const QWidget *widget) const
5648 {
5649  QSize sz(csz);
5650  bool useAquaGuideline = true;
5651 
5652  switch (ct) {
5653  case QStyle::CT_SpinBox:
5654  // hack to work around horrible sizeHint() code in QAbstractSpinBox
5655  sz.setHeight(sz.height() - 3);
5656  break;
5657  case QStyle::CT_TabWidget:
5658  // the size between the pane and the "contentsRect" (+4,+4)
5659  // (the "contentsRect" is on the inside of the pane)
5660  sz = QWindowsStyle::sizeFromContents(ct, opt, csz, widget);
5691  // then add the size between the stackwidget and the "contentsRect"
5692 
5693  if (const QStyleOptionTabWidgetFrame *twf
5694  = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
5695  QSize extra(0,0);
5696  const int overlap = pixelMetric(PM_TabBarBaseOverlap, opt, widget);
5697  const int gapBetweenTabbarAndStackWidget = 2 + 14 - overlap;
5698 
5699  if (getTabDirection(twf->shape) == kThemeTabNorth || getTabDirection(twf->shape) == kThemeTabSouth) {
5700  extra = QSize(2, gapBetweenTabbarAndStackWidget + 1);
5701  } else {
5702  extra = QSize(gapBetweenTabbarAndStackWidget + 1, 2);
5703  }
5704  sz+= extra;
5705  }
5706 
5707  break;
5708  case QStyle::CT_TabBarTab:
5709  if (const QStyleOptionTabV3 *tab = qstyleoption_cast<const QStyleOptionTabV3 *>(opt)) {
5710  const QAquaWidgetSize AquaSize = d->aquaSizeConstrain(opt, widget);
5711  const bool differentFont = (widget && widget->testAttribute(Qt::WA_SetFont))
5713  ThemeTabDirection ttd = getTabDirection(tab->shape);
5714  bool vertTabs = ttd == kThemeTabWest || ttd == kThemeTabEast;
5715  if (vertTabs)
5716  sz.transpose();
5717  int defaultTabHeight;
5718  int defaultExtraSpace = proxy()->pixelMetric(PM_TabBarTabHSpace, tab, widget); // Remove spurious gcc warning (AFAIK)
5719  QFontMetrics fm = opt->fontMetrics;
5720  switch (AquaSize) {
5721  case QAquaSizeUnknown:
5722  case QAquaSizeLarge:
5723  if (tab->documentMode)
5724  defaultTabHeight = 23;
5725  else
5726  defaultTabHeight = 21;
5727  break;
5728  case QAquaSizeSmall:
5729  defaultTabHeight = 18;
5730  break;
5731  case QAquaSizeMini:
5732  defaultTabHeight = 16;
5733  break;
5734  }
5735  bool setWidth = false;
5736  if (differentFont || !tab->icon.isNull()) {
5737  sz.rheight() = qMax(defaultTabHeight, sz.height());
5738  } else {
5739  QSize textSize = fm.size(Qt::TextShowMnemonic, tab->text);
5740  sz.rheight() = qMax(defaultTabHeight, textSize.height());
5741  sz.rwidth() = textSize.width() + defaultExtraSpace;
5742  setWidth = true;
5743  }
5744 
5745  if (vertTabs)
5746  sz.transpose();
5747 
5748  int maxWidgetHeight = qMax(tab->leftButtonSize.height(), tab->rightButtonSize.height());
5749  int maxWidgetWidth = qMax(tab->leftButtonSize.width(), tab->rightButtonSize.width());
5750 
5751  int widgetWidth = 0;
5752  int widgetHeight = 0;
5753  int padding = 0;
5754  if (tab->leftButtonSize.isValid()) {
5755  padding += 8;
5756  widgetWidth += tab->leftButtonSize.width();
5757  widgetHeight += tab->leftButtonSize.height();
5758  }
5759  if (tab->rightButtonSize.isValid()) {
5760  padding += 8;
5761  widgetWidth += tab->rightButtonSize.width();
5762  widgetHeight += tab->rightButtonSize.height();
5763  }
5764 
5765  if (vertTabs) {
5766  sz.setHeight(sz.height() + widgetHeight + padding);
5767  sz.setWidth(qMax(sz.width(), maxWidgetWidth));
5768  } else {
5769  if (setWidth)
5770  sz.setWidth(sz.width() + widgetWidth + padding);
5771  sz.setHeight(qMax(sz.height(), maxWidgetHeight));
5772  }
5773  }
5774  break;
5775  case QStyle::CT_PushButton:
5776  // By default, we fit the contents inside a normal rounded push button.
5777  // Do this by add enough space around the contents so that rounded
5778  // borders (including highlighting when active) will show.
5781  break;
5782  case QStyle::CT_MenuItem:
5783  if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
5784  int maxpmw = mi->maxIconWidth;
5785  const QComboBox *comboBox = qobject_cast<const QComboBox *>(widget);
5786  int w = sz.width(),
5787  h = sz.height();
5788  if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
5789  w = 10;
5790  SInt16 ash;
5791  GetThemeMenuSeparatorHeight(&ash);
5792  h = ash;
5793  } else {
5794  h = mi->fontMetrics.height() + 2;
5795  if (!mi->icon.isNull()) {
5796  if (comboBox) {
5797  const QSize &iconSize = comboBox->iconSize();
5798  h = qMax(h, iconSize.height() + 4);
5799  maxpmw = qMax(maxpmw, iconSize.width());
5800  } else {
5801  int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
5802  h = qMax(h, mi->icon.actualSize(QSize(iconExtent, iconExtent)).height() + 4);
5803  }
5804  }
5805  }
5806  if (mi->text.contains(QLatin1Char('\t')))
5807  w += 12;
5808  if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
5809  w += 20;
5810  if (maxpmw)
5811  w += maxpmw + 6;
5812  // add space for a check. All items have place for a check too.
5813  w += 20;
5814  if (comboBox && comboBox->isVisible()) {
5816  cmb.initFrom(comboBox);
5817  cmb.editable = false;
5822  comboBox).width());
5823  } else {
5824  w += 12;
5825  }
5826  sz = QSize(w, h);
5827  }
5828  break;
5829  case CT_ToolButton:
5830  if (widget && qobject_cast<const QToolBar *>(widget->parentWidget())) {
5831  if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(widget->parent())) {
5832  if (mainWindow->unifiedTitleAndToolBarOnMac()) {
5833  sz.rwidth() += 4;
5834  if (sz.height() <= 32) {
5835  // Workaround strange HIToolBar bug when getting constraints.
5836  sz.rheight() += 1;
5837  }
5838  return sz;
5839  }
5840  }
5841  }
5842  sz.rwidth() += 10;
5843  sz.rheight() += 10;
5844  return sz;
5845  case CT_ComboBox:
5846  sz.rwidth() += 50;
5847  break;
5848  case CT_Menu: {
5849  QStyleHintReturnMask menuMask;
5850  QStyleOption myOption = *opt;
5851  myOption.rect.setSize(sz);
5852  if (proxy()->styleHint(SH_Menu_Mask, &myOption, widget, &menuMask)) {
5853  sz = menuMask.region.boundingRect().size();
5854  }
5855  break; }
5856  case CT_HeaderSection:{
5857  const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt);
5858  sz = QWindowsStyle::sizeFromContents(ct, opt, csz, widget);
5859  if (header->text.contains(QLatin1Char('\n')))
5860  useAquaGuideline = false;
5861  break; }
5862  case CT_ScrollBar :
5863  // Make sure that the scroll bar is large enough to display the thumb indicator.
5864  if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
5865  const int minimumSize = scrollButtonsCutoffSize(thumbIndicatorCutoff, widgetSizePolicy(widget));
5866  if (slider->orientation == Qt::Horizontal)
5867  sz = sz.expandedTo(QSize(minimumSize, sz.height()));
5868  else
5869  sz = sz.expandedTo(QSize(sz.width(), minimumSize));
5870  }
5871  break;
5872  case CT_ItemViewItem:
5873  if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
5874  sz = QCommonStyle::sizeFromContents(ct, vopt, csz, widget);
5875  sz.setHeight(sz.height() + 2);
5876  }
5877  break;
5878 
5879  default:
5880  sz = QWindowsStyle::sizeFromContents(ct, opt, csz, widget);
5881  }
5882 
5883  if (useAquaGuideline){
5884  QSize macsz;
5885  if (d->aquaSizeConstrain(opt, widget, ct, sz, &macsz) != QAquaSizeUnknown) {
5886  if (macsz.width() != -1)
5887  sz.setWidth(macsz.width());
5888  if (macsz.height() != -1)
5889  sz.setHeight(macsz.height());
5890  }
5891  }
5892 
5893  // The sizes that Carbon and the guidelines gives us excludes the focus frame.
5894  // We compensate for this by adding some extra space here to make room for the frame when drawing:
5895  if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)){
5896  QAquaWidgetSize widgetSize = d->aquaSizeConstrain(opt, widget);
5897  int bkind = 0;
5898  switch (widgetSize) {
5899  default:
5900  case QAquaSizeLarge:
5901  bkind = combo->editable ? kThemeComboBox : kThemePopupButton;
5902  break;
5903  case QAquaSizeSmall:
5904  bkind = combo->editable ? int(kThemeComboBoxSmall) : int(kThemePopupButtonSmall);
5905  break;
5906  case QAquaSizeMini:
5907  bkind = combo->editable ? kThemeComboBoxMini : kThemePopupButtonMini;
5908  break;
5909  }
5910  HIRect tmpRect = {{0, 0}, {0, 0}};
5911  HIRect diffRect = QMacStylePrivate::comboboxInnerBounds(tmpRect, bkind);
5912  sz.rwidth() -= qRound(diffRect.size.width);
5913  sz.rheight() -= qRound(diffRect.size.height);
5914  } else if (ct == CT_PushButton || ct == CT_ToolButton){
5915  ThemeButtonKind bkind;
5916  QAquaWidgetSize widgetSize = d->aquaSizeConstrain(opt, widget);
5917  switch (ct) {
5918  default:
5919  case CT_PushButton:
5920  if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
5921  if (btn->features & QStyleOptionButton::CommandLinkButton) {
5922  return QWindowsStyle::sizeFromContents(ct, opt, sz, widget);
5923  }
5924  }
5925 
5926  switch (widgetSize) {
5927  default:
5928  case QAquaSizeLarge:
5929  bkind = kThemePushButton;
5930  break;
5931  case QAquaSizeSmall:
5932  bkind = kThemePushButtonSmall;
5933  break;
5934  case QAquaSizeMini:
5935  bkind = kThemePushButtonMini;
5936  break;
5937  }
5938  break;
5939  case CT_ToolButton:
5940  switch (widgetSize) {
5941  default:
5942  case QAquaSizeLarge:
5943  bkind = kThemeLargeBevelButton;
5944  break;
5945  case QAquaSizeMini:
5946  case QAquaSizeSmall:
5947  bkind = kThemeSmallBevelButton;
5948  }
5949  break;
5950  }
5951 
5952  HIThemeButtonDrawInfo bdi;
5953  bdi.version = qt_mac_hitheme_version;
5954  bdi.state = kThemeStateActive;
5955  bdi.kind = bkind;
5956  bdi.value = kThemeButtonOff;
5957  bdi.adornment = kThemeAdornmentNone;
5958  HIRect macRect, myRect;
5959  myRect = CGRectMake(0, 0, sz.width(), sz.height());
5960  HIThemeGetButtonBackgroundBounds(&myRect, &bdi, &macRect);
5961  // Mini buttons only return their actual size in HIThemeGetButtonBackgroundBounds, so help them out a bit (guess),
5962  if (bkind == kThemePushButtonMini)
5963  macRect.size.height += 8.;
5964  else if (bkind == kThemePushButtonSmall)
5965  macRect.size.height -= 10;
5966  sz.setWidth(sz.width() + int(macRect.size.width - myRect.size.width));
5967  sz.setHeight(sz.height() + int(macRect.size.height - myRect.size.height));
5968  }
5969  return sz;
5970 }
5971 
5972 void QMacStyle::drawItemText(QPainter *p, const QRect &r, int flags, const QPalette &pal,
5973  bool enabled, const QString &text, QPalette::ColorRole textRole) const
5974 {
5975  if(flags & Qt::TextShowMnemonic)
5976  flags |= Qt::TextHideMnemonic;
5977  QWindowsStyle::drawItemText(p, r, flags, pal, enabled, text, textRole);
5978 }
5979 
5981 {
5982  if(e->type() == QEvent::FocusIn) {
5983  QWidget *f = 0;
5984  QWidget *focusWidget = QApplication::focusWidget();
5985 #ifndef QT_NO_GRAPHICSVIEW
5986  if (QGraphicsView *graphicsView = qobject_cast<QGraphicsView *>(focusWidget)) {
5987  QGraphicsItem *focusItem = graphicsView->scene() ? graphicsView->scene()->focusItem() : 0;
5988  if (focusItem && focusItem->type() == QGraphicsProxyWidget::Type) {
5989  QGraphicsProxyWidget *proxy = static_cast<QGraphicsProxyWidget *>(focusItem);
5990  if (proxy->widget())
5991  focusWidget = proxy->widget()->focusWidget();
5992  }
5993  }
5994 #endif
5995  if (focusWidget && focusWidget->testAttribute(Qt::WA_MacShowFocusRect)) {
5996  f = focusWidget;
5997  QWidget *top = f->parentWidget();
5998  while (top && !top->isWindow() && !(top->windowType() == Qt::SubWindow))
5999  top = top->parentWidget();
6000 #ifndef QT_NO_MAINWINDOW
6001  if (qobject_cast<QMainWindow *>(top)) {
6002  QWidget *central = static_cast<QMainWindow *>(top)->centralWidget();
6003  for (const QWidget *par = f; par; par = par->parentWidget()) {
6004  if (par == central) {
6005  top = central;
6006  break;
6007  }
6008  if (par->isWindow())
6009  break;
6010  }
6011  }
6012 #endif
6013  }
6014  if (f) {
6015  if(!d->focusWidget)
6016  d->focusWidget = new QFocusFrame(f);
6017  d->focusWidget->setWidget(f);
6018  } else if(d->focusWidget) {
6019  d->focusWidget->setWidget(0);
6020  }
6021  } else if(e->type() == QEvent::FocusOut) {
6022  if(d->focusWidget)
6023  d->focusWidget->setWidget(0);
6024  }
6025  return false;
6026 }
6027 
6029  const QWidget *widget) const
6030 {
6031  switch (standardIcon) {
6032  default:
6033  return QWindowsStyle::standardIconImplementation(standardIcon, opt, widget);
6036  QPixmap pixmap(qt_mac_toolbar_ext);
6037  if (standardIcon == SP_ToolBarVerticalExtensionButton) {
6038  QPixmap pix2(pixmap.height(), pixmap.width());
6039  pix2.fill(Qt::transparent);
6040  QPainter p(&pix2);
6041  p.translate(pix2.width(), 0);
6042  p.rotate(90);
6043  p.drawPixmap(0, 0, pixmap);
6044  return pix2;
6045  }
6046  return pixmap;
6047  }
6048  }
6049 }
6050 
6052  QSizePolicy::ControlType control2,
6053  Qt::Orientation orientation,
6054  const QStyleOption *option,
6055  const QWidget *widget) const
6056 {
6058  bool isMetal = (widget && widget->testAttribute(Qt::WA_MacBrushedMetal));
6059  int controlSize = getControlSize(option, widget);
6060 
6061  if (control2 == QSizePolicy::ButtonBox) {
6062  /*
6063  AHIG seems to prefer a 12-pixel margin between group
6064  boxes and the row of buttons. The 20 pixel comes from
6065  Builder.
6066  */
6067  if (isMetal // (AHIG, guess, guess)
6068  || (control1 & (QSizePolicy::Frame // guess
6069  | QSizePolicy::GroupBox // (AHIG, guess, guess)
6070  | QSizePolicy::TabWidget // guess
6071  | ButtonMask))) { // AHIG
6072  return_SIZE(14, 8, 8);
6073  } else if (control1 == QSizePolicy::LineEdit) {
6074  return_SIZE(8, 8, 8); // Interface Builder
6075  } else {
6076  return_SIZE(20, 7, 7); // Interface Builder
6077  }
6078  }
6079 
6080  if ((control1 | control2) & ButtonMask) {
6081  if (control1 == QSizePolicy::LineEdit)
6082  return_SIZE(8, 8, 8); // Interface Builder
6083  else if (control2 == QSizePolicy::LineEdit) {
6084  if (orientation == Qt::Vertical)
6085  return_SIZE(20, 7, 7); // Interface Builder
6086  else
6087  return_SIZE(20, 8, 8);
6088  }
6089  return_SIZE(14, 8, 8); // Interface Builder
6090  }
6091 
6092  switch (CT2(control1, control2)) {
6093  case CT1(QSizePolicy::Label): // guess
6099  case CT2(QSizePolicy::Label, QSizePolicy::Slider): // guess
6102  return_SIZE(8, 6, 5);
6104  return 8; // AHIG
6105  case CT1(QSizePolicy::CheckBox):
6108  if (orientation == Qt::Vertical)
6109  return_SIZE(8, 8, 7); // AHIG and Builder
6110  break;
6112  if (orientation == Qt::Vertical)
6113  return 5; // (Builder, guess, AHIG)
6114  }
6115 
6116  if (orientation == Qt::Horizontal
6117  && (control2 & (QSizePolicy::CheckBox | QSizePolicy::RadioButton)))
6118  return_SIZE(12, 10, 8); // guess
6119 
6120  if ((control1 | control2) & (QSizePolicy::Frame
6123  /*
6124  These values were chosen so that nested container widgets
6125  look good side by side. Builder uses 8, which looks way
6126  too small, and AHIG doesn't say anything.
6127  */
6128  return_SIZE(16, 10, 10); // guess
6129  }
6130 
6131  if ((control1 | control2) & (QSizePolicy::Line | QSizePolicy::Slider))
6132  return_SIZE(12, 10, 8); // AHIG
6133 
6134  if ((control1 | control2) & QSizePolicy::LineEdit)
6135  return_SIZE(10, 8, 8); // AHIG
6136 
6137  /*
6138  AHIG and Builder differ by up to 4 pixels for stacked editable
6139  comboboxes. We use some values that work fairly well in all
6140  cases.
6141  */
6142  if ((control1 | control2) & QSizePolicy::ComboBox)
6143  return_SIZE(10, 8, 7); // guess
6144 
6145  /*
6146  Builder defaults to 8, 6, 5 in lots of cases, but most of the time the
6147  result looks too cramped.
6148  */
6149  return_SIZE(10, 8, 6); // guess
6150 }
6151 
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qstring.cpp:6448
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
QSize iconSize
the size of the icon for the button
Definition: qstyleoption.h:292
int startTimer(int interval)
Starts a timer and returns a timer identifier, or returns zero if it could not start a timer...
Definition: qobject.cpp:1623
static int qt_mac_hitheme_tab_version()
QBool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.h:904
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:86
const int qt_mac_hitheme_version
QPaintDevice * device() const
Returns the paint device on which this painter is currently painting, or 0 if the painter is not acti...
Definition: qpainter.cpp:1530
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
double d
Definition: qnumeric_p.h:62
static QRect alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment, const QSize &size, const QRect &rectangle)
Returns a new rectangle of the specified size that is aligned to the given rectangle according to the...
Definition: qstyle.cpp:2120
QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget=0) const
QPixmap generateBackgroundPattern() const
void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w=0) const
Reimplemented Function
int height
the height of the item
Definition: qstyleoption.h:474
void polish(QApplication *)
Reimplemented Function
HIRect *(* PtrHIShapeGetBounds)(HIShapeRef, HIRect *)
void unpolish(QApplication *)
Reimplemented Function
const int macRightBorder
bool addWidget(QWidget *)
QImage toImage() const
Converts the pixmap to a QImage.
Definition: qpixmap.cpp:542
QPalette palette
the widget&#39;s palette
Definition: qwidget.h:180
QString qt_mac_removeMnemonics(const QString &original)
QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *opt, const QWidget *widget=0) const
Reimplemented Function
QWidget * parentWidget() const
Returns the parent of this widget, or 0 if it does not have any parent widget.
Definition: qwidget.h:1035
The QApplication class manages the GUI application&#39;s control flow and main settings.
Definition: qapplication.h:99
void setFont(const QFont &)
Use the single-argument overload instead.
Definition: qwidget.cpp:4996
SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, const QPoint &pt, const QWidget *w=0) const
Reimplemented Function
static QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags=Qt::AutoColor)
Converts the given image to a pixmap using the specified flags to control the conversion.
Definition: qpixmap.cpp:2197
static CGColorSpaceRef macGenericColorSpace()
void unpolish(QWidget *w)
Reimplemented Function
int width(const QString &, int len=-1) const
Returns the width in pixels of the first len characters of text.
QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const
Reimplemented Function
void drawTabCloseButton(QPainter *p, bool hover, bool active, bool selected)
bool qt_mac_is_metal(const QWidget *w)
qreal alphaF() const
Returns the alpha color component of this color.
Definition: qcolor.cpp:1106
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
void drawPath(const QPainterPath &path)
Draws the given painter path using the current pen for outline and the current brush for filling...
Definition: qpainter.cpp:3502
unsigned int QRgb
Definition: qrgb.h:53
QWidget * focusWidget() const
Returns the last child of this widget that setFocus had been called on.
Definition: qwidget.cpp:6863
QRect adjusted(int x1, int y1, int x2, int y2) const
Returns a new rectangle with dx1, dy1, dx2 and dy2 added respectively to the existing coordinates of ...
Definition: qrect.h:431
TabPosition
This enum describes the position of the tab.
Definition: qstyleoption.h:310
void setHeight(int h)
Sets the height of the rectangle to the given height.
Definition: qrect.h:445
const QBrush & base() const
Returns the base brush of the current color group.
Definition: qpalette.h:130
SubControl
This enum describes the available sub controls.
Definition: qstyle.h:402
StyleHint
This enum describes the available style hints.
Definition: qstyle.h:640
void drawArc(const QRectF &rect, int a, int alen)
Draws the arc defined by the given rectangle, startAngle and spanAngle.
Definition: qpainter.cpp:4602
Qt::ToolButtonStyle toolButtonStyle
whether the tool button displays an icon only, text only, or text beside/below the icon...
Definition: qtoolbutton.h:66
The QStyleHintReturn class provides style hints that return more than basic data types.
Definition: qstyleoption.h:907
void setBottom(int pos)
Sets the bottom edge of the rectangle to the given y coordinate.
Definition: qrect.h:267
QRect rotateTabPainter(QPainter *p, QTabBar::Shape shape, QRect tabRect)
void startAnimate(Animates, QWidget *)
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
static QPixmap darkenPixmap(const QPixmap &pixmap)
The QFontMetrics class provides font metrics information.
Definition: qfontmetrics.h:65
void setColorAt(qreal pos, const QColor &color)
Creates a stop point at the given position with the given color.
Definition: qbrush.cpp:1475
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
The QStyleOptionDockWidget class is used to describe the parameters for drawing a dock widget...
Definition: qstyleoption.h:504
QString text() const
const QColor & color() const
Returns the brush color.
Definition: qbrush.h:183
void drawTabShape(QPainter *p, const QStyleOptionTabV3 *tabOpt)
int width() const
Returns the width of the pixmap.
Definition: qpixmap.cpp:630
QPointer< QWidget > widget
QSize size() const
Returns the size of the pixmap.
Definition: qpixmap.cpp:661
QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget=0) const
Reimplemented Function
ColorRole
The ColorRole enum defines the different symbolic color roles used in current GUIs.
Definition: qpalette.h:93
void syncState()
Updates all dirty states in this engine.
const QChar at(int i) const
Returns the character at the given index position in the string.
Definition: qstring.h:698
const QBrush & dark() const
Returns the dark brush of the current color group.
Definition: qpalette.h:127
void moveLeft(int pos)
Moves the rectangle horizontally, leaving the rectangle&#39;s left edge at the given x coordinate...
Definition: qrect.h:350
The QDockWidget class provides a widget that can be docked inside a QMainWindow or floated as a top-l...
Definition: qdockwidget.h:60
int width
the width of the widget excluding any window frame
Definition: qwidget.h:166
bool isActiveWindow
whether this widget&#39;s window is the active window
Definition: qwidget.h:186
virtual void drawItemText(QPainter *p, const QRect &r, int flags, const QPalette &pal, bool enabled, const QString &text, QPalette::ColorRole textRole=QPalette::NoRole) const
Draws the given text in the specified rectangle using the provided painter and palette.
static int closeButtonSize
int qCeil(qreal v)
Definition: qmath.h:63
qreal greenF() const
Returns the green color component of this color.
Definition: qcolor.cpp:1241
The QMatrix class specifies 2D transformations of a coordinate system.
Definition: qmatrix.h:61
QStyle::State state
the style flags that are used when drawing the control
Definition: qstyleoption.h:88
The QStyleOptionMenuItem class is used to describe the parameter necessary for drawing a menu item...
Definition: qstyleoption.h:435
The QStyleOptionHeader class is used to describe the parameters for drawing a header.
Definition: qstyleoption.h:251
bool isWindow() const
Returns true if the widget is an independent window, otherwise returns false.
Definition: qwidget.h:945
Q_GUI_EXPORT_INLINE int qAlpha(QRgb rgb)
Definition: qrgb.h:66
The QPainterPath class provides a container for painting operations, enabling graphical shapes to be ...
Definition: qpainterpath.h:67
QAquaWidgetSize aquaSizeConstrain(const QStyleOption *option, const QWidget *widg, QStyle::ContentsType ct=QStyle::CT_CustomBase, QSize szHint=QSize(-1, -1), QSize *insz=0) const
bool qt_scrollbar_jump_to_pos
bool autoDefault
whether the push button is an auto default button
Definition: qpushbutton.h:61
static const QColor mainWindowGradientEnd(200, 200, 200)
virtual QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget=0) const =0
Returns the rectangle containing the specified subControl of the given complex control (with the styl...
bool isVisible() const
Definition: qwidget.h:1005
void setCapStyle(Qt::PenCapStyle pcs)
Sets the pen&#39;s cap style to the given style.
Definition: qpen.cpp:723
bool isVisibleTo(QWidget *) const
Returns true if this widget would become visible if ancestor is shown; otherwise returns false...
Definition: qwidget.cpp:8371
static QSize globalStrut()
void rotate(qreal a)
Rotates the coordinate system the given angle clockwise.
Definition: qpainter.cpp:3287
const QBrush & background() const
Use window() instead.
Definition: qpalette.h:134
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option=0, const QWidget *widget=0) const =0
Returns the value of the given pixel metric.
int pixelMetric(PixelMetric pm, const QStyleOption *opt=0, const QWidget *widget=0) const
Reimplemented Function
qreal width() const
Returns the width.
Definition: qsize.h:284
ComplexControl
This enum describes the available complex controls.
Definition: qstyle.h:386
bool closable
whether the dock window is closable
Definition: qstyleoption.h:511
The QStyleOptionQ3ListView class is used to describe the parameters for drawing a Q3ListView...
Definition: qstyleoption.h:747
QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w=0) const
Reimplemented Function
SelectedPosition
This enum describes the position of the selected tab.
Definition: qstyleoption.h:311
static C reverse(const C &l)
void setClipRect(const QRectF &, Qt::ClipOperation op=Qt::ReplaceClip)
Enables clipping, and sets the clip region to the given rectangle using the given clip operation...
Definition: qpainter.cpp:2801
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
void setCapStyle(Qt::PenCapStyle style)
Sets the cap style of the generated outlines to style.
static bool verticalTabs(QTabBar::Shape shape)
QFont font
the font currently set for the widget
Definition: qwidget.h:181
The QGraphicsItem class is the base class for all graphical items in a QGraphicsScene.
Definition: qgraphicsitem.h:89
const int macItemHMargin
static void drawTableHeader(const HIRect &outerBounds, bool drawTopBorder, bool drawLeftBorder, const HIThemeButtonDrawInfo &bdi, QPainter *p)
The QStyleOptionTitleBar class is used to describe the parameters for drawing a title bar...
Definition: qstyleoption.h:816
bool doAnimate(Animates)
void restore()
Restores the current painter state (pops a saved state off the stack).
Definition: qpainter.cpp:1620
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
The QStyleOptionViewItemV4 class is used to describe the parameters necessary for drawing a frame in ...
Definition: qstyleoption.h:609
static const int PushButtonBottomOffset
State
This enum describes the state for which a pixmap is intended to be used.
Definition: qicon.h:64
PixelMetric
This enum describes the various available pixel metrics.
Definition: qstyle.h:474
QSize expandedTo(const QSize &) const
Returns a size holding the maximum width and height of this size and the given otherSize.
Definition: qsize.h:187
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
static const int MiniButtonH
QColor color() const
Returns the color of this pen&#39;s brush.
Definition: qpen.cpp:771
static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg, QSize szHint, QAquaWidgetSize sz)
QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *w=0) const
Reimplemented Function
static const QColor titlebarGradientInactiveEnd(207, 207, 207)
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
int childCount
the number of children the item has
Definition: qstyleoption.h:477
The QPushButton widget provides a command button.
Definition: qpushbutton.h:57
#define QT_END_INCLUDE_NAMESPACE
This macro is equivalent to QT_BEGIN_NAMESPACE.
Definition: qglobal.h:92
QSize iconSize
the size of the icons shown in the combobox.
Definition: qcombobox.h:77
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
static const QColor titlebarSeparatorLineInactive(131, 131, 131)
int bytesPerLine() const
Returns the number of bytes per image scanline.
Definition: qimage.cpp:1812
QSlider::TickPosition tickPosition
the position of the slider&#39;s tick marks, if any
Definition: qstyleoption.h:710
QSizeF size(int flags, const QString &str, int tabstops=0, int *tabarray=0) const
Returns the size in pixels of the characters in the given text.
virtual void drawItemText(QPainter *painter, const QRect &rect, int flags, const QPalette &pal, bool enabled, const QString &text, QPalette::ColorRole textRole=QPalette::NoRole) const
Draws the given text in the specified rectangle using the provided painter and palette.
Definition: qstyle.cpp:532
long ASN1_INTEGER_get ASN1_INTEGER * a
QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const
Reimplemented Function
static QPalette palette()
Returns the application palette.
QRect boundingRect() const
Returns the bounding rectangle of this region.
Definition: qregion.cpp:4363
void setWidget(QWidget *widget)
QFocusFrame will track changes to widget and resize itself automatically.
The QAbstractScrollArea widget provides a scrolling area with on-demand scroll bars.
The QTabBar class provides a tab bar, e.g.
Definition: qtabbar.h:59
QStyle::SubControls activeSubControls
This variable holds a bitwise OR of the sub-controls that are active for the complex control...
Definition: qstyleoption.h:694
const struct __HIShape * HIShapeRef
bool editable
whether or not the combobox is editable or not
Definition: qstyleoption.h:802
static const QColor titlebarGradientInactiveBegin(241, 241, 241)
QString text
the text of the header
Definition: qstyleoption.h:263
void * resolve(const char *symbol)
Returns the address of the exported symbol symbol.
Definition: qlibrary.cpp:1155
void drawLine(const QLineF &line)
Draws a line defined by line.
Definition: qpainter.h:573
The QProgressBar widget provides a horizontal or vertical progress bar.
Definition: qprogressbar.h:58
void qt_mac_dispose_rgn(RgnHandle r)
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
void removeWidget(QWidget *)
QString text
the text of the button
Definition: qstyleoption.h:290
void setY(int y)
Sets the top edge of the rectangle to the given y coordinate.
Definition: qrect.h:285
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
The QString class provides a Unicode character string.
Definition: qstring.h:83
QFontMetrics fontMetrics
the font metrics that should be used when drawing text in the control
Definition: qstyleoption.h:91
static const QRect qt_qrectForHIRect(const HIRect &hirect)
TickPosition tickPosition
the tickmark position for this slider
Definition: qslider.h:62
bool hasFocus() const
Definition: qwidget.cpp:6583
QPalette standardPalette() const
Returns the style&#39;s standard palette.
void setHeight(int h)
Sets the height to the given height.
Definition: qsize.h:135
T * qobject_cast(QObject *object)
Definition: qobject.h:375
struct QMacStylePrivate::ButtonState buttonState
static const QColor titlebarGradientActiveBegin(220, 220, 220)
QMacStylePrivate * d
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
const ThemeWindowType QtWinType
static QAquaWidgetSize qt_aqua_guess_size(const QWidget *widg, QSize large, QSize small, QSize mini)
void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w=0) const
Reimplemented Function
QMatrix & translate(qreal dx, qreal dy)
Moves the coordinate system dx along the x axis and dy along the y axis, and returns a reference to t...
Definition: qmatrix.cpp:922
const QColor & color(ColorGroup cg, ColorRole cr) const
Returns the color in the specified color group, used for the given color role.
Definition: qpalette.h:107
The QPen class defines how a QPainter should draw lines and outlines of shapes.
Definition: qpen.h:64
QRgb pixel(int x, int y) const
Returns the color of the pixel at coordinates (x, y).
Definition: qimage.cpp:4240
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
QTabBar::Shape shape
the tab shape used to draw the tab; by default QTabBar::RoundedNorth
Definition: qstyleoption.h:316
#define SIZE(large, small, mini)
static const int PushButtonLeftOffset
void moveTo(const QPointF &p)
Moves the current point to the given point, implicitly starting a new subpath and closing the previou...
Q_CORE_EXPORT QTextStream & right(QTextStream &s)
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
The QStyleOptionToolButton class is used to describe the parameters for drawing a tool button...
Definition: qstyleoption.h:768
static PtrHIShapeGetBounds ptrHIShapeGetBounds
#define return_SIZE(large, small, mini)
void save()
Saves the current painter state (pushes the state onto a stack).
Definition: qpainter.cpp:1590
static const int DisclosureOffset
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
QString elidedText(const QString &text, Qt::TextElideMode mode, int width, int flags=0) const
If the string text is wider than width, returns an elided version of the string (i.
StandardPixmap
This enum describes the available standard pixmaps.
Definition: qstyle.h:755
#define CT2(c1, c2)
static QPixmap * find(const QString &key)
void getHsv(int *h, int *s, int *v, int *a=0) const
Sets the contents pointed to by h, s, v, and a, to the hue, saturation, value, and alpha-channel (tra...
Definition: qcolor.cpp:679
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
Q_GUI_EXPORT_INLINE int qRed(QRgb rgb)
Definition: qrgb.h:57
void setHsv(int h, int s, int v, int a=255)
Sets a HSV color value; h is the hue, s is the saturation, v is the value and a is the alpha componen...
Definition: qcolor.cpp:734
QStyle * style() const
Definition: qwidget.cpp:2742
OSWindowRef qt_mac_window_for(const QWidget *)
Definition: qwidget_mac.mm:484
ColorGroup currentColorGroup() const
Returns the palette&#39;s current color group.
Definition: qpalette.h:104
The QLineF class provides a two-dimensional vector using floating point precision.
Definition: qline.h:212
int toInt(bool *ok=0) const
Returns the variant as an int if the variant has type() Int , Bool , ByteArray , Char ...
Definition: qvariant.cpp:2625
void setWidth(int w)
Sets the width to the given width.
Definition: qsize.h:132
QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt=0, const QWidget *widget=0) const
int ascent() const
Returns the ascent of the font.
void setDashPattern(Qt::PenStyle)
Sets the dash pattern for the generated outlines to style.
void update()
Updates the widget unless updates are disabled or the widget is hidden.
Definition: qwidget.cpp:10883
QRect boundingRect(QChar) const
Returns the rectangle that is covered by ink if character ch were to be drawn at the origin of the co...
void lineTo(const QPointF &p)
Adds a straight line from the current position to the given endPoint.
void setColor(const QColor &color)
Sets the color of this pen&#39;s brush to the given color.
Definition: qpen.cpp:787
Q_CORE_EXPORT void qDebug(const char *,...)
CFAbsoluteTime defaultButtonStart
bool isWindowModified() const
Definition: qwidget.cpp:11554
void setCurrentColorGroup(ColorGroup cg)
Set the palette&#39;s current color group to cg.
Definition: qpalette.h:105
QColor darker(int f=200) const
Returns a darker (or lighter) color, but does not change this object.
Definition: qcolor.h:301
bool upsideDown
the slider control orientation
Definition: qstyleoption.h:712
unsigned char uchar
Definition: qglobal.h:994
The QBitmap class provides monochrome (1-bit depth) pixmaps.
Definition: qbitmap.h:55
The QStyleOptionProgressBarV2 class is used to describe the parameters necessary for drawing a progre...
Definition: qstyleoption.h:417
int width() const
Returns the width.
Definition: qsize.h:126
static QIcon windowIcon()
QRegion clipRegion() const
Returns the currently set clip region.
Definition: qpainter.cpp:2562
void drawText(const QPointF &p, const QString &s)
Draws the given text with the currently defined text direction, beginning at the given position...
Definition: qpainter.cpp:6231
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
void setRenderHint(RenderHint hint, bool on=true)
Sets the given render hint on the painter if on is true; otherwise clears the render hint...
Definition: qpainter.cpp:7620
QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option=0, const QWidget *widget=0) const
Returns an icon for the given standardIcon.
Definition: qstyle.cpp:2327
The QRadioButton widget provides a radio button with a text label.
Definition: qradiobutton.h:56
void setHsvF(qreal h, qreal s, qreal v, qreal a=1.0)
Sets a HSV color value; h is the hue, s is the saturation, v is the value and a is the alpha componen...
Definition: qcolor.cpp:706
const QPen & pen() const
Returns the painter&#39;s current pen.
Definition: qpainter.cpp:4152
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
void drawEllipse(const QRectF &r)
Draws the ellipse defined by the given rectangle.
Definition: qpainter.cpp:4464
QFontMetrics fontMetrics() const
Returns the font metrics for the painter if the painter is active.
Definition: qpainter.cpp:2077
void setBrush(ColorRole cr, const QBrush &brush)
Sets the brush for the given color role to the specified brush for all groups in the palette...
Definition: qpalette.h:206
Q_GUI_EXPORT_INLINE QRgb qRgba(int r, int g, int b, int a)
Definition: qrgb.h:72
void polish(QWidget *w)
Reimplemented Function
void drawDial(const QStyleOptionSlider *option, QPainter *painter)
int totalHeight
the total height of the item, including its children
Definition: qstyleoption.h:475
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
Shape
This enum type lists the built-in shapes supported by QTabBar.
Definition: qtabbar.h:81
virtual QRect itemTextRect(const QFontMetrics &fm, const QRect &r, int flags, bool enabled, const QString &text) const
Returns the area within the given rectangle in which to draw the provided text according to the speci...
Definition: qstyle.cpp:470
QBool contains(const T &t) const
Returns true if the list contains an occurrence of value; otherwise returns false.
Definition: qlist.h:880
The QStyleOptionQ3ListViewItem class is used to describe an item drawn in a Q3ListView.
Definition: qstyleoption.h:463
QPainterPath createStroke(const QPainterPath &path) const
Generates a new path that is a fillable area representing the outline of the given path...
QGraphicsItem * focusItem() const
When the scene is active, this functions returns the scene&#39;s current focus item, or 0 if no item curr...
QPoint bottomRight() const
Returns the position of the rectangle&#39;s bottom-right corner.
Definition: qrect.h:291
QMatrix & rotate(qreal a)
Rotates the coordinate system the given degrees counterclockwise.
Definition: qmatrix.cpp:990
QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget=0) const
Reimplemented Function
const QBrush & light() const
Returns the light brush of the current color group.
Definition: qpalette.h:126
void drawLines(const QLineF *lines, int lineCount)
Draws the first lineCount lines in the array lines using the current pen.
Definition: qpainter.cpp:4873
void fillPath(const QPainterPath &path, const QBrush &brush)
Fills the given path using the given brush.
Definition: qpainter.cpp:3456
QString left(int n) const Q_REQUIRED_RESULT
Returns a substring that contains the n leftmost characters of the string.
Definition: qstring.cpp:3664
static const QColor titlebarGradientActiveEnd(151, 151, 151)
QSize size(int flags, const QString &str, int tabstops=0, int *tabarray=0) const
Returns the size in pixels of text.
virtual QPalette standardPalette() const
Returns the style&#39;s standard palette.
Definition: qstyle.cpp:2283
The QStyleOption class stores the parameters used by QStyle functions.
Definition: qstyleoption.h:67
int size() const
Returns the number of characters in this string.
Definition: qstring.h:102
int height
the height of the widget excluding any window frame
Definition: qwidget.h:167
bool testAttribute(Qt::WidgetAttribute) const
Returns true if attribute attribute is set on this widget; otherwise returns false.
Definition: qwidget.h:1041
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
static void setFocusRectPolicy(QWidget *w, FocusRectPolicy policy)
#define qApp
ContentsType
This enum describes the available contents types.
Definition: qstyle.h:602
The QTreeView class provides a default model/view implementation of a tree view.
Definition: qtreeview.h:58
void initFrom(const QWidget *w)
Definition: qstyleoption.h:99
The QStyleOptionSpinBox class is used to describe the parameters necessary for drawing a spin box...
Definition: qstyleoption.h:729
void setTop(int pos)
Sets the top edge of the rectangle to the given y coordinate.
Definition: qrect.h:261
static ThemeTabDirection getTabDirection(QTabBar::Shape shape)
const QFont & font() const
Returns the currently set font used for drawing text.
Definition: qpainter.cpp:4312
static const QColor mainWindowGradientBegin(240, 240, 240)
bool eventFilter(QObject *, QEvent *)
Filters events if this object has been installed as an event filter for the watched object...
QIcon icon
the icon of the button
Definition: qstyleoption.h:291
QSize size() const
Returns the size of the rectangle.
Definition: qrect.h:309
Mode
This enum type describes the mode for which a pixmap is intended to be used.
Definition: qicon.h:63
QAquaWidgetSize
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
bool isNull() const
Returns true if the icon is empty; otherwise returns false.
Definition: qicon.cpp:769
void adjust(int x1, int y1, int x2, int y2)
Adds dx1, dy1, dx2 and dy2 respectively to the existing coordinates of the rectangle.
Definition: qrect.h:434
LayoutDirection
Definition: qnamespace.h:1580
The QComboBox widget is a combined button and popup list.
Definition: qcombobox.h:62
virtual int type() const
Returns the type of an item as an int.
QFontMetrics fontMetrics() const
Returns the font metrics for the widget&#39;s current font.
Definition: qwidget.h:984
virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w=0) const =0
Draws the given primitive element with the provided painter using the style options specified by opti...
qreal height() const
Returns the height of the font.
Q3ListViewItemFeatures features
the features for this item
Definition: qstyleoption.h:473
void setSize(const QSize &s)
Sets the size of the rectangle to the given size.
Definition: qrect.h:448
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
void transpose()
Swaps the width and height values.
Definition: qsize.cpp:196
The QStyleOptionFrame class is used to describe the parameters for drawing a frame.
Definition: qstyleoption.h:118
unsigned int uint
Definition: qglobal.h:996
int indexOf(QChar c, int from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:2838
static int qt_mac_aqua_get_metric(ThemeMetric met)
bool macWindowIsTextured(void *window)
static Bigint * diff(Bigint *a, Bigint *b)
T findChild(const QString &aName=QString()) const
Returns the child of this object that can be cast into type T and that is called name, or 0 if there is no such object.
Definition: qobject.h:158
int pixelMetric(PixelMetric pm, const QStyleOption *option=0, const QWidget *widget=0) const
Reimplemented Function
Qt::Orientation orientation() const
FontHash * qt_app_fonts_hash()
void addRect(const QRectF &rect)
Adds the given rectangle to this path as a closed subpath.
QRegion qt_mac_convert_mac_region(RgnHandle)
QPaintEngine * paintEngine() const
Returns the paint engine that the painter is currently operating on if the painter is active; otherwi...
Definition: qpainter.cpp:1991
QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *widget=0) const
Reimplemented Function
The QStyleOptionTabWidgetFrame class is used to describe the parameters for drawing the frame around ...
Definition: qstyleoption.h:175
int sliderPosition
the position of the slider handle
Definition: qstyleoption.h:713
The QSlider widget provides a vertical or horizontal slider.
Definition: qslider.h:57
The QRegion class specifies a clip region for a painter.
Definition: qregion.h:68
static const int BevelButtonW
The QPainterPathStroker class is used to generate fillable outlines for a given painter path...
Definition: qpainterpath.h:264
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option)
ButtonFeatures features
a bitwise OR of the features that describe this button
Definition: qstyleoption.h:289
void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w=0) const
Reimplemented Function
The State element defines configurations of objects and properties.
static const int SmallButtonH
int layoutSpacingImplementation(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, Qt::Orientation orientation, const QStyleOption *option=0, const QWidget *widget=0) const
QPixmap texture() const
Returns the custom brush pattern, or a null pixmap if no custom brush pattern has been set...
Definition: qbrush.cpp:785
void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *w=0) const
Reimplemented Function
static void drawCombobox(const HIRect &outerBounds, const HIThemeButtonDrawInfo &bdi, QPainter *p)
bool isNull() const
Returns true if this byte array is null; otherwise returns false.
signed long OSStatus
The QStyleOptionRubberBand class is used to describe the parameters needed for drawing a rubber band...
Definition: qstyleoption.h:669
Q_GUI_EXPORT_INLINE int qBlue(QRgb rgb)
Definition: qrgb.h:63
bool inherits(const char *classname) const
Returns true if this object is an instance of a class that inherits className or a QObject subclass t...
Definition: qobject.h:275
struct OpaqueRgnHandle * RgnHandle
The QFontInfo class provides general information about fonts.
Definition: qfontinfo.h:54
The QTableView class provides a default model/view implementation of a table view.
Definition: qtableview.h:58
void setX(int x)
Sets the left edge of the rectangle to the given x coordinate.
Definition: qrect.h:282
const int macItemVMargin
FrameFeatures features
a bitwise OR of the features that describe this frame.
Definition: qstyleoption.h:143
int count() const
Definition: qstring.h:103
bool contains(const QPoint &p, bool proper=false) const
Returns true if the given point is inside or on the edge of the rectangle, otherwise returns false...
Definition: qrect.cpp:1101
bool isEnabled() const
Definition: qwidget.h:948
void qSwap(T &value1, T &value2)
Definition: qglobal.h:2181
const QBrush & brush(ColorGroup cg, ColorRole cr) const
Returns the brush in the specified color group, used for the given color role.
Definition: qpalette.cpp:874
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
QSize rightButtonSize
the size for the right widget on the tab.
Definition: qstyleoption.h:353
void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *w=0) const
Reimplemented Function
The QGraphicsProxyWidget class provides a proxy layer for embedding a QWidget in a QGraphicsScene...
bool floatable
whether the dock window is floatable
Definition: qstyleoption.h:513
int styleHint(StyleHint hint, const QStyleOption *opt=0, const QWidget *widget=0, QStyleHintReturn *returnData=0) const
Reimplemented Function
Q_CORE_EXPORT QTextStream & center(QTextStream &s)
Qt::LayoutDirection layoutDirection
the layout direction for this widget
Definition: qwidget.h:216
bool documentMode
whether the tabbar is in document mode.
Definition: qstyleoption.h:351
static HIRect qt_hirectForQRect(const QRect &convertRect, const QRect &rect=QRect())
virtual ~QMacStyle()
QPoint topRight() const
Returns the position of the rectangle&#39;s top-right corner.
Definition: qrect.h:294
const QBrush & brush() const
Returns the painter&#39;s current brush.
Definition: qpainter.cpp:4232
void drawTiledPixmap(const QRectF &rect, const QPixmap &pm, const QPointF &offset=QPointF())
Draws a tiled pixmap, inside the given rectangle with its origin at the given position.
Definition: qpainter.cpp:7146
The QStyleOptionTabBarBaseV2 class is used to describe the base of a tab bar, i.e.
Definition: qstyleoption.h:235
void fill(const QColor &fillColor=Qt::white)
Fills the pixmap with the given color.
Definition: qpixmap.cpp:1080
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
bool contentFitsInPushButton(const QStyleOptionButton *btn, HIThemeButtonDrawInfo *bdi, ThemeButtonKind buttonKindToCheck) const
QPalette palette
the palette that should be used when painting the control
Definition: qstyleoption.h:92
void setRenderHints(RenderHints hints, bool on=true)
Sets the given render hints on the painter if on is true; otherwise clears the render hints...
Definition: qpainter.cpp:7649
The QBrush class defines the fill pattern of shapes drawn by QPainter.
Definition: qbrush.h:76
bool isNull() const
Returns true if this string is null; otherwise returns false.
Definition: qstring.h:505
QPoint center() const
Returns the center point of the rectangle.
Definition: qrect.h:300
void getSliderInfo(QStyle::ComplexControl cc, const QStyleOptionSlider *slider, HIThemeTrackDrawInfo *tdi, const QWidget *needToRemoveMe)
struct CGRect CGRect
bool unifiedTitleAndToolBarOnMac
whether the window uses the unified title and toolbar look on Mac OS X
Definition: qmainwindow.h:83
QString mid(int position, int n=-1) const Q_REQUIRED_RESULT
Returns a string that contains n characters of this string, starting at the specified position index...
Definition: qstring.cpp:3706
bool animatable(Animates, const QWidget *) const
virtual void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const
Draws the given pixmap in the specified rectangle, according to the specified alignment, using the provided painter.
Definition: qstyle.cpp:570
Q_GUI_EXPORT_INLINE int qGray(int r, int g, int b)
Definition: qrgb.h:75
const QBrush & windowText() const
Returns the window text (general foreground) brush of the current color group.
Definition: qpalette.h:124
QString text
the text of the tab
Definition: qstyleoption.h:317
uchar * bits()
Returns a pointer to the first pixel data.
Definition: qimage.cpp:1946
SelectedPosition selectedPosition
the position of the selected tab in relation to this tab
Definition: qstyleoption.h:321
void setPixel(int x, int y, uint index_or_rgb)
Sets the pixel index or color at (x, y) to index_or_rgb.
Definition: qimage.cpp:4311
The QStyleHintReturnMask class provides style hints that return a QRegion.
Definition: qstyleoption.h:923
QPaintDevice * qt_mac_safe_pdev
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
int width() const
Returns the width of the image.
Definition: qimage.cpp:1557
int maximum
the maximum value for the slider
Definition: qstyleoption.h:709
QString arg(qlonglong a, int fieldwidth=0, int base=10, const QChar &fillChar=QLatin1Char(' ')) const Q_REQUIRED_RESULT
Definition: qstring.cpp:7186
static QRect visualRect(Qt::LayoutDirection direction, const QRect &boundingRect, const QRect &logicalRect)
Returns the given logicalRectangle converted to screen coordinates based on the specified direction...
Definition: qstyle.cpp:2087
QSize iconSize() const
static const int PushButtonTopOffset
QImage convertToFormat(Format f, Qt::ImageConversionFlags flags=Qt::AutoColor) const Q_REQUIRED_RESULT
Returns a copy of the image in the given format.
Definition: qimage.cpp:3966
static Qt::KeyboardModifiers keyboardModifiers()
Returns the current state of the modifier keys on the keyboard.
void setClipRegion(const QRegion &, Qt::ClipOperation op=Qt::ReplaceClip)
Sets the clip region to the given region using the specified clip operation.
Definition: qpainter.cpp:2917
QSize pushButtonSizeFromContents(const QStyleOptionButton *btn) const
void timerEvent(QTimerEvent *)
This event handler can be reimplemented in a subclass to receive timer events for the object...
int qMacVersion()
Definition: qglobal.h:1685
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
QPoint bottomLeft() const
Returns the position of the rectangle&#39;s bottom-left corner.
Definition: qrect.h:297
QPixmap * qt_mac_backgroundPattern
PrimitiveElement
This enum describes the various primitive elements.
Definition: qstyle.h:145
void setAlphaF(qreal alpha)
Sets the alpha of this color to alpha.
Definition: qcolor.cpp:1117
The QTimerEvent class contains parameters that describe a timer event.
Definition: qcoreevent.h:341
#define CT1(c)
void setLeft(int pos)
Sets the left edge of the rectangle to the given x coordinate.
Definition: qrect.h:258
The QLinearGradient class is used in combination with QBrush to specify a linear gradient brush...
Definition: qbrush.h:280
State
Definition: qaudio.h:59
qint64 cacheKey() const
Returns a number that identifies the contents of this QIcon object.
Definition: qicon.cpp:679
The QFont class specifies a font used for drawing text.
Definition: qfont.h:64
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255
const QBrush & highlightedText() const
Returns the highlighted text brush of the current color group.
Definition: qpalette.h:141
static int getControlSize(const QStyleOption *option, const QWidget *widget)
void setWidthF(qreal width)
Sets the pen width to the given width in pixels with floating point precision.
Definition: qpen.cpp:690
T qstyleoption_cast(const QStyleOption *opt)
Definition: qstyleoption.h:885
QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *widget=0) const
Reimplemented Function
QSize actualSize(const QSize &size, Mode mode=Normal, State state=Off) const
Returns the actual size of the icon for the requested size, mode, and state.
Definition: qicon.cpp:730
int minimum
the minimum value for the slider
Definition: qstyleoption.h:708
qreal redF() const
Returns the red color component of this color.
Definition: qcolor.cpp:1213
int x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:252
QSizePolicy sizePolicy
the default layout behavior of the widget
Definition: qwidget.h:171
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget=0) const
Reimplemented Function
void setRect(int x, int y, int w, int h)
Sets the coordinates of the rectangle&#39;s top-left corner to ({x}, {y}), and its size to the given widt...
Definition: qrect.h:400
static WidgetSizePolicy widgetSizePolicy(const QWidget *w)
static bool insert(const QString &key, const QPixmap &pixmap)
Inserts a copy of the pixmap pixmap associated with the key into the cache.
int key
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
void setColor(ColorGroup cg, ColorRole cr, const QColor &color)
Sets the color in the specified color group, used for the given color role, to the specified solid co...
Definition: qpalette.h:201
static QRect comboboxEditBounds(const QRect &outerBounds, const HIThemeButtonDrawInfo &bdi)
QVector< QRect > rects() const
Returns an array of non-overlapping rectangles that make up the region.
Definition: qregion.cpp:4412
void installEventFilter(QObject *)
Installs an event filter filterObj on this object.
Definition: qobject.cpp:2070
void setBrush(const QBrush &brush)
Sets the painter&#39;s brush to the given brush.
Definition: qpainter.cpp:4171
virtual void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w=0) const =0
Draws the given element with the provided painter with the style options specified by option...
virtual int styleHint(StyleHint sh, const QStyleOption *opt=0, const QWidget *w=0, QStyleHintReturn *shret=0) const
Reimplemented Function
void setMatrix(const QMatrix &matrix, bool combine=false)
Use setWorldTransform() instead.
Definition: qpainter.cpp:3045
static FocusRectPolicy focusRectPolicy(const QWidget *w)
The QMainWindow class provides a main application window.
Definition: qmainwindow.h:63
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
void setAlpha(int alpha)
Sets the alpha of this color to alpha.
Definition: qcolor.cpp:1094
void stopAnimate(Animates, QWidget *)
static const int BevelButtonH
The QStyleOptionGroupBox class describes the parameters for drawing a group box.
Definition: qstyleoption.h:834
static bool desktopSettingsAware()
Returns true if Qt is set to use the system&#39;s standard colors, fonts, etc.
const char * className() const
Returns the class name.
Definition: qobjectdefs.h:491
The QStyleOptionComboBox class is used to describe the parameter for drawing a combobox.
Definition: qstyleoption.h:796
int & rheight()
Returns a reference to the height.
Definition: qsize.h:144
void setWidth(int w)
Sets the width of the rectangle to the given width.
Definition: qrect.h:442
void setPen(const QColor &color)
Sets the painter&#39;s pen to have style Qt::SolidLine, width 0 and the specified color.
Definition: qpainter.cpp:4047
qreal pointSizeF() const
Returns the point size of the matched window system font.
Definition: qfont.cpp:2710
QString objectName() const
The QStyleOptionTabV3 class is used to describe the parameters necessary for drawing a tabs in Qt 4...
Definition: qstyleoption.h:347
int height() const
Returns the height.
Definition: qsize.h:129
Qt::LayoutDirection direction
the text layout direction that should be used when drawing text in the control
Definition: qstyleoption.h:89
void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush)
if(void) toggleToolbarShown
qreal blueF() const
Returns the blue color component of this color.
Definition: qcolor.cpp:1269
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
QColor qcolorForTheme(ThemeBrush brush)
Definition: qt_mac.cpp:110
bool isValid() const
Returns true if both the width and height is equal to or greater than 0; otherwise returns false...
Definition: qsize.h:123
QTabBar::Shape shape
the shape of the tab bar
Definition: qstyleoption.h:224
static const char *const qt_mac_toolbar_ext[]
QFactoryLoader * l
SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, const QPoint &pt, const QWidget *w=0) const
Reimplemented Function
static const int PushButtonContentPadding
bool isDefault() const
static ThemeDrawState getDrawState(QStyle::State flags)
QMacStylePrivate(QMacStyle *style)
int height() const
Returns the height of the image.
Definition: qimage.cpp:1572
The QStyleOptionFrameV2 class is used to describe the parameters necessary for drawing a frame in Qt ...
Definition: qstyleoption.h:134
qint64 cacheKey() const
Returns a number that identifies this QPixmap.
Definition: qpixmap.cpp:1136
void drawRect(const QRectF &rect)
Draws the current rectangle with the current pen and brush.
Definition: qpainter.h:650
QPointer< QFocusFrame > focusWidget
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
void setAttribute(Qt::WidgetAttribute, bool on=true)
Sets the attribute attribute on this widget if on is true; otherwise clears the attribute.
Definition: qwidget.cpp:11087
void setLoadHints(LoadHints hints)
Definition: qlibrary.cpp:1304
const QStyle * proxy() const
Definition: qstyle.cpp:2546
void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w=0) const
Reimplemented Function
Qt::Orientation orientation
the slider&#39;s orientation (horizontal or vertical)
Definition: qstyleoption.h:707
QVariant property(const char *name) const
Returns the value of the object&#39;s name property.
Definition: qobject.cpp:3807
QWidget * window() const
Returns the window for this widget, i.e.
Definition: qwidget.cpp:4492
The QPixmap class is an off-screen image representation that can be used as a paint device...
Definition: qpixmap.h:71
void drawBorderPixmap(const QPixmap &pixmap, QPainter *painter, const QRect &rect, int left, int top, int right, int bottom)
Q_GUI_EXPORT_INLINE int qGreen(QRgb rgb)
Definition: qrgb.h:60
CGContextRef qt_mac_cg_context(const QPaintDevice *)
Returns the CoreGraphics CGContextRef of the paint device.
#define QT_BEGIN_INCLUDE_NAMESPACE
This macro is equivalent to QT_END_NAMESPACE.
Definition: qglobal.h:91
The QStyleOptionTab class is used to describe the parameters for drawing a tab bar.
Definition: qstyleoption.h:304
void setPointSizeF(qreal)
Sets the point size to pointSize.
Definition: qfont.cpp:1121
The QFocusFrame widget provides a focus frame which can be outside of a widget&#39;s normal paintable are...
Definition: qfocusframe.h:56
The QGraphicsView class provides a widget for displaying the contents of a QGraphicsScene.
Definition: qgraphicsview.h:64
QPixmap pixmap(const QSize &size, Mode mode=Normal, State state=Off) const
Returns a pixmap with the requested size, mode, and state, generating one if necessary.
Definition: qicon.cpp:693
bool isNull() const
Returns true if both the width and height is 0; otherwise returns false.
Definition: qsize.h:117
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(0), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
Invokes the member (a signal or a slot name) on the object obj.
void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect)
Draws the rectangular portion source of the given pixmap into the given target in the paint device...
Definition: qpainter.cpp:5619
int height() const
Returns the height of the pixmap.
Definition: qpixmap.cpp:645
static QBitmap fromImage(const QImage &image, Qt::ImageConversionFlags flags=Qt::AutoColor)
Returns a copy of the given image converted to a bitmap using the specified image conversion flags...
Definition: qbitmap.cpp:281
static const int PushButtonRightOffset
ControlElement
This enum represents a control element.
Definition: qstyle.h:217
The QStyleOptionSlider class is used to describe the parameters needed for drawing a slider...
Definition: qstyleoption.h:701
int pageStep
the size of the page step of the slider
Definition: qstyleoption.h:716
static const MacVersion MacintoshVersion
the version of the Macintosh operating system on which the application is run (Mac only)...
Definition: qglobal.h:1646
The QFontMetricsF class provides font metrics information.
Definition: qfontmetrics.h:145
int pointSize() const
Returns the point size of the font.
Definition: qfont.cpp:981
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
void setFont(const QFont &f)
Sets the painter&#39;s font to the given font.
Definition: qpainter.cpp:4288
ToolButtonStyle
Definition: qnamespace.h:1572
Qt::WindowType windowType() const
Returns the window type of this widget.
Definition: qwidget.h:937
QGraphicsScene * scene() const
Returns the current scene for the item, or 0 if the item is not stored in a scene.
QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget=0) const
Reimplemented Function
The QTabWidget class provides a stack of tabbed widgets.
Definition: qtabwidget.h:60
static void setWidgetSizePolicy(const QWidget *w, WidgetSizePolicy policy)
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
The QStyleOptionComplex class is used to hold parameters that are common to all complex controls...
Definition: qstyleoption.h:687
struct CGContext * CGContextRef
static bool isTreeView(const QWidget *widget)
int animateSpeed(Animates) const
QRegion region
the region for style hints that return a QRegion
Definition: qstyleoption.h:930
QPointer< QPushButton > defaultButton
void initHIThemePushButton(const QStyleOptionButton *btn, const QWidget *widget, const ThemeDrawState tds, HIThemeButtonDrawInfo *bdi) const
The QWindowsStyle class provides a Microsoft Windows-like look and feel.
Definition: qwindowsstyle.h:57
void moveTop(int pos)
Moves the rectangle vertically, leaving the rectangle&#39;s top edge at the given y coordinate.
Definition: qrect.h:353
The QToolButton class provides a quick-access button to commands or options, usually used inside a QT...
Definition: qtoolbutton.h:59
QList< QPointer< QWidget > > progressBars
The QStyleOptionProgressBar class is used to describe the parameters necessary for drawing a progress...
Definition: qstyleoption.h:396
QSize leftButtonSize
the size for the left widget on the tab.
Definition: qstyleoption.h:352
void initComboboxBdi(const QStyleOptionComboBox *combo, HIThemeButtonDrawInfo *bdi, const QWidget *widget, const ThemeDrawState &tds)
QColor lighter(int f=150) const
Returns a lighter (or darker) color, but does not change this object.
Definition: qcolor.h:298
int height() const
Returns the height of the font.
HIRect pushButtonContentBounds(const QStyleOptionButton *btn, const HIThemeButtonDrawInfo *bdi) const
bool isValid() const
Returns true if the storage type of this variant is not QVariant::Invalid; otherwise returns false...
Definition: qvariant.h:485
void translate(int dx, int dy)
Moves the rectangle dx along the x axis and dy along the y axis, relative to the current position...
Definition: qrect.h:312
static const KeyPair *const end
static void drawToolbarButtonArrow(const QRect &toolButtonRect, ThemeDrawState tds, CGContextRef cg)
void drawColorlessButton(const HIRect &macRect, HIThemeButtonDrawInfo *bdi, QPainter *p, const QStyleOption *opt) const
Orientation
Definition: qnamespace.h:174
static int scrollButtonsCutoffSize(ScrollBarCutoffType cutoffType, QMacStyle::WidgetSizePolicy widgetSize)
static void setLayoutItemMargins(int left, int top, int right, int bottom, QRect *rect, Qt::LayoutDirection dir)
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
ScrollBarCutoffType
The QRubberBand class provides a rectangle or line that can indicate a selection or a boundary...
Definition: qrubberband.h:58
Type type() const
Returns the event type.
Definition: qcoreevent.h:303
The QFrame class is the base class of widgets that can have a frame.
Definition: qframe.h:55
Q_CORE_EXPORT QTextStream & left(QTextStream &s)
ControlType controlType() const
Definition: qlayout.cpp:1670
static bool isRightToLeft()
Returns true if the application&#39;s layout direction is Qt::RightToLeft; otherwise returns false...
Definition: qapplication.h:233
static const QColor titlebarSeparatorLineActive(111, 111, 111)
static QWidget * focusWidget()
Returns the application widget that has the keyboard input focus, or 0 if no widget in this applicati...
The QStyleOptionButton class is used to describe the parameters for drawing buttons.
Definition: qstyleoption.h:279
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
static bool isVerticalTabs(const QTabBar::Shape shape)
void setWindowOpacity(qreal level)
Definition: qwidget.cpp:11497
void drawTabBase(QPainter *p, const QStyleOptionTabBarBaseV2 *tbb, const QWidget *w)
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
QRect rect
the area that should be used for various calculations and painting
Definition: qstyleoption.h:90
static HIRect comboboxInnerBounds(const HIRect &outerBounds, int buttonKind)
QStyle::SubControls subControls
This variable holds a bitwise OR of the sub-controls to be drawn for the complex control.
Definition: qstyleoption.h:693
QRgb rgb() const
Returns the RGB value of the color.
Definition: qcolor.cpp:1051
#define enabled
static QPaintDevice * redirected(const QPaintDevice *device, QPoint *offset=0)
Using QWidget::render() obsoletes the use of this function.
Definition: qpainter.cpp:8391
Q_DECL_CONSTEXPR int qRound(qreal d)
Definition: qglobal.h:1203
void setPalette(const QPalette &)
Use the single-argument overload instead.
Definition: qwidget.cpp:4858
bool event(QEvent *e)
This virtual function receives events to an object and should return true if the event e was recogniz...
virtual const QMetaObject * metaObject() const
Returns a pointer to the meta-object of this object.
const int macItemFrame
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
Definition: qimage.cpp:1886
bool end()
Ends painting.
Definition: qpainter.cpp:1929
QTabBar::Shape shape
the tab shape used to draw the tabs
Definition: qstyleoption.h:183
QWidget * widget() const
Returns a pointer to the embedded widget.
static bool isNull(const QVariant::Private *d)
Definition: qvariant.cpp:300
int & rwidth()
Returns a reference to the width.
Definition: qsize.h:141
void fillRect(const QRectF &, const QBrush &)
Fills the given rectangle with the brush specified.
Definition: qpainter.cpp:7420
#define text
Definition: qobjectdefs.h:80
QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *w=0) const
Reimplemented Function
void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w=0) const
Reimplemented Function
const QBrush & text() const
Returns the text foreground brush of the current color group.
Definition: qpalette.h:129
QIcon icon() const
The QLibrary class loads shared libraries at runtime.
Definition: qlibrary.h:62
SubElement
This enum represents a sub-area of a widget.
Definition: qstyle.h:289
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
void setWidth(int width)
Sets the pen width to the given width in pixels with integer precision.
Definition: qpen.cpp:667
float CGFloat
void killTimer(int id)
Kills the timer with timer identifier, id.
Definition: qobject.cpp:1650
QPoint topLeft() const
Returns the position of the rectangle&#39;s top-left corner.
Definition: qrect.h:288
int removeAll(const T &t)
Removes all occurrences of value in the list and returns the number of entries removed.
Definition: qlist.h:770
void translate(const QPointF &offset)
Translates the coordinate system by the given offset; i.e.
Definition: qpainter.cpp:3311
The QPalette class contains color groups for each widget state.
Definition: qpalette.h:61
The QIcon class provides scalable icons in different modes and states.
Definition: qicon.h:60
void removeAt(int i)
Removes the item at index position i.
Definition: qlist.h:480