-
Marco Martin authored
The qstyle can set as preferred size for itemview items a different size than the text height depending from the result of sizeFromContents( CT_ItemViewItem, .. Examples of styles that do this, are Oxygen and Breeze, in order to have a bit more spacing. This makes the combobox render incorrectly. This patch makes use of the size hint of the qstyle instead of the text height. Since the height can be more than the font height, the text (and optional icon) are now drawn vertically centered in the delegate. Change-Id: I898d85c994d5760979750c2f3a5dafd83f1e3cbd Reviewed-by:
J-P Nurmi <jpnurmi@theqtcompany.com>
04ec29f8
qquickstyleitem.cpp 70.21 KiB
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qquickstyleitem_p.h"
#include <qstringbuilder.h>
#include <qpainter.h>
#include <qpixmapcache.h>
#include <qstyle.h>
#include <qstyleoption.h>
#include <qapplication.h>
#include <qsgsimpletexturenode.h>
#include <qquickwindow.h>
#include "private/qguiapplication_p.h"
#include <QtQuick/private/qquickwindow_p.h>
#include <QtQuick/private/qquickitem_p.h>
#include <QtGui/qpa/qplatformtheme.h>
#include "../qquickmenuitem_p.h"
QT_BEGIN_NAMESPACE
#ifdef Q_OS_OSX
#include <Carbon/Carbon.h>
static inline HIRect qt_hirectForQRect(const QRect &convertRect, const QRect &rect = QRect())
{
return CGRectMake(convertRect.x() + rect.x(), convertRect.y() + rect.y(),
convertRect.width() - rect.width(), convertRect.height() - rect.height());
}
/*! \internal
Returns the CoreGraphics CGContextRef of the paint device. 0 is
returned if it can't be obtained. It is the caller's responsibility to
CGContextRelease the context when finished using it.
\warning This function is only available on Mac OS X.
\warning This function is duplicated in qmacstyle_mac.mm
*/
CGContextRef qt_mac_cg_context(const QPaintDevice *pdev)
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
{
if (pdev->devType() == QInternal::Image) {
const QImage *i = static_cast<const QImage*>(pdev);
QImage *image = const_cast< QImage*>(i);
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
uint flags = kCGImageAlphaPremultipliedFirst;
flags |= kCGBitmapByteOrder32Host;
CGContextRef ret = 0;
ret = CGBitmapContextCreate(image->bits(), image->width(), image->height(),
8, image->bytesPerLine(), colorspace, flags);
CGContextTranslateCTM(ret, 0, image->height());
CGContextScaleCTM(ret, 1, -1);
return ret;
}
return 0;
}
#endif
class QQuickStyleNode : public QSGNinePatchNode
{
public:
QQuickStyleNode()
: m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
{
m_geometry.setDrawingMode(GL_TRIANGLE_STRIP);
setGeometry(&m_geometry);
// The texture material has mipmap filtering set to Nearest by default. This is not ideal.
m_material.setMipmapFiltering(QSGTexture::None);
setMaterial(&m_material);
}
~QQuickStyleNode()
{
delete m_material.texture();
}
virtual void setTexture(QSGTexture *texture)
{
delete m_material.texture();
m_material.setTexture(texture);
}
virtual void setBounds(const QRectF &bounds)
{
m_bounds = bounds;
}
virtual void setDevicePixelRatio(qreal ratio)
{
m_devicePixelRatio = ratio;
}
virtual void setPadding(qreal left, qreal top, qreal right, qreal bottom)
{
m_paddingLeft = left;
m_paddingTop = top;
m_paddingRight = right;
m_paddingBottom = bottom;
}
virtual void update() {
QSGTexture *texture = m_material.texture();
if (m_paddingLeft <= 0 && m_paddingTop <= 0 && m_paddingRight <= 0 && m_paddingBottom <= 0) {
m_geometry.allocate(4, 0);
QSGGeometry::updateTexturedRectGeometry(&m_geometry, m_bounds, texture->normalizedTextureSubRect());
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
markDirty(QSGNode::DirtyGeometry | QSGNode::DirtyMaterial);
return;
}
QRectF tc = texture->normalizedTextureSubRect();
QSize ts = texture->textureSize();
ts.setHeight(ts.height() / m_devicePixelRatio);
ts.setWidth(ts.width() / m_devicePixelRatio);
qreal invtw = tc.width() / ts.width();
qreal invth = tc.height() / ts.height();
struct Coord { qreal p; qreal t; };
Coord cx[4] = { { m_bounds.left(), tc.left() },
{ m_bounds.left() + m_paddingLeft, tc.left() + m_paddingLeft * invtw },
{ m_bounds.right() - m_paddingRight, tc.right() - m_paddingRight * invtw },
{ m_bounds.right(), tc.right() }
};
Coord cy[4] = { { m_bounds.top(), tc.top() },
{ m_bounds.top() + m_paddingTop, tc.top() + m_paddingTop * invth },
{ m_bounds.bottom() - m_paddingBottom, tc.bottom() - m_paddingBottom * invth },
{ m_bounds.bottom(), tc.bottom() }
};
m_geometry.allocate(16, 28);
QSGGeometry::TexturedPoint2D *v = m_geometry.vertexDataAsTexturedPoint2D();
for (int y=0; y<4; ++y) {
for (int x=0; x<4; ++x) {
v->set(cx[x].p, cy[y].p, cx[x].t, cy[y].t);
++v;
}
}
quint16 *i = m_geometry.indexDataAsUShort();
for (int r=0; r<3; ++r) {
if (r > 0)
*i++ = 4 * r;
for (int c=0; c<4; ++c) {
i[0] = 4 * r + c;
i[1] = 4 * r + c + 4;
i+=2;
}
if (r < 2)
*i++ = 4 * r + 3 + 4;
}
markDirty(QSGNode::DirtyGeometry | QSGNode::DirtyMaterial);
// v = m_geometry.vertexDataAsTexturedPoint2D();
// for (int j=0; j<m_geometry.vertexCount(); ++j)
// qDebug() << v[j].x << v[j].y << v[j].tx << v[j].ty;
// i = m_geometry.indexDataAsUShort();
// for (int j=0; j<m_geometry.indexCount(); ++j)
// qDebug() << i[j];
}
QRectF m_bounds;
qreal m_devicePixelRatio;
qreal m_paddingLeft;
qreal m_paddingTop;
qreal m_paddingRight;
qreal m_paddingBottom;
QSGGeometry m_geometry;
QSGTextureMaterial m_material;
};
QQuickStyleItem::QQuickStyleItem(QQuickItem *parent)
: QQuickItem(parent),
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
m_styleoption(0),
m_itemType(Undefined),
m_sunken(false),
m_raised(false),
m_active(true),
m_selected(false),
m_focus(false),
m_hover(false),
m_on(false),
m_horizontal(true),
m_transient(false),
m_sharedWidget(false),
m_minimum(0),
m_maximum(100),
m_value(0),
m_step(0),
m_paintMargins(0),
m_contentWidth(0),
m_contentHeight(0),
m_textureWidth(0),
m_textureHeight(0)
{
m_font = qApp->font();
setFlag(QQuickItem::ItemHasContents, true);
setSmooth(false);
connect(this, SIGNAL(visibleChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(widthChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(heightChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(enabledChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(infoChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(onChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(selectedChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(activeChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(textChanged()), this, SLOT(updateSizeHint()));
connect(this, SIGNAL(textChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(activeChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(raisedChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(sunkenChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(hoverChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(maximumChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(minimumChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(valueChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(horizontalChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(transientChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(activeControlChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(hasFocusChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(activeControlChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(hintChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(propertiesChanged()), this, SLOT(updateSizeHint()));
connect(this, SIGNAL(propertiesChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(elementTypeChanged()), this, SLOT(updateItem()));
connect(this, SIGNAL(contentWidthChanged(int)), this, SLOT(updateSizeHint()));
connect(this, SIGNAL(contentHeightChanged(int)), this, SLOT(updateSizeHint()));
connect(this, SIGNAL(widthChanged()), this, SLOT(updateRect()));
connect(this, SIGNAL(heightChanged()), this, SLOT(updateRect()));
connect(this, SIGNAL(heightChanged()), this, SLOT(updateBaselineOffset()));
connect(this, SIGNAL(contentHeightChanged(int)), this, SLOT(updateBaselineOffset()));
}
QQuickStyleItem::~QQuickStyleItem()
{
delete m_styleoption;
m_styleoption = 0;
}
void QQuickStyleItem::initStyleOption()
{
QString type = elementType();
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
if (m_styleoption)
m_styleoption->state = 0;
QString sizeHint = m_hints.value("size").toString();
QPlatformTheme::Font platformFont = (sizeHint == "mini") ? QPlatformTheme::MiniFont :
(sizeHint == "small") ? QPlatformTheme::SmallFont :
QPlatformTheme::SystemFont;
bool needsResolvePalette = true;
switch (m_itemType) {
case Button: {
if (!m_styleoption)
m_styleoption = new QStyleOptionButton();
QStyleOptionButton *opt = qstyleoption_cast<QStyleOptionButton*>(m_styleoption);
opt->text = text();
opt->icon = m_properties["icon"].value<QIcon>();
int e = qApp->style()->pixelMetric(QStyle::PM_ButtonIconSize, m_styleoption, 0);
opt->iconSize = QSize(e, e);
opt->features = (activeControl() == "default") ?
QStyleOptionButton::DefaultButton :
QStyleOptionButton::None;
if (platformFont == QPlatformTheme::SystemFont)
platformFont = QPlatformTheme::PushButtonFont;
const QFont *font = QGuiApplicationPrivate::platformTheme()->font(platformFont);
if (font)
opt->fontMetrics = QFontMetrics(*font);
QObject * menu = m_properties["menu"].value<QObject *>();
if (menu) {
opt->features |= QStyleOptionButton::HasMenu;
#ifdef Q_OS_OSX
if (style() == "mac") {
if (platformFont == QPlatformTheme::PushButtonFont)
menu->setProperty("__xOffset", 12);
else
menu->setProperty("__xOffset", 11);
if (platformFont == QPlatformTheme::MiniFont)
menu->setProperty("__yOffset", 5);
else if (platformFont == QPlatformTheme::SmallFont)
menu->setProperty("__yOffset", 6);
else
menu->setProperty("__yOffset", 3);
if (font)
menu->setProperty("__font", *font);
}
#endif
}
}
break;
case ItemRow: {
if (!m_styleoption)
m_styleoption = new QStyleOptionViewItem();
QStyleOptionViewItem *opt = qstyleoption_cast<QStyleOptionViewItem*>(m_styleoption);
opt->features = 0;
if (activeControl() == "alternate")
opt->features |= QStyleOptionViewItem::Alternate;
}
break;
case Splitter: {
if (!m_styleoption) {
m_styleoption = new QStyleOption;
}
}
break;
case Item: {
if (!m_styleoption) {
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
m_styleoption = new QStyleOptionViewItem();
}
QStyleOptionViewItem *opt = qstyleoption_cast<QStyleOptionViewItem*>(m_styleoption);
opt->features = QStyleOptionViewItem::HasDisplay;
opt->text = text();
opt->textElideMode = Qt::ElideRight;
opt->displayAlignment = Qt::AlignLeft | Qt::AlignVCenter;
opt->decorationAlignment = Qt::AlignCenter;
resolvePalette();
needsResolvePalette = false;
QPalette pal = m_styleoption->palette;
pal.setBrush(QPalette::Base, Qt::NoBrush);
m_styleoption->palette = pal;
if (const QFont *font = QGuiApplicationPrivate::platformTheme()->font(QPlatformTheme::ItemViewFont)) {
opt->fontMetrics = QFontMetrics(*font);
opt->font = *font;
}
}
break;
case Header: {
if (!m_styleoption)
m_styleoption = new QStyleOptionHeader();
QStyleOptionHeader *opt = qstyleoption_cast<QStyleOptionHeader*>(m_styleoption);
opt->text = text();
opt->textAlignment = static_cast<Qt::AlignmentFlag>(m_properties.value("textalignment").toInt());
opt->sortIndicator = activeControl() == "down" ?
QStyleOptionHeader::SortDown
: activeControl() == "up" ?
QStyleOptionHeader::SortUp : QStyleOptionHeader::None;
QString headerpos = m_properties.value("headerpos").toString();
if (headerpos == "beginning")
opt->position = QStyleOptionHeader::Beginning;
else if (headerpos == "end")
opt->position = QStyleOptionHeader::End;
else if (headerpos == "only")
opt->position = QStyleOptionHeader::OnlyOneSection;
else
opt->position = QStyleOptionHeader::Middle;
if (const QFont *font = QGuiApplicationPrivate::platformTheme()->font(QPlatformTheme::HeaderViewFont))
opt->fontMetrics = QFontMetrics(*font);
}
break;
case ToolButton: {
if (!m_styleoption)
m_styleoption = new QStyleOptionToolButton();
QStyleOptionToolButton *opt =
qstyleoption_cast<QStyleOptionToolButton*>(m_styleoption);
opt->subControls = QStyle::SC_ToolButton;
opt->state |= QStyle::State_AutoRaise;
opt->activeSubControls = QStyle::SC_ToolButton;
opt->text = text();
opt->icon = m_properties["icon"].value<QIcon>();
if (m_properties.value("menu").toBool()) {
opt->subControls |= QStyle::SC_ToolButtonMenu;
opt->features = QStyleOptionToolButton::HasMenu;
}
// For now icon only is displayed by default.
opt->toolButtonStyle = Qt::ToolButtonIconOnly;
if (opt->icon.isNull() && !opt->text.isEmpty())
opt->toolButtonStyle = Qt::ToolButtonTextOnly;
int e = qApp->style()->pixelMetric(QStyle::PM_ToolBarIconSize, m_styleoption, 0);
opt->iconSize = QSize(e, e);
if (const QFont *font = QGuiApplicationPrivate::platformTheme()->font(QPlatformTheme::ToolButtonFont)) {
opt->fontMetrics = QFontMetrics(*font);
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
opt->font = *font;
}
}
break;
case ToolBar: {
if (!m_styleoption)
m_styleoption = new QStyleOptionToolBar();
}
break;
case Tab: {
if (!m_styleoption)
m_styleoption = new QStyleOptionTab();
QStyleOptionTab *opt = qstyleoption_cast<QStyleOptionTab*>(m_styleoption);
opt->text = text();
if (m_properties.value("hasFrame").toBool())
opt->features |= QStyleOptionTab::HasFrame;
QString orientation = m_properties.value("orientation").toString();
QString position = m_properties.value("tabpos").toString();
QString selectedPosition = m_properties.value("selectedpos").toString();
opt->shape = (orientation == "Bottom") ? QTabBar::RoundedSouth : QTabBar::RoundedNorth;
if (position == QLatin1String("beginning"))
opt->position = QStyleOptionTab::Beginning;
else if (position == QLatin1String("end"))
opt->position = QStyleOptionTab::End;
else if (position == QLatin1String("only"))
opt->position = QStyleOptionTab::OnlyOneTab;
else
opt->position = QStyleOptionTab::Middle;
if (selectedPosition == QLatin1String("next"))
opt->selectedPosition = QStyleOptionTab::NextIsSelected;
else if (selectedPosition == QLatin1String("previous"))
opt->selectedPosition = QStyleOptionTab::PreviousIsSelected;
else
opt->selectedPosition = QStyleOptionTab::NotAdjacent;
} break;
case Frame: {
if (!m_styleoption)
m_styleoption = new QStyleOptionFrame();
QStyleOptionFrame *opt = qstyleoption_cast<QStyleOptionFrame*>(m_styleoption);
opt->frameShape = QFrame::StyledPanel;
opt->lineWidth = 1;
opt->midLineWidth = 1;
}
break;
case FocusRect: {
if (!m_styleoption)
m_styleoption = new QStyleOptionFocusRect();
// Needed on windows
m_styleoption->state |= QStyle::State_KeyboardFocusChange;
}
break;
case TabFrame: {
if (!m_styleoption)
m_styleoption = new QStyleOptionTabWidgetFrame();
QStyleOptionTabWidgetFrame *opt = qstyleoption_cast<QStyleOptionTabWidgetFrame*>(m_styleoption);
opt->selectedTabRect = m_properties["selectedTabRect"].toRect();
opt->shape = m_properties["orientation"] == Qt::BottomEdge ? QTabBar::RoundedSouth : QTabBar::RoundedNorth;
if (minimum())
opt->selectedTabRect = QRect(value(), 0, minimum(), height());
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
opt->tabBarSize = QSize(minimum() , height());
// oxygen style needs this hack
opt->leftCornerWidgetSize = QSize(value(), 0);
}
break;
case MenuBar:
if (!m_styleoption) {
QStyleOptionMenuItem *menuOpt = new QStyleOptionMenuItem();
menuOpt->menuItemType = QStyleOptionMenuItem::EmptyArea;
m_styleoption = menuOpt;
}
break;
case MenuBarItem:
{
if (!m_styleoption)
m_styleoption = new QStyleOptionMenuItem();
QStyleOptionMenuItem *opt = qstyleoption_cast<QStyleOptionMenuItem*>(m_styleoption);
opt->text = text();
opt->menuItemType = QStyleOptionMenuItem::Normal;
setProperty("_q_showUnderlined", m_hints["showUnderlined"].toBool());
if (const QFont *font = QGuiApplicationPrivate::platformTheme()->font(QPlatformTheme::MenuBarFont)) {
opt->font = *font;
opt->fontMetrics = QFontMetrics(opt->font);
m_font = opt->font;
}
}
break;
case Menu: {
if (!m_styleoption)
m_styleoption = new QStyleOptionMenuItem();
}
break;
case MenuItem:
case ComboBoxItem:
{
if (!m_styleoption)
m_styleoption = new QStyleOptionMenuItem();
QStyleOptionMenuItem *opt = qstyleoption_cast<QStyleOptionMenuItem*>(m_styleoption);
// For GTK style. See below, in setElementType()
setProperty("_q_isComboBoxPopupItem", m_itemType == ComboBoxItem);
QQuickMenuItemType::MenuItemType type =
static_cast<QQuickMenuItemType::MenuItemType>(m_properties["type"].toInt());
if (type == QQuickMenuItemType::ScrollIndicator) {
int scrollerDirection = m_properties["scrollerDirection"].toInt();
opt->menuItemType = QStyleOptionMenuItem::Scroller;
opt->state |= scrollerDirection == Qt::UpArrow ?
QStyle::State_UpArrow : QStyle::State_DownArrow;
} else if (type == QQuickMenuItemType::Separator) {
opt->menuItemType = QStyleOptionMenuItem::Separator;
} else {
opt->text = text();
if (type == QQuickMenuItemType::Menu) {
opt->menuItemType = QStyleOptionMenuItem::SubMenu;
} else {
opt->menuItemType = QStyleOptionMenuItem::Normal;
QString shortcut = m_properties["shortcut"].toString();
if (!shortcut.isEmpty()) {
opt->text += QLatin1Char('\t') + shortcut;
opt->tabWidth = qMax(opt->tabWidth, qRound(textWidth(shortcut)));
}
if (m_properties["checkable"].toBool()) {
opt->checked = on();
561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
QVariant exclusive = m_properties["exclusive"];
opt->checkType = exclusive.toBool() ? QStyleOptionMenuItem::Exclusive :
QStyleOptionMenuItem::NonExclusive;
}
}
if (m_properties["icon"].canConvert<QIcon>())
opt->icon = m_properties["icon"].value<QIcon>();
setProperty("_q_showUnderlined", m_hints["showUnderlined"].toBool());
if (const QFont *font = QGuiApplicationPrivate::platformTheme()->font(m_itemType == ComboBoxItem ? QPlatformTheme::ComboMenuItemFont : QPlatformTheme::MenuFont)) {
opt->font = *font;
opt->fontMetrics = QFontMetrics(opt->font);
m_font = opt->font;
}
}
}
break;
case CheckBox:
case RadioButton:
{
if (!m_styleoption)
m_styleoption = new QStyleOptionButton();
QStyleOptionButton *opt = qstyleoption_cast<QStyleOptionButton*>(m_styleoption);
if (!on())
opt->state |= QStyle::State_Off;
if (m_properties.value("partiallyChecked").toBool())
opt->state |= QStyle::State_NoChange;
opt->text = text();
}
break;
case Edit: {
if (!m_styleoption)
m_styleoption = new QStyleOptionFrame();
QStyleOptionFrame *opt = qstyleoption_cast<QStyleOptionFrame*>(m_styleoption);
opt->lineWidth = 1; // this must be non-zero
}
break;
case ComboBox :{
if (!m_styleoption)
m_styleoption = new QStyleOptionComboBox();
QStyleOptionComboBox *opt = qstyleoption_cast<QStyleOptionComboBox*>(m_styleoption);
if (platformFont == QPlatformTheme::SystemFont)
platformFont = QPlatformTheme::PushButtonFont;
const QFont *font = QGuiApplicationPrivate::platformTheme()->font(platformFont);
if (font)
opt->fontMetrics = QFontMetrics(*font);
opt->currentText = text();
opt->editable = m_properties["editable"].toBool();
#ifdef Q_OS_OSX
if (m_properties["popup"].canConvert<QObject *>() && style() == "mac") {
QObject *popup = m_properties["popup"].value<QObject *>();
if (platformFont == QPlatformTheme::MiniFont) {
popup->setProperty("__xOffset", -2);
popup->setProperty("__yOffset", 5);
} else {
if (platformFont == QPlatformTheme::SmallFont)
popup->setProperty("__xOffset", -1);
popup->setProperty("__yOffset", 6);
}
if (font)
popup->setProperty("__font", *font);
}
#endif
}
break;
case SpinBox: {
631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
if (!m_styleoption)
m_styleoption = new QStyleOptionSpinBox();
QStyleOptionSpinBox *opt = qstyleoption_cast<QStyleOptionSpinBox*>(m_styleoption);
opt->frame = true;
opt->subControls = QStyle::SC_SpinBoxFrame | QStyle::SC_SpinBoxEditField;
if (value() & 0x1)
opt->activeSubControls = QStyle::SC_SpinBoxUp;
else if (value() & (1<<1))
opt->activeSubControls = QStyle::SC_SpinBoxDown;
opt->subControls = QStyle::SC_All;
opt->stepEnabled = 0;
if (value() & (1<<2))
opt->stepEnabled |= QAbstractSpinBox::StepUpEnabled;
if (value() & (1<<3))
opt->stepEnabled |= QAbstractSpinBox::StepDownEnabled;
}
break;
case Slider:
case Dial:
{
if (!m_styleoption)
m_styleoption = new QStyleOptionSlider();
QStyleOptionSlider *opt = qstyleoption_cast<QStyleOptionSlider*>(m_styleoption);
opt->orientation = horizontal() ? Qt::Horizontal : Qt::Vertical;
opt->upsideDown = !horizontal();
opt->minimum = minimum();
opt->maximum = maximum();
opt->sliderPosition = value();
opt->singleStep = step();
if (opt->singleStep) {
qreal numOfSteps = (opt->maximum - opt->minimum) / opt->singleStep;
// at least 5 pixels between tick marks
if (numOfSteps && (width() / numOfSteps < 5))
opt->tickInterval = qRound((5 * numOfSteps / width()) + 0.5) * step();
else
opt->tickInterval = opt->singleStep;
} else // default Qt-components implementation
opt->tickInterval = opt->maximum != opt->minimum ? 1200 / (opt->maximum - opt->minimum) : 0;
opt->sliderValue = value();
opt->subControls = QStyle::SC_SliderGroove | QStyle::SC_SliderHandle;
opt->tickPosition = (activeControl() == "ticks" ?
QSlider::TicksBelow : QSlider::NoTicks);
if (opt->tickPosition != QSlider::NoTicks)
opt->subControls |= QStyle::SC_SliderTickmarks;
opt->activeSubControls = QStyle::SC_SliderHandle;
}
break;
case ProgressBar: {
if (!m_styleoption)
m_styleoption = new QStyleOptionProgressBar();
QStyleOptionProgressBar *opt = qstyleoption_cast<QStyleOptionProgressBar*>(m_styleoption);
opt->orientation = horizontal() ? Qt::Horizontal : Qt::Vertical;
opt->minimum = minimum();
opt->maximum = maximum();
opt->progress = value();
}
break;
case GroupBox: {
if (!m_styleoption)
m_styleoption = new QStyleOptionGroupBox();
QStyleOptionGroupBox *opt = qstyleoption_cast<QStyleOptionGroupBox*>(m_styleoption);
opt->text = text();
701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
opt->lineWidth = 1;
opt->subControls = QStyle::SC_GroupBoxLabel;
opt->features = 0;
if (m_properties["sunken"].toBool()) { // Qt draws an ugly line here so I ignore it
opt->subControls |= QStyle::SC_GroupBoxFrame;
} else {
opt->features |= QStyleOptionFrame::Flat;
}
if (m_properties["checkable"].toBool())
opt->subControls |= QStyle::SC_GroupBoxCheckBox;
}
break;
case ScrollBar: {
if (!m_styleoption)
m_styleoption = new QStyleOptionSlider();
QStyleOptionSlider *opt = qstyleoption_cast<QStyleOptionSlider*>(m_styleoption);
opt->minimum = minimum();
opt->maximum = maximum();
opt->pageStep = qMax(0, int(horizontal() ? width() : height()));
opt->orientation = horizontal() ? Qt::Horizontal : Qt::Vertical;
opt->sliderPosition = value();
opt->sliderValue = value();
opt->activeSubControls = (activeControl() == QLatin1String("up"))
? QStyle::SC_ScrollBarSubLine : (activeControl() == QLatin1String("down")) ?
QStyle::SC_ScrollBarAddLine :
(activeControl() == QLatin1String("handle")) ?
QStyle::SC_ScrollBarSlider : hover() ? QStyle::SC_ScrollBarGroove : QStyle::SC_None;
if (raised())
opt->state |= QStyle::State_On;
opt->sliderValue = value();
opt->subControls = QStyle::SC_All;
setTransient(qApp->style()->styleHint(QStyle::SH_ScrollBar_Transient, m_styleoption));
break;
}
default:
break;
}
if (!m_styleoption)
m_styleoption = new QStyleOption();
if (needsResolvePalette)
resolvePalette();
m_styleoption->styleObject = this;
m_styleoption->direction = qApp->layoutDirection();
int w = m_textureWidth > 0 ? m_textureWidth : width();
int h = m_textureHeight > 0 ? m_textureHeight : height();
m_styleoption->rect = QRect(m_paintMargins, 0, w - 2* m_paintMargins, h);
if (isEnabled()) {
m_styleoption->state |= QStyle::State_Enabled;
m_styleoption->palette.setCurrentColorGroup(QPalette::Active);
} else {
m_styleoption->palette.setCurrentColorGroup(QPalette::Disabled);
}
if (m_active)
m_styleoption->state |= QStyle::State_Active;
else
m_styleoption->palette.setCurrentColorGroup(QPalette::Inactive);
if (m_sunken)
m_styleoption->state |= QStyle::State_Sunken;
if (m_raised)
m_styleoption->state |= QStyle::State_Raised;
771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
if (m_selected)
m_styleoption->state |= QStyle::State_Selected;
if (m_focus)
m_styleoption->state |= QStyle::State_HasFocus;
if (m_on)
m_styleoption->state |= QStyle::State_On;
if (m_hover)
m_styleoption->state |= QStyle::State_MouseOver;
if (m_horizontal)
m_styleoption->state |= QStyle::State_Horizontal;
// some styles don't draw a focus rectangle if
// QStyle::State_KeyboardFocusChange is not set
if (window()) {
Qt::FocusReason lastFocusReason = QQuickWindowPrivate::get(window())->lastFocusReason;
if (lastFocusReason == Qt::TabFocusReason || lastFocusReason == Qt::BacktabFocusReason) {
m_styleoption->state |= QStyle::State_KeyboardFocusChange;
}
}
if (sizeHint == "mini") {
m_styleoption->state |= QStyle::State_Mini;
} else if (sizeHint == "small") {
m_styleoption->state |= QStyle::State_Small;
}
}
void QQuickStyleItem::resolvePalette()
{
QPlatformTheme::Palette paletteType = QPlatformTheme::SystemPalette;
switch (m_itemType) {
case Button:
paletteType = QPlatformTheme::ButtonPalette;
break;
case RadioButton:
paletteType = QPlatformTheme::RadioButtonPalette;
break;
case CheckBox:
paletteType = QPlatformTheme::CheckBoxPalette;
break;
case ComboBox:
case ComboBoxItem:
paletteType = QPlatformTheme::ComboBoxPalette;
break;
case ToolBar:
case ToolButton:
paletteType = QPlatformTheme::ToolButtonPalette;
break;
case Tab:
case TabFrame:
paletteType = QPlatformTheme::TabBarPalette;
break;
case Edit:
paletteType = QPlatformTheme::TextEditPalette;
break;
case GroupBox:
paletteType = QPlatformTheme::GroupBoxPalette;
break;
case Header:
paletteType = QPlatformTheme::HeaderPalette;
break;
case Item:
case ItemRow:
paletteType = QPlatformTheme::ItemViewPalette;
break;
case Menu:
case MenuItem:
paletteType = QPlatformTheme::MenuPalette;
break;
841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
case MenuBar:
case MenuBarItem:
paletteType = QPlatformTheme::MenuBarPalette;
break;
default:
break;
}
const QPalette *platformPalette = QGuiApplicationPrivate::platformTheme()->palette(paletteType);
if (platformPalette)
m_styleoption->palette = *platformPalette;
// Defaults to SystemPalette otherwise
}
/*
* Property style
*
* Returns a simplified style name.
*
* QMacStyle = "mac"
* QWindowsXPStyle = "windowsxp"
* QFusionStyle = "fusion"
*/
QString QQuickStyleItem::style() const
{
QString style = qApp->style()->metaObject()->className();
style = style.toLower();
if (style.startsWith(QLatin1Char('q')))
style = style.right(style.length() - 1);
if (style.endsWith("style"))
style = style.left(style.length() - 5);
return style;
}
QString QQuickStyleItem::hitTest(int px, int py)
{
QStyle::SubControl subcontrol = QStyle::SC_All;
switch (m_itemType) {
case SpinBox :{
subcontrol = qApp->style()->hitTestComplexControl(QStyle::CC_SpinBox,
qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
QPoint(px,py), 0);
if (subcontrol == QStyle::SC_SpinBoxUp)
return "up";
else if (subcontrol == QStyle::SC_SpinBoxDown)
return "down";
}
break;
case Slider: {
subcontrol = qApp->style()->hitTestComplexControl(QStyle::CC_Slider,
qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
QPoint(px,py), 0);
if (subcontrol == QStyle::SC_SliderHandle)
return "handle";
}
break;
case ScrollBar: {
subcontrol = qApp->style()->hitTestComplexControl(QStyle::CC_ScrollBar,
qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
QPoint(px,py), 0);
if (subcontrol == QStyle::SC_ScrollBarSlider)
return "handle";
if (subcontrol == QStyle::SC_ScrollBarSubLine)
return "up";
else if (subcontrol == QStyle::SC_ScrollBarSubPage)
911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
return "upPage";
if (subcontrol == QStyle::SC_ScrollBarAddLine)
return "down";
else if (subcontrol == QStyle::SC_ScrollBarAddPage)
return "downPage";
}
break;
default:
break;
}
return "none";
}
QSize QQuickStyleItem::sizeFromContents(int width, int height)
{
initStyleOption();
QSize size;
switch (m_itemType) {
case RadioButton:
size = qApp->style()->sizeFromContents(QStyle::CT_RadioButton, m_styleoption, QSize(width,height));
break;
case CheckBox:
size = qApp->style()->sizeFromContents(QStyle::CT_CheckBox, m_styleoption, QSize(width,height));
break;
case ToolBar:
size = QSize(200, style().contains("windows") ? 30 : 42);
break;
case ToolButton: {
QStyleOptionToolButton *btn = qstyleoption_cast<QStyleOptionToolButton*>(m_styleoption);
int w = 0;
int h = 0;
if (btn->toolButtonStyle != Qt::ToolButtonTextOnly) {
QSize icon = btn->iconSize;
w = icon.width();
h = icon.height();
}
if (btn->toolButtonStyle != Qt::ToolButtonIconOnly) {
QSize textSize = btn->fontMetrics.size(Qt::TextShowMnemonic, btn->text);
textSize.setWidth(textSize.width() + btn->fontMetrics.width(QLatin1Char(' '))*2);
if (btn->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
h += 4 + textSize.height();
if (textSize.width() > w)
w = textSize.width();
} else if (btn->toolButtonStyle == Qt::ToolButtonTextBesideIcon) {
w += 4 + textSize.width();
if (textSize.height() > h)
h = textSize.height();
} else { // TextOnly
w = textSize.width();
h = textSize.height();
}
}
btn->rect.setSize(QSize(w, h));
size = qApp->style()->sizeFromContents(QStyle::CT_ToolButton, m_styleoption, QSize(w, h)); }
break;
case Button: {
QStyleOptionButton *btn = qstyleoption_cast<QStyleOptionButton*>(m_styleoption);
int contentWidth = btn->fontMetrics.width(btn->text);
int contentHeight = btn->fontMetrics.height();
if (!btn->icon.isNull()) {
//+4 matches a hardcoded value in QStyle and acts as a margin between the icon and the text.
contentWidth += btn->iconSize.width() + 4;
contentHeight = qMax(btn->fontMetrics.height(), btn->iconSize.height());
}
int newWidth = qMax(width, contentWidth);
int newHeight = qMax(height, contentHeight);
size = qApp->style()->sizeFromContents(QStyle::CT_PushButton, m_styleoption, QSize(newWidth, newHeight)); }
981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
#ifdef Q_OS_OSX
if (style() == "mac") {
// Cancel out QMacStylePrivate::PushButton*Offset, or part of it
size -= QSize(7, 6);
}
#endif
break;
case ComboBox: {
QStyleOptionComboBox *btn = qstyleoption_cast<QStyleOptionComboBox*>(m_styleoption);
int newWidth = qMax(width, btn->fontMetrics.width(btn->currentText));
int newHeight = qMax(height, btn->fontMetrics.height());
size = qApp->style()->sizeFromContents(QStyle::CT_ComboBox, m_styleoption, QSize(newWidth, newHeight)); }
break;
case Tab:
size = qApp->style()->sizeFromContents(QStyle::CT_TabBarTab, m_styleoption, QSize(width,height));
break;
case Slider:
size = qApp->style()->sizeFromContents(QStyle::CT_Slider, m_styleoption, QSize(width,height));
break;
case ProgressBar:
size = qApp->style()->sizeFromContents(QStyle::CT_ProgressBar, m_styleoption, QSize(width,height));
break;
case SpinBox:
#ifdef Q_OS_OSX
if (style() == "mac") {
size = qApp->style()->sizeFromContents(QStyle::CT_SpinBox, m_styleoption, QSize(width, height + 5));
break;
}
#endif // fall through if not mac
case Edit:
#ifdef Q_OS_OSX
if (style() =="mac") {
QString sizeHint = m_hints.value("size").toString();
if ((sizeHint == "small") || (sizeHint == "mini"))
size = QSize(width, 19);
else
size = QSize(width, 22);
if (style() == "mac" && hints().value("rounded").toBool())
size += QSize(4, 4);
} else
#endif
{
// We have to create a new style option since we might be calling with a QStyleOptionSpinBox
QStyleOptionFrame frame;
frame.state = m_styleoption->state;
frame.lineWidth = qApp->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, m_styleoption, 0);
frame.rect = m_styleoption->rect;
frame.styleObject = this;
size = qApp->style()->sizeFromContents(QStyle::CT_LineEdit, &frame, QSize(width, height));
if (m_itemType == SpinBox)
size.setWidth(qApp->style()->sizeFromContents(QStyle::CT_SpinBox,
m_styleoption, QSize(width + 2, height)).width());
}
break;
case GroupBox: {
QStyleOptionGroupBox *box = qstyleoption_cast<QStyleOptionGroupBox*>(m_styleoption);
QFontMetrics metrics(box->fontMetrics);
int baseWidth = metrics.width(box->text) + metrics.width(QLatin1Char(' '));
int baseHeight = metrics.height() + m_contentHeight;
if (box->subControls & QStyle::SC_GroupBoxCheckBox) {
baseWidth += qApp->style()->pixelMetric(QStyle::PM_IndicatorWidth);
baseWidth += qApp->style()->pixelMetric(QStyle::PM_CheckBoxLabelSpacing);
baseHeight = qMax(baseHeight, qApp->style()->pixelMetric(QStyle::PM_IndicatorHeight));
}
size = qApp->style()->sizeFromContents(QStyle::CT_GroupBox, m_styleoption, QSize(qMax(baseWidth, m_contentWidth), baseHeight));
}
break;
case Header:
size = qApp->style()->sizeFromContents(QStyle::CT_HeaderSection, m_styleoption, QSize(width,height));
1051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
#ifdef Q_OS_OSX
if (style() =="mac")
size.setHeight(15);
#endif
break;
case ItemRow:
case Item: //fall through
size = qApp->style()->sizeFromContents(QStyle::CT_ItemViewItem, m_styleoption, QSize(width,height));
break;
case MenuBarItem:
size = qApp->style()->sizeFromContents(QStyle::CT_MenuBarItem, m_styleoption, QSize(width,height));
break;
case MenuBar:
size = qApp->style()->sizeFromContents(QStyle::CT_MenuBar, m_styleoption, QSize(width,height));
break;
case Menu:
size = qApp->style()->sizeFromContents(QStyle::CT_Menu, m_styleoption, QSize(width,height));
break;
case MenuItem:
case ComboBoxItem:
if (static_cast<QStyleOptionMenuItem *>(m_styleoption)->menuItemType == QStyleOptionMenuItem::Scroller) {
size.setHeight(qMax(QApplication::globalStrut().height(),
qApp->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, 0)));
} else {
size = qApp->style()->sizeFromContents(QStyle::CT_MenuItem, m_styleoption, QSize(width,height));
}
break;
default:
break;
} return size;
}
qreal QQuickStyleItem::baselineOffset()
{
QRect r;
bool ceilResult = true; // By default baseline offset rounding is done upwards
switch (m_itemType) {
case RadioButton:
r = qApp->style()->subElementRect(QStyle::SE_RadioButtonContents, m_styleoption);
break;
case Button:
r = qApp->style()->subElementRect(QStyle::SE_PushButtonContents, m_styleoption);
break;
case CheckBox:
r = qApp->style()->subElementRect(QStyle::SE_CheckBoxContents, m_styleoption);
break;
case Edit:
r = qApp->style()->subElementRect(QStyle::SE_LineEditContents, m_styleoption);
break;
case ComboBox:
if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(m_styleoption)) {
r = qApp->style()->subControlRect(QStyle::CC_ComboBox, combo, QStyle::SC_ComboBoxEditField);
if (style() != QStringLiteral("mac"))
r.adjust(0,0,0,1);
}
break;
case SpinBox:
if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(m_styleoption)) {
r = qApp->style()->subControlRect(QStyle::CC_SpinBox, spinbox, QStyle::SC_SpinBoxEditField);
ceilResult = false;
}
break;
default:
break;
}
if (r.height() > 0) {
const QFontMetrics &fm = m_styleoption->fontMetrics;
int surplus = r.height() - fm.height();
if ((surplus & 1) && ceilResult)
surplus++;
1121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190
int result = r.top() + surplus/2 + fm.ascent();
#ifdef Q_OS_OSX
if (style() == QStringLiteral("mac")) {
switch (m_itemType) {
case Button:
case Edit:
result -= 1;
break;
case ComboBox:
// adjust back the adjustments done in drawControl(CE_ComboBoxLabel)
result += 1;
break;
default:
break;
}
}
#endif
return result;
}
return 0.;
}
void QQuickStyleItem::updateBaselineOffset()
{
const qreal baseline = baselineOffset();
if (baseline > 0)
setBaselineOffset(baseline);
}
void QQuickStyleItem::setContentWidth(int arg)
{
if (m_contentWidth != arg) {
m_contentWidth = arg;
emit contentWidthChanged(arg);
}
}
void QQuickStyleItem::setContentHeight(int arg)
{
if (m_contentHeight != arg) {
m_contentHeight = arg;
emit contentHeightChanged(arg);
}
}
void QQuickStyleItem::updateSizeHint()
{
QSize implicitSize = sizeFromContents(m_contentWidth, m_contentHeight);
setImplicitSize(implicitSize.width(), implicitSize.height());
}
void QQuickStyleItem::updateRect()
{
initStyleOption();
m_styleoption->rect.setWidth(width());
m_styleoption->rect.setHeight(height());
}
int QQuickStyleItem::pixelMetric(const QString &metric)
{
if (metric == "scrollbarExtent")
return qApp->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0 );
else if (metric == "defaultframewidth")
return qApp->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, m_styleoption);
else if (metric == "taboverlap")
return qApp->style()->pixelMetric(QStyle::PM_TabBarTabOverlap, 0 );
else if (metric == "tabbaseoverlap")
return qApp->style()->pixelMetric(QStyle::PM_TabBarBaseOverlap, m_styleoption );
1191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
else if (metric == "tabhspace")
return qApp->style()->pixelMetric(QStyle::PM_TabBarTabHSpace, 0 );
else if (metric == "indicatorwidth")
return qApp->style()->pixelMetric(QStyle::PM_ExclusiveIndicatorWidth, 0 );
else if (metric == "tabvspace")
return qApp->style()->pixelMetric(QStyle::PM_TabBarTabVSpace, 0 );
else if (metric == "tabbaseheight")
return qApp->style()->pixelMetric(QStyle::PM_TabBarBaseHeight, 0 );
else if (metric == "tabvshift")
return qApp->style()->pixelMetric(QStyle::PM_TabBarTabShiftVertical, 0 );
else if (metric == "menubarhmargin")
return qApp->style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0 );
else if (metric == "menubarvmargin")
return qApp->style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0 );
else if (metric == "menubarpanelwidth")
return qApp->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0 );
else if (metric == "menubaritemspacing")
return qApp->style()->pixelMetric(QStyle::PM_MenuBarItemSpacing, 0 );
else if (metric == "spacebelowmenubar")
return qApp->style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, m_styleoption);
else if (metric == "menuhmargin")
return qApp->style()->pixelMetric(QStyle::PM_MenuHMargin, 0 );
else if (metric == "menuvmargin")
return qApp->style()->pixelMetric(QStyle::PM_MenuVMargin, 0 );
else if (metric == "menupanelwidth")
return qApp->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0 );
else if (metric == "submenuoverlap")
return qApp->style()->pixelMetric(QStyle::PM_SubMenuOverlap, 0 );
else if (metric == "splitterwidth")
return qApp->style()->pixelMetric(QStyle::PM_SplitterWidth, 0 );
else if (metric == "scrollbarspacing")
return abs(qApp->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, 0 ));
return 0;
}
QVariant QQuickStyleItem::styleHint(const QString &metric)
{
initStyleOption();
if (metric == "comboboxpopup") {
return qApp->style()->styleHint(QStyle::SH_ComboBox_Popup, m_styleoption);
} else if (metric == "highlightedTextColor") {
return m_styleoption->palette.highlightedText().color().name();
} else if (metric == "textColor") {
QPalette pal = m_styleoption->palette;
pal.setCurrentColorGroup(active()? QPalette::Active : QPalette::Inactive);
return pal.text().color().name();
} else if (metric == "focuswidget") {
return qApp->style()->styleHint(QStyle::SH_FocusFrame_AboveWidget);
} else if (metric == "tabbaralignment") {
int result = qApp->style()->styleHint(QStyle::SH_TabBar_Alignment);
if (result == Qt::AlignCenter)
return "center";
return "left";
} else if (metric == "externalScrollBars") {
return qApp->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents);
} else if (metric == "scrollToClickPosition")
return qApp->style()->styleHint(QStyle::SH_ScrollBar_LeftClickAbsolutePosition);
else if (metric == "activateItemOnSingleClick")
return qApp->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick);
else if (metric == "submenupopupdelay")
return qApp->style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, m_styleoption);
return 0;
// Add SH_Menu_SpaceActivatesItem
}
void QQuickStyleItem::setHints(const QVariantMap &str)
{
if (m_hints != str) {
m_hints = str;
1261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
initStyleOption();
updateSizeHint();
if (m_styleoption->state & QStyle::State_Mini) {
m_font.setPointSize(9.);
emit fontChanged();
} else if (m_styleoption->state & QStyle::State_Small) {
m_font.setPointSize(11.);
emit fontChanged();
} else {
emit hintChanged();
}
}
}
void QQuickStyleItem::resetHints()
{
m_hints.clear();
}
void QQuickStyleItem::setElementType(const QString &str)
{
if (m_type == str)
return;
m_type = str;
emit elementTypeChanged();
if (m_styleoption) {
delete m_styleoption;
m_styleoption = 0;
}
// Only enable visible if the widget can animate
if (str == "menu") {
m_itemType = Menu;
} else if (str == "menuitem") {
m_itemType = MenuItem;
} else if (str == "item" || str == "itemrow" || str == "header") {
#ifdef Q_OS_OSX
m_font.setPointSize(11.0);
emit fontChanged();
#endif
if (str == "header") {
m_itemType = Header;
} else {
m_itemType = (str == "item") ? Item : ItemRow;
}
} else if (str == "groupbox") {
m_itemType = GroupBox;
} else if (str == "tab") {
m_itemType = Tab;
} else if (str == "tabframe") {
m_itemType = TabFrame;
} else if (str == "comboboxitem") {
// Gtk uses qobject cast, hence we need to separate this from menuitem
// On mac, we temporarily use the menu item because it has more accurate
// palette.
m_itemType = ComboBoxItem;
} else if (str == "toolbar") {
m_itemType = ToolBar;
} else if (str == "toolbutton") {
m_itemType = ToolButton;
} else if (str == "slider") {
m_itemType = Slider;
} else if (str == "frame") {
m_itemType = Frame;
} else if (str == "combobox") {
m_itemType = ComboBox;
} else if (str == "splitter") {
1331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400
m_itemType = Splitter;
} else if (str == "progressbar") {
m_itemType = ProgressBar;
} else if (str == "button") {
m_itemType = Button;
} else if (str == "checkbox") {
m_itemType = CheckBox;
} else if (str == "radiobutton") {
m_itemType = RadioButton;
} else if (str == "edit") {
m_itemType = Edit;
} else if (str == "spinbox") {
m_itemType = SpinBox;
} else if (str == "scrollbar") {
m_itemType = ScrollBar;
} else if (str == "widget") {
m_itemType = Widget;
} else if (str == "focusframe") {
m_itemType = FocusFrame;
} else if (str == "focusrect") {
m_itemType = FocusRect;
} else if (str == "dial") {
m_itemType = Dial;
} else if (str == "statusbar") {
m_itemType = StatusBar;
} else if (str == "machelpbutton") {
m_itemType = MacHelpButton;
} else if (str == "scrollareacorner") {
m_itemType = ScrollAreaCorner;
} else if (str == "menubar") {
m_itemType = MenuBar;
} else if (str == "menubaritem") {
m_itemType = MenuBarItem;
} else {
m_itemType = Undefined;
}
updateSizeHint();
}
QRectF QQuickStyleItem::subControlRect(const QString &subcontrolString)
{
QStyle::SubControl subcontrol = QStyle::SC_None;
initStyleOption();
switch (m_itemType) {
case SpinBox:
{
QStyle::ComplexControl control = QStyle::CC_SpinBox;
if (subcontrolString == QLatin1String("down"))
subcontrol = QStyle::SC_SpinBoxDown;
else if (subcontrolString == QLatin1String("up"))
subcontrol = QStyle::SC_SpinBoxUp;
else if (subcontrolString == QLatin1String("edit")){
subcontrol = QStyle::SC_SpinBoxEditField;
}
return qApp->style()->subControlRect(control,
qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
subcontrol);
}
break;
case Slider:
{
QStyle::ComplexControl control = QStyle::CC_Slider;
if (subcontrolString == QLatin1String("handle"))
subcontrol = QStyle::SC_SliderHandle;
else if (subcontrolString == QLatin1String("groove"))
subcontrol = QStyle::SC_SliderGroove;
return qApp->style()->subControlRect(control,
qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
subcontrol);
1401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470
}
break;
case ScrollBar:
{
QStyle::ComplexControl control = QStyle::CC_ScrollBar;
if (subcontrolString == QLatin1String("slider"))
subcontrol = QStyle::SC_ScrollBarSlider;
if (subcontrolString == QLatin1String("groove"))
subcontrol = QStyle::SC_ScrollBarGroove;
else if (subcontrolString == QLatin1String("handle"))
subcontrol = QStyle::SC_ScrollBarSlider;
else if (subcontrolString == QLatin1String("add"))
subcontrol = QStyle::SC_ScrollBarAddPage;
else if (subcontrolString == QLatin1String("sub"))
subcontrol = QStyle::SC_ScrollBarSubPage;
return qApp->style()->subControlRect(control,
qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
subcontrol);
}
break;
default:
break;
}
return QRectF();
}
namespace {
class QHighDpiPixmapsEnabler {
public:
QHighDpiPixmapsEnabler()
:wasEnabled(false)
{
if (!qApp->testAttribute(Qt::AA_UseHighDpiPixmaps)) {
qApp->setAttribute(Qt::AA_UseHighDpiPixmaps);
wasEnabled = true;
}
}
~QHighDpiPixmapsEnabler()
{
if (wasEnabled)
qApp->setAttribute(Qt::AA_UseHighDpiPixmaps, false);
}
private:
bool wasEnabled;
};
}
void QQuickStyleItem::paint(QPainter *painter)
{
initStyleOption();
if (QStyleOptionMenuItem *opt = qstyleoption_cast<QStyleOptionMenuItem*>(m_styleoption))
painter->setFont(opt->font);
else {
QPlatformTheme::Font platformFont = (m_styleoption->state & QStyle::State_Mini) ? QPlatformTheme::MiniFont :
(m_styleoption->state & QStyle::State_Small) ? QPlatformTheme::SmallFont :
QPlatformTheme::NFonts;
if (platformFont != QPlatformTheme::NFonts)
if (const QFont *font = QGuiApplicationPrivate::platformTheme()->font(platformFont))
painter->setFont(*font);
}
// Set AA_UseHighDpiPixmaps when calling style code to make QIcon return
// "retina" pixmaps. The flag is controlled by the application so we can't
// set it unconditinally.
QHighDpiPixmapsEnabler enabler;
switch (m_itemType) {
case Button:
1471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540
#ifdef Q_OS_OSX
if (style() == "mac") {
// Add back what was substracted in sizeFromContents()
m_styleoption->rect.adjust(-4, -2, 3, 4);
}
#endif
qApp->style()->drawControl(QStyle::CE_PushButton, m_styleoption, painter);
break;
case ItemRow :{
QPixmap pixmap;
// Only draw through style once
const QString pmKey = QLatin1Literal("itemrow") % QString::number(m_styleoption->state,16) % activeControl();
if (!QPixmapCache::find(pmKey, pixmap) || pixmap.width() < width() || height() != pixmap.height()) {
int newSize = width();
pixmap = QPixmap(newSize, height());
pixmap.fill(Qt::transparent);
QPainter pixpainter(&pixmap);
qApp->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, m_styleoption, &pixpainter);
if ((style() == "mac" || !qApp->style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected)) && selected()) {
QPalette pal = QApplication::palette("QAbstractItemView");
pal.setCurrentColorGroup(m_styleoption->palette.currentColorGroup());
pixpainter.fillRect(m_styleoption->rect, pal.highlight());
}
QPixmapCache::insert(pmKey, pixmap);
}
painter->drawPixmap(0, 0, pixmap);
}
break;
case Item:
qApp->style()->drawControl(QStyle::CE_ItemViewItem, m_styleoption, painter);
break;
case Header:
qApp->style()->drawControl(QStyle::CE_Header, m_styleoption, painter);
break;
case ToolButton:
#ifdef Q_OS_OSX
if (style() == "mac" && hints().value("segmented").toBool()) {
const QPaintDevice *target = painter->device();
HIThemeSegmentDrawInfo sgi;
sgi.version = 0;
sgi.state = isEnabled() ? kThemeStateActive : kThemeStateDisabled;
if (sunken()) sgi.state |= kThemeStatePressed;
sgi.size = kHIThemeSegmentSizeNormal;
sgi.kind = kHIThemeSegmentKindTextured;
sgi.value = on() && !sunken() ? kThemeButtonOn : kThemeButtonOff;
sgi.adornment |= kHIThemeSegmentAdornmentLeadingSeparator;
if (sunken()) {
sgi.adornment |= kHIThemeSegmentAdornmentTrailingSeparator;
}
SInt32 button_height;
GetThemeMetric(kThemeMetricButtonRoundedHeight, &button_height);
QString buttonPos = m_properties.value("position").toString();
sgi.position = buttonPos == "leftmost" ? kHIThemeSegmentPositionFirst :
buttonPos == "rightmost" ? kHIThemeSegmentPositionLast :
buttonPos == "h_middle" ? kHIThemeSegmentPositionMiddle :
kHIThemeSegmentPositionOnly;
QRect centered = m_styleoption->rect;
centered.setHeight(button_height);
centered.moveCenter(m_styleoption->rect.center());
HIRect hirect = qt_hirectForQRect(centered.translated(0, -1), QRect(0, 0, 0, 0));
HIThemeDrawSegment(&hirect, &sgi, qt_mac_cg_context(target), kHIThemeOrientationNormal);
} else
#endif
qApp->style()->drawComplexControl(QStyle::CC_ToolButton, qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), painter);
break;
case Tab:
#ifdef Q_OS_OSX
if (style() == "mac") {
1541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610
m_styleoption->rect.translate(0, 1); // Unhack QMacStyle's hack
qApp->style()->drawControl(QStyle::CE_TabBarTabShape, m_styleoption, painter);
m_styleoption->rect.translate(0, -1);
qApp->style()->drawControl(QStyle::CE_TabBarTabLabel, m_styleoption, painter);
} else
#endif
{
qApp->style()->drawControl(QStyle::CE_TabBarTab, m_styleoption, painter);
}
break;
case Frame:
qApp->style()->drawControl(QStyle::CE_ShapedFrame, m_styleoption, painter);
break;
case FocusFrame:
qApp->style()->drawControl(QStyle::CE_FocusFrame, m_styleoption, painter);
break;
case FocusRect:
qApp->style()->drawPrimitive(QStyle::PE_FrameFocusRect, m_styleoption, painter);
break;
case TabFrame:
qApp->style()->drawPrimitive(QStyle::PE_FrameTabWidget, m_styleoption, painter);
break;
case MenuBar:
qApp->style()->drawControl(QStyle::CE_MenuBarEmptyArea, m_styleoption, painter);
break;
case MenuBarItem:
qApp->style()->drawControl(QStyle::CE_MenuBarItem, m_styleoption, painter);
break;
case MenuItem:
case ComboBoxItem: { // fall through
QStyle::ControlElement menuElement =
static_cast<QStyleOptionMenuItem *>(m_styleoption)->menuItemType == QStyleOptionMenuItem::Scroller ?
QStyle::CE_MenuScroller : QStyle::CE_MenuItem;
qApp->style()->drawControl(menuElement, m_styleoption, painter);
}
break;
case CheckBox:
qApp->style()->drawControl(QStyle::CE_CheckBox, m_styleoption, painter);
break;
case RadioButton:
qApp->style()->drawControl(QStyle::CE_RadioButton, m_styleoption, painter);
break;
case Edit: {
#ifdef Q_OS_OSX
if (style() == "mac" && hints().value("rounded").toBool()) {
const QPaintDevice *target = painter->device();
HIThemeFrameDrawInfo fdi;
fdi.version = 0;
fdi.state = kThemeStateActive;
SInt32 frame_size;
GetThemeMetric(kThemeMetricEditTextFrameOutset, &frame_size);
fdi.kind = kHIThemeFrameTextFieldRound;
if ((m_styleoption->state & QStyle::State_ReadOnly) || !(m_styleoption->state & QStyle::State_Enabled))
fdi.state = kThemeStateInactive;
fdi.isFocused = hasFocus();
HIRect hirect = qt_hirectForQRect(m_styleoption->rect.adjusted(2, 2, -2, 2), QRect(0, 0, 0, 0));
HIThemeDrawFrame(&hirect, &fdi, qt_mac_cg_context(target), kHIThemeOrientationNormal);
} else
#endif
qApp->style()->drawPrimitive(QStyle::PE_PanelLineEdit, m_styleoption, painter);
}
break;
case MacHelpButton:
#ifdef Q_OS_OSX
{
const QPaintDevice *target = painter->device();
HIThemeButtonDrawInfo fdi;
fdi.kind = kThemeRoundButtonHelp;
fdi.version = 0;
fdi.adornment = 0;
1611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680
fdi.state = sunken() ? kThemeStatePressed : kThemeStateActive;
HIRect hirect = qt_hirectForQRect(m_styleoption->rect,QRect(0, 0, 0, 0));
HIThemeDrawButton(&hirect, &fdi, qt_mac_cg_context(target), kHIThemeOrientationNormal, NULL);
}
#endif
break;
case Widget:
qApp->style()->drawPrimitive(QStyle::PE_Widget, m_styleoption, painter);
break;
case ScrollAreaCorner:
qApp->style()->drawPrimitive(QStyle::PE_PanelScrollAreaCorner, m_styleoption, painter);
break;
case Splitter:
if (m_styleoption->rect.width() == 1)
painter->fillRect(0, 0, width(), height(), m_styleoption->palette.dark().color());
else
qApp->style()->drawControl(QStyle::CE_Splitter, m_styleoption, painter);
break;
case ComboBox:
{
qApp->style()->drawComplexControl(QStyle::CC_ComboBox,
qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
painter);
// This is needed on mac as it will use the painter color and ignore the palette
QPen pen = painter->pen();
painter->setPen(m_styleoption->palette.text().color());
qApp->style()->drawControl(QStyle::CE_ComboBoxLabel, m_styleoption, painter);
painter->setPen(pen);
} break;
case SpinBox:
#ifdef Q_OS_MAC
// macstyle depends on the embedded qlineedit to fill the editfield background
if (style() == "mac") {
QRect editRect = qApp->style()->subControlRect(QStyle::CC_SpinBox,
qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
QStyle::SC_SpinBoxEditField);
painter->fillRect(editRect.adjusted(-1, -1, 1, 1), m_styleoption->palette.base());
}
#endif
qApp->style()->drawComplexControl(QStyle::CC_SpinBox,
qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
painter);
break;
case Slider:
qApp->style()->drawComplexControl(QStyle::CC_Slider,
qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
painter);
break;
case Dial:
qApp->style()->drawComplexControl(QStyle::CC_Dial,
qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
painter);
break;
case ProgressBar:
qApp->style()->drawControl(QStyle::CE_ProgressBar, m_styleoption, painter);
break;
case ToolBar:
painter->fillRect(m_styleoption->rect, m_styleoption->palette.window().color());
qApp->style()->drawControl(QStyle::CE_ToolBar, m_styleoption, painter);
painter->save();
painter->setPen(style() != "fusion" ? m_styleoption->palette.dark().color().darker(120) :
m_styleoption->palette.window().color().lighter(107));
painter->drawLine(m_styleoption->rect.bottomLeft(), m_styleoption->rect.bottomRight());
painter->restore();
break;
case StatusBar:
#ifdef Q_OS_OSX
if (style() == "mac") {
qApp->style()->drawControl(QStyle::CE_ToolBar, m_styleoption, painter);
painter->setPen(m_styleoption->palette.dark().color().darker(120));
1681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750
painter->drawLine(m_styleoption->rect.topLeft(), m_styleoption->rect.topRight());
} else
#endif
{
painter->fillRect(m_styleoption->rect, m_styleoption->palette.window().color());
painter->setPen(m_styleoption->palette.dark().color().darker(120));
painter->drawLine(m_styleoption->rect.topLeft(), m_styleoption->rect.topRight());
qApp->style()->drawPrimitive(QStyle::PE_PanelStatusBar, m_styleoption, painter);
}
break;
case GroupBox:
qApp->style()->drawComplexControl(QStyle::CC_GroupBox, qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), painter);
break;
case ScrollBar:
qApp->style()->drawComplexControl(QStyle::CC_ScrollBar, qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), painter);
break;
case Menu: {
QStyleHintReturnMask val;
qApp->style()->styleHint(QStyle::SH_Menu_Mask, m_styleoption, 0, &val);
painter->save();
painter->setClipRegion(val.region);
painter->fillRect(m_styleoption->rect, m_styleoption->palette.window());
painter->restore();
qApp->style()->drawPrimitive(QStyle::PE_PanelMenu, m_styleoption, painter);
if (int fw = qApp->style()->pixelMetric(QStyle::PM_MenuPanelWidth)) {
QStyleOptionFrame frame;
frame.state = QStyle::State_None;
frame.lineWidth = fw;
frame.midLineWidth = 0;
frame.rect = m_styleoption->rect;
frame.styleObject = this;
frame.palette = m_styleoption->palette;
qApp->style()->drawPrimitive(QStyle::PE_FrameMenu, &frame, painter);
}
}
break;
default:
break;
}
}
qreal QQuickStyleItem::textWidth(const QString &text)
{
QFontMetricsF fm = QFontMetricsF(m_styleoption->fontMetrics);
return fm.boundingRect(text).width();
}
qreal QQuickStyleItem::textHeight(const QString &text)
{
QFontMetricsF fm = QFontMetricsF(m_styleoption->fontMetrics);
return text.isEmpty() ? fm.height() :
fm.boundingRect(text).height();
}
QString QQuickStyleItem::elidedText(const QString &text, int elideMode, int width)
{
return m_styleoption->fontMetrics.elidedText(text, Qt::TextElideMode(elideMode), width);
}
bool QQuickStyleItem::hasThemeIcon(const QString &icon) const
{
return QIcon::hasThemeIcon(icon);
}
bool QQuickStyleItem::event(QEvent *ev)
{
if (ev->type() == QEvent::StyleAnimationUpdate) {
if (isVisible()) {
ev->accept();
1751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820
polish();
}
return true;
} else if (ev->type() == QEvent::StyleChange) {
if (m_itemType == ScrollBar)
initStyleOption();
}
return QQuickItem::event(ev);
}
void QQuickStyleItem::setTextureWidth(int w)
{
if (m_textureWidth == w)
return;
m_textureWidth = w;
emit textureWidthChanged(m_textureWidth);
update();
}
void QQuickStyleItem::setTextureHeight(int h)
{
if (m_textureHeight == h)
return;
m_textureHeight = h;
emit textureHeightChanged(m_textureHeight);
update();
}
QSGNode *QQuickStyleItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
{
if (m_image.isNull()) {
delete node;
return 0;
}
QSGNinePatchNode *styleNode = static_cast<QSGNinePatchNode *>(node);
if (!styleNode) {
styleNode = QQuickItemPrivate::get(this)->sceneGraphContext()->createNinePatchNode();
if (!styleNode)
styleNode = new QQuickStyleNode;
}
#ifdef QSG_RUNTIME_DESCRIPTION
qsgnode_set_description(styleNode,
QString::fromLatin1("%1:%2, '%3'")
.arg(style())
.arg(elementType())
.arg(text()));
#endif
styleNode->setTexture(window()->createTextureFromImage(m_image, QQuickWindow::TextureCanUseAtlas));
styleNode->setBounds(boundingRect());
styleNode->setDevicePixelRatio(window()->devicePixelRatio());
styleNode->setPadding(m_border.left(), m_border.top(), m_border.right(), m_border.bottom());
styleNode->update();
return styleNode;
}
void QQuickStyleItem::updatePolish()
{
if (width() >= 1 && height() >= 1) { // Note these are reals so 1 pixel is minimum
float devicePixelRatio = window() ? window()->devicePixelRatio() : qApp->devicePixelRatio();
int w = m_textureWidth > 0 ? m_textureWidth : width();
int h = m_textureHeight > 0 ? m_textureHeight : height();
m_image = QImage(w * devicePixelRatio, h * devicePixelRatio, QImage::Format_ARGB32_Premultiplied);
m_image.setDevicePixelRatio(devicePixelRatio);
m_image.fill(Qt::transparent);
QPainter painter(&m_image);
painter.setLayoutDirection(qApp->layoutDirection());
182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871
paint(&painter);
QQuickItem::update();
} else if (!m_image.isNull()) {
m_image = QImage();
QQuickItem::update();
}
}
QPixmap QQuickTableRowImageProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
{
Q_UNUSED (requestedSize);
int width = 16;
int height = 16;
if (size)
*size = QSize(width, height);
QPixmap pixmap(width, height);
QStyleOptionViewItem opt;
opt.state |= QStyle::State_Enabled;
opt.rect = QRect(0, 0, width, height);
QString style = qApp->style()->metaObject()->className();
opt.features = 0;
if (id.contains("selected"))
opt.state |= QStyle::State_Selected;
if (id.contains("active")) {
opt.state |= QStyle::State_Active;
opt.palette.setCurrentColorGroup(QPalette::Active);
} else
opt.palette.setCurrentColorGroup(QPalette::Inactive);
if (id.contains("alternate"))
opt.features |= QStyleOptionViewItem::Alternate;
QPalette pal = QApplication::palette("QAbstractItemView");
if (opt.state & QStyle::State_Selected && (style.contains("Mac") ||
!qApp->style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected))) {
pal.setCurrentColorGroup(opt.palette.currentColorGroup());
pixmap.fill(pal.highlight().color());
} else {
pixmap.fill(pal.base().color());
QPainter pixpainter(&pixmap);
qApp->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, &pixpainter);
}
return pixmap;
}
QT_END_NAMESPACE