File indexing completed on 2023-12-03 11:02:52

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