diff --git a/containments/CMakeLists.txt b/containments/CMakeLists.txt index fd2ddeab..a1915629 100644 --- a/containments/CMakeLists.txt +++ b/containments/CMakeLists.txt @@ -1,5 +1,4 @@ add_subdirectory(panel) add_subdirectory(homescreen) -add_subdirectory(homescreen2) add_subdirectory(taskpanel) diff --git a/containments/homescreen/CMakeLists.txt b/containments/homescreen/CMakeLists.txt index 8a4ffda4..1e185c14 100644 --- a/containments/homescreen/CMakeLists.txt +++ b/containments/homescreen/CMakeLists.txt @@ -11,6 +11,7 @@ target_link_libraries(plasma_containment_phone_homescreen Qt5::Gui KF5::Plasma Qt5::Qml + Qt5::Quick KF5::I18n KF5::Service KF5::KIOWidgets diff --git a/containments/homescreen/applicationlistmodel.cpp b/containments/homescreen/applicationlistmodel.cpp index b3e06c71..513681f4 100644 --- a/containments/homescreen/applicationlistmodel.cpp +++ b/containments/homescreen/applicationlistmodel.cpp @@ -37,12 +37,26 @@ #include #include -ApplicationListModel::ApplicationListModel(QObject *parent) - : QAbstractListModel(parent) + +ApplicationListModel::ApplicationListModel(HomeScreen *parent) + : QAbstractListModel(parent), + m_homeScreen(parent) { //can't use the new syntax as this signal is overloaded connect(KSycoca::self(), SIGNAL(databaseChanged(const QStringList &)), this, SLOT(sycocaDbChanged(const QStringList &))); + m_favorites = m_homeScreen->config().readEntry("Favorites", QStringList()); + m_desktopItems = m_homeScreen->config().readEntry("DesktopItems", QStringList()).toSet(); + m_appOrder = m_homeScreen->config().readEntry("AppOrder", QStringList()); + m_maxFavoriteCount = m_homeScreen->config().readEntry("MaxFavoriteCount", 5); + + int i = 0; + for (auto app : m_appOrder) { + m_appPositions[app] = i; + ++i; + } + //here or delayed? + loadApplications(); } ApplicationListModel::~ApplicationListModel() @@ -56,6 +70,8 @@ QHash ApplicationListModel::roleNames() const roleNames[ApplicationStorageIdRole] = "ApplicationStorageIdRole"; roleNames[ApplicationEntryPathRole] = "ApplicationEntryPathRole"; roleNames[ApplicationOriginalRowRole] = "ApplicationOriginalRowRole"; + roleNames[ApplicationStartupNotifyRole] = "ApplicationStartupNotifyRole"; + roleNames[ApplicationLocationRole] = "ApplicationLocationRole"; return roleNames; } @@ -120,8 +136,6 @@ void ApplicationListModel::loadApplications() } else if (entry->property("Exec").isValid()) { KService::Ptr service(static_cast(entry.data())); - qDebug() << " desktopEntryName: " << service->desktopEntryName(); - if (service->isApplication() && !blacklist.contains(service->desktopEntryName()) && service->showOnCurrentPlatform() && @@ -134,6 +148,13 @@ void ApplicationListModel::loadApplications() data.icon = service->icon(); data.storageId = service->storageId(); data.entryPath = service->exec(); + data.startupNotify = service->property("StartupNotify").toBool(); + + if (m_favorites.contains(data.storageId)) { + data.location = Favorites; + } else if (m_desktopItems.contains(data.storageId)) { + data.location = Desktop; + } auto it = m_appPositions.constFind(service->storageId()); if (it != m_appPositions.constEnd()) { @@ -178,6 +199,10 @@ QVariant ApplicationListModel::data(const QModelIndex &index, int role) const return m_applicationList.at(index.row()).entryPath; case ApplicationOriginalRowRole: return index.row(); + case ApplicationStartupNotifyRole: + return m_applicationList.at(index.row()).startupNotify; + case ApplicationLocationRole: + return m_applicationList.at(index.row()).location; default: return QVariant(); @@ -205,7 +230,52 @@ void ApplicationListModel::moveRow(const QModelIndex& /* sourceParent */, int so moveItem(sourceRow, destinationChild); } -Q_INVOKABLE void ApplicationListModel::moveItem(int row, int destination) +void ApplicationListModel::setLocation(int row, LauncherLocation location) +{ + if (row < 0 || row >= m_applicationList.length()) { + return; + } + + ApplicationData &data = m_applicationList[row]; + if (data.location == location) { + return; + } + + if (location == Favorites) {qWarning()<<"favoriting"<= m_maxFavoriteCount || m_favorites.count() >= m_maxFavoriteCount) { + return; + } + + m_favorites.insert(row, data.storageId); + + m_homeScreen->config().writeEntry("Favorites", m_favorites); + emit favoriteCountChanged(); + + // Out of favorites + } else if (data.location == Favorites) { + m_favorites.removeAll(data.storageId); + m_homeScreen->config().writeEntry("Favorites", m_favorites); + emit favoriteCountChanged(); + } + + // In Desktop + if (location == Desktop) { + m_desktopItems.insert(data.storageId); + m_homeScreen->config().writeEntry("DesktopItems", m_desktopItems.toList()); + + // Out of Desktop + } else if (data.location == Desktop) { + m_desktopItems.remove(data.storageId); + m_homeScreen->config().writeEntry("DesktopItems", m_desktopItems.toList()); + } + + data.location = location; + emit m_homeScreen->configNeedsSaving(); + emit dataChanged(index(row, 0), index(row, 0)); +} + +void ApplicationListModel::moveItem(int row, int destination) { if (row < 0 || destination < 0 || row >= m_applicationList.length() || destination >= m_applicationList.length() || row == destination) { @@ -220,6 +290,7 @@ Q_INVOKABLE void ApplicationListModel::moveItem(int row, int destination) ApplicationData data = m_applicationList.at(row); m_applicationList.insert(destination, data); m_applicationList.takeAt(row); + } else { ApplicationData data = m_applicationList.takeAt(row); m_applicationList.insert(destination, data); @@ -235,8 +306,8 @@ Q_INVOKABLE void ApplicationListModel::moveItem(int row, int destination) ++i; } + m_homeScreen->config().writeEntry("AppOrder", m_appOrder); - emit appOrderChanged(); endMoveRows(); } @@ -251,23 +322,38 @@ void ApplicationListModel::runApplication(const QString &storageId) KRun::runService(*service, QList(), nullptr); } -QStringList ApplicationListModel::appOrder() const +int ApplicationListModel::maxFavoriteCount() const { - return m_appOrder; + return m_maxFavoriteCount; } -void ApplicationListModel::setAppOrder(const QStringList &order) +void ApplicationListModel::setMaxFavoriteCount(int count) { - if (m_appOrder == order) { + if (m_maxFavoriteCount == count) { return; } - m_appOrder = order; - m_appPositions.clear(); - int i = 0; - for (auto app : m_appOrder) { - m_appPositions[app] = i; - ++i; + if (m_maxFavoriteCount > count) { + while (m_favorites.size() > count && m_favorites.count() > 0) { + m_favorites.pop_back(); + } + emit favoriteCountChanged(); + + int i = 0; + for (auto &app : m_applicationList) { + if (i >= count && app.location == Favorites) { + app.location = Grid; + emit dataChanged(index(i, 0), index(i, 0)); + } + ++i; + } } - emit appOrderChanged(); + + m_maxFavoriteCount = count; + m_homeScreen->config().writeEntry("MaxFavoriteCount", m_maxFavoriteCount); + + emit maxFavoriteCountChanged(); } + +#include "moc_applicationlistmodel.cpp" + diff --git a/containments/homescreen/applicationlistmodel.h b/containments/homescreen/applicationlistmodel.h index ddf65bf5..7e3f1ad4 100644 --- a/containments/homescreen/applicationlistmodel.h +++ b/containments/homescreen/applicationlistmodel.h @@ -25,30 +25,58 @@ #include #include +#include "homescreen.h" + class QString; +class ApplicationListModel; + struct ApplicationData { QString name; QString icon; QString storageId; QString entryPath; + int location = 0; //FIXME + bool startupNotify = true; }; class ApplicationListModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(int count READ count NOTIFY countChanged) - Q_PROPERTY(QStringList appOrder READ appOrder WRITE setAppOrder NOTIFY appOrderChanged) + Q_PROPERTY(int favoriteCount READ favoriteCount NOTIFY favoriteCountChanged) + Q_PROPERTY(int maxFavoriteCount READ maxFavoriteCount WRITE setMaxFavoriteCount NOTIFY maxFavoriteCountChanged) public: - ApplicationListModel(QObject *parent = nullptr); + enum LauncherLocation { + Grid = 0, + Favorites, + Desktop + }; + Q_ENUM(LauncherLocation) + + enum Roles { + ApplicationNameRole = Qt::UserRole + 1, + ApplicationIconRole, + ApplicationStorageIdRole, + ApplicationEntryPathRole, + ApplicationOriginalRowRole, + ApplicationStartupNotifyRole, + ApplicationLocationRole + }; + + ApplicationListModel(HomeScreen *parent = nullptr); ~ApplicationListModel() override; int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; void moveRow(const QModelIndex &sourceParent, int sourceRow, const QModelIndex &destinationParent, int destinationChild); - int count() { return m_applicationList.count(); } + int count() const { return m_applicationList.count(); } + int favoriteCount() const { return m_favorites.count();} + + int maxFavoriteCount() const; + void setMaxFavoriteCount(int count); QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; @@ -56,16 +84,7 @@ public: QHash roleNames() const Q_DECL_OVERRIDE; - enum Roles { - ApplicationNameRole = Qt::UserRole + 1, - ApplicationIconRole = Qt::UserRole + 2, - ApplicationStorageIdRole = Qt::UserRole + 3, - ApplicationEntryPathRole = Qt::UserRole + 4, - ApplicationOriginalRowRole = Qt::UserRole + 6 - }; - - QStringList appOrder() const; - void setAppOrder(const QStringList &order); + Q_INVOKABLE void setLocation(int row, LauncherLocation location); Q_INVOKABLE void moveItem(int row, int order); @@ -78,12 +97,17 @@ public Q_SLOTS: Q_SIGNALS: void countChanged(); - void appOrderChanged(); + void favoriteCountChanged(); + void maxFavoriteCountChanged(); private: QList m_applicationList; + HomeScreen *m_homeScreen = nullptr; + int m_maxFavoriteCount = 0; QStringList m_appOrder; + QStringList m_favorites; + QSet m_desktopItems; QHash m_appPositions; }; diff --git a/containments/homescreen/homescreen.cpp b/containments/homescreen/homescreen.cpp index 452667e4..8932d62f 100644 --- a/containments/homescreen/homescreen.cpp +++ b/containments/homescreen/homescreen.cpp @@ -22,12 +22,13 @@ #include #include +#include HomeScreen::HomeScreen(QObject *parent, const QVariantList &args) : Plasma::Containment(parent, args) { - qmlRegisterType(); - m_applicationListModel = new ApplicationListModel(this); + qmlRegisterUncreatableType("org.kde.phone.homescreen", 1, 0, "ApplicationListModel", QStringLiteral("Cannot create item of type ApplicationListModel")); + setHasConfigurationInterface(true); } @@ -36,9 +37,30 @@ HomeScreen::~HomeScreen() ApplicationListModel *HomeScreen::applicationListModel() { + if (!m_applicationListModel) { + m_applicationListModel = new ApplicationListModel(this); + } return m_applicationListModel; } +void HomeScreen::stackBefore(QQuickItem *item1, QQuickItem *item2) +{ + if (!item1 || !item2 || item1->parentItem() != item2->parentItem()) { + return; + } + + item1->stackBefore(item2); +} + +void HomeScreen::stackAfter(QQuickItem *item1, QQuickItem *item2) +{ + if (!item1 || !item2 || item1->parentItem() != item2->parentItem()) { + return; + } + + item1->stackAfter(item2); +} + K_EXPORT_PLASMA_APPLET_WITH_JSON(homescreen, HomeScreen, "metadata.json") #include "homescreen.moc" diff --git a/containments/homescreen/homescreen.h b/containments/homescreen/homescreen.h index 6a7bbf18..1387b81e 100644 --- a/containments/homescreen/homescreen.h +++ b/containments/homescreen/homescreen.h @@ -24,6 +24,7 @@ #include +class QQuickItem; class ApplicationListModel; class HomeScreen : public Plasma::Containment @@ -37,8 +38,11 @@ public: ApplicationListModel *applicationListModel(); + Q_INVOKABLE void stackBefore(QQuickItem *item1, QQuickItem *item2); + Q_INVOKABLE void stackAfter(QQuickItem *item1, QQuickItem *item2); + private: - ApplicationListModel *m_applicationListModel; + ApplicationListModel *m_applicationListModel = nullptr; }; diff --git a/containments/homescreen/package/contents/code/LayoutManager.js b/containments/homescreen/package/contents/code/LayoutManager.js deleted file mode 100644 index 34f0d306..00000000 --- a/containments/homescreen/package/contents/code/LayoutManager.js +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright 2013 Marco Martin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details - * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -var layout; -var root; -var plasmoid; -var lastSpacer; - - -function restore() { - var configString = String(plasmoid.configuration.AppletOrder) - - //array, a cell for encoded item order - var itemsArray = configString.split(";"); - - //map applet id->order in panel - var idsOrder = new Object(); - //map order in panel -> applet pointer - var appletsOrder = new Object(); - - for (var i = 0; i < itemsArray.length; i++) { - //property name: applet id - //property value: order - idsOrder[itemsArray[i]] = i; - } - - for (var i = 0; i < plasmoid.applets.length; ++i) { - if (idsOrder[plasmoid.applets[i].id] !== undefined) { - appletsOrder[idsOrder[plasmoid.applets[i].id]] = plasmoid.applets[i]; - //ones that weren't saved in AppletOrder go to the end - } else { - appletsOrder["unordered"+i] = plasmoid.applets[i]; - } - } - - //finally, restore the applets in the correct order - for (var i in appletsOrder) { - root.addApplet(appletsOrder[i], -1, -1) - } - //rewrite, so if in the orders there were now invalid ids or if some were missing creates a correct list instead - save(); -} - -function save() { - var ids = new Array(); - for (var i = 0; i < layout.children.length; ++i) { - var child = layout.children[i]; - - if (child.applet) { - ids.push(child.applet.id); - } - } - plasmoid.configuration.AppletOrder = ids.join(';'); -} - -function removeApplet (applet) { - for (var i = layout.children.length - 1; i >= 0; --i) { - var child = layout.children[i]; - if (child.applet === applet) { - child.destroy(); - } - } -} - -//insert item2 before item1 -function insertBefore(item1, item2) { - if (item1 === item2) { - return; - } - var removed = new Array(); - - var child; - - var i; - for (i = layout.children.length - 1; i >= 0; --i) { - child = layout.children[i]; - removed.push(child); - child.parent = root; - - if (child === item1) { - break; - } - } - - item2.parent = layout; - - for (var j = removed.length - 1; j >= 0; --j) { - removed[j].parent = layout; - } - return i; -} - -//insert item2 after item1 -function insertAfter(item1, item2) { - if (item1 === item2) { - return; - } - var removed = new Array(); - - var child; - - var i; - for (i = layout.children.length - 1; i >= 0; --i) { - child = layout.children[i]; - //never ever insert after lastSpacer - if (child === lastSpacer && item1 === lastSpacer) { - removed.push(child); - child.parent = root; - break; - } else if (child === item1) { - break; - } - - removed.push(child); - child.parent = root; - } - - item2.parent = layout; - - for (var j = removed.length - 1; j >= 0; --j) { - removed[j].parent = layout; - } - return i; -} - -function insertAtIndex(item, position) { - if (position < 0 || position >= layout.children.length) { - return; - } - - //never ever insert after lastSpacer - if (layout.children[position] === lastSpacer) { - --position; - } - - var removedItems = new Array(); - - for (var i = position; i < layout.children.length; ++i) { - var child = layout.children[position]; - child.parent = root; - removedItems.push(child); - } - - item.parent = layout; - for (var i in removedItems) { - removedItems[i].parent = layout; - } -} - -function insertAtCoordinates(item, x, y) { - if (root.isHorizontal) { - y = layout.height / 2; - } else { - x = layout.width / 2; - } - var child = layout.childAt(x, y); - - if (!child || child === item) { - child = layout.children[0]; - } - item.parent = root; - - //PlasmaCore.Types.Vertical = 3 - if ((plasmoid.formFactor === 3 && y < child.y + child.height/2) || - (plasmoid.formFactor !== 3 && x < child.x + child.width/2)) { - return insertBefore(child, item); - } else { - return insertAfter(child, item); - } -} diff --git a/containments/homescreen/package/contents/config/main.xml b/containments/homescreen/package/contents/config/main.xml index 92a9517b..d191ada3 100644 --- a/containments/homescreen/package/contents/config/main.xml +++ b/containments/homescreen/package/contents/config/main.xml @@ -6,9 +6,6 @@ - - - org.kde.phone.dialer.desktop diff --git a/containments/homescreen2/package/contents/ui/ActionButton.qml b/containments/homescreen/package/contents/ui/ActionButton.qml similarity index 100% rename from containments/homescreen2/package/contents/ui/ActionButton.qml rename to containments/homescreen/package/contents/ui/ActionButton.qml diff --git a/containments/homescreen/package/contents/ui/AppletsArea.qml b/containments/homescreen/package/contents/ui/AppletsArea.qml deleted file mode 100644 index 2d4c84cf..00000000 --- a/containments/homescreen/package/contents/ui/AppletsArea.qml +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright 2015 Marco Martin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA. - */ - -import QtQuick 2.4 -import QtQuick.Layouts 1.1 - -import org.kde.plasma.plasmoid 2.0 -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.plasma.components 2.0 as PlasmaComponents -import org.kde.kquickcontrolsaddons 2.0 - -MouseArea { - id: headerItem - z: 999 - property Item layout: appletsLayout - property Item lastSpacer: spacer - property Item favoritesStrip: favoritesView - width: root.width - height: Math.max(applicationsView.height - stripe.height, mainLayout.Layout.minimumHeight) - property int margin: stripe.height + units.gridUnit * 2 - property Item draggingApplet - property int startMouseX - property int startMouseY - property int oldMouseX - property int oldMouseY - - drag.filterChildren: true - EventGenerator { - id: eventGenerator - } - - SequentialAnimation { - id: removeAnim - property Item target - property real to - NumberAnimation { - properties: "x" - duration: units.longDuration - easing.type: Easing.InOutQuad - target: removeAnim.target - to: removeAnim.to - } - ScriptAction { - script: removeAnim.target.applet.action("remove").trigger(); - } - } - - onPressed: { - startMouseX = mouse.x; - startMouseY = mouse.y; - } - onPressAndHold: { - var absolutePos = mapToItem(appletsLayout, mouse.x, mouse.y); - var absoluteStartPos = mapToItem(appletsLayout, startMouseX, startMouseY); - - if (Math.abs(absolutePos.x - absoluteStartPos.x) > units.gridUnit*2 || - Math.abs(absolutePos.y - absoluteStartPos.y) > units.gridUnit*2) { - print("finger moved too much, press and hold canceled") - return; - } - print(favoritesView.contains(mapToItem(favoritesView, mouse.x, mouse.y))) - if (!favoritesView.contains(mapToItem(favoritesView, mouse.x, mouse.y))) { - editOverlay.visible = true; - var pos = mapToItem(appletsLayout, mouse.x, mouse.y); - draggingApplet = appletsSpace.layout.childAt(absolutePos.x, absolutePos.y); - editOverlay.applet = draggingApplet; - - oldMouseX = mouse.x; - oldMouseY = mouse.y; - - eventGenerator.sendGrabEvent(draggingApplet, EventGenerator.UngrabMouse); - eventGenerator.sendGrabEvent(headerItem, EventGenerator.GrabMouse); - eventGenerator.sendMouseEvent(headerItem, EventGenerator.MouseButtonPress, mouse.x, mouse.y, Qt.LeftButton, Qt.LeftButton, 0) - - if (draggingApplet) { - draggingApplet.animationsEnabled = false; - dndSpacer.height = draggingApplet.height; - root.layoutManager.insertBefore(draggingApplet, dndSpacer); - draggingApplet.parent = headerItem; - - pos = mapToItem(headerItem, mouse.x, mouse.y); - draggingApplet.y = pos.y - draggingApplet.height/2; - - applicationsView.interactive = false; - } - } - } - - onPositionChanged: { - if (!draggingApplet) { - return; - } - - applicationsView.interactive = false; - if (Math.abs(mouse.x - startMouseX) > units.gridUnit || - Math.abs(mouse.y - startMouseY) > units.gridUnit) { - editOverlay.opacity = 0; - } - - draggingApplet.x -= oldMouseX - mouse.x; - draggingApplet.y -= oldMouseY - mouse.y; - oldMouseX = mouse.x; - oldMouseY = mouse.y; - - var pos = mapToItem(appletsLayout, mouse.x, mouse.y); - var itemUnderMouse = appletsSpace.layout.childAt(pos.x, pos.y); - - if (itemUnderMouse && itemUnderMouse != dndSpacer) { - dndSpacer.parent = colorScope; - if (pos.y < itemUnderMouse.y + itemUnderMouse.height/2) { - root.layoutManager.insertBefore(itemUnderMouse, dndSpacer); - } else { - root.layoutManager.insertAfter(itemUnderMouse, dndSpacer); - } - } - - pos = mapToItem(root, mouse.x, mouse.y); - //SCROLL UP - if (applicationsView.contentY > -applicationsView.headerItem.height + root.height && pos.y < root.height/4) { - root.scrollUp(); - //SCROLL DOWN - } else if (applicationsView.contentY < 0 && pos.y > 3 * (root.height / 4)) { - root.scrollDown(); - //DON't SCROLL - } else { - root.stopScroll(); - } - } - onReleased: { - if (!draggingApplet) { - return; - } - - if (draggingApplet.x > -draggingApplet.width/3 && draggingApplet.x < draggingApplet.width/3) { - draggingApplet.x = 0; - root.layoutManager.insertBefore( dndSpacer, draggingApplet); - } else { - removeAnim.target = draggingApplet; - removeAnim.to = (draggingApplet.x > 0) ? root.width : -root.width - removeAnim.running = true; - } - applicationsView.interactive = true; - dndSpacer.parent = colorScope; - draggingApplet = null; - } - - ColumnLayout { - id: mainLayout - anchors { - fill: parent - } - - Item { - Layout.minimumHeight: krunner.inputHeight - Layout.minimumWidth: Layout.minimumHeight - } - PlasmaCore.ColorScope { - id: colorScope - //TODO: decide what color we want applets - colorGroup: PlasmaCore.Theme.NormalColorGroup - Layout.fillWidth: true - Layout.minimumHeight: appletsLayout.implicitHeight - Layout.maximumHeight: appletsLayout.implicitHeight - Column { - id: appletsLayout - width: parent.width - move: Transition { - NumberAnimation { - properties: "x,y" - duration: units.longDuration - easing.type: Easing.InOutQuad - } - } - } - Item { - id: dndSpacer - width: parent.width - } - } - } - SatelliteStripe { - id: stripe - z: 99 - property int viewPos: applicationsView.contentItem.height * applicationsView.visibleArea.yPosition - - y: Math.max(viewPos + krunner.inputHeight - units.smallSpacing, - Math.min(parent.height, viewPos + plasmoid.availableScreenRect.height - height) ) - - PlasmaCore.IconItem { - id: goUp - source: "arrow-up" - width: units.iconSizes.medium - height: width - colorGroup: PlasmaCore.Theme.ComplementaryColorGroup - anchors { - horizontalCenter: parent.horizontalCenter - bottom: parent.top - margins: units.largeSpacing - } - MouseArea { - anchors { - fill: parent - margins: -units.smallSpacing - } - onClicked: applicationsView.flick(0, -applicationsView.height/2) - } - } - - GridView { - id: favoritesView - //FIXME: QQuickItem has a contains, but seems to not work - function contains(point) { - return point.x > 0 && point.x < width && point.y > 0 && point.y < height; - } - anchors.fill: parent - property int columns: 4 - interactive: false - flow: GridView.FlowTopToBottom - - cellWidth: root.width / 4 - cellHeight: root.buttonHeight - - model: plasmoid.nativeInterface.applicationListModel - delegate: HomeLauncher { - maximumLineCount: 1 - iconSize: root.iconSize - } - - move: Transition { - NumberAnimation { - duration: units.longDuration - easing.type: Easing.InOutQuad - properties: "x,y" - } - } - moveDisplaced: Transition { - NumberAnimation { - duration: units.longDuration - easing.type: Easing.InOutQuad - properties: "x,y" - } - } - } - } -} diff --git a/containments/homescreen2/package/contents/ui/ConfigOverlay.qml b/containments/homescreen/package/contents/ui/ConfigOverlay.qml similarity index 100% rename from containments/homescreen2/package/contents/ui/ConfigOverlay.qml rename to containments/homescreen/package/contents/ui/ConfigOverlay.qml diff --git a/containments/homescreen/package/contents/ui/EditOverlay.qml b/containments/homescreen/package/contents/ui/EditOverlay.qml deleted file mode 100644 index 0c0b9359..00000000 --- a/containments/homescreen/package/contents/ui/EditOverlay.qml +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2015 Marco Martin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) version 3, or any - * later version accepted by the membership of KDE e.V. (or its - * successor approved by the membership of KDE e.V.), which shall - * act as a proxy defined in Section 6 of version 3 of the license. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - */ - -import QtQuick 2.2 -import QtQuick.Layouts 1.1 - -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.plasma.components 2.0 as PlasmaComponents -import org.kde.plasma.extras 2.0 as PlasmaExtras - -import org.kde.milou 0.1 as Milou - -Rectangle { - id: editOverlay - anchors.fill: parent - - property Item applet - color: Qt.rgba(0, 0, 0, 0.8) - visible: false - onVisibleChanged: { - if (visible) { - opacity = 1; - } - } - opacity: 0 - Behavior on opacity { - SequentialAnimation { - OpacityAnimator { - duration: units.longDuration - easing.type: Easing.InOutQuad - } - ScriptAction { - script: { - if (editOverlay.opacity == 0) { - editOverlay.visible = false; - } - } - } - } - } - - MouseArea { - enabled: listView.visible - anchors.fill: parent - preventStealing: true - onClicked: editOverlay.opacity = 0; - PlasmaComponents.ButtonRow { - visible: editOverlay.applet - spacing: 0 - exclusive: false - anchors.horizontalCenter: parent.horizontalCenter - y: editOverlay.mapFromItem(editOverlay.applet.parent, 0, editOverlay.applet.y).y + editOverlay.applet.height/2 - height/2 - PlasmaComponents.ToolButton { - iconSource: "configure" - text: i18n("Configure...") - flat: false - onClicked: { - editOverlay.applet.applet.action("configure").trigger(); - editOverlay.opacity = 0; - } - } - PlasmaComponents.ToolButton { - iconSource: "window-close" - text: i18n("Remove") - flat: false - onClicked: { - editOverlay.applet.applet.action("remove").trigger(); - editOverlay.opacity = 0; - } - } - } - } - PlasmaCore.FrameSvgItem { - id: background - anchors { - left: parent.left - right: parent.right - bottom: parent.bottom - bottomMargin: editOverlay.height - (plasmoid.availableScreenRect.y + plasmoid.availableScreenRect.height) - } - height: buttonsLayout.height + fixedMargins.top + fixedMargins.bottom/2 - imagePath: "widgets/background" - enabledBorders: PlasmaCore.FrameSvg.TopBorder - RowLayout { - id: buttonsLayout - anchors { - left: parent.left - right: parent.right - top: parent.top - topMargin: parent.fixedMargins.top - leftMargin: parent.fixedMargins.left/2 - rightMargin: parent.fixedMargins.right/2 - bottomMargin: parent.fixedMargins.bottom/2 - } - PlasmaComponents.ToolButton { - Layout.fillWidth: true - Layout.fillHeight:true - text: i18n("Wallpaper...") - onClicked: { - plasmoid.action("configure").trigger(); - editOverlay.opacity = 0; - } - } - PlasmaComponents.ToolButton { - Layout.fillWidth: true - Layout.fillHeight:true - text: i18n("Add Widgets...") - onClicked: { - plasmoid.action("add widgets").trigger(); - editOverlay.opacity = 0; - } - } - } - } -} - diff --git a/containments/homescreen/package/contents/ui/FeedbackWindow.qml b/containments/homescreen/package/contents/ui/FeedbackWindow.qml index b9b92f09..15b92488 100644 --- a/containments/homescreen/package/contents/ui/FeedbackWindow.qml +++ b/containments/homescreen/package/contents/ui/FeedbackWindow.qml @@ -22,11 +22,13 @@ import QtQuick.Layouts 1.1 import QtQuick.Window 2.2 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents +import org.kde.plasma.extras 2.0 as PlasmaExtras Window { id: window property alias state: background.state + property alias icon: icon.source width: Screen.width height: Screen.height color: "transparent" @@ -41,19 +43,33 @@ Window { } } - PlasmaCore.ColorScope { + Item { id: background anchors.fill: parent - colorGroup: PlasmaCore.Theme.ComplementaryColorGroup + //colorGroup: PlasmaCore.Theme.ComplementaryColorGroup width: window.width height: window.height state: "closed" Rectangle { anchors.fill: parent color: background.backgroundColor - - PlasmaComponents.BusyIndicator { + + ColumnLayout { anchors.centerIn: parent + PlasmaCore.IconItem { + id: icon + colorGroup: PlasmaCore.Theme.ComplementaryColorGroup + Layout.preferredWidth: units.iconSizes.enormous + Layout.preferredHeight: Layout.preferredWidth + Layout.alignment: Qt.AlignCenter + } + PlasmaExtras.Heading { + text: window.title + Layout.alignment: Qt.AlignCenter + } + /* PlasmaComponents.BusyIndicator { + Layout.alignment: Qt.AlignCenter + }*/ } } diff --git a/containments/homescreen/package/contents/ui/HomeLauncher.qml b/containments/homescreen/package/contents/ui/HomeLauncher.qml deleted file mode 100644 index 6f438149..00000000 --- a/containments/homescreen/package/contents/ui/HomeLauncher.qml +++ /dev/null @@ -1,63 +0,0 @@ -import QtQuick 2.5 -import QtQuick.Layouts 1.2 -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.kio 1.0 as Kio -import org.kde.plasma.components 2.0 as PlasmaComponents - -Item { - id: delegateRoot - - property int iconSize - property var modelData: model - property bool isDropTarget: delegateRoot != dragDelegate && root.reorderingApps && applicationsView.dragData && applicationsView.dragData.ApplicationStorageIdRole == modelData.ApplicationStorageIdRole - property alias maximumLineCount: label.maximumLineCount - - width: applicationsView.cellWidth - height: applicationsView.cellHeight - - ColumnLayout { - anchors { - left: parent.left - right: parent.right - horizontalCenter: parent.horizonalCenter - verticalCenter: parent.verticalCenter - } - opacity: isDropTarget ? 0.3 : 1 - - PlasmaCore.IconItem { - id: icon - Layout.alignment: Qt.AlignHCenter - Layout.preferredWidth: delegateRoot.iconSize - Layout.preferredHeight: delegateRoot.iconSize - usesPlasmaTheme: false - source: modelData.ApplicationIconRole - scale: root.reorderingApps && applicationsView.dragData && applicationsView.dragData.ApplicationStorageIdRole != modelData.ApplicationStorageIdRole ? 0.6 : 1 - Behavior on scale { - NumberAnimation { - duration: units.longDuration - easing.type: Easing.InOutQuad - } - } - } - - PlasmaComponents.Label { - id: label - visible: text.length > 0 - - Layout.alignment: Qt.AlignHCenter - Layout.fillWidth: true - Layout.leftMargin: units.gridUnit - Layout.rightMargin: units.gridUnit - - wrapMode: Text.WordWrap - horizontalAlignment: Qt.AlignHCenter - verticalAlignment: Qt.AlignVCenter - maximumLineCount: 1 - elide: Text.ElideRight - - text: modelData.ApplicationNameRole - font.pixelSize: theme.defaultFont.pixelSize - color: PlasmaCore.ColorScope.textColor - } - } -} diff --git a/containments/homescreen/package/contents/ui/KRunner.qml b/containments/homescreen/package/contents/ui/KRunner.qml index 7a586adb..3632d877 100644 --- a/containments/homescreen/package/contents/ui/KRunner.qml +++ b/containments/homescreen/package/contents/ui/KRunner.qml @@ -31,7 +31,6 @@ import org.kde.milou 0.1 as Milou Rectangle { id: krunner - anchors.fill: parent height: childrenRect.height color: listView.visible ? Qt.rgba(0, 0, 0, 0.8) : "transparent" property alias showingResults: listView.visible @@ -53,7 +52,7 @@ Rectangle { clip: true imagePath: "widgets/background" enabledBorders: PlasmaCore.FrameSvg.BottomBorder - height: childrenRect.height + fixedMargins.top/2 + fixedMargins.bottom + height: Math.min(krunner.height, childrenRect.height + fixedMargins.top/2 + fixedMargins.bottom) Behavior on height { NumberAnimation { duration: units.longDuration @@ -71,7 +70,7 @@ Rectangle { } ColumnLayout { - height: Qt.inputMethod.keyboardRectangle.height > 0 ? (Math.min(implicitHeight, Qt.inputMethod.keyboardRectangle.y - plasmoid.availableScreenRect.y)) : implicitHeight + height: Qt.inputMethod.keyboardRectangle.height > 0 ? (Math.min(implicitHeight, background.height, Qt.inputMethod.keyboardRectangle.y - plasmoid.availableScreenRect.y)) : implicitHeight anchors { left: parent.left right: parent.right diff --git a/containments/homescreen/package/contents/ui/SatelliteStripe.qml b/containments/homescreen/package/contents/ui/SatelliteStripe.qml deleted file mode 100644 index 85154ab7..00000000 --- a/containments/homescreen/package/contents/ui/SatelliteStripe.qml +++ /dev/null @@ -1,25 +0,0 @@ - - -import QtQuick 2.0 -import org.kde.plasma.core 2.0 as PlasmaCore - -PlasmaCore.ColorScope { - colorGroup: PlasmaCore.Theme.NormalColorGroup - - PlasmaCore.FrameSvgItem { - z: -1 - imagePath: "widgets/background" - enabledBorders: PlasmaCore.FrameSvgItem.TopBorder | PlasmaCore.FrameSvgItem.BottomBorder - anchors { - fill: parent - topMargin: -margins.top / 2 - bottomMargin: -margins.bottom / 2 - } - } - - //cut away one line from the favorites bar - height: applicationsView.cellHeight - width: parent.width - y: parent.height / 2 - height / 2 - x: 0 -} diff --git a/containments/homescreen2/package/contents/ui/ScrollIndicator.qml b/containments/homescreen/package/contents/ui/ScrollIndicator.qml similarity index 100% rename from containments/homescreen2/package/contents/ui/ScrollIndicator.qml rename to containments/homescreen/package/contents/ui/ScrollIndicator.qml diff --git a/containments/homescreen2/package/contents/ui/launcher/Delegate.qml b/containments/homescreen/package/contents/ui/launcher/Delegate.qml similarity index 100% rename from containments/homescreen2/package/contents/ui/launcher/Delegate.qml rename to containments/homescreen/package/contents/ui/launcher/Delegate.qml diff --git a/containments/homescreen2/package/contents/ui/launcher/FavoriteStrip.qml b/containments/homescreen/package/contents/ui/launcher/FavoriteStrip.qml similarity index 100% rename from containments/homescreen2/package/contents/ui/launcher/FavoriteStrip.qml rename to containments/homescreen/package/contents/ui/launcher/FavoriteStrip.qml diff --git a/containments/homescreen2/package/contents/ui/launcher/FeedbackWindow.qml b/containments/homescreen/package/contents/ui/launcher/FeedbackWindow.qml similarity index 100% rename from containments/homescreen2/package/contents/ui/launcher/FeedbackWindow.qml rename to containments/homescreen/package/contents/ui/launcher/FeedbackWindow.qml diff --git a/containments/homescreen2/package/contents/ui/launcher/LauncherContainer.qml b/containments/homescreen/package/contents/ui/launcher/LauncherContainer.qml similarity index 100% rename from containments/homescreen2/package/contents/ui/launcher/LauncherContainer.qml rename to containments/homescreen/package/contents/ui/launcher/LauncherContainer.qml diff --git a/containments/homescreen2/package/contents/ui/launcher/LauncherDragManager.qml b/containments/homescreen/package/contents/ui/launcher/LauncherDragManager.qml similarity index 100% rename from containments/homescreen2/package/contents/ui/launcher/LauncherDragManager.qml rename to containments/homescreen/package/contents/ui/launcher/LauncherDragManager.qml diff --git a/containments/homescreen2/package/contents/ui/launcher/LauncherGrid.qml b/containments/homescreen/package/contents/ui/launcher/LauncherGrid.qml similarity index 100% rename from containments/homescreen2/package/contents/ui/launcher/LauncherGrid.qml rename to containments/homescreen/package/contents/ui/launcher/LauncherGrid.qml diff --git a/containments/homescreen/package/contents/ui/main.qml b/containments/homescreen/package/contents/ui/main.qml index b78e3869..135a4b81 100644 --- a/containments/homescreen/package/contents/ui/main.qml +++ b/containments/homescreen/package/contents/ui/main.qml @@ -1,81 +1,45 @@ /* - * Copyright 2015 Marco Martin + * Copyright 2019 Marco Martin * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA. + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import QtQuick 2.4 +import QtQuick 2.12 import QtQuick.Layouts 1.1 +import QtGraphicalEffects 1.0 import org.kde.plasma.plasmoid 2.0 import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.plasma.components 2.0 as PlasmaComponents -import org.kde.kquickcontrolsaddons 2.0 +import org.kde.plasma.components 3.0 as PlasmaComponents +import org.kde.draganddrop 2.0 as DragDrop -import "LayoutManager.js" as LayoutManager +import "launcher" as Launcher + +import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager + +import org.kde.phone.homescreen 1.0 Item { id: root - width: 480 - height: 640 + width: 640 + height: 480 -//BEGIN properties property Item toolBox - property alias appletsSpace: applicationsView.headerItem - readonly property int iconSize: units.iconSizes.large - property int buttonHeight: dragDelegate.height - property bool reorderingApps: false - property var layoutManager: LayoutManager -//END properties //BEGIN functions - function addApplet(applet, x, y) { - var container = appletContainerComponent.createObject(appletsSpace.layout) - container.visible = true - print("Applet added: " + applet) - - var appletWidth = applet.width; - var appletHeight = applet.height; - applet.parent = container; - container.applet = applet; - applet.anchors.fill = container; - applet.visible = true; - container.visible = true; - - // If the provided position is valid, use it. - if (x >= 0 && y >= 0) { - var index = LayoutManager.insertAtCoordinates(container, x , y); - - // Fall through to determining an appropriate insert position. - } else { - var before = null; - //container.animationsEnabled = false; - - if (before) { - LayoutManager.insertBefore(before, container); - - // Fall through to adding at the end. - } else { - container.parent = appletsSpace.layout; - } - - //event compress the enable of animations - //startupTimer.restart(); - } - } - //Autoscroll related functions function scrollUp() { autoScrollTimer.scrollDown = false; @@ -97,122 +61,50 @@ Item { scrollDownIndicator.opacity = 0; } + function recalculateMaxFavoriteCount() { + if (!componentComplete) { + return; + } - + plasmoid.nativeInterface.applicationListModel.maxFavoriteCount = Math.floor(Math.min(width, height) / launcher.cellWidth); + } //END functions -//BEGIN slots + + property bool componentComplete: false + onWidthChanged: recalculateMaxFavoriteCount() + onHeightChanged:recalculateMaxFavoriteCount() Component.onCompleted: { - LayoutManager.plasmoid = plasmoid; - LayoutManager.root = root; - LayoutManager.layout = appletsSpace.layout; - LayoutManager.restore(); - applicationsView.contentY = -applicationsView.headerItem.height*2; - - plasmoid.nativeInterface.applicationListModel.appOrder = plasmoid.configuration.AppOrder; - plasmoid.nativeInterface.applicationListModel.loadApplications(); + componentComplete = true; + recalculateMaxFavoriteCount() } - Timer { - interval: 200 - running: true - onTriggered: { - applicationsView.contentY = -applicationsView.headerItem.height; - } - } - - Containment.onAppletAdded: { - addApplet(applet, x, y); - LayoutManager.save(); - } - - Connections { - target: plasmoid.nativeInterface.applicationListModel - onAppOrderChanged: { - plasmoid.configuration.AppOrder = plasmoid.nativeInterface.applicationListModel.appOrder; - } - } -//END slots - Timer { id: autoScrollTimer property bool scrollDown: true repeat: true interval: 1500 onTriggered: { - //reordering launcher icons - if (root.reorderingApps) { - scrollAnim.to = scrollDown ? - //Scroll down - Math.min(applicationsView.contentItem.height - applicationsView.headerItem.height - root.height, applicationsView.contentY + root.height/2) : - //Scroll up - Math.max(0, applicationsView.contentY - root.height/2); + scrollAnim.to = scrollDown ? + //Scroll down + Math.min(mainFlickable.contentItem.height - root.height, mainFlickable.contentY + root.height/2) : + //Scroll up + Math.max(0, mainFlickable.contentY - root.height/2); - //reordering applets - } else { - scrollAnim.to = scrollDown ? - //Scroll down - Math.min(-root.height, applicationsView.contentY + root.height/2) : - //Scroll up - Math.max(-applicationsView.headerItem.height + root.height, applicationsView.contentY - root.height/2); - } scrollAnim.running = true; } } - Component { - id: appletContainerComponent - MouseArea { - id: appletContainer - //not used yet - property bool animationsEnabled: true - property Item applet - z: applet && applet.compactRepresentationItem && applet.expanded ? 99 : 0 - opacity: 1 - Math.abs(x/(width/2)) - Layout.fillWidth: true - Layout.fillHeight: applet && applet.Layout.fillHeight - - Connections { - target: plasmoid - - onAppletRemoved: { - print("Applet removed Applet-" + applet.id) - if (applet.id == appletContainer.applet.id) { - appletContainer.destroy(); - } - } - } - - onAppletChanged: { - if (applet.backgroundHints == PlasmaCore.Types.StandardBackground) { - applet.anchors.margins = background.margins.top; - } - } - - property int oldX: x - property int oldY: y - PlasmaCore.FrameSvgItem { - id: background - z: -1 - anchors.fill: parent - imagePath: "widgets/background" - visible: applet.backgroundHints == PlasmaCore.Types.StandardBackground - } - - width: parent.width - height: Math.max(applet.switchHeight + 1 + background.margins.top + background.margins.bottom, Math.max(applet.Layout.minimumHeight, (root.height-applicationsView.headerItem.margin) / 2)) - - PlasmaComponents.BusyIndicator { - z: 1000 - visible: applet && applet.busy - running: visible - anchors.centerIn: parent - width: Math.min(parent.width, parent.height) - height: width - } + Connections { + target: plasmoid + onEditModeChanged: { + appletsLayout.editMode = plasmoid.editMode } } + FeedbackWindow { + id: feedbackWindow + } SequentialAnimation { id: clickFedbackAnimation property Item target @@ -234,12 +126,205 @@ Item { easing.type: Easing.InOutQuad } } - FeedbackWindow { - id: feedbackWindow + + Launcher.LauncherDragManager { + id: launcherDragManager + anchors.fill: parent + z: 2 + appletsLayout: appletsLayout + launcherGrid: launcher + favoriteStrip: favoriteStrip } + + Flickable { + id: mainFlickable + width: parent.width + anchors { + fill: parent + topMargin: plasmoid.availableScreenRect.y + krunner.inputHeight + bottomMargin: plasmoid.screenGeometry.height - plasmoid.availableScreenRect.height - plasmoid.availableScreenRect.y + } + + bottomMargin: favoriteStrip.height + contentWidth: width + contentHeight: flickableContents.height + interactive: !plasmoid.editMode && !launcherDragManager.active + + PlasmaComponents.ScrollBar.vertical: PlasmaComponents.ScrollBar { + id: scrollabr + opacity: mainFlickable.moving + interactive: false + Behavior on opacity { + OpacityAnimator { + duration: units.longDuration * 2 + easing.type: Easing.InOutQuad + } + } + } + NumberAnimation { + id: scrollAnim + target: mainFlickable + properties: "contentY" + duration: units.longDuration + easing.type: Easing.InOutQuad + } + + Column { + id: flickableContents + width: mainFlickable.width + spacing: Math.max(0, favoriteStrip.frame.height - mainFlickable.contentY) + + DragDrop.DropArea { + anchors { + left: parent.left + right: parent.right + } + height: mainFlickable.height - favoriteStrip.frame.height //TODO: multiple widgets pages + + onDragEnter: { + event.accept(event.proposedAction); + } + onDragMove: { + appletsLayout.showPlaceHolderAt( + Qt.rect(event.x - appletsLayout.defaultItemWidth / 2, + event.y - appletsLayout.defaultItemHeight / 2, + appletsLayout.defaultItemWidth, + appletsLayout.defaultItemHeight) + ); + } + + onDragLeave: { + appletsLayout.hidePlaceHolder(); + } + + preventStealing: true + + onDrop: { + plasmoid.processMimeData(event.mimeData, + event.x - appletsLayout.placeHolder.width / 2, event.y - appletsLayout.placeHolder.height / 2); + event.accept(event.proposedAction); + appletsLayout.hidePlaceHolder(); + } + + PlasmaCore.Svg { + id: arrowsSvg + imagePath: "widgets/arrows" + colorGroup: PlasmaCore.Theme.ComplementaryColorGroup + } + PlasmaCore.IconItem { + z: 9 + anchors { + horizontalCenter: parent.horizontalCenter + bottom: parent.bottom + } + source: "arrow-up" + width: units.iconSizes.medium + height: width + colorGroup: PlasmaCore.Theme.ComplementaryColorGroup + + MouseArea { + anchors { + fill: parent + margins: -units.smallSpacing + } + onClicked: mainFlickable.flick(0, -mainFlickable.height) + } + } + + ContainmentLayoutManager.AppletsLayout { + id: appletsLayout + + anchors.fill: parent + + cellWidth: Math.floor(width / launcher.columns) + cellHeight: launcher.cellHeight + + configKey: width > height ? "ItemGeometriesHorizontal" : "ItemGeometriesVertical" + containment: plasmoid + editModeCondition: plasmoid.immutable + ? ContainmentLayoutManager.AppletsLayout.Manual + : ContainmentLayoutManager.AppletsLayout.AfterPressAndHold + + // Sets the containment in edit mode when we go in edit mode as well + onEditModeChanged: plasmoid.editMode = editMode + + minimumItemWidth: units.gridUnit * 3 + minimumItemHeight: minimumItemWidth + + defaultItemWidth: units.gridUnit * 6 + defaultItemHeight: defaultItemWidth + + //cellWidth: units.iconSizes.small + //cellHeight: cellWidth + + acceptsAppletCallback: function(applet, x, y) { + print("Applet: "+applet+" "+x+" "+y) + return true; + } + + appletContainerComponent: ContainmentLayoutManager.BasicAppletContainer { + id: appletContainer + configOverlayComponent: ConfigOverlay {} + + onEditModeChanged: { + launcherDragManager.active = dragActive || editMode; + } + onDragActiveChanged: { + launcherDragManager.active = dragActive || editMode; + } + } + + placeHolder: ContainmentLayoutManager.PlaceHolder {} + } + } + + Launcher.LauncherGrid { + id: launcher + anchors { + left: parent.left + right: parent.right + } + + favoriteStrip: favoriteStrip + appletsLayout: appletsLayout + } + } + } + + ScrollIndicator { + id: scrollUpIndicator + anchors { + top: parent.top + topMargin: units.gridUnit * 2 + } + elementId: "up-arrow" + } + ScrollIndicator { + id: scrollDownIndicator + anchors { + bottom: favoriteStrip.top + bottomMargin: units.gridUnit + } + elementId: "down-arrow" + } + + Launcher.FavoriteStrip { + id: favoriteStrip + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + bottomMargin: plasmoid.screenGeometry.height - plasmoid.availableScreenRect.height - plasmoid.availableScreenRect.y + } + appletsLayout: appletsLayout + launcherGrid: launcher + //y: Math.max(krunner.inputHeight, root.height - height - mainFlickable.contentY) + } + KRunner { id: krunner z: 998 + height: plasmoid.availableScreenRect.height anchors { top: parent.top left: parent.left @@ -247,275 +332,5 @@ Item { topMargin: plasmoid.availableScreenRect.y } } - - - EditOverlay { - id: editOverlay - z: 999 - } - MouseEventListener { - id: mainListener - anchors.fill: parent - - //Events handling: those events are about clicking and reordering of app icons - //applet related events are in AppeltsArea.qml - onPressAndHold: { - var pos = mapToItem(applicationsView.headerItem.favoritesStrip, mouse.x, mouse.y); - //in favorites area? - var item; - if (applicationsView.headerItem.favoritesStrip.contains(pos)) { - item = applicationsView.headerItem.favoritesStrip.itemAt(pos.x, pos.y); - } else { - pos = mapToItem(applicationsView.contentItem, mouse.x, mouse.y); - item = applicationsView.itemAt(pos.x, pos.y) - } - if (!item) { - return; - } - - applicationsView.dragData = new Object; - applicationsView.dragData.ApplicationNameRole = item.modelData.ApplicationNameRole; - applicationsView.dragData.ApplicationIconRole = item.modelData.ApplicationIconRole; - applicationsView.dragData.ApplicationStorageIdRole = item.modelData.ApplicationStorageIdRole; - applicationsView.dragData.ApplicationEntryPathRole = item.modelData.ApplicationEntryPathRole; - applicationsView.dragData.ApplicationOriginalRowRole = item.modelData.ApplicationOriginalRowRole; - - dragDelegate.modelData = applicationsView.dragData; - applicationsView.interactive = false; - root.reorderingApps = true; - dragDelegate.x = Math.floor(mouse.x / root.buttonHeight) * root.buttonHeight - dragDelegate.y = Math.floor(mouse.y / root.buttonHeight) * root.buttonHeight - dragDelegate.xTarget = mouse.x - dragDelegate.width/2; - dragDelegate.yTarget = mouse.y - dragDelegate.width/2; - dragDelegate.opacity = 1; - } - onPositionChanged: { - if (!applicationsView.dragData) { - return; - } - dragDelegate.x = mouse.x - dragDelegate.width/2; - dragDelegate.y = mouse.y - dragDelegate.height/2; - - var pos = mapToItem(applicationsView.contentItem, mouse.x, mouse.y); - - //in favorites area? - if (applicationsView.headerItem.favoritesStrip.contains(mapToItem(applicationsView.headerItem.favoritesStrip, mouse.x, mouse.y))) { - pos.y = 1; - } - - var newRow = (Math.round(applicationsView.width / applicationsView.cellWidth) * Math.floor(pos.y / applicationsView.cellHeight) + Math.floor(pos.x / applicationsView.cellWidth)); - - if (applicationsView.dragData.ApplicationOriginalRowRole != newRow) { - plasmoid.nativeInterface.applicationListModel.moveItem(applicationsView.dragData.ApplicationOriginalRowRole, newRow); - applicationsView.dragData.ApplicationOriginalRowRole = newRow; - } - - var pos = mapToItem(applicationsView.headerItem.favoritesStrip, mouse.x, mouse.y); - //FAVORITES - if (applicationsView.headerItem.favoritesStrip.contains(pos)) { - root.stopScroll(); - //SCROLL UP - } else if (applicationsView.contentY > 0 && mouse.y < root.buttonHeight + root.height / 4) { - root.scrollUp(); - //SCROLL DOWN - } else if (!applicationsView.atYEnd && mouse.y > 3 * (root.height / 4)) { - root.scrollDown(); - //DON't SCROLL - } else { - root.stopScroll(); - } - - } - onReleased: { - if (krunner.showingResults) { - return; - } - applicationsView.interactive = true; - dragDelegate.xTarget = Math.floor(mouse.x / root.buttonHeight) * root.buttonHeight; - dragDelegate.yTarget = Math.floor(mouse.y / root.buttonHeight) * root.buttonHeight; - dragDelegate.opacity = 0; - if (dragDelegate.modelData) { - dragDelegate.modelData.ApplicationIconRole = ""; - dragDelegate.modelDataChanged(); - } - applicationsView.dragData = null; - root.reorderingApps = false; - applicationsView.forceLayout(); - root.stopScroll(); - } - onClicked: { - if (krunner.showingResults) { - return; - } - var pos = mapToItem(applicationsView.headerItem.favoritesStrip, mouse.x, mouse.y); - - //in favorites area? - var item; - if (applicationsView.headerItem.favoritesStrip.contains(pos)) { - item = applicationsView.headerItem.favoritesStrip.itemAt(pos.x, pos.y); - } else { - pos = mapToItem(applicationsView.contentItem, mouse.x, mouse.y); - item = applicationsView.itemAt(pos.x, pos.y) - } - if (!item) { - return; - } - - clickFedbackAnimation.target = item; - clickFedbackAnimation.running = true; - feedbackWindow.title = item.modelData.ApplicationNameRole; - feedbackWindow.state = "open"; - plasmoid.nativeInterface.applicationListModel.runApplication(item.modelData.ApplicationStorageIdRole); - } - - PlasmaCore.ColorScope { - anchors.fill: parent - //TODO: decide what color we want applets - colorGroup: PlasmaCore.Theme.ComplementaryColorGroup - - Rectangle { - color: PlasmaCore.ColorScope.backgroundColor - opacity: 0.9 * (Math.min(applicationsView.contentY + root.height, root.height) / root.height) - anchors.fill: parent - } - - PlasmaCore.Svg { - id: arrowsSvg - imagePath: "widgets/arrows" - colorGroup: PlasmaCore.Theme.ComplementaryColorGroup - } - PlasmaCore.SvgItem { - id: scrollUpIndicator - anchors { - horizontalCenter: parent.horizontalCenter - top: parent.top - topMargin: 300 - } - z: 2 - opacity: 0 - svg: arrowsSvg - elementId: "up-arrow" - width: units.iconSizes.large - height: width - Behavior on opacity { - OpacityAnimator { - duration: 1000 - easing.type: Easing.InOutQuad - } - } - } - PlasmaCore.SvgItem { - id: scrollDownIndicator - anchors { - horizontalCenter: parent.horizontalCenter - bottom: parent.bottom - bottomMargin: units.gridUnit * 2 - } - z: 2 - opacity: 0 - svg: arrowsSvg - elementId: "down-arrow" - width: units.iconSizes.large - height: width - Behavior on opacity { - OpacityAnimator { - duration: 1000 - easing.type: Easing.InOutQuad - } - } - } - - //This HomeLauncher is the placeholder for the "drag" - //delegate (that is not actual drag and drop - HomeLauncher { - id: dragDelegate - z: 999 - property int xTarget - property int yTarget - iconSize: root.iconSize - - Behavior on opacity { - ParallelAnimation { - OpacityAnimator { - duration: units.longDuration - easing.type: Easing.InOutQuad - } - PropertyAnimation { - properties: "x" - to: dragDelegate.xTarget - target: dragDelegate - duration: units.longDuration - easing.type: Easing.InOutQuad - } - PropertyAnimation { - properties: "y" - to: dragDelegate.yTarget - target: dragDelegate - duration: units.longDuration - easing.type: Easing.InOutQuad - } - } - } - } - GridView { - id: applicationsView - anchors { - fill: parent - topMargin: plasmoid.availableScreenRect.y - bottomMargin: root.height - plasmoid.availableScreenRect.y - plasmoid.availableScreenRect.height - } - - property var dragData - - cellWidth: root.width / 4 - cellHeight: root.buttonHeight - model: plasmoid.nativeInterface.applicationListModel - - snapMode: GridView.SnapToRow - - NumberAnimation { - id: scrollAnim - target: applicationsView - properties: "contentY" - duration: units.longDuration - easing.type: Easing.InOutQuad - } - move: Transition { - NumberAnimation { - duration: units.longDuration - easing.type: Easing.InOutQuad - properties: "x,y" - } - } - moveDisplaced: Transition { - NumberAnimation { - duration: units.longDuration - easing.type: Easing.InOutQuad - properties: "x,y" - } - } - - //clip: true - delegate: HomeLauncher { - visible: index > 3 - iconSize: root.iconSize - } - header: AppletsArea {} - footer: Item { - width: units. gridUnit * 4 - height: width - } - } - - PlasmaComponents.ScrollBar { - anchors { - right: parent.right - top: parent.top - bottom: parent.bottom - } - interactive: false - flickableItem: applicationsView - } - } - } } + diff --git a/containments/homescreen2/CMakeLists.txt b/containments/homescreen2/CMakeLists.txt deleted file mode 100644 index 2e8dce79..00000000 --- a/containments/homescreen2/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -set(homescreen_SRCS - homescreen.cpp - applicationlistmodel.cpp -) - -add_library(plasma_containment_phone_homescreen2 MODULE ${homescreen_SRCS}) - -kcoreaddons_desktop_to_json(plasma_containment_phone_homescreen2 package/metadata.desktop) - -target_link_libraries(plasma_containment_phone_homescreen2 - Qt5::Gui - KF5::Plasma - Qt5::Qml - Qt5::Quick - KF5::I18n - KF5::Service - KF5::KIOWidgets - ) - - -install(TARGETS plasma_containment_phone_homescreen2 DESTINATION ${KDE_INSTALL_PLUGINDIR}/plasma/applets) - -plasma_install_package(package org.kde.phone.homescreen2) - diff --git a/containments/homescreen2/Messages.sh b/containments/homescreen2/Messages.sh deleted file mode 100755 index c0782d94..00000000 --- a/containments/homescreen2/Messages.sh +++ /dev/null @@ -1,4 +0,0 @@ -#! /usr/bin/env bash -$EXTRACTRC `find . -name \*.rc -o -name \*.ui -o -name \*.kcfg` >> rc.cpp -$XGETTEXT `find . -name \*.js -o -name \*.qml -o -name \*.cpp` -o $podir/plasma_applet_org.kde.phone.homescreen.pot -rm -f rc.cpp diff --git a/containments/homescreen2/applicationlistmodel.cpp b/containments/homescreen2/applicationlistmodel.cpp deleted file mode 100644 index 513681f4..00000000 --- a/containments/homescreen2/applicationlistmodel.cpp +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright (C) 2014 Antonis Tsiapaliokas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, - * or (at your option) any later version, as published by the Free - * Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -// Self -#include "applicationlistmodel.h" - -// Qt -#include -#include -#include - -// KDE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -ApplicationListModel::ApplicationListModel(HomeScreen *parent) - : QAbstractListModel(parent), - m_homeScreen(parent) -{ - //can't use the new syntax as this signal is overloaded - connect(KSycoca::self(), SIGNAL(databaseChanged(const QStringList &)), - this, SLOT(sycocaDbChanged(const QStringList &))); - m_favorites = m_homeScreen->config().readEntry("Favorites", QStringList()); - m_desktopItems = m_homeScreen->config().readEntry("DesktopItems", QStringList()).toSet(); - m_appOrder = m_homeScreen->config().readEntry("AppOrder", QStringList()); - m_maxFavoriteCount = m_homeScreen->config().readEntry("MaxFavoriteCount", 5); - - int i = 0; - for (auto app : m_appOrder) { - m_appPositions[app] = i; - ++i; - } - //here or delayed? - loadApplications(); -} - -ApplicationListModel::~ApplicationListModel() -= default; - -QHash ApplicationListModel::roleNames() const -{ - QHash roleNames; - roleNames[ApplicationNameRole] = "ApplicationNameRole"; - roleNames[ApplicationIconRole] = "ApplicationIconRole"; - roleNames[ApplicationStorageIdRole] = "ApplicationStorageIdRole"; - roleNames[ApplicationEntryPathRole] = "ApplicationEntryPathRole"; - roleNames[ApplicationOriginalRowRole] = "ApplicationOriginalRowRole"; - roleNames[ApplicationStartupNotifyRole] = "ApplicationStartupNotifyRole"; - roleNames[ApplicationLocationRole] = "ApplicationLocationRole"; - - return roleNames; -} - -void ApplicationListModel::sycocaDbChanged(const QStringList &changes) -{ - if (!changes.contains("apps") && !changes.contains("xdgdata-apps")) { - return; - } - - m_applicationList.clear(); - - loadApplications(); -} - -bool appNameLessThan(const ApplicationData &a1, const ApplicationData &a2) -{ - return a1.name.toLower() < a2.name.toLower(); -} - -void ApplicationListModel::loadApplications() -{ - auto cfg = KSharedConfig::openConfig("applications-blacklistrc"); - auto blgroup = KConfigGroup(cfg, QStringLiteral("Applications")); - - // This is only temporary to get a clue what those apps' desktop files are called - // I'll remove it once I've done a blacklist - QStringList bl; - - QStringList blacklist = blgroup.readEntry("blacklist", QStringList()); - - - beginResetModel(); - - m_applicationList.clear(); - - KServiceGroup::Ptr group = KServiceGroup::root(); - if (!group || !group->isValid()) return; - KServiceGroup::List subGroupList = group->entries(true); - - QMap orderedList; - QList unorderedList; - - // Iterate over all entries in the group - while (!subGroupList.isEmpty()) { - KSycocaEntry::Ptr groupEntry = subGroupList.first(); - subGroupList.pop_front(); - - if (groupEntry->isType(KST_KServiceGroup)) { - KServiceGroup::Ptr serviceGroup(static_cast(groupEntry.data())); - - if (!serviceGroup->noDisplay()) { - KServiceGroup::List entryGroupList = serviceGroup->entries(true); - - for(KServiceGroup::List::ConstIterator it = entryGroupList.constBegin(); it != entryGroupList.constEnd(); it++) { - KSycocaEntry::Ptr entry = (*it); - - if (entry->isType(KST_KServiceGroup)) { - KServiceGroup::Ptr serviceGroup(static_cast(entry.data())); - subGroupList << serviceGroup; - - } else if (entry->property("Exec").isValid()) { - KService::Ptr service(static_cast(entry.data())); - - if (service->isApplication() && - !blacklist.contains(service->desktopEntryName()) && - service->showOnCurrentPlatform() && - !service->property("Terminal", QVariant::Bool).toBool()) { - - bl << service->desktopEntryName(); - - ApplicationData data; - data.name = service->name(); - data.icon = service->icon(); - data.storageId = service->storageId(); - data.entryPath = service->exec(); - data.startupNotify = service->property("StartupNotify").toBool(); - - if (m_favorites.contains(data.storageId)) { - data.location = Favorites; - } else if (m_desktopItems.contains(data.storageId)) { - data.location = Desktop; - } - - auto it = m_appPositions.constFind(service->storageId()); - if (it != m_appPositions.constEnd()) { - orderedList[*it] = data; - } else { - unorderedList << data; - } - } - } - } - } - } - } - - blgroup.writeEntry("allapps", bl); - blgroup.writeEntry("blacklist", blacklist); - cfg->sync(); - - std::sort(unorderedList.begin(), unorderedList.end(), appNameLessThan); - m_applicationList << orderedList.values(); - m_applicationList << unorderedList; - - endResetModel(); - emit countChanged(); -} - -QVariant ApplicationListModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) { - return QVariant(); - } - - switch (role) { - case Qt::DisplayRole: - case ApplicationNameRole: - return m_applicationList.at(index.row()).name; - case ApplicationIconRole: - return m_applicationList.at(index.row()).icon; - case ApplicationStorageIdRole: - return m_applicationList.at(index.row()).storageId; - case ApplicationEntryPathRole: - return m_applicationList.at(index.row()).entryPath; - case ApplicationOriginalRowRole: - return index.row(); - case ApplicationStartupNotifyRole: - return m_applicationList.at(index.row()).startupNotify; - case ApplicationLocationRole: - return m_applicationList.at(index.row()).location; - - default: - return QVariant(); - } -} - -Qt::ItemFlags ApplicationListModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - return nullptr; - return Qt::ItemIsDragEnabled|QAbstractItemModel::flags(index); -} - -int ApplicationListModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) { - return 0; - } - - return m_applicationList.count(); -} - -void ApplicationListModel::moveRow(const QModelIndex& /* sourceParent */, int sourceRow, const QModelIndex& /* destinationParent */, int destinationChild) -{ - moveItem(sourceRow, destinationChild); -} - -void ApplicationListModel::setLocation(int row, LauncherLocation location) -{ - if (row < 0 || row >= m_applicationList.length()) { - return; - } - - ApplicationData &data = m_applicationList[row]; - if (data.location == location) { - return; - } - - if (location == Favorites) {qWarning()<<"favoriting"<= m_maxFavoriteCount || m_favorites.count() >= m_maxFavoriteCount) { - return; - } - - m_favorites.insert(row, data.storageId); - - m_homeScreen->config().writeEntry("Favorites", m_favorites); - emit favoriteCountChanged(); - - // Out of favorites - } else if (data.location == Favorites) { - m_favorites.removeAll(data.storageId); - m_homeScreen->config().writeEntry("Favorites", m_favorites); - emit favoriteCountChanged(); - } - - // In Desktop - if (location == Desktop) { - m_desktopItems.insert(data.storageId); - m_homeScreen->config().writeEntry("DesktopItems", m_desktopItems.toList()); - - // Out of Desktop - } else if (data.location == Desktop) { - m_desktopItems.remove(data.storageId); - m_homeScreen->config().writeEntry("DesktopItems", m_desktopItems.toList()); - } - - data.location = location; - emit m_homeScreen->configNeedsSaving(); - emit dataChanged(index(row, 0), index(row, 0)); -} - -void ApplicationListModel::moveItem(int row, int destination) -{ - if (row < 0 || destination < 0 || row >= m_applicationList.length() || - destination >= m_applicationList.length() || row == destination) { - return; - } - if (destination > row) { - ++destination; - } - - beginMoveRows(QModelIndex(), row, row, QModelIndex(), destination); - if (destination > row) { - ApplicationData data = m_applicationList.at(row); - m_applicationList.insert(destination, data); - m_applicationList.takeAt(row); - - } else { - ApplicationData data = m_applicationList.takeAt(row); - m_applicationList.insert(destination, data); - } - - - m_appOrder.clear(); - m_appPositions.clear(); - int i = 0; - for (auto app : m_applicationList) { - m_appOrder << app.storageId; - m_appPositions[app.storageId] = i; - ++i; - } - - m_homeScreen->config().writeEntry("AppOrder", m_appOrder); - - endMoveRows(); -} - -void ApplicationListModel::runApplication(const QString &storageId) -{ - if (storageId.isEmpty()) { - return; - } - - KService::Ptr service = KService::serviceByStorageId(storageId); - - KRun::runService(*service, QList(), nullptr); -} - -int ApplicationListModel::maxFavoriteCount() const -{ - return m_maxFavoriteCount; -} - -void ApplicationListModel::setMaxFavoriteCount(int count) -{ - if (m_maxFavoriteCount == count) { - return; - } - - if (m_maxFavoriteCount > count) { - while (m_favorites.size() > count && m_favorites.count() > 0) { - m_favorites.pop_back(); - } - emit favoriteCountChanged(); - - int i = 0; - for (auto &app : m_applicationList) { - if (i >= count && app.location == Favorites) { - app.location = Grid; - emit dataChanged(index(i, 0), index(i, 0)); - } - ++i; - } - } - - m_maxFavoriteCount = count; - m_homeScreen->config().writeEntry("MaxFavoriteCount", m_maxFavoriteCount); - - emit maxFavoriteCountChanged(); -} - -#include "moc_applicationlistmodel.cpp" - diff --git a/containments/homescreen2/applicationlistmodel.h b/containments/homescreen2/applicationlistmodel.h deleted file mode 100644 index 7e3f1ad4..00000000 --- a/containments/homescreen2/applicationlistmodel.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2014 Antonis Tsiapaliokas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, - * or (at your option) any later version, as published by the Free - * Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef APPLICATIONLISTMODEL_H -#define APPLICATIONLISTMODEL_H - -// Qt -#include -#include -#include - -#include "homescreen.h" - -class QString; - -class ApplicationListModel; - -struct ApplicationData { - QString name; - QString icon; - QString storageId; - QString entryPath; - int location = 0; //FIXME - bool startupNotify = true; -}; - -class ApplicationListModel : public QAbstractListModel { - Q_OBJECT - - Q_PROPERTY(int count READ count NOTIFY countChanged) - Q_PROPERTY(int favoriteCount READ favoriteCount NOTIFY favoriteCountChanged) - Q_PROPERTY(int maxFavoriteCount READ maxFavoriteCount WRITE setMaxFavoriteCount NOTIFY maxFavoriteCountChanged) - -public: - enum LauncherLocation { - Grid = 0, - Favorites, - Desktop - }; - Q_ENUM(LauncherLocation) - - enum Roles { - ApplicationNameRole = Qt::UserRole + 1, - ApplicationIconRole, - ApplicationStorageIdRole, - ApplicationEntryPathRole, - ApplicationOriginalRowRole, - ApplicationStartupNotifyRole, - ApplicationLocationRole - }; - - ApplicationListModel(HomeScreen *parent = nullptr); - ~ApplicationListModel() override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; - - void moveRow(const QModelIndex &sourceParent, int sourceRow, const QModelIndex &destinationParent, int destinationChild); - - int count() const { return m_applicationList.count(); } - int favoriteCount() const { return m_favorites.count();} - - int maxFavoriteCount() const; - void setMaxFavoriteCount(int count); - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; - - Qt::ItemFlags flags(const QModelIndex &index) const override; - - QHash roleNames() const Q_DECL_OVERRIDE; - - Q_INVOKABLE void setLocation(int row, LauncherLocation location); - - Q_INVOKABLE void moveItem(int row, int order); - - Q_INVOKABLE void runApplication(const QString &storageId); - - Q_INVOKABLE void loadApplications(); - -public Q_SLOTS: - void sycocaDbChanged(const QStringList &change); - -Q_SIGNALS: - void countChanged(); - void favoriteCountChanged(); - void maxFavoriteCountChanged(); - -private: - QList m_applicationList; - - HomeScreen *m_homeScreen = nullptr; - int m_maxFavoriteCount = 0; - QStringList m_appOrder; - QStringList m_favorites; - QSet m_desktopItems; - QHash m_appPositions; -}; - -#endif // APPLICATIONLISTMODEL_H diff --git a/containments/homescreen2/homescreen.cpp b/containments/homescreen2/homescreen.cpp deleted file mode 100644 index 8932d62f..00000000 --- a/containments/homescreen2/homescreen.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 Marco Martin * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * - ***************************************************************************/ - -#include "homescreen.h" -#include "applicationlistmodel.h" - -#include -#include -#include - -HomeScreen::HomeScreen(QObject *parent, const QVariantList &args) - : Plasma::Containment(parent, args) -{ - qmlRegisterUncreatableType("org.kde.phone.homescreen", 1, 0, "ApplicationListModel", QStringLiteral("Cannot create item of type ApplicationListModel")); - - setHasConfigurationInterface(true); -} - -HomeScreen::~HomeScreen() -= default; - -ApplicationListModel *HomeScreen::applicationListModel() -{ - if (!m_applicationListModel) { - m_applicationListModel = new ApplicationListModel(this); - } - return m_applicationListModel; -} - -void HomeScreen::stackBefore(QQuickItem *item1, QQuickItem *item2) -{ - if (!item1 || !item2 || item1->parentItem() != item2->parentItem()) { - return; - } - - item1->stackBefore(item2); -} - -void HomeScreen::stackAfter(QQuickItem *item1, QQuickItem *item2) -{ - if (!item1 || !item2 || item1->parentItem() != item2->parentItem()) { - return; - } - - item1->stackAfter(item2); -} - -K_EXPORT_PLASMA_APPLET_WITH_JSON(homescreen, HomeScreen, "metadata.json") - -#include "homescreen.moc" diff --git a/containments/homescreen2/homescreen.h b/containments/homescreen2/homescreen.h deleted file mode 100644 index 1387b81e..00000000 --- a/containments/homescreen2/homescreen.h +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 Marco Martin * - * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * - ***************************************************************************/ - -#ifndef HOMESCREEN_H -#define HOMESCREEN_H - - -#include - -class QQuickItem; -class ApplicationListModel; - -class HomeScreen : public Plasma::Containment -{ - Q_OBJECT - Q_PROPERTY(ApplicationListModel *applicationListModel READ applicationListModel CONSTANT) - -public: - HomeScreen( QObject *parent, const QVariantList &args ); - ~HomeScreen() override; - - ApplicationListModel *applicationListModel(); - - Q_INVOKABLE void stackBefore(QQuickItem *item1, QQuickItem *item2); - Q_INVOKABLE void stackAfter(QQuickItem *item1, QQuickItem *item2); - -private: - ApplicationListModel *m_applicationListModel = nullptr; - -}; - -#endif diff --git a/containments/homescreen2/package/contents/config/main.xml b/containments/homescreen2/package/contents/config/main.xml deleted file mode 100644 index d191ada3..00000000 --- a/containments/homescreen2/package/contents/config/main.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - org.kde.phone.dialer.desktop - - - - diff --git a/containments/homescreen2/package/contents/ui/FeedbackWindow.qml b/containments/homescreen2/package/contents/ui/FeedbackWindow.qml deleted file mode 100644 index 15b92488..00000000 --- a/containments/homescreen2/package/contents/ui/FeedbackWindow.qml +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2015 Marco Martin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details - * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -import QtQuick 2.0 -import QtQuick.Layouts 1.1 -import QtQuick.Window 2.2 -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.plasma.components 2.0 as PlasmaComponents -import org.kde.plasma.extras 2.0 as PlasmaExtras - -Window { - id: window - - property alias state: background.state - property alias icon: icon.source - width: Screen.width - height: Screen.height - color: "transparent" - onVisibleChanged: { - if (!visible) { - background.state = "closed"; - } - } - onActiveChanged: { - if (!active) { - background.state = "closed"; - } - } - - Item { - id: background - anchors.fill: parent - //colorGroup: PlasmaCore.Theme.ComplementaryColorGroup - width: window.width - height: window.height - state: "closed" - Rectangle { - anchors.fill: parent - color: background.backgroundColor - - ColumnLayout { - anchors.centerIn: parent - PlasmaCore.IconItem { - id: icon - colorGroup: PlasmaCore.Theme.ComplementaryColorGroup - Layout.preferredWidth: units.iconSizes.enormous - Layout.preferredHeight: Layout.preferredWidth - Layout.alignment: Qt.AlignCenter - } - PlasmaExtras.Heading { - text: window.title - Layout.alignment: Qt.AlignCenter - } - /* PlasmaComponents.BusyIndicator { - Layout.alignment: Qt.AlignCenter - }*/ - } - } - - states: [ - State { - name: "closed" - PropertyChanges { - target: background - scale: 0 - } - PropertyChanges { - target: window - visible: false - } - }, - State { - name: "open" - PropertyChanges { - target: background - scale: 1 - } - PropertyChanges { - target: window - visible: true - } - } - ] - - transitions: [ - Transition { - from: "closed" - SequentialAnimation { - ScriptAction { - script: window.visible = true; - } - PropertyAnimation { - target: background - duration: units.longDuration - easing.type: Easing.InOutQuad - properties: "scale" - } - } - } - ] - } -} diff --git a/containments/homescreen2/package/contents/ui/KRunner.qml b/containments/homescreen2/package/contents/ui/KRunner.qml deleted file mode 100644 index 3632d877..00000000 --- a/containments/homescreen2/package/contents/ui/KRunner.qml +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2015 Vishesh Handa - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) version 3, or any - * later version accepted by the membership of KDE e.V. (or its - * successor approved by the membership of KDE e.V.), which shall - * act as a proxy defined in Section 6 of version 3 of the license. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - */ - -import QtQuick 2.0 -import QtQuick.Layouts 1.1 -import QtQuick.Window 2.1 - -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.plasma.components 2.0 as PlasmaComponents -import org.kde.plasma.extras 2.0 as PlasmaExtras - -import org.kde.milou 0.1 as Milou - -Rectangle { - id: krunner - height: childrenRect.height - color: listView.visible ? Qt.rgba(0, 0, 0, 0.8) : "transparent" - property alias showingResults: listView.visible - property int inputHeight: queryField.height + background.fixedMargins.top/2 + background.fixedMargins.bottom - - MouseArea { - enabled: listView.visible - anchors.fill: parent - preventStealing: true - onClicked: queryField.text = ""; - } - PlasmaCore.FrameSvgItem { - id: background - anchors { - left: parent.left - right: parent.right - top: parent.top - } - clip: true - imagePath: "widgets/background" - enabledBorders: PlasmaCore.FrameSvg.BottomBorder - height: Math.min(krunner.height, childrenRect.height + fixedMargins.top/2 + fixedMargins.bottom) - Behavior on height { - NumberAnimation { - duration: units.longDuration - easing.type: Easing.InOutQuad - } - } - transform: Translate { - y: root.locked || editOverlay.visible ? -background.height : 0 - Behavior on y { - NumberAnimation { - duration: units.longDuration - easing.type: Easing.InOutQuad - } - } - } - - ColumnLayout { - height: Qt.inputMethod.keyboardRectangle.height > 0 ? (Math.min(implicitHeight, background.height, Qt.inputMethod.keyboardRectangle.y - plasmoid.availableScreenRect.y)) : implicitHeight - anchors { - left: parent.left - right: parent.right - top: parent.top - topMargin: background.fixedMargins.top / 2 - leftMargin: background.fixedMargins.left / 2 - rightMargin: background.fixedMargins.right / 2 - } - PlasmaComponents.TextField { - id: queryField - clearButtonShown: true - Layout.fillWidth: true - Layout.alignment: Qt.AlignTop - - Keys.onEscapePressed: runnerWindow.visible = false - placeholderText: "Search..." - } - - PlasmaExtras.ScrollArea { - visible: listView.count > 0 - Layout.fillWidth: true - Layout.fillHeight: true - Layout.preferredHeight: listView.contentHeight - Layout.alignment: Qt.AlignTop - - Milou.ResultsListView { - id: listView - queryString: queryField.text - highlight: null - - onActivated: queryField.text = "" - onUpdateQueryString: { - queryField.text = text - queryField.cursorPosition = cursorPosition - } - } - } - - Keys.onReturnPressed: { - if (queryField.texr.length == 0) - runnerWindow.visible = false; - } - Keys.onEnterPressed: { - if (queryField.texr.length == 0) - runnerWindow.visible = false; - } - } - } -} - diff --git a/containments/homescreen2/package/contents/ui/main.qml b/containments/homescreen2/package/contents/ui/main.qml deleted file mode 100644 index 135a4b81..00000000 --- a/containments/homescreen2/package/contents/ui/main.qml +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2019 Marco Martin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details - * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -import QtQuick 2.12 -import QtQuick.Layouts 1.1 -import QtGraphicalEffects 1.0 - -import org.kde.plasma.plasmoid 2.0 -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.plasma.components 3.0 as PlasmaComponents -import org.kde.draganddrop 2.0 as DragDrop - -import "launcher" as Launcher - -import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager - -import org.kde.phone.homescreen 1.0 - -Item { - id: root - width: 640 - height: 480 - - property Item toolBox - -//BEGIN functions - //Autoscroll related functions - function scrollUp() { - autoScrollTimer.scrollDown = false; - autoScrollTimer.running = true; - scrollUpIndicator.opacity = 1; - scrollDownIndicator.opacity = 0; - } - - function scrollDown() { - autoScrollTimer.scrollDown = true; - autoScrollTimer.running = true; - scrollUpIndicator.opacity = 0; - scrollDownIndicator.opacity = 1; - } - - function stopScroll() { - autoScrollTimer.running = false; - scrollUpIndicator.opacity = 0; - scrollDownIndicator.opacity = 0; - } - - function recalculateMaxFavoriteCount() { - if (!componentComplete) { - return; - } - - plasmoid.nativeInterface.applicationListModel.maxFavoriteCount = Math.floor(Math.min(width, height) / launcher.cellWidth); - } -//END functions - - - property bool componentComplete: false - onWidthChanged: recalculateMaxFavoriteCount() - onHeightChanged:recalculateMaxFavoriteCount() - Component.onCompleted: { - componentComplete = true; - recalculateMaxFavoriteCount() - } - - Timer { - id: autoScrollTimer - property bool scrollDown: true - repeat: true - interval: 1500 - onTriggered: { - scrollAnim.to = scrollDown ? - //Scroll down - Math.min(mainFlickable.contentItem.height - root.height, mainFlickable.contentY + root.height/2) : - //Scroll up - Math.max(0, mainFlickable.contentY - root.height/2); - - scrollAnim.running = true; - } - } - - Connections { - target: plasmoid - onEditModeChanged: { - appletsLayout.editMode = plasmoid.editMode - } - } - - FeedbackWindow { - id: feedbackWindow - } - SequentialAnimation { - id: clickFedbackAnimation - property Item target - NumberAnimation { - target: clickFedbackAnimation.target - properties: "scale" - to: 2 - duration: units.longDuration - easing.type: Easing.InOutQuad - } - PauseAnimation { - duration: units.shortDuration - } - NumberAnimation { - target: clickFedbackAnimation.target - properties: "scale" - to: 1 - duration: units.longDuration - easing.type: Easing.InOutQuad - } - } - - Launcher.LauncherDragManager { - id: launcherDragManager - anchors.fill: parent - z: 2 - appletsLayout: appletsLayout - launcherGrid: launcher - favoriteStrip: favoriteStrip - } - - Flickable { - id: mainFlickable - width: parent.width - anchors { - fill: parent - topMargin: plasmoid.availableScreenRect.y + krunner.inputHeight - bottomMargin: plasmoid.screenGeometry.height - plasmoid.availableScreenRect.height - plasmoid.availableScreenRect.y - } - - bottomMargin: favoriteStrip.height - contentWidth: width - contentHeight: flickableContents.height - interactive: !plasmoid.editMode && !launcherDragManager.active - - PlasmaComponents.ScrollBar.vertical: PlasmaComponents.ScrollBar { - id: scrollabr - opacity: mainFlickable.moving - interactive: false - Behavior on opacity { - OpacityAnimator { - duration: units.longDuration * 2 - easing.type: Easing.InOutQuad - } - } - } - NumberAnimation { - id: scrollAnim - target: mainFlickable - properties: "contentY" - duration: units.longDuration - easing.type: Easing.InOutQuad - } - - Column { - id: flickableContents - width: mainFlickable.width - spacing: Math.max(0, favoriteStrip.frame.height - mainFlickable.contentY) - - DragDrop.DropArea { - anchors { - left: parent.left - right: parent.right - } - height: mainFlickable.height - favoriteStrip.frame.height //TODO: multiple widgets pages - - onDragEnter: { - event.accept(event.proposedAction); - } - onDragMove: { - appletsLayout.showPlaceHolderAt( - Qt.rect(event.x - appletsLayout.defaultItemWidth / 2, - event.y - appletsLayout.defaultItemHeight / 2, - appletsLayout.defaultItemWidth, - appletsLayout.defaultItemHeight) - ); - } - - onDragLeave: { - appletsLayout.hidePlaceHolder(); - } - - preventStealing: true - - onDrop: { - plasmoid.processMimeData(event.mimeData, - event.x - appletsLayout.placeHolder.width / 2, event.y - appletsLayout.placeHolder.height / 2); - event.accept(event.proposedAction); - appletsLayout.hidePlaceHolder(); - } - - PlasmaCore.Svg { - id: arrowsSvg - imagePath: "widgets/arrows" - colorGroup: PlasmaCore.Theme.ComplementaryColorGroup - } - PlasmaCore.IconItem { - z: 9 - anchors { - horizontalCenter: parent.horizontalCenter - bottom: parent.bottom - } - source: "arrow-up" - width: units.iconSizes.medium - height: width - colorGroup: PlasmaCore.Theme.ComplementaryColorGroup - - MouseArea { - anchors { - fill: parent - margins: -units.smallSpacing - } - onClicked: mainFlickable.flick(0, -mainFlickable.height) - } - } - - ContainmentLayoutManager.AppletsLayout { - id: appletsLayout - - anchors.fill: parent - - cellWidth: Math.floor(width / launcher.columns) - cellHeight: launcher.cellHeight - - configKey: width > height ? "ItemGeometriesHorizontal" : "ItemGeometriesVertical" - containment: plasmoid - editModeCondition: plasmoid.immutable - ? ContainmentLayoutManager.AppletsLayout.Manual - : ContainmentLayoutManager.AppletsLayout.AfterPressAndHold - - // Sets the containment in edit mode when we go in edit mode as well - onEditModeChanged: plasmoid.editMode = editMode - - minimumItemWidth: units.gridUnit * 3 - minimumItemHeight: minimumItemWidth - - defaultItemWidth: units.gridUnit * 6 - defaultItemHeight: defaultItemWidth - - //cellWidth: units.iconSizes.small - //cellHeight: cellWidth - - acceptsAppletCallback: function(applet, x, y) { - print("Applet: "+applet+" "+x+" "+y) - return true; - } - - appletContainerComponent: ContainmentLayoutManager.BasicAppletContainer { - id: appletContainer - configOverlayComponent: ConfigOverlay {} - - onEditModeChanged: { - launcherDragManager.active = dragActive || editMode; - } - onDragActiveChanged: { - launcherDragManager.active = dragActive || editMode; - } - } - - placeHolder: ContainmentLayoutManager.PlaceHolder {} - } - } - - Launcher.LauncherGrid { - id: launcher - anchors { - left: parent.left - right: parent.right - } - - favoriteStrip: favoriteStrip - appletsLayout: appletsLayout - } - } - } - - ScrollIndicator { - id: scrollUpIndicator - anchors { - top: parent.top - topMargin: units.gridUnit * 2 - } - elementId: "up-arrow" - } - ScrollIndicator { - id: scrollDownIndicator - anchors { - bottom: favoriteStrip.top - bottomMargin: units.gridUnit - } - elementId: "down-arrow" - } - - Launcher.FavoriteStrip { - id: favoriteStrip - anchors { - left: parent.left - right: parent.right - bottom: parent.bottom - bottomMargin: plasmoid.screenGeometry.height - plasmoid.availableScreenRect.height - plasmoid.availableScreenRect.y - } - appletsLayout: appletsLayout - launcherGrid: launcher - //y: Math.max(krunner.inputHeight, root.height - height - mainFlickable.contentY) - } - - KRunner { - id: krunner - z: 998 - height: plasmoid.availableScreenRect.height - anchors { - top: parent.top - left: parent.left - right: parent.right - topMargin: plasmoid.availableScreenRect.y - } - } -} - diff --git a/containments/homescreen2/package/metadata.desktop b/containments/homescreen2/package/metadata.desktop deleted file mode 100644 index cc05cf69..00000000 --- a/containments/homescreen2/package/metadata.desktop +++ /dev/null @@ -1,37 +0,0 @@ -[Desktop Entry] -Encoding=UTF-8 -Keywords= -Name=Phone Homescreen -Name[ca]=Pantalla d'inici del telèfon -Name[ca@valencia]=Pantalla d'inici del telèfon -Name[cs]=Domácí obrazovka telefonu -Name[en_GB]=Phone Homescreen -Name[es]=Pantalla de inicio del teléfono -Name[fi]=Phonen aloitusnäyttö -Name[fr]=Page d'accueil du téléphone -Name[gl]=Pantalla de inicio do teléfono -Name[it]=Schermata home del telefono -Name[ko]=전화 홈 화면 -Name[nl]=Standaardscherm van de telefoon -Name[nn]=Heimebilete for telefon -Name[pl]=Ekran domowy telefonu -Name[pt]=Ecrã Inicial -Name[sv]=Telefonens hemskärm -Name[tr]=Telefon Ana Ekranı -Name[uk]=Домашня сторінка телефону -Name[x-test]=xxPhone Homescreenxx -Name[zh_CN]=手机主屏幕 -Name[zh_TW]=手機的主畫面 -Type=Service - -X-KDE-ServiceTypes=Plasma/Applet,Plasma/Containment -X-Plasma-API=declarativeappletscript -X-KDE-Library=plasma_containment_phone_homescreen2 -X-KDE-PluginInfo-Author=Marco Martin -X-KDE-PluginInfo-Category=Containments -X-KDE-PluginInfo-Email=mart@kde.org -X-KDE-PluginInfo-License=GPLv2+ -X-KDE-PluginInfo-Name=org.kde.phone.homescreen2 -X-KDE-PluginInfo-Version= -X-KDE-PluginInfo-Website= -X-Plasma-MainScript=ui/main.qml diff --git a/shell/contents/defaults b/shell/contents/defaults index 6fe92065..f1357990 100644 --- a/shell/contents/defaults +++ b/shell/contents/defaults @@ -2,7 +2,7 @@ LookAndFeelPackage=org.kde.plasma.phone [Desktop] -Containment=org.kde.phone.homescreen2 +Containment=org.kde.phone.homescreen ToolBox=org.kde.plasma.nano.desktoptoolbox [Desktop][ContainmentActions]