mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
This MR ensures that delegates created with make_shared do not also get initialized with a QObject parent. Some of the classes used the same constructor parameter for HomeScreen and used it as a parent simultaneously. This was refactored so that they are separated.
408 lines
12 KiB
C++
408 lines
12 KiB
C++
// SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#include "foliodelegate.h"
|
|
#include "homescreenstate.h"
|
|
|
|
FolioDelegate::FolioDelegate(QObject *parent)
|
|
: QObject{parent}
|
|
, m_type{FolioDelegate::None}
|
|
, m_application{nullptr}
|
|
, m_folder{nullptr}
|
|
, m_widget{nullptr}
|
|
{
|
|
}
|
|
|
|
FolioDelegate::FolioDelegate(FolioApplication::Ptr application, QObject *parent)
|
|
: QObject{parent}
|
|
, m_type{FolioDelegate::Application}
|
|
, m_application{application}
|
|
, m_folder{nullptr}
|
|
, m_widget{nullptr}
|
|
{
|
|
}
|
|
|
|
FolioDelegate::FolioDelegate(FolioApplicationFolder::Ptr folder, QObject *parent)
|
|
: QObject{parent}
|
|
, m_type{FolioDelegate::Folder}
|
|
, m_application{nullptr}
|
|
, m_folder{folder}
|
|
, m_widget{nullptr}
|
|
{
|
|
}
|
|
|
|
FolioDelegate::FolioDelegate(FolioWidget::Ptr widget, QObject *parent)
|
|
: QObject{parent}
|
|
, m_type{FolioDelegate::Widget}
|
|
, m_application{nullptr}
|
|
, m_folder{nullptr}
|
|
, m_widget{widget}
|
|
{
|
|
}
|
|
|
|
FolioDelegate::Ptr FolioDelegate::fromJson(QJsonObject &obj, HomeScreen *homeScreen)
|
|
{
|
|
const QString type = obj[QStringLiteral("type")].toString();
|
|
if (type == "application") {
|
|
// read application
|
|
FolioApplication::Ptr app = FolioApplication::fromJson(obj);
|
|
|
|
if (app) {
|
|
return std::make_shared<FolioDelegate>(app);
|
|
}
|
|
|
|
} else if (type == "folder") {
|
|
// read folder
|
|
FolioApplicationFolder::Ptr folder = FolioApplicationFolder::fromJson(obj, homeScreen);
|
|
|
|
if (folder) {
|
|
return std::make_shared<FolioDelegate>(folder);
|
|
}
|
|
|
|
} else if (type == "widget") {
|
|
// read widget
|
|
FolioWidget::Ptr widget = FolioWidget::fromJson(obj, homeScreen);
|
|
|
|
if (widget) {
|
|
return std::make_shared<FolioDelegate>(widget);
|
|
}
|
|
} else if (type == "none") {
|
|
return std::make_shared<FolioDelegate>();
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
QJsonObject FolioDelegate::toJson() const
|
|
{
|
|
switch (m_type) {
|
|
case FolioDelegate::Application:
|
|
return m_application->toJson();
|
|
case FolioDelegate::Folder:
|
|
return m_folder->toJson();
|
|
case FolioDelegate::Widget:
|
|
return m_widget->toJson();
|
|
case FolioDelegate::None: {
|
|
QJsonObject obj;
|
|
obj[QStringLiteral("type")] = "none";
|
|
return obj;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return QJsonObject{};
|
|
}
|
|
|
|
FolioDelegate::Type FolioDelegate::type() const
|
|
{
|
|
return m_type;
|
|
}
|
|
|
|
FolioApplication::Ptr FolioDelegate::application()
|
|
{
|
|
return m_application;
|
|
}
|
|
|
|
FolioApplication *FolioDelegate::applicationRaw()
|
|
{
|
|
return m_application.get();
|
|
}
|
|
|
|
FolioApplicationFolder::Ptr FolioDelegate::folder()
|
|
{
|
|
return m_folder;
|
|
}
|
|
|
|
FolioApplicationFolder *FolioDelegate::folderRaw()
|
|
{
|
|
return m_folder.get();
|
|
}
|
|
|
|
FolioWidget::Ptr FolioDelegate::widget()
|
|
{
|
|
return m_widget;
|
|
}
|
|
|
|
FolioWidget *FolioDelegate::widgetRaw()
|
|
{
|
|
return m_widget.get();
|
|
}
|
|
|
|
FolioPageDelegate::FolioPageDelegate(int row, int column, HomeScreen *homeScreen, QObject *parent)
|
|
: FolioDelegate{parent}
|
|
, m_homeScreen{homeScreen}
|
|
, m_row{row}
|
|
, m_column{column}
|
|
{
|
|
init();
|
|
}
|
|
|
|
FolioPageDelegate::FolioPageDelegate(int row, int column, FolioApplication::Ptr application, HomeScreen *homeScreen, QObject *parent)
|
|
: FolioDelegate{application, parent}
|
|
, m_homeScreen{homeScreen}
|
|
, m_row{row}
|
|
, m_column{column}
|
|
{
|
|
init();
|
|
}
|
|
|
|
FolioPageDelegate::FolioPageDelegate(int row, int column, FolioApplicationFolder::Ptr folder, HomeScreen *homeScreen, QObject *parent)
|
|
: FolioDelegate{folder, parent}
|
|
, m_homeScreen{homeScreen}
|
|
, m_row{row}
|
|
, m_column{column}
|
|
{
|
|
init();
|
|
}
|
|
|
|
FolioPageDelegate::FolioPageDelegate(int row, int column, FolioWidget::Ptr widget, HomeScreen *homeScreen, QObject *parent)
|
|
: FolioDelegate{widget, parent}
|
|
, m_homeScreen{homeScreen}
|
|
, m_row{row}
|
|
, m_column{column}
|
|
{
|
|
init();
|
|
}
|
|
|
|
FolioPageDelegate::FolioPageDelegate(int row, int column, FolioDelegate::Ptr delegate, HomeScreen *homeScreen, QObject *parent)
|
|
: FolioDelegate{parent}
|
|
, m_homeScreen{homeScreen}
|
|
, 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.get(), &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->shared_from_this()));
|
|
setColumnOnly(getTranslatedTopLeftColumn(m_homeScreen, m_realRow, m_realColumn, this->shared_from_this()));
|
|
});
|
|
}
|
|
|
|
FolioPageDelegate::Ptr FolioPageDelegate::fromJson(QJsonObject &obj, HomeScreen *homeScreen)
|
|
{
|
|
FolioDelegate::Ptr fd = FolioDelegate::fromJson(obj, homeScreen);
|
|
|
|
if (!fd) {
|
|
return nullptr;
|
|
}
|
|
|
|
int realRow = obj[QStringLiteral("row")].toInt();
|
|
int realColumn = obj[QStringLiteral("column")].toInt();
|
|
|
|
int row = getTranslatedTopLeftRow(homeScreen, realRow, realColumn, fd);
|
|
int column = getTranslatedTopLeftColumn(homeScreen, realRow, realColumn, fd);
|
|
|
|
FolioPageDelegate::Ptr delegate = std::make_shared<FolioPageDelegate>(row, column, fd, homeScreen);
|
|
fd->deleteLater();
|
|
|
|
return delegate;
|
|
}
|
|
|
|
int FolioPageDelegate::getTranslatedTopLeftRow(HomeScreen *homeScreen, int realRow, int realColumn, FolioDelegate::Ptr 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::Ptr 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();
|
|
}
|
|
}
|
|
|
|
std::shared_ptr<FolioPageDelegate> FolioPageDelegate::sharedPageDelegate()
|
|
{
|
|
return static_pointer_cast<FolioPageDelegate>(shared_from_this());
|
|
}
|