File indexing completed on 2024-06-02 05:42:16
0001 // SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org> 0002 // SPDX-License-Identifier: GPL-2.0-or-later 0003 0004 #include "foliowidget.h" 0005 #include "homescreenstate.h" 0006 #include "widgetsmanager.h" 0007 0008 FolioWidget::FolioWidget(QObject *parent, int id, int realGridWidth, int realGridHeight) 0009 : QObject{parent} 0010 , m_id{id} 0011 , m_realGridWidth{realGridWidth} 0012 , m_realGridHeight{realGridHeight} 0013 , m_applet{nullptr} 0014 , m_quickApplet{nullptr} 0015 { 0016 auto *applet = WidgetsManager::self()->getWidget(id); 0017 if (applet) { 0018 setApplet(applet); 0019 } 0020 init(); 0021 } 0022 0023 FolioWidget::FolioWidget(QObject *parent, Plasma::Applet *applet, int realGridWidth, int realGridHeight) 0024 : QObject{parent} 0025 , m_id{applet ? static_cast<int>(applet->id()) : -1} 0026 , m_realGridWidth{realGridWidth} 0027 , m_realGridHeight{realGridHeight} 0028 { 0029 setApplet(applet); 0030 init(); 0031 } 0032 0033 void FolioWidget::init() 0034 { 0035 connect(HomeScreenState::self(), &HomeScreenState::pageOrientationChanged, this, [this]() { 0036 Q_EMIT gridWidthChanged(); 0037 Q_EMIT gridHeightChanged(); 0038 }); 0039 0040 connect(WidgetsManager::self(), &WidgetsManager::widgetAdded, this, [this](Plasma::Applet *applet) { 0041 if (applet && static_cast<int>(applet->id()) == m_id) { 0042 setApplet(applet); 0043 } 0044 }); 0045 connect(WidgetsManager::self(), &WidgetsManager::widgetRemoved, this, [this](Plasma::Applet *applet) { 0046 if (applet && static_cast<int>(applet->id()) == m_id) { 0047 setApplet(nullptr); 0048 } 0049 }); 0050 } 0051 0052 FolioWidget *FolioWidget::fromJson(QJsonObject &obj, QObject *parent) 0053 { 0054 int id = obj[QStringLiteral("id")].toInt(); 0055 int gridWidth = obj[QStringLiteral("gridWidth")].toInt(); 0056 int gridHeight = obj[QStringLiteral("gridHeight")].toInt(); 0057 return new FolioWidget(parent, id, gridWidth, gridHeight); 0058 } 0059 0060 QJsonObject FolioWidget::toJson() const 0061 { 0062 QJsonObject obj; 0063 obj[QStringLiteral("type")] = "widget"; 0064 obj[QStringLiteral("id")] = m_id; 0065 obj[QStringLiteral("gridWidth")] = m_realGridWidth; 0066 obj[QStringLiteral("gridHeight")] = m_realGridHeight; 0067 return obj; 0068 } 0069 0070 int FolioWidget::id() const 0071 { 0072 return m_id; 0073 } 0074 0075 int FolioWidget::gridWidth() const 0076 { 0077 switch (HomeScreenState::self()->pageOrientation()) { 0078 case HomeScreenState::RegularPosition: 0079 return m_realGridWidth; 0080 case HomeScreenState::RotateClockwise: 0081 return m_realGridHeight; 0082 case HomeScreenState::RotateCounterClockwise: 0083 return m_realGridHeight; 0084 case HomeScreenState::RotateUpsideDown: 0085 return m_realGridWidth; 0086 } 0087 return m_realGridWidth; 0088 } 0089 0090 void FolioWidget::setGridWidth(int gridWidth) 0091 { 0092 switch (HomeScreenState::self()->pageOrientation()) { 0093 case HomeScreenState::RegularPosition: 0094 setRealGridWidth(gridWidth); 0095 break; 0096 case HomeScreenState::RotateClockwise: { 0097 int oldGridHeight = m_realGridHeight; 0098 setRealGridHeight(gridWidth); 0099 Q_EMIT realTopLeftPositionChanged(oldGridHeight - gridWidth, 0); 0100 break; 0101 } 0102 case HomeScreenState::RotateCounterClockwise: 0103 setRealGridHeight(gridWidth); 0104 break; 0105 case HomeScreenState::RotateUpsideDown: { 0106 int oldGridWidth = m_realGridWidth; 0107 setRealGridWidth(gridWidth); 0108 Q_EMIT realTopLeftPositionChanged(0, oldGridWidth - gridWidth); 0109 break; 0110 } 0111 } 0112 } 0113 0114 int FolioWidget::gridHeight() const 0115 { 0116 switch (HomeScreenState::self()->pageOrientation()) { 0117 case HomeScreenState::RegularPosition: 0118 return m_realGridHeight; 0119 case HomeScreenState::RotateClockwise: 0120 return m_realGridWidth; 0121 case HomeScreenState::RotateCounterClockwise: 0122 return m_realGridWidth; 0123 case HomeScreenState::RotateUpsideDown: 0124 return m_realGridHeight; 0125 } 0126 return m_realGridHeight; 0127 } 0128 0129 void FolioWidget::setGridHeight(int gridHeight) 0130 { 0131 switch (HomeScreenState::self()->pageOrientation()) { 0132 case HomeScreenState::RegularPosition: 0133 setRealGridHeight(gridHeight); 0134 break; 0135 case HomeScreenState::RotateClockwise: 0136 setRealGridWidth(gridHeight); 0137 break; 0138 case HomeScreenState::RotateCounterClockwise: { 0139 int oldGridWidth = m_realGridWidth; 0140 setRealGridWidth(gridHeight); 0141 Q_EMIT realTopLeftPositionChanged(0, oldGridWidth - gridHeight); 0142 break; 0143 } 0144 case HomeScreenState::RotateUpsideDown: { 0145 int oldGridHeight = m_realGridHeight; 0146 setRealGridHeight(gridHeight); 0147 Q_EMIT realTopLeftPositionChanged(oldGridHeight - gridHeight, 0); 0148 break; 0149 } 0150 } 0151 } 0152 0153 int FolioWidget::realGridWidth() const 0154 { 0155 return m_realGridWidth; 0156 } 0157 0158 void FolioWidget::setRealGridWidth(int gridWidth) 0159 { 0160 if (m_realGridWidth != gridWidth) { 0161 m_realGridWidth = gridWidth; 0162 0163 // emit both because realGridWidth could be either gridWidth or gridHeight 0164 Q_EMIT gridWidthChanged(); 0165 Q_EMIT gridHeightChanged(); 0166 0167 Q_EMIT saveRequested(); 0168 } 0169 } 0170 0171 int FolioWidget::realGridHeight() const 0172 { 0173 return m_realGridHeight; 0174 } 0175 0176 void FolioWidget::setRealGridHeight(int gridHeight) 0177 { 0178 if (m_realGridHeight != gridHeight) { 0179 m_realGridHeight = gridHeight; 0180 0181 // emit both because realGridHeight could be either gridWidth or gridHeight 0182 Q_EMIT gridWidthChanged(); 0183 Q_EMIT gridHeightChanged(); 0184 0185 Q_EMIT saveRequested(); 0186 } 0187 } 0188 0189 GridPosition FolioWidget::topLeftCorner(int row, int column) 0190 { 0191 switch (HomeScreenState::self()->pageOrientation()) { 0192 case HomeScreenState::RegularPosition: 0193 return {row, column}; 0194 case HomeScreenState::RotateClockwise: 0195 return {row, column - gridWidth() + 1}; 0196 case HomeScreenState::RotateCounterClockwise: 0197 return {row - gridHeight() + 1, column}; 0198 case HomeScreenState::RotateUpsideDown: 0199 return {row - gridHeight() + 1, column - gridWidth() + 1}; 0200 } 0201 return {row, column}; 0202 } 0203 0204 bool FolioWidget::isInBounds(int widgetRow, int widgetColumn, int row, int column) 0205 { 0206 return (row >= widgetRow) && (row <= widgetRow + gridHeight() - 1) && (column >= widgetColumn) && (column <= widgetColumn + gridWidth() - 1); 0207 } 0208 0209 bool FolioWidget::overlapsWidget(int widgetRow, int widgetColumn, FolioWidget *otherWidget, int otherWidgetRow, int otherWidgetColumn) 0210 { 0211 if (!otherWidget) { 0212 return false; 0213 } 0214 0215 // property: if they overlap, then at least one corner of one widget is in the other widget 0216 int widgetMaxRow = widgetRow + gridHeight() - 1; 0217 int widgetMaxColumn = widgetColumn + gridWidth() - 1; 0218 int otherWidgetMaxRow = otherWidgetRow + otherWidget->gridHeight() - 1; 0219 int otherWidgetMaxColumn = otherWidgetColumn + otherWidget->gridWidth() - 1; 0220 0221 return isInBounds(widgetRow, widgetColumn, otherWidgetRow, otherWidgetColumn) || isInBounds(widgetRow, widgetColumn, otherWidgetMaxRow, otherWidgetColumn) 0222 || isInBounds(widgetRow, widgetColumn, otherWidgetRow, otherWidgetMaxColumn) 0223 || isInBounds(widgetRow, widgetColumn, otherWidgetMaxRow, otherWidgetMaxColumn) 0224 || otherWidget->isInBounds(otherWidgetRow, otherWidgetColumn, widgetRow, widgetColumn) 0225 || otherWidget->isInBounds(otherWidgetRow, otherWidgetColumn, widgetMaxRow, widgetColumn) 0226 || otherWidget->isInBounds(otherWidgetRow, otherWidgetColumn, widgetRow, widgetMaxColumn) 0227 || otherWidget->isInBounds(otherWidgetRow, otherWidgetColumn, widgetMaxRow, widgetMaxColumn); 0228 } 0229 0230 Plasma::Applet *FolioWidget::applet() const 0231 { 0232 return m_applet; 0233 } 0234 0235 void FolioWidget::setApplet(Plasma::Applet *applet) 0236 { 0237 m_applet = applet; 0238 Q_EMIT appletChanged(); 0239 0240 int id = applet ? applet->id() : -1; 0241 if (m_id != id) { 0242 m_id = id; 0243 Q_EMIT idChanged(); 0244 0245 // ensure the id is saved 0246 Q_EMIT saveRequested(); 0247 } 0248 0249 if (m_applet) { 0250 setVisualApplet(PlasmaQuick::AppletQuickItem::itemForApplet(m_applet)); 0251 } else { 0252 setVisualApplet(nullptr); 0253 } 0254 } 0255 0256 PlasmaQuick::AppletQuickItem *FolioWidget::visualApplet() const 0257 { 0258 return m_quickApplet; 0259 } 0260 0261 void FolioWidget::setVisualApplet(PlasmaQuick::AppletQuickItem *quickItem) 0262 { 0263 m_quickApplet = quickItem; 0264 Q_EMIT visualAppletChanged(); 0265 } 0266 0267 void FolioWidget::destroyApplet() 0268 { 0269 if (m_applet) { 0270 m_applet->destroy(); 0271 } 0272 }