File indexing completed on 2024-04-14 03:53:48
0001 /* 0002 * SPDX-FileCopyrightText: 2020 Arjen Hiemstra <ahiemstra@heimr.nl> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include <QQuickItem> 0010 #include <memory> 0011 0012 #include <QQmlEngine> 0013 0014 class PaintedRectangleItem; 0015 0016 /** 0017 * @brief Grouped property for rectangle border. 0018 */ 0019 class BorderGroup : public QObject 0020 { 0021 Q_OBJECT 0022 QML_ELEMENT 0023 QML_UNCREATABLE("") 0024 /** 0025 * @brief This property holds the border's width in pixels. 0026 * 0027 * default: ``0``px 0028 */ 0029 Q_PROPERTY(qreal width READ width WRITE setWidth NOTIFY changed FINAL) 0030 /** 0031 * @brief This property holds the border's color. 0032 * 0033 * Full RGBA colors are supported. 0034 * 0035 * default: ``Qt::black`` 0036 */ 0037 Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY changed FINAL) 0038 0039 public: 0040 explicit BorderGroup(QObject *parent = nullptr); 0041 0042 qreal width() const; 0043 void setWidth(qreal newWidth); 0044 0045 QColor color() const; 0046 void setColor(const QColor &newColor); 0047 0048 Q_SIGNAL void changed(); 0049 0050 inline bool isEnabled() const 0051 { 0052 return !qFuzzyIsNull(m_width); 0053 } 0054 0055 private: 0056 qreal m_width = 0.0; 0057 QColor m_color = Qt::black; 0058 }; 0059 0060 /** 0061 * @brief Grouped property for the rectangle's shadow. 0062 */ 0063 class ShadowGroup : public QObject 0064 { 0065 Q_OBJECT 0066 QML_ELEMENT 0067 QML_UNCREATABLE("") 0068 /** 0069 * @brief This property holds the shadow's approximate size in pixels. 0070 * @note The actual shadow size can be less than this value due to falloff. 0071 * 0072 * default: ``0``px 0073 */ 0074 Q_PROPERTY(qreal size READ size WRITE setSize NOTIFY changed FINAL) 0075 /** 0076 * @brief This property holds the shadow's offset in pixels on the X axis. 0077 * 0078 * default: ``0``px 0079 */ 0080 Q_PROPERTY(qreal xOffset READ xOffset WRITE setXOffset NOTIFY changed FINAL) 0081 /** 0082 * @brief This property holds the shadow's offset in pixels on the Y axis. 0083 * 0084 * default: ``0``px 0085 */ 0086 Q_PROPERTY(qreal yOffset READ yOffset WRITE setYOffset NOTIFY changed FINAL) 0087 /** 0088 * @brief This property holds the shadow's color. 0089 * 0090 * Full RGBA colors are supported. 0091 * 0092 * default: ``Qt::black`` 0093 */ 0094 Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY changed FINAL) 0095 0096 public: 0097 explicit ShadowGroup(QObject *parent = nullptr); 0098 0099 qreal size() const; 0100 void setSize(qreal newSize); 0101 0102 qreal xOffset() const; 0103 void setXOffset(qreal newXOffset); 0104 0105 qreal yOffset() const; 0106 void setYOffset(qreal newYOffset); 0107 0108 QColor color() const; 0109 void setColor(const QColor &newShadowColor); 0110 0111 Q_SIGNAL void changed(); 0112 0113 private: 0114 qreal m_size = 0.0; 0115 qreal m_xOffset = 0.0; 0116 qreal m_yOffset = 0.0; 0117 QColor m_color = Qt::black; 0118 }; 0119 0120 /** 0121 * @brief Grouped property for corner radius. 0122 */ 0123 class CornersGroup : public QObject 0124 { 0125 Q_OBJECT 0126 QML_ELEMENT 0127 QML_UNCREATABLE("") 0128 /** 0129 * @brief This property holds the top-left corner's radius in pixels. 0130 * 0131 * Setting this to ``-1`` indicates that the value should be ignored. 0132 * 0133 * default: ``-1``px 0134 */ 0135 Q_PROPERTY(qreal topLeftRadius READ topLeft WRITE setTopLeft NOTIFY changed FINAL) 0136 0137 /** 0138 * @brief This property holds the top-right corner's radius in pixels. 0139 * 0140 * Setting this to ``-1`` indicates that the value should be ignored. 0141 * 0142 * default: ``-1``px 0143 */ 0144 Q_PROPERTY(qreal topRightRadius READ topRight WRITE setTopRight NOTIFY changed FINAL) 0145 0146 /** 0147 * @brief This property holds the bottom-left corner's radius in pixels. 0148 * 0149 * Setting this to ``-1`` indicates that the value should be ignored. 0150 * 0151 * default: ``-1``px 0152 */ 0153 Q_PROPERTY(qreal bottomLeftRadius READ bottomLeft WRITE setBottomLeft NOTIFY changed FINAL) 0154 0155 /** 0156 * @brief This property holds the bottom-right corner's radius in pixels. 0157 * 0158 * Setting this to ``-1`` indicates that the value should be ignored. 0159 * 0160 * default: ``-1``px 0161 */ 0162 Q_PROPERTY(qreal bottomRightRadius READ bottomRight WRITE setBottomRight NOTIFY changed FINAL) 0163 0164 public: 0165 explicit CornersGroup(QObject *parent = nullptr); 0166 0167 qreal topLeft() const; 0168 void setTopLeft(qreal newTopLeft); 0169 0170 qreal topRight() const; 0171 void setTopRight(qreal newTopRight); 0172 0173 qreal bottomLeft() const; 0174 void setBottomLeft(qreal newBottomLeft); 0175 0176 qreal bottomRight() const; 0177 void setBottomRight(qreal newBottomRight); 0178 0179 Q_SIGNAL void changed(); 0180 0181 QVector4D toVector4D(float all) const; 0182 0183 private: 0184 float m_topLeft = -1.0; 0185 float m_topRight = -1.0; 0186 float m_bottomLeft = -1.0; 0187 float m_bottomRight = -1.0; 0188 }; 0189 0190 /** 0191 * @brief A rectangle with a shadow behind it. 0192 * 0193 * This item will render a rectangle, with a shadow below it. The rendering is done 0194 * using distance fields, which provide greatly improved performance. The shadow is 0195 * rendered outside of the item's bounds, so the item's width and height are the 0196 * rectangle's width and height. 0197 * 0198 * @since 5.69 0199 * @since 2.12 0200 */ 0201 class ShadowedRectangle : public QQuickItem 0202 { 0203 Q_OBJECT 0204 QML_ELEMENT 0205 /** 0206 * @brief This property holds the radii of the rectangle's corners. 0207 * 0208 * This is the amount of rounding to apply to all of the rectangle's 0209 * corners, in pixels. Each corner can have a different radius. 0210 * 0211 * default: ``0`` 0212 * 0213 * @see corners 0214 */ 0215 Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged FINAL) 0216 0217 /** 0218 * @brief This property holds the rectangle's color. 0219 * 0220 * Full RGBA colors are supported. 0221 * 0222 * default: ``Qt::white`` 0223 */ 0224 Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged FINAL) 0225 0226 /** 0227 * @brief This property holds the border's grouped property. 0228 * 0229 * Example usage: 0230 * @code 0231 * Kirigami.ShadowedRectangle { 0232 * border.width: 2 0233 * border.color: Kirigami.Theme.textColor 0234 * } 0235 * @endcode 0236 * @see BorderGroup 0237 */ 0238 Q_PROPERTY(BorderGroup *border READ border CONSTANT FINAL) 0239 0240 /** 0241 * @brief This property holds the shadow's grouped property. 0242 * 0243 * Example usage: 0244 * @code 0245 * Kirigami.ShadowedRectangle { 0246 * shadow.size: 20 0247 * shadow.xOffset: 5 0248 * shadow.yOffset: 5 0249 * } 0250 * @endcode 0251 * 0252 * @see ShadowGroup 0253 */ 0254 Q_PROPERTY(ShadowGroup *shadow READ shadow CONSTANT FINAL) 0255 0256 /** 0257 * @brief This property holds the corners grouped property 0258 * 0259 * Note that the values from this group override \property radius for the 0260 * corner they affect. 0261 * 0262 * Example usage: 0263 * @code 0264 * Kirigami.ShadowedRectangle { 0265 * corners.topLeftRadius: 4 0266 * corners.topRightRadius: 5 0267 * corners.bottomLeftRadius: 2 0268 * corners.bottomRightRadius: 10 0269 * @endcode 0270 * 0271 * @see CornersGroup 0272 */ 0273 Q_PROPERTY(CornersGroup *corners READ corners CONSTANT FINAL) 0274 0275 /** 0276 * @brief This property holds the rectangle's render mode. 0277 * 0278 * default: ``RenderType::Auto`` 0279 * 0280 * @see RenderType 0281 */ 0282 Q_PROPERTY(RenderType renderType READ renderType WRITE setRenderType NOTIFY renderTypeChanged FINAL) 0283 0284 /** 0285 * @brief This property tells whether software rendering is being used. 0286 * 0287 * default: ``false`` 0288 */ 0289 Q_PROPERTY(bool softwareRendering READ isSoftwareRendering NOTIFY softwareRenderingChanged FINAL) 0290 0291 public: 0292 ShadowedRectangle(QQuickItem *parent = nullptr); 0293 ~ShadowedRectangle() override; 0294 0295 /** 0296 * @brief Available rendering types for ShadowedRectangle. 0297 */ 0298 enum RenderType { 0299 0300 /** 0301 * @brief Automatically determine the optimal rendering type. 0302 * 0303 * This will use the highest rendering quality possible, falling back to 0304 * lower quality if the hardware doesn't support it. It will use software 0305 * rendering if the QtQuick scene graph is set to use software rendering. 0306 */ 0307 Auto, 0308 0309 /** 0310 * @brief Use the highest rendering quality possible, even if the hardware might 0311 * not be able to handle it normally. 0312 */ 0313 HighQuality, 0314 0315 /** 0316 * @brief Use the lowest rendering quality, even if the hardware could handle 0317 * higher quality rendering. 0318 * 0319 * This might result in certain effects being omitted, like shadows. 0320 */ 0321 LowQuality, 0322 0323 /** 0324 * @brief Always use software rendering for this rectangle. 0325 * 0326 * Software rendering is intended as a fallback when the QtQuick scene 0327 * graph is configured to use software rendering. It will result in 0328 * a number of missing features, like shadows and multiple corner radii. 0329 */ 0330 Software 0331 }; 0332 Q_ENUM(RenderType) 0333 0334 BorderGroup *border() const; 0335 ShadowGroup *shadow() const; 0336 CornersGroup *corners() const; 0337 0338 qreal radius() const; 0339 void setRadius(qreal newRadius); 0340 Q_SIGNAL void radiusChanged(); 0341 0342 QColor color() const; 0343 void setColor(const QColor &newColor); 0344 Q_SIGNAL void colorChanged(); 0345 0346 RenderType renderType() const; 0347 void setRenderType(RenderType renderType); 0348 Q_SIGNAL void renderTypeChanged(); 0349 0350 void componentComplete() override; 0351 0352 bool isSoftwareRendering() const; 0353 0354 Q_SIGNALS: 0355 void softwareRenderingChanged(); 0356 0357 protected: 0358 PaintedRectangleItem *softwareItem() const; 0359 void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) override; 0360 QSGNode *updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *data) override; 0361 0362 private: 0363 void checkSoftwareItem(); 0364 const std::unique_ptr<BorderGroup> m_border; 0365 const std::unique_ptr<ShadowGroup> m_shadow; 0366 const std::unique_ptr<CornersGroup> m_corners; 0367 qreal m_radius = 0.0; 0368 QColor m_color = Qt::white; 0369 RenderType m_renderType = RenderType::Auto; 0370 PaintedRectangleItem *m_softwareItem = nullptr; 0371 };