Make components out of the homescreen

Move most of the homescreen pieces in a QML import
that can be reused making it easier to do alternative homescreens
This commit is contained in:
Marco Martin 2021-03-18 15:07:33 +01:00
parent 0be66f024e
commit 690abebfd5
35 changed files with 585 additions and 327 deletions

View file

@ -53,11 +53,12 @@ plasma_install_package(look-and-feel org.kde.plasma.phone look-and-feel)
plasma_install_package(shell org.kde.plasma.phoneshell shells)
install(FILES plasma_phone_components.notifyrc DESTINATION ${KNOTIFYRC_INSTALL_DIR})
install(DIRECTORY components/ DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/plasma/private/mobileshell)
add_subdirectory(bin)
add_subdirectory(applets)
add_subdirectory(containments)
add_subdirectory(components)
feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)

View file

@ -0,0 +1,3 @@
add_subdirectory(mobilehomescreencomponents)
install(DIRECTORY mobileshell/ DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/plasma/private/mobileshell)

View file

@ -0,0 +1,27 @@
set(mobilehomescreencomponentsplugin_SRCS
mobilehomescreencomponentsplugin.cpp
applicationlistmodel.cpp
favoritesmodel.cpp
homescreenutils.cpp
)
add_library(mobilehomescreencomponentsplugin ${mobilehomescreencomponentsplugin_SRCS})
target_link_libraries(mobilehomescreencomponentsplugin
PUBLIC
Qt::Core
PRIVATE
Qt::Qml
Qt::Quick
KF5::KIOGui
KF5::Plasma
KF5::Notifications
KF5::PlasmaQuick
KF5::WaylandClient
)
install(TARGETS mobilehomescreencomponentsplugin DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/plasma/private/mobilehomescreencomponents)
install(DIRECTORY qml/ DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/plasma/private/mobilehomescreencomponents)

View file

@ -9,9 +9,9 @@
// Qt
#include <QByteArray>
#include <QDebug>
#include <QModelIndex>
#include <QProcess>
#include <QDebug>
#include <QQuickItem>
#include <QQuickWindow>
@ -29,13 +29,17 @@
#include <KWayland/Client/registry.h>
#include <KWayland/Client/surface.h>
#include <Plasma/Applet>
#include <PlasmaQuick/AppletQuickItem>
constexpr int MAX_FAVOURITES = 5;
ApplicationListModel::ApplicationListModel(HomeScreen *parent)
ApplicationListModel::ApplicationListModel(QObject *parent)
: QAbstractListModel(parent)
, m_applet(parent)
//m_applet(parent)
{
connect(KSycoca::self(), qOverload<const QStringList &>(&KSycoca::databaseChanged), this, &ApplicationListModel::sycocaDbChanged);
connect(KSycoca::self(), qOverload<const QStringList &>(&KSycoca::databaseChanged),
this, &ApplicationListModel::sycocaDbChanged);
loadSettings();
initWayland();
@ -48,15 +52,15 @@ void ApplicationListModel::loadSettings()
if (!m_applet) {
return;
}
m_favorites = m_applet->config().readEntry("Favorites", QStringList());
m_favorites = m_applet->applet()->config().readEntry("Favorites", QStringList());
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
const auto di = m_applet->config().readEntry("DesktopItems", QStringList());
const auto di = m_applet->applet()->config().readEntry("DesktopItems", QStringList());
m_desktopItems = QSet<QString>(di.begin(), di.end());
#else
m_desktopItems = m_applet->config().readEntry("DesktopItems", QStringList()).toSet();
m_desktopItems = m_applet->applet()->config().readEntry("DesktopItems", QStringList()).toSet();
#endif
m_appOrder = m_applet->config().readEntry("AppOrder", QStringList());
m_maxFavoriteCount = m_applet->config().readEntry("MaxFavoriteCount", MAX_FAVOURITES);
m_appOrder = m_applet->applet()->config().readEntry("AppOrder", QStringList());
m_maxFavoriteCount = m_applet->applet()->config().readEntry("MaxFavoriteCount", MAX_FAVOURITES);
int i = 0;
for (const QString &app : qAsConst(m_appOrder)) {
@ -64,7 +68,7 @@ void ApplicationListModel::loadSettings()
++i;
}
// loadApplications();
//loadApplications();
}
QHash<int, QByteArray> ApplicationListModel::roleNames() const
@ -78,7 +82,7 @@ QHash<int, QByteArray> ApplicationListModel::roleNames() const
{ApplicationStartupNotifyRole, QByteArrayLiteral("applicationStartupNotify")},
{ApplicationLocationRole, QByteArrayLiteral("applicationLocation")},
{ApplicationRunningRole, QByteArrayLiteral("applicationRunning")},
{ApplicationUniqueIdRole, QByteArrayLiteral("applicationUniqueId")},
{ApplicationUniqueIdRole, QByteArrayLiteral("applicationUniqueId")}
};
}
@ -111,36 +115,39 @@ void ApplicationListModel::initWayland()
}
auto *registry = new Registry(this);
registry->create(connection);
connect(registry, &Registry::plasmaWindowManagementAnnounced, this, [this, registry](quint32 name, quint32 version) {
m_windowManagement = registry->createPlasmaWindowManagement(name, version, this);
qRegisterMetaType<QVector<int>>("QVector<int>");
connect(registry, &Registry::plasmaWindowManagementAnnounced, this,
[this, registry] (quint32 name, quint32 version) {
m_windowManagement = registry->createPlasmaWindowManagement(name, version, this);
qRegisterMetaType<QVector<int> >("QVector<int>");
connect(m_windowManagement, &KWayland::Client::PlasmaWindowManagement::windowCreated, this, [this](KWayland::Client::PlasmaWindow *window) {
if (window->appId() == QStringLiteral("org.kde.plasmashell")) {
return;
}
int idx = 0;
for (auto i = m_applicationList.begin(); i != m_applicationList.end(); i++) {
if ((*i).storageId == window->appId() + QStringLiteral(".desktop")) {
(*i).window = window;
emit dataChanged(index(idx, 0), index(idx, 0));
connect(window, &KWayland::Client::PlasmaWindow::unmapped, this, [this, window]() {
int idx = 0;
for (auto i = m_applicationList.begin(); i != m_applicationList.end(); i++) {
if ((*i).storageId == window->appId() + QStringLiteral(".desktop")) {
(*i).window = nullptr;
emit dataChanged(index(idx, 0), index(idx, 0));
break;
}
idx++;
}
});
break;
connect(m_windowManagement, &KWayland::Client::PlasmaWindowManagement::windowCreated,
this, [this] (KWayland::Client::PlasmaWindow *window) {
if (window->appId() == QStringLiteral("org.kde.plasmashell")) {
return;
}
idx++;
}
});
});
int idx = 0;
for (auto i = m_applicationList.begin(); i != m_applicationList.end(); i++) {
if ((*i).storageId == window->appId() + QStringLiteral(".desktop")) {
(*i).window = window;
emit dataChanged(index(idx, 0), index(idx, 0));
connect(window, &KWayland::Client::PlasmaWindow::unmapped, this, [this, window] () {
int idx = 0;
for (auto i = m_applicationList.begin(); i != m_applicationList.end(); i++) {
if ((*i).storageId == window->appId() + QStringLiteral(".desktop")) {
(*i).window = nullptr;
emit dataChanged(index(idx, 0), index(idx, 0));
break;
}
idx++;
}
});
break;
}
idx++;
}
});
}
);
registry->setup();
connection->roundtrip();
@ -158,9 +165,7 @@ void ApplicationListModel::loadApplications()
m_applicationList.clear();
KServiceGroup::Ptr group = KServiceGroup::root();
if (!group || !group->isValid()) {
return;
}
if (!group || !group->isValid()) return;
KServiceGroup::List subGroupList = group->entries(true);
QMap<int, ApplicationData> orderedList;
@ -178,7 +183,7 @@ void ApplicationListModel::loadApplications()
if (!serviceGroup->noDisplay()) {
KServiceGroup::List entryGroupList = serviceGroup->entries(true);
for (KServiceGroup::List::ConstIterator it = entryGroupList.constBegin(); it != entryGroupList.constEnd(); it++) {
for(KServiceGroup::List::ConstIterator it = entryGroupList.constBegin(); it != entryGroupList.constEnd(); it++) {
KSycocaEntry::Ptr entry = (*it);
if (entry->isType(KST_KServiceGroup)) {
@ -188,10 +193,11 @@ void ApplicationListModel::loadApplications()
} else if (entry->property(QStringLiteral("Exec")).isValid()) {
KService::Ptr service(static_cast<KService *>(entry.data()));
if (service->isApplication() //
&& !blacklist.contains(service->desktopEntryName()) //
&& service->showOnCurrentPlatform() //
&& !service->property(QStringLiteral("Terminal"), QVariant::Bool).toBool()) {
if (service->isApplication() &&
!blacklist.contains(service->desktopEntryName()) &&
service->showOnCurrentPlatform() &&
!service->property(QStringLiteral("Terminal"), QVariant::Bool).toBool()) {
ApplicationData data;
data.name = service->name();
data.icon = service->icon();
@ -239,7 +245,7 @@ void ApplicationListModel::loadApplications()
}
if (favChanged) {
if (m_applet) {
m_applet->config().writeEntry("Favorites", m_favorites);
m_applet->applet()->config().writeEntry("Favorites", m_favorites);
}
emit favoriteCountChanged();
}
@ -279,10 +285,9 @@ QVariant ApplicationListModel::data(const QModelIndex &index, int role) const
Qt::ItemFlags ApplicationListModel::flags(const QModelIndex &index) const
{
if (!index.isValid()) {
if (!index.isValid())
return {};
}
return Qt::ItemIsDragEnabled | QAbstractListModel::flags(index);
return Qt::ItemIsDragEnabled|QAbstractListModel::flags(index);
}
int ApplicationListModel::rowCount(const QModelIndex &parent) const
@ -294,7 +299,7 @@ int ApplicationListModel::rowCount(const QModelIndex &parent) const
return m_applicationList.count();
}
void ApplicationListModel::moveRow(const QModelIndex & /* sourceParent */, int sourceRow, const QModelIndex & /* destinationParent */, int destinationChild)
void ApplicationListModel::moveRow(const QModelIndex& /* sourceParent */, int sourceRow, const QModelIndex& /* destinationParent */, int destinationChild)
{
moveItem(sourceRow, destinationChild);
}
@ -313,22 +318,23 @@ void ApplicationListModel::setLocation(int row, LauncherLocation location)
if (location == Favorites) {
qWarning() << "favoriting" << row << data.name;
// Deny favorites when full
if (row >= m_maxFavoriteCount || m_favorites.count() >= m_maxFavoriteCount || m_favorites.contains(data.uniqueId)) {
if (row >= m_maxFavoriteCount || m_favorites.count() >= m_maxFavoriteCount ||
m_favorites.contains(data.uniqueId)) {
return;
}
m_favorites.insert(row, data.uniqueId);
if (m_applet) {
m_applet->config().writeEntry("Favorites", m_favorites);
m_applet->applet()->config().writeEntry("Favorites", m_favorites);
}
emit favoriteCountChanged();
// Out of favorites
} else if (data.location == Favorites) {
// Out of favorites
} else if (data.location == Favorites) {
m_favorites.removeAll(data.uniqueId);
if (m_applet) {
m_applet->config().writeEntry("Favorites", m_favorites);
m_applet->applet()->config().writeEntry("Favorites", m_favorites);
}
emit favoriteCountChanged();
}
@ -337,27 +343,28 @@ void ApplicationListModel::setLocation(int row, LauncherLocation location)
if (location == Desktop) {
m_desktopItems.insert(data.uniqueId);
if (m_applet) {
m_applet->config().writeEntry("DesktopItems", m_desktopItems.values());
m_applet->applet()->config().writeEntry("DesktopItems", m_desktopItems.values());
}
// Out of Desktop
} else if (data.location == Desktop) {
// Out of Desktop
} else if (data.location == Desktop) {
m_desktopItems.remove(data.uniqueId);
if (m_applet) {
m_applet->config().writeEntry(QStringLiteral("DesktopItems"), m_desktopItems.values());
m_applet->applet()->config().writeEntry(QStringLiteral("DesktopItems"), m_desktopItems.values());
}
}
data.location = location;
if (m_applet) {
emit m_applet->configNeedsSaving();
emit m_applet->applet()->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) {
if (row < 0 || destination < 0 || row >= m_applicationList.length() ||
destination >= m_applicationList.length() || row == destination) {
return;
}
if (destination > row) {
@ -375,6 +382,7 @@ void ApplicationListModel::moveItem(int row, int destination)
m_applicationList.insert(destination, data);
}
m_appOrder.clear();
m_appPositions.clear();
int i = 0;
@ -385,7 +393,7 @@ void ApplicationListModel::moveItem(int row, int destination)
}
if (m_applet) {
m_applet->config().writeEntry("AppOrder", m_appOrder);
m_applet->applet()->config().writeEntry("AppOrder", m_appOrder);
}
endMoveRows();
@ -439,20 +447,25 @@ void ApplicationListModel::setMaxFavoriteCount(int count)
m_maxFavoriteCount = count;
if (m_applet) {
m_applet->config().writeEntry("MaxFavoriteCount", m_maxFavoriteCount);
m_applet->applet()->config().writeEntry("MaxFavoriteCount", m_maxFavoriteCount);
}
emit maxFavoriteCountChanged();
}
Plasma::Applet *ApplicationListModel::applet() const
PlasmaQuick::AppletQuickItem *ApplicationListModel::applet() const
{
return m_applet;
}
void ApplicationListModel::setApplet(Plasma::Applet *applet)
void ApplicationListModel::setApplet(PlasmaQuick::AppletQuickItem *applet)
{
if (m_applet == applet) {
return;
}
m_applet = applet;
loadSettings();
emit appletChanged();
}
void ApplicationListModel::setMinimizedDelegate(int row, QQuickItem *delegate)
@ -479,7 +492,7 @@ void ApplicationListModel::setMinimizedDelegate(int row, QQuickItem *delegate)
return;
}
QRect rect = delegate->mapRectToScene(QRectF(0, 0, delegate->width(), delegate->height())).toRect();
QRect rect = delegate->mapRectToScene(QRectF(0,0, delegate->width(), delegate->height())).toRect();
window->setMinimizedGeometry(surface, rect);
}
@ -512,3 +525,4 @@ void ApplicationListModel::unsetMinimizedDelegate(int row, QQuickItem *delegate)
}
#include "moc_applicationlistmodel.cpp"

View file

@ -8,12 +8,12 @@
#define APPLICATIONLISTMODEL_H
// Qt
#include <QObject>
#include <QAbstractListModel>
#include <QList>
#include <QObject>
#include <QSet>
#include "homescreen.h"
#include "homescreenutils.h"
class QString;
@ -26,12 +26,18 @@ class PlasmaWindow;
}
}
namespace PlasmaQuick
{
class AppletQuickItem;
}
class ApplicationListModel;
class ApplicationListModel : public QAbstractListModel
{
class ApplicationListModel : public QAbstractListModel {
Q_OBJECT
Q_PROPERTY(PlasmaQuick::AppletQuickItem *applet READ applet WRITE setApplet NOTIFY appletChanged)
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)
@ -40,7 +46,7 @@ public:
enum LauncherLocation {
Grid = 0,
Favorites,
Desktop,
Desktop
};
Q_ENUM(LauncherLocation)
@ -64,10 +70,10 @@ public:
ApplicationStartupNotifyRole,
ApplicationLocationRole,
ApplicationRunningRole,
ApplicationUniqueIdRole,
ApplicationUniqueIdRole
};
ApplicationListModel(HomeScreen *parent = nullptr);
ApplicationListModel(QObject *parent = nullptr);
~ApplicationListModel() override;
void loadSettings();
@ -76,20 +82,14 @@ public:
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 count() const { return m_applicationList.count(); }
int favoriteCount() const { return m_favorites.count();}
int maxFavoriteCount() const;
void setMaxFavoriteCount(int count);
void setApplet(Plasma::Applet *applet);
Plasma::Applet *applet() const;
void setApplet(PlasmaQuick::AppletQuickItem *applet);
PlasmaQuick::AppletQuickItem *applet() const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
@ -109,12 +109,13 @@ public:
Q_INVOKABLE void unsetMinimizedDelegate(int row, QQuickItem *delegate);
public Q_SLOTS:
void sycocaDbChanged(const QStringList &change);
void sycocaDbChanged(const QStringList &change);
Q_SIGNALS:
void countChanged();
void favoriteCountChanged();
void maxFavoriteCountChanged();
void appletChanged();
protected:
void initWayland();
@ -122,7 +123,7 @@ protected:
QList<ApplicationData> m_applicationList;
KWayland::Client::PlasmaWindowManagement *m_windowManagement = nullptr;
Plasma::Applet *m_applet = nullptr;
PlasmaQuick::AppletQuickItem *m_applet = nullptr;
int m_maxFavoriteCount = 0;
QStringList m_appOrder;
QStringList m_favorites;

View file

@ -9,22 +9,26 @@
// Qt
#include <QByteArray>
#include <QDebug>
#include <QModelIndex>
#include <QDebug>
// KDE
#include <KService>
#include <KSharedConfig>
#include <Plasma/Applet>
#include <PlasmaQuick/AppletQuickItem>
constexpr int MAX_FAVOURITES = 5;
FavoritesModel::FavoritesModel(HomeScreen *parent)
FavoritesModel::FavoritesModel(QObject *parent)
: ApplicationListModel(parent)
{
}
FavoritesModel::~FavoritesModel() = default;
QString FavoritesModel::storageToUniqueId(const QString &storageId) const
{
if (storageId.isEmpty()) {
@ -50,8 +54,10 @@ QString FavoritesModel::uniqueToStorageId(const QString &uniqueId) const
return uniqueId.split(QLatin1Char('-')).first();
}
void FavoritesModel::loadApplications()
{
beginResetModel();
m_applicationList.clear();
@ -96,10 +102,10 @@ void FavoritesModel::loadApplications()
emit countChanged();
if (m_applet) {
m_applet->config().writeEntry("Favorites", m_favorites);
m_applet->config().writeEntry("AppOrder", m_appOrder);
m_applet->config().writeEntry("DesktopItems", m_desktopItems.values());
emit m_applet->configNeedsSaving();
m_applet->applet()->config().writeEntry("Favorites", m_favorites);
m_applet->applet()->config().writeEntry("AppOrder", m_appOrder);
m_applet->applet()->config().writeEntry("DesktopItems", m_desktopItems.values());
emit m_applet->applet()->configNeedsSaving();
}
if (favChanged) {
@ -142,10 +148,10 @@ void FavoritesModel::addFavorite(const QString &storageId, int row, LauncherLoca
}
if (m_applet) {
m_applet->config().writeEntry("Favorites", m_favorites);
m_applet->config().writeEntry("AppOrder", m_appOrder);
m_applet->config().writeEntry("DesktopItems", m_desktopItems.values());
emit m_applet->configNeedsSaving();
m_applet->applet()->config().writeEntry("Favorites", m_favorites);
m_applet->applet()->config().writeEntry("AppOrder", m_appOrder);
m_applet->applet()->config().writeEntry("DesktopItems", m_desktopItems.values());
emit m_applet->applet()->configNeedsSaving();
}
}
}
@ -171,11 +177,12 @@ void FavoritesModel::removeFavorite(int row)
}
if (m_applet) {
m_applet->config().writeEntry("Favorites", m_favorites);
m_applet->config().writeEntry("AppOrder", m_appOrder);
m_applet->config().writeEntry("DesktopItems", m_desktopItems.values());
emit m_applet->configNeedsSaving();
m_applet->applet()->config().writeEntry("Favorites", m_favorites);
m_applet->applet()->config().writeEntry("AppOrder", m_appOrder);
m_applet->applet()->config().writeEntry("DesktopItems", m_desktopItems.values());
emit m_applet->applet()->configNeedsSaving();
}
}
#include "moc_favoritesmodel.cpp"

View file

@ -7,13 +7,13 @@
#pragma once
// Qt
#include <QObject>
#include <QAbstractListModel>
#include <QList>
#include <QObject>
#include <QSet>
#include "homescreenutils.h"
#include "applicationlistmodel.h"
#include "homescreen.h"
class QString;
@ -28,14 +28,14 @@ class PlasmaWindow;
class FavoritesModel;
class FavoritesModel : public ApplicationListModel
{
class FavoritesModel : public ApplicationListModel {
Q_OBJECT
public:
FavoritesModel(HomeScreen *parent = nullptr);
FavoritesModel(QObject *parent = nullptr);
~FavoritesModel() override;
QString storageToUniqueId(const QString &storageId) const;
QString uniqueToStorageId(const QString &uniqueId) const;
@ -43,4 +43,7 @@ public:
Q_INVOKABLE void removeFavorite(int row);
Q_INVOKABLE void loadApplications() override;
};

View file

@ -0,0 +1,55 @@
/*
SPDX-FileCopyrightText: 2021 Marco Martin <mart@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "homescreenutils.h"
#include "applicationlistmodel.h"
#include "favoritesmodel.h"
#include <QtQml>
#include <QDebug>
#include <QQuickItem>
HomeScreenUtils::HomeScreenUtils(QObject *parent)
: QObject(parent)
{
}
HomeScreenUtils::~HomeScreenUtils() = default;
ApplicationListModel *HomeScreenUtils::applicationListModel()
{
if (!m_applicationListModel) {
if (m_showAllApps) {
m_applicationListModel = new ApplicationListModel(this);
} else {
m_applicationListModel = new FavoritesModel(this);
}
// m_applicationListModel->setApplet(this);
m_applicationListModel->loadApplications();
}
return m_applicationListModel;
}
void HomeScreenUtils::stackBefore(QQuickItem *item1, QQuickItem *item2)
{
if (!item1 || !item2 || item1 == item2 || item1->parentItem() != item2->parentItem()) {
return;
}
item1->stackBefore(item2);
}
void HomeScreenUtils::stackAfter(QQuickItem *item1, QQuickItem *item2)
{
if (!item1 || !item2 || item1 == item2 || item1->parentItem() != item2->parentItem()) {
return;
}
item1->stackAfter(item2);
}
#include "moc_homescreenutils.cpp"

View file

@ -0,0 +1,37 @@
/*
SPDX-FileCopyrightText: 2021 Marco Martin <mart@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include <QObject>
class QQuickItem;
class ApplicationListModel;
class FavoritesModel;
class HomeScreenUtils : public QObject
{
Q_OBJECT
Q_PROPERTY(ApplicationListModel *applicationListModel READ applicationListModel CONSTANT)
public:
HomeScreenUtils( QObject *parent = 0);
~HomeScreenUtils() override;
ApplicationListModel *applicationListModel();
Q_INVOKABLE void stackBefore(QQuickItem *item1, QQuickItem *item2);
Q_INVOKABLE void stackAfter(QQuickItem *item1, QQuickItem *item2);
protected:
// void configChanged() override;
private:
ApplicationListModel *m_applicationListModel = nullptr;
bool m_showAllApps = false;
};

View file

@ -0,0 +1,51 @@
/*
* Copyright 2019 by Marco Martin <mart@kde.org>
* 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.
*/
#include "mobilehomescreencomponentsplugin.h"
#include <QQmlContext>
#include <QQuickItem>
#include "favoritesmodel.h"
#include "applicationlistmodel.h"
#include "homescreenutils.h"
void MobileHomeScreenComponentsPlugin::registerTypes(const char *uri)
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("org.kde.plasma.private.mobilehomescreencomponents"));
qmlRegisterSingletonType<HomeScreenUtils>(uri, 0, 1, "HomeScreenUtils",
[](QQmlEngine *, QJSEngine *) {
return new HomeScreenUtils{};
});
qmlRegisterSingletonType<ApplicationListModel>(uri, 0, 1, "ApplicationListModel",
[](QQmlEngine *, QJSEngine *) {
return new ApplicationListModel{};
});
qmlRegisterSingletonType<FavoritesModel>(uri, 0, 1, "FavoritesModel",
[](QQmlEngine *, QJSEngine *) {
return new FavoritesModel{};
});
// qmlProtectModule(uri, 1);
}
//#include "moc_mobilehomescreencomponentplugin.cpp"

View file

@ -0,0 +1,34 @@
/*
* Copyright 2019 by Marco Martin <mart@kde.org>
* 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.
*/
#pragma once
#include <QUrl>
#include <QQmlEngine>
#include <QQmlExtensionPlugin>
class MobileHomeScreenComponentsPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
public:
void registerTypes(const char *uri) override;
};

View file

@ -16,7 +16,7 @@ import org.kde.kirigami 2.10 as Kirigami
import org.kde.plasma.private.nanoshell 2.0 as NanoShell
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.phone.homescreen 1.0
import org.kde.plasma.private.mobilehomescreencomponents 0.1 as HomeScreenComponents
import "private"
@ -204,10 +204,7 @@ Item {
// boundsBehavior: Flickable.StopAtBounds
model: ApplicationListModel {
id: allApplicationsModel
Component.onCompleted: loadApplications()
}
model: HomeScreenComponents.ApplicationListModel
header: Rectangle {
height: root.height - root.topPadding - root.bottomPadding - root.closedPositionOffset
@ -247,8 +244,8 @@ Item {
Math.min(delegate.iconItem.width, delegate.iconItem.height));
}
allApplicationsModel.setMinimizedDelegate(index, delegate);
allApplicationsModel.runApplication(storageId);
HomeScreenComponents.ApplicationListModel.setMinimizedDelegate(index, delegate);
HomeScreenComponents.ApplicationListModel.runApplication(storageId);
root.launched();
closeTimer.restart();
}

View file

@ -16,7 +16,6 @@ import org.kde.kquickcontrolsaddons 2.0
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.phone.homescreen 1.0
MouseArea {
id: delegate
@ -97,7 +96,7 @@ MouseArea {
//FIXME: export smallestReadableFont
font.pointSize: theme.defaultFont.pointSize * 0.9
color: "white"//model.applicationLocation == ApplicationListModel.Desktop ? "white" : theme.textColor
color: "white"
}
}
}

View file

@ -21,8 +21,6 @@ LauncherContainer {
flow.flow: Flow.TopToBottom
opacity: launcherDragManager.active && plasmoid.nativeInterface.applicationListModel.favoriteCount >= plasmoid.nativeInterface.applicationListModel.maxFavoriteCount ? 0.3 : 1
height: visible ? cellHeight : 0
frame.implicitWidth: cellWidth * Math.max(1, flow.children.length) + frame.leftPadding + frame.rightPadding

View file

@ -17,10 +17,9 @@ import "private" as Private
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
import org.kde.phone.homescreen 1.0
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.plasma.private.mobilehomescreencomponents 0.1 as HomeScreenComponents
Flickable {
id: mainFlickable
@ -33,6 +32,7 @@ Flickable {
property ContainmentLayoutManager.AppletsLayout appletsLayout: null
property Item footer
property alias dragGestureEnabled: gestureHandler.enabled
opacity: 1 - appDrawer.openFactor
transform: Translate {
y: -mainFlickable.height/10 * appDrawer.openFactor
@ -41,9 +41,7 @@ Flickable {
clip: true
property bool showAddPageIndicator: false
//bottomMargin: favoriteStrip.height
contentHeight: height
//interactive: !plasmoid.editMode && !launcherDragManager.active
interactive: false
signal cancelEditModeForItemsRequested
@ -133,7 +131,6 @@ Flickable {
target: appletsLayout
appDrawer: mainFlickable.appDrawer
mainFlickable: mainFlickable
enabled: root.focus && appDrawer.status !== AppDrawer.Status.Open && !appletsLayout.editMode && !plasmoid.editMode && !launcherDragManager.active
onSnapPage: mainFlickable.snapPage();
onSnapNextPage: mainFlickable.snapNextPage();
onSnapPrevPage: mainFlickable.snapPrevPage();
@ -185,23 +182,33 @@ Flickable {
}
}
Private.ScrollIndicator {
id: scrollLeftIndicator
parent: mainFlickable
anchors {
left: parent.left
leftMargin: units.smallSpacing
Item {
z: 9999999
anchors.fill: parent
parent: {
let candidate = mainFlickable;
while (candidate.parent) {
candidate = candidate.parent;
}
return candidate;
}
elementId: "left-arrow"
}
Private.ScrollIndicator {
id: scrollRightIndicator
parent: mainFlickable
anchors {
right: parent.right
rightMargin: units.smallSpacing
Private.ScrollIndicator {
id: scrollLeftIndicator
anchors {
left: parent.left
leftMargin: units.smallSpacing
}
elementId: "left-arrow"
}
Private.ScrollIndicator {
id: scrollRightIndicator
anchors {
right: parent.right
rightMargin: units.smallSpacing
}
elementId: "right-arrow"
}
elementId: "right-arrow"
}
}

View file

@ -16,7 +16,7 @@ import org.kde.kquickcontrolsaddons 2.0
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.phone.homescreen 1.0
import org.kde.plasma.private.mobilehomescreencomponents 0.1 as HomeScreenComponents
import "private" as Private
@ -47,9 +47,9 @@ ContainmentLayoutManager.ItemContainer {
}
if (!MobileShell.HomeScreenControls.taskSwitcherVisible) {
plasmoid.nativeInterface.applicationListModel.setMinimizedDelegate(index, delegate);
HomeScreenComponents.ApplicationListModel.setMinimizedDelegate(index, delegate);
} else {
plasmoid.nativeInterface.applicationListModel.unsetMinimizedDelegate(index, delegate);
HomeScreenComponents.ApplicationListModel.unsetMinimizedDelegate(index, delegate);
}
}
@ -94,8 +94,8 @@ ContainmentLayoutManager.ItemContainer {
delegate.launch(delegate.x + (PlasmaCore.Units.smallSpacing * 2), delegate.y + (PlasmaCore.Units.smallSpacing * 2), icon.source, modelData.applicationName);
}
plasmoid.nativeInterface.applicationListModel.setMinimizedDelegate(index, delegate);
plasmoid.nativeInterface.applicationListModel.runApplication(modelData.applicationStorageId);
HomeScreenComponents.ApplicationListModel.setMinimizedDelegate(index, delegate);
HomeScreenComponents.ApplicationListModel.runApplication(modelData.applicationStorageId);
}
//preventStealing: true
@ -156,9 +156,9 @@ ContainmentLayoutManager.ItemContainer {
//FIXME: export smallestReadableFont
font.pointSize: theme.defaultFont.pointSize * 0.9
color: "white"//model.applicationLocation == ApplicationListModel.Desktop ? "white" : theme.textColor
color: "white"//model.applicationLocation == HomeScreenComponents.ApplicationListModel.Desktop ? "white" : theme.textColor
layer.enabled: true//model.applicationLocation == ApplicationListModel.Desktop
layer.enabled: true//model.applicationLocation == HomeScreenComponents.ApplicationListModel.Desktop
layer.effect: DropShadow {
horizontalOffset: 0
verticalOffset: 2

View file

@ -16,17 +16,17 @@ import org.kde.draganddrop 2.0 as DragDrop
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
import org.kde.phone.homescreen 1.0
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.plasma.private.mobilehomescreencomponents 0.1 as HomeScreenComponents
import "private" as Private
DragDrop.DropArea {
id: dropArea
width: mainFlickable.width * 100
//width: Math.max(mainFlickable.width, mainFlickable.width * Math.ceil(appletsLayout.childrenRect.width/mainFlickable.width))
height: mainFlickable.height + favoriteStrip.height + units.gridUnit
height: mainFlickable.height
property alias itemsBoundingRect: appletsLayout.childrenRect
@ -34,6 +34,21 @@ DragDrop.DropArea {
property FavoriteStrip favoriteStrip
property LauncherDragManager launcherDragManager: LauncherDragManager {
id: launcherDragManager
parent: {
let candidate = dropArea;
while (candidate.parent) {
candidate = candidate.parent;
}
return candidate;
}
anchors.fill: parent
z: 999999
appletsLayout: homeScreenContents.appletsLayout
favoriteStrip: dropArea.favoriteStrip
}
Connections {
target: plasmoid
function onEditModeChanged() {
@ -48,7 +63,7 @@ DragDrop.DropArea {
onDragMove: {
let posInFavorites = favoriteStrip.mapFromItem(this, event.x, event.y);
if (posInFavorites.y > 0) {
if (plasmoid.nativeInterface.applicationListModel.favoriteCount >= plasmoid.nativeInterface.applicationListModel.maxFavoriteCount ) {
if (HomeScreenComponents.ApplicationListModel.favoriteCount >= HomeScreenComponents.ApplicationListModel.maxFavoriteCount ) {
launcherDragManager.hideSpacer();
} else {
launcherDragManager.showSpacerAtPos(event.x, event.y, favoriteStrip);
@ -91,12 +106,12 @@ DragDrop.DropArea {
let posInFavorites = favoriteStrip.flow.mapFromItem(this, event.x, event.y);
if (posInFavorites.y > 0) {
if (plasmoid.nativeInterface.applicationListModel.favoriteCount >= plasmoid.nativeInterface.applicationListModel.maxFavoriteCount ) {
if (HomeScreenComponents.ApplicationListModel.favoriteCount >= HomeScreenComponents.ApplicationListModel.maxFavoriteCount ) {
return;
}
let pos = Math.min(plasmoid.nativeInterface.applicationListModel.count, Math.floor(posInFavorites.x/favoriteStrip.cellWidth))
plasmoid.nativeInterface.applicationListModel.addFavorite(storageId, pos, ApplicationListModel.Favorites)
let pos = Math.min(HomeScreenComponents.FavoritesModel.count, Math.floor(posInFavorites.x/favoriteStrip.cellWidth))
HomeScreenComponents.FavoritesModel.addFavorite(storageId, pos, HomeScreenComponents.ApplicationListModel.Favorites)
let item = launcherRepeater.itemAt(pos);
if (item) {
@ -110,9 +125,8 @@ DragDrop.DropArea {
return;
}
let pos = plasmoid.nativeInterface.applicationListModel.count;
plasmoid.nativeInterface.applicationListModel.addFavorite(storageId, pos, ApplicationListModel.Desktop)
let pos = HomeScreenComponents.FavoritesModel.count;
HomeScreenComponents.FavoritesModel.addFavorite(storageId, pos, HomeScreenComponents.ApplicationListModel.Desktop)
let item = launcherRepeater.itemAt(pos);
event.accept(event.proposedAction);
@ -136,7 +150,7 @@ DragDrop.DropArea {
anchors {
fill: parent
bottomMargin: favoriteStrip.height
bottomMargin: dropArea.favoriteStrip ? dropArea.favoriteStrip.height : 0
}
signal appletsLayoutInteracted
@ -176,88 +190,8 @@ DragDrop.DropArea {
print("Applet: "+applet+" "+x+" "+y)
return true;
}
appletContainerComponent: ContainmentLayoutManager.BasicAppletContainer {
id: appletContainer
configOverlayComponent: Private.ConfigOverlay {}
onEditModeChanged: {
launcherDragManager.active = dragActive || editMode;
}
property real dragCenterX
property real dragCenterY
editModeCondition: ContainmentLayoutManager.ItemContainer.AfterPressAndHold
onDragActiveChanged: {
launcherDragManager.active = dragActive || editMode;
if (dragActive) {
// Must be 0, 0 as at this point dragCenterX and dragCenterY are on the drag before"
launcherDragManager.startDrag(appletContainer);
launcherDragManager.currentlyDraggedDelegate = appletContainer;
// Reparenting removed focus
appletContainer.forceActiveFocus();
} else {
launcherDragManager.dropItem(appletContainer, dragCenterX, dragCenterY);
plasmoid.editMode = false;
launcherRepeater.stopScrollRequested();
launcherDragManager.currentlyDraggedDelegate = null;
forceActiveFocus();
}
}
onUserDrag: {
dragCenterX = dragCenter.x;
dragCenterY = dragCenter.y;
launcherDragManager.dragItem(appletContainer, dragCenter.x, dragCenter.y);
var pos = plasmoid.fullRepresentationItem.mapFromItem(appletContainer, dragCenter.x, dragCenter.y);
//SCROLL LEFT
if (pos.x < units.gridUnit) {
launcherRepeater.scrollLeftRequested();
//SCROLL RIGHT
} else if (pos.x > mainFlickable.width - units.gridUnit) {
launcherRepeater.scrollRightRequested();
//DON't SCROLL
} else {
launcherRepeater.stopScrollRequested();
}
appletContainer.x = Math.max(0, Math.min(mainFlickable.width - appletContainer.width, appletContainer.x));
}
Connections {
target: appletsLayout
function onAppletsLayoutInteracted() {
appletContainer.editMode = false;
}
}
Connections {
target: dropArea
function onWidthChanged () {
let spaceReleased = false;
if (appletContainer.width > mainFlickable.width || appletContainer.height > mainFlickable.height) {
appletContainer.width = Math.min(appletContainer.width, mainFlickable.width);
appletContainer.height = Math.min(appletContainer.height, mainFlickable.height);
spaceReleased = true;
}
if (Math.floor((appletContainer.x) / mainFlickable.width) < Math.floor((appletContainer.x + appletContainer.width/2) / mainFlickable.width)) {
appletsLayout.releaseSpace(appletContainer);
appletContainer.x = Math.floor((appletContainer.x + appletContainer.width) / mainFlickable.width) * mainFlickable.width;
appletsLayout.positionItem(appletContainer);
spaceReleased = false;
} else if (Math.floor((appletContainer.x + appletContainer.width/2) / mainFlickable.width) < Math.floor((appletContainer.x + appletContainer.width) / mainFlickable.width)) {
appletsLayout.releaseSpace(appletContainer);
appletContainer.x = Math.ceil(appletContainer.x / mainFlickable.width) * mainFlickable.width - appletContainer.width;
appletsLayout.positionItem(appletContainer);
spaceReleased = false;
}
if (spaceReleased) {
appletsLayout.positionItem(appletContainer);
}
}
}
appletContainerComponent: MobileAppletContainer {
launcherDragManager: dropArea.launcherDragManager
}
placeHolder: ContainmentLayoutManager.PlaceHolder {}

View file

@ -7,8 +7,8 @@
import QtQuick 2.4
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
import org.kde.plasma.private.mobilehomescreencomponents 0.1 as HomeScreenComponents
import org.kde.phone.homescreen 1.0
Item {
id: root
@ -17,7 +17,7 @@ Item {
property FavoriteStrip favoriteStrip
property ContainmentLayoutManager.ItemContainer currentlyDraggedDelegate
property bool active
property QtObject model: plasmoid.nativeInterface.applicationListModel
property QtObject model: HomeScreenComponents.ApplicationListModel
readonly property Item spacer: Item {
width: favoriteStrip.cellWidth
@ -42,7 +42,7 @@ Item {
var pos = favoriteStrip.flow.mapFromItem(delegate, 0, 0);
newRow = Math.floor((pos.x + dragCenterX) / delegate.width);
//root.model.setLocation(delegate.modelData.index, ApplicationListModel.Favorites);
//root.model.setLocation(delegate.modelData.index, HomeScreenComponents.ApplicationListModel.Favorites);
showSpacer(delegate, dragCenterX, dragCenterY);
root.model.moveItem(delegate.modelData.index, newRow);
@ -50,7 +50,7 @@ Item {
// Put it on desktop
} else {
var pos = appletsLayout.mapFromItem(delegate, 0, 0);
//root.model.setLocation(delegate.modelData.index, ApplicationListModel.Desktop);
//root.model.setLocation(delegate.modelData.index, HomeScreenComponents.ApplicationListModel.Desktop);
showSpacer(delegate, dragCenterX, dragCenterY);
return;
@ -163,7 +163,7 @@ Item {
if (!item.modelData) {
return appletsLayout;
} else if (favoriteStrip.contains(Qt.point(0,favoriteStrip.frame.mapFromItem(item, dragCenterX, dragCenterY).y))
&& (item.modelData.applicationLocation == ApplicationListModel.Favorites
&& (item.modelData.applicationLocation == HomeScreenComponents.ApplicationListModel.Favorites
|| root.model.favoriteCount < root.model.maxFavoriteCount)) {
return favoriteStrip;
} else {
@ -278,7 +278,7 @@ Item {
if (container == appletsLayout) {
if (item.modelData) {
root.model.setLocation(item.modelData.index, ApplicationListModel.Desktop);
root.model.setLocation(item.modelData.index, HomeScreenComponents.ApplicationListModel.Desktop);
}
var pos = appletsLayout.mapFromItem(item, 0, 0);
item.parent = appletsLayout;
@ -289,9 +289,9 @@ Item {
return;
} else if (container == favoriteStrip) {
root.model.setLocation(item.modelData.index, ApplicationListModel.Favorites);
root.model.setLocation(item.modelData.index, HomeScreenComponents.ApplicationListModel.Favorites);
} else {
root.model.setLocation(item.modelData.index, ApplicationListModel.Grid);
root.model.setLocation(item.modelData.index, HomeScreenComponents.ApplicationListModel.Grid);
}
var child = nearestChild(item, dragCenterX, dragCenterY, container);

View file

@ -17,7 +17,7 @@ import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutM
import org.kde.plasma.private.nanoshell 2.0 as NanoShell
import org.kde.phone.homescreen 1.0
import org.kde.plasma.private.mobilehomescreencomponents 0.1 as HomeScreenComponents
LauncherContainer {
id: root
@ -32,7 +32,7 @@ LauncherContainer {
Repeater {
parent: root.flow
model: plasmoid.nativeInterface.applicationListModel
model: HomeScreenComponents.ApplicationListModel
delegate: HomeDelegate {
id: delegate
width: root.cellWidth
@ -41,16 +41,16 @@ LauncherContainer {
parent: parentFromLocation
property Item parentFromLocation: {
switch (model.applicationLocation) {
case ApplicationListModel.Desktop:
case HomeScreenComponents.ApplicationListModel.Desktop:
return appletsLayout;
case ApplicationListModel.Favorites:
case HomeScreenComponents.ApplicationListModel.Favorites:
return favoriteStrip.flow;
default:
return root.flow;
}
}
Component.onCompleted: {
if (model.applicationLocation === ApplicationListModel.Desktop) {
if (model.applicationLocation === HomeScreenComponents.ApplicationListModel.Desktop) {
appletsLayout.restoreItem(delegate);
}
}
@ -68,11 +68,11 @@ LauncherContainer {
onParentFromLocationChanged: {
if (!launcherDragManager.active && parent != parentFromLocation) {
parent = parentFromLocation;
if (model.applicationLocation === ApplicationListModel.Favorites) {
if (model.applicationLocation === HomeScreenComponents.ApplicationListModel.Favorites) {
plasmoid.nativeInterface.stackBefore(delegate, parentFromLocation.children[index]);
} else if (model.applicationLocation === ApplicationListModel.Grid) {
plasmoid.nativeInterface.stackBefore(delegate, parentFromLocation.children[Math.max(0, index - plasmoid.nativeInterface.applicationListModel.favoriteCount)]);
} else if (model.applicationLocation === HomeScreenComponents.ApplicationListModel.Grid) {
plasmoid.nativeInterface.stackBefore(delegate, parentFromLocation.children[Math.max(0, index - HomeScreenComponents.ApplicationListModel.favoriteCount)]);
}
}
}

View file

@ -17,12 +17,12 @@ import org.kde.kquickcontrolsaddons 2.0
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.plasma.private.nanoshell 2.0 as NanoShell
import org.kde.phone.homescreen 1.0
import org.kde.kirigami 2.14 as Kirigami
import org.kde.plasma.private.mobilehomescreencomponents 0.1 as HomeScreenComponents
Repeater {
id: launcherRepeater
model: plasmoid.nativeInterface.applicationListModel
model: HomeScreenComponents.FavoritesModel
property ContainmentLayoutManager.AppletsLayout appletsLayout
property FavoriteStrip favoriteStrip
property int cellWidth
@ -48,15 +48,15 @@ Repeater {
reservedSpaceForLabel: metrics.height
property Item parentFromLocation: {
switch (model.applicationLocation) {
case ApplicationListModel.Favorites:
case HomeScreenComponents.ApplicationListModel.Favorites:
return favoriteStrip.flow;
case ApplicationListModel.Desktop:
case HomeScreenComponents.ApplicationListModel.Desktop:
default:
return appletsLayout;
}
}
Component.onCompleted: {
if (model.applicationLocation === ApplicationListModel.Desktop) {
if (model.applicationLocation === HomeScreenComponents.ApplicationListModel.Desktop) {
appletsLayout.restoreItem(delegate);
}
}
@ -114,11 +114,11 @@ Repeater {
onParentFromLocationChanged: {
if (!launcherDragManager.active && parent != parentFromLocation) {
parent = parentFromLocation;
if (model.applicationLocation === ApplicationListModel.Favorites) {
if (model.applicationLocation === HomeScreenComponents.ApplicationListModel.Favorites) {
plasmoid.nativeInterface.stackBefore(delegate, parentFromLocation.children[index]);
} else if (model.applicationLocation === ApplicationListModel.Grid) {
plasmoid.nativeInterface.stackBefore(delegate, parentFromLocation.children[Math.max(0, index - plasmoid.nativeInterface.applicationListModel.favoriteCount)]);
} else if (model.applicationLocation === HomeScreenComponents.ApplicationListModel.Grid) {
plasmoid.nativeInterface.stackBefore(delegate, parentFromLocation.children[Math.max(0, index - HomeScreenComponents.ApplicationListModel.favoriteCount)]);
}
}
}

View file

@ -0,0 +1,115 @@
/*
* SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org>
*
* SPDX-License-Identifier: LGPL-2.0-or-later
*/
import QtQuick 2.12
import QtQuick.Window 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 org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import "private" as Private
ContainmentLayoutManager.BasicAppletContainer {
id: appletContainer
configOverlayComponent: Private.ConfigOverlay {}
property LauncherDragManager launcherDragManager
onEditModeChanged: {
launcherDragManager.active = dragActive || editMode;
}
property real dragCenterX
property real dragCenterY
editModeCondition: ContainmentLayoutManager.ItemContainer.AfterPressAndHold
onDragActiveChanged: {
launcherDragManager.active = dragActive || editMode;
if (dragActive) {
// Must be 0, 0 as at this point dragCenterX and dragCenterY are on the drag before"
launcherDragManager.startDrag(appletContainer);
launcherDragManager.currentlyDraggedDelegate = appletContainer;
// Reparenting removed focus
appletContainer.forceActiveFocus();
} else {
launcherDragManager.dropItem(appletContainer, dragCenterX, dragCenterY);
plasmoid.editMode = false;
launcherRepeater.stopScrollRequested();
launcherDragManager.currentlyDraggedDelegate = null;
forceActiveFocus();
}
}
onUserDrag: {
dragCenterX = dragCenter.x;
dragCenterY = dragCenter.y;
launcherDragManager.dragItem(appletContainer, dragCenter.x, dragCenter.y);
var pos = plasmoid.fullRepresentationItem.mapFromItem(appletContainer, dragCenter.x, dragCenter.y);
//SCROLL LEFT
if (pos.x < units.gridUnit) {
launcherRepeater.scrollLeftRequested();
//SCROLL RIGHT
} else if (pos.x > mainFlickable.width - units.gridUnit) {
launcherRepeater.scrollRightRequested();
//DON't SCROLL
} else {
launcherRepeater.stopScrollRequested();
}
appletContainer.x = Math.max(0, Math.min(mainFlickable.width - appletContainer.width, appletContainer.x));
}
onWidthChanged: {
if (appletContainer.x + appletContainer.width > mainFlickable.width * Math.max(1, Math.ceil(appletContainer.x / mainFlickable.width))) {
appletsLayout.releaseSpace(appletContainer);
appletContainer.width = (mainFlickable.width * Math.max(1, Math.ceil(appletContainer.x / mainFlickable.width)) - appletContainer.x);
appletsLayout.positionItem(appletContainer);
}
}
Connections {
target: appletsLayout
function onAppletsLayoutInteracted() {
appletContainer.editMode = false;
}
}
Connections {
target: dropArea
function onWidthChanged () {
let spaceReleased = false;
if (appletContainer.width > mainFlickable.width || appletContainer.height > mainFlickable.height) {
appletsLayout.releaseSpace(appletContainer);
appletContainer.width = Math.min(appletContainer.width, mainFlickable.width);
appletContainer.height = Math.min(appletContainer.height, mainFlickable.height);
spaceReleased = true;
}
if (Math.floor((appletContainer.x) / mainFlickable.width) < Math.floor((appletContainer.x + appletContainer.width/2) / mainFlickable.width)) {
appletsLayout.releaseSpace(appletContainer);
appletContainer.x = Math.floor((appletContainer.x + appletContainer.width) / mainFlickable.width) * mainFlickable.width;
appletsLayout.positionItem(appletContainer);
spaceReleased = false;
} else if (Math.floor((appletContainer.x + appletContainer.width/2) / mainFlickable.width) < Math.floor((appletContainer.x + appletContainer.width) / mainFlickable.width)) {
appletsLayout.releaseSpace(appletContainer);
appletContainer.x = Math.ceil(appletContainer.x / mainFlickable.width) * mainFlickable.width - appletContainer.width;
appletsLayout.positionItem(appletContainer);
spaceReleased = false;
}
if (spaceReleased) {
appletsLayout.positionItem(appletContainer);
}
}
}
}

View file

@ -16,7 +16,7 @@ import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutM
ContainmentLayoutManager.ConfigOverlayWithHandles {
id: overlay
readonly property int iconSize: units.iconSizes.medium
readonly property int iconSize: PlasmaCore.Units.iconSizes.medium
PlasmaCore.Svg {
id: configIconsSvg
imagePath: "widgets/configuration-icons"
@ -40,7 +40,7 @@ ContainmentLayoutManager.ConfigOverlayWithHandles {
property: "scale"
from: 1
to: 0
duration: units.longDuration
duration: PlasmaCore.Units.longDuration
easing.type: Easing.InOutQuad
}
ScriptAction {
@ -60,7 +60,7 @@ ContainmentLayoutManager.ConfigOverlayWithHandles {
RowLayout {
id: layout
spacing: units.largeSpacing
spacing: PlasmaCore.Units.largeSpacing
anchors {
fill: parent
topMargin: parent.margins.top

View file

@ -16,8 +16,7 @@ import org.kde.kquickcontrolsaddons 2.0
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.phone.homescreen 1.0
import org.kde.plasma.private.mobilehomescreencomponents 0.1 as HomeScreenComponents
PC3.RoundButton {
id: removeButton
@ -57,7 +56,7 @@ PC3.RoundButton {
ScriptAction {
script: {
appletsLayout.releaseSpace(delegate);
plasmoid.nativeInterface.applicationListModel.removeFavorite(index);
HomeScreenComponents.ApplicationListModel.removeFavorite(index);
}
}
}

View file

@ -16,8 +16,6 @@ import org.kde.draganddrop 2.0 as DragDrop
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
import org.kde.phone.homescreen 1.0
import org.kde.plasma.private.mobileshell 1.0 as MobileShell

View file

@ -0,0 +1,16 @@
module org.kde.plasma.private.mobilehomescreencomponents
plugin mobilehomescreencomponentsplugin
AppDrawer 0.1 AppDrawer.qml
DrawerDelegate 0.1 DrawerDelegate.qml
FavoriteStrip 0.1 FavoriteStrip.qml
FlickablePages 0.1 FlickablePages.qml
HomeDelegate 0.1 HomeDelegate.qml
HomeScreenContents 0.1 HomeScreenContents.qml
LauncherContainer 0.1 LauncherContainer.qml
LauncherDragManager 0.1 LauncherDragManager.qml
LauncherGrid 0.1 LauncherGrid.qml
LauncherRepeater 0.1 LauncherRepeater.qml
MobileAppletContainer 0.1 MobileAppletContainer.qml

View file

@ -1,7 +1,5 @@
set(homescreen_SRCS
homescreen.cpp
applicationlistmodel.cpp
favoritesmodel.cpp
)
add_library(plasma_containment_phone_homescreen MODULE ${homescreen_SRCS})
@ -24,4 +22,3 @@ target_link_libraries(plasma_containment_phone_homescreen
install(TARGETS plasma_containment_phone_homescreen DESTINATION ${KDE_INSTALL_PLUGINDIR}/plasma/applets)
plasma_install_package(package org.kde.phone.homescreen)

View file

@ -4,8 +4,6 @@
*/
#include "homescreen.h"
#include "applicationlistmodel.h"
#include "favoritesmodel.h"
#include <QDebug>
#include <QQuickItem>
@ -14,8 +12,6 @@
HomeScreen::HomeScreen(QObject *parent, const QVariantList &args)
: Plasma::Containment(parent, args)
{
qmlRegisterType<ApplicationListModel>("org.kde.phone.homescreen", 1, 0, "ApplicationListModel");
qmlRegisterType<FavoritesModel>("org.kde.phone.homescreen", 1, 0, "FavoritesModel");
setHasConfigurationInterface(true);
}
@ -25,24 +21,8 @@ HomeScreen::~HomeScreen() = default;
void HomeScreen::configChanged()
{
Plasma::Containment::configChanged();
if (m_applicationListModel) {
m_applicationListModel->loadSettings();
}
}
ApplicationListModel *HomeScreen::applicationListModel()
{
if (!m_applicationListModel) {
if (m_showAllApps) {
m_applicationListModel = new ApplicationListModel(this);
} else {
m_applicationListModel = new FavoritesModel(this);
}
m_applicationListModel->setApplet(this);
m_applicationListModel->loadApplications();
}
return m_applicationListModel;
}
void HomeScreen::stackBefore(QQuickItem *item1, QQuickItem *item2)
{

View file

@ -16,7 +16,6 @@ class FavoritesModel;
class HomeScreen : public Plasma::Containment
{
Q_OBJECT
Q_PROPERTY(ApplicationListModel *applicationListModel READ applicationListModel CONSTANT)
public:
HomeScreen(QObject *parent, const QVariantList &args);
@ -24,7 +23,6 @@ public:
void configChanged() override;
ApplicationListModel *applicationListModel();
Q_INVOKABLE void stackBefore(QQuickItem *item1, QQuickItem *item2);
Q_INVOKABLE void stackAfter(QQuickItem *item1, QQuickItem *item2);
@ -33,7 +31,6 @@ protected:
// void configChanged() override;
private:
ApplicationListModel *m_applicationListModel = nullptr;
bool m_showAllApps = false;
};

View file

@ -14,14 +14,9 @@ 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
//TODO: everything using this will eventually move in Launcher
import "launcher/private" as LauncherPrivate
import org.kde.plasma.private.mobilehomescreencomponents 0.1 as HomeScreenComponents
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
import org.kde.phone.homescreen 1.0
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
FocusScope {
@ -38,16 +33,20 @@ FocusScope {
return;
}
plasmoid.nativeInterface.applicationListModel.maxFavoriteCount = Math.max(4, Math.floor(Math.min(width, height) / homeScreenContents.appletsLayout.cellWidth));
HomeScreenComponents.ApplicationListModel.maxFavoriteCount = Math.max(4, Math.floor(Math.min(width, height) / homeScreenContents.appletsLayout.cellWidth));
}
//END functions
property bool componentComplete: false
onWidthChanged: recalculateMaxFavoriteCount()
onHeightChanged:recalculateMaxFavoriteCount()
Component.onCompleted: {
// ApplicationListModel doesn't have a plasmoid as is not the one that should be doing writing
HomeScreenComponents.ApplicationListModel.loadApplications();
HomeScreenComponents.FavoritesModel.applet = plasmoid;
HomeScreenComponents.FavoritesModel.loadApplications();
if (plasmoid.screen == 0) {
MobileShell.HomeScreenControls.homeScreen = root
MobileShell.HomeScreenControls.homeScreenWindow = root.Window.window
@ -88,15 +87,7 @@ FocusScope {
}
}
Launcher.LauncherDragManager {
id: launcherDragManager
anchors.fill: parent
z: 2
appletsLayout: homeScreenContents.appletsLayout
favoriteStrip: favoriteStrip
}
Launcher.FlickablePages {
HomeScreenComponents.FlickablePages {
id: mainFlickable
anchors {
@ -110,17 +101,19 @@ FocusScope {
appletsLayout: homeScreenContents.appletsLayout
appDrawer: appDrawer
contentWidth: Math.max(width, width * Math.ceil(homeScreenContents.itemsBoundingRect.width/width)) + (launcherDragManager.active ? width : 0)
showAddPageIndicator: launcherDragManager.active
contentWidth: Math.max(width, width * Math.ceil(homeScreenContents.itemsBoundingRect.width/width)) + (homeScreenContents.launcherDragManager.active ? width : 0)
showAddPageIndicator: homeScreenContents.launcherDragManager.active
Launcher.HomeScreenContents {
dragGestureEnabled: root.focus && appDrawer.status !== HomeScreenComponents.AppDrawer.Status.Open && !appletsLayout.editMode && !plasmoid.editMode && !homeScreenContents.launcherDragManager.active
HomeScreenComponents.HomeScreenContents {
id: homeScreenContents
width: mainFlickable.width * 100
favoriteStrip: favoriteStrip
}
}
Launcher.AppDrawer {
HomeScreenComponents.AppDrawer {
id: appDrawer
anchors.fill: parent
@ -129,20 +122,15 @@ FocusScope {
closedPositionOffset: favoriteStrip.height
}
Launcher.FavoriteStrip {
HomeScreenComponents.FavoriteStrip {
id: favoriteStrip
appletsLayout: homeScreenContents.appletsLayout
visible: flow.children.length > 0 || launcherDragManager.active || homeScreenContents.containsDrag
visible: flow.children.length > 0 || homeScreenContents.launcherDragManager.active || homeScreenContents.containsDrag
opacity: homeScreenContents.launcherDragManager.active && HomeScreenComponents.ApplicationListModel.favoriteCount >= HomeScreenComponents.ApplicationListModel.maxFavoriteCount ? 0.3 : 1
LauncherPrivate.DragGestureHandler {
target: favoriteStrip
appDrawer: appDrawer
mainFlickable: mainFlickable
enabled: root.focus && appDrawer.status !== Launcher.AppDrawer.Status.Open && !homeScreenContents.appletsLayout.editMode && !plasmoid.editMode && !launcherDragManager.active
onSnapPage: mainFlickable.snapPage();
}
TapHandler {
target: favoriteStrip
onTapped: {