mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
Currently delegates do not get deleted when removed from models. Due to the complexity of drag state and other objects, we can't simply delete the delegate when removed from the model because they might still be involved in animations or other state at the time of removal. Use smart pointers to have the delegate objects deleted instead. QML unfortunately doesn't support QSharedPointer, so we need to expose raw pointers to it.
274 lines
8.2 KiB
C++
274 lines
8.2 KiB
C++
// SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#include "foliowidget.h"
|
|
#include "homescreenstate.h"
|
|
#include "widgetsmanager.h"
|
|
|
|
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 = m_homeScreen->widgetsManager()->getWidget(id);
|
|
if (applet) {
|
|
setApplet(applet);
|
|
}
|
|
init();
|
|
}
|
|
|
|
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}
|
|
{
|
|
setApplet(applet);
|
|
init();
|
|
}
|
|
|
|
void FolioWidget::init()
|
|
{
|
|
connect(m_homeScreen->homeScreenState(), &HomeScreenState::pageOrientationChanged, this, [this]() {
|
|
Q_EMIT gridWidthChanged();
|
|
Q_EMIT gridHeightChanged();
|
|
});
|
|
|
|
connect(m_homeScreen->widgetsManager(), &WidgetsManager::widgetAdded, this, [this](Plasma::Applet *applet) {
|
|
if (applet && static_cast<int>(applet->id()) == m_id) {
|
|
setApplet(applet);
|
|
}
|
|
});
|
|
connect(m_homeScreen->widgetsManager(), &WidgetsManager::widgetRemoved, this, [this](Plasma::Applet *applet) {
|
|
if (applet && static_cast<int>(applet->id()) == m_id) {
|
|
setApplet(nullptr);
|
|
}
|
|
});
|
|
}
|
|
|
|
FolioWidget::Ptr FolioWidget::fromJson(QJsonObject &obj, HomeScreen *parent)
|
|
{
|
|
int id = obj[QStringLiteral("id")].toInt();
|
|
int gridWidth = obj[QStringLiteral("gridWidth")].toInt();
|
|
int gridHeight = obj[QStringLiteral("gridHeight")].toInt();
|
|
return std::make_shared<FolioWidget>(parent, id, gridWidth, gridHeight);
|
|
}
|
|
|
|
QJsonObject FolioWidget::toJson() const
|
|
{
|
|
QJsonObject obj;
|
|
obj[QStringLiteral("type")] = "widget";
|
|
obj[QStringLiteral("id")] = m_id;
|
|
obj[QStringLiteral("gridWidth")] = m_realGridWidth;
|
|
obj[QStringLiteral("gridHeight")] = m_realGridHeight;
|
|
return obj;
|
|
}
|
|
|
|
int FolioWidget::id() const
|
|
{
|
|
return m_id;
|
|
}
|
|
|
|
int FolioWidget::gridWidth() const
|
|
{
|
|
switch (m_homeScreen->homeScreenState()->pageOrientation()) {
|
|
case HomeScreenState::RegularPosition:
|
|
return m_realGridWidth;
|
|
case HomeScreenState::RotateClockwise:
|
|
return m_realGridHeight;
|
|
case HomeScreenState::RotateCounterClockwise:
|
|
return m_realGridHeight;
|
|
case HomeScreenState::RotateUpsideDown:
|
|
return m_realGridWidth;
|
|
}
|
|
return m_realGridWidth;
|
|
}
|
|
|
|
void FolioWidget::setGridWidth(int gridWidth)
|
|
{
|
|
switch (m_homeScreen->homeScreenState()->pageOrientation()) {
|
|
case HomeScreenState::RegularPosition:
|
|
setRealGridWidth(gridWidth);
|
|
break;
|
|
case HomeScreenState::RotateClockwise: {
|
|
int oldGridHeight = m_realGridHeight;
|
|
setRealGridHeight(gridWidth);
|
|
Q_EMIT realTopLeftPositionChanged(oldGridHeight - gridWidth, 0);
|
|
break;
|
|
}
|
|
case HomeScreenState::RotateCounterClockwise:
|
|
setRealGridHeight(gridWidth);
|
|
break;
|
|
case HomeScreenState::RotateUpsideDown: {
|
|
int oldGridWidth = m_realGridWidth;
|
|
setRealGridWidth(gridWidth);
|
|
Q_EMIT realTopLeftPositionChanged(0, oldGridWidth - gridWidth);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
int FolioWidget::gridHeight() const
|
|
{
|
|
switch (m_homeScreen->homeScreenState()->pageOrientation()) {
|
|
case HomeScreenState::RegularPosition:
|
|
return m_realGridHeight;
|
|
case HomeScreenState::RotateClockwise:
|
|
return m_realGridWidth;
|
|
case HomeScreenState::RotateCounterClockwise:
|
|
return m_realGridWidth;
|
|
case HomeScreenState::RotateUpsideDown:
|
|
return m_realGridHeight;
|
|
}
|
|
return m_realGridHeight;
|
|
}
|
|
|
|
void FolioWidget::setGridHeight(int gridHeight)
|
|
{
|
|
switch (m_homeScreen->homeScreenState()->pageOrientation()) {
|
|
case HomeScreenState::RegularPosition:
|
|
setRealGridHeight(gridHeight);
|
|
break;
|
|
case HomeScreenState::RotateClockwise:
|
|
setRealGridWidth(gridHeight);
|
|
break;
|
|
case HomeScreenState::RotateCounterClockwise: {
|
|
int oldGridWidth = m_realGridWidth;
|
|
setRealGridWidth(gridHeight);
|
|
Q_EMIT realTopLeftPositionChanged(0, oldGridWidth - gridHeight);
|
|
break;
|
|
}
|
|
case HomeScreenState::RotateUpsideDown: {
|
|
int oldGridHeight = m_realGridHeight;
|
|
setRealGridHeight(gridHeight);
|
|
Q_EMIT realTopLeftPositionChanged(oldGridHeight - gridHeight, 0);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
int FolioWidget::realGridWidth() const
|
|
{
|
|
return m_realGridWidth;
|
|
}
|
|
|
|
void FolioWidget::setRealGridWidth(int gridWidth)
|
|
{
|
|
if (m_realGridWidth != gridWidth) {
|
|
m_realGridWidth = gridWidth;
|
|
|
|
// emit both because realGridWidth could be either gridWidth or gridHeight
|
|
Q_EMIT gridWidthChanged();
|
|
Q_EMIT gridHeightChanged();
|
|
|
|
Q_EMIT saveRequested();
|
|
}
|
|
}
|
|
|
|
int FolioWidget::realGridHeight() const
|
|
{
|
|
return m_realGridHeight;
|
|
}
|
|
|
|
void FolioWidget::setRealGridHeight(int gridHeight)
|
|
{
|
|
if (m_realGridHeight != gridHeight) {
|
|
m_realGridHeight = gridHeight;
|
|
|
|
// emit both because realGridHeight could be either gridWidth or gridHeight
|
|
Q_EMIT gridWidthChanged();
|
|
Q_EMIT gridHeightChanged();
|
|
|
|
Q_EMIT saveRequested();
|
|
}
|
|
}
|
|
|
|
GridPosition FolioWidget::topLeftCorner(int row, int column)
|
|
{
|
|
switch (m_homeScreen->homeScreenState()->pageOrientation()) {
|
|
case HomeScreenState::RegularPosition:
|
|
return {row, column};
|
|
case HomeScreenState::RotateClockwise:
|
|
return {row, column - gridWidth() + 1};
|
|
case HomeScreenState::RotateCounterClockwise:
|
|
return {row - gridHeight() + 1, column};
|
|
case HomeScreenState::RotateUpsideDown:
|
|
return {row - gridHeight() + 1, column - gridWidth() + 1};
|
|
}
|
|
return {row, column};
|
|
}
|
|
|
|
bool FolioWidget::isInBounds(int widgetRow, int widgetColumn, int row, int column)
|
|
{
|
|
return (row >= widgetRow) && (row <= widgetRow + gridHeight() - 1) && (column >= widgetColumn) && (column <= widgetColumn + gridWidth() - 1);
|
|
}
|
|
|
|
bool FolioWidget::overlapsWidget(int widgetRow, int widgetColumn, FolioWidget::Ptr otherWidget, int otherWidgetRow, int otherWidgetColumn)
|
|
{
|
|
if (!otherWidget) {
|
|
return false;
|
|
}
|
|
|
|
// property: if they overlap, then at least one corner of one widget is in the other widget
|
|
int widgetMaxRow = widgetRow + gridHeight() - 1;
|
|
int widgetMaxColumn = widgetColumn + gridWidth() - 1;
|
|
int otherWidgetMaxRow = otherWidgetRow + otherWidget->gridHeight() - 1;
|
|
int otherWidgetMaxColumn = otherWidgetColumn + otherWidget->gridWidth() - 1;
|
|
|
|
return isInBounds(widgetRow, widgetColumn, otherWidgetRow, otherWidgetColumn) || isInBounds(widgetRow, widgetColumn, otherWidgetMaxRow, otherWidgetColumn)
|
|
|| isInBounds(widgetRow, widgetColumn, otherWidgetRow, otherWidgetMaxColumn)
|
|
|| isInBounds(widgetRow, widgetColumn, otherWidgetMaxRow, otherWidgetMaxColumn)
|
|
|| otherWidget->isInBounds(otherWidgetRow, otherWidgetColumn, widgetRow, widgetColumn)
|
|
|| otherWidget->isInBounds(otherWidgetRow, otherWidgetColumn, widgetMaxRow, widgetColumn)
|
|
|| otherWidget->isInBounds(otherWidgetRow, otherWidgetColumn, widgetRow, widgetMaxColumn)
|
|
|| otherWidget->isInBounds(otherWidgetRow, otherWidgetColumn, widgetMaxRow, widgetMaxColumn);
|
|
}
|
|
|
|
Plasma::Applet *FolioWidget::applet() const
|
|
{
|
|
return m_applet;
|
|
}
|
|
|
|
void FolioWidget::setApplet(Plasma::Applet *applet)
|
|
{
|
|
m_applet = applet;
|
|
Q_EMIT appletChanged();
|
|
|
|
int id = applet ? applet->id() : -1;
|
|
if (m_id != id) {
|
|
m_id = id;
|
|
Q_EMIT idChanged();
|
|
|
|
// ensure the id is saved
|
|
Q_EMIT saveRequested();
|
|
}
|
|
|
|
if (m_applet) {
|
|
setVisualApplet(PlasmaQuick::AppletQuickItem::itemForApplet(m_applet));
|
|
} else {
|
|
setVisualApplet(nullptr);
|
|
}
|
|
}
|
|
|
|
PlasmaQuick::AppletQuickItem *FolioWidget::visualApplet() const
|
|
{
|
|
return m_quickApplet;
|
|
}
|
|
|
|
void FolioWidget::setVisualApplet(PlasmaQuick::AppletQuickItem *quickItem)
|
|
{
|
|
m_quickApplet = quickItem;
|
|
Q_EMIT visualAppletChanged();
|
|
}
|
|
|
|
void FolioWidget::destroyApplet()
|
|
{
|
|
if (m_applet) {
|
|
m_applet->destroy();
|
|
}
|
|
}
|