2023-10-22 03:59:27 +00:00
|
|
|
// SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
|
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
|
|
|
|
|
|
#include "favouritesmodel.h"
|
|
|
|
|
#include "homescreenstate.h"
|
|
|
|
|
|
|
|
|
|
#include <QByteArray>
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
#include <QJsonArray>
|
|
|
|
|
#include <QJsonDocument>
|
|
|
|
|
#include <QModelIndex>
|
|
|
|
|
#include <QProcess>
|
|
|
|
|
#include <QQuickWindow>
|
|
|
|
|
|
|
|
|
|
#include <KApplicationTrader>
|
|
|
|
|
#include <KConfigGroup>
|
|
|
|
|
#include <KIO/ApplicationLauncherJob>
|
|
|
|
|
#include <KNotificationJobUiDelegate>
|
|
|
|
|
#include <KService>
|
|
|
|
|
#include <KSharedConfig>
|
|
|
|
|
#include <KSycoca>
|
|
|
|
|
|
2024-06-21 04:42:14 +00:00
|
|
|
FavouritesModel::FavouritesModel(HomeScreen *parent)
|
2023-10-22 03:59:27 +00:00
|
|
|
: QAbstractListModel{parent}
|
2024-06-21 04:42:14 +00:00
|
|
|
, m_homeScreen{parent}
|
2023-10-22 03:59:27 +00:00
|
|
|
{
|
2024-06-21 04:42:14 +00:00
|
|
|
connect(m_homeScreen->homeScreenState(), &HomeScreenState::pageWidthChanged, this, [this]() {
|
2023-10-22 03:59:27 +00:00
|
|
|
evaluateDelegatePositions(true);
|
|
|
|
|
});
|
2024-06-21 04:42:14 +00:00
|
|
|
connect(m_homeScreen->homeScreenState(), &HomeScreenState::pageHeightChanged, this, [this]() {
|
2023-10-22 03:59:27 +00:00
|
|
|
evaluateDelegatePositions(true);
|
|
|
|
|
});
|
2024-06-21 04:42:14 +00:00
|
|
|
connect(m_homeScreen->homeScreenState(), &HomeScreenState::pageCellWidthChanged, this, [this]() {
|
2023-10-22 03:59:27 +00:00
|
|
|
evaluateDelegatePositions(true);
|
|
|
|
|
});
|
2024-06-21 04:42:14 +00:00
|
|
|
connect(m_homeScreen->homeScreenState(), &HomeScreenState::pageCellHeightChanged, this, [this]() {
|
2023-10-22 03:59:27 +00:00
|
|
|
evaluateDelegatePositions(true);
|
|
|
|
|
});
|
2024-06-21 04:42:14 +00:00
|
|
|
connect(m_homeScreen->homeScreenState(), &HomeScreenState::favouritesBarLocationChanged, this, [this]() {
|
2023-10-22 03:59:27 +00:00
|
|
|
evaluateDelegatePositions(true);
|
|
|
|
|
});
|
2024-06-21 04:42:14 +00:00
|
|
|
connect(m_homeScreen->homeScreenState(), &HomeScreenState::pageOrientationChanged, this, [this]() {
|
2023-10-22 03:59:27 +00:00
|
|
|
evaluateDelegatePositions(true);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int FavouritesModel::rowCount(const QModelIndex &parent) const
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(parent)
|
|
|
|
|
return m_delegates.count();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVariant FavouritesModel::data(const QModelIndex &index, int role) const
|
|
|
|
|
{
|
|
|
|
|
if (!index.isValid() || index.row() < 0 || index.row() >= m_delegates.size()) {
|
|
|
|
|
return QVariant();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (role) {
|
|
|
|
|
case DelegateRole:
|
|
|
|
|
return QVariant::fromValue(m_delegates.at(index.row()).delegate);
|
|
|
|
|
case XPositionRole:
|
|
|
|
|
return QVariant::fromValue(m_delegates.at(index.row()).xPosition);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return QVariant();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QHash<int, QByteArray> FavouritesModel::roleNames() const
|
|
|
|
|
{
|
|
|
|
|
return {{DelegateRole, "delegate"}, {XPositionRole, "xPosition"}};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FavouritesModel::removeEntry(int row)
|
|
|
|
|
{
|
|
|
|
|
if (row < 0 || row >= m_delegates.size()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
beginRemoveRows(QModelIndex(), row, row);
|
|
|
|
|
// HACK: do not deleteLater(), because the delegate might still be used somewhere else
|
|
|
|
|
// m_delegates[row].delegate->deleteLater();
|
|
|
|
|
m_delegates.removeAt(row);
|
|
|
|
|
endRemoveRows();
|
|
|
|
|
|
|
|
|
|
evaluateDelegatePositions();
|
|
|
|
|
|
|
|
|
|
save();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FavouritesModel::moveEntry(int fromRow, int toRow)
|
|
|
|
|
{
|
|
|
|
|
if (fromRow < 0 || toRow < 0 || fromRow >= m_delegates.size() || toRow >= m_delegates.size() || fromRow == toRow) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (toRow > fromRow) {
|
|
|
|
|
++toRow;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
beginMoveRows(QModelIndex(), fromRow, fromRow, QModelIndex(), toRow);
|
|
|
|
|
if (toRow > fromRow) {
|
|
|
|
|
auto delegate = m_delegates.at(fromRow);
|
|
|
|
|
m_delegates.insert(toRow, delegate);
|
|
|
|
|
m_delegates.takeAt(fromRow);
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
auto delegate = m_delegates.takeAt(fromRow);
|
|
|
|
|
m_delegates.insert(toRow, delegate);
|
|
|
|
|
}
|
|
|
|
|
endMoveRows();
|
|
|
|
|
|
|
|
|
|
evaluateDelegatePositions();
|
|
|
|
|
|
|
|
|
|
save();
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-05 05:14:39 +00:00
|
|
|
bool FavouritesModel::canAddEntry(int row, FolioDelegate *delegate)
|
2023-10-22 03:59:27 +00:00
|
|
|
{
|
|
|
|
|
if (!delegate) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (row < 0 || row > m_delegates.size()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-05 05:14:39 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool FavouritesModel::addEntry(int row, FolioDelegate *delegate)
|
|
|
|
|
{
|
|
|
|
|
if (!canAddEntry(row, delegate)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-22 03:59:27 +00:00
|
|
|
if (row == m_delegates.size()) {
|
|
|
|
|
beginInsertRows(QModelIndex(), row, row);
|
|
|
|
|
m_delegates.append({delegate, 0});
|
|
|
|
|
evaluateDelegatePositions(false);
|
|
|
|
|
endInsertRows();
|
|
|
|
|
} else if (m_delegates[row].delegate->type() == FolioDelegate::None) {
|
|
|
|
|
replaceGhostEntry(delegate);
|
|
|
|
|
} else {
|
|
|
|
|
beginInsertRows(QModelIndex(), row, row);
|
|
|
|
|
m_delegates.insert(row, {delegate, 0});
|
|
|
|
|
evaluateDelegatePositions(false);
|
|
|
|
|
endInsertRows();
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-05 05:14:39 +00:00
|
|
|
// ensure saves are connected when requested by the delegate
|
|
|
|
|
connectSaveRequests(delegate);
|
|
|
|
|
|
2023-10-22 03:59:27 +00:00
|
|
|
evaluateDelegatePositions();
|
|
|
|
|
|
|
|
|
|
save();
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FolioDelegate *FavouritesModel::getEntryAt(int row)
|
|
|
|
|
{
|
|
|
|
|
if (row < 0 || row >= m_delegates.size()) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return m_delegates[row].delegate;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 13:44:17 +00:00
|
|
|
bool FavouritesModel::isFull() const
|
|
|
|
|
{
|
2024-06-21 04:42:14 +00:00
|
|
|
auto homeScreenState = m_homeScreen->homeScreenState();
|
|
|
|
|
bool isLocationBottom = homeScreenState->favouritesBarLocation() == HomeScreenState::Bottom;
|
2024-03-06 13:44:17 +00:00
|
|
|
|
|
|
|
|
if (isLocationBottom) {
|
2024-06-21 04:42:14 +00:00
|
|
|
return m_delegates.size() >= homeScreenState->pageColumns();
|
2024-03-06 13:44:17 +00:00
|
|
|
} else {
|
2024-06-21 04:42:14 +00:00
|
|
|
return m_delegates.size() >= homeScreenState->pageRows();
|
2024-03-06 13:44:17 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-22 03:59:27 +00:00
|
|
|
int FavouritesModel::getGhostEntryPosition()
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < m_delegates.size(); i++) {
|
|
|
|
|
if (m_delegates[i].delegate->type() == FolioDelegate::None) {
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FavouritesModel::setGhostEntry(int row)
|
|
|
|
|
{
|
|
|
|
|
bool found = false;
|
|
|
|
|
|
|
|
|
|
// check if a ghost entry already exists, then swap them
|
|
|
|
|
for (int i = 0; i < m_delegates.size(); i++) {
|
|
|
|
|
if (m_delegates[i].delegate->type() == FolioDelegate::None) {
|
|
|
|
|
found = true;
|
|
|
|
|
|
|
|
|
|
if (row != i) {
|
|
|
|
|
moveEntry(i, row);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if it doesn't, add a new empty delegate
|
|
|
|
|
if (!found) {
|
2024-06-21 04:42:14 +00:00
|
|
|
FolioDelegate *ghost = new FolioDelegate{m_homeScreen};
|
2023-10-22 03:59:27 +00:00
|
|
|
addEntry(row, ghost);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FavouritesModel::replaceGhostEntry(FolioDelegate *delegate)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < m_delegates.size(); i++) {
|
|
|
|
|
if (m_delegates[i].delegate->type() == FolioDelegate::None) {
|
2024-06-21 04:42:14 +00:00
|
|
|
m_delegates[i].delegate->deleteLater();
|
2023-10-22 03:59:27 +00:00
|
|
|
m_delegates[i].delegate = delegate;
|
|
|
|
|
|
|
|
|
|
Q_EMIT dataChanged(createIndex(i, 0), createIndex(i, 0), {DelegateRole});
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FavouritesModel::deleteGhostEntry()
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < m_delegates.size(); i++) {
|
|
|
|
|
if (m_delegates[i].delegate->type() == FolioDelegate::None) {
|
2024-06-21 04:42:14 +00:00
|
|
|
auto ghostEntry = m_delegates[i].delegate;
|
2023-10-22 03:59:27 +00:00
|
|
|
removeEntry(i);
|
2024-06-21 04:42:14 +00:00
|
|
|
|
|
|
|
|
// ensure ghost entry is deleted
|
|
|
|
|
ghostEntry->deleteLater();
|
2023-10-22 03:59:27 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-22 17:17:09 +00:00
|
|
|
QJsonArray FavouritesModel::exportToJson()
|
2023-10-22 03:59:27 +00:00
|
|
|
{
|
|
|
|
|
QJsonArray arr;
|
|
|
|
|
for (int i = 0; i < m_delegates.size(); i++) {
|
|
|
|
|
FolioDelegate *delegate = m_delegates[i].delegate;
|
|
|
|
|
|
|
|
|
|
// if this delegate is empty, ignore it
|
|
|
|
|
if (!delegate || delegate->type() == FolioDelegate::None) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
arr.append(delegate->toJson());
|
|
|
|
|
}
|
2023-10-22 17:17:09 +00:00
|
|
|
return arr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FavouritesModel::save()
|
|
|
|
|
{
|
2024-06-21 04:42:14 +00:00
|
|
|
if (!m_homeScreen) {
|
2023-10-22 17:17:09 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QJsonArray arr = exportToJson();
|
2023-10-22 03:59:27 +00:00
|
|
|
QByteArray data = QJsonDocument(arr).toJson(QJsonDocument::Compact);
|
|
|
|
|
|
2024-06-21 04:42:14 +00:00
|
|
|
m_homeScreen->config().writeEntry("Favourites", QString::fromStdString(data.toStdString()));
|
|
|
|
|
Q_EMIT m_homeScreen->configNeedsSaving();
|
2023-10-22 03:59:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FavouritesModel::load()
|
|
|
|
|
{
|
2024-06-21 04:42:14 +00:00
|
|
|
if (!m_homeScreen) {
|
2023-10-22 03:59:27 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-21 04:42:14 +00:00
|
|
|
QJsonDocument doc = QJsonDocument::fromJson(m_homeScreen->config().readEntry("Favourites", "{}").toUtf8());
|
2023-10-22 17:17:09 +00:00
|
|
|
loadFromJson(doc.array());
|
|
|
|
|
}
|
2023-10-22 03:59:27 +00:00
|
|
|
|
2023-10-22 17:17:09 +00:00
|
|
|
void FavouritesModel::loadFromJson(QJsonArray arr)
|
|
|
|
|
{
|
2023-10-22 03:59:27 +00:00
|
|
|
beginResetModel();
|
|
|
|
|
|
|
|
|
|
m_delegates.clear();
|
|
|
|
|
|
2023-10-22 17:17:09 +00:00
|
|
|
for (QJsonValueRef r : arr) {
|
2023-10-22 03:59:27 +00:00
|
|
|
QJsonObject obj = r.toObject();
|
2024-06-21 04:42:14 +00:00
|
|
|
FolioDelegate *delegate = FolioDelegate::fromJson(obj, m_homeScreen);
|
2023-10-22 03:59:27 +00:00
|
|
|
|
|
|
|
|
if (delegate) {
|
2023-11-05 05:14:39 +00:00
|
|
|
connectSaveRequests(delegate);
|
2023-10-22 03:59:27 +00:00
|
|
|
m_delegates.append({delegate, 0});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
evaluateDelegatePositions(false);
|
|
|
|
|
endResetModel();
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-05 05:14:39 +00:00
|
|
|
void FavouritesModel::connectSaveRequests(FolioDelegate *delegate)
|
|
|
|
|
{
|
|
|
|
|
if (delegate->type() == FolioDelegate::Folder && delegate->folder()) {
|
|
|
|
|
connect(delegate->folder(), &FolioApplicationFolder::saveRequested, this, &FavouritesModel::save);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-22 03:59:27 +00:00
|
|
|
bool FavouritesModel::dropPositionIsEdge(qreal x, qreal y) const
|
|
|
|
|
{
|
2024-06-21 04:42:14 +00:00
|
|
|
auto homeScreenState = m_homeScreen->homeScreenState();
|
|
|
|
|
|
2023-10-22 03:59:27 +00:00
|
|
|
qreal startPosition = getDelegateRowStartPos();
|
2024-06-21 04:42:14 +00:00
|
|
|
bool isLocationBottom = homeScreenState->favouritesBarLocation() == HomeScreenState::Bottom;
|
|
|
|
|
qreal cellLength = isLocationBottom ? homeScreenState->pageCellWidth() : homeScreenState->pageCellHeight();
|
2023-10-22 03:59:27 +00:00
|
|
|
|
|
|
|
|
qreal pos = isLocationBottom ? x : y;
|
|
|
|
|
|
|
|
|
|
if (pos < startPosition) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qreal currentPos = startPosition;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < m_delegates.size(); i++) {
|
2024-06-16 20:50:06 +00:00
|
|
|
// if it is within the center 70% of a delegate, it is not at an edge
|
2023-10-22 03:59:27 +00:00
|
|
|
if (pos >= (currentPos + cellLength * 0.15) && pos <= (currentPos + cellLength * 0.85)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
currentPos += cellLength;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int FavouritesModel::dropInsertPosition(qreal x, qreal y) const
|
|
|
|
|
{
|
2024-06-21 04:42:14 +00:00
|
|
|
auto homeScreenState = m_homeScreen->homeScreenState();
|
|
|
|
|
|
2023-10-22 03:59:27 +00:00
|
|
|
qreal startPosition = getDelegateRowStartPos();
|
2024-06-21 04:42:14 +00:00
|
|
|
bool isLocationBottom = homeScreenState->favouritesBarLocation() == HomeScreenState::Bottom;
|
|
|
|
|
qreal cellLength = isLocationBottom ? homeScreenState->pageCellWidth() : homeScreenState->pageCellHeight();
|
2023-10-22 03:59:27 +00:00
|
|
|
|
|
|
|
|
qreal pos = isLocationBottom ? x : y;
|
|
|
|
|
|
|
|
|
|
if (pos < startPosition) {
|
|
|
|
|
return adjustIndex(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qreal currentPos = startPosition;
|
|
|
|
|
for (int i = 0; i < m_delegates.size(); i++) {
|
|
|
|
|
if (pos < currentPos + cellLength * 0.85) {
|
|
|
|
|
return adjustIndex(i);
|
|
|
|
|
} else if (pos < currentPos + cellLength) {
|
|
|
|
|
return adjustIndex(i + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
currentPos += cellLength;
|
|
|
|
|
}
|
|
|
|
|
return adjustIndex(m_delegates.size());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QPointF FavouritesModel::getDelegateScreenPosition(int position) const
|
|
|
|
|
{
|
|
|
|
|
position = adjustIndex(position);
|
|
|
|
|
|
2024-06-21 04:42:14 +00:00
|
|
|
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();
|
2023-10-22 03:59:27 +00:00
|
|
|
|
|
|
|
|
qreal startPosition = getDelegateRowStartPos();
|
|
|
|
|
|
2024-06-21 04:42:14 +00:00
|
|
|
switch (homeScreenState->favouritesBarLocation()) {
|
2023-10-22 03:59:27 +00:00
|
|
|
case HomeScreenState::Bottom: {
|
|
|
|
|
qreal favouritesHeight = screenHeight - pageHeight - screenBottomPadding - screenTopPadding;
|
|
|
|
|
qreal x = screenLeftPadding + startPosition + cellWidth * position;
|
|
|
|
|
qreal y = screenTopPadding + pageHeight + (favouritesHeight / 2) - (cellHeight / 2);
|
|
|
|
|
return {x, y};
|
|
|
|
|
}
|
|
|
|
|
case HomeScreenState::Left: {
|
|
|
|
|
qreal favouritesWidth = screenWidth - screenLeftPadding - pageWidth - screenRightPadding;
|
|
|
|
|
qreal x = screenLeftPadding + (favouritesWidth / 2) - (cellWidth / 2);
|
|
|
|
|
qreal y = startPosition + cellHeight * position;
|
|
|
|
|
return {x, y};
|
|
|
|
|
}
|
|
|
|
|
case HomeScreenState::Right: {
|
|
|
|
|
qreal favouritesWidth = screenWidth - screenLeftPadding - pageWidth - screenRightPadding;
|
|
|
|
|
qreal x = screenLeftPadding + pageWidth + (favouritesWidth / 2) - (cellWidth / 2);
|
|
|
|
|
qreal y = startPosition + cellHeight * position;
|
|
|
|
|
return {x, y};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return {0, 0};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FavouritesModel::evaluateDelegatePositions(bool emitSignal)
|
|
|
|
|
{
|
2024-06-21 04:42:14 +00:00
|
|
|
auto homeScreenState = m_homeScreen->homeScreenState();
|
|
|
|
|
|
|
|
|
|
bool isLocationBottom = homeScreenState->favouritesBarLocation() == HomeScreenState::Bottom;
|
|
|
|
|
qreal cellLength = isLocationBottom ? homeScreenState->pageCellWidth() : homeScreenState->pageCellHeight();
|
2023-10-22 03:59:27 +00:00
|
|
|
qreal startPosition = getDelegateRowStartPos();
|
|
|
|
|
qreal currentPos = startPosition;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < m_delegates.size(); ++i) {
|
|
|
|
|
m_delegates[adjustIndex(i)].xPosition = qRound(currentPos);
|
|
|
|
|
currentPos += cellLength;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (emitSignal) {
|
|
|
|
|
Q_EMIT dataChanged(createIndex(0, 0), createIndex(m_delegates.size() - 1, 0), {XPositionRole});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qreal FavouritesModel::getDelegateRowStartPos() const
|
|
|
|
|
{
|
2024-06-21 04:42:14 +00:00
|
|
|
auto homeScreenState = m_homeScreen->homeScreenState();
|
|
|
|
|
|
2023-10-22 03:59:27 +00:00
|
|
|
const int length = m_delegates.size();
|
2024-06-21 04:42:14 +00:00
|
|
|
const bool isLocationBottom = homeScreenState->favouritesBarLocation() == HomeScreenState::Bottom;
|
|
|
|
|
const qreal cellLength = isLocationBottom ? homeScreenState->pageCellWidth() : homeScreenState->pageCellHeight();
|
|
|
|
|
const qreal pageLength = isLocationBottom ? homeScreenState->pageWidth() : homeScreenState->pageHeight();
|
2023-10-22 03:59:27 +00:00
|
|
|
|
2024-06-21 04:42:14 +00:00
|
|
|
const qreal topMargin = homeScreenState->viewTopPadding();
|
|
|
|
|
const qreal leftMargin = homeScreenState->viewLeftPadding();
|
2023-10-22 03:59:27 +00:00
|
|
|
const qreal panelOffset = isLocationBottom ? leftMargin : topMargin;
|
|
|
|
|
|
|
|
|
|
return (pageLength / 2) - (((qreal)length) / 2) * cellLength + panelOffset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int FavouritesModel::adjustIndex(int index) const
|
|
|
|
|
{
|
2024-06-21 04:42:14 +00:00
|
|
|
auto homeScreenState = m_homeScreen->homeScreenState();
|
|
|
|
|
|
|
|
|
|
if (homeScreenState->favouritesBarLocation() == HomeScreenState::Bottom || homeScreenState->favouritesBarLocation() == HomeScreenState::Left) {
|
2023-10-22 03:59:27 +00:00
|
|
|
return index;
|
|
|
|
|
} else {
|
|
|
|
|
// if it's on the right side of the screen, we flip the order of the delegates
|
|
|
|
|
return qMax(0, m_delegates.size() - index - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|