File indexing completed on 2024-04-21 05:31:17

0001 /*
0002     SPDX-FileCopyrightText: 2021 Michail Vourlakos <mvourlakos@gmail.com>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #ifndef CONTAINMENTLAYOUTMANAGER_H
0007 #define CONTAINMENTLAYOUTMANAGER_H
0008 
0009 //Qt
0010 #include <QHash>
0011 #include <QMetaMethod>
0012 #include <QObject>
0013 #include <QQmlPropertyMap>
0014 #include <QQuickItem>
0015 #include <QTimer>
0016 
0017 namespace KDeclarative {
0018 class ConfigPropertyMap;
0019 }
0020 
0021 namespace Latte{
0022 namespace Containment{
0023 
0024 class LayoutManager : public QObject
0025 {
0026   Q_OBJECT  
0027     Q_PROPERTY(QObject *plasmoidObj READ plasmoid() WRITE setPlasmoid NOTIFY plasmoidChanged)
0028 
0029     Q_PROPERTY(QQuickItem *rootItem READ rootItem WRITE setRootItem NOTIFY rootItemChanged)
0030     Q_PROPERTY(QQuickItem *mainLayout READ mainLayout WRITE setMainLayout NOTIFY mainLayoutChanged)
0031     Q_PROPERTY(QQuickItem *startLayout READ startLayout WRITE setStartLayout NOTIFY startLayoutChanged)
0032     Q_PROPERTY(QQuickItem *endLayout READ endLayout WRITE setEndLayout NOTIFY endLayoutChanged)
0033 
0034     Q_PROPERTY(QQuickItem *dndSpacerItem READ dndSpacer WRITE setDndSpacer NOTIFY dndSpacerChanged)
0035     Q_PROPERTY(QQuickItem *metrics READ metrics WRITE setMetrics NOTIFY metricsChanged)
0036 
0037     Q_PROPERTY(bool hasRestoredApplets READ hasRestoredApplets NOTIFY hasRestoredAppletsChanged)
0038 
0039     //! this is the only way I have found to write their values properly in the configuration file in Multiple mode
0040     //! if they are not used from qml side in the form of plasmoid.configuration..... then
0041     //! appletsOrder is not stored when needed and applets additions/removals are not valid on next startup
0042     Q_PROPERTY(int splitterPosition READ splitterPosition NOTIFY splitterPositionChanged)
0043     Q_PROPERTY(int splitterPosition2 READ splitterPosition2 NOTIFY splitterPosition2Changed)
0044     Q_PROPERTY(QList<int> appletOrder READ appletOrder NOTIFY appletOrderChanged)
0045     Q_PROPERTY(QList<int> order READ order NOTIFY orderChanged) //includes also splitters
0046     Q_PROPERTY(QList<int> lockedZoomApplets READ lockedZoomApplets NOTIFY lockedZoomAppletsChanged)
0047     Q_PROPERTY(QList<int> userBlocksColorizingApplets READ userBlocksColorizingApplets NOTIFY userBlocksColorizingAppletsChanged)
0048     Q_PROPERTY(QList<int> appletsInScheduledDestruction READ appletsInScheduledDestruction NOTIFY appletsInScheduledDestructionChanged)
0049 
0050 public:
0051     static const int JUSTIFYSPLITTERID = -10;
0052 
0053     LayoutManager(QObject *parent = nullptr);
0054 
0055     bool hasRestoredApplets() const;
0056 
0057     int splitterPosition() const;
0058     int splitterPosition2() const;
0059     QList<int> appletOrder() const;
0060     QList<int> lockedZoomApplets() const;
0061     QList<int> order() const;
0062     QList<int> userBlocksColorizingApplets() const;
0063     QList<int> appletsInScheduledDestruction() const;
0064 
0065     QObject *plasmoid() const;
0066     void setPlasmoid(QObject *plasmoid);
0067 
0068     QQuickItem *rootItem() const;
0069     void setRootItem(QQuickItem *root);
0070 
0071     QQuickItem *mainLayout() const;
0072     void setMainLayout(QQuickItem *main);
0073 
0074     QQuickItem *startLayout() const;
0075     void setStartLayout(QQuickItem *start);
0076 
0077     QQuickItem *endLayout() const;
0078     void setEndLayout(QQuickItem *end);
0079 
0080     QQuickItem *dndSpacer() const;
0081     void setDndSpacer(QQuickItem *dnd);
0082 
0083     QQuickItem *metrics() const;
0084     void setMetrics(QQuickItem *metrics);
0085 
0086 public slots:
0087     Q_INVOKABLE void restore();
0088     Q_INVOKABLE void save();
0089     Q_INVOKABLE void saveOptions();
0090     Q_INVOKABLE void setOption(const int &appletId, const QString &property, const QVariant &value);
0091 
0092     Q_INVOKABLE void addAppletItem(QObject *applet, int x, int y);
0093     Q_INVOKABLE void addAppletItem(QObject *applet, int index);
0094     Q_INVOKABLE void removeAppletItem(QObject *applet);
0095 
0096     Q_INVOKABLE void addJustifySplittersInMainLayout();
0097     Q_INVOKABLE void moveAppletsBasedOnJustifyAlignment();
0098     Q_INVOKABLE void joinLayoutsToMainLayout();
0099     Q_INVOKABLE void insertBefore(QQuickItem *hoveredItem, QQuickItem *item);
0100     Q_INVOKABLE void insertAfter(QQuickItem *hoveredItem, QQuickItem *item);
0101     Q_INVOKABLE void insertAtCoordinates(QQuickItem *item, const int &x, const int &y);
0102 
0103     Q_INVOKABLE int dndSpacerIndex();
0104 
0105     Q_INVOKABLE bool isMasqueradedIndex(const int &x, const int &y);
0106     Q_INVOKABLE int masquearadedIndex(const int &x, const int &y);
0107     Q_INVOKABLE QPoint indexToMasquearadedPoint(const int &index);
0108 
0109     void requestAppletsOrder(const QList<int> &order);
0110     void requestAppletsInLockedZoom(const QList<int> &applets);
0111     void requestAppletsDisabledColoring(const QList<int> &applets);
0112     void setAppletInScheduledDestruction(const int &id, const bool &enabled);
0113 
0114 
0115 signals:
0116     void appletOrderChanged();
0117     void appletsInScheduledDestructionChanged();
0118     void hasRestoredAppletsChanged();
0119     void plasmoidChanged();
0120     void rootItemChanged();
0121     void dndSpacerChanged();
0122     void lockedZoomAppletsChanged();
0123     void userBlocksColorizingAppletsChanged();
0124 
0125     void mainLayoutChanged();
0126     void metricsChanged();
0127     void orderChanged();
0128     void splitterPositionChanged();
0129     void splitterPosition2Changed();
0130     void startLayoutChanged();
0131     void endLayoutChanged();
0132 
0133 private slots:
0134     void onRootItemChanged();
0135     void destroyJustifySplitters();
0136 
0137     void updateOrder();
0138     void cleanupOptions();
0139     void reorderParabolicSpacers();
0140 
0141 private:
0142     void restoreOptions();
0143     void restoreOption(const char *option);
0144     void saveOption(const char *option);
0145 
0146     void destroyAppletContainer(QObject *applet);
0147 
0148     void initSaveConnections();
0149 
0150     void insertAtLayoutTail(QQuickItem *layout, QQuickItem *item);
0151     void insertAtLayoutHead(QQuickItem *layout, QQuickItem *item);
0152     void insertAtLayoutIndex(QQuickItem *layout, QQuickItem *item, const int &index);
0153 
0154     void setSplitterPosition(const int &position);
0155     void setSplitterPosition2(const int &position);
0156 
0157     void setAppletOrder(const QList<int> &order);
0158     void setOrder(const QList<int> &order);
0159     void setLockedZoomApplets(const QList<int> &applets);
0160     void setUserBlocksColorizingApplets(const QList<int> &applets);
0161 
0162     void reorderSplitterInStartLayout();
0163     void reorderSplitterInEndLayout();
0164 
0165     bool isJustifySplitter(const QQuickItem *item) const;
0166     bool isValidApplet(const int &id);
0167     bool insertAtLayoutCoordinates(QQuickItem *layout, QQuickItem *item, int x, int y);
0168 
0169     int distanceFromTail(QQuickItem *layout, QPointF pos) const;
0170     int distanceFromHead(QQuickItem *layout, QPointF pos) const;
0171 
0172     QQuickItem *firstSplitter();
0173     QQuickItem *lastSplitter();
0174     QQuickItem *appletItem(const int &id);
0175     QQuickItem *appletItemInLayout(QQuickItem *layout, const int &id);
0176 
0177     void printAppletList(QList<QQuickItem *> list);
0178 
0179     QList<int> toIntList(const QString &serialized);
0180     QString toStr(const QList<int> &list);
0181 
0182 private:
0183     //! This is needed in order to overcome plasma frameworks limitations and instead of adding dropped widgets
0184     //! based on coordinates, to be able to add them directly at the correct index
0185     static const int MASQUERADEDINDEXTOPOINTBASE = -23456;
0186 
0187     int m_splitterPosition{-1};
0188     int m_splitterPosition2{-1};
0189     QList<int> m_appletOrder;
0190     QList<int> m_lockedZoomApplets;
0191     QList<int> m_order;
0192     QList<int> m_userBlocksColorizingApplets;
0193 
0194     QQuickItem *m_rootItem{nullptr};
0195     QQuickItem *m_dndSpacer{nullptr};
0196 
0197     QQuickItem *m_mainLayout{nullptr};
0198     QQuickItem *m_startLayout{nullptr};
0199     QQuickItem *m_endLayout{nullptr};
0200     QQuickItem *m_metrics{nullptr};
0201 
0202     QObject *m_plasmoid{nullptr};
0203     KDeclarative::ConfigPropertyMap *m_configuration{nullptr};
0204 
0205     QHash<int, QQuickItem *> m_appletsInScheduledDestruction;
0206 
0207     QMetaMethod m_createAppletItemMethod;
0208     QMetaMethod m_createJustifySplitterMethod;
0209     QMetaMethod m_initAppletContainerMethod;
0210 
0211     bool m_hasRestoredApplets{false};
0212     QTimer m_hasRestoredAppletsTimer;
0213 
0214     //! first QString is the option in AppletItem
0215     //! second QString is how the option is stored in
0216     QHash<QString, QString> m_option;
0217 };
0218 }
0219 }
0220 #endif // CONTAINMENTLAYOUTMANAGER_H