-
Jens Bache-Wiig authored
This is a regression caused by removing the fillrect for SpinBoxStyle itself. Change-Id: Ibab509634a12aec591d2d031a0e735d602b388c6 Reviewed-by:
Gabriel de Dietrich <gabriel.dedietrich@digia.com>
a0dccdd0
qquickstyleitem.cpp 66.94 KiB
/****************************************************************************
**
** Copyright (C) 2013 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:LGPL$
** 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 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $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 <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
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
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)
{
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 QSGGeometryNode
{
public:
QQuickStyleNode()
: m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
{
m_geometry.setDrawingMode(GL_TRIANGLE_STRIP);
setGeometry(&m_geometry);
setMaterial(&m_material);
}
~QQuickStyleNode()
{
delete m_material.texture();
}
void initialize(QSGTexture *texture,
const QRectF &bounds, qreal devicePixelRatio,
int left, int top, int right, int bottom) {
delete m_material.texture();
m_material.setTexture(texture);
if (left <= 0 && top <= 0 && right <= 0 && bottom <= 0) {
m_geometry.allocate(4, 0);
QSGGeometry::updateTexturedRectGeometry(&m_geometry, bounds, texture->normalizedTextureSubRect());
markDirty(QSGNode::DirtyGeometry | QSGNode::DirtyMaterial);
return;
}
QRectF tc = texture->normalizedTextureSubRect();
QSize ts = texture->textureSize();
ts.setHeight(ts.height() / devicePixelRatio);
ts.setWidth(ts.width() / devicePixelRatio);
qreal invtw = tc.width() / ts.width();
qreal invth = tc.height() / ts.height();
struct Coord { qreal p; qreal t; };
Coord cx[4] = { { bounds.left(), tc.left() },
{ bounds.left() + left, tc.left() + left * invtw },
{ bounds.right() - right, tc.right() - right * invtw },
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
{ bounds.right(), tc.right() }
};
Coord cy[4] = { { bounds.top(), tc.top() },
{ bounds.top() + top, tc.top() + top * invth },
{ bounds.bottom() - bottom, tc.bottom() - bottom * invth },
{ 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];
}
QSGGeometry m_geometry;
QSGTextureMaterial m_material;
};
QQuickStyleItem::QQuickStyleItem(QQuickItem *parent)
: QQuickItem(parent),
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)
{
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
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();
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;
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)
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
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) {
m_styleoption = new QStyleOptionViewItem();
}
QStyleOptionViewItem *opt = qstyleoption_cast<QStyleOptionViewItem*>(m_styleoption);
opt->features = QStyleOptionViewItem::HasDisplay;
opt->text = text();
opt->textElideMode = Qt::ElideRight;
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
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
: 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);
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"))
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
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());
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;
}
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
}
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();
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;
561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
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: {
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();
631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
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();
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")) ?
701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
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();
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;
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;
if (sizeHint == "mini") {
m_styleoption->state |= QStyle::State_Mini;
} else if (sizeHint == "small") {
m_styleoption->state |= QStyle::State_Small;
}
}
/*
* Property style
*
* Returns a simplified style name.
*
* QMacStyle = "mac"
* QWindowsXPStyle = "windowsxp"
* QFusionStyle = "fusion"
*/
QString QQuickStyleItem::style() const
{
771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
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)
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;
841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
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 newWidth = qMax(width, btn->fontMetrics.width(btn->text));
int newHeight = qMax(height, btn->fontMetrics.height());
size = qApp->style()->sizeFromContents(QStyle::CT_PushButton, m_styleoption, QSize(newWidth, newHeight)); }
#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 trough if not mac
case Edit:
#ifdef Q_OS_OSX
if (style() =="mac") {
QString sizeHint = m_hints.value("size").toString();
if ((sizeHint == "small") || (sizeHint == "mini"))
911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
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));
#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()
{
981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
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++;
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;
1051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
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 );
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;
}
1121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190
QVariant QQuickStyleItem::styleHint(const QString &metric)
{
initStyleOption();
if (metric == "comboboxpopup") {
return qApp->style()->styleHint(QStyle::SH_ComboBox_Popup, m_styleoption);
} else if (metric == "highlightedTextColor") {
QPalette pal = QApplication::palette("QAbstractItemView");
pal.setCurrentColorGroup(m_styleoption->palette.currentColorGroup());
return pal.highlightedText().color().name();
} else if (metric == "textColor") {
QPalette pal = qApp->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);
return 0;
// Add SH_Menu_SpaceActivatesItem, SH_Menu_SubMenuPopupDelay
}
void QQuickStyleItem::setHints(const QVariantMap &str)
{
if (m_hints != str) {
m_hints = str;
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
1191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
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") {
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 {
1261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
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);
}
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)) {
1331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400
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:
#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;
1401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470
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") {
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);
1471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540
}
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;
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,
1541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610
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));
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;
qApp->style()->drawPrimitive(QStyle::PE_FrameMenu, &frame, painter);
}
1611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680
}
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();
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;
}
1681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750
QQuickStyleNode *styleNode = static_cast<QQuickStyleNode *>(node);
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->initialize(window()->createTextureFromImage(m_image, QQuickWindow::TextureCanUseAtlas),
boundingRect(),
window()->devicePixelRatio(),
m_border.left(), m_border.top(), m_border.right(), m_border.bottom());
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());
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());
17511752175317541755175617571758175917601761
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