File indexing completed on 2024-12-01 03:45:23

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