File indexing completed on 2024-05-12 17:08:54
0001 /* 0002 SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include <QPointer> 0010 #include <QQmlParserStatus> 0011 #include <QQuickItem> 0012 #include <QQuickWindow> 0013 0014 class QTimer; 0015 0016 namespace Plasma 0017 { 0018 class Containment; 0019 } 0020 0021 namespace PlasmaQuick 0022 { 0023 class AppletQuickItem; 0024 } 0025 0026 class AbstractLayoutManager; 0027 class AppletContainer; 0028 class ItemContainer; 0029 0030 class AppletsLayout : public QQuickItem 0031 { 0032 Q_OBJECT 0033 Q_INTERFACES(QQmlParserStatus) 0034 0035 Q_PROPERTY(QString configKey READ configKey WRITE setConfigKey NOTIFY configKeyChanged) 0036 0037 // A config key that can be used as fallback when loading and configKey is not found 0038 // Is always a backup of the last used configKey. Useful when the configkey depends 0039 // from the screen size and plasma starts on an "unexpected" size 0040 Q_PROPERTY(QString fallbackConfigKey READ fallbackConfigKey WRITE setFallbackConfigKey NOTIFY fallbackConfigKeyChanged) 0041 0042 Q_PROPERTY(bool relayoutLock READ relayoutLock WRITE setRelayoutLock NOTIFY relayoutLockChanged) 0043 0044 Q_PROPERTY(PlasmaQuick::AppletQuickItem *containment READ containment WRITE setContainment NOTIFY containmentChanged) 0045 0046 Q_PROPERTY(QJSValue acceptsAppletCallback READ acceptsAppletCallback WRITE setAcceptsAppletCallback NOTIFY acceptsAppletCallbackChanged) 0047 0048 Q_PROPERTY(qreal minimumItemWidth READ minimumItemWidth WRITE setMinimumItemWidth NOTIFY minimumItemWidthChanged) 0049 0050 Q_PROPERTY(qreal minimumItemHeight READ minimumItemHeight WRITE setMinimumItemHeight NOTIFY minimumItemHeightChanged) 0051 0052 Q_PROPERTY(qreal defaultItemWidth READ defaultItemWidth WRITE setDefaultItemWidth NOTIFY defaultItemWidthChanged) 0053 0054 Q_PROPERTY(qreal defaultItemHeight READ defaultItemHeight WRITE setDefaultItemHeight NOTIFY defaultItemHeightChanged) 0055 0056 Q_PROPERTY(qreal cellWidth READ cellWidth WRITE setCellWidth NOTIFY cellWidthChanged) 0057 0058 Q_PROPERTY(qreal cellHeight READ cellHeight WRITE setCellHeight NOTIFY cellHeightChanged) 0059 0060 Q_PROPERTY(QQmlComponent *appletContainerComponent READ appletContainerComponent WRITE setAppletContainerComponent NOTIFY appletContainerComponentChanged) 0061 0062 Q_PROPERTY(ItemContainer *placeHolder READ placeHolder WRITE setPlaceHolder NOTIFY placeHolderChanged); 0063 0064 /** 0065 * if the applets layout contains some kind of main MouseArea, 0066 * MouseEventListener or Flickable, we want to filter its events to make the 0067 * long mouse press work 0068 */ 0069 Q_PROPERTY(QQuickItem *eventManagerToFilter READ eventManagerToFilter WRITE setEventManagerToFilter NOTIFY eventManagerToFilterChanged); 0070 0071 Q_PROPERTY(AppletsLayout::EditModeCondition editModeCondition READ editModeCondition WRITE setEditModeCondition NOTIFY editModeConditionChanged) 0072 Q_PROPERTY(bool editMode READ editMode WRITE setEditMode NOTIFY editModeChanged) 0073 0074 public: 0075 enum PreferredLayoutDirection { 0076 Closest = 0, 0077 LeftToRight, 0078 RightToLeft, 0079 TopToBottom, 0080 BottomToTop, 0081 }; 0082 Q_ENUM(PreferredLayoutDirection) 0083 0084 enum EditModeCondition { 0085 Locked = 0, 0086 Manual, 0087 AfterPressAndHold, 0088 }; 0089 Q_ENUM(EditModeCondition) 0090 0091 enum LayoutChange { 0092 NoChange = 0, 0093 SizeChange = 1, 0094 ConfigKeyChange = 2, 0095 }; 0096 Q_DECLARE_FLAGS(LayoutChanges, LayoutChange) 0097 0098 AppletsLayout(QQuickItem *parent = nullptr); 0099 ~AppletsLayout(); 0100 0101 // QML setters and getters 0102 QString configKey() const; 0103 void setConfigKey(const QString &key); 0104 0105 QString fallbackConfigKey() const; 0106 void setFallbackConfigKey(const QString &key); 0107 0108 bool relayoutLock() const; 0109 void setRelayoutLock(bool lock); 0110 0111 PlasmaQuick::AppletQuickItem *containment() const; 0112 void setContainment(PlasmaQuick::AppletQuickItem *containment); 0113 0114 QJSValue acceptsAppletCallback() const; 0115 void setAcceptsAppletCallback(const QJSValue &callback); 0116 0117 qreal minimumItemWidth() const; 0118 void setMinimumItemWidth(qreal width); 0119 0120 qreal minimumItemHeight() const; 0121 void setMinimumItemHeight(qreal height); 0122 0123 qreal defaultItemWidth() const; 0124 void setDefaultItemWidth(qreal width); 0125 0126 qreal defaultItemHeight() const; 0127 void setDefaultItemHeight(qreal height); 0128 0129 qreal cellWidth() const; 0130 void setCellWidth(qreal width); 0131 0132 qreal cellHeight() const; 0133 void setCellHeight(qreal height); 0134 0135 QQmlComponent *appletContainerComponent() const; 0136 void setAppletContainerComponent(QQmlComponent *component); 0137 0138 ItemContainer *placeHolder() const; 0139 void setPlaceHolder(ItemContainer *placeHolder); 0140 0141 QQuickItem *eventManagerToFilter() const; 0142 void setEventManagerToFilter(QQuickItem *item); 0143 0144 EditModeCondition editModeCondition() const; 0145 void setEditModeCondition(EditModeCondition condition); 0146 0147 bool editMode() const; 0148 void setEditMode(bool edit); 0149 0150 Q_INVOKABLE void save(); 0151 Q_INVOKABLE void showPlaceHolderAt(const QRectF &geom); 0152 Q_INVOKABLE void showPlaceHolderForItem(ItemContainer *item); 0153 Q_INVOKABLE void hidePlaceHolder(); 0154 0155 Q_INVOKABLE bool isRectAvailable(qreal x, qreal y, qreal width, qreal height); 0156 Q_INVOKABLE bool itemIsManaged(ItemContainer *item); 0157 Q_INVOKABLE void positionItem(ItemContainer *item); 0158 Q_INVOKABLE void restoreItem(ItemContainer *item); 0159 Q_INVOKABLE void releaseSpace(ItemContainer *item); 0160 0161 Q_SIGNALS: 0162 /** 0163 * An applet has been refused by the layout: acceptsAppletCallback 0164 * returned false and will need to be managed in a different way 0165 */ 0166 void appletRefused(QObject *applet, int x, int y); 0167 0168 void configKeyChanged(); 0169 void fallbackConfigKeyChanged(); 0170 void relayoutLockChanged(); 0171 void containmentChanged(); 0172 void minimumItemWidthChanged(); 0173 void minimumItemHeightChanged(); 0174 void defaultItemWidthChanged(); 0175 void defaultItemHeightChanged(); 0176 void cellWidthChanged(); 0177 void cellHeightChanged(); 0178 void acceptsAppletCallbackChanged(); 0179 void appletContainerComponentChanged(); 0180 void placeHolderChanged(); 0181 void eventManagerToFilterChanged(); 0182 void editModeConditionChanged(); 0183 void editModeChanged(); 0184 0185 protected: 0186 bool childMouseEventFilter(QQuickItem *item, QEvent *event) override; 0187 void updatePolish() override; 0188 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0189 void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; 0190 #else 0191 void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; 0192 #endif 0193 0194 // void classBegin() override; 0195 void componentComplete() override; 0196 void mousePressEvent(QMouseEvent *event) override; 0197 void mouseMoveEvent(QMouseEvent *event) override; 0198 void mouseReleaseEvent(QMouseEvent *event) override; 0199 void mouseUngrabEvent() override; 0200 0201 private Q_SLOTS: 0202 void appletAdded(QObject *applet, int x, int y); 0203 void appletRemoved(QObject *applet); 0204 0205 private: 0206 AppletContainer *createContainerForApplet(PlasmaQuick::AppletQuickItem *appletItem); 0207 0208 QString m_configKey; 0209 QString m_fallbackConfigKey; 0210 QTimer *m_saveLayoutTimer; 0211 QTimer *m_layoutChangeTimer; 0212 LayoutChanges m_layoutChanges = NoChange; 0213 0214 PlasmaQuick::AppletQuickItem *m_containmentItem = nullptr; 0215 Plasma::Containment *m_containment = nullptr; 0216 QQmlComponent *m_appletContainerComponent = nullptr; 0217 0218 AbstractLayoutManager *m_layoutManager = nullptr; 0219 0220 QPointer<ItemContainer> m_placeHolder; 0221 QPointer<QQuickItem> m_eventManagerToFilter; 0222 0223 QTimer *m_pressAndHoldTimer; 0224 0225 QJSValue m_acceptsAppletCallback; 0226 0227 AppletsLayout::EditModeCondition m_editModeCondition = AppletsLayout::Manual; 0228 0229 QHash<PlasmaQuick::AppletQuickItem *, AppletContainer *> m_containerForApplet; 0230 0231 QSizeF m_minimumItemSize; 0232 QSizeF m_defaultItemSize; 0233 QSizeF m_savedSize; 0234 QRectF m_geometryBeforeResolutionChange; 0235 0236 QPointF m_mouseDownPosition = QPoint(-1, -1); 0237 bool m_mouseDownWasEditMode = false; 0238 bool m_editMode = false; 0239 bool m_relayoutLock = false; 0240 }; 0241 0242 Q_DECLARE_OPERATORS_FOR_FLAGS(AppletsLayout::LayoutChanges)