src/gui/styles/qmacstyle_mac.mm
changeset 18 2f34d5167611
parent 3 41300fa6a67c
child 30 5dc02b23752f
equal deleted inserted replaced
3:41300fa6a67c 18:2f34d5167611
     1 /****************************************************************************
     1 /****************************************************************************
     2 **
     2 **
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     4 ** All rights reserved.
     4 ** All rights reserved.
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     6 **
     6 **
     7 ** This file is part of the QtGui module of the Qt Toolkit.
     7 ** This file is part of the QtGui module of the Qt Toolkit.
     8 **
     8 **
   665             return ret;
   665             return ret;
   666     }
   666     }
   667 
   667 
   668     switch (ct) {
   668     switch (ct) {
   669     case QStyle::CT_PushButton: {
   669     case QStyle::CT_PushButton: {
   670         const QPushButton *psh = static_cast<const QPushButton *>(widg);
   670         const QPushButton *psh = qobject_cast<const QPushButton *>(widg);
   671         QString buttonText = qt_mac_removeMnemonics(psh->text());
   671         // If this comparison is false, then the widget was not a push button.
   672         if (buttonText.contains(QLatin1Char('\n')))
   672         // This is bad and there's very little we can do since we were requested to find a
   673             ret = QSize(-1, -1);
   673         // sensible size for a widget that pretends to be a QPushButton but is not.
   674         else if (sz == QAquaSizeLarge)
   674         if(psh) {
   675             ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight));
   675             QString buttonText = qt_mac_removeMnemonics(psh->text());
   676         else if (sz == QAquaSizeSmall)
   676             if (buttonText.contains(QLatin1Char('\n')))
   677             ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight));
   677                 ret = QSize(-1, -1);
   678         else if (sz == QAquaSizeMini)
   678             else if (sz == QAquaSizeLarge)
   679             ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight));
   679                 ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight));
   680 
   680             else if (sz == QAquaSizeSmall)
   681         if (!psh->icon().isNull()){
   681                 ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight));
   682             // If the button got an icon, and the icon is larger than the
   682             else if (sz == QAquaSizeMini)
   683             // button, we can't decide on a default size
   683                 ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight));
   684             ret.setWidth(-1);
   684 
   685             if (ret.height() < psh->iconSize().height())
   685             if (!psh->icon().isNull()){
   686                 ret.setHeight(-1);
   686                 // If the button got an icon, and the icon is larger than the
   687         }
   687                 // button, we can't decide on a default size
   688         else if (buttonText == QLatin1String("OK") || buttonText == QLatin1String("Cancel")){
   688                 ret.setWidth(-1);
   689             // Aqua Style guidelines restrict the size of OK and Cancel buttons to 68 pixels.
   689                 if (ret.height() < psh->iconSize().height())
   690             // However, this doesn't work for German, therefore only do it for English,
   690                     ret.setHeight(-1);
   691             // I suppose it would be better to do some sort of lookups for languages
   691             }
   692             // that like to have really long words.
   692             else if (buttonText == QLatin1String("OK") || buttonText == QLatin1String("Cancel")){
   693             ret.setWidth(77 - 8);
   693                 // Aqua Style guidelines restrict the size of OK and Cancel buttons to 68 pixels.
   694         }
   694                 // However, this doesn't work for German, therefore only do it for English,
   695 
   695                 // I suppose it would be better to do some sort of lookups for languages
       
   696                 // that like to have really long words.
       
   697                 ret.setWidth(77 - 8);
       
   698             }
       
   699         } else {
       
   700             // The only sensible thing to do is to return whatever the style suggests...
       
   701             if (sz == QAquaSizeLarge)
       
   702                 ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight));
       
   703             else if (sz == QAquaSizeSmall)
       
   704                 ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight));
       
   705             else if (sz == QAquaSizeMini)
       
   706                 ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight));
       
   707             else
       
   708                 // Since there's no default size we return the large size...
       
   709                 ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight));
       
   710          }
   696 #if 0 //Not sure we are applying the rules correctly for RadioButtons/CheckBoxes --Sam
   711 #if 0 //Not sure we are applying the rules correctly for RadioButtons/CheckBoxes --Sam
   697     } else if (ct == QStyle::CT_RadioButton) {
   712     } else if (ct == QStyle::CT_RadioButton) {
   698         QRadioButton *rdo = static_cast<QRadioButton *>(widg);
   713         QRadioButton *rdo = static_cast<QRadioButton *>(widg);
   699         // Exception for case where multiline radio button text requires no size constrainment
   714         // Exception for case where multiline radio button text requires no size constrainment
   700         if (rdo->text().find('\n') != -1)
   715         if (rdo->text().find('\n') != -1)
   747         break;
   762         break;
   748     case QStyle::CT_ToolButton:
   763     case QStyle::CT_ToolButton:
   749         if (sz == QAquaSizeSmall) {
   764         if (sz == QAquaSizeSmall) {
   750             int width = 0, height = 0;
   765             int width = 0, height = 0;
   751             if (szHint == QSize(-1, -1)) { //just 'guess'..
   766             if (szHint == QSize(-1, -1)) { //just 'guess'..
   752                 const QToolButton *bt = static_cast<const QToolButton *>(widg);
   767                 const QToolButton *bt = qobject_cast<const QToolButton *>(widg);
   753                 if (!bt->icon().isNull()) {
   768                 // If this conversion fails then the widget was not what it claimed to be.
   754                     QSize iconSize = bt->iconSize();
   769                 if(bt) {
   755                     QSize pmSize = bt->icon().actualSize(QSize(32, 32), QIcon::Normal);
   770                     if (!bt->icon().isNull()) {
   756                     width = qMax(width, qMax(iconSize.width(), pmSize.width()));
   771                         QSize iconSize = bt->iconSize();
   757                     height = qMax(height, qMax(iconSize.height(), pmSize.height()));
   772                         QSize pmSize = bt->icon().actualSize(QSize(32, 32), QIcon::Normal);
   758                 }
   773                         width = qMax(width, qMax(iconSize.width(), pmSize.width()));
   759                 if (!bt->text().isNull() && bt->toolButtonStyle() != Qt::ToolButtonIconOnly) {
   774                         height = qMax(height, qMax(iconSize.height(), pmSize.height()));
   760                     int text_width = bt->fontMetrics().width(bt->text()),
       
   761                        text_height = bt->fontMetrics().height();
       
   762                     if (bt->toolButtonStyle() == Qt::ToolButtonTextUnderIcon) {
       
   763                         width = qMax(width, text_width);
       
   764                         height += text_height;
       
   765                     } else {
       
   766                         width += text_width;
       
   767                         width = qMax(height, text_height);
       
   768                     }
   775                     }
       
   776                     if (!bt->text().isNull() && bt->toolButtonStyle() != Qt::ToolButtonIconOnly) {
       
   777                         int text_width = bt->fontMetrics().width(bt->text()),
       
   778                            text_height = bt->fontMetrics().height();
       
   779                         if (bt->toolButtonStyle() == Qt::ToolButtonTextUnderIcon) {
       
   780                             width = qMax(width, text_width);
       
   781                             height += text_height;
       
   782                         } else {
       
   783                             width += text_width;
       
   784                             width = qMax(height, text_height);
       
   785                         }
       
   786                     }
       
   787                 } else {
       
   788                     // Let's return the size hint...
       
   789                     width = szHint.width();
       
   790                     height = szHint.height();
   769                 }
   791                 }
   770             } else {
   792             } else {
   771                 width = szHint.width();
   793                 width = szHint.width();
   772                 height = szHint.height();
   794                 height = szHint.height();
   773             }
   795             }
   776             ret = QSize(width, height);
   798             ret = QSize(width, height);
   777         }
   799         }
   778         break;
   800         break;
   779     case QStyle::CT_Slider: {
   801     case QStyle::CT_Slider: {
   780         int w = -1;
   802         int w = -1;
   781         const QSlider *sld = static_cast<const QSlider *>(widg);
   803         const QSlider *sld = qobject_cast<const QSlider *>(widg);
   782         if (sz == QAquaSizeLarge) {
   804         // If this conversion fails then the widget was not what it claimed to be.
   783             if (sld->orientation() == Qt::Horizontal) {
   805         if(sld) {
   784                 w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight);
   806             if (sz == QAquaSizeLarge) {
   785                 if (sld->tickPosition() != QSlider::NoTicks)
   807                 if (sld->orientation() == Qt::Horizontal) {
   786                     w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight);
   808                     w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight);
   787             } else {
   809                     if (sld->tickPosition() != QSlider::NoTicks)
   788                 w = qt_mac_aqua_get_metric(kThemeMetricVSliderWidth);
   810                         w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight);
   789                 if (sld->tickPosition() != QSlider::NoTicks)
   811                 } else {
   790                     w += qt_mac_aqua_get_metric(kThemeMetricVSliderTickWidth);
   812                     w = qt_mac_aqua_get_metric(kThemeMetricVSliderWidth);
   791             }
   813                     if (sld->tickPosition() != QSlider::NoTicks)
   792         } else if (sz == QAquaSizeSmall) {
   814                         w += qt_mac_aqua_get_metric(kThemeMetricVSliderTickWidth);
   793             if (sld->orientation() == Qt::Horizontal) {
   815                 }
   794                 w = qt_mac_aqua_get_metric(kThemeMetricSmallHSliderHeight);
   816             } else if (sz == QAquaSizeSmall) {
   795                 if (sld->tickPosition() != QSlider::NoTicks)
   817                 if (sld->orientation() == Qt::Horizontal) {
   796                     w += qt_mac_aqua_get_metric(kThemeMetricSmallHSliderTickHeight);
   818                     w = qt_mac_aqua_get_metric(kThemeMetricSmallHSliderHeight);
   797             } else {
   819                     if (sld->tickPosition() != QSlider::NoTicks)
   798                 w = qt_mac_aqua_get_metric(kThemeMetricSmallVSliderWidth);
   820                         w += qt_mac_aqua_get_metric(kThemeMetricSmallHSliderTickHeight);
   799                 if (sld->tickPosition() != QSlider::NoTicks)
   821                 } else {
   800                     w += qt_mac_aqua_get_metric(kThemeMetricSmallVSliderTickWidth);
   822                     w = qt_mac_aqua_get_metric(kThemeMetricSmallVSliderWidth);
   801             }
   823                     if (sld->tickPosition() != QSlider::NoTicks)
   802         } else if (sz == QAquaSizeMini) {
   824                         w += qt_mac_aqua_get_metric(kThemeMetricSmallVSliderTickWidth);
   803             if (sld->orientation() == Qt::Horizontal) {
   825                 }
   804                 w = qt_mac_aqua_get_metric(kThemeMetricMiniHSliderHeight);
   826             } else if (sz == QAquaSizeMini) {
   805                 if (sld->tickPosition() != QSlider::NoTicks)
   827                 if (sld->orientation() == Qt::Horizontal) {
   806                     w += qt_mac_aqua_get_metric(kThemeMetricMiniHSliderTickHeight);
   828                     w = qt_mac_aqua_get_metric(kThemeMetricMiniHSliderHeight);
   807             } else {
   829                     if (sld->tickPosition() != QSlider::NoTicks)
   808                 w = qt_mac_aqua_get_metric(kThemeMetricMiniVSliderWidth);
   830                         w += qt_mac_aqua_get_metric(kThemeMetricMiniHSliderTickHeight);
   809                 if (sld->tickPosition() != QSlider::NoTicks)
   831                 } else {
   810                     w += qt_mac_aqua_get_metric(kThemeMetricMiniVSliderTickWidth);
   832                     w = qt_mac_aqua_get_metric(kThemeMetricMiniVSliderWidth);
   811             }
   833                     if (sld->tickPosition() != QSlider::NoTicks)
       
   834                         w += qt_mac_aqua_get_metric(kThemeMetricMiniVSliderTickWidth);
       
   835                 }
       
   836             }
       
   837         } else {
       
   838             // This is tricky, we were requested to find a size for a slider which is not
       
   839             // a slider. We don't know if this is vertical or horizontal or if we need to
       
   840             // have tick marks or not.
       
   841             // For this case we will return an horizontal slider without tick marks.
       
   842             w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight);
       
   843             w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight);
   812         }
   844         }
   813         if (sld->orientation() == Qt::Horizontal)
   845         if (sld->orientation() == Qt::Horizontal)
   814             ret.setHeight(w);
   846             ret.setHeight(w);
   815         else
   847         else
   816             ret.setWidth(w);
   848             ret.setWidth(w);
  2377         break;
  2409         break;
  2378     case PM_MenuHMargin:
  2410     case PM_MenuHMargin:
  2379         ret = 0;
  2411         ret = 0;
  2380         break;
  2412         break;
  2381     case PM_ToolBarFrameWidth:
  2413     case PM_ToolBarFrameWidth:
  2382         ret = 0;
  2414         ret = 1;
       
  2415         if (widget) {
       
  2416             if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(widget->parent()))
       
  2417                 if (mainWindow->unifiedTitleAndToolBarOnMac())
       
  2418                     ret = 0;
       
  2419         }
  2383         break;
  2420         break;
  2384     default:
  2421     default:
  2385         ret = QWindowsStyle::pixelMetric(metric, opt, widget);
  2422         ret = QWindowsStyle::pixelMetric(metric, opt, widget);
  2386         break;
  2423         break;
  2387     }
  2424     }
  3341 
  3378 
  3342                         // Draw the text if it's needed.
  3379                         // Draw the text if it's needed.
  3343                         if (tb->toolButtonStyle != Qt::ToolButtonIconOnly) {
  3380                         if (tb->toolButtonStyle != Qt::ToolButtonIconOnly) {
  3344                             needText = true;
  3381                             needText = true;
  3345                             if (tb->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
  3382                             if (tb->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
  3346                                 pr.setHeight(pixmap.size().height());
  3383                                 QMainWindow *mw = qobject_cast<QMainWindow *>(w->window());
  3347                                 cr.adjust(0, pr.bottom() + 1, 0, 1);
  3384                                 if (mw && mw->unifiedTitleAndToolBarOnMac()) {
       
  3385                                     pr.setHeight(pixmap.size().height());
       
  3386                                     cr.adjust(0, pr.bottom() + 1, 0, 1);
       
  3387                                 } else {
       
  3388                                     pr.setHeight(pixmap.size().height() + 6);
       
  3389                                     cr.adjust(0, pr.bottom(), 0, -3);
       
  3390                                 }       
  3348                                 alignment |= Qt::AlignCenter;
  3391                                 alignment |= Qt::AlignCenter;
  3349                             } else {
  3392                             } else {
  3350                                 pr.setWidth(pixmap.width() + 8);
  3393                                 pr.setWidth(pixmap.width() + 8);
  3351                                 cr.adjust(pr.right(), 0, 0, 0);
  3394                                 cr.adjust(pr.right(), 0, 0, 0);
  3352                                 alignment |= Qt::AlignLeft | Qt::AlignVCenter;
  3395                                 alignment |= Qt::AlignLeft | Qt::AlignVCenter;
  3704                     rotateTabPainter(p, myTab.shape, myTab.rect);
  3747                     rotateTabPainter(p, myTab.shape, myTab.rect);
  3705 
  3748 
  3706                     QPalette np = tab->palette;
  3749                     QPalette np = tab->palette;
  3707                     np.setColor(QPalette::WindowText, QColor(255, 255, 255, 75));
  3750                     np.setColor(QPalette::WindowText, QColor(255, 255, 255, 75));
  3708                     QRect nr = subElementRect(SE_TabBarTabText, opt, w);
  3751                     QRect nr = subElementRect(SE_TabBarTabText, opt, w);
  3709                     nr.moveTop(+1);
  3752                     nr.moveTop(-1);
  3710                     int alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextHideMnemonic;
  3753                     int alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextHideMnemonic;
  3711                     proxy()->drawItemText(p, nr, alignment, np, tab->state & State_Enabled,
  3754                     proxy()->drawItemText(p, nr, alignment, np, tab->state & State_Enabled,
  3712                                                tab->text, QPalette::WindowText);
  3755                                                tab->text, QPalette::WindowText);
  3713                     p->restore();
  3756                     p->restore();
  3714                 }
  3757                 }
  3994                 // myFont may not have any "hard" flags set. We override
  4037                 // myFont may not have any "hard" flags set. We override
  3995                 // the point size so that when it is resolved against the device, this font will win.
  4038                 // the point size so that when it is resolved against the device, this font will win.
  3996                 // This is mainly to handle cases where someone sets the font on the window
  4039                 // This is mainly to handle cases where someone sets the font on the window
  3997                 // and then the combo inherits it and passes it onward. At that point the resolve mask
  4040                 // and then the combo inherits it and passes it onward. At that point the resolve mask
  3998                 // is very, very weak. This makes it stonger.
  4041                 // is very, very weak. This makes it stonger.
  3999                 myFont.setPointSizeF(mi->font.pointSizeF());
  4042                 myFont.setPointSizeF(QFontInfo(mi->font).pointSizeF());
  4000                 p->setFont(myFont);
  4043                 p->setFont(myFont);
  4001                 p->drawText(xpos, yPos, contentRect.width() - xm - tabwidth + 1,
  4044                 p->drawText(xpos, yPos, contentRect.width() - xm - tabwidth + 1,
  4002                             contentRect.height(), text_flags ^ Qt::AlignRight, s);
  4045                             contentRect.height(), text_flags ^ Qt::AlignRight, s);
  4003                 p->restore();
  4046                 p->restore();
  4004             }
  4047             }
  4307                 // We need to allow the text a bit more space when the header is as
  4350                 // We need to allow the text a bit more space when the header is as
  4308                 // small as kThemeMetricListHeaderHeight, otherwise it gets clipped:
  4351                 // small as kThemeMetricListHeaderHeight, otherwise it gets clipped:
  4309                 rect.setY(0);
  4352                 rect.setY(0);
  4310                 rect.setHeight(widget->height());
  4353                 rect.setHeight(widget->height());
  4311             }
  4354             }
  4312             if (opt->direction == Qt::RightToLeft)
       
  4313                 rect.adjust(15, 0, -20, 0);
       
  4314         }
  4355         }
  4315         break;
  4356         break;
  4316     case SE_ProgressBarGroove:
  4357     case SE_ProgressBarGroove:
  4317     case SE_ProgressBarLabel:
  4358     case SE_ProgressBarLabel:
  4318         break;
  4359         break;
  5683             sz = QSize(w, h);
  5724             sz = QSize(w, h);
  5684         }
  5725         }
  5685         break;
  5726         break;
  5686     case CT_ToolButton:
  5727     case CT_ToolButton:
  5687         if (widget && qobject_cast<const QToolBar *>(widget->parentWidget())) {
  5728         if (widget && qobject_cast<const QToolBar *>(widget->parentWidget())) {
  5688             sz.rwidth() += 4;
  5729             if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(widget->parent())) {
  5689             if (sz.height() <= 32) {
  5730                 if (mainWindow->unifiedTitleAndToolBarOnMac()) {
  5690                 // Workaround strange HIToolBar bug when getting constraints.
  5731                     sz.rwidth() += 4;
  5691                 sz.rheight() += 1;
  5732                     if (sz.height() <= 32) {
  5692             }
  5733                         // Workaround strange HIToolBar bug when getting constraints.
  5693             return sz;
  5734                         sz.rheight() += 1;
       
  5735                     }
       
  5736                     return sz;
       
  5737                 }
       
  5738             }
  5694         }
  5739         }
  5695         sz.rwidth() += 10;
  5740         sz.rwidth() += 10;
  5696         sz.rheight() += 10;
  5741         sz.rheight() += 10;
  5697         return sz;
  5742         return sz;
  5698     case CT_ComboBox:
  5743     case CT_ComboBox: