homescreens/folio: Port away from singletons to support multi-display

https://invent.kde.org/plasma/plasma-mobile/-/issues/316
This commit is contained in:
Devin Lin 2024-06-21 00:42:14 -04:00
parent 600fd05900
commit 21ed42ee30
50 changed files with 1136 additions and 993 deletions

View file

@ -18,7 +18,7 @@
#include <KSharedConfig>
#include <KSycoca>
ApplicationListModel::ApplicationListModel(QObject *parent)
ApplicationListModel::ApplicationListModel(HomeScreen *parent)
: QAbstractListModel(parent)
{
connect(KSycoca::self(), &KSycoca::databaseChanged, this, &ApplicationListModel::sycocaDbChanged);
@ -34,12 +34,6 @@ ApplicationListModel::ApplicationListModel(QObject *parent)
ApplicationListModel::~ApplicationListModel() = default;
ApplicationListModel *ApplicationListModel::self()
{
static ApplicationListModel *inst = new ApplicationListModel(nullptr);
return inst;
}
QHash<int, QByteArray> ApplicationListModel::roleNames() const
{
return {{DelegateRole, QByteArrayLiteral("delegate")}};
@ -82,8 +76,8 @@ void ApplicationListModel::load()
const KService::List apps = KApplicationTrader::query(filter);
for (const KService::Ptr &service : apps) {
FolioApplication *app = new FolioApplication{this, service};
FolioDelegate *delegate = new FolioDelegate{app, this};
FolioApplication *app = new FolioApplication{m_homeScreen, service};
FolioDelegate *delegate = new FolioDelegate{app, m_homeScreen};
unorderedList << delegate;
}

View file

@ -11,6 +11,10 @@
#include <QSet>
#include "foliodelegate.h"
#include "homescreen.h"
class HomeScreen;
class FolioDelegate;
/**
* @short The base application list, used directly by the app drawer.
@ -24,15 +28,14 @@ public:
DelegateRole = Qt::UserRole + 1,
};
ApplicationListModel(QObject *parent = nullptr);
ApplicationListModel(HomeScreen *parent = nullptr);
~ApplicationListModel() override;
static ApplicationListModel *self();
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE;
Q_INVOKABLE void load();
void load();
public Q_SLOTS:
void sycocaDbChanged();
@ -41,5 +44,6 @@ Q_SIGNALS:
void launchError(const QString &msg);
protected:
HomeScreen *m_homeScreen{nullptr};
QList<FolioDelegate *> m_delegates;
};

View file

@ -122,8 +122,10 @@ void DelegateDragPosition::setFolder(FolioApplicationFolder *folder)
}
}
DragState::DragState(HomeScreenState *state, QObject *parent)
DragState::DragState(HomeScreenState *state, HomeScreen *parent)
: QObject{parent}
, m_homeScreen{parent}
, m_state{state}
, m_changePageTimer{new QTimer{this}}
, m_openFolderTimer{new QTimer{this}}
, m_leaveFolderTimer{new QTimer{this}}
@ -132,7 +134,6 @@ DragState::DragState(HomeScreenState *state, QObject *parent)
, m_favouritesInsertBetweenTimer{new QTimer{this}}
, m_candidateDropPosition{new DelegateDragPosition{this}}
, m_startPosition{new DelegateDragPosition{this}}
, m_state{state}
{
if (!state) {
return;
@ -170,7 +171,7 @@ DragState::DragState(HomeScreenState *state, QObject *parent)
connect(m_state, &HomeScreenState::delegateDragFromFolderStarted, this, &DragState::onDelegateDragFromFolderStarted);
connect(m_state, &HomeScreenState::delegateDragFromWidgetListStarted, this, &DragState::onDelegateDragFromWidgetListStarted);
connect(m_state, &HomeScreenState::swipeStateChanged, this, [this]() {
if (HomeScreenState::self()->swipeState() == HomeScreenState::DraggingDelegate) {
if (m_state->swipeState() == HomeScreenState::DraggingDelegate) {
onDelegateDraggingStarted();
}
});
@ -314,7 +315,8 @@ void DragState::onDelegateDragPositionOverFavouritesChanged()
qreal x = getPointerX();
qreal y = getPointerY();
int dropIndex = FavouritesModel::self()->dropInsertPosition(x, y);
FavouritesModel *favouritesModel = m_homeScreen->favouritesModel();
int dropIndex = favouritesModel->dropInsertPosition(x, y);
// if the drop position changed, cancel the open folder timer
if (m_candidateDropPosition->location() != DelegateDragPosition::Favourites || m_candidateDropPosition->favouritesPosition() != dropIndex) {
@ -329,7 +331,7 @@ void DragState::onDelegateDragPositionOverFavouritesChanged()
}
// ignore this event if the favourites area is full already
if (FavouritesModel::self()->isFull()) {
if (favouritesModel->isFull()) {
return;
}
@ -338,7 +340,7 @@ void DragState::onDelegateDragPositionOverFavouritesChanged()
return;
}
if (FavouritesModel::self()->dropPositionIsEdge(x, y)) {
if (favouritesModel->dropPositionIsEdge(x, y)) {
// if we need to make space for the delegate
// start the insertion timer (so that the user has time to move the delegate away)
@ -350,13 +352,13 @@ void DragState::onDelegateDragPositionOverFavouritesChanged()
// if we are hovering over the center of a folder or app
// delete ghost entry if there is one
int ghostEntryPosition = FavouritesModel::self()->getGhostEntryPosition();
int ghostEntryPosition = favouritesModel->getGhostEntryPosition();
if (ghostEntryPosition != -1 && ghostEntryPosition != dropIndex) {
if (dropIndex > ghostEntryPosition) {
// correct index if deleting the ghost will change the index
dropIndex--;
}
FavouritesModel::self()->deleteGhostEntry();
favouritesModel->deleteGhostEntry();
}
// update the current drop position
@ -365,7 +367,7 @@ void DragState::onDelegateDragPositionOverFavouritesChanged()
// start folder open timer if hovering over a folder
// get delegate being hovered over
FolioDelegate *delegate = FavouritesModel::self()->getEntryAt(dropIndex);
FolioDelegate *delegate = favouritesModel->getEntryAt(dropIndex);
// check delegate is a folder and the drop delegate is an app
if (delegate && delegate->type() == FolioDelegate::Folder && m_dropDelegate && m_dropDelegate->type() == FolioDelegate::Application) {
@ -422,7 +424,7 @@ void DragState::onDelegateDragPositionOverPageViewChanged()
m_candidateDropPosition->setLocation(DelegateDragPosition::Pages);
// start folder open timer if hovering over a folder
PageModel *pageModel = PageListModel::self()->getPage(page);
PageModel *pageModel = m_homeScreen->pageListModel()->getPage(page);
if (pageModel) {
// get delegate being hovered over
FolioDelegate *delegate = pageModel->getDelegate(row, column);
@ -462,7 +464,7 @@ void DragState::onDelegateDraggingStarted()
void DragState::onDelegateDragFromPageStarted(int page, int row, int column)
{
// fetch delegate at start position
PageModel *pageModel = PageListModel::self()->getPage(page);
PageModel *pageModel = m_homeScreen->pageListModel()->getPage(page);
if (pageModel) {
setDropDelegate(pageModel->getDelegate(row, column));
} else {
@ -479,7 +481,7 @@ void DragState::onDelegateDragFromPageStarted(int page, int row, int column)
void DragState::onDelegateDragFromFavouritesStarted(int position)
{
// fetch delegate at start position
setDropDelegate(FavouritesModel::self()->getEntryAt(position));
setDropDelegate(m_homeScreen->favouritesModel()->getEntryAt(position));
// set start location
m_startPosition->setFavouritesPosition(position);
@ -490,8 +492,8 @@ void DragState::onDelegateDragFromAppDrawerStarted(QString storageId)
{
// fetch delegate at start position
if (KService::Ptr service = KService::serviceByStorageId(storageId)) {
FolioApplication *app = new FolioApplication{this, service};
setDropDelegate(new FolioDelegate{app, this});
FolioApplication *app = new FolioApplication{m_homeScreen, service};
setDropDelegate(new FolioDelegate{app, m_homeScreen});
} else {
setDropDelegate(nullptr);
}
@ -515,8 +517,8 @@ void DragState::onDelegateDragFromWidgetListStarted(QString appletPluginId)
{
// default widget has dimensions of 1x1, and id of -1
m_createdAppletPluginId = appletPluginId;
FolioWidget *widget = new FolioWidget{this, -1, 1, 1};
setDropDelegate(new FolioDelegate{widget, this});
FolioWidget *widget = new FolioWidget{m_homeScreen, -1, 1, 1};
setDropDelegate(new FolioDelegate{widget, m_homeScreen});
// set start location
m_startPosition->setLocation(DelegateDragPosition::WidgetList);
@ -533,10 +535,10 @@ void DragState::onDelegateDropped()
// delete empty pages at the end if they exist
// (it can be created if user drags app to new page, but doesn't place it there)
PageListModel::self()->deleteEmptyPagesAtEnd();
m_homeScreen->pageListModel()->deleteEmptyPagesAtEnd();
// clear ghost position if there is one
FavouritesModel::self()->deleteGhostEntry();
m_homeScreen->favouritesModel()->deleteGhostEntry();
// reset timers
m_folderInsertBetweenTimer->stop();
@ -581,6 +583,8 @@ void DragState::onChangePageTimerFinished()
const int leftPagePosition = 0;
const int rightPagePosition = m_state->pageWidth();
PageListModel *pageListModel = m_homeScreen->pageListModel();
qreal x = getPointerX();
if (qAbs(leftPagePosition - x) <= PAGE_CHANGE_THRESHOLD) {
// if we are at the left edge, go left
@ -594,12 +598,12 @@ void DragState::onChangePageTimerFinished()
int page = m_state->currentPage() + 1;
// if we are at the right-most page, try to create a new one if the current page isn't empty
if (page == PageListModel::self()->rowCount() && !PageListModel::self()->isLastPageEmpty()) {
PageListModel::self()->addPageAtEnd();
if (page == pageListModel->rowCount() && !pageListModel->isLastPageEmpty()) {
pageListModel->addPageAtEnd();
}
// go to page if it exists
if (page < PageListModel::self()->rowCount()) {
if (page < pageListModel->rowCount()) {
m_state->goToPage(page);
}
}
@ -618,7 +622,7 @@ void DragState::onOpenFolderTimerFinished()
switch (m_candidateDropPosition->location()) {
case DelegateDragPosition::Pages: {
// get current page
PageModel *page = PageListModel::self()->getPage(m_candidateDropPosition->page());
PageModel *page = m_homeScreen->pageListModel()->getPage(m_candidateDropPosition->page());
if (!page) {
return;
}
@ -630,20 +634,19 @@ void DragState::onOpenFolderTimerFinished()
}
folder = delegate->folder();
screenPosition = HomeScreenState::self()->getPageDelegateScreenPosition(m_candidateDropPosition->page(),
m_candidateDropPosition->pageRow(),
m_candidateDropPosition->pageColumn());
screenPosition =
m_state->getPageDelegateScreenPosition(m_candidateDropPosition->page(), m_candidateDropPosition->pageRow(), m_candidateDropPosition->pageColumn());
break;
}
case DelegateDragPosition::Favourites: {
// get delegate being hovered over in favourites bar
FolioDelegate *delegate = FavouritesModel::self()->getEntryAt(m_candidateDropPosition->favouritesPosition());
FolioDelegate *delegate = m_homeScreen->favouritesModel()->getEntryAt(m_candidateDropPosition->favouritesPosition());
if (!delegate || delegate->type() != FolioDelegate::Folder) {
return;
}
folder = delegate->folder();
screenPosition = HomeScreenState::self()->getFavouritesDelegateScreenPosition(m_candidateDropPosition->favouritesPosition());
screenPosition = m_homeScreen->homeScreenState()->getFavouritesDelegateScreenPosition(m_candidateDropPosition->favouritesPosition());
break;
}
default:
@ -727,7 +730,7 @@ void DragState::onFavouritesInsertBetweenTimerFinished()
m_candidateDropPosition->setLocation(DelegateDragPosition::Favourites);
// insert it at this position, shifting existing apps to the side
FavouritesModel::self()->setGhostEntry(m_favouritesInsertBetweenIndex);
m_homeScreen->favouritesModel()->setGhostEntry(m_favouritesInsertBetweenIndex);
}
void DragState::deleteStartPositionDelegate()
@ -735,14 +738,14 @@ void DragState::deleteStartPositionDelegate()
// delete the delegate at the start position
switch (m_startPosition->location()) {
case DelegateDragPosition::Pages: {
PageModel *page = PageListModel::self()->getPage(m_startPosition->page());
PageModel *page = m_homeScreen->pageListModel()->getPage(m_startPosition->page());
if (page) {
page->removeDelegate(m_startPosition->pageRow(), m_startPosition->pageColumn());
}
break;
}
case DelegateDragPosition::Favourites:
FavouritesModel::self()->removeEntry(m_startPosition->favouritesPosition());
m_homeScreen->favouritesModel()->removeEntry(m_startPosition->favouritesPosition());
break;
case DelegateDragPosition::Folder:
m_startPosition->folder()->removeDelegate(m_startPosition->folderPosition());
@ -767,7 +770,7 @@ bool DragState::createDropPositionDelegate()
switch (m_candidateDropPosition->location()) {
case DelegateDragPosition::Pages: {
// locate the page we are dropping on
PageModel *page = PageListModel::self()->getPage(m_candidateDropPosition->page());
PageModel *page = m_homeScreen->pageListModel()->getPage(m_candidateDropPosition->page());
if (!page) {
break;
}
@ -776,7 +779,7 @@ bool DragState::createDropPositionDelegate()
int column = m_candidateDropPosition->pageColumn();
// delegate to add
FolioPageDelegate *delegate = new FolioPageDelegate{row, column, m_dropDelegate, PageListModel::self()};
FolioPageDelegate *delegate = new FolioPageDelegate{row, column, m_dropDelegate, m_homeScreen};
// delegate that exists at the drop position
FolioPageDelegate *existingDelegate = page->getDelegate(row, column);
@ -795,10 +798,10 @@ bool DragState::createDropPositionDelegate()
} else if (existingDelegate->type() == FolioDelegate::Application && !isStartPositionEqualDropPosition()) {
// create a folder from the two apps
FolioApplicationFolder *folder = new FolioApplicationFolder(this, DEFAULT_FOLDER_NAME);
FolioApplicationFolder *folder = new FolioApplicationFolder(m_homeScreen, DEFAULT_FOLDER_NAME);
folder->addDelegate(delegate, 0);
folder->addDelegate(existingDelegate, 0);
FolioPageDelegate *folderDelegate = new FolioPageDelegate{row, column, folder, this};
FolioPageDelegate *folderDelegate = new FolioPageDelegate{row, column, folder, m_homeScreen};
page->removeDelegate(row, column);
page->addDelegate(folderDelegate);
@ -822,7 +825,7 @@ bool DragState::createDropPositionDelegate()
}
case DelegateDragPosition::Favourites: {
// delegate that exists at the drop position
FolioDelegate *existingDelegate = FavouritesModel::self()->getEntryAt(m_candidateDropPosition->favouritesPosition());
FolioDelegate *existingDelegate = m_homeScreen->favouritesModel()->getEntryAt(m_candidateDropPosition->favouritesPosition());
// if a delegate already exists at the spot, check if we can insert/create a folder
if (existingDelegate) {
@ -838,13 +841,13 @@ bool DragState::createDropPositionDelegate()
} else if (existingDelegate->type() == FolioDelegate::Application && !isStartPositionEqualDropPosition()) {
// create a folder from the two apps
FolioApplicationFolder *folder = new FolioApplicationFolder(this, DEFAULT_FOLDER_NAME);
FolioApplicationFolder *folder = new FolioApplicationFolder(m_homeScreen, DEFAULT_FOLDER_NAME);
folder->addDelegate(m_dropDelegate, 0);
folder->addDelegate(existingDelegate, 0);
FolioDelegate *folderDelegate = new FolioDelegate{folder, this};
FolioDelegate *folderDelegate = new FolioDelegate{folder, m_homeScreen};
FavouritesModel::self()->removeEntry(m_candidateDropPosition->favouritesPosition());
FavouritesModel::self()->addEntry(m_candidateDropPosition->favouritesPosition(), folderDelegate);
m_homeScreen->favouritesModel()->removeEntry(m_candidateDropPosition->favouritesPosition());
m_homeScreen->favouritesModel()->addEntry(m_candidateDropPosition->favouritesPosition(), folderDelegate);
added = true;
break;
@ -854,7 +857,7 @@ bool DragState::createDropPositionDelegate()
// otherwise, just add the delegate at this position
added = FavouritesModel::self()->addEntry(m_candidateDropPosition->favouritesPosition(), m_dropDelegate);
added = m_homeScreen->favouritesModel()->addEntry(m_candidateDropPosition->favouritesPosition(), m_dropDelegate);
// if we couldn't add the delegate, try again but at the start position
if (!added && !isStartPositionEqualDropPosition()) {
@ -902,8 +905,8 @@ bool DragState::createDropPositionDelegate()
}
// if we are dropping a new widget, we need to now create the applet in the containment
if (added && m_startPosition->location() == DelegateDragPosition::WidgetList && m_dropDelegate->type() == FolioDelegate::Widget && m_state->containment()) {
Plasma::Applet *applet = m_state->containment()->createApplet(m_createdAppletPluginId);
if (added && m_startPosition->location() == DelegateDragPosition::WidgetList && m_dropDelegate->type() == FolioDelegate::Widget && m_homeScreen) {
Plasma::Applet *applet = m_homeScreen->createApplet(m_createdAppletPluginId);
// associate the new delegate with the Plasma::Applet
m_dropDelegate->widget()->setApplet(applet);

View file

@ -8,8 +8,10 @@
#include "folioapplicationfolder.h"
#include "foliodelegate.h"
#include "homescreen.h"
#include "homescreenstate.h"
class HomeScreen;
class HomeScreenState;
class DelegateDragPosition : public QObject
@ -83,7 +85,7 @@ class DragState : public QObject
Q_PROPERTY(FolioDelegate *dropDelegate READ dropDelegate NOTIFY dropDelegateChanged)
public:
DragState(HomeScreenState *state = nullptr, QObject *parent = nullptr);
DragState(HomeScreenState *state = nullptr, HomeScreen *parent = nullptr);
DelegateDragPosition *candidateDropPosition() const;
DelegateDragPosition *startPosition() const;
@ -138,6 +140,9 @@ private:
qreal getPointerX();
qreal getPointerY();
HomeScreen *m_homeScreen{nullptr};
HomeScreenState *m_state{nullptr};
QTimer *m_changePageTimer{nullptr};
QTimer *m_openFolderTimer{nullptr};
QTimer *m_leaveFolderTimer{nullptr};
@ -162,6 +167,4 @@ private:
// when dropping a new widget, this is the applet name
QString m_createdAppletPluginId{};
HomeScreenState *m_state{nullptr};
};

View file

@ -20,31 +20,26 @@
#include <KSharedConfig>
#include <KSycoca>
FavouritesModel *FavouritesModel::self()
{
static FavouritesModel *inst = new FavouritesModel();
return inst;
}
FavouritesModel::FavouritesModel(QObject *parent)
FavouritesModel::FavouritesModel(HomeScreen *parent)
: QAbstractListModel{parent}
, m_homeScreen{parent}
{
connect(HomeScreenState::self(), &HomeScreenState::pageWidthChanged, this, [this]() {
connect(m_homeScreen->homeScreenState(), &HomeScreenState::pageWidthChanged, this, [this]() {
evaluateDelegatePositions(true);
});
connect(HomeScreenState::self(), &HomeScreenState::pageHeightChanged, this, [this]() {
connect(m_homeScreen->homeScreenState(), &HomeScreenState::pageHeightChanged, this, [this]() {
evaluateDelegatePositions(true);
});
connect(HomeScreenState::self(), &HomeScreenState::pageCellWidthChanged, this, [this]() {
connect(m_homeScreen->homeScreenState(), &HomeScreenState::pageCellWidthChanged, this, [this]() {
evaluateDelegatePositions(true);
});
connect(HomeScreenState::self(), &HomeScreenState::pageCellHeightChanged, this, [this]() {
connect(m_homeScreen->homeScreenState(), &HomeScreenState::pageCellHeightChanged, this, [this]() {
evaluateDelegatePositions(true);
});
connect(HomeScreenState::self(), &HomeScreenState::favouritesBarLocationChanged, this, [this]() {
connect(m_homeScreen->homeScreenState(), &HomeScreenState::favouritesBarLocationChanged, this, [this]() {
evaluateDelegatePositions(true);
});
connect(HomeScreenState::self(), &HomeScreenState::pageOrientationChanged, this, [this]() {
connect(m_homeScreen->homeScreenState(), &HomeScreenState::pageOrientationChanged, this, [this]() {
evaluateDelegatePositions(true);
});
}
@ -173,12 +168,13 @@ FolioDelegate *FavouritesModel::getEntryAt(int row)
bool FavouritesModel::isFull() const
{
bool isLocationBottom = HomeScreenState::self()->favouritesBarLocation() == HomeScreenState::Bottom;
auto homeScreenState = m_homeScreen->homeScreenState();
bool isLocationBottom = homeScreenState->favouritesBarLocation() == HomeScreenState::Bottom;
if (isLocationBottom) {
return m_delegates.size() >= HomeScreenState::self()->pageColumns();
return m_delegates.size() >= homeScreenState->pageColumns();
} else {
return m_delegates.size() >= HomeScreenState::self()->pageRows();
return m_delegates.size() >= homeScreenState->pageRows();
}
}
@ -209,7 +205,7 @@ void FavouritesModel::setGhostEntry(int row)
// if it doesn't, add a new empty delegate
if (!found) {
FolioDelegate *ghost = new FolioDelegate{this};
FolioDelegate *ghost = new FolioDelegate{m_homeScreen};
addEntry(row, ghost);
}
}
@ -218,6 +214,7 @@ void FavouritesModel::replaceGhostEntry(FolioDelegate *delegate)
{
for (int i = 0; i < m_delegates.size(); i++) {
if (m_delegates[i].delegate->type() == FolioDelegate::None) {
m_delegates[i].delegate->deleteLater();
m_delegates[i].delegate = delegate;
Q_EMIT dataChanged(createIndex(i, 0), createIndex(i, 0), {DelegateRole});
@ -230,7 +227,11 @@ void FavouritesModel::deleteGhostEntry()
{
for (int i = 0; i < m_delegates.size(); i++) {
if (m_delegates[i].delegate->type() == FolioDelegate::None) {
auto ghostEntry = m_delegates[i].delegate;
removeEntry(i);
// ensure ghost entry is deleted
ghostEntry->deleteLater();
}
}
}
@ -253,24 +254,24 @@ QJsonArray FavouritesModel::exportToJson()
void FavouritesModel::save()
{
if (!m_containment) {
if (!m_homeScreen) {
return;
}
QJsonArray arr = exportToJson();
QByteArray data = QJsonDocument(arr).toJson(QJsonDocument::Compact);
m_containment->config().writeEntry("Favourites", QString::fromStdString(data.toStdString()));
Q_EMIT m_containment->configNeedsSaving();
m_homeScreen->config().writeEntry("Favourites", QString::fromStdString(data.toStdString()));
Q_EMIT m_homeScreen->configNeedsSaving();
}
void FavouritesModel::load()
{
if (!m_containment) {
if (!m_homeScreen) {
return;
}
QJsonDocument doc = QJsonDocument::fromJson(m_containment->config().readEntry("Favourites", "{}").toUtf8());
QJsonDocument doc = QJsonDocument::fromJson(m_homeScreen->config().readEntry("Favourites", "{}").toUtf8());
loadFromJson(doc.array());
}
@ -282,7 +283,7 @@ void FavouritesModel::loadFromJson(QJsonArray arr)
for (QJsonValueRef r : arr) {
QJsonObject obj = r.toObject();
FolioDelegate *delegate = FolioDelegate::fromJson(obj, this);
FolioDelegate *delegate = FolioDelegate::fromJson(obj, m_homeScreen);
if (delegate) {
connectSaveRequests(delegate);
@ -301,16 +302,13 @@ void FavouritesModel::connectSaveRequests(FolioDelegate *delegate)
}
}
void FavouritesModel::setContainment(Plasma::Containment *containment)
{
m_containment = containment;
}
bool FavouritesModel::dropPositionIsEdge(qreal x, qreal y) const
{
auto homeScreenState = m_homeScreen->homeScreenState();
qreal startPosition = getDelegateRowStartPos();
bool isLocationBottom = HomeScreenState::self()->favouritesBarLocation() == HomeScreenState::Bottom;
qreal cellLength = isLocationBottom ? HomeScreenState::self()->pageCellWidth() : HomeScreenState::self()->pageCellHeight();
bool isLocationBottom = homeScreenState->favouritesBarLocation() == HomeScreenState::Bottom;
qreal cellLength = isLocationBottom ? homeScreenState->pageCellWidth() : homeScreenState->pageCellHeight();
qreal pos = isLocationBottom ? x : y;
@ -334,9 +332,11 @@ bool FavouritesModel::dropPositionIsEdge(qreal x, qreal y) const
int FavouritesModel::dropInsertPosition(qreal x, qreal y) const
{
auto homeScreenState = m_homeScreen->homeScreenState();
qreal startPosition = getDelegateRowStartPos();
bool isLocationBottom = HomeScreenState::self()->favouritesBarLocation() == HomeScreenState::Bottom;
qreal cellLength = isLocationBottom ? HomeScreenState::self()->pageCellWidth() : HomeScreenState::self()->pageCellHeight();
bool isLocationBottom = homeScreenState->favouritesBarLocation() == HomeScreenState::Bottom;
qreal cellLength = isLocationBottom ? homeScreenState->pageCellWidth() : homeScreenState->pageCellHeight();
qreal pos = isLocationBottom ? x : y;
@ -361,20 +361,21 @@ QPointF FavouritesModel::getDelegateScreenPosition(int position) const
{
position = adjustIndex(position);
qreal screenHeight = HomeScreenState::self()->viewHeight();
qreal screenWidth = HomeScreenState::self()->viewWidth();
qreal pageHeight = HomeScreenState::self()->pageHeight();
qreal pageWidth = HomeScreenState::self()->pageWidth();
qreal screenTopPadding = HomeScreenState::self()->viewTopPadding();
qreal screenBottomPadding = HomeScreenState::self()->viewBottomPadding();
qreal screenLeftPadding = HomeScreenState::self()->viewLeftPadding();
qreal screenRightPadding = HomeScreenState::self()->viewRightPadding();
qreal cellHeight = HomeScreenState::self()->pageCellHeight();
qreal cellWidth = HomeScreenState::self()->pageCellWidth();
auto homeScreenState = m_homeScreen->homeScreenState();
qreal screenHeight = homeScreenState->viewHeight();
qreal screenWidth = homeScreenState->viewWidth();
qreal pageHeight = homeScreenState->pageHeight();
qreal pageWidth = homeScreenState->pageWidth();
qreal screenTopPadding = homeScreenState->viewTopPadding();
qreal screenBottomPadding = homeScreenState->viewBottomPadding();
qreal screenLeftPadding = homeScreenState->viewLeftPadding();
qreal screenRightPadding = homeScreenState->viewRightPadding();
qreal cellHeight = homeScreenState->pageCellHeight();
qreal cellWidth = homeScreenState->pageCellWidth();
qreal startPosition = getDelegateRowStartPos();
switch (HomeScreenState::self()->favouritesBarLocation()) {
switch (homeScreenState->favouritesBarLocation()) {
case HomeScreenState::Bottom: {
qreal favouritesHeight = screenHeight - pageHeight - screenBottomPadding - screenTopPadding;
qreal x = screenLeftPadding + startPosition + cellWidth * position;
@ -399,8 +400,10 @@ QPointF FavouritesModel::getDelegateScreenPosition(int position) const
void FavouritesModel::evaluateDelegatePositions(bool emitSignal)
{
bool isLocationBottom = HomeScreenState::self()->favouritesBarLocation() == HomeScreenState::Bottom;
qreal cellLength = isLocationBottom ? HomeScreenState::self()->pageCellWidth() : HomeScreenState::self()->pageCellHeight();
auto homeScreenState = m_homeScreen->homeScreenState();
bool isLocationBottom = homeScreenState->favouritesBarLocation() == HomeScreenState::Bottom;
qreal cellLength = isLocationBottom ? homeScreenState->pageCellWidth() : homeScreenState->pageCellHeight();
qreal startPosition = getDelegateRowStartPos();
qreal currentPos = startPosition;
@ -416,13 +419,15 @@ void FavouritesModel::evaluateDelegatePositions(bool emitSignal)
qreal FavouritesModel::getDelegateRowStartPos() const
{
const int length = m_delegates.size();
const bool isLocationBottom = HomeScreenState::self()->favouritesBarLocation() == HomeScreenState::Bottom;
const qreal cellLength = isLocationBottom ? HomeScreenState::self()->pageCellWidth() : HomeScreenState::self()->pageCellHeight();
const qreal pageLength = isLocationBottom ? HomeScreenState::self()->pageWidth() : HomeScreenState::self()->pageHeight();
auto homeScreenState = m_homeScreen->homeScreenState();
const qreal topMargin = HomeScreenState::self()->viewTopPadding();
const qreal leftMargin = HomeScreenState::self()->viewLeftPadding();
const int length = m_delegates.size();
const bool isLocationBottom = homeScreenState->favouritesBarLocation() == HomeScreenState::Bottom;
const qreal cellLength = isLocationBottom ? homeScreenState->pageCellWidth() : homeScreenState->pageCellHeight();
const qreal pageLength = isLocationBottom ? homeScreenState->pageWidth() : homeScreenState->pageHeight();
const qreal topMargin = homeScreenState->viewTopPadding();
const qreal leftMargin = homeScreenState->viewLeftPadding();
const qreal panelOffset = isLocationBottom ? leftMargin : topMargin;
return (pageLength / 2) - (((qreal)length) / 2) * cellLength + panelOffset;
@ -430,8 +435,9 @@ qreal FavouritesModel::getDelegateRowStartPos() const
int FavouritesModel::adjustIndex(int index) const
{
if (HomeScreenState::self()->favouritesBarLocation() == HomeScreenState::Bottom
|| HomeScreenState::self()->favouritesBarLocation() == HomeScreenState::Left) {
auto homeScreenState = m_homeScreen->homeScreenState();
if (homeScreenState->favouritesBarLocation() == HomeScreenState::Bottom || homeScreenState->favouritesBarLocation() == HomeScreenState::Left) {
return index;
} else {
// if it's on the right side of the screen, we flip the order of the delegates

View file

@ -11,9 +11,13 @@
#include <QQuickItem>
#include <QSet>
#include <Plasma/Containment>
#include <Plasma/Applet>
#include "foliodelegate.h"
#include "homescreen.h"
class HomeScreen;
class FolioDelegate;
struct FavouritesDelegate {
FolioDelegate *delegate;
@ -30,8 +34,7 @@ public:
XPositionRole,
};
FavouritesModel(QObject *parent = nullptr);
static FavouritesModel *self();
FavouritesModel(HomeScreen *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
@ -68,8 +71,6 @@ public:
Q_INVOKABLE void load();
void loadFromJson(QJsonArray arr);
void setContainment(Plasma::Containment *containment);
private:
void connectSaveRequests(FolioDelegate *delegate);
void evaluateDelegatePositions(bool emitSignal = true);
@ -81,7 +82,7 @@ private:
// this is so that we only have to calculate positions assuming one orientation
int adjustIndex(int index) const;
QList<FavouritesDelegate> m_delegates;
HomeScreen *m_homeScreen{nullptr};
Plasma::Containment *m_containment{nullptr};
QList<FavouritesDelegate> m_delegates;
};

View file

@ -9,7 +9,7 @@
#include <KNotificationJobUiDelegate>
FolioApplication::FolioApplication(QObject *parent, KService::Ptr service)
FolioApplication::FolioApplication(HomeScreen *parent, KService::Ptr service)
: QObject{parent}
, m_running{false}
, m_name{service->name()}
@ -35,7 +35,7 @@ FolioApplication::FolioApplication(QObject *parent, KService::Ptr service)
});
}
FolioApplication *FolioApplication::fromJson(QJsonObject &obj, QObject *parent)
FolioApplication *FolioApplication::fromJson(QJsonObject &obj, HomeScreen *parent)
{
QString storageId = obj[QStringLiteral("storageId")].toString();
if (KService::Ptr service = KService::serviceByStorageId(storageId)) {

View file

@ -16,6 +16,10 @@
#include <KWayland/Client/registry.h>
#include <KWayland/Client/surface.h>
#include "homescreen.h"
class HomeScreen;
/**
* @short Object that represents an application.
*/
@ -28,9 +32,9 @@ class FolioApplication : public QObject
Q_PROPERTY(QString storageId READ storageId NOTIFY storageIdChanged)
public:
FolioApplication(QObject *parent = nullptr, KService::Ptr service = QExplicitlySharedDataPointer<KService>{nullptr});
FolioApplication(HomeScreen *parent = nullptr, KService::Ptr service = QExplicitlySharedDataPointer<KService>{nullptr});
static FolioApplication *fromJson(QJsonObject &obj, QObject *parent); // may return nullptr
static FolioApplication *fromJson(QJsonObject &obj, HomeScreen *parent); // may return nullptr
QJsonObject toJson() const;
bool running() const;

View file

@ -7,14 +7,15 @@
#include <QJsonArray>
#include <algorithm>
FolioApplicationFolder::FolioApplicationFolder(QObject *parent, QString name)
FolioApplicationFolder::FolioApplicationFolder(HomeScreen *parent, QString name)
: QObject{parent}
, m_homeScreen{parent}
, m_name{name}
, m_applicationFolderModel{new ApplicationFolderModel{this}}
{
}
FolioApplicationFolder *FolioApplicationFolder::fromJson(QJsonObject &obj, QObject *parent)
FolioApplicationFolder *FolioApplicationFolder::fromJson(QJsonObject &obj, HomeScreen *parent)
{
QString name = obj[QStringLiteral("name")].toString();
QList<FolioApplication *> apps;
@ -86,7 +87,7 @@ void FolioApplicationFolder::setApplications(QList<FolioApplication *> applicati
m_delegates.clear();
for (auto *app : applications) {
m_delegates.append({new FolioDelegate{app, this}, 0, 0});
m_delegates.append({new FolioDelegate{app, m_homeScreen}, 0, 0});
}
m_applicationFolderModel = new ApplicationFolderModel{this};
m_applicationFolderModel->evaluateDelegatePositions();
@ -125,28 +126,29 @@ ApplicationFolderModel::ApplicationFolderModel(FolioApplicationFolder *folder)
: QAbstractListModel{folder}
, m_folder{folder}
{
connect(HomeScreenState::self(), &HomeScreenState::folderPageWidthChanged, this, [this]() {
HomeScreenState *homeScreenState = folder->m_homeScreen->homeScreenState();
connect(homeScreenState, &HomeScreenState::folderPageWidthChanged, this, [this]() {
evaluateDelegatePositions();
});
connect(HomeScreenState::self(), &HomeScreenState::folderPageHeightChanged, this, [this]() {
connect(homeScreenState, &HomeScreenState::folderPageHeightChanged, this, [this]() {
evaluateDelegatePositions();
});
connect(HomeScreenState::self(), &HomeScreenState::folderPageContentWidthChanged, this, [this]() {
connect(homeScreenState, &HomeScreenState::folderPageContentWidthChanged, this, [this]() {
evaluateDelegatePositions();
});
connect(HomeScreenState::self(), &HomeScreenState::folderPageContentHeightChanged, this, [this]() {
connect(homeScreenState, &HomeScreenState::folderPageContentHeightChanged, this, [this]() {
evaluateDelegatePositions();
});
connect(HomeScreenState::self(), &HomeScreenState::viewWidthChanged, this, [this]() {
connect(homeScreenState, &HomeScreenState::viewWidthChanged, this, [this]() {
evaluateDelegatePositions();
});
connect(HomeScreenState::self(), &HomeScreenState::viewHeightChanged, this, [this]() {
connect(homeScreenState, &HomeScreenState::viewHeightChanged, this, [this]() {
evaluateDelegatePositions();
});
connect(HomeScreenState::self(), &HomeScreenState::pageCellWidthChanged, this, [this]() {
connect(homeScreenState, &HomeScreenState::pageCellWidthChanged, this, [this]() {
evaluateDelegatePositions();
});
connect(HomeScreenState::self(), &HomeScreenState::pageCellHeightChanged, this, [this]() {
connect(homeScreenState, &HomeScreenState::pageCellHeightChanged, this, [this]() {
evaluateDelegatePositions();
});
}
@ -312,7 +314,7 @@ void ApplicationFolderModel::setGhostEntry(int index)
}
if (!ghost) {
ghost = new FolioDelegate{HomeScreenState::self()};
ghost = new FolioDelegate{m_folder->m_homeScreen};
}
// add empty delegate at new position
@ -342,8 +344,8 @@ void ApplicationFolderModel::deleteGhostEntry()
int ApplicationFolderModel::dropInsertPosition(int page, qreal x, qreal y)
{
qreal cellWidth = HomeScreenState::self()->pageCellWidth();
qreal cellHeight = HomeScreenState::self()->pageCellHeight();
qreal cellWidth = m_folder->m_homeScreen->homeScreenState()->pageCellWidth();
qreal cellHeight = m_folder->m_homeScreen->homeScreenState()->pageCellHeight();
int row = (y - topMarginFromScreenEdge()) / cellHeight;
row = std::max(0, std::min(numRowsOnPage(), row));
@ -369,18 +371,18 @@ int ApplicationFolderModel::dropInsertPosition(int page, qreal x, qreal y)
bool ApplicationFolderModel::isDropPositionOutside(qreal x, qreal y)
{
return (x < leftMarginFromScreenEdge()) || (x > (HomeScreenState::self()->viewWidth() - leftMarginFromScreenEdge())) || (y < topMarginFromScreenEdge())
|| (y > HomeScreenState::self()->viewHeight() - topMarginFromScreenEdge());
return (x < leftMarginFromScreenEdge()) || (x > (m_folder->m_homeScreen->homeScreenState()->viewWidth() - leftMarginFromScreenEdge()))
|| (y < topMarginFromScreenEdge()) || (y > m_folder->m_homeScreen->homeScreenState()->viewHeight() - topMarginFromScreenEdge());
}
void ApplicationFolderModel::evaluateDelegatePositions(bool emitSignal)
{
qreal pageWidth = HomeScreenState::self()->folderPageWidth();
qreal pageWidth = m_folder->m_homeScreen->homeScreenState()->folderPageWidth();
qreal topMargin = verticalPageMargin();
qreal leftMargin = horizontalPageMargin();
qreal cellWidth = HomeScreenState::self()->pageCellWidth();
qreal cellHeight = HomeScreenState::self()->pageCellHeight();
qreal cellWidth = m_folder->m_homeScreen->homeScreenState()->pageCellWidth();
qreal cellHeight = m_folder->m_homeScreen->homeScreenState()->pageCellHeight();
int rows = numRowsOnPage();
int columns = numColumnsOnPage();
@ -418,7 +420,7 @@ void ApplicationFolderModel::evaluateDelegatePositions(bool emitSignal)
QPointF ApplicationFolderModel::getDelegateStartPosition(int page)
{
qreal pageWidth = HomeScreenState::self()->folderPageWidth();
qreal pageWidth = m_folder->m_homeScreen->homeScreenState()->folderPageWidth();
qreal x = pageWidth * page + leftMarginFromScreenEdge();
qreal y = topMarginFromScreenEdge();
@ -433,48 +435,54 @@ int ApplicationFolderModel::numTotalPages()
int ApplicationFolderModel::numRowsOnPage()
{
qreal contentHeight = HomeScreenState::self()->folderPageContentHeight();
qreal cellHeight = HomeScreenState::self()->pageCellHeight();
HomeScreenState *homeScreenState = m_folder->m_homeScreen->homeScreenState();
qreal contentHeight = homeScreenState->folderPageContentHeight();
qreal cellHeight = homeScreenState->pageCellHeight();
return std::max(0.0, contentHeight / cellHeight);
}
int ApplicationFolderModel::numColumnsOnPage()
{
qreal contentWidth = HomeScreenState::self()->folderPageContentWidth();
qreal cellWidth = HomeScreenState::self()->pageCellWidth();
HomeScreenState *homeScreenState = m_folder->m_homeScreen->homeScreenState();
qreal contentWidth = homeScreenState->folderPageContentWidth();
qreal cellWidth = homeScreenState->pageCellWidth();
return std::max(0.0, contentWidth / cellWidth);
}
qreal ApplicationFolderModel::leftMarginFromScreenEdge()
{
qreal viewWidth = HomeScreenState::self()->viewWidth();
qreal folderPageWidth = HomeScreenState::self()->folderPageWidth();
HomeScreenState *homeScreenState = m_folder->m_homeScreen->homeScreenState();
qreal viewWidth = homeScreenState->viewWidth();
qreal folderPageWidth = homeScreenState->folderPageWidth();
return (viewWidth - folderPageWidth) / 2 + horizontalPageMargin();
}
qreal ApplicationFolderModel::topMarginFromScreenEdge()
{
qreal viewHeight = HomeScreenState::self()->viewHeight();
qreal folderPageHeight = HomeScreenState::self()->folderPageHeight();
HomeScreenState *homeScreenState = m_folder->m_homeScreen->homeScreenState();
qreal viewHeight = homeScreenState->viewHeight();
qreal folderPageHeight = homeScreenState->folderPageHeight();
return (viewHeight - folderPageHeight) / 2 + verticalPageMargin();
}
qreal ApplicationFolderModel::horizontalPageMargin()
{
qreal pageWidth = HomeScreenState::self()->folderPageWidth();
qreal pageContentWidth = HomeScreenState::self()->folderPageContentWidth();
HomeScreenState *homeScreenState = m_folder->m_homeScreen->homeScreenState();
qreal pageWidth = homeScreenState->folderPageWidth();
qreal pageContentWidth = homeScreenState->folderPageContentWidth();
return (pageWidth - pageContentWidth) / 2;
}
qreal ApplicationFolderModel::verticalPageMargin()
{
qreal pageHeight = HomeScreenState::self()->folderPageHeight();
qreal pageContentHeight = HomeScreenState::self()->folderPageContentHeight();
HomeScreenState *homeScreenState = m_folder->m_homeScreen->homeScreenState();
qreal pageHeight = homeScreenState->folderPageHeight();
qreal pageContentHeight = homeScreenState->folderPageContentHeight();
return (pageHeight - pageContentHeight) / 2;
}

View file

@ -5,6 +5,7 @@
#include "folioapplication.h"
#include "foliodelegate.h"
#include "homescreen.h"
#include <QAbstractListModel>
#include <QObject>
@ -17,9 +18,11 @@
#include <KWayland/Client/registry.h>
#include <KWayland/Client/surface.h>
class HomeScreen;
struct ApplicationDelegate;
class ApplicationFolderModel;
class FolioDelegate;
class FolioApplication;
/**
* @short Object that represents an application folder.
@ -33,9 +36,9 @@ class FolioApplicationFolder : public QObject
Q_PROPERTY(ApplicationFolderModel *applications READ applications NOTIFY applicationsReset)
public:
FolioApplicationFolder(QObject *parent = nullptr, QString name = QString{});
FolioApplicationFolder(HomeScreen *parent = nullptr, QString name = QString{});
static FolioApplicationFolder *fromJson(QJsonObject &obj, QObject *parent);
static FolioApplicationFolder *fromJson(QJsonObject &obj, HomeScreen *parent);
QJsonObject toJson() const;
QString name() const;
@ -60,9 +63,11 @@ Q_SIGNALS:
void applicationsReset();
private:
HomeScreen *m_homeScreen{nullptr};
QString m_name;
QList<ApplicationDelegate> m_delegates;
ApplicationFolderModel *m_applicationFolderModel;
ApplicationFolderModel *m_applicationFolderModel{nullptr};
friend class ApplicationFolderModel;
};

View file

@ -4,7 +4,7 @@
#include "foliodelegate.h"
#include "homescreenstate.h"
FolioDelegate::FolioDelegate(QObject *parent)
FolioDelegate::FolioDelegate(HomeScreen *parent)
: QObject{parent}
, m_type{FolioDelegate::None}
, m_application{nullptr}
@ -13,7 +13,7 @@ FolioDelegate::FolioDelegate(QObject *parent)
{
}
FolioDelegate::FolioDelegate(FolioApplication *application, QObject *parent)
FolioDelegate::FolioDelegate(FolioApplication *application, HomeScreen *parent)
: QObject{parent}
, m_type{FolioDelegate::Application}
, m_application{application}
@ -22,7 +22,7 @@ FolioDelegate::FolioDelegate(FolioApplication *application, QObject *parent)
{
}
FolioDelegate::FolioDelegate(FolioApplicationFolder *folder, QObject *parent)
FolioDelegate::FolioDelegate(FolioApplicationFolder *folder, HomeScreen *parent)
: QObject{parent}
, m_type{FolioDelegate::Folder}
, m_application{nullptr}
@ -31,7 +31,7 @@ FolioDelegate::FolioDelegate(FolioApplicationFolder *folder, QObject *parent)
{
}
FolioDelegate::FolioDelegate(FolioWidget *widget, QObject *parent)
FolioDelegate::FolioDelegate(FolioWidget *widget, HomeScreen *parent)
: QObject{parent}
, m_type{FolioDelegate::Widget}
, m_application{nullptr}
@ -40,7 +40,7 @@ FolioDelegate::FolioDelegate(FolioWidget *widget, QObject *parent)
{
}
FolioDelegate *FolioDelegate::fromJson(QJsonObject &obj, QObject *parent)
FolioDelegate *FolioDelegate::fromJson(QJsonObject &obj, HomeScreen *parent)
{
const QString type = obj[QStringLiteral("type")].toString();
if (type == "application") {
@ -112,3 +112,277 @@ FolioWidget *FolioDelegate::widget()
{
return m_widget;
}
FolioPageDelegate::FolioPageDelegate(int row, int column, HomeScreen *parent)
: FolioDelegate{parent}
, m_homeScreen{parent}
, m_row{row}
, m_column{column}
{
init();
}
FolioPageDelegate::FolioPageDelegate(int row, int column, FolioApplication *application, HomeScreen *parent)
: FolioDelegate{application, parent}
, m_homeScreen{parent}
, m_row{row}
, m_column{column}
{
init();
}
FolioPageDelegate::FolioPageDelegate(int row, int column, FolioApplicationFolder *folder, HomeScreen *parent)
: FolioDelegate{folder, parent}
, m_homeScreen{parent}
, m_row{row}
, m_column{column}
{
init();
}
FolioPageDelegate::FolioPageDelegate(int row, int column, FolioWidget *widget, HomeScreen *parent)
: FolioDelegate{widget, parent}
, m_homeScreen{parent}
, m_row{row}
, m_column{column}
{
init();
}
FolioPageDelegate::FolioPageDelegate(int row, int column, FolioDelegate *delegate, HomeScreen *parent)
: FolioDelegate{parent}
, m_homeScreen{parent}
, m_row{row}
, m_column{column}
{
m_type = delegate->type();
m_application = delegate->application();
m_folder = delegate->folder();
m_widget = delegate->widget();
init();
}
void FolioPageDelegate::init()
{
HomeScreenState *homeScreenState = m_homeScreen->homeScreenState();
// we have to use the "real" rows and columns, so fetch them from FolioSettings instead of HomeScreenState
switch (homeScreenState->pageOrientation()) {
case HomeScreenState::RegularPosition:
m_realRow = m_row;
m_realColumn = m_column;
break;
case HomeScreenState::RotateClockwise:
m_realRow = homeScreenState->pageColumns() - m_column - 1;
m_realColumn = m_row;
if (m_widget) {
// since top-left in cw is bottom-left in portrait
m_realRow -= m_widget->realGridHeight() - 1;
}
break;
case HomeScreenState::RotateCounterClockwise:
m_realRow = m_column;
m_realColumn = homeScreenState->pageRows() - m_row - 1;
if (m_widget) {
// since top-left in ccw is top-right in portrait
m_realColumn -= m_widget->realGridWidth() - 1;
}
break;
case HomeScreenState::RotateUpsideDown:
m_realRow = homeScreenState->pageRows() - m_row - 1;
m_realColumn = homeScreenState->pageColumns() - m_column - 1;
if (m_widget) {
// since top-left in upside-down is bottom-right in portrait
m_realRow -= m_widget->realGridHeight() - 1;
m_realColumn -= m_widget->realGridWidth() - 1;
}
break;
}
if (m_widget) {
connect(m_widget, &FolioWidget::realTopLeftPositionChanged, this, [this](int rowOffset, int columnOffset) {
m_realRow += rowOffset;
m_realColumn += columnOffset;
});
}
connect(homeScreenState, &HomeScreenState::pageOrientationChanged, this, [this]() {
setRowOnly(getTranslatedTopLeftRow(m_homeScreen, m_realRow, m_realColumn, this));
setColumnOnly(getTranslatedTopLeftColumn(m_homeScreen, m_realRow, m_realColumn, this));
});
}
FolioPageDelegate *FolioPageDelegate::fromJson(QJsonObject &obj, HomeScreen *parent)
{
FolioDelegate *fd = FolioDelegate::fromJson(obj, parent);
if (!fd) {
return nullptr;
}
int realRow = obj[QStringLiteral("row")].toInt();
int realColumn = obj[QStringLiteral("column")].toInt();
int row = getTranslatedTopLeftRow(parent, realRow, realColumn, fd);
int column = getTranslatedTopLeftColumn(parent, realRow, realColumn, fd);
FolioPageDelegate *delegate = new FolioPageDelegate{row, column, fd, parent};
fd->deleteLater();
return delegate;
}
int FolioPageDelegate::getTranslatedTopLeftRow(HomeScreen *homeScreen, int realRow, int realColumn, FolioDelegate *fd)
{
int row = getTranslatedRow(homeScreen, realRow, realColumn);
int column = getTranslatedColumn(homeScreen, realRow, realColumn);
// special logic to return "top left" for widgets, since they take more than one tile
if (fd->type() == FolioDelegate::Widget) {
return fd->widget()->topLeftCorner(row, column).row;
} else {
return row;
}
}
int FolioPageDelegate::getTranslatedTopLeftColumn(HomeScreen *homeScreen, int realRow, int realColumn, FolioDelegate *fd)
{
int row = getTranslatedRow(homeScreen, realRow, realColumn);
int column = getTranslatedColumn(homeScreen, realRow, realColumn);
// special logic to return "top left" for widgets, since they take more than one tile
if (fd->type() == FolioDelegate::Widget) {
return fd->widget()->topLeftCorner(row, column).column;
} else {
return column;
}
}
int FolioPageDelegate::getTranslatedRow(HomeScreen *homeScreen, int realRow, int realColumn)
{
HomeScreenState *homeScreenState = homeScreen->homeScreenState();
FolioSettings *folioSettings = homeScreen->folioSettings();
// we have to use the "real" rows and columns, so fetch them from FolioSettings instead of HomeScreenState
switch (homeScreenState->pageOrientation()) {
case HomeScreenState::RegularPosition:
return realRow;
case HomeScreenState::RotateClockwise:
return realColumn;
case HomeScreenState::RotateCounterClockwise:
return folioSettings->homeScreenColumns() - realColumn - 1;
case HomeScreenState::RotateUpsideDown:
return folioSettings->homeScreenRows() - realRow - 1;
}
return realRow;
}
int FolioPageDelegate::getTranslatedColumn(HomeScreen *homeScreen, int realRow, int realColumn)
{
HomeScreenState *homeScreenState = homeScreen->homeScreenState();
FolioSettings *folioSettings = homeScreen->folioSettings();
// we have to use the "real" rows and columns, so fetch them from FolioSettings instead of HomeScreenState
switch (homeScreenState->pageOrientation()) {
case HomeScreenState::RegularPosition:
return realColumn;
case HomeScreenState::RotateClockwise:
return folioSettings->homeScreenRows() - realRow - 1;
case HomeScreenState::RotateCounterClockwise:
return realRow;
case HomeScreenState::RotateUpsideDown:
return folioSettings->homeScreenColumns() - realColumn - 1;
}
return realRow;
}
QJsonObject FolioPageDelegate::toJson() const
{
QJsonObject o = FolioDelegate::toJson();
o[QStringLiteral("row")] = m_realRow;
o[QStringLiteral("column")] = m_realColumn;
return o;
}
int FolioPageDelegate::row()
{
return m_row;
}
void FolioPageDelegate::setRow(int row)
{
HomeScreenState *homeScreenState = m_homeScreen->homeScreenState();
if (m_row != row) {
// adjust stored data too
switch (homeScreenState->pageOrientation()) {
case HomeScreenState::RegularPosition:
m_realRow = row;
break;
case HomeScreenState::RotateClockwise:
m_realColumn += row - m_row;
break;
case HomeScreenState::RotateCounterClockwise:
m_realColumn += m_row - row;
break;
case HomeScreenState::RotateUpsideDown:
m_realRow += m_row - row;
break;
}
setRowOnly(row);
}
}
void FolioPageDelegate::setRowOnly(int row)
{
if (m_row != row) {
m_row = row;
Q_EMIT rowChanged();
}
}
int FolioPageDelegate::column()
{
return m_column;
}
void FolioPageDelegate::setColumn(int column)
{
HomeScreenState *homeScreenState = m_homeScreen->homeScreenState();
if (m_column != column) {
// adjust stored data too
switch (homeScreenState->pageOrientation()) {
case HomeScreenState::RegularPosition:
m_realColumn = column;
break;
case HomeScreenState::RotateClockwise:
m_realRow += m_column - column;
break;
case HomeScreenState::RotateCounterClockwise:
m_realRow += column - m_column;
break;
case HomeScreenState::RotateUpsideDown:
m_realColumn += m_column - column;
break;
}
setColumnOnly(column);
}
}
void FolioPageDelegate::setColumnOnly(int column)
{
if (m_column != column) {
m_column = column;
Q_EMIT columnChanged();
}
}

View file

@ -8,9 +8,13 @@
#include "folioapplication.h"
#include "folioapplicationfolder.h"
#include "foliowidget.h"
#include "homescreen.h"
class HomeScreen;
class FolioApplication;
class FolioApplicationFolder;
class FolioWidget;
class FolioDelegate : public QObject
{
Q_OBJECT
@ -28,12 +32,12 @@ public:
};
Q_ENUM(Type)
FolioDelegate(QObject *parent = nullptr);
FolioDelegate(FolioApplication *application, QObject *parent);
FolioDelegate(FolioApplicationFolder *folder, QObject *parent);
FolioDelegate(FolioWidget *widget, QObject *parent);
FolioDelegate(HomeScreen *parent = nullptr);
FolioDelegate(FolioApplication *application, HomeScreen *parent);
FolioDelegate(FolioApplicationFolder *folder, HomeScreen *parent);
FolioDelegate(FolioWidget *widget, HomeScreen *parent);
static FolioDelegate *fromJson(QJsonObject &obj, QObject *parent);
static FolioDelegate *fromJson(QJsonObject &obj, HomeScreen *parent);
virtual QJsonObject toJson() const;
@ -48,3 +52,48 @@ protected:
FolioApplicationFolder *m_folder{nullptr};
FolioWidget *m_widget{nullptr};
};
class FolioPageDelegate : public FolioDelegate
{
Q_OBJECT
Q_PROPERTY(int row READ row NOTIFY rowChanged)
Q_PROPERTY(int column READ column NOTIFY columnChanged)
QML_UNCREATABLE("")
public:
FolioPageDelegate(int row = 0, int column = 0, HomeScreen *parent = nullptr);
FolioPageDelegate(int row, int column, FolioApplication *application, HomeScreen *parent);
FolioPageDelegate(int row, int column, FolioApplicationFolder *folder, HomeScreen *parent);
FolioPageDelegate(int row, int column, FolioWidget *widget, HomeScreen *parent);
FolioPageDelegate(int row, int column, FolioDelegate *delegate, HomeScreen *parent);
static FolioPageDelegate *fromJson(QJsonObject &obj, HomeScreen *parent);
static int getTranslatedTopLeftRow(HomeScreen *homeScreen, int realRow, int realColumn, FolioDelegate *fd);
static int getTranslatedTopLeftColumn(HomeScreen *homeScreen, int realRow, int realColumn, FolioDelegate *fd);
static int getTranslatedRow(HomeScreen *homeScreen, int realRow, int realColumn);
static int getTranslatedColumn(HomeScreen *homeScreen, int realRow, int realColumn);
virtual QJsonObject toJson() const override;
int row();
void setRow(int row);
int column();
void setColumn(int column);
Q_SIGNALS:
void rowChanged();
void columnChanged();
private:
void setRowOnly(int row);
void setColumnOnly(int column);
void init();
HomeScreen *m_homeScreen{nullptr};
int m_realRow;
int m_realColumn;
int m_row;
int m_column;
};

View file

@ -10,17 +10,12 @@
#include <QJsonDocument>
#include <QTextStream>
FolioSettings::FolioSettings(QObject *parent)
FolioSettings::FolioSettings(HomeScreen *parent)
: QObject{parent}
, m_homeScreen{parent}
{
}
FolioSettings *FolioSettings::self()
{
static FolioSettings *settings = new FolioSettings;
return settings;
}
int FolioSettings::homeScreenRows() const
{
// ensure that this is fetched fast and cached (it is called extremely often)
@ -134,43 +129,38 @@ void FolioSettings::setShowWallpaperBlur(bool showWallpaperBlur)
}
}
void FolioSettings::setApplet(Plasma::Applet *applet)
{
m_applet = applet;
}
void FolioSettings::save()
{
if (!m_applet) {
if (!m_homeScreen) {
return;
}
m_applet->config().writeEntry("homeScreenRows", m_homeScreenRows);
m_applet->config().writeEntry("homeScreenColumns", m_homeScreenColumns);
m_applet->config().writeEntry("showPagesAppLabels", m_showPagesAppLabels);
m_applet->config().writeEntry("showFavouritesAppLabels", m_showFavouritesAppLabels);
m_applet->config().writeEntry("delegateIconSize", m_delegateIconSize);
m_applet->config().writeEntry("showFavouritesBarBackground", m_showFavouritesBarBackground);
m_applet->config().writeEntry("pageTransitionEffect", (int)m_pageTransitionEffect);
m_applet->config().writeEntry("showWallpaperBlur", m_showWallpaperBlur);
m_homeScreen->config().writeEntry("homeScreenRows", m_homeScreenRows);
m_homeScreen->config().writeEntry("homeScreenColumns", m_homeScreenColumns);
m_homeScreen->config().writeEntry("showPagesAppLabels", m_showPagesAppLabels);
m_homeScreen->config().writeEntry("showFavouritesAppLabels", m_showFavouritesAppLabels);
m_homeScreen->config().writeEntry("delegateIconSize", m_delegateIconSize);
m_homeScreen->config().writeEntry("showFavouritesBarBackground", m_showFavouritesBarBackground);
m_homeScreen->config().writeEntry("pageTransitionEffect", (int)m_pageTransitionEffect);
m_homeScreen->config().writeEntry("showWallpaperBlur", m_showWallpaperBlur);
Q_EMIT m_applet->configNeedsSaving();
Q_EMIT m_homeScreen->configNeedsSaving();
}
void FolioSettings::load()
{
if (!m_applet) {
if (!m_homeScreen) {
return;
}
m_homeScreenRows = m_applet->config().readEntry("homeScreenRows", 5);
m_homeScreenColumns = m_applet->config().readEntry("homeScreenColumns", 4);
m_showPagesAppLabels = m_applet->config().readEntry("showPagesAppLabels", true);
m_showFavouritesAppLabels = m_applet->config().readEntry("showFavoritesAppLabels", false);
m_delegateIconSize = m_applet->config().readEntry("delegateIconSize", 48);
m_showFavouritesBarBackground = m_applet->config().readEntry("showFavoritesBarBackground", true);
m_pageTransitionEffect = static_cast<PageTransitionEffect>(m_applet->config().readEntry("pageTransitionEffect", (int)SlideTransition));
m_showWallpaperBlur = m_applet->config().readEntry("showWallpaperBlur", true);
m_homeScreenRows = m_homeScreen->config().readEntry("homeScreenRows", 5);
m_homeScreenColumns = m_homeScreen->config().readEntry("homeScreenColumns", 4);
m_showPagesAppLabels = m_homeScreen->config().readEntry("showPagesAppLabels", true);
m_showFavouritesAppLabels = m_homeScreen->config().readEntry("showFavoritesAppLabels", false);
m_delegateIconSize = m_homeScreen->config().readEntry("delegateIconSize", 48);
m_showFavouritesBarBackground = m_homeScreen->config().readEntry("showFavoritesBarBackground", true);
m_pageTransitionEffect = static_cast<PageTransitionEffect>(m_homeScreen->config().readEntry("pageTransitionEffect", (int)SlideTransition));
m_showWallpaperBlur = m_homeScreen->config().readEntry("showWallpaperBlur", true);
Q_EMIT homeScreenRowsChanged();
Q_EMIT homeScreenColumnsChanged();
@ -182,12 +172,16 @@ void FolioSettings::load()
bool FolioSettings::saveLayoutToFile(QString path)
{
if (!m_homeScreen) {
return false;
}
if (path.startsWith(QStringLiteral("file://"))) {
path = path.replace(QStringLiteral("file://"), QString());
}
QJsonArray favourites = FavouritesModel::self()->exportToJson();
QJsonArray pages = PageListModel::self()->exportToJson();
QJsonArray favourites = m_homeScreen->favouritesModel()->exportToJson();
QJsonArray pages = m_homeScreen->pageListModel()->exportToJson();
QJsonObject obj;
obj[QStringLiteral("Favourites")] = favourites;
@ -209,6 +203,10 @@ bool FolioSettings::saveLayoutToFile(QString path)
bool FolioSettings::loadLayoutFromFile(QString path)
{
if (!m_homeScreen) {
return false;
}
if (path.startsWith(QStringLiteral("file://"))) {
path = path.replace(QStringLiteral("file://"), QString());
}
@ -227,11 +225,11 @@ bool FolioSettings::loadLayoutFromFile(QString path)
QJsonObject obj = doc.object();
// TODO error checking
FavouritesModel::self()->loadFromJson(obj[QStringLiteral("Favourites")].toArray());
PageListModel::self()->loadFromJson(obj[QStringLiteral("Pages")].toArray());
m_homeScreen->favouritesModel()->loadFromJson(obj[QStringLiteral("Favourites")].toArray());
m_homeScreen->pageListModel()->loadFromJson(obj[QStringLiteral("Pages")].toArray());
FavouritesModel::self()->save();
PageListModel::self()->save();
m_homeScreen->favouritesModel()->save();
m_homeScreen->pageListModel()->save();
return true;
}

View file

@ -7,6 +7,10 @@
#include <Plasma/Applet>
#include "homescreen.h"
class HomeScreen;
class FolioSettings : public QObject
{
Q_OBJECT
@ -21,9 +25,7 @@ class FolioSettings : public QObject
Q_PROPERTY(bool showWallpaperBlur READ showWallpaperBlur WRITE setShowWallpaperBlur NOTIFY showWallpaperBlurChanged)
public:
FolioSettings(QObject *parent = nullptr);
static FolioSettings *self();
FolioSettings(HomeScreen *parent = nullptr);
// ensure that existing enum values are the same when modifying, since this value is saved
enum PageTransitionEffect {
@ -67,8 +69,6 @@ public:
Q_INVOKABLE bool saveLayoutToFile(QString path);
Q_INVOKABLE bool loadLayoutFromFile(QString path);
Q_INVOKABLE void setApplet(Plasma::Applet *applet);
Q_SIGNALS:
void homeScreenRowsChanged();
void homeScreenColumnsChanged();
@ -82,6 +82,8 @@ Q_SIGNALS:
private:
void save();
HomeScreen *m_homeScreen{nullptr};
int m_homeScreenRows{5};
int m_homeScreenColumns{4};
bool m_showPagesAppLabels{false};
@ -90,6 +92,4 @@ private:
bool m_showFavouritesBarBackground{false};
PageTransitionEffect m_pageTransitionEffect{SlideTransition};
bool m_showWallpaperBlur{false};
Plasma::Applet *m_applet{nullptr};
};

View file

@ -5,23 +5,25 @@
#include "homescreenstate.h"
#include "widgetsmanager.h"
FolioWidget::FolioWidget(QObject *parent, int id, int realGridWidth, int realGridHeight)
FolioWidget::FolioWidget(HomeScreen *parent, int id, int realGridWidth, int realGridHeight)
: QObject{parent}
, m_homeScreen{parent}
, m_id{id}
, m_realGridWidth{realGridWidth}
, m_realGridHeight{realGridHeight}
, m_applet{nullptr}
, m_quickApplet{nullptr}
{
auto *applet = WidgetsManager::self()->getWidget(id);
auto *applet = m_homeScreen->widgetsManager()->getWidget(id);
if (applet) {
setApplet(applet);
}
init();
}
FolioWidget::FolioWidget(QObject *parent, Plasma::Applet *applet, int realGridWidth, int realGridHeight)
FolioWidget::FolioWidget(HomeScreen *parent, Plasma::Applet *applet, int realGridWidth, int realGridHeight)
: QObject{parent}
, m_homeScreen{parent}
, m_id{applet ? static_cast<int>(applet->id()) : -1}
, m_realGridWidth{realGridWidth}
, m_realGridHeight{realGridHeight}
@ -32,24 +34,24 @@ FolioWidget::FolioWidget(QObject *parent, Plasma::Applet *applet, int realGridWi
void FolioWidget::init()
{
connect(HomeScreenState::self(), &HomeScreenState::pageOrientationChanged, this, [this]() {
connect(m_homeScreen->homeScreenState(), &HomeScreenState::pageOrientationChanged, this, [this]() {
Q_EMIT gridWidthChanged();
Q_EMIT gridHeightChanged();
});
connect(WidgetsManager::self(), &WidgetsManager::widgetAdded, this, [this](Plasma::Applet *applet) {
connect(m_homeScreen->widgetsManager(), &WidgetsManager::widgetAdded, this, [this](Plasma::Applet *applet) {
if (applet && static_cast<int>(applet->id()) == m_id) {
setApplet(applet);
}
});
connect(WidgetsManager::self(), &WidgetsManager::widgetRemoved, this, [this](Plasma::Applet *applet) {
connect(m_homeScreen->widgetsManager(), &WidgetsManager::widgetRemoved, this, [this](Plasma::Applet *applet) {
if (applet && static_cast<int>(applet->id()) == m_id) {
setApplet(nullptr);
}
});
}
FolioWidget *FolioWidget::fromJson(QJsonObject &obj, QObject *parent)
FolioWidget *FolioWidget::fromJson(QJsonObject &obj, HomeScreen *parent)
{
int id = obj[QStringLiteral("id")].toInt();
int gridWidth = obj[QStringLiteral("gridWidth")].toInt();
@ -74,7 +76,7 @@ int FolioWidget::id() const
int FolioWidget::gridWidth() const
{
switch (HomeScreenState::self()->pageOrientation()) {
switch (m_homeScreen->homeScreenState()->pageOrientation()) {
case HomeScreenState::RegularPosition:
return m_realGridWidth;
case HomeScreenState::RotateClockwise:
@ -89,7 +91,7 @@ int FolioWidget::gridWidth() const
void FolioWidget::setGridWidth(int gridWidth)
{
switch (HomeScreenState::self()->pageOrientation()) {
switch (m_homeScreen->homeScreenState()->pageOrientation()) {
case HomeScreenState::RegularPosition:
setRealGridWidth(gridWidth);
break;
@ -113,7 +115,7 @@ void FolioWidget::setGridWidth(int gridWidth)
int FolioWidget::gridHeight() const
{
switch (HomeScreenState::self()->pageOrientation()) {
switch (m_homeScreen->homeScreenState()->pageOrientation()) {
case HomeScreenState::RegularPosition:
return m_realGridHeight;
case HomeScreenState::RotateClockwise:
@ -128,7 +130,7 @@ int FolioWidget::gridHeight() const
void FolioWidget::setGridHeight(int gridHeight)
{
switch (HomeScreenState::self()->pageOrientation()) {
switch (m_homeScreen->homeScreenState()->pageOrientation()) {
case HomeScreenState::RegularPosition:
setRealGridHeight(gridHeight);
break;
@ -188,7 +190,7 @@ void FolioWidget::setRealGridHeight(int gridHeight)
GridPosition FolioWidget::topLeftCorner(int row, int column)
{
switch (HomeScreenState::self()->pageOrientation()) {
switch (m_homeScreen->homeScreenState()->pageOrientation()) {
case HomeScreenState::RegularPosition:
return {row, column};
case HomeScreenState::RotateClockwise:

View file

@ -3,11 +3,15 @@
#pragma once
#include "homescreen.h"
#include <QObject>
#include <Plasma/Applet>
#include <PlasmaQuick/AppletQuickItem>
class HomeScreen;
struct GridPosition {
Q_GADGET
public:
@ -28,10 +32,10 @@ class FolioWidget : public QObject
Q_PROPERTY(PlasmaQuick::AppletQuickItem *visualApplet READ visualApplet NOTIFY visualAppletChanged)
public:
FolioWidget(QObject *parent = nullptr, int id = -1, int gridWidth = 0, int gridHeight = 0);
FolioWidget(QObject *parent, Plasma::Applet *applet, int gridWidth, int gridHeight);
FolioWidget(HomeScreen *parent = nullptr, int id = -1, int gridWidth = 0, int gridHeight = 0);
FolioWidget(HomeScreen *parent, Plasma::Applet *applet, int gridWidth, int gridHeight);
static FolioWidget *fromJson(QJsonObject &obj, QObject *parent);
static FolioWidget *fromJson(QJsonObject &obj, HomeScreen *parent);
QJsonObject toJson() const;
int id() const;
@ -80,10 +84,12 @@ private:
void init();
void setVisualApplet(PlasmaQuick::AppletQuickItem *quickApplet);
int m_id = -1;
int m_realGridWidth = 1;
int m_realGridHeight = 1;
HomeScreen *m_homeScreen{nullptr};
Plasma::Applet *m_applet = nullptr;
PlasmaQuick::AppletQuickItem *m_quickApplet = nullptr;
int m_id{-1};
int m_realGridWidth{1};
int m_realGridHeight{1};
Plasma::Applet *m_applet{nullptr};
PlasmaQuick::AppletQuickItem *m_quickApplet{nullptr};
};

View file

@ -4,20 +4,6 @@
#include "homescreen.h"
#include "applicationlistmodel.h"
#include "delegatetoucharea.h"
#include "favouritesmodel.h"
#include "folioapplication.h"
#include "folioapplicationfolder.h"
#include "foliodelegate.h"
#include "foliosettings.h"
#include "foliowidget.h"
#include "homescreenstate.h"
#include "pagelistmodel.h"
#include "pagemodel.h"
#include "widgetcontainer.h"
#include "widgetsmanager.h"
#include <KWindowSystem>
#include <QDebug>
@ -27,50 +13,35 @@
HomeScreen::HomeScreen(QObject *parent, const KPluginMetaData &data, const QVariantList &args)
: Plasma::Containment{parent, data, args}
, m_folioSettings{new FolioSettings{this}}
, m_homeScreenState{new HomeScreenState{this}}
, m_widgetsManager{new WidgetsManager{this}}
, m_applicationListModel{new ApplicationListModel{this}}
, m_favouritesModel{new FavouritesModel{this}}
, m_pageListModel{new PageListModel{this}}
{
setHasConfigurationInterface(true);
// HomeScreenState init() has dependencies on other objects
m_homeScreenState->init();
const char *uri = "org.kde.private.mobile.homescreen.folio";
// pre-initialize
FolioSettings::self()->setApplet(this);
HomeScreenState::self()->setContainment(this);
WidgetsManager::self();
// models are loaded in main.qml
ApplicationListModel::self();
FavouritesModel::self()->setContainment(this);
PageListModel::self()->setContainment(this);
qmlRegisterSingletonType<ApplicationListModel>(uri, 1, 0, "ApplicationListModel", [](QQmlEngine *, QJSEngine *) -> QObject * {
return ApplicationListModel::self();
});
qmlRegisterSingletonType<FavouritesModel>(uri, 1, 0, "FavouritesModel", [](QQmlEngine *, QJSEngine *) -> QObject * {
return FavouritesModel::self();
});
qmlRegisterSingletonType<PageListModel>(uri, 1, 0, "PageListModel", [](QQmlEngine *, QJSEngine *) -> QObject * {
return PageListModel::self();
});
qmlRegisterSingletonType<FolioSettings>(uri, 1, 0, "FolioSettings", [](QQmlEngine *, QJSEngine *) -> QObject * {
return FolioSettings::self();
});
qmlRegisterSingletonType<HomeScreenState>(uri, 1, 0, "HomeScreenState", [](QQmlEngine *, QJSEngine *) -> QObject * {
return HomeScreenState::self();
});
qmlRegisterType<FolioApplication>(uri, 1, 0, "FolioApplication");
qmlRegisterType<FolioApplicationFolder>(uri, 1, 0, "FolioApplicationFolder");
qmlRegisterType<FolioWidget>(uri, 1, 0, "FolioWidget");
qmlRegisterType<FolioDelegate>(uri, 1, 0, "FolioDelegate");
qmlRegisterType<PageModel>(uri, 1, 0, "PageModel");
qmlRegisterType<FolioPageDelegate>(uri, 1, 0, "FolioPageDelegate");
qmlRegisterUncreatableType<HomeScreen>(uri, 1, 0, "HomeScreen", "");
qmlRegisterUncreatableType<ApplicationListModel>(uri, 1, 0, "ApplicationListModel", "");
qmlRegisterUncreatableType<FavouritesModel>(uri, 1, 0, "FavouritesModel", "");
qmlRegisterUncreatableType<PageListModel>(uri, 1, 0, "PageListModel", "");
qmlRegisterUncreatableType<FolioSettings>(uri, 1, 0, "FolioSettings", "");
qmlRegisterUncreatableType<HomeScreenState>(uri, 1, 0, "HomeScreenState", "");
qmlRegisterUncreatableType<FolioApplication>(uri, 1, 0, "FolioApplication", "");
qmlRegisterUncreatableType<FolioApplicationFolder>(uri, 1, 0, "FolioApplicationFolder", "");
qmlRegisterUncreatableType<FolioWidget>(uri, 1, 0, "FolioWidget", "");
qmlRegisterUncreatableType<FolioDelegate>(uri, 1, 0, "FolioDelegate", "");
qmlRegisterUncreatableType<PageModel>(uri, 1, 0, "PageModel", "");
qmlRegisterUncreatableType<FolioPageDelegate>(uri, 1, 0, "FolioPageDelegate", "");
qmlRegisterType<DelegateTouchArea>(uri, 1, 0, "DelegateTouchArea");
qmlRegisterType<DelegateDragPosition>(uri, 1, 0, "DelegateDragPosition");
qmlRegisterUncreatableType<DelegateDragPosition>(uri, 1, 0, "DelegateDragPosition", "");
qmlRegisterType<WidgetContainer>(uri, 1, 0, "WidgetContainer");
setHasConfigurationInterface(true);
connect(KWindowSystem::self(), &KWindowSystem::showingDesktopChanged, this, &HomeScreen::showingDesktopChanged);
connect(this, &Plasma::Containment::appletAdded, this, &HomeScreen::onAppletAdded);
@ -86,12 +57,43 @@ void HomeScreen::configChanged()
void HomeScreen::onAppletAdded(Plasma::Applet *applet, const QRectF &geometryHint)
{
WidgetsManager::self()->addWidget(applet);
Q_UNUSED(geometryHint)
widgetsManager()->addWidget(applet);
}
void HomeScreen::onAppletAboutToBeRemoved(Plasma::Applet *applet)
{
WidgetsManager::self()->removeWidget(applet);
widgetsManager()->removeWidget(applet);
}
FolioSettings *HomeScreen::folioSettings()
{
return m_folioSettings;
}
HomeScreenState *HomeScreen::homeScreenState()
{
return m_homeScreenState;
}
WidgetsManager *HomeScreen::widgetsManager()
{
return m_widgetsManager;
}
ApplicationListModel *HomeScreen::applicationListModel()
{
return m_applicationListModel;
}
FavouritesModel *HomeScreen::favouritesModel()
{
return m_favouritesModel;
}
PageListModel *HomeScreen::pageListModel()
{
return m_pageListModel;
}
K_PLUGIN_CLASS(HomeScreen)

View file

@ -7,9 +7,36 @@
#include <Plasma/Containment>
#include <QSortFilterProxyModel>
#include "applicationlistmodel.h"
#include "delegatetoucharea.h"
#include "favouritesmodel.h"
#include "folioapplication.h"
#include "folioapplicationfolder.h"
#include "foliodelegate.h"
#include "foliosettings.h"
#include "foliowidget.h"
#include "homescreenstate.h"
#include "pagelistmodel.h"
#include "pagemodel.h"
#include "widgetcontainer.h"
#include "widgetsmanager.h"
class FolioSettings;
class PageListModel;
class WidgetsManager;
class HomeScreenState;
class FavouritesModel;
class ApplicationListModel;
class HomeScreen : public Plasma::Containment
{
Q_OBJECT
Q_PROPERTY(FolioSettings *FolioSettings READ folioSettings CONSTANT)
Q_PROPERTY(HomeScreenState *HomeScreenState READ homeScreenState CONSTANT)
Q_PROPERTY(WidgetsManager *WidgetsManager READ widgetsManager CONSTANT)
Q_PROPERTY(ApplicationListModel *ApplicationListModel READ applicationListModel CONSTANT)
Q_PROPERTY(FavouritesModel *FavouritesModel READ favouritesModel CONSTANT)
Q_PROPERTY(PageListModel *PageListModel READ pageListModel CONSTANT)
public:
HomeScreen(QObject *parent, const KPluginMetaData &data, const QVariantList &args);
@ -17,10 +44,25 @@ public:
void configChanged() override;
FolioSettings *folioSettings();
HomeScreenState *homeScreenState();
WidgetsManager *widgetsManager();
ApplicationListModel *applicationListModel();
FavouritesModel *favouritesModel();
PageListModel *pageListModel();
Q_SIGNALS:
void showingDesktopChanged(bool showingDesktop);
private Q_SLOTS:
void onAppletAdded(Plasma::Applet *applet, const QRectF &geometryHint);
void onAppletAboutToBeRemoved(Plasma::Applet *applet);
private:
FolioSettings *m_folioSettings{nullptr};
HomeScreenState *m_homeScreenState{nullptr};
WidgetsManager *m_widgetsManager{nullptr};
ApplicationListModel *m_applicationListModel{nullptr};
FavouritesModel *m_favouritesModel{nullptr};
PageListModel *m_pageListModel{nullptr};
};

View file

@ -17,12 +17,6 @@ constexpr qreal DETERMINE_SWIPE_THRESHOLD = 10;
constexpr qreal VERTICAL_FAVOURITES_BAR_THRESHOLD = 400;
HomeScreenState *HomeScreenState::self()
{
static HomeScreenState *inst = new HomeScreenState{nullptr};
return inst;
}
QPropertyAnimation *HomeScreenState::setupAnimation(QByteArray property, int duration, QEasingCurve::Type curve, qreal endValue)
{
auto anim = new QPropertyAnimation{this, property, this};
@ -32,11 +26,16 @@ QPropertyAnimation *HomeScreenState::setupAnimation(QByteArray property, int dur
return anim;
}
HomeScreenState::HomeScreenState(QObject *parent)
HomeScreenState::HomeScreenState(HomeScreen *parent)
: QObject{parent}
, m_dragState{new DragState{this, this}}
, m_homeScreen{parent}
, m_dragState{new DragState{this, parent}}
, m_appDrawerY{APP_DRAWER_OPEN_DIST}
, m_searchWidgetY{SEARCH_WIDGET_OPEN_DIST}
{
}
void HomeScreenState::init()
{
const int expoDuration = 800;
const int cubicDuration = 400;
@ -136,11 +135,11 @@ HomeScreenState::HomeScreenState(QObject *parent)
Q_EMIT favouritesBarLocationChanged();
});
connect(FolioSettings::self(), &FolioSettings::homeScreenRowsChanged, this, [this]() {
connect(m_homeScreen->folioSettings(), &FolioSettings::homeScreenRowsChanged, this, [this]() {
Q_EMIT pageRowsChanged();
Q_EMIT pageColumnsChanged();
});
connect(FolioSettings::self(), &FolioSettings::homeScreenColumnsChanged, this, [this]() {
connect(m_homeScreen->folioSettings(), &FolioSettings::homeScreenColumnsChanged, this, [this]() {
Q_EMIT pageRowsChanged();
Q_EMIT pageColumnsChanged();
});
@ -277,18 +276,18 @@ HomeScreenState::FavouritesBarLocation HomeScreenState::favouritesBarLocation()
int HomeScreenState::pageRows() const
{
if (m_pageOrientation == RegularPosition || m_pageOrientation == RotateUpsideDown) {
return FolioSettings::self()->homeScreenRows();
return m_homeScreen->folioSettings()->homeScreenRows();
} else {
return FolioSettings::self()->homeScreenColumns();
return m_homeScreen->folioSettings()->homeScreenColumns();
}
}
int HomeScreenState::pageColumns() const
{
if (m_pageOrientation == RegularPosition || m_pageOrientation == RotateUpsideDown) {
return FolioSettings::self()->homeScreenColumns();
return m_homeScreen->folioSettings()->homeScreenColumns();
} else {
return FolioSettings::self()->homeScreenRows();
return m_homeScreen->folioSettings()->homeScreenRows();
}
}
@ -622,7 +621,7 @@ int HomeScreenState::currentFolderPage()
FolioDelegate *HomeScreenState::getPageDelegateAt(int page, int row, int column)
{
PageModel *pageModel = PageListModel::self()->getPage(page);
PageModel *pageModel = m_homeScreen->pageListModel()->getPage(page);
if (!pageModel) {
return nullptr;
}
@ -637,7 +636,7 @@ FolioDelegate *HomeScreenState::getPageDelegateAt(int page, int row, int column)
FolioDelegate *HomeScreenState::getFavouritesDelegateAt(int position)
{
return FavouritesModel::self()->getEntryAt(position);
return m_homeScreen->favouritesModel()->getEntryAt(position);
}
FolioDelegate *HomeScreenState::getFolderDelegateAt(int position)
@ -659,7 +658,7 @@ QPointF HomeScreenState::getPageDelegateScreenPosition(int page, int row, int co
QPointF HomeScreenState::getFavouritesDelegateScreenPosition(int position)
{
return FavouritesModel::self()->getDelegateScreenPosition(position);
return m_homeScreen->favouritesModel()->getDelegateScreenPosition(position);
}
QPointF HomeScreenState::getFolderDelegateScreenPosition(int position)
@ -679,16 +678,6 @@ QPointF HomeScreenState::getFolderDelegateScreenPosition(int position)
return {x, y};
}
Plasma::Containment *HomeScreenState::containment()
{
return m_containment;
}
void HomeScreenState::setContainment(Plasma::Containment *containment)
{
m_containment = containment;
}
void HomeScreenState::openAppDrawer()
{
cancelAppDrawerAnimations();
@ -719,7 +708,7 @@ void HomeScreenState::closeSearchWidget()
void HomeScreenState::snapPage()
{
const int numOfPages = PageListModel::self()->rowCount();
const int numOfPages = m_homeScreen->pageListModel()->rowCount();
const int leftPage = qBound(0.0, (m_pageViewX / m_pageWidth), numOfPages - 1.0);
const qreal leftPagePos = -leftPage * m_pageWidth;
@ -745,7 +734,7 @@ void HomeScreenState::goToPage(int page)
page = 0;
}
const int numOfPages = PageListModel::self()->rowCount();
const int numOfPages = m_homeScreen->pageListModel()->rowCount();
if (page >= numOfPages) {
page = std::max(0, numOfPages - 1);
}

View file

@ -10,8 +10,10 @@
#include <Plasma/Applet>
#include "dragstate.h"
#include "homescreen.h"
class DragState;
class HomeScreen;
/**
* @short The homescreen state, containing information on positioning panels as well as any swipe events.
@ -110,9 +112,8 @@ public:
};
Q_ENUM(PageOrientation)
static HomeScreenState *self();
HomeScreenState(QObject *parent = nullptr);
HomeScreenState(HomeScreen *parent = nullptr);
void init(); // separate function due to dependencies on other classes
// the current state of swipe interaction
SwipeState swipeState() const;
@ -257,9 +258,6 @@ public:
Q_INVOKABLE QPointF getFavouritesDelegateScreenPosition(int position);
Q_INVOKABLE QPointF getFolderDelegateScreenPosition(int position);
Plasma::Containment *containment();
void setContainment(Plasma::Containment *containment);
Q_SIGNALS:
void swipeStateChanged();
void viewStateChanged();
@ -354,6 +352,8 @@ private:
QPropertyAnimation *setupAnimation(QByteArray property, int duration, QEasingCurve::Type curve, qreal endValue);
HomeScreen *m_homeScreen{nullptr};
SwipeState m_swipeState{SwipeState::None};
ViewState m_viewState{ViewState::PageView};
@ -414,6 +414,4 @@ private:
QPropertyAnimation *m_folderPageAnim{nullptr};
QPropertyAnimation *m_openSettingsAnim{nullptr};
QPropertyAnimation *m_closeSettingsAnim{nullptr};
Plasma::Containment *m_containment{nullptr};
};

View file

@ -10,11 +10,13 @@ import org.kde.plasma.components 3.0 as PC3
import org.kde.kirigami as Kirigami
import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.private.mobile.homescreen.folio as Folio
import 'private'
Item {
id: root
required property Folio.HomeScreen folio
property var homeScreen
@ -53,6 +55,7 @@ Item {
AppDrawerGrid {
id: appDrawerGrid
folio: root.folio
homeScreen: root.homeScreen
height: parent.height - drawerHeader.height
anchors.left: parent.left

View file

@ -17,6 +17,8 @@ import "./delegate"
MobileShell.GridView {
id: root
property Folio.HomeScreen folio
cacheBuffer: cellHeight * 20
reuseItems: true
layer.enabled: true
@ -24,14 +26,14 @@ MobileShell.GridView {
property var homeScreen
property real headerHeight
readonly property int reservedSpaceForLabel: Folio.HomeScreenState.pageDelegateLabelHeight
readonly property int reservedSpaceForLabel: folio.HomeScreenState.pageDelegateLabelHeight
readonly property real effectiveContentWidth: width - leftMargin - rightMargin
readonly property real horizontalMargin: Math.round(width * 0.05)
leftMargin: horizontalMargin
rightMargin: horizontalMargin
cellWidth: effectiveContentWidth / Math.min(Math.floor(effectiveContentWidth / (Folio.FolioSettings.delegateIconSize + Kirigami.Units.largeSpacing * 3.5)), 8)
cellWidth: effectiveContentWidth / Math.min(Math.floor(effectiveContentWidth / (folio.FolioSettings.delegateIconSize + Kirigami.Units.largeSpacing * 3.5)), 8)
cellHeight: cellWidth + reservedSpaceForLabel
boundsBehavior: Flickable.DragAndOvershootBounds
@ -41,14 +43,14 @@ MobileShell.GridView {
// HACK: the first swipe from the top of the app drawer is done from HomeScreenState, not the flickable
// due to issues with Flickable getting its swipe stolen by SwipeArea
interactive: (dragging || !atYBeginning) // allow us to drag to the top
&& Folio.HomeScreenState.swipeState !== Folio.HomeScreenState.SwipingAppDrawerGrid
interactive: (dragging || !atYBeginning) // allow us to drag to the top
&& folio.HomeScreenState.swipeState !== Folio.HomeScreenState.SwipingAppDrawerGrid
Connections {
target: Folio.HomeScreenState
target: folio.HomeScreenState
function onSwipeStateChanged() {
if (Folio.HomeScreenState.swipeState === Folio.HomeScreenState.SwipingAppDrawerGrid) {
if (folio.HomeScreenState.swipeState === Folio.HomeScreenState.SwipingAppDrawerGrid) {
velocityCalculator.startMeasure();
velocityCalculator.changePosition(root.contentY);
}
@ -76,10 +78,12 @@ MobileShell.GridView {
id: velocityCalculator
}
model: Folio.ApplicationListModel
model: folio.ApplicationListModel
delegate: AppDelegate {
id: delegate
id: appDelegate
folio: root.folio
shadow: false
application: model.delegate.application
@ -87,18 +91,18 @@ MobileShell.GridView {
height: root.cellHeight
onPressAndHold: {
const mappedCoords = root.homeScreen.prepareStartDelegateDrag(model.delegate, delegate.delegateItem);
Folio.HomeScreenState.closeAppDrawer();
const mappedCoords = root.homeScreen.prepareStartDelegateDrag(model.delegate, appDelegate.delegateItem);
folio.HomeScreenState.closeAppDrawer();
// we need to adjust because app drawer delegates have a different size than regular homescreen delegates
const centerX = mappedCoords.x + root.cellWidth / 2;
const centerY = mappedCoords.y + root.cellHeight / 2;
Folio.HomeScreenState.startDelegateAppDrawerDrag(
centerX - Folio.HomeScreenState.pageCellWidth / 2,
centerY - Folio.HomeScreenState.pageCellHeight / 2,
delegate.pressPosition.x * (Folio.HomeScreenState.pageCellWidth / root.cellWidth),
delegate.pressPosition.y * (Folio.HomeScreenState.pageCellHeight / root.cellHeight),
folio.HomeScreenState.startDelegateAppDrawerDrag(
centerX - folio.HomeScreenState.pageCellWidth / 2,
centerY - folio.HomeScreenState.pageCellHeight / 2,
appDelegate.pressPosition.x * (folio.HomeScreenState.pageCellWidth / root.cellWidth),
appDelegate.pressPosition.y * (folio.HomeScreenState.pageCellHeight / root.cellHeight),
model.delegate.application.storageId
);
}

View file

@ -11,25 +11,26 @@ import "./delegate"
Item {
id: root
width: Folio.HomeScreenState.pageCellWidth
height: Folio.HomeScreenState.pageCellHeight
property Folio.HomeScreen folio
property Folio.FolioDelegate delegate
width: folio.HomeScreenState.pageCellWidth
height: folio.HomeScreenState.pageCellHeight
readonly property real dropAnimationRunning: dragXAnim.running || dragYAnim.running
// ignore widget dragging, that is not handled by this component
readonly property bool isWidgetDrag: Folio.HomeScreenState.dragState.dropDelegate && Folio.HomeScreenState.dragState.dropDelegate.type === Folio.FolioDelegate.Widget
readonly property bool isWidgetDrag: folio.HomeScreenState.dragState.dropDelegate && folio.HomeScreenState.dragState.dropDelegate.type === Folio.FolioDelegate.Widget
visible: false
x: Folio.HomeScreenState.delegateDragX
y: Folio.HomeScreenState.delegateDragY
x: folio.HomeScreenState.delegateDragX
y: folio.HomeScreenState.delegateDragY
function setXBinding() {
x = Qt.binding(() => Folio.HomeScreenState.delegateDragX);
x = Qt.binding(() => folio.HomeScreenState.delegateDragX);
}
function setYBinding() {
y = Qt.binding(() => Folio.HomeScreenState.delegateDragY);
y = Qt.binding(() => folio.HomeScreenState.delegateDragY);
}
// animate drop x
@ -67,13 +68,13 @@ Item {
Connections {
id: stateWatcher
target: Folio.HomeScreenState
target: folio.HomeScreenState
property var delegateDroppedOn: null
// reset and show drag item
function onSwipeStateChanged() {
if (Folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate && !isWidgetDrag) {
if (folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate && !isWidgetDrag) {
root.scale = 1.0;
root.visible = true;
}
@ -85,15 +86,15 @@ Item {
return;
}
let dragState = Folio.HomeScreenState.dragState;
let dragState = folio.HomeScreenState.dragState;
let dropPosition = dragState.candidateDropPosition;
switch (dropPosition.location) {
case Folio.DelegateDragPosition.Pages:
stateWatcher.delegateDroppedOn = Folio.HomeScreenState.getPageDelegateAt(dropPosition.page, dropPosition.pageRow, dropPosition.pageColumn);
stateWatcher.delegateDroppedOn = folio.HomeScreenState.getPageDelegateAt(dropPosition.page, dropPosition.pageRow, dropPosition.pageColumn);
break;
case Folio.DelegateDragPosition.Favourites:
stateWatcher.delegateDroppedOn = Folio.HomeScreenState.getFavouritesDelegateAt(dropPosition.favouritesPosition);
stateWatcher.delegateDroppedOn = folio.HomeScreenState.getFavouritesDelegateAt(dropPosition.favouritesPosition);
break;
case Folio.DelegateDragPosition.Folder:
stateWatcher.delegateDroppedOn = null;
@ -103,7 +104,7 @@ Item {
}
Connections {
target: Folio.HomeScreenState.dragState
target: folio.HomeScreenState.dragState
// animate from when the delegate is dropped to its drop position
function onDelegateDroppedAndPlaced() {
@ -111,20 +112,20 @@ Item {
return;
}
let dragState = Folio.HomeScreenState.dragState;
let dragState = folio.HomeScreenState.dragState;
let dropPosition = dragState.candidateDropPosition;
let pos = null;
switch (dropPosition.location) {
case Folio.DelegateDragPosition.Pages:
pos = Folio.HomeScreenState.getPageDelegateScreenPosition(dropPosition.page, dropPosition.pageRow, dropPosition.pageColumn);
pos = folio.HomeScreenState.getPageDelegateScreenPosition(dropPosition.page, dropPosition.pageRow, dropPosition.pageColumn);
break;
case Folio.DelegateDragPosition.Favourites:
pos = Folio.HomeScreenState.getFavouritesDelegateScreenPosition(dropPosition.favouritesPosition);
pos = folio.HomeScreenState.getFavouritesDelegateScreenPosition(dropPosition.favouritesPosition);
break;
case Folio.DelegateDragPosition.Folder:
pos = Folio.HomeScreenState.getFolderDelegateScreenPosition(dropPosition.folderPosition);
pos = folio.HomeScreenState.getFolderDelegateScreenPosition(dropPosition.folderPosition);
break;
}
@ -156,9 +157,10 @@ Item {
// icon
DelegateIconLoader {
id: loader
folio: root.folio
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
Layout.minimumWidth: Folio.FolioSettings.delegateIconSize
Layout.minimumHeight: Folio.FolioSettings.delegateIconSize
Layout.minimumWidth: folio.FolioSettings.delegateIconSize
Layout.minimumHeight: folio.FolioSettings.delegateIconSize
Layout.preferredHeight: Layout.minimumHeight
delegate: root.delegate
@ -173,8 +175,8 @@ Item {
opacity: 0
Layout.fillWidth: true
Layout.preferredHeight: Folio.HomeScreenState.pageDelegateLabelHeight
Layout.topMargin: Folio.HomeScreenState.pageDelegateLabelSpacing
Layout.preferredHeight: folio.HomeScreenState.pageDelegateLabelHeight
Layout.topMargin: folio.HomeScreenState.pageDelegateLabelSpacing
Layout.leftMargin: -parent.anchors.leftMargin + Kirigami.Units.smallSpacing
Layout.rightMargin: -parent.anchors.rightMargin + Kirigami.Units.smallSpacing
}

View file

@ -16,6 +16,7 @@ import "./delegate"
MouseArea {
id: root
property Folio.HomeScreen folio
property var homeScreen
@ -25,10 +26,10 @@ MouseArea {
signal delegateDragRequested(var item)
onPressAndHold: Folio.HomeScreenState.openSettingsView()
onPressAndHold: folio.HomeScreenState.openSettingsView()
Repeater {
model: Folio.FavouritesModel
model: folio.FavouritesModel
delegate: Item {
id: delegate
@ -36,10 +37,10 @@ MouseArea {
property var delegateModel: model.delegate
property int index: model.index
property var dragState: Folio.HomeScreenState.dragState
property var dragState: folio.HomeScreenState.dragState
property bool isDropPositionThis: dragState.candidateDropPosition.location === Folio.DelegateDragPosition.Favourites &&
dragState.candidateDropPosition.favouritesPosition === delegate.index
property bool isAppHoveredOver: Folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate &&
property bool isAppHoveredOver: folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate &&
dragState.dropDelegate &&
dragState.dropDelegate.type === Folio.FolioDelegate.Application &&
isDropPositionThis
@ -49,8 +50,8 @@ MouseArea {
x: model.xPosition - leftMargin
y: model.xPosition - topMargin
anchors.verticalCenter: Folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Bottom ? parent.verticalCenter : undefined
anchors.horizontalCenter: Folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Bottom ? undefined : parent.horizontalCenter
anchors.verticalCenter: folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Bottom ? parent.verticalCenter : undefined
anchors.horizontalCenter: folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Bottom ? undefined : parent.horizontalCenter
Behavior on x {
NumberAnimation { duration: 250; easing.type: Easing.InOutQuad }
@ -59,10 +60,10 @@ MouseArea {
NumberAnimation { duration: 250; easing.type: Easing.InOutQuad }
}
implicitWidth: Folio.HomeScreenState.pageCellWidth
implicitHeight: Folio.HomeScreenState.pageCellHeight
width: Folio.HomeScreenState.pageCellWidth
height: Folio.HomeScreenState.pageCellHeight
implicitWidth: folio.HomeScreenState.pageCellWidth
implicitHeight: folio.HomeScreenState.pageCellHeight
width: folio.HomeScreenState.pageCellWidth
height: folio.HomeScreenState.pageCellHeight
Loader {
anchors.fill: parent
@ -90,12 +91,13 @@ MouseArea {
AppDelegate {
id: appDelegate
folio: root.folio
application: delegate.delegateModel.application
name: Folio.FolioSettings.showFavouritesAppLabels ? delegate.delegateModel.application.name : ""
name: folio.FolioSettings.showFavouritesAppLabels ? delegate.delegateModel.application.name : ""
shadow: true
turnToFolder: delegate.isAppHoveredOver
turnToFolderAnimEnabled: Folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate
turnToFolderAnimEnabled: folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate
// do not show if the drop animation is running to this delegate
visible: !(root.homeScreen.dropAnimationRunning && delegate.isDropPositionThis)
@ -118,7 +120,7 @@ MouseArea {
onPressAndHoldReleased: {
// cancel the event if the delegate is not dragged
if (Folio.HomeScreenState.swipeState === Folio.HomeScreenState.AwaitingDraggingDelegate) {
if (folio.HomeScreenState.swipeState === Folio.HomeScreenState.AwaitingDraggingDelegate) {
homeScreen.cancelDelegateDrag();
}
}
@ -132,10 +134,10 @@ MouseArea {
// close menu when drag starts
Connections {
target: Folio.HomeScreenState
target: folio.HomeScreenState
function onSwipeStateChanged() {
if (Folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate) {
if (folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate) {
contextMenu.close();
}
}
@ -145,7 +147,7 @@ MouseArea {
Kirigami.Action {
icon.name: "emblem-favorite"
text: i18n("Remove")
onTriggered: Folio.FavouritesModel.removeEntry(delegate.index)
onTriggered: folio.FavouritesModel.removeEntry(delegate.index)
}
]
}
@ -157,9 +159,10 @@ MouseArea {
AppFolderDelegate {
id: appFolderDelegate
folio: root.folio
shadow: true
folder: delegate.delegateModel.folder
name: Folio.FolioSettings.showFavouritesAppLabels ? delegate.delegateModel.folder.name : ""
name: folio.FolioSettings.showFavouritesAppLabels ? delegate.delegateModel.folder.name : ""
// do not show if the drop animation is running to this delegate, and the drop delegate is a folder
visible: !(root.homeScreen.dropAnimationRunning &&
@ -173,12 +176,12 @@ MouseArea {
onAfterClickAnimation: {
const pos = homeScreen.prepareFolderOpen(appFolderDelegate.contentItem);
Folio.HomeScreenState.openFolder(pos.x, pos.y, delegate.delegateModel.folder);
folio.HomeScreenState.openFolder(pos.x, pos.y, delegate.delegateModel.folder);
}
onPressAndHold: {
let mappedCoords = root.homeScreen.prepareStartDelegateDrag(delegate.delegateModel, appFolderDelegate.delegateItem);
Folio.HomeScreenState.startDelegateFavouritesDrag(
folio.HomeScreenState.startDelegateFavouritesDrag(
mappedCoords.x,
mappedCoords.y,
appFolderDelegate.pressPosition.x,
@ -191,7 +194,7 @@ MouseArea {
onPressAndHoldReleased: {
// cancel the event if the delegate is not dragged
if (Folio.HomeScreenState.swipeState === Folio.HomeScreenState.AwaitingDraggingDelegate) {
if (folio.HomeScreenState.swipeState === Folio.HomeScreenState.AwaitingDraggingDelegate) {
root.homeScreen.cancelDelegateDrag();
}
}
@ -205,10 +208,10 @@ MouseArea {
// close menu when drag starts
Connections {
target: Folio.HomeScreenState
target: folio.HomeScreenState
function onSwipeStateChanged() {
if (Folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate) {
if (folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate) {
contextMenu.close();
}
}
@ -225,7 +228,7 @@ MouseArea {
ConfirmDeleteFolderDialogLoader {
id: deleteDialog
parent: root.homeScreen
onAccepted: Folio.FavouritesModel.removeEntry(delegate.index)
onAccepted: folio.FavouritesModel.removeEntry(delegate.index)
}
}
}

View file

@ -16,6 +16,7 @@ import "./delegate"
Folio.DelegateTouchArea {
id: root
property Folio.HomeScreen folio
property var homeScreen
@ -23,25 +24,26 @@ Folio.DelegateTouchArea {
property real folderPositionX
property real folderPositionY
property Folio.FolioApplicationFolder folder: Folio.HomeScreenState.currentFolder
property Folio.FolioApplicationFolder folder: folio.HomeScreenState.currentFolder
onClicked: close();
function close() {
Folio.HomeScreenState.closeFolder();
folio.HomeScreenState.closeFolder();
}
Connections {
target: Folio.HomeScreenState
target: folio.HomeScreenState
function onFolderAboutToOpen(x, y) {
root.folderPositionX = x - Folio.HomeScreenState.viewLeftPadding;
root.folderPositionY = y - Folio.HomeScreenState.viewRightPadding;
root.folderPositionX = x - folio.HomeScreenState.viewLeftPadding;
root.folderPositionY = y - folio.HomeScreenState.viewRightPadding;
}
}
FolderViewTitle {
id: titleText
folio: root.folio
width: root.width
// have to use y instead of anchors to avoid animations
@ -59,18 +61,18 @@ Folio.DelegateTouchArea {
function updateContentWidth() {
let margin = folderBackground.margin;
let columns = Math.floor((folderBackground.width - margin * 2) / Folio.HomeScreenState.pageCellWidth);
Folio.HomeScreenState.folderPageContentWidth = columns * Folio.HomeScreenState.pageCellWidth;
let columns = Math.floor((folderBackground.width - margin * 2) / folio.HomeScreenState.pageCellWidth);
folio.HomeScreenState.folderPageContentWidth = columns * folio.HomeScreenState.pageCellWidth;
}
function updateContentHeight() {
let margin = folderBackground.margin;
let rows = Math.floor((folderBackground.height - margin * 2) / Folio.HomeScreenState.pageCellHeight);
Folio.HomeScreenState.folderPageContentHeight = rows * Folio.HomeScreenState.pageCellHeight;
let rows = Math.floor((folderBackground.height - margin * 2) / folio.HomeScreenState.pageCellHeight);
folio.HomeScreenState.folderPageContentHeight = rows * folio.HomeScreenState.pageCellHeight;
}
Connections {
target: Folio.HomeScreenState
target: folio.HomeScreenState
function onPageCellWidthChanged() {
root.updateContentWidth();
@ -94,31 +96,31 @@ Folio.DelegateTouchArea {
width: {
let perRow = 0;
if (root.width < root.height) {
perRow = Math.floor((maxLength - margin * 2) / Folio.HomeScreenState.pageCellWidth);
perRow = Math.floor((maxLength - margin * 2) / folio.HomeScreenState.pageCellWidth);
} else {
// try to get the same number of rows as columns
perRow = Math.floor((maxLength - margin * 2) / Folio.HomeScreenState.pageCellHeight);
perRow = Math.floor((maxLength - margin * 2) / folio.HomeScreenState.pageCellHeight);
}
return Math.min(root.width * 0.9, perRow * Folio.HomeScreenState.pageCellWidth + margin * 2);
return Math.min(root.width * 0.9, perRow * folio.HomeScreenState.pageCellWidth + margin * 2);
}
height: {
let perRow = 0;
if (root.width < root.height) {
// try to get the same number of rows as columns
perRow = Math.floor((maxLength - margin * 2) / Folio.HomeScreenState.pageCellWidth);
perRow = Math.floor((maxLength - margin * 2) / folio.HomeScreenState.pageCellWidth);
} else {
perRow = Math.floor((maxLength - margin * 2) / Folio.HomeScreenState.pageCellHeight);
perRow = Math.floor((maxLength - margin * 2) / folio.HomeScreenState.pageCellHeight);
}
return Math.min(root.height * 0.9, perRow * Folio.HomeScreenState.pageCellHeight + margin * 2);
return Math.min(root.height * 0.9, perRow * folio.HomeScreenState.pageCellHeight + margin * 2);
}
onWidthChanged: {
Folio.HomeScreenState.folderPageWidth = width;
folio.HomeScreenState.folderPageWidth = width;
root.updateContentWidth();
root.updateContentHeight();
}
onHeightChanged: {
Folio.HomeScreenState.folderPageHeight = height;
folio.HomeScreenState.folderPageHeight = height;
root.updateContentWidth();
root.updateContentHeight();
}
@ -126,12 +128,12 @@ Folio.DelegateTouchArea {
x: {
const folderPos = root.folderPositionX;
const centerX = (root.width / 2) - (width / 2);
return Math.round(folderPos + (centerX - folderPos) * Folio.HomeScreenState.folderOpenProgress);
return Math.round(folderPos + (centerX - folderPos) * folio.HomeScreenState.folderOpenProgress);
}
y: {
const folderPos = root.folderPositionY;
const centerY = (root.height / 2) - (height / 2);
return Math.round(folderPos + (centerY - folderPos) * Folio.HomeScreenState.folderOpenProgress);
return Math.round(folderPos + (centerY - folderPos) * folio.HomeScreenState.folderOpenProgress);
}
transform: [
@ -140,15 +142,15 @@ Folio.DelegateTouchArea {
origin.y: 0
xScale: {
const iconSize = Folio.FolioSettings.delegateIconSize;
const iconSize = folio.FolioSettings.delegateIconSize;
const fullWidth = folderBackground.width;
const candidate = iconSize + (fullWidth - iconSize) * Folio.HomeScreenState.folderOpenProgress;
const candidate = iconSize + (fullWidth - iconSize) * folio.HomeScreenState.folderOpenProgress;
return Math.max(0, Math.min(1, candidate / fullWidth));
}
yScale: {
const iconSize = Folio.FolioSettings.delegateIconSize;
const iconSize = folio.FolioSettings.delegateIconSize;
const fullHeight = folderBackground.height;
const candidate = iconSize + (fullHeight - iconSize) * Folio.HomeScreenState.folderOpenProgress;
const candidate = iconSize + (fullHeight - iconSize) * folio.HomeScreenState.folderOpenProgress;
return Math.max(0, Math.min(1, candidate / fullHeight));
}
}
@ -163,7 +165,7 @@ Folio.DelegateTouchArea {
Item {
id: contentContainer
x: Folio.HomeScreenState.folderViewX
x: folio.HomeScreenState.folderViewX
Repeater {
model: root.folder ? root.folder.applications : []
@ -174,7 +176,7 @@ Folio.DelegateTouchArea {
property var delegateModel: model.delegate
property int index: model.index
property var dragState: Folio.HomeScreenState.dragState
property var dragState: folio.HomeScreenState.dragState
property bool isDropPositionThis: dragState.candidateDropPosition.location === Folio.DelegateDragPosition.Folder &&
dragState.candidateDropPosition.folderPosition === index
@ -188,10 +190,10 @@ Folio.DelegateTouchArea {
NumberAnimation { duration: 250; easing.type: Easing.InOutQuad }
}
implicitWidth: Folio.HomeScreenState.pageCellWidth
implicitHeight: Folio.HomeScreenState.pageCellHeight
width: Folio.HomeScreenState.pageCellWidth
height: Folio.HomeScreenState.pageCellHeight
implicitWidth: folio.HomeScreenState.pageCellWidth
implicitHeight: folio.HomeScreenState.pageCellHeight
width: folio.HomeScreenState.pageCellWidth
height: folio.HomeScreenState.pageCellHeight
Loader {
id: delegateLoader
@ -217,6 +219,7 @@ Folio.DelegateTouchArea {
AppDelegate {
id: appDelegate
folio: root.folio
application: delegate.delegateModel.application
// do not show if the drop animation is running to this delegate
@ -227,7 +230,7 @@ Folio.DelegateTouchArea {
onPressAndHold: {
let mappedCoords = root.homeScreen.prepareStartDelegateDrag(delegate.delegateModel, appDelegate.delegateItem);
Folio.HomeScreenState.startDelegateFolderDrag(
folio.HomeScreenState.startDelegateFolderDrag(
mappedCoords.x,
mappedCoords.y,
appDelegate.pressPosition.x,
@ -241,7 +244,7 @@ Folio.DelegateTouchArea {
onPressAndHoldReleased: {
// cancel the event if the delegate is not dragged
if (Folio.HomeScreenState.swipeState === Folio.HomeScreenState.AwaitingDraggingDelegate) {
if (folio.HomeScreenState.swipeState === Folio.HomeScreenState.AwaitingDraggingDelegate) {
homeScreen.cancelDelegateDrag();
}
}
@ -255,10 +258,10 @@ Folio.DelegateTouchArea {
// close menu when drag starts
Connections {
target: Folio.HomeScreenState
target: folio.HomeScreenState
function onSwipeStateChanged() {
if (Folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate) {
if (folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate) {
contextMenu.close();
}
}
@ -289,8 +292,8 @@ Folio.DelegateTouchArea {
y: Math.round((root.height / 2) + (folderBackground.height / 2) + Kirigami.Units.largeSpacing)
anchors.horizontalCenter: parent.horizontalCenter
currentIndex: Folio.HomeScreenState.currentFolderPage
count: Folio.HomeScreenState.currentFolder ? Folio.HomeScreenState.currentFolder.applications.numberOfPages : 0
currentIndex: folio.HomeScreenState.currentFolderPage
count: folio.HomeScreenState.currentFolder ? folio.HomeScreenState.currentFolder.applications.numberOfPages : 0
opacity: (root.opacity === 1) ? 1 : 0
Behavior on opacity {

View file

@ -13,12 +13,13 @@ import org.kde.private.mobile.homescreen.folio 1.0 as Folio
MobileShell.BaseItem {
id: root
property Folio.HomeScreen folio
property Folio.FolioApplicationFolder folder
property bool inFolderTitleEditMode: false
Connections {
target: Folio.HomeScreenState
target: folio.HomeScreenState
function onLeftCurrentFolder() {
root.inFolderTitleEditMode = false;

View file

@ -19,6 +19,8 @@ import "./settings"
Item {
id: root
property Folio.HomeScreen folio
property Folio.HomeScreenState homeScreenState: folio.HomeScreenState
property real topMargin: 0
property real bottomMargin: 0
@ -27,8 +29,6 @@ Item {
property bool interactive: true
property Folio.HomeScreenState homeScreenState: Folio.HomeScreenState
// non-widget drop animation
readonly property bool dropAnimationRunning: delegateDragItem.dropAnimationRunning || widgetDragItem.dropAnimationRunning
@ -38,10 +38,10 @@ Item {
// how much to scale out in the settings mode
readonly property real settingsModeHomeScreenScale: 0.8
onTopMarginChanged: Folio.HomeScreenState.viewTopPadding = root.topMargin
onBottomMarginChanged: Folio.HomeScreenState.viewBottomPadding = root.bottomMargin
onLeftMarginChanged: Folio.HomeScreenState.viewLeftPadding = root.leftMargin
onRightMarginChanged: Folio.HomeScreenState.viewRightPadding = root.rightMargin
onTopMarginChanged: folio.HomeScreenState.viewTopPadding = root.topMargin
onBottomMarginChanged: folio.HomeScreenState.viewBottomPadding = root.bottomMargin
onLeftMarginChanged: folio.HomeScreenState.viewLeftPadding = root.leftMargin
onRightMarginChanged: folio.HomeScreenState.viewRightPadding = root.rightMargin
// called by any delegates when starting drag
// returns the mapped coordinates to be used in the home screen state
@ -73,10 +73,10 @@ Item {
text: "M\nM"
visible: false
onHeightChanged: Folio.HomeScreenState.pageDelegateLabelHeight = appLabelMetrics.height
onHeightChanged: folio.HomeScreenState.pageDelegateLabelHeight = appLabelMetrics.height
Component.onCompleted: {
Folio.HomeScreenState.pageDelegateLabelWidth = Kirigami.Units.smallSpacing;
folio.HomeScreenState.pageDelegateLabelWidth = Kirigami.Units.smallSpacing;
}
}
@ -85,8 +85,8 @@ Item {
id: screenDimensions
anchors.fill: parent
onWidthChanged: Folio.HomeScreenState.viewWidth = width;
onHeightChanged: Folio.HomeScreenState.viewHeight = height;
onWidthChanged: folio.HomeScreenState.viewWidth = width;
onHeightChanged: folio.HomeScreenState.viewHeight = height;
}
// a way of stopping focus
@ -102,10 +102,10 @@ Item {
interactive: root.interactive &&
settings.homeScreenInteractive &&
(appDrawer.flickable.contentY <= 10 || // disable the swipe area when we are swiping in the app drawer, and not in drag-and-drop
Folio.HomeScreenState.swipeState === Folio.HomeScreenState.AwaitingDraggingDelegate ||
Folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate ||
Folio.HomeScreenState.swipeState === Folio.HomeScreenState.SwipingAppDrawerGrid ||
Folio.HomeScreenState.viewState !== Folio.HomeScreenState.AppDrawerView)
folio.HomeScreenState.swipeState === Folio.HomeScreenState.AwaitingDraggingDelegate ||
folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate ||
folio.HomeScreenState.swipeState === Folio.HomeScreenState.SwipingAppDrawerGrid ||
folio.HomeScreenState.viewState !== Folio.HomeScreenState.AppDrawerView)
onSwipeStarted: {
homeScreenState.swipeStarted();
@ -126,9 +126,10 @@ Item {
SettingsComponent {
id: settings
folio: root.folio
width: parent.width
height: parent.height
opacity: Folio.HomeScreenState.settingsOpenProgress
opacity: folio.HomeScreenState.settingsOpenProgress
z: 1
// move the settings out of the way if it is not visible
@ -160,12 +161,13 @@ Item {
HomeScreenPages {
id: homeScreenPages
folio: root.folio
homeScreen: root
anchors.topMargin: root.topMargin
anchors.leftMargin: Folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Left ? 0 : root.leftMargin
anchors.rightMargin: Folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Right ? 0 : root.rightMargin
anchors.bottomMargin: Folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Bottom ? 0 : root.bottomMargin
anchors.leftMargin: folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Left ? 0 : root.leftMargin
anchors.rightMargin: folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Right ? 0 : root.rightMargin
anchors.bottomMargin: folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Bottom ? 0 : root.bottomMargin
// update the model with page dimensions
onWidthChanged: {
@ -178,7 +180,7 @@ Item {
transform: [
Scale {
// animation when settings opens
property real scaleFactor: 1 - Folio.HomeScreenState.settingsOpenProgress * (1 - settingsModeHomeScreenScale)
property real scaleFactor: 1 - folio.HomeScreenState.settingsOpenProgress * (1 - settingsModeHomeScreenScale)
origin.x: root.leftMargin + (root.width - root.rightMargin - root.leftMargin) / 2
origin.y: root.height * settingsModeHomeScreenScale / 2
xScale: scaleFactor
@ -189,7 +191,7 @@ Item {
states: [
State {
name: "bottom"
when: Folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Bottom
when: folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Bottom
AnchorChanges {
target: homeScreenPages
anchors.top: parent.top
@ -199,7 +201,7 @@ Item {
}
}, State {
name: "left"
when: Folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Left
when: folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Left
AnchorChanges {
target: homeScreenPages
anchors.top: parent.top
@ -209,7 +211,7 @@ Item {
}
}, State {
name: "right"
when: Folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Right
when: folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Right
AnchorChanges {
target: homeScreenPages
anchors.top: parent.top
@ -226,29 +228,30 @@ Item {
color: Qt.rgba(255, 255, 255, 0.2)
// don't show in settings mode
opacity: 1 - Folio.HomeScreenState.settingsOpenProgress
visible: Folio.FolioSettings.showFavouritesBarBackground
opacity: 1 - folio.HomeScreenState.settingsOpenProgress
visible: folio.FolioSettings.showFavouritesBarBackground
anchors.top: Folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Bottom ? favouritesBar.top : parent.top
anchors.top: folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Bottom ? favouritesBar.top : parent.top
anchors.bottom: parent.bottom
anchors.left: Folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Right ? favouritesBar.left : parent.left
anchors.right: Folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Left ? favouritesBar.right : parent.right
anchors.left: folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Right ? favouritesBar.left : parent.left
anchors.right: folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Left ? favouritesBar.right : parent.right
// because of the scale animation, we need to extend the panel out a bit
anchors.topMargin: Folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Bottom ? 0 : -Kirigami.Units.gridUnit * 5
anchors.topMargin: folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Bottom ? 0 : -Kirigami.Units.gridUnit * 5
anchors.bottomMargin: -Kirigami.Units.gridUnit * 5
anchors.leftMargin: Folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Right ? 0 : -Kirigami.Units.gridUnit * 5
anchors.rightMargin: Folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Left ? 0 : -Kirigami.Units.gridUnit * 5
anchors.leftMargin: folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Right ? 0 : -Kirigami.Units.gridUnit * 5
anchors.rightMargin: folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Left ? 0 : -Kirigami.Units.gridUnit * 5
}
FavouritesBar {
id: favouritesBar
folio: root.folio
homeScreen: root
leftMargin: root.leftMargin
topMargin: root.topMargin
// don't show in settings mode
opacity: 1 - Folio.HomeScreenState.settingsOpenProgress
opacity: 1 - folio.HomeScreenState.settingsOpenProgress
visible: opacity > 0
// one is ignored as anchors are set
@ -263,7 +266,7 @@ Item {
states: [
State {
name: "bottom"
when: Folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Bottom
when: folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Bottom
AnchorChanges {
target: favouritesBar
anchors.top: undefined
@ -277,7 +280,7 @@ Item {
}
}, State {
name: "left"
when: Folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Left
when: folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Left
AnchorChanges {
target: favouritesBar
anchors.top: parent.top
@ -291,7 +294,7 @@ Item {
}
}, State {
name: "right"
when: Folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Right
when: folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Right
AnchorChanges {
target: favouritesBar
anchors.top: parent.top
@ -309,10 +312,10 @@ Item {
Item {
id: pageIndicatorWrapper
property bool favouritesBarAtBottom: Folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Bottom
property bool favouritesBarAtBottom: folio.HomeScreenState.favouritesBarLocation === Folio.HomeScreenState.Bottom
// don't show in settings mode
opacity: 1 - Folio.HomeScreenState.settingsOpenProgress
opacity: 1 - folio.HomeScreenState.settingsOpenProgress
anchors.top: parent.top
anchors.left: parent.left
@ -333,11 +336,11 @@ Item {
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
currentIndex: Folio.HomeScreenState.currentPage
count: Folio.PageListModel.length
currentIndex: folio.HomeScreenState.currentPage
count: folio.PageListModel.length
TapHandler {
onTapped: Folio.HomeScreenState.openAppDrawer()
onTapped: folio.HomeScreenState.openAppDrawer()
}
}
@ -346,18 +349,18 @@ Item {
source: 'arrow-up'
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
implicitHeight: Kirigami.Units.iconSizes.small
implicitWidth: Kirigami.Units.iconSizes.small
visible: Folio.PageListModel.length <= 1
visible: folio.PageListModel.length <= 1
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: Kirigami.Units.smallSpacing
TapHandler {
onTapped: Folio.HomeScreenState.openAppDrawer()
onTapped: folio.HomeScreenState.openAppDrawer()
}
}
}
@ -366,6 +369,7 @@ Item {
// folder view
FolderView {
id: folderView
folio: root.folio
anchors.fill: parent
anchors.topMargin: root.topMargin
anchors.leftMargin: root.leftMargin
@ -380,16 +384,19 @@ Item {
// drag and drop component
DelegateDragItem {
id: delegateDragItem
folio: root.folio
}
// drag and drop for widgets
WidgetDragItem {
id: widgetDragItem
folio: root.folio
}
// bottom app drawer
AppDrawer {
id: appDrawer
folio: root.folio
width: parent.width
height: parent.height
@ -416,7 +423,7 @@ Item {
rightPadding: root.rightMargin
Connections {
target: Folio.HomeScreenState
target: folio.HomeScreenState
function onAppDrawerClosed() {
// reset app drawer position when closed
@ -443,7 +450,7 @@ Item {
// focus the search bar if it opens
Connections {
target: Folio.HomeScreenState
target: folio.HomeScreenState
function onSearchWidgetOpenProgressChanged() {
if (homeScreenState.searchWidgetOpenProgress === 1.0) {

View file

@ -17,6 +17,7 @@ import "./private"
Item {
id: root
property Folio.HomeScreen folio
property int pageNum
@ -28,43 +29,44 @@ Item {
id: settingsViewBackground
anchors.fill: parent
color: Qt.rgba(255, 255, 255, 0.2)
opacity: Folio.HomeScreenState.settingsOpenProgress
opacity: folio.HomeScreenState.settingsOpenProgress
radius: Kirigami.Units.largeSpacing
}
// square that shows when hovering over a spot to drop a delegate on
PlaceholderDelegate {
id: dragDropFeedback
width: Folio.HomeScreenState.pageCellWidth
height: Folio.HomeScreenState.pageCellHeight
folio: root.folio
width: folio.HomeScreenState.pageCellWidth
height: folio.HomeScreenState.pageCellHeight
property var dropPosition: Folio.HomeScreenState.dragState.candidateDropPosition
property var dropDelegate: Folio.HomeScreenState.dragState.dropDelegate
property var dropPosition: folio.HomeScreenState.dragState.candidateDropPosition
property var dropDelegate: folio.HomeScreenState.dragState.dropDelegate
property bool dropDelegateIsWidget: dropDelegate && dropDelegate.type === Folio.FolioDelegate.Widget
// only show if it is an empty spot on this page
visible: Folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate &&
visible: folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate &&
dropPosition.location === Folio.DelegateDragPosition.Pages &&
dropPosition.page === root.pageNum &&
!dropDelegateIsWidget &&
Folio.HomeScreenState.getPageDelegateAt(root.pageNum, dropPosition.pageRow, dropPosition.pageColumn) === null
folio.HomeScreenState.getPageDelegateAt(root.pageNum, dropPosition.pageRow, dropPosition.pageColumn) === null
x: dropPosition.pageColumn * Folio.HomeScreenState.pageCellWidth
y: dropPosition.pageRow * Folio.HomeScreenState.pageCellHeight
x: dropPosition.pageColumn * folio.HomeScreenState.pageCellWidth
y: dropPosition.pageRow * folio.HomeScreenState.pageCellHeight
}
// square that shows when a widget hovers over a spot to drop a delegate on
Rectangle {
id: widgetDragDropFeedback
width: (dropDelegateIsWidget ? dropDelegate.widget.gridWidth : 0) * Folio.HomeScreenState.pageCellWidth
height: (dropDelegateIsWidget ? dropDelegate.widget.gridHeight : 0) * Folio.HomeScreenState.pageCellHeight
width: (dropDelegateIsWidget ? dropDelegate.widget.gridWidth : 0) * folio.HomeScreenState.pageCellWidth
height: (dropDelegateIsWidget ? dropDelegate.widget.gridHeight : 0) * folio.HomeScreenState.pageCellHeight
property var dropPosition: Folio.HomeScreenState.dragState.candidateDropPosition
property var dropDelegate: Folio.HomeScreenState.dragState.dropDelegate
property var dropPosition: folio.HomeScreenState.dragState.candidateDropPosition
property var dropDelegate: folio.HomeScreenState.dragState.dropDelegate
property bool dropDelegateIsWidget: dropDelegate && dropDelegate.type === Folio.FolioDelegate.Widget
// only show if the widget can be placed here
visible: Folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate &&
visible: folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate &&
dropPosition.location === Folio.DelegateDragPosition.Pages &&
dropPosition.page === root.pageNum &&
dropDelegateIsWidget &&
@ -73,8 +75,8 @@ Item {
radius: Kirigami.Units.smallSpacing
color: Qt.rgba(255, 255, 255, 0.3)
x: dropPosition.pageColumn * Folio.HomeScreenState.pageCellWidth
y: dropPosition.pageRow * Folio.HomeScreenState.pageCellHeight
x: dropPosition.pageColumn * folio.HomeScreenState.pageCellWidth
y: dropPosition.pageRow * folio.HomeScreenState.pageCellHeight
layer.enabled: true
layer.effect: DelegateShadow {}
@ -91,14 +93,14 @@ Item {
property int row: pageDelegate.row
property int column: pageDelegate.column
property var dragState: Folio.HomeScreenState.dragState
property var dragState: folio.HomeScreenState.dragState
property bool isDropPositionThis: dragState.candidateDropPosition.location === Folio.DelegateDragPosition.Pages &&
dragState.candidateDropPosition.page === root.pageNum &&
dragState.candidateDropPosition.pageRow === delegate.pageDelegate.row &&
dragState.candidateDropPosition.pageColumn === delegate.pageDelegate.column
property bool isAppHoveredOver: Folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate &&
property bool isAppHoveredOver: folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate &&
dragState.dropDelegate &&
dragState.dropDelegate.type === Folio.FolioDelegate.Application &&
isDropPositionThis
@ -108,20 +110,21 @@ Item {
width: loader.item ? loader.item.width : 0
height: loader.item ? loader.item.height : 0
x: column * Folio.HomeScreenState.pageCellWidth
y: row * Folio.HomeScreenState.pageCellHeight
x: column * folio.HomeScreenState.pageCellWidth
y: row * folio.HomeScreenState.pageCellHeight
visible: row >= 0 && row < Folio.HomeScreenState.pageRows &&
column >= 0 && column < Folio.HomeScreenState.pageColumns
visible: row >= 0 && row < folio.HomeScreenState.pageRows &&
column >= 0 && column < folio.HomeScreenState.pageColumns
// called when we want to delete this delegate
function removeSelf() {
// remove from model
root.pageModel.removeDelegate(delegate.row, delegate.column);
// delete empty pages at the end, and snap position to page that exists
Folio.PageListModel.deleteEmptyPagesAtEnd();
Folio.HomeScreenState.snapPage();
// TODO: this doesn't work, because the removeDelegate calls removes this entire object and the calls fail
// // delete empty pages at the end, and snap position to page that exists
// folio.PageListModel.deleteEmptyPagesAtEnd();
// folio.HomeScreenState.snapPage();
}
Loader {
@ -153,15 +156,16 @@ Item {
AppDelegate {
id: appDelegate
name: Folio.FolioSettings.showPagesAppLabels ? delegate.pageDelegate.application.name : ""
folio: root.folio
name: folio.FolioSettings.showPagesAppLabels ? delegate.pageDelegate.application.name : ""
application: delegate.pageDelegate.application
turnToFolder: delegate.isAppHoveredOver
turnToFolderAnimEnabled: Folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate
turnToFolderAnimEnabled: folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate
implicitWidth: Folio.HomeScreenState.pageCellWidth
implicitHeight: Folio.HomeScreenState.pageCellHeight
width: Folio.HomeScreenState.pageCellWidth
height: Folio.HomeScreenState.pageCellHeight
implicitWidth: folio.HomeScreenState.pageCellWidth
implicitHeight: folio.HomeScreenState.pageCellHeight
width: folio.HomeScreenState.pageCellWidth
height: folio.HomeScreenState.pageCellHeight
// do not show if the drop animation is running to this delegate
visible: !(root.homeScreen.dropAnimationRunning && delegate.isDropPositionThis)
@ -171,7 +175,7 @@ Item {
onPressAndHold: {
let mappedCoords = root.homeScreen.prepareStartDelegateDrag(delegate.pageDelegate, appDelegate.delegateItem);
Folio.HomeScreenState.startDelegatePageDrag(
folio.HomeScreenState.startDelegatePageDrag(
mappedCoords.x,
mappedCoords.y,
appDelegate.pressPosition.x,
@ -185,7 +189,7 @@ Item {
}
onPressAndHoldReleased: {
// cancel the event if the delegate is not dragged
if (Folio.HomeScreenState.swipeState === Folio.HomeScreenState.AwaitingDraggingDelegate) {
if (folio.HomeScreenState.swipeState === Folio.HomeScreenState.AwaitingDraggingDelegate) {
homeScreen.cancelDelegateDrag();
}
}
@ -199,10 +203,10 @@ Item {
// close menu when drag starts
Connections {
target: Folio.HomeScreenState
target: folio.HomeScreenState
function onSwipeStateChanged() {
if (Folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate) {
if (folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate) {
contextMenu.close();
}
}
@ -224,13 +228,14 @@ Item {
AppFolderDelegate {
id: appFolderDelegate
name: Folio.FolioSettings.showPagesAppLabels ? delegate.pageDelegate.folder.name : ""
folio: root.folio
name: folio.FolioSettings.showPagesAppLabels ? delegate.pageDelegate.folder.name : ""
folder: delegate.pageDelegate.folder
implicitWidth: Folio.HomeScreenState.pageCellWidth
implicitHeight: Folio.HomeScreenState.pageCellHeight
width: Folio.HomeScreenState.pageCellWidth
height: Folio.HomeScreenState.pageCellHeight
implicitWidth: folio.HomeScreenState.pageCellWidth
implicitHeight: folio.HomeScreenState.pageCellHeight
width: folio.HomeScreenState.pageCellWidth
height: folio.HomeScreenState.pageCellHeight
// do not show if the drop animation is running to this delegate, and the drop delegate is a folder
visible: !(root.homeScreen.dropAnimationRunning &&
@ -244,12 +249,12 @@ Item {
onAfterClickAnimation: {
const pos = homeScreen.prepareFolderOpen(appFolderDelegate.contentItem);
Folio.HomeScreenState.openFolder(pos.x, pos.y, folder);
folio.HomeScreenState.openFolder(pos.x, pos.y, folder);
}
onPressAndHold: {
let mappedCoords = root.homeScreen.prepareStartDelegateDrag(delegate.pageDelegate, appFolderDelegate.delegateItem);
Folio.HomeScreenState.startDelegatePageDrag(
folio.HomeScreenState.startDelegatePageDrag(
mappedCoords.x,
mappedCoords.y,
appFolderDelegate.pressPosition.x,
@ -264,7 +269,7 @@ Item {
onPressAndHoldReleased: {
// cancel the event if the delegate is not dragged
if (Folio.HomeScreenState.swipeState === Folio.HomeScreenState.AwaitingDraggingDelegate) {
if (folio.HomeScreenState.swipeState === Folio.HomeScreenState.AwaitingDraggingDelegate) {
homeScreen.cancelDelegateDrag();
}
}
@ -278,10 +283,10 @@ Item {
// close menu when drag starts
Connections {
target: Folio.HomeScreenState
target: folio.HomeScreenState
function onSwipeStateChanged() {
if (Folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate) {
if (folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate) {
contextMenu.close();
}
}
@ -309,6 +314,7 @@ Item {
WidgetDelegate {
id: widgetDelegate
folio: root.folio
// don't reparent applet if the drop animation is running to this delegate
// background: there is only one "visual" instance of the widget, once this delegate loads
@ -321,7 +327,7 @@ Item {
onStartEditMode: (pressPoint) => {
let mappedCoords = root.homeScreen.prepareStartDelegateDrag(delegate.pageDelegate, widgetDelegate);
Folio.HomeScreenState.startDelegatePageDrag(
folio.HomeScreenState.startDelegatePageDrag(
mappedCoords.x,
mappedCoords.y,
pressPoint.x - mappedCoords.x,
@ -336,8 +342,8 @@ Item {
onPressReleased: {
// cancel the event if the delegate is not dragged
if (Folio.HomeScreenState.swipeState === Folio.HomeScreenState.AwaitingDraggingDelegate) {
Folio.HomeScreenState.cancelDelegateDrag();
if (folio.HomeScreenState.swipeState === Folio.HomeScreenState.AwaitingDraggingDelegate) {
folio.HomeScreenState.cancelDelegateDrag();
widgetConfig.fullyOpen();
}
}
@ -352,6 +358,7 @@ Item {
WidgetDelegateConfig {
id: widgetConfig
folio: root.folio
homeScreen: root.homeScreen
pageModel: root.pageModel

View file

@ -11,19 +11,21 @@ import org.kde.private.mobile.homescreen.folio 1.0 as Folio
MouseArea {
id: root
property Folio.HomeScreen folio
property var homeScreen
readonly property real verticalMargin: Math.round((Folio.HomeScreenState.pageHeight - Folio.HomeScreenState.pageContentHeight) / 2)
readonly property real horizontalMargin: Math.round((Folio.HomeScreenState.pageWidth - Folio.HomeScreenState.pageContentWidth) / 2)
readonly property real verticalMargin: Math.round((folio.HomeScreenState.pageHeight - folio.HomeScreenState.pageContentHeight) / 2)
readonly property real horizontalMargin: Math.round((folio.HomeScreenState.pageWidth - folio.HomeScreenState.pageContentWidth) / 2)
onPressAndHold: Folio.HomeScreenState.openSettingsView()
onPressAndHold: folio.HomeScreenState.openSettingsView()
Repeater {
model: Folio.PageListModel
model: folio.PageListModel
delegate: HomeScreenPage {
id: homeScreenPage
folio: root.folio
pageNum: model.index
pageModel: model.delegate
homeScreen: root.homeScreen
@ -35,13 +37,13 @@ MouseArea {
anchors.bottomMargin: root.verticalMargin
// animation so that full opacity is only when the page is in view
readonly property real distanceToCenter: Math.abs(-Folio.HomeScreenState.pageViewX - root.width * pageNum)
readonly property real positionX: root.width * index + Folio.HomeScreenState.pageViewX
readonly property real distanceToCenter: Math.abs(-folio.HomeScreenState.pageViewX - root.width * pageNum)
readonly property real positionX: root.width * index + folio.HomeScreenState.pageViewX
readonly property real progressToCenter: 1 - Math.min(1, Math.max(0, distanceToCenter / root.width))
visible: opacity > 0
opacity: {
switch (Folio.FolioSettings.pageTransitionEffect) {
switch (folio.FolioSettings.pageTransitionEffect) {
case Folio.FolioSettings.StackTransition:
return (positionX < 0) ? progressToCenter :
((progressToCenter < 0.3) ? 0 : ((1 / 0.7) * (progressToCenter - 0.3)))
@ -52,7 +54,7 @@ MouseArea {
// x position of page
transform: {
switch (Folio.FolioSettings.pageTransitionEffect) {
switch (folio.FolioSettings.pageTransitionEffect) {
case Folio.FolioSettings.SlideTransition:
return [translate];
case Folio.FolioSettings.CubeTransition:
@ -75,8 +77,8 @@ MouseArea {
Scale {
id: stackScale
origin.x: Folio.HomeScreenState.pageWidth / 2
origin.y: Folio.HomeScreenState.pageHeight / 2
origin.x: folio.HomeScreenState.pageWidth / 2
origin.y: folio.HomeScreenState.pageHeight / 2
xScale: (homeScreenPage.positionX < 0) ? 1 : 0.5 + homeScreenPage.progressToCenter * 0.5
yScale: (homeScreenPage.positionX < 0) ? 1 : 0.5 + homeScreenPage.progressToCenter * 0.5
}
@ -89,8 +91,8 @@ MouseArea {
Rotation {
id: cubeTransitionRotation
origin.x: (positionX < 0) ?
(Folio.HomeScreenState.pageWidth / 2) * homeScreenPage.progressToCenter :
(Folio.HomeScreenState.pageWidth / 2) + (Folio.HomeScreenState.pageWidth / 2) * (1 - homeScreenPage.progressToCenter);
(folio.HomeScreenState.pageWidth / 2) * homeScreenPage.progressToCenter :
(folio.HomeScreenState.pageWidth / 2) + (folio.HomeScreenState.pageWidth / 2) * (1 - homeScreenPage.progressToCenter);
origin.y: Folio.HomeScreenState.pageHeight / 2;
axis { x: 0; y: 1; z: 0 }
angle: {
@ -101,8 +103,8 @@ MouseArea {
Rotation {
id: rotationTransitionRotation
origin.x: (positionX < 0) ?
(Folio.HomeScreenState.pageWidth / 2) * homeScreenPage.progressToCenter :
(Folio.HomeScreenState.pageWidth / 2) + (Folio.HomeScreenState.pageWidth / 2) * (1 - homeScreenPage.progressToCenter);
(folio.HomeScreenState.pageWidth / 2) * homeScreenPage.progressToCenter :
(folio.HomeScreenState.pageWidth / 2) + (folio.HomeScreenState.pageWidth / 2) * (1 - homeScreenPage.progressToCenter);
origin.y: 0
axis { x: -0.2; y: 0.3; z: 0.5 }
angle: {

View file

@ -11,8 +11,10 @@ import "./delegate"
Item {
id: root
width: Folio.HomeScreenState.pageCellWidth
height: Folio.HomeScreenState.pageCellHeight
property Folio.HomeScreen folio
width: folio.HomeScreenState.pageCellWidth
height: folio.HomeScreenState.pageCellHeight
// we need to simulate the position of the icon if it is placed at this spot
ColumnLayout {
@ -26,8 +28,8 @@ Item {
radius: Kirigami.Units.largeSpacing
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
Layout.minimumWidth: Folio.FolioSettings.delegateIconSize
Layout.minimumHeight: Folio.FolioSettings.delegateIconSize
Layout.minimumWidth: folio.FolioSettings.delegateIconSize
Layout.minimumHeight: folio.FolioSettings.delegateIconSize
Layout.preferredHeight: Layout.minimumHeight
layer.enabled: true
layer.effect: DelegateShadow {}
@ -38,8 +40,8 @@ Item {
id: label
opacity: 0
Layout.fillWidth: true
Layout.preferredHeight: Folio.HomeScreenState.pageDelegateLabelHeight
Layout.topMargin: Folio.HomeScreenState.pageDelegateLabelSpacing
Layout.preferredHeight: folio.HomeScreenState.pageDelegateLabelHeight
Layout.topMargin: folio.HomeScreenState.pageDelegateLabelSpacing
}
}
}

View file

@ -18,17 +18,19 @@ import './private'
Item {
id: root
property Folio.HomeScreen folio
width: widgetLoader.item ? widgetLoader.item.width : 0
height: widgetLoader.item ? widgetLoader.item.height : 0
property Folio.FolioWidget widget
readonly property bool isWidgetDelegate: Folio.HomeScreenState.dragState.dropDelegate && Folio.HomeScreenState.dragState.dropDelegate.type === Folio.FolioDelegate.Widget
readonly property bool isWidgetDelegate: folio.HomeScreenState.dragState.dropDelegate && folio.HomeScreenState.dragState.dropDelegate.type === Folio.FolioDelegate.Widget
readonly property bool dropAnimationRunning: dragXAnim.running || dragYAnim.running
visible: false
x: Math.round(Folio.HomeScreenState.delegateDragX)
y: Math.round(Folio.HomeScreenState.delegateDragY)
x: Math.round(folio.HomeScreenState.delegateDragX)
y: Math.round(folio.HomeScreenState.delegateDragY)
function startDrag(widget) {
root.widget = widget;
@ -36,10 +38,10 @@ Item {
}
function setXBinding() {
x = Qt.binding(() => Math.round(Folio.HomeScreenState.delegateDragX));
x = Qt.binding(() => Math.round(folio.HomeScreenState.delegateDragX));
}
function setYBinding() {
y = Qt.binding(() => Math.round(Folio.HomeScreenState.delegateDragY));
y = Qt.binding(() => Math.round(folio.HomeScreenState.delegateDragY));
}
// animate drop x
@ -70,20 +72,20 @@ Item {
Connections {
id: stateWatcher
target: Folio.HomeScreenState
target: folio.HomeScreenState
function onSwipeStateChanged() {
if (Folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate &&
Folio.HomeScreenState.dragState.dropDelegate &&
Folio.HomeScreenState.dragState.dropDelegate.type === Folio.FolioDelegate.Widget) {
if (folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate &&
folio.HomeScreenState.dragState.dropDelegate &&
folio.HomeScreenState.dragState.dropDelegate.type === Folio.FolioDelegate.Widget) {
root.startDrag(Folio.HomeScreenState.dragState.dropDelegate.widget);
root.startDrag(folio.HomeScreenState.dragState.dropDelegate.widget);
}
}
}
Connections {
target: Folio.HomeScreenState.dragState
target: folio.HomeScreenState.dragState
// animate from when the delegate is dropped to its drop position
function onDelegateDroppedAndPlaced() {
@ -91,10 +93,10 @@ Item {
return;
}
let dragState = Folio.HomeScreenState.dragState;
let dragState = folio.HomeScreenState.dragState;
let dropPosition = dragState.candidateDropPosition;
let pos = Folio.HomeScreenState.getPageDelegateScreenPosition(dropPosition.page, dropPosition.pageRow, dropPosition.pageColumn);
let pos = folio.HomeScreenState.getPageDelegateScreenPosition(dropPosition.page, dropPosition.pageRow, dropPosition.pageColumn);
dragXAnim.to = pos.x;
dragYAnim.to = pos.y;
@ -114,6 +116,7 @@ Item {
active: root.widget
sourceComponent: WidgetDelegate {
folio: root.folio
widget: root.widget
layer.enabled: true

View file

@ -16,7 +16,8 @@ import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
import org.kde.plasma.private.mobileshell as MobileShell
Folio.DelegateTouchArea {
id: delegate
id: root
property Folio.HomeScreen folio
property string name
property bool shadow: false
@ -37,7 +38,7 @@ Folio.DelegateTouchArea {
duration: ShellSettings.Settings.animationsEnabled ? 80 : 1
to: ShellSettings.Settings.animationsEnabled ? 0.8 : 1
onFinished: {
if (!delegate.pressed) {
if (!root.pressed) {
growAnim.restart();
}
}
@ -49,9 +50,9 @@ Folio.DelegateTouchArea {
duration: ShellSettings.Settings.animationsEnabled ? 80 : 1
to: 1
onFinished: {
if (delegate.clickRequested) {
delegate.afterClickAnimation();
delegate.clickRequested = false;
if (root.clickRequested) {
root.afterClickAnimation();
root.clickRequested = false;
}
}
}
@ -68,7 +69,7 @@ Folio.DelegateTouchArea {
// trigger handled by press animation
onClicked: clickRequested = true;
layer.enabled: delegate.shadow
layer.enabled: root.shadow
layer.effect: DelegateShadow {}
Item {
@ -83,24 +84,24 @@ Folio.DelegateTouchArea {
// affects the delegate's x and y position, which messes up the starting drag and drop
// position (for mapFromItem in HomeScreen.qml)
transform: Scale {
origin.x: delegate.width / 2;
origin.y: delegate.height / 2;
xScale: delegate.zoomScale
yScale: delegate.zoomScale
origin.x: root.width / 2;
origin.y: root.height / 2;
xScale: root.zoomScale
yScale: root.zoomScale
}
MobileShell.BaseItem {
id: visualItem
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
Layout.minimumWidth: Folio.FolioSettings.delegateIconSize
Layout.minimumHeight: Folio.FolioSettings.delegateIconSize
Layout.minimumWidth: folio.FolioSettings.delegateIconSize
Layout.minimumHeight: folio.FolioSettings.delegateIconSize
Layout.preferredHeight: Layout.minimumHeight
// darken effect when hovered
// TODO: removed for now, since hovered property seems to overlap with the touch pressed event
// layer {
// enabled: delegate.hovered
// enabled: root.hovered
// effect: ColorOverlay {
// color: Qt.rgba(0, 0, 0, 0.3)
// }
@ -112,12 +113,12 @@ Folio.DelegateTouchArea {
opacity: text.length > 0
Layout.fillWidth: true
Layout.preferredHeight: Folio.HomeScreenState.pageDelegateLabelHeight
Layout.topMargin: Folio.HomeScreenState.pageDelegateLabelSpacing
Layout.preferredHeight: folio.HomeScreenState.pageDelegateLabelHeight
Layout.topMargin: folio.HomeScreenState.pageDelegateLabelSpacing
Layout.leftMargin: -parent.anchors.leftMargin + Kirigami.Units.smallSpacing
Layout.rightMargin: -parent.anchors.rightMargin + Kirigami.Units.smallSpacing
text: delegate.name
text: root.name
color: "white"
}
}

View file

@ -14,6 +14,7 @@ import org.kde.plasma.private.mobileshell as MobileShell
AbstractDelegate {
id: root
shadow: true
name: application.name
@ -43,8 +44,8 @@ AbstractDelegate {
}
contentItem: Item {
height: Folio.FolioSettings.delegateIconSize
width: Folio.FolioSettings.delegateIconSize
height: folio.FolioSettings.delegateIconSize
width: folio.FolioSettings.delegateIconSize
// background for folder creation animation
Rectangle {
@ -76,6 +77,7 @@ AbstractDelegate {
// app icon
DelegateAppIcon {
id: icon
folio: root.folio
anchors.fill: parent
source: root.application.icon

View file

@ -18,6 +18,7 @@ AbstractDelegate {
property bool appHoveredOver: false
contentItem: DelegateFolderIcon {
folio: root.folio
folder: root.folder
expandBackground: root.appHoveredOver
}

View file

@ -12,7 +12,8 @@ import org.kde.private.mobile.homescreen.folio 1.0 as Folio
Kirigami.Icon {
id: root
property Folio.HomeScreen folio
height: Folio.FolioSettings.delegateIconSize
width: Folio.FolioSettings.delegateIconSize
height: folio.FolioSettings.delegateIconSize
width: folio.FolioSettings.delegateIconSize
}

View file

@ -12,13 +12,14 @@ import org.kde.private.mobile.homescreen.folio 1.0 as Folio
Item {
id: root
property Folio.HomeScreen folio
property Folio.FolioApplicationFolder folder
property bool expandBackground: false
height: Folio.FolioSettings.delegateIconSize
width: Folio.FolioSettings.delegateIconSize
height: folio.FolioSettings.delegateIconSize
width: folio.FolioSettings.delegateIconSize
Rectangle {
id: rect

View file

@ -12,9 +12,10 @@ import org.kde.private.mobile.homescreen.folio 1.0 as Folio
Loader {
id: root
property Folio.HomeScreen folio
height: Folio.FolioSettings.delegateIconSize
width: Folio.FolioSettings.delegateIconSize
height: folio.FolioSettings.delegateIconSize
width: folio.FolioSettings.delegateIconSize
property Folio.FolioDelegate delegate
@ -39,6 +40,7 @@ Loader {
id: appIcon
DelegateAppIcon {
folio: root.folio
source: delegate.application.icon
}
}
@ -47,6 +49,7 @@ Loader {
id: folderIcon
DelegateFolderIcon {
folio: root.folio
folder: delegate.folder
}
}

View file

@ -17,6 +17,7 @@ import '../private'
Folio.WidgetContainer {
id: root
property Folio.HomeScreen folio
property Folio.FolioWidget widget
@ -28,8 +29,8 @@ Folio.WidgetContainer {
readonly property real leftWidgetBackgroundPadding: widgetBackground.margins.left
readonly property real rightWidgetBackgroundPadding: widgetBackground.margins.right
implicitWidth: (widget ? widget.gridWidth : 0) * Folio.HomeScreenState.pageCellWidth
implicitHeight: (widget ? widget.gridHeight : 0) * Folio.HomeScreenState.pageCellHeight
implicitWidth: (widget ? widget.gridWidth : 0) * folio.HomeScreenState.pageCellWidth
implicitHeight: (widget ? widget.gridHeight : 0) * folio.HomeScreenState.pageCellHeight
width: implicitWidth
height: implicitHeight

View file

@ -17,6 +17,7 @@ import '../private'
Item {
id: root
property Folio.HomeScreen folio
property var homeScreen
@ -85,11 +86,11 @@ Item {
}
Connections {
target: Folio.HomeScreenState
target: folio.HomeScreenState
// if we are starting drag-and-drop, close the menu immediately
function onSwipeStateChanged() {
if (Folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate) {
if (folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate) {
configOverlay.animClose();
root.closed();
}
@ -104,7 +105,7 @@ Item {
}
}
// this is the actual interactive popup for widget settings, only
// this is the actual interactive popup for widget settings, only
// opened when the user releases their press (and doesn't drag)
QQC2.Popup {
id: configPopup
@ -136,7 +137,7 @@ Item {
}
Connections {
target: Folio.HomeScreenState
target: folio.HomeScreenState
// don't show config overlay if we have navigated to another page
function onCurrentPageChanged() {
@ -153,6 +154,7 @@ Item {
WidgetResizeHandleFrame {
id: resizeFrame
folio: root.folio
anchors.fill: parent
widgetWidth: root.widgetWidth

View file

@ -20,12 +20,12 @@ import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
ContainmentItem {
id: root
property Folio.HomeScreen folio: root.plasmoid
Component.onCompleted: {
Folio.FolioSettings.load();
Folio.ApplicationListModel.load();
Folio.FavouritesModel.load();
Folio.PageListModel.load();
folio.FolioSettings.load();
folio.FavouritesModel.load();
folio.PageListModel.load();
// ensure the gestures work immediately on load
forceActiveFocus();
@ -33,7 +33,7 @@ ContainmentItem {
Loader {
id: wallpaperBlurLoader
active: Folio.FolioSettings.showWallpaperBlur
active: folio.FolioSettings.showWallpaperBlur
anchors.fill: parent
sourceComponent: Item {
@ -60,12 +60,12 @@ ContainmentItem {
source: controlledWallpaperSource
anchors.fill: parent
visible: opacity > 0
opacity: Math.min(1,
opacity: Math.min(1,
Math.max(
1 - homeScreen.contentOpacity,
Folio.HomeScreenState.appDrawerOpenProgress * 2, // blur faster during swipe
Folio.HomeScreenState.searchWidgetOpenProgress * 1.5, // blur faster during swipe
Folio.HomeScreenState.folderOpenProgress
folio.HomeScreenState.appDrawerOpenProgress * 2, // blur faster during swipe
folio.HomeScreenState.searchWidgetOpenProgress * 1.5, // blur faster during swipe
folio.HomeScreenState.folderOpenProgress
)
)
}
@ -83,30 +83,30 @@ ContainmentItem {
if (isInWindow) {
// only minimize windows and go to homescreen when not in docked mode
if (!ShellSettings.Settings.convergenceModeEnabled) {
Folio.HomeScreenState.closeFolder();
Folio.HomeScreenState.closeSearchWidget();
Folio.HomeScreenState.closeAppDrawer();
Folio.HomeScreenState.goToPage(0);
folio.HomeScreenState.closeFolder();
folio.HomeScreenState.closeSearchWidget();
folio.HomeScreenState.closeAppDrawer();
folio.HomeScreenState.goToPage(0);
WindowPlugin.WindowUtil.minimizeAll();
}
} else { // if we are on the homescreen
switch (Folio.HomeScreenState.viewState) {
switch (folio.HomeScreenState.viewState) {
case Folio.HomeScreenState.PageView:
if (Folio.HomeScreenState.currentPage === 0) {
Folio.HomeScreenState.openAppDrawer();
if (folio.HomeScreenState.currentPage === 0) {
folio.HomeScreenState.openAppDrawer();
} else {
Folio.HomeScreenState.goToPage(0);
folio.HomeScreenState.goToPage(0);
}
break;
case Folio.HomeScreenState.AppDrawerView:
Folio.HomeScreenState.closeAppDrawer();
folio.HomeScreenState.closeAppDrawer();
break;
case Folio.HomeScreenState.SearchWidgetView:
Folio.HomeScreenState.closeSearchWidget();
folio.HomeScreenState.closeSearchWidget();
break;
case Folio.HomeScreenState.FolderView:
Folio.HomeScreenState.closeFolder();
folio.HomeScreenState.closeFolder();
break;
}
}
@ -119,7 +119,7 @@ ContainmentItem {
anchors.fill: parent
color: Qt.rgba(0, 0, 0, 0.6)
opacity: Folio.HomeScreenState.appDrawerOpenProgress
opacity: folio.HomeScreenState.appDrawerOpenProgress
}
Rectangle {
@ -127,7 +127,7 @@ ContainmentItem {
anchors.fill: parent
color: Qt.rgba(0, 0, 0, 0.3)
opacity: Folio.HomeScreenState.searchWidgetOpenProgress
opacity: folio.HomeScreenState.searchWidgetOpenProgress
}
Rectangle {
@ -135,7 +135,7 @@ ContainmentItem {
anchors.fill: parent
color: Qt.rgba(0, 0, 0, 0.3)
opacity: Folio.HomeScreenState.settingsOpenProgress
opacity: folio.HomeScreenState.settingsOpenProgress
}
MobileShell.HomeScreen {
@ -154,6 +154,7 @@ ContainmentItem {
// homescreen component
HomeScreen {
id: folioHomeScreen
folio: root.folio
anchors.fill: parent
topMargin: homeScreen.topMargin
@ -168,7 +169,7 @@ ContainmentItem {
// listen to app launch errors
Connections {
target: Folio.ApplicationListModel
target: folio.ApplicationListModel
function onLaunchError(msg) {
MobileShellState.ShellDBusClient.closeAppLaunchAnimation()
}

View file

@ -13,6 +13,7 @@ import '../delegate'
Item {
id: root
property Folio.HomeScreen folio
// given by parent:
@ -117,16 +118,16 @@ Item {
handleContainer.height = root.startDragHeight + bottomEdgeDelta + topEdgeDelta;
// update the widget dimensions and position
const columnsMovedRight = Math.round((handleContainer.x - root.startX) / Folio.HomeScreenState.pageCellWidth);
const rowsMovedDown = Math.round((handleContainer.y - root.startY) / Folio.HomeScreenState.pageCellHeight);
const columnsMovedRight = Math.round((handleContainer.x - root.startX) / folio.HomeScreenState.pageCellWidth);
const rowsMovedDown = Math.round((handleContainer.y - root.startY) / folio.HomeScreenState.pageCellHeight);
const realWidgetWidth = handleContainer.width + widgetLeftMargin + widgetRightMargin;
const realWidgetHeight = handleContainer.height + widgetTopMargin + widgetBottomMargin;
const widgetRowAfterDrag = startWidgetRow + rowsMovedDown;
const widgetColumnAfterDrag = startWidgetColumn + columnsMovedRight;
const widgetGridWidthAfterDrag = Math.round(realWidgetWidth / Folio.HomeScreenState.pageCellWidth);
const widgetGridHeightAfterDrag = Math.round(realWidgetHeight / Folio.HomeScreenState.pageCellHeight);
const widgetGridWidthAfterDrag = Math.round(realWidgetWidth / folio.HomeScreenState.pageCellWidth);
const widgetGridHeightAfterDrag = Math.round(realWidgetHeight / folio.HomeScreenState.pageCellHeight);
root.widgetChangeAfterDrag(widgetRowAfterDrag, widgetColumnAfterDrag, widgetGridWidthAfterDrag, widgetGridHeightAfterDrag);
}

View file

@ -19,6 +19,7 @@ import '../private'
MouseArea {
id: root
property Folio.HomeScreen folio
property var homeScreen
@ -116,13 +117,13 @@ MouseArea {
onPressAndHold: {
root.requestClose();
Folio.HomeScreenState.closeSettingsView();
folio.HomeScreenState.closeSettingsView();
let mappedCoords = root.homeScreen.prepareStartDelegateDrag(null, delegate);
const widthOffset = Folio.HomeScreenState.pageCellWidth / 2;
const heightOffset = Folio.HomeScreenState.pageCellHeight / 2;
Folio.HomeScreenState.startDelegateWidgetListDrag(
const widthOffset = folio.HomeScreenState.pageCellWidth / 2;
const heightOffset = folio.HomeScreenState.pageCellHeight / 2;
folio.HomeScreenState.startDelegateWidgetListDrag(
mappedCoords.x + mouseX - widthOffset,
mappedCoords.y + mouseY - heightOffset,
widthOffset,

View file

@ -16,6 +16,7 @@ import '../delegate'
Item {
id: root
property Folio.HomeScreen folio
property var homeScreen
property real settingsModeHomeScreenScale
@ -31,7 +32,7 @@ Item {
anchors.bottom: settingsBar.top
onClicked: {
Folio.HomeScreenState.closeSettingsView();
folio.HomeScreenState.closeSettingsView();
}
}
@ -66,7 +67,7 @@ Item {
implicitHeight: Kirigami.Units.iconSizes.smallMedium
source: 'edit-image'
}
QQC2.Label {
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
text: i18n('Wallpapers')
@ -76,7 +77,7 @@ Item {
onClicked: {
wallpaperSelectorLoader.active = true;
Folio.HomeScreenState.closeSettingsView();
folio.HomeScreenState.closeSettingsView();
}
}
@ -94,7 +95,7 @@ Item {
implicitHeight: Kirigami.Units.iconSizes.smallMedium
source: 'settings-configure'
}
QQC2.Label {
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
text: i18n('Settings')
@ -123,7 +124,7 @@ Item {
implicitHeight: Kirigami.Units.iconSizes.smallMedium
source: 'widget-alternatives'
}
QQC2.Label {
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
text: i18n('Widgets')
@ -140,6 +141,7 @@ Item {
AppletListViewer {
id: appletListViewer
folio: root.folio
width: parent.width
height: parent.height
@ -162,6 +164,7 @@ Item {
SettingsWindow {
id: settingsWindow
folio: root.folio
visible: false
onRequestConfigureMenu: {

View file

@ -16,6 +16,8 @@ import '../delegate'
Window {
id: root
property Folio.HomeScreen folio
flags: Qt.FramelessWindowHint
color: 'transparent'
@ -92,18 +94,19 @@ Window {
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
Item {
Layout.preferredHeight: Folio.HomeScreenState.pageCellHeight
Layout.preferredHeight: folio.HomeScreenState.pageCellHeight
Layout.fillWidth: true
AbstractDelegate {
folio: root.folio
anchors.centerIn: parent
implicitHeight: Folio.HomeScreenState.pageCellHeight
implicitWidth: Folio.HomeScreenState.pageCellWidth
implicitHeight: folio.HomeScreenState.pageCellHeight
implicitWidth: folio.HomeScreenState.pageCellWidth
name: i18n('Application')
contentItem: DelegateAppIcon {
height: Folio.FolioSettings.delegateIconSize
width: Folio.FolioSettings.delegateIconSize
height: folio.FolioSettings.delegateIconSize
width: folio.FolioSettings.delegateIconSize
source: 'applications-system'
}
}
@ -112,8 +115,8 @@ Window {
FormCard.FormCard {
id: iconsCard
readonly property bool isVerticalOrientation: Folio.HomeScreenState.pageOrientation === Folio.HomeScreenState.RegularPosition ||
Folio.HomeScreenState.pageOrientation === Folio.HomeScreenState.RotateUpsideDown
readonly property bool isVerticalOrientation: folio.HomeScreenState.pageOrientation === Folio.HomeScreenState.RegularPosition ||
folio.HomeScreenState.pageOrientation === Folio.HomeScreenState.RotateUpsideDown
readonly property string numOfRowsText: i18n("Number of rows")
readonly property string numOfColumnsText: i18n("Number of columns")
@ -123,10 +126,10 @@ Window {
label: i18n("Size of icons on homescreen")
from: 16
to: 128
value: Folio.FolioSettings.delegateIconSize
value: folio.FolioSettings.delegateIconSize
onValueChanged: {
if (value !== Folio.FolioSettings.delegateIconSize) {
Folio.FolioSettings.delegateIconSize = value;
if (value !== folio.FolioSettings.delegateIconSize) {
folio.FolioSettings.delegateIconSize = value;
}
}
}
@ -136,10 +139,10 @@ Window {
label: iconsCard.isVerticalOrientation ? iconsCard.numOfRowsText : iconsCard.numOfColumnsText
from: 3
to: 10
value: Folio.FolioSettings.homeScreenRows
value: folio.FolioSettings.homeScreenRows
onValueChanged: {
if (value !== Folio.FolioSettings.homeScreenRows) {
Folio.FolioSettings.homeScreenRows = value;
if (value !== folio.FolioSettings.homeScreenRows) {
folio.FolioSettings.homeScreenRows = value;
}
}
}
@ -149,10 +152,10 @@ Window {
label: iconsCard.isVerticalOrientation ? iconsCard.numOfColumnsText : iconsCard.numOfRowsText
from: 3
to: 10
value: Folio.FolioSettings.homeScreenColumns
value: folio.FolioSettings.homeScreenColumns
onValueChanged: {
if (value !== Folio.FolioSettings.homeScreenColumns) {
Folio.FolioSettings.homeScreenColumns = value;
if (value !== folio.FolioSettings.homeScreenColumns) {
folio.FolioSettings.homeScreenColumns = value;
}
}
}
@ -170,10 +173,10 @@ Window {
FormCard.FormSwitchDelegate {
id: showLabelsOnHomeScreen
text: i18n("Show labels on homescreen")
checked: Folio.FolioSettings.showPagesAppLabels
checked: folio.FolioSettings.showPagesAppLabels
onCheckedChanged: {
if (checked != Folio.FolioSettings.showPagesAppLabels) {
Folio.FolioSettings.showPagesAppLabels = checked;
if (checked != folio.FolioSettings.showPagesAppLabels) {
folio.FolioSettings.showPagesAppLabels = checked;
}
}
}
@ -183,10 +186,10 @@ Window {
FormCard.FormSwitchDelegate {
id: showLabelsInFavourites
text: i18n("Show labels in favorites bar")
checked: Folio.FolioSettings.showFavouritesAppLabels
checked: folio.FolioSettings.showFavouritesAppLabels
onCheckedChanged: {
if (checked != Folio.FolioSettings.showFavouritesAppLabels) {
Folio.FolioSettings.showFavouritesAppLabels = checked;
if (checked != folio.FolioSettings.showFavouritesAppLabels) {
folio.FolioSettings.showFavouritesAppLabels = checked;
}
}
}
@ -197,7 +200,7 @@ Window {
id: pageTransitionCombobox
text: i18n("Page transition effect")
currentIndex: indexOfValue(Folio.FolioSettings.pageTransitionEffect)
currentIndex: indexOfValue(folio.FolioSettings.pageTransitionEffect)
model: ListModel {
// we can't use i18n with ListElement
Component.onCompleted: {
@ -208,14 +211,14 @@ Window {
append({"name": i18n("Rotation"), "value": Folio.FolioSettings.RotationTransition});
// indexOfValue doesn't bind to model changes unfortunately, set currentIndex manually here
pageTransitionCombobox.currentIndex = pageTransitionCombobox.indexOfValue(Folio.FolioSettings.pageTransitionEffect)
pageTransitionCombobox.currentIndex = pageTransitionCombobox.indexOfValue(folio.FolioSettings.pageTransitionEffect)
}
}
textRole: "name"
valueRole: "value"
onCurrentValueChanged: Folio.FolioSettings.pageTransitionEffect = currentValue
onCurrentValueChanged: folio.FolioSettings.pageTransitionEffect = currentValue
}
}
@ -227,10 +230,10 @@ Window {
FormCard.FormSwitchDelegate {
text: i18n('Show background')
icon.name: 'draw-rectangle'
checked: Folio.FolioSettings.showFavouritesBarBackground
checked: folio.FolioSettings.showFavouritesBarBackground
onCheckedChanged: {
if (checked !== Folio.FolioSettings.showFavouritesBarBackground) {
Folio.FolioSettings.showFavouritesBarBackground = checked;
if (checked !== folio.FolioSettings.showFavouritesBarBackground) {
folio.FolioSettings.showFavouritesBarBackground = checked;
}
}
}
@ -244,10 +247,10 @@ Window {
FormCard.FormSwitchDelegate {
id: showWallpaperBlur
text: i18nc("@option:check", "Show wallpaper blur effect")
checked: Folio.FolioSettings.showWallpaperBlur
checked: folio.FolioSettings.showWallpaperBlur
onCheckedChanged: {
if (checked != Folio.FolioSettings.showWallpaperBlur) {
Folio.FolioSettings.showWallpaperBlur = checked;
if (checked != folio.FolioSettings.showWallpaperBlur) {
folio.FolioSettings.showWallpaperBlur = checked;
}
}
}
@ -295,7 +298,7 @@ Window {
onAccepted: {
console.log('saving layout to ' + selectedFile);
if (selectedFile) {
let status = Folio.FolioSettings.saveLayoutToFile(selectedFile);
let status = folio.FolioSettings.saveLayoutToFile(selectedFile);
if (status) {
exportedSuccessfullyPrompt.open();
} else {
@ -335,7 +338,7 @@ Window {
title: i18n("Confirm Import")
subtitle: i18n("This will overwrite your existing homescreen layout!")
standardButtons: Kirigami.Dialog.Ok | Kirigami.Dialog.Cancel
onAccepted: Folio.FolioSettings.loadLayoutFromFile(importFileDialog.selectedFile);
onAccepted: folio.FolioSettings.loadLayoutFromFile(importFileDialog.selectedFile);
}
}
}

View file

@ -7,14 +7,9 @@
#include <QJsonArray>
#include <QJsonDocument>
PageListModel *PageListModel::self()
{
static PageListModel *model = new PageListModel;
return model;
}
PageListModel::PageListModel(QObject *parent)
PageListModel::PageListModel(HomeScreen *parent)
: QAbstractListModel{parent}
, m_homeScreen{parent}
{
}
@ -77,7 +72,7 @@ Q_INVOKABLE void PageListModel::addPageAtEnd()
{
beginInsertRows(QModelIndex(), m_pages.size(), m_pages.size());
PageModel *page = new PageModel{{}, this};
PageModel *page = new PageModel{{}, this, m_homeScreen};
connect(page, &PageModel::saveRequested, this, &PageListModel::save);
m_pages.append(page);
@ -96,9 +91,11 @@ bool PageListModel::isLastPageEmpty()
void PageListModel::deleteEmptyPagesAtEnd()
{
auto pageListModel = m_homeScreen->pageListModel();
// delete empty pages at the end if they exist
while (PageListModel::self()->isLastPageEmpty() && PageListModel::self()->rowCount() > 1) {
PageListModel::self()->removePage(PageListModel::self()->rowCount() - 1);
while (pageListModel->isLastPageEmpty() && pageListModel->rowCount() > 1) {
pageListModel->removePage(pageListModel->rowCount() - 1);
}
}
@ -113,24 +110,24 @@ QJsonArray PageListModel::exportToJson()
void PageListModel::save()
{
if (!m_containment) {
if (!m_homeScreen) {
return;
}
QJsonArray arr = exportToJson();
QByteArray data = QJsonDocument(arr).toJson(QJsonDocument::Compact);
m_containment->config().writeEntry("Pages", QString::fromStdString(data.toStdString()));
Q_EMIT m_containment->configNeedsSaving();
m_homeScreen->config().writeEntry("Pages", QString::fromStdString(data.toStdString()));
Q_EMIT m_homeScreen->configNeedsSaving();
}
void PageListModel::load()
{
if (!m_containment) {
if (!m_homeScreen) {
return;
}
QJsonDocument doc = QJsonDocument::fromJson(m_containment->config().readEntry("Pages", "{}").toUtf8());
QJsonDocument doc = QJsonDocument::fromJson(m_homeScreen->config().readEntry("Pages", "{}").toUtf8());
loadFromJson(doc.array());
}
@ -143,7 +140,7 @@ void PageListModel::loadFromJson(QJsonArray arr)
for (QJsonValueRef r : arr) {
QJsonArray obj = r.toArray();
PageModel *page = PageModel::fromJson(obj, this);
PageModel *page = PageModel::fromJson(obj, this, m_homeScreen);
if (page) {
connect(page, &PageModel::saveRequested, this, &PageListModel::save);
m_pages.append(page);
@ -159,8 +156,3 @@ void PageListModel::loadFromJson(QJsonArray arr)
addPageAtEnd();
}
}
void PageListModel::setContainment(Plasma::Containment *containment)
{
m_containment = containment;
}

View file

@ -3,6 +3,7 @@
#pragma once
#include "homescreen.h"
#include "pagemodel.h"
#include <QAbstractListModel>
@ -10,6 +11,9 @@
#include <Plasma/Containment>
class HomeScreen;
class PageModel;
class PageListModel : public QAbstractListModel
{
Q_OBJECT
@ -18,9 +22,7 @@ class PageListModel : public QAbstractListModel
public:
enum Roles { PageRole = Qt::UserRole + 1 };
PageListModel(QObject *parent = nullptr);
static PageListModel *self();
PageListModel(HomeScreen *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
@ -40,13 +42,11 @@ public:
Q_INVOKABLE void load();
void loadFromJson(QJsonArray arr);
void setContainment(Plasma::Containment *containment);
Q_SIGNALS:
void lengthChanged();
private:
QList<PageModel *> m_pages;
HomeScreen *m_homeScreen{nullptr};
Plasma::Containment *m_containment{nullptr};
QList<PageModel *> m_pages;
};

View file

@ -6,268 +6,12 @@
#include "homescreenstate.h"
#include "widgetsmanager.h"
FolioPageDelegate::FolioPageDelegate(int row, int column, QObject *parent)
: FolioDelegate{parent}
, m_row{row}
, m_column{column}
{
init();
}
FolioPageDelegate::FolioPageDelegate(int row, int column, FolioApplication *application, QObject *parent)
: FolioDelegate{application, parent}
, m_row{row}
, m_column{column}
{
init();
}
FolioPageDelegate::FolioPageDelegate(int row, int column, FolioApplicationFolder *folder, QObject *parent)
: FolioDelegate{folder, parent}
, m_row{row}
, m_column{column}
{
init();
}
FolioPageDelegate::FolioPageDelegate(int row, int column, FolioWidget *widget, QObject *parent)
: FolioDelegate{widget, parent}
, m_row{row}
, m_column{column}
{
init();
}
FolioPageDelegate::FolioPageDelegate(int row, int column, FolioDelegate *delegate, QObject *parent)
: FolioDelegate{parent}
, m_row{row}
, m_column{column}
{
m_type = delegate->type();
m_application = delegate->application();
m_folder = delegate->folder();
m_widget = delegate->widget();
init();
}
void FolioPageDelegate::init()
{
// we have to use the "real" rows and columns, so fetch them from FolioSettings instead of HomeScreenState
switch (HomeScreenState::self()->pageOrientation()) {
case HomeScreenState::RegularPosition:
m_realRow = m_row;
m_realColumn = m_column;
break;
case HomeScreenState::RotateClockwise:
m_realRow = HomeScreenState::self()->pageColumns() - m_column - 1;
m_realColumn = m_row;
if (m_widget) {
// since top-left in cw is bottom-left in portrait
m_realRow -= m_widget->realGridHeight() - 1;
}
break;
case HomeScreenState::RotateCounterClockwise:
m_realRow = m_column;
m_realColumn = HomeScreenState::self()->pageRows() - m_row - 1;
if (m_widget) {
// since top-left in ccw is top-right in portrait
m_realColumn -= m_widget->realGridWidth() - 1;
}
break;
case HomeScreenState::RotateUpsideDown:
m_realRow = HomeScreenState::self()->pageRows() - m_row - 1;
m_realColumn = HomeScreenState::self()->pageColumns() - m_column - 1;
if (m_widget) {
// since top-left in upside-down is bottom-right in portrait
m_realRow -= m_widget->realGridHeight() - 1;
m_realColumn -= m_widget->realGridWidth() - 1;
}
break;
}
if (m_widget) {
connect(m_widget, &FolioWidget::realTopLeftPositionChanged, this, [this](int rowOffset, int columnOffset) {
m_realRow += rowOffset;
m_realColumn += columnOffset;
});
}
connect(HomeScreenState::self(), &HomeScreenState::pageOrientationChanged, this, [this]() {
setRowOnly(getTranslatedTopLeftRow(m_realRow, m_realColumn, this));
setColumnOnly(getTranslatedTopLeftColumn(m_realRow, m_realColumn, this));
});
}
FolioPageDelegate *FolioPageDelegate::fromJson(QJsonObject &obj, QObject *parent)
{
FolioDelegate *fd = FolioDelegate::fromJson(obj, parent);
if (!fd) {
return nullptr;
}
int realRow = obj[QStringLiteral("row")].toInt();
int realColumn = obj[QStringLiteral("column")].toInt();
int row = getTranslatedTopLeftRow(realRow, realColumn, fd);
int column = getTranslatedTopLeftColumn(realRow, realColumn, fd);
FolioPageDelegate *delegate = new FolioPageDelegate{row, column, fd, parent};
fd->deleteLater();
return delegate;
}
int FolioPageDelegate::getTranslatedTopLeftRow(int realRow, int realColumn, FolioDelegate *fd)
{
int row = getTranslatedRow(realRow, realColumn);
int column = getTranslatedColumn(realRow, realColumn);
// special logic to return "top left" for widgets, since they take more than one tile
if (fd->type() == FolioDelegate::Widget) {
return fd->widget()->topLeftCorner(row, column).row;
} else {
return row;
}
}
int FolioPageDelegate::getTranslatedTopLeftColumn(int realRow, int realColumn, FolioDelegate *fd)
{
int row = getTranslatedRow(realRow, realColumn);
int column = getTranslatedColumn(realRow, realColumn);
// special logic to return "top left" for widgets, since they take more than one tile
if (fd->type() == FolioDelegate::Widget) {
return fd->widget()->topLeftCorner(row, column).column;
} else {
return column;
}
}
int FolioPageDelegate::getTranslatedRow(int realRow, int realColumn)
{
// we have to use the "real" rows and columns, so fetch them from FolioSettings instead of HomeScreenState
switch (HomeScreenState::self()->pageOrientation()) {
case HomeScreenState::RegularPosition:
return realRow;
case HomeScreenState::RotateClockwise:
return realColumn;
case HomeScreenState::RotateCounterClockwise:
return FolioSettings::self()->homeScreenColumns() - realColumn - 1;
case HomeScreenState::RotateUpsideDown:
return FolioSettings::self()->homeScreenRows() - realRow - 1;
}
return realRow;
}
int FolioPageDelegate::getTranslatedColumn(int realRow, int realColumn)
{
// we have to use the "real" rows and columns, so fetch them from FolioSettings instead of HomeScreenState
switch (HomeScreenState::self()->pageOrientation()) {
case HomeScreenState::RegularPosition:
return realColumn;
case HomeScreenState::RotateClockwise:
return FolioSettings::self()->homeScreenRows() - realRow - 1;
case HomeScreenState::RotateCounterClockwise:
return realRow;
case HomeScreenState::RotateUpsideDown:
return FolioSettings::self()->homeScreenColumns() - realColumn - 1;
}
return realRow;
}
QJsonObject FolioPageDelegate::toJson() const
{
QJsonObject o = FolioDelegate::toJson();
o[QStringLiteral("row")] = m_realRow;
o[QStringLiteral("column")] = m_realColumn;
return o;
}
int FolioPageDelegate::row()
{
return m_row;
}
void FolioPageDelegate::setRow(int row)
{
if (m_row != row) {
// adjust stored data too
switch (HomeScreenState::self()->pageOrientation()) {
case HomeScreenState::RegularPosition:
m_realRow = row;
break;
case HomeScreenState::RotateClockwise:
m_realColumn += row - m_row;
break;
case HomeScreenState::RotateCounterClockwise:
m_realColumn += m_row - row;
break;
case HomeScreenState::RotateUpsideDown:
m_realRow += m_row - row;
break;
}
setRowOnly(row);
}
}
void FolioPageDelegate::setRowOnly(int row)
{
if (m_row != row) {
m_row = row;
Q_EMIT rowChanged();
}
}
int FolioPageDelegate::column()
{
return m_column;
}
void FolioPageDelegate::setColumn(int column)
{
if (m_column != column) {
// adjust stored data too
switch (HomeScreenState::self()->pageOrientation()) {
case HomeScreenState::RegularPosition:
m_realColumn = column;
break;
case HomeScreenState::RotateClockwise:
m_realRow += m_column - column;
break;
case HomeScreenState::RotateCounterClockwise:
m_realRow += column - m_column;
break;
case HomeScreenState::RotateUpsideDown:
m_realColumn += m_column - column;
break;
}
setColumnOnly(column);
}
}
void FolioPageDelegate::setColumnOnly(int column)
{
if (m_column != column) {
m_column = column;
Q_EMIT columnChanged();
}
}
PageModel::PageModel(QList<FolioPageDelegate *> delegates, QObject *parent)
PageModel::PageModel(QList<FolioPageDelegate *> delegates, QObject *parent, HomeScreen *homeScreen)
: QAbstractListModel{parent}
, m_homeScreen{homeScreen}
, m_delegates{delegates}
{
connect(WidgetsManager::self(), &WidgetsManager::widgetRemoved, this, [this](Plasma::Applet *applet) {
connect(homeScreen->widgetsManager(), &WidgetsManager::widgetRemoved, this, [this](Plasma::Applet *applet) {
if (applet) {
// delete any instance of this widget
for (int i = 0; i < m_delegates.size(); i++) {
@ -283,20 +27,20 @@ PageModel::PageModel(QList<FolioPageDelegate *> delegates, QObject *parent)
PageModel::~PageModel() = default;
PageModel *PageModel::fromJson(QJsonArray &arr, QObject *parent)
PageModel *PageModel::fromJson(QJsonArray &arr, QObject *parent, HomeScreen *homeScreen)
{
QList<FolioPageDelegate *> delegates;
for (QJsonValueRef r : arr) {
QJsonObject obj = r.toObject();
FolioPageDelegate *delegate = FolioPageDelegate::fromJson(obj, parent);
FolioPageDelegate *delegate = FolioPageDelegate::fromJson(obj, homeScreen);
if (delegate) {
delegates.append(delegate);
}
}
PageModel *model = new PageModel{delegates, parent};
PageModel *model = new PageModel{delegates, parent, homeScreen};
// ensure delegates can request saves
for (auto *delegate : delegates) {
@ -372,7 +116,9 @@ void PageModel::removeDelegate(int index)
bool PageModel::canAddDelegate(int row, int column, FolioDelegate *delegate)
{
if (row < 0 || row >= HomeScreenState::self()->pageRows() || column < 0 || column >= HomeScreenState::self()->pageColumns()) {
HomeScreenState *homeScreenState = m_homeScreen->homeScreenState();
if (row < 0 || row >= homeScreenState->pageRows() || column < 0 || column >= homeScreenState->pageColumns()) {
return false;
}
@ -384,8 +130,8 @@ bool PageModel::canAddDelegate(int row, int column, FolioDelegate *delegate)
int maxColumn = column + delegate->widget()->gridWidth() - 1;
// check bounds
if ((row < 0 || row >= HomeScreenState::self()->pageRows()) || (maxRow < 0 || maxRow >= HomeScreenState::self()->pageRows())
|| (column < 0 || column >= HomeScreenState::self()->pageColumns()) || (maxColumn < 0 || maxColumn >= HomeScreenState::self()->pageColumns())) {
if ((row < 0 || row >= homeScreenState->pageRows()) || (maxRow < 0 || maxRow >= homeScreenState->pageRows())
|| (column < 0 || column >= homeScreenState->pageColumns()) || (maxColumn < 0 || maxColumn >= homeScreenState->pageColumns())) {
return false;
}
@ -462,11 +208,11 @@ void PageModel::moveAndResizeWidgetDelegate(FolioPageDelegate *delegate, int new
}
// test if we can add the delegate with new size and position
FolioWidget *testWidget = new FolioWidget(this, 0, 0, 0);
FolioWidget *testWidget = new FolioWidget(m_homeScreen, 0, 0, 0);
// we have to use setGridWidth and setGridHeight since it takes into account the page orientation
testWidget->setGridWidth(newGridWidth);
testWidget->setGridHeight(newGridHeight);
FolioDelegate *testDelegate = new FolioDelegate(testWidget, this);
FolioDelegate *testDelegate = new FolioDelegate(testWidget, m_homeScreen);
// NOT THREAD SAFE!
// which is fine, because the GUI isn't multithreaded

View file

@ -6,6 +6,7 @@
#include "folioapplication.h"
#include "folioapplicationfolder.h"
#include "foliodelegate.h"
#include "homescreen.h"
#include <QAbstractListModel>
#include <QJsonArray>
@ -13,51 +14,13 @@
#include <Plasma/Applet>
class FolioPageDelegate : public FolioDelegate
{
Q_OBJECT
Q_PROPERTY(int row READ row NOTIFY rowChanged)
Q_PROPERTY(int column READ column NOTIFY columnChanged)
public:
FolioPageDelegate(int row = 0, int column = 0, QObject *parent = nullptr);
FolioPageDelegate(int row, int column, FolioApplication *application, QObject *parent);
FolioPageDelegate(int row, int column, FolioApplicationFolder *folder, QObject *parent);
FolioPageDelegate(int row, int column, FolioWidget *widget, QObject *parent);
FolioPageDelegate(int row, int column, FolioDelegate *delegate, QObject *parent);
static FolioPageDelegate *fromJson(QJsonObject &obj, QObject *parent);
static int getTranslatedTopLeftRow(int realRow, int realColumn, FolioDelegate *fd);
static int getTranslatedTopLeftColumn(int realRow, int realColumn, FolioDelegate *fd);
static int getTranslatedRow(int realRow, int realColumn);
static int getTranslatedColumn(int realRow, int realColumn);
virtual QJsonObject toJson() const override;
int row();
void setRow(int row);
int column();
void setColumn(int column);
Q_SIGNALS:
void rowChanged();
void columnChanged();
private:
void setRowOnly(int row);
void setColumnOnly(int column);
void init();
int m_realRow;
int m_realColumn;
int m_row;
int m_column;
};
class HomeScreen;
class FolioPageDelegate;
class PageModel : public QAbstractListModel
{
Q_OBJECT
public:
enum Roles {
DelegateRole = Qt::UserRole + 1,
@ -66,10 +29,10 @@ public:
ShownRole,
};
PageModel(QList<FolioPageDelegate *> delegates = QList<FolioPageDelegate *>{}, QObject *parent = nullptr);
PageModel(QList<FolioPageDelegate *> delegates = QList<FolioPageDelegate *>{}, QObject *parent = nullptr, HomeScreen *m_homeScreen = nullptr);
~PageModel();
static PageModel *fromJson(QJsonArray &arr, QObject *parent);
static PageModel *fromJson(QJsonArray &arr, QObject *parent, HomeScreen *homeScreen);
QJsonArray toJson() const;
@ -95,5 +58,7 @@ Q_SIGNALS:
private:
void connectSaveRequests(FolioDelegate *delegate);
HomeScreen *m_homeScreen{nullptr};
QList<FolioPageDelegate *> m_delegates;
};

View file

@ -8,12 +8,6 @@ WidgetsManager::WidgetsManager(QObject *parent)
{
}
WidgetsManager *WidgetsManager::self()
{
static WidgetsManager *manager = new WidgetsManager{nullptr};
return manager;
}
Plasma::Applet *WidgetsManager::getWidget(int id)
{
for (auto *widget : m_widgets) {

View file

@ -3,6 +3,8 @@
#pragma once
#include "homescreen.h"
#include <QObject>
#include <Plasma/Applet>
@ -15,8 +17,6 @@ class WidgetsManager : public QObject
public:
WidgetsManager(QObject *parent = nullptr);
static WidgetsManager *self();
Plasma::Applet *getWidget(int id);
void addWidget(Plasma::Applet *applet);