File indexing completed on 2024-12-08 12:26:51

0001 /*
0002     SPDX-FileCopyrightText: 2017 by Marco Martin <mart@kde.org>
0003     SPDX-FileCopyrightText: 2017 by David Edmundson <davidedmundson@kde.org>
0004     SPDX-FileCopyrightText: 2016 The Qt Company Ltd. <https://www.qt.io/licensing/>
0005 
0006     This file is part of the Qt Quick Controls module of the Qt Toolkit.
0007 
0008     SPDX-License-Identifier: LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KFQF-Accepted-GPL OR LicenseRef-Qt-Commercial
0009 */
0010 
0011 #ifndef KQUICKSTYLEITEM_P_H
0012 #define KQUICKSTYLEITEM_P_H
0013 
0014 #include "kquickpadding_p.h"
0015 #include <QPointer>
0016 #include <QtGui/qimage.h>
0017 #include <QtQuick/qquickimageprovider.h>
0018 #include <QtQuick/qquickitem.h>
0019 
0020 #include <memory>
0021 
0022 class QWidget;
0023 class QStyleOption;
0024 class QStyle;
0025 
0026 namespace Kirigami
0027 {
0028 class PlatformTheme;
0029 }
0030 
0031 class QQuickTableRowImageProvider1 : public QQuickImageProvider
0032 {
0033 public:
0034     QQuickTableRowImageProvider1()
0035         : QQuickImageProvider(QQuickImageProvider::Pixmap)
0036     {
0037     }
0038     QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) override;
0039 };
0040 
0041 class KQuickStyleItem : public QQuickItem
0042 {
0043     Q_OBJECT
0044 
0045     Q_PROPERTY(KQuickPadding *border READ border CONSTANT)
0046 
0047     Q_PROPERTY(bool sunken READ sunken WRITE setSunken NOTIFY sunkenChanged)
0048     Q_PROPERTY(bool raised READ raised WRITE setRaised NOTIFY raisedChanged)
0049     Q_PROPERTY(bool flat READ flat WRITE setFlat NOTIFY flatChanged)
0050     Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
0051     Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectedChanged)
0052     Q_PROPERTY(bool hasFocus READ hasFocus WRITE sethasFocus NOTIFY hasFocusChanged)
0053     Q_PROPERTY(bool on READ on WRITE setOn NOTIFY onChanged)
0054     Q_PROPERTY(bool hover READ hover WRITE setHover NOTIFY hoverChanged)
0055     Q_PROPERTY(bool horizontal READ horizontal WRITE setHorizontal NOTIFY horizontalChanged)
0056     Q_PROPERTY(bool isTransient READ isTransient WRITE setTransient NOTIFY transientChanged)
0057 
0058     Q_PROPERTY(QString elementType READ elementType WRITE setElementType NOTIFY elementTypeChanged)
0059     Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
0060     Q_PROPERTY(QString activeControl READ activeControl WRITE setActiveControl NOTIFY activeControlChanged)
0061     Q_PROPERTY(QString styleName READ styleName NOTIFY styleNameChanged)
0062     Q_PROPERTY(QVariantMap hints READ hints WRITE setHints NOTIFY hintChanged RESET resetHints)
0063     Q_PROPERTY(QVariantMap properties READ properties WRITE setProperties NOTIFY propertiesChanged)
0064     Q_PROPERTY(QFont font READ font NOTIFY fontChanged)
0065 
0066     // For range controls
0067     Q_PROPERTY(int minimum READ minimum WRITE setMinimum NOTIFY minimumChanged)
0068     Q_PROPERTY(int maximum READ maximum WRITE setMaximum NOTIFY maximumChanged)
0069     Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged)
0070     Q_PROPERTY(int step READ step WRITE setStep NOTIFY stepChanged)
0071     Q_PROPERTY(int paintMargins READ paintMargins WRITE setPaintMargins NOTIFY paintMarginsChanged)
0072 
0073     Q_PROPERTY(int contentWidth READ contentWidth WRITE setContentWidth NOTIFY contentWidthChanged)
0074     Q_PROPERTY(int contentHeight READ contentHeight WRITE setContentHeight NOTIFY contentHeightChanged)
0075 
0076     Q_PROPERTY(int textureWidth READ textureWidth WRITE setTextureWidth NOTIFY textureWidthChanged)
0077     Q_PROPERTY(int textureHeight READ textureHeight WRITE setTextureHeight NOTIFY textureHeightChanged)
0078 
0079     Q_PROPERTY(int leftPadding READ leftPadding NOTIFY leftPaddingChanged)
0080     Q_PROPERTY(int topPadding READ topPadding NOTIFY topPaddingChanged)
0081     Q_PROPERTY(int rightPadding READ rightPadding NOTIFY rightPaddingChanged)
0082     Q_PROPERTY(int bottomPadding READ bottomPadding NOTIFY bottomPaddingChanged)
0083 
0084     Q_PROPERTY(QQuickItem *control READ control WRITE setControl NOTIFY controlChanged)
0085 
0086     KQuickPadding *border()
0087     {
0088         return &m_border;
0089     }
0090 
0091 public:
0092     KQuickStyleItem(QQuickItem *parent = nullptr);
0093     ~KQuickStyleItem() override;
0094 
0095     enum MenuItemType {
0096         SeparatorType = 0,
0097         ItemType,
0098         MenuType,
0099         ScrollIndicatorType,
0100     };
0101 
0102     enum Type {
0103         Undefined,
0104         Button,
0105         RadioButton,
0106         CheckBox,
0107         ComboBox,
0108         ComboBoxItem,
0109         Dial,
0110         ToolBar,
0111         ToolButton,
0112         Tab,
0113         TabFrame,
0114         Frame,
0115         FocusFrame,
0116         FocusRect,
0117         SpinBox,
0118         Slider,
0119         ScrollBar,
0120         ProgressBar,
0121         Edit,
0122         GroupBox,
0123         Header,
0124         Item,
0125         ItemRow,
0126         ItemBranchIndicator,
0127         Splitter,
0128         Menu,
0129         MenuItem,
0130         Widget,
0131         StatusBar,
0132         ScrollAreaCorner,
0133         MacHelpButton,
0134         MenuBar,
0135         MenuBarItem,
0136         DelayButton,
0137     };
0138 
0139     void paint(QPainter *);
0140 
0141     bool sunken() const
0142     {
0143         return m_sunken;
0144     }
0145     bool raised() const
0146     {
0147         return m_raised;
0148     }
0149     bool flat() const
0150     {
0151         return m_flat;
0152     }
0153     bool active() const
0154     {
0155         return m_active;
0156     }
0157     bool selected() const
0158     {
0159         return m_selected;
0160     }
0161     bool hasFocus() const
0162     {
0163         return m_focus;
0164     }
0165     bool on() const
0166     {
0167         return m_on;
0168     }
0169     bool hover() const
0170     {
0171         return m_hover;
0172     }
0173     bool horizontal() const
0174     {
0175         return m_horizontal;
0176     }
0177     bool isTransient() const
0178     {
0179         return m_transient;
0180     }
0181 
0182     int minimum() const
0183     {
0184         return m_minimum;
0185     }
0186     int maximum() const
0187     {
0188         return m_maximum;
0189     }
0190     int step() const
0191     {
0192         return m_step;
0193     }
0194     int value() const
0195     {
0196         return m_value;
0197     }
0198     int paintMargins() const
0199     {
0200         return m_paintMargins;
0201     }
0202 
0203     QString elementType() const
0204     {
0205         return m_type;
0206     }
0207     QString text() const
0208     {
0209         return m_text;
0210     }
0211     QString activeControl() const
0212     {
0213         return m_activeControl;
0214     }
0215     QVariantMap hints() const
0216     {
0217         return m_hints;
0218     }
0219     QVariantMap properties() const
0220     {
0221         return m_properties;
0222     }
0223     QFont font() const
0224     {
0225         return m_font;
0226     }
0227     QString styleName() const;
0228 
0229     void setSunken(bool sunken)
0230     {
0231         if (m_sunken != sunken) {
0232             m_sunken = sunken;
0233             polish();
0234             Q_EMIT sunkenChanged();
0235         }
0236     }
0237     void setRaised(bool raised)
0238     {
0239         if (m_raised != raised) {
0240             m_raised = raised;
0241             polish();
0242             Q_EMIT raisedChanged();
0243         }
0244     }
0245     void setFlat(bool flat)
0246     {
0247         if (m_flat != flat) {
0248             m_flat = flat;
0249             polish();
0250             Q_EMIT flatChanged();
0251         }
0252     }
0253     void setActive(bool active)
0254     {
0255         if (m_active != active) {
0256             m_active = active;
0257             polish();
0258             Q_EMIT activeChanged();
0259         }
0260     }
0261     void setSelected(bool selected)
0262     {
0263         if (m_selected != selected) {
0264             m_selected = selected;
0265             polish();
0266             Q_EMIT selectedChanged();
0267         }
0268     }
0269     void sethasFocus(bool focus)
0270     {
0271         if (m_focus != focus) {
0272             m_focus = focus;
0273             polish();
0274             Q_EMIT hasFocusChanged();
0275         }
0276     }
0277     void setOn(bool on)
0278     {
0279         if (m_on != on) {
0280             m_on = on;
0281             polish();
0282             Q_EMIT onChanged();
0283         }
0284     }
0285     void setHover(bool hover)
0286     {
0287         if (m_hover != hover) {
0288             m_hover = hover;
0289             polish();
0290             Q_EMIT hoverChanged();
0291         }
0292     }
0293     void setHorizontal(bool horizontal)
0294     {
0295         if (m_horizontal != horizontal) {
0296             m_horizontal = horizontal;
0297             polish();
0298             Q_EMIT horizontalChanged();
0299         }
0300     }
0301     void setTransient(bool transient)
0302     {
0303         if (m_transient != transient) {
0304             m_transient = transient;
0305             polish();
0306             Q_EMIT transientChanged();
0307         }
0308     }
0309     void setMinimum(int minimum)
0310     {
0311         if (m_minimum != minimum) {
0312             m_minimum = minimum;
0313             polish();
0314             Q_EMIT minimumChanged();
0315         }
0316     }
0317     void setMaximum(int maximum)
0318     {
0319         if (m_maximum != maximum) {
0320             m_maximum = maximum;
0321             polish();
0322             Q_EMIT maximumChanged();
0323         }
0324     }
0325     void setValue(int value)
0326     {
0327         if (m_value != value) {
0328             m_value = value;
0329             polish();
0330             Q_EMIT valueChanged();
0331         }
0332     }
0333     void setStep(int step)
0334     {
0335         if (m_step != step) {
0336             m_step = step;
0337             polish();
0338             Q_EMIT stepChanged();
0339         }
0340     }
0341     void setPaintMargins(int value)
0342     {
0343         if (m_paintMargins != value) {
0344             m_paintMargins = value;
0345             polish();
0346             Q_EMIT paintMarginsChanged();
0347         }
0348     }
0349     void setElementType(const QString &str);
0350     void setText(const QString &str)
0351     {
0352         if (m_text != str) {
0353             m_text = str;
0354             updateSizeHint();
0355             polish();
0356             Q_EMIT textChanged();
0357         }
0358     }
0359     void setActiveControl(const QString &str)
0360     {
0361         if (m_activeControl != str) {
0362             m_activeControl = str;
0363             polish();
0364             Q_EMIT activeControlChanged();
0365         }
0366     }
0367     void setHints(const QVariantMap &str);
0368     void setProperties(const QVariantMap &props)
0369     {
0370         if (m_properties != props) {
0371             m_properties = props;
0372             m_iconDirty = true;
0373             updateSizeHint();
0374             polish();
0375             Q_EMIT propertiesChanged();
0376         }
0377     }
0378     void resetHints();
0379 
0380     int contentWidth() const
0381     {
0382         return m_contentWidth;
0383     }
0384     void setContentWidth(int arg);
0385 
0386     int contentHeight() const
0387     {
0388         return m_contentHeight;
0389     }
0390     void setContentHeight(int arg);
0391 
0392     virtual void initStyleOption();
0393     void resolvePalette();
0394 
0395     int leftPadding() const;
0396     int topPadding() const;
0397     int rightPadding() const;
0398     int bottomPadding() const;
0399 
0400     Q_INVOKABLE qreal textWidth(const QString &);
0401     Q_INVOKABLE qreal textHeight(const QString &);
0402 
0403     int textureWidth() const
0404     {
0405         return m_textureWidth;
0406     }
0407     void setTextureWidth(int w);
0408 
0409     int textureHeight() const
0410     {
0411         return m_textureHeight;
0412     }
0413     void setTextureHeight(int h);
0414 
0415     QQuickItem *control() const;
0416     void setControl(QQuickItem *control);
0417 
0418     static QStyle *style();
0419 
0420 public Q_SLOTS:
0421     int pixelMetric(const QString &);
0422     QVariant styleHint(const QString &);
0423     void updateSizeHint();
0424     void updateRect();
0425     void updateBaselineOffset();
0426     void updateItem()
0427     {
0428         polish();
0429     }
0430     QString hitTest(int x, int y);
0431     QRectF subControlRect(const QString &subcontrolString);
0432     QSize sizeFromContents(int width, int height);
0433     QRect computeBoundingRect(const QList<QRect>& rects);
0434     QString elidedText(const QString &text, int elideMode, int width);
0435     bool hasThemeIcon(const QString &) const;
0436 
0437 Q_SIGNALS:
0438     void elementTypeChanged();
0439     void textChanged();
0440     void sunkenChanged();
0441     void raisedChanged();
0442     void flatChanged();
0443     void activeChanged();
0444     void selectedChanged();
0445     void hasFocusChanged();
0446     void onChanged();
0447     void hoverChanged();
0448     void horizontalChanged();
0449     void transientChanged();
0450     void minimumChanged();
0451     void maximumChanged();
0452     void stepChanged();
0453     void valueChanged();
0454     void activeControlChanged();
0455     void styleNameChanged();
0456     void paintMarginsChanged();
0457     void hintChanged();
0458     void propertiesChanged();
0459     void fontChanged();
0460     void controlChanged();
0461 
0462     void contentWidthChanged(int arg);
0463     void contentHeightChanged(int arg);
0464 
0465     void textureWidthChanged(int w);
0466     void textureHeightChanged(int h);
0467 
0468     void leftPaddingChanged();
0469     void topPaddingChanged();
0470     void rightPaddingChanged();
0471     void bottomPaddingChanged();
0472 
0473 protected:
0474     bool event(QEvent *) override;
0475     QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
0476     void updatePolish() override;
0477     bool eventFilter(QObject *watched, QEvent *event) override;
0478     void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) override;
0479 
0480 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0481     void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
0482 #else
0483     void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
0484 #endif
0485 
0486 private:
0487     QIcon iconFromIconProperty() const;
0488     const char *classNameForItem() const;
0489     qreal baselineOffset();
0490     void styleChanged();
0491 
0492 protected:
0493     Kirigami::PlatformTheme *m_theme = nullptr;
0494     QStyleOption *m_styleoption;
0495     QPointer<QQuickItem> m_control;
0496     QPointer<QWindow> m_window;
0497     Type m_itemType;
0498 
0499     QString m_type;
0500     QString m_text;
0501     QString m_activeControl;
0502     QVariantMap m_hints;
0503     QVariantMap m_properties;
0504     QFont m_font;
0505 
0506     bool m_sunken;
0507     bool m_raised;
0508     bool m_flat;
0509     bool m_active;
0510     bool m_selected;
0511     bool m_focus;
0512     bool m_hover;
0513     bool m_on;
0514     bool m_horizontal;
0515     bool m_transient;
0516     bool m_sharedWidget;
0517     bool m_iconDirty = true;
0518 
0519     int m_minimum;
0520     int m_maximum;
0521     int m_value;
0522     int m_step;
0523     int m_paintMargins;
0524 
0525     int m_contentWidth;
0526     int m_contentHeight;
0527 
0528     int m_textureWidth;
0529     int m_textureHeight;
0530 
0531     Qt::FocusReason m_lastFocusReason;
0532 
0533     QImage m_image;
0534     KQuickPadding m_border;
0535 
0536     static std::unique_ptr<QStyle> s_style;
0537 };
0538 
0539 #endif // QQUICKSTYLEITEM_P_H