mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
prototype for a new homescreen containment
This commit is contained in:
parent
9d8b2f8daf
commit
8f8a23c6ea
12 changed files with 945 additions and 0 deletions
|
|
@ -1,4 +1,5 @@
|
|||
|
||||
add_subdirectory(panel)
|
||||
add_subdirectory(homescreen)
|
||||
add_subdirectory(homescreen2)
|
||||
add_subdirectory(taskpanel)
|
||||
|
|
|
|||
23
containments/homescreen2/CMakeLists.txt
Normal file
23
containments/homescreen2/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
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
|
||||
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)
|
||||
|
||||
4
containments/homescreen2/Messages.sh
Executable file
4
containments/homescreen2/Messages.sh
Executable file
|
|
@ -0,0 +1,4 @@
|
|||
#! /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
|
||||
273
containments/homescreen2/applicationlistmodel.cpp
Normal file
273
containments/homescreen2/applicationlistmodel.cpp
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
/*
|
||||
* Copyright (C) 2014 Antonis Tsiapaliokas <antonis.tsiapaliokas@kde.org>
|
||||
*
|
||||
* 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 <QByteArray>
|
||||
#include <QModelIndex>
|
||||
#include <QProcess>
|
||||
|
||||
// KDE
|
||||
#include <KPluginInfo>
|
||||
#include <KService>
|
||||
#include <KServiceGroup>
|
||||
#include <KServiceTypeTrader>
|
||||
#include <KSharedConfig>
|
||||
#include <KSycoca>
|
||||
#include <KSycocaEntry>
|
||||
#include <KShell>
|
||||
#include <KIOWidgets/KRun>
|
||||
#include <QDebug>
|
||||
|
||||
ApplicationListModel::ApplicationListModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
//can't use the new syntax as this signal is overloaded
|
||||
connect(KSycoca::self(), SIGNAL(databaseChanged(const QStringList &)),
|
||||
this, SLOT(sycocaDbChanged(const QStringList &)));
|
||||
}
|
||||
|
||||
ApplicationListModel::~ApplicationListModel()
|
||||
= default;
|
||||
|
||||
QHash<int, QByteArray> ApplicationListModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roleNames;
|
||||
roleNames[ApplicationNameRole] = "ApplicationNameRole";
|
||||
roleNames[ApplicationIconRole] = "ApplicationIconRole";
|
||||
roleNames[ApplicationStorageIdRole] = "ApplicationStorageIdRole";
|
||||
roleNames[ApplicationEntryPathRole] = "ApplicationEntryPathRole";
|
||||
roleNames[ApplicationOriginalRowRole] = "ApplicationOriginalRowRole";
|
||||
|
||||
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<int, ApplicationData> orderedList;
|
||||
QList<ApplicationData> 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<KServiceGroup* >(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<KServiceGroup* >(entry.data()));
|
||||
subGroupList << serviceGroup;
|
||||
|
||||
} else if (entry->property("Exec").isValid()) {
|
||||
KService::Ptr service(static_cast<KService* >(entry.data()));
|
||||
|
||||
qDebug() << " desktopEntryName: " << service->desktopEntryName();
|
||||
|
||||
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();
|
||||
|
||||
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();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
Q_INVOKABLE 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;
|
||||
}
|
||||
|
||||
|
||||
emit appOrderChanged();
|
||||
endMoveRows();
|
||||
}
|
||||
|
||||
void ApplicationListModel::runApplication(const QString &storageId)
|
||||
{
|
||||
if (storageId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
KService::Ptr service = KService::serviceByStorageId(storageId);
|
||||
|
||||
KRun::runService(*service, QList<QUrl>(), nullptr);
|
||||
}
|
||||
|
||||
QStringList ApplicationListModel::appOrder() const
|
||||
{
|
||||
return m_appOrder;
|
||||
}
|
||||
|
||||
void ApplicationListModel::setAppOrder(const QStringList &order)
|
||||
{
|
||||
if (m_appOrder == order) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_appOrder = order;
|
||||
m_appPositions.clear();
|
||||
int i = 0;
|
||||
for (auto app : m_appOrder) {
|
||||
m_appPositions[app] = i;
|
||||
++i;
|
||||
}
|
||||
emit appOrderChanged();
|
||||
}
|
||||
90
containments/homescreen2/applicationlistmodel.h
Normal file
90
containments/homescreen2/applicationlistmodel.h
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (C) 2014 Antonis Tsiapaliokas <antonis.tsiapaliokas@kde.org>
|
||||
*
|
||||
* 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 <QObject>
|
||||
#include <QAbstractListModel>
|
||||
#include <QList>
|
||||
|
||||
class QString;
|
||||
|
||||
struct ApplicationData {
|
||||
QString name;
|
||||
QString icon;
|
||||
QString storageId;
|
||||
QString entryPath;
|
||||
};
|
||||
|
||||
class ApplicationListModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(int count READ count NOTIFY countChanged)
|
||||
Q_PROPERTY(QStringList appOrder READ appOrder WRITE setAppOrder NOTIFY appOrderChanged)
|
||||
|
||||
public:
|
||||
ApplicationListModel(QObject *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(); }
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
|
||||
QHash<int, QByteArray> 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 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 appOrderChanged();
|
||||
|
||||
private:
|
||||
QList<ApplicationData> m_applicationList;
|
||||
|
||||
QStringList m_appOrder;
|
||||
QHash<QString, int> m_appPositions;
|
||||
};
|
||||
|
||||
#endif // APPLICATIONLISTMODEL_H
|
||||
44
containments/homescreen2/homescreen.cpp
Normal file
44
containments/homescreen2/homescreen.cpp
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2015 Marco Martin <mart@kde.org> *
|
||||
* *
|
||||
* 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 <QtQml>
|
||||
#include <QDebug>
|
||||
|
||||
HomeScreen::HomeScreen(QObject *parent, const QVariantList &args)
|
||||
: Plasma::Containment(parent, args)
|
||||
{
|
||||
qmlRegisterType<ApplicationListModel>();
|
||||
m_applicationListModel = new ApplicationListModel(this);
|
||||
setHasConfigurationInterface(true);
|
||||
}
|
||||
|
||||
HomeScreen::~HomeScreen()
|
||||
= default;
|
||||
|
||||
ApplicationListModel *HomeScreen::applicationListModel()
|
||||
{
|
||||
return m_applicationListModel;
|
||||
}
|
||||
|
||||
K_EXPORT_PLASMA_APPLET_WITH_JSON(homescreen, HomeScreen, "metadata.json")
|
||||
|
||||
#include "homescreen.moc"
|
||||
45
containments/homescreen2/homescreen.h
Normal file
45
containments/homescreen2/homescreen.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2015 Marco Martin <mart@kde.org> *
|
||||
*
|
||||
* *
|
||||
* 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 <Plasma/Containment>
|
||||
|
||||
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();
|
||||
|
||||
private:
|
||||
ApplicationListModel *m_applicationListModel;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
17
containments/homescreen2/package/contents/config/main.xml
Normal file
17
containments/homescreen2/package/contents/config/main.xml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
|
||||
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
|
||||
<kcfgfile name=""/>
|
||||
|
||||
<group name="General">
|
||||
<entry name="ItemsGeometries" type="String" hidden="true">
|
||||
<label>Encoded geometries of items (resource categories).</label>
|
||||
</entry>
|
||||
<entry name="VerticalItemsGeometries" type="String" hidden="true">
|
||||
<label>Encoded geometries of items, vertical screen (resource categories).</label>
|
||||
</entry>
|
||||
</group>
|
||||
|
||||
</kcfg>
|
||||
148
containments/homescreen2/package/contents/ui/ActionButton.qml
Normal file
148
containments/homescreen2/package/contents/ui/ActionButton.qml
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright 2011 Marco Martin <mart@kde.org>
|
||||
* Copyright 2013 Sebastian Kügler <sebas@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.
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||
|
||||
PlasmaCore.ToolTipArea {
|
||||
id: button
|
||||
|
||||
location: PlasmaCore.Types.LeftEdge
|
||||
mainText: action !== undefined ? action.text : ""
|
||||
mainItem: toolTipDelegate
|
||||
|
||||
//API
|
||||
property PlasmaCore.Svg svg
|
||||
property alias elementId: icon.elementId
|
||||
property QtObject action
|
||||
property bool backgroundVisible: false
|
||||
property int iconSize: 32
|
||||
property int pressedOffset: 1
|
||||
property bool checked: false
|
||||
property bool toggle: false
|
||||
property string text
|
||||
signal clicked
|
||||
|
||||
implicitWidth: buttonRow.implicitWidth
|
||||
implicitHeight: buttonRow.implicitHeight
|
||||
|
||||
opacity: action==undefined||action.enabled?1:0.6
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
|
||||
onCheckedChanged: {
|
||||
if (checked) {
|
||||
buttonItem.elementId = "pressed"
|
||||
shadowItem.opacity = 0
|
||||
} else {
|
||||
buttonItem.elementId = "normal"
|
||||
shadowItem.opacity = 1
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaCore.Svg {
|
||||
id: buttonSvg
|
||||
imagePath: "widgets/actionbutton"
|
||||
}
|
||||
|
||||
PlasmaCore.SvgItem {
|
||||
id: shadowItem
|
||||
svg: buttonSvg
|
||||
elementId: "shadow"
|
||||
width: iconSize+13//button.backgroundVisible?iconSize+8:iconSize
|
||||
height: width
|
||||
visible: button.backgroundVisible
|
||||
}
|
||||
|
||||
Row {
|
||||
id: buttonRow
|
||||
|
||||
Item {
|
||||
width: buttonItem.visible?buttonItem.width:iconSize
|
||||
height: buttonItem.visible?buttonItem.height:iconSize
|
||||
|
||||
PlasmaCore.SvgItem {
|
||||
id: buttonItem
|
||||
svg: buttonSvg
|
||||
elementId: "normal"
|
||||
width: shadowItem.width
|
||||
height: shadowItem.height
|
||||
visible: backgroundVisible
|
||||
}
|
||||
|
||||
PlasmaCore.SvgItem {
|
||||
id: icon
|
||||
width: iconSize
|
||||
height: iconSize
|
||||
svg: button.svg
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: actionText
|
||||
text: button.text
|
||||
style: Text.Outline
|
||||
color: theme.textColor
|
||||
styleColor: Qt.rgba(1,1,1,0.4)
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: -10
|
||||
anchors.topMargin: -10
|
||||
anchors.rightMargin: -10
|
||||
anchors.bottomMargin: -10
|
||||
preventStealing: true
|
||||
onPressed: {
|
||||
buttonItem.elementId = "pressed"
|
||||
shadowItem.opacity = 0;
|
||||
button.x = button.x + button.pressedOffset;
|
||||
button.y = button.y + button.pressedOffset;
|
||||
}
|
||||
onReleased: {
|
||||
if (button.checked || !button.toggle) {
|
||||
buttonItem.elementId = "normal"
|
||||
shadowItem.opacity = 1
|
||||
button.checked = false
|
||||
} else {
|
||||
button.checked = true
|
||||
}
|
||||
button.x = button.x - button.pressedOffset;
|
||||
button.y = button.y - button.pressedOffset;
|
||||
}
|
||||
onClicked: {
|
||||
if (action) {
|
||||
action.trigger()
|
||||
} else {
|
||||
button.clicked()
|
||||
}
|
||||
appletContainer.editMode = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
129
containments/homescreen2/package/contents/ui/ConfigOverlay.qml
Normal file
129
containments/homescreen2/package/contents/ui/ConfigOverlay.qml
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright 2019 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.
|
||||
*/
|
||||
|
||||
import QtQuick 2.12
|
||||
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 3.0 as PlasmaComponents
|
||||
|
||||
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
|
||||
|
||||
ContainmentLayoutManager.ConfigOverlayWithHandles {
|
||||
id: overlay
|
||||
|
||||
readonly property int iconSize: units.iconSizes.small
|
||||
PlasmaCore.Svg {
|
||||
id: configIconsSvg
|
||||
imagePath: "widgets/configuration-icons"
|
||||
}
|
||||
|
||||
PlasmaComponents.Label {
|
||||
id: toolTipDelegate
|
||||
|
||||
width: contentWidth
|
||||
height: undefined
|
||||
|
||||
property Item toolTip
|
||||
|
||||
text: (toolTip != null) ? toolTip.mainText : ""
|
||||
}
|
||||
|
||||
SequentialAnimation {
|
||||
id: removeAnim
|
||||
NumberAnimation {
|
||||
target: overlay.itemContainer
|
||||
property: "scale"
|
||||
from: 1
|
||||
to: 0
|
||||
duration: units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
ScriptAction {
|
||||
script: {
|
||||
appletContainer.applet.action("remove").trigger();
|
||||
appletContainer.editMode = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: frame
|
||||
anchors.centerIn: parent
|
||||
|
||||
width: layout.implicitWidth + margins.left + margins.right
|
||||
height: layout.implicitHeight + margins.top + margins.bottom
|
||||
imagePath: "widgets/background"
|
||||
|
||||
RowLayout {
|
||||
id: layout
|
||||
spacing: units.largeSpacing
|
||||
anchors {
|
||||
fill: parent
|
||||
topMargin: parent.margins.top
|
||||
leftMargin: parent.margins.left
|
||||
bottomMargin: parent.margins.bottom
|
||||
rightMargin: parent.margins.right
|
||||
}
|
||||
|
||||
ActionButton {
|
||||
svg: configIconsSvg
|
||||
elementId: "configure"
|
||||
iconSize: overlay.iconSize
|
||||
visible: (action && typeof(action) != "undefined") ? action.enabled : false
|
||||
action: (applet) ? applet.action("configure") : null
|
||||
Component.onCompleted: {
|
||||
if (action && typeof(action) != "undefined") {
|
||||
action.enabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ActionButton {
|
||||
id: closeButton
|
||||
svg: configIconsSvg
|
||||
elementId: "delete"
|
||||
mainText: i18n("Remove")
|
||||
iconSize: overlay.iconSize
|
||||
visible: {
|
||||
if (!applet) {
|
||||
return false;
|
||||
}
|
||||
var a = applet.action("remove");
|
||||
return (a && typeof(a) != "undefined") ? a.enabled : false;
|
||||
}
|
||||
// we don't set action, since we want to catch the button click,
|
||||
// animate, and then trigger the "remove" action
|
||||
// Triggering the action is handled in the overlay.itemContainer, we just
|
||||
// emit a signal here to avoid the applet-gets-removed-before-we-
|
||||
// can-animate it race condition.
|
||||
onClicked: {
|
||||
removeAnim.restart();
|
||||
}
|
||||
Component.onCompleted: {
|
||||
var a = applet.action("remove");
|
||||
if (a && typeof(a) != "undefined") {
|
||||
a.enabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
134
containments/homescreen2/package/contents/ui/main.qml
Normal file
134
containments/homescreen2/package/contents/ui/main.qml
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* Copyright 2019 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.
|
||||
*/
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Controls 2.2 as Controls
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.draganddrop 2.0 as DragDrop
|
||||
|
||||
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
|
||||
|
||||
Item {
|
||||
id: root
|
||||
width: 640
|
||||
height: 480
|
||||
|
||||
property Item toolBox
|
||||
|
||||
DragDrop.DropArea {
|
||||
anchors.fill: parent
|
||||
|
||||
//TODO type safety?
|
||||
property Item appletsArea
|
||||
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();
|
||||
}
|
||||
|
||||
Text {
|
||||
text:"Edit Mode"
|
||||
color: "white"
|
||||
visible: appletsLayout.editMode
|
||||
}
|
||||
Connections {
|
||||
target: plasmoid
|
||||
onEditModeChanged: appletsLayout.editMode = plasmoid.editMode
|
||||
}
|
||||
|
||||
ContainmentLayoutManager.AppletsLayout {
|
||||
id: appletsLayout
|
||||
anchors.fill: parent
|
||||
configKey: width > height ? "ItemGeometries" : "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 {}
|
||||
}
|
||||
|
||||
placeHolder: ContainmentLayoutManager.PlaceHolder {}
|
||||
|
||||
Repeater {
|
||||
model: 3
|
||||
ContainmentLayoutManager.ItemContainer {
|
||||
id: extraIcon
|
||||
key: "Icon-" + modelData
|
||||
preferredLayoutDirection: editMode ? ContainmentLayoutManager.AppletsLayout.Closest : ContainmentLayoutManager.AppletsLayout.TopToBottom
|
||||
x: 16
|
||||
y: 16
|
||||
implicitWidth: 48
|
||||
implicitHeight: 48
|
||||
|
||||
editModeCondition: ContainmentLayoutManager.ItemContainer.AfterPress
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: extraIcon.focus ? "green" : "red"
|
||||
radius: width
|
||||
opacity: extraIcon.editMode ? 0.6 : 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
37
containments/homescreen2/package/metadata.desktop
Normal file
37
containments/homescreen2/package/metadata.desktop
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
[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
|
||||
Loading…
Reference in a new issue