File indexing completed on 2024-12-29 05:06:03

0001 // SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
0002 // SPDX-License-Identifier: GPL-2.0-or-later
0003 
0004 #pragma once
0005 
0006 #include <QObject>
0007 #include <QTimer>
0008 
0009 #include "folioapplicationfolder.h"
0010 #include "foliodelegate.h"
0011 #include "homescreenstate.h"
0012 
0013 class HomeScreenState;
0014 
0015 class DelegateDragPosition : public QObject
0016 {
0017     Q_OBJECT
0018     Q_PROPERTY(DelegateDragPosition::Location location READ location NOTIFY locationChanged)
0019     Q_PROPERTY(int page READ page NOTIFY pageChanged)
0020     Q_PROPERTY(int pageRow READ pageRow NOTIFY pageRowChanged)
0021     Q_PROPERTY(int pageColumn READ pageColumn NOTIFY pageColumnChanged)
0022     Q_PROPERTY(int favouritesPosition READ favouritesPosition NOTIFY favouritesPositionChanged)
0023     Q_PROPERTY(int folderPosition READ folderPosition NOTIFY folderPositionChanged)
0024     Q_PROPERTY(FolioApplicationFolder *folder READ folder NOTIFY folderChanged)
0025 
0026 public:
0027     enum Location { Pages, Favourites, AppDrawer, Folder, WidgetList };
0028     Q_ENUM(Location)
0029 
0030     DelegateDragPosition(QObject *parent = nullptr);
0031     ~DelegateDragPosition();
0032 
0033     void copyFrom(DelegateDragPosition *position);
0034 
0035     Location location() const;
0036     void setLocation(Location location);
0037 
0038     int page() const;
0039     void setPage(int page);
0040 
0041     int pageRow() const;
0042     void setPageRow(int pageRow);
0043 
0044     int pageColumn() const;
0045     void setPageColumn(int pageColumn);
0046 
0047     int favouritesPosition() const;
0048     void setFavouritesPosition(int favouritesPosition);
0049 
0050     int folderPosition() const;
0051     void setFolderPosition(int folderPosition);
0052 
0053     // TODO: what if the folder becomes invalid? we need to clear it
0054     FolioApplicationFolder *folder() const;
0055     void setFolder(FolioApplicationFolder *folder);
0056 
0057 Q_SIGNALS:
0058     void locationChanged();
0059     void pageChanged();
0060     void pageRowChanged();
0061     void pageColumnChanged();
0062     void favouritesPositionChanged();
0063     void folderPositionChanged();
0064     void folderChanged();
0065 
0066 private:
0067     Location m_location{DelegateDragPosition::Pages};
0068     int m_page{0};
0069     int m_pageRow{0};
0070     int m_pageColumn{0};
0071     int m_favouritesPosition{0};
0072     int m_folderPosition{0};
0073     FolioApplicationFolder *m_folder{nullptr};
0074 };
0075 
0076 Q_DECLARE_METATYPE(DelegateDragPosition);
0077 
0078 class DragState : public QObject
0079 {
0080     Q_OBJECT
0081     Q_PROPERTY(DelegateDragPosition *candidateDropPosition READ candidateDropPosition CONSTANT)
0082     Q_PROPERTY(DelegateDragPosition *startPosition READ startPosition CONSTANT)
0083     Q_PROPERTY(FolioDelegate *dropDelegate READ dropDelegate NOTIFY dropDelegateChanged)
0084 
0085 public:
0086     DragState(HomeScreenState *state = nullptr, QObject *parent = nullptr);
0087 
0088     DelegateDragPosition *candidateDropPosition() const;
0089     DelegateDragPosition *startPosition() const;
0090     FolioDelegate *dropDelegate() const;
0091     void setDropDelegate(FolioDelegate *dropDelegate);
0092 
0093 Q_SIGNALS:
0094     void dropDelegateChanged();
0095     void delegateDroppedAndPlaced();
0096 
0097     // if you drop a new delegate on an invalid spot
0098     void newDelegateDropAbandoned();
0099 
0100 private Q_SLOTS:
0101     void onDelegateDragPositionChanged();
0102     void onDelegateDragPositionOverFolderViewChanged();
0103     void onDelegateDragPositionOverFavouritesChanged();
0104     void onDelegateDragPositionOverPageViewChanged();
0105 
0106     void onDelegateDraggingStarted();
0107     void onDelegateDragFromPageStarted(int page, int row, int column);
0108     void onDelegateDragFromFavouritesStarted(int position);
0109     void onDelegateDragFromAppDrawerStarted(QString storageId);
0110     void onDelegateDragFromFolderStarted(FolioApplicationFolder *folder, int position);
0111     void onDelegateDragFromWidgetListStarted(QString appletPluginId);
0112     void onDelegateDropped();
0113 
0114     void onLeaveCurrentFolder();
0115 
0116     void onChangePageTimerFinished();
0117     void onOpenFolderTimerFinished();
0118     void onLeaveFolderTimerFinished();
0119     void onChangeFolderPageTimerFinished();
0120     void onFolderInsertBetweenTimerFinished();
0121     void onFavouritesInsertBetweenTimerFinished();
0122 
0123 private:
0124     // deletes the delegate at m_startPosition
0125     void deleteStartPositionDelegate();
0126 
0127     // places the delegate at m_candidateDropPosition, returning whether it was successful
0128     bool createDropPositionDelegate();
0129 
0130     // whether m_startPosition = m_candidateDropPosition
0131     bool isStartPositionEqualDropPosition();
0132 
0133     // we need to adjust so that the coord is in the center of the delegate
0134     qreal getDraggedDelegateX();
0135     qreal getDraggedDelegateY();
0136 
0137     // position of the dragging pointer
0138     qreal getPointerX();
0139     qreal getPointerY();
0140 
0141     QTimer *m_changePageTimer{nullptr};
0142     QTimer *m_openFolderTimer{nullptr};
0143     QTimer *m_leaveFolderTimer{nullptr};
0144     QTimer *m_changeFolderPageTimer{nullptr};
0145 
0146     // inserting between apps in a folder
0147     QTimer *m_folderInsertBetweenTimer{nullptr};
0148     int m_folderInsertBetweenIndex{0};
0149 
0150     // inserting between apps in the favourites strip
0151     QTimer *m_favouritesInsertBetweenTimer{nullptr};
0152     int m_favouritesInsertBetweenIndex{0};
0153 
0154     // the delegate that is being dropped
0155     FolioDelegate *m_dropDelegate{nullptr};
0156 
0157     // where we are hovering over, potentially to drop the delegate
0158     DelegateDragPosition *const m_candidateDropPosition{nullptr};
0159 
0160     // this is the original start position of the drag
0161     DelegateDragPosition *const m_startPosition{nullptr};
0162 
0163     // when dropping a new widget, this is the applet name
0164     QString m_createdAppletPluginId{};
0165 
0166     HomeScreenState *m_state{nullptr};
0167 };