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