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

0001 // SPDX-FileCopyrightText: 2022-2023 Devin Lin <devin@kde.org>
0002 // SPDX-License-Identifier: GPL-2.0-or-later
0003 
0004 #pragma once
0005 
0006 #include "folioapplication.h"
0007 #include "foliodelegate.h"
0008 
0009 #include <QAbstractListModel>
0010 #include <QObject>
0011 #include <QString>
0012 
0013 #include <KService>
0014 
0015 #include <KWayland/Client/connection_thread.h>
0016 #include <KWayland/Client/plasmawindowmanagement.h>
0017 #include <KWayland/Client/registry.h>
0018 #include <KWayland/Client/surface.h>
0019 
0020 struct ApplicationDelegate;
0021 class ApplicationFolderModel;
0022 class FolioDelegate;
0023 
0024 /**
0025  * @short Object that represents an application folder.
0026  */
0027 
0028 class FolioApplicationFolder : public QObject
0029 {
0030     Q_OBJECT
0031     Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
0032     Q_PROPERTY(QList<FolioApplication *> appPreviews READ appPreviews NOTIFY applicationsChanged)
0033     Q_PROPERTY(ApplicationFolderModel *applications READ applications NOTIFY applicationsReset)
0034 
0035 public:
0036     FolioApplicationFolder(QObject *parent = nullptr, QString name = QString{});
0037 
0038     static FolioApplicationFolder *fromJson(QJsonObject &obj, QObject *parent);
0039     QJsonObject toJson() const;
0040 
0041     QString name() const;
0042     void setName(QString &name);
0043 
0044     QList<FolioApplication *> appPreviews();
0045 
0046     ApplicationFolderModel *applications();
0047     void setApplications(QList<FolioApplication *> applications);
0048 
0049     void moveEntry(int fromRow, int toRow);
0050     bool addDelegate(FolioDelegate *delegate, int row);
0051     Q_INVOKABLE void removeDelegate(int row);
0052 
0053     int dropInsertPosition(int page, qreal x, qreal y);
0054     bool isDropPositionOutside(qreal x, qreal y);
0055 
0056 Q_SIGNALS:
0057     void nameChanged();
0058     void saveRequested();
0059     void applicationsChanged();
0060     void applicationsReset();
0061 
0062 private:
0063     QString m_name;
0064     QList<ApplicationDelegate> m_delegates;
0065     ApplicationFolderModel *m_applicationFolderModel;
0066 
0067     friend class ApplicationFolderModel;
0068 };
0069 
0070 struct ApplicationDelegate {
0071     FolioDelegate *delegate;
0072     qreal xPosition;
0073     qreal yPosition;
0074 };
0075 
0076 class ApplicationFolderModel : public QAbstractListModel
0077 {
0078     Q_OBJECT
0079     Q_PROPERTY(int numberOfPages READ numTotalPages NOTIFY numberOfPagesChanged)
0080 
0081 public:
0082     enum Roles {
0083         DelegateRole = Qt::UserRole + 1,
0084         XPositionRole,
0085         YPositionRole,
0086     };
0087     ApplicationFolderModel(FolioApplicationFolder *folder);
0088 
0089     int rowCount(const QModelIndex &parent = QModelIndex()) const override;
0090     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
0091     QHash<int, QByteArray> roleNames() const override;
0092 
0093     FolioDelegate *getDelegate(int index);
0094     void moveEntry(int fromRow, int toRow);
0095     bool canAddDelegate(FolioDelegate *delegate, int index);
0096     bool addDelegate(FolioDelegate *delegate, int index);
0097     void removeDelegate(int index);
0098     QPointF getDelegatePosition(int index);
0099 
0100     // for use with drag and drop, as the delegate is dragged around
0101     // ghost - fake delegate exists at an index, so a gap is created
0102     // invisible - existing delegate looks like it doesn't exist
0103     int getGhostEntryPosition();
0104     void setGhostEntry(int index);
0105     void replaceGhostEntry(FolioDelegate *delegate);
0106     void deleteGhostEntry();
0107 
0108     // the index that dropping at the position given would place the delegate at.
0109     int dropInsertPosition(int page, qreal x, qreal y);
0110 
0111     // whether this position is outside of the folder area
0112     bool isDropPositionOutside(qreal x, qreal y);
0113 
0114     // distance between page content to screen edge
0115     qreal leftMarginFromScreenEdge();
0116     qreal topMarginFromScreenEdge();
0117 
0118     int numTotalPages();
0119 
0120 Q_SIGNALS:
0121     void numberOfPagesChanged();
0122 
0123 private:
0124     void evaluateDelegatePositions(bool emitSignal = true);
0125 
0126     // get the position where delegates start being placed
0127     QPointF getDelegateStartPosition(int page);
0128 
0129     int numRowsOnPage();
0130     int numColumnsOnPage();
0131 
0132     // distance between folder edge and page content
0133     qreal horizontalPageMargin();
0134     qreal verticalPageMargin();
0135 
0136     FolioApplicationFolder *m_folder{nullptr};
0137 
0138     friend class FolioApplicationFolder;
0139 };