mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
homescreens/halcyon: Add new homescreen
This commit is contained in:
parent
b9f9066880
commit
a173cf9b9d
13 changed files with 752 additions and 0 deletions
|
|
@ -213,4 +213,12 @@ Item {
|
||||||
z: 999999
|
z: 999999
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// listen to app launch errors
|
||||||
|
Connections {
|
||||||
|
target: MobileShell.ApplicationListModel
|
||||||
|
function onLaunchError(msg) {
|
||||||
|
MobileShell.HomeScreenControls.closeAppLaunchAnimation()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,4 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
add_subdirectory(default)
|
add_subdirectory(default)
|
||||||
|
add_subdirectory(halcyon)
|
||||||
|
|
|
||||||
27
containments/homescreens/halcyon/CMakeLists.txt
Normal file
27
containments/homescreens/halcyon/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
# SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
set(homescreen_SRCS
|
||||||
|
homescreen.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(plasma_containment_phone_homescreen_halcyon MODULE ${homescreen_SRCS})
|
||||||
|
|
||||||
|
kcoreaddons_desktop_to_json(plasma_containment_phone_homescreen_halcyon package/metadata.desktop)
|
||||||
|
|
||||||
|
target_link_libraries(plasma_containment_phone_homescreen_halcyon
|
||||||
|
Qt::Gui
|
||||||
|
KF5::Plasma
|
||||||
|
Qt::Qml
|
||||||
|
Qt::Quick
|
||||||
|
KF5::I18n
|
||||||
|
KF5::Service
|
||||||
|
KF5::KIOGui
|
||||||
|
KF5::Notifications
|
||||||
|
KF5::WaylandClient
|
||||||
|
KF5::WindowSystem
|
||||||
|
)
|
||||||
|
|
||||||
|
install(TARGETS plasma_containment_phone_homescreen_halcyon DESTINATION ${KDE_INSTALL_PLUGINDIR}/plasma/applets)
|
||||||
|
|
||||||
|
plasma_install_package(package org.kde.phone.homescreen.halcyon)
|
||||||
9
containments/homescreens/halcyon/Messages.sh
Normal file
9
containments/homescreens/halcyon/Messages.sh
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
#! /usr/bin/env bash
|
||||||
|
|
||||||
|
# SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
$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.simple.pot
|
||||||
|
rm -f rc.cpp
|
||||||
|
|
||||||
2
containments/homescreens/halcyon/homescreen.cpp
Normal file
2
containments/homescreens/halcyon/homescreen.cpp
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
2
containments/homescreens/halcyon/homescreen.h
Normal file
2
containments/homescreens/halcyon/homescreen.h
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import QtGraphicalEffects 1.12
|
||||||
|
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
|
||||||
|
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property bool softwareRendering: GraphicsInfo.api === GraphicsInfo.Software
|
||||||
|
readonly property bool is24HourTime: MobileShell.ShellUtil.isSystem24HourFormat
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: Qt.formatTime(timeSource.data["Local"]["DateTime"], root.is24HourTime ? "h:mm" : "h:mm ap")
|
||||||
|
color: "white"
|
||||||
|
style: softwareRendering ? Text.Outline : Text.Normal
|
||||||
|
styleColor: softwareRendering ? ColorScope.backgroundColor : "transparent" // no outline, doesn't matter
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
font.weight: Font.Bold // this font weight may switch to regular on distros that don't have a light variant
|
||||||
|
font.pointSize: 28
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: DropShadow {
|
||||||
|
verticalOffset: 1
|
||||||
|
radius: 4
|
||||||
|
samples: 6
|
||||||
|
color: Qt.rgba(0, 0, 0, 0.5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.topMargin: PlasmaCore.Units.smallSpacing
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
text: Qt.formatDate(timeSource.data["Local"]["DateTime"], "ddd, MMM d")
|
||||||
|
color: "white"
|
||||||
|
style: softwareRendering ? Text.Outline : Text.Normal
|
||||||
|
styleColor: softwareRendering ? ColorScope.backgroundColor : "transparent" // no outline, doesn't matter
|
||||||
|
|
||||||
|
font.pointSize: 12
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: DropShadow {
|
||||||
|
verticalOffset: 1
|
||||||
|
radius: 4
|
||||||
|
samples: 6
|
||||||
|
color: Qt.rgba(0, 0, 0, 0.5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaCore.DataSource {
|
||||||
|
id: timeSource
|
||||||
|
engine: "time"
|
||||||
|
connectedSources: ["Local"]
|
||||||
|
interval: 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,153 @@
|
||||||
|
// SPDX-FileCopyrightText: 2022 Devin Lin <espidev@gmail.com>
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
import QtQuick 2.4
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
import QtQuick.Controls 2.3 as Controls
|
||||||
|
import QtGraphicalEffects 1.6
|
||||||
|
|
||||||
|
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.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.kirigami 2.19 as Kirigami
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: delegate
|
||||||
|
property alias iconItem: icon
|
||||||
|
|
||||||
|
signal launch(int x, int y, var source, string title, string storageId)
|
||||||
|
signal dragStarted(string imageSource, int x, int y, string mimeData)
|
||||||
|
|
||||||
|
onLaunch: {
|
||||||
|
if (icon !== "") {
|
||||||
|
MobileShell.HomeScreenControls.openAppLaunchAnimation(
|
||||||
|
icon,
|
||||||
|
title,
|
||||||
|
delegate.iconItem.Kirigami.ScenePosition.x + delegate.iconItem.width/2,
|
||||||
|
delegate.iconItem.Kirigami.ScenePosition.y + delegate.iconItem.height/2,
|
||||||
|
Math.min(delegate.iconItem.width, delegate.iconItem.height));
|
||||||
|
}
|
||||||
|
|
||||||
|
MobileShell.ApplicationListModel.setMinimizedDelegate(index, delegate);
|
||||||
|
MobileShell.ApplicationListModel.runApplication(storageId);
|
||||||
|
}
|
||||||
|
|
||||||
|
onPressAndHold: {
|
||||||
|
dialogLoader.active = true;
|
||||||
|
dialogLoader.item.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
// launch app
|
||||||
|
if (model.applicationRunning) {
|
||||||
|
delegate.launch(0, 0, "", model.applicationName, model.applicationStorageId);
|
||||||
|
} else {
|
||||||
|
delegate.launch(delegate.x + (PlasmaCore.Units.smallSpacing * 2), delegate.y + (PlasmaCore.Units.smallSpacing * 2), icon.source, model.applicationName, model.applicationStorageId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: dialogLoader
|
||||||
|
active: false
|
||||||
|
|
||||||
|
sourceComponent: PlasmaComponents.Menu {
|
||||||
|
title: label.text
|
||||||
|
|
||||||
|
PlasmaComponents.MenuItem {
|
||||||
|
icon.name: "emblem-favorite"
|
||||||
|
text: i18n("Remove from favourites")
|
||||||
|
onClicked: {
|
||||||
|
MobileShell.FavoritesModel.removeFavorite(model.index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClosed: dialogLoader.active = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
radius: height / 2
|
||||||
|
|
||||||
|
color: delegate.pressed ? Qt.rgba(255, 255, 255, 0.2) : (delegate.containsMouse ? Qt.rgba(255, 255, 255, 0.1) : "transparent")
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
leftMargin: PlasmaCore.Units.smallSpacing * 2
|
||||||
|
topMargin: PlasmaCore.Units.smallSpacing
|
||||||
|
rightMargin: PlasmaCore.Units.smallSpacing * 2
|
||||||
|
bottomMargin: PlasmaCore.Units.smallSpacing
|
||||||
|
}
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
PlasmaCore.IconItem {
|
||||||
|
id: icon
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignLeft
|
||||||
|
Layout.minimumWidth: Layout.minimumHeight
|
||||||
|
Layout.preferredWidth: Layout.minimumHeight
|
||||||
|
Layout.minimumHeight: parent.height
|
||||||
|
Layout.preferredHeight: Layout.minimumHeight
|
||||||
|
|
||||||
|
usesPlasmaTheme: false
|
||||||
|
source: model.applicationIcon
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
bottom: parent.bottom
|
||||||
|
}
|
||||||
|
visible: model.applicationRunning
|
||||||
|
radius: width
|
||||||
|
width: PlasmaCore.Units.smallSpacing
|
||||||
|
height: width
|
||||||
|
color: PlasmaCore.Theme.highlightColor
|
||||||
|
}
|
||||||
|
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: DropShadow {
|
||||||
|
verticalOffset: 1
|
||||||
|
radius: 4
|
||||||
|
samples: 6
|
||||||
|
color: Qt.rgba(0, 0, 0, 0.5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaComponents.Label {
|
||||||
|
id: label
|
||||||
|
visible: text.length > 0
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: PlasmaCore.Units.smallSpacing * 2
|
||||||
|
Layout.rightMargin: PlasmaCore.Units.largeSpacing
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
maximumLineCount: 1
|
||||||
|
elide: Text.ElideRight
|
||||||
|
|
||||||
|
text: model.applicationName
|
||||||
|
|
||||||
|
font.pointSize: PlasmaCore.Theme.defaultFont.pointSize
|
||||||
|
font.weight: Font.Bold
|
||||||
|
color: "white"
|
||||||
|
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: DropShadow {
|
||||||
|
verticalOffset: 1
|
||||||
|
radius: 4
|
||||||
|
samples: 6
|
||||||
|
color: Qt.rgba(0, 0, 0, 0.5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,173 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
import QtQuick.Controls 2.15 as Controls
|
||||||
|
import QtGraphicalEffects 1.6
|
||||||
|
|
||||||
|
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.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.kirigami 2.19 as Kirigami
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: delegate
|
||||||
|
width: GridView.view.cellWidth
|
||||||
|
height: GridView.view.cellHeight
|
||||||
|
|
||||||
|
property int reservedSpaceForLabel
|
||||||
|
property alias iconItem: icon
|
||||||
|
|
||||||
|
readonly property real margins: Math.floor(width * 0.2)
|
||||||
|
|
||||||
|
signal launch(int x, int y, var source, string title, string storageId)
|
||||||
|
|
||||||
|
onPressAndHold: {
|
||||||
|
dialogLoader.active = true;
|
||||||
|
dialogLoader.item.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
function launchApp() {
|
||||||
|
// launch app
|
||||||
|
if (model.applicationRunning) {
|
||||||
|
delegate.launch(0, 0, "", model.applicationName, model.applicationStorageId);
|
||||||
|
} else {
|
||||||
|
delegate.launch(delegate.x + (PlasmaCore.Units.smallSpacing * 2), delegate.y + (PlasmaCore.Units.smallSpacing * 2), icon.source, model.applicationName, model.applicationStorageId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: dialogLoader
|
||||||
|
active: false
|
||||||
|
|
||||||
|
sourceComponent: PlasmaComponents.Menu {
|
||||||
|
title: label.text
|
||||||
|
|
||||||
|
PlasmaComponents.MenuItem {
|
||||||
|
icon.name: "emblem-favorite"
|
||||||
|
text: i18n("Add to favourites")
|
||||||
|
onClicked: {
|
||||||
|
MobileShell.FavoritesModel.addFavorite(model.applicationStorageId, 0, MobileShell.ApplicationListModel.Favorites);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClosed: dialogLoader.active = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// grow/shrink animation
|
||||||
|
property real zoomScale: 1
|
||||||
|
transform: Scale {
|
||||||
|
origin.x: delegate.width / 2;
|
||||||
|
origin.y: delegate.height / 2;
|
||||||
|
xScale: delegate.zoomScale
|
||||||
|
yScale: delegate.zoomScale
|
||||||
|
}
|
||||||
|
|
||||||
|
property bool launchAppRequested: false
|
||||||
|
|
||||||
|
NumberAnimation on zoomScale {
|
||||||
|
id: shrinkAnim
|
||||||
|
running: false
|
||||||
|
duration: MobileShell.MobileShellSettings.animationsEnabled ? 80 : 1
|
||||||
|
to: MobileShell.MobileShellSettings.animationsEnabled ? 0.8 : 1
|
||||||
|
onFinished: {
|
||||||
|
if (!delegate.pressed) {
|
||||||
|
growAnim.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberAnimation on zoomScale {
|
||||||
|
id: growAnim
|
||||||
|
running: false
|
||||||
|
duration: MobileShell.MobileShellSettings.animationsEnabled ? 80 : 1
|
||||||
|
to: 1
|
||||||
|
onFinished: {
|
||||||
|
if (delegate.launchAppRequested) {
|
||||||
|
delegate.launchApp();
|
||||||
|
delegate.launchAppRequested = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
hoverEnabled: true
|
||||||
|
onPressedChanged: {
|
||||||
|
if (pressed) {
|
||||||
|
growAnim.stop();
|
||||||
|
shrinkAnim.restart();
|
||||||
|
} else if (!pressed && !shrinkAnim.running) {
|
||||||
|
growAnim.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// launch app handled by press animation
|
||||||
|
onClicked: launchAppRequested = true;
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
leftMargin: margins
|
||||||
|
topMargin: margins
|
||||||
|
rightMargin: margins
|
||||||
|
bottomMargin: margins
|
||||||
|
}
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
PlasmaCore.IconItem {
|
||||||
|
id: icon
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.minimumHeight: Math.floor(parent.height - delegate.reservedSpaceForLabel)
|
||||||
|
Layout.preferredHeight: Layout.minimumHeight
|
||||||
|
|
||||||
|
usesPlasmaTheme: false
|
||||||
|
source: model.applicationIcon
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
bottom: parent.bottom
|
||||||
|
}
|
||||||
|
visible: model.applicationRunning
|
||||||
|
radius: width
|
||||||
|
width: PlasmaCore.Units.smallSpacing
|
||||||
|
height: width
|
||||||
|
color: theme.highlightColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaComponents.Label {
|
||||||
|
id: label
|
||||||
|
visible: text.length > 0
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: PlasmaCore.Units.smallSpacing
|
||||||
|
Layout.preferredHeight: delegate.reservedSpaceForLabel
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
Layout.leftMargin: -parent.anchors.leftMargin + PlasmaCore.Units.smallSpacing
|
||||||
|
Layout.rightMargin: -parent.anchors.rightMargin + PlasmaCore.Units.smallSpacing
|
||||||
|
maximumLineCount: 2
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignTop
|
||||||
|
elide: Text.ElideRight
|
||||||
|
|
||||||
|
text: model.applicationName
|
||||||
|
|
||||||
|
font.pointSize: theme.defaultFont.pointSize * 0.85
|
||||||
|
font.weight: Font.Bold
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com>
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
import QtQuick.Controls 2.15 as Controls
|
||||||
|
|
||||||
|
import org.kde.plasma.plasmoid 2.0
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
import org.kde.plasma.components 3.0 as PC3
|
||||||
|
import org.kde.plasma.extras 2.0 as PlasmaExtras
|
||||||
|
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
|
||||||
|
|
||||||
|
GridView {
|
||||||
|
id: gridView
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
signal launched
|
||||||
|
|
||||||
|
readonly property int reservedSpaceForLabel: metrics.height
|
||||||
|
|
||||||
|
cellWidth: width / Math.min(Math.floor(width / (PlasmaCore.Units.iconSizes.huge + Kirigami.Units.largeSpacing * 2)), 8)
|
||||||
|
cellHeight: cellWidth + reservedSpaceForLabel
|
||||||
|
|
||||||
|
property int columns: Math.floor(width / cellWidth)
|
||||||
|
property int rows: Math.ceil(model.count / columns)
|
||||||
|
|
||||||
|
cacheBuffer: Math.max(0, rows * cellHeight)
|
||||||
|
|
||||||
|
model: MobileShell.ApplicationListModel
|
||||||
|
|
||||||
|
header: Controls.Control {
|
||||||
|
implicitWidth: gridView.width
|
||||||
|
topPadding: PlasmaCore.Units.largeSpacing
|
||||||
|
bottomPadding: PlasmaCore.Units.largeSpacing
|
||||||
|
leftPadding: PlasmaCore.Units.smallSpacing
|
||||||
|
|
||||||
|
contentItem: PlasmaExtras.Heading {
|
||||||
|
color: "white"
|
||||||
|
level: 1
|
||||||
|
font.weight: Font.Bold
|
||||||
|
text: i18n("Applications")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PC3.Label {
|
||||||
|
id: metrics
|
||||||
|
text: "M\nM"
|
||||||
|
visible: false
|
||||||
|
font.pointSize: PlasmaCore.Theme.defaultFont.pointSize * 0.85
|
||||||
|
font.weight: Font.Bold
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: GridAppDelegate {
|
||||||
|
id: delegate
|
||||||
|
|
||||||
|
width: gridView.cellWidth
|
||||||
|
height: gridView.cellHeight
|
||||||
|
reservedSpaceForLabel: gridView.reservedSpaceForLabel
|
||||||
|
|
||||||
|
onLaunch: (x, y, icon, title, storageId) => {
|
||||||
|
if (icon !== "") {
|
||||||
|
MobileShell.HomeScreenControls.openAppLaunchAnimation(
|
||||||
|
icon,
|
||||||
|
title,
|
||||||
|
delegate.iconItem.Kirigami.ScenePosition.x + delegate.iconItem.width/2,
|
||||||
|
delegate.iconItem.Kirigami.ScenePosition.y + delegate.iconItem.height/2,
|
||||||
|
Math.min(delegate.iconItem.width, delegate.iconItem.height));
|
||||||
|
}
|
||||||
|
|
||||||
|
MobileShell.ApplicationListModel.setMinimizedDelegate(index, delegate);
|
||||||
|
MobileShell.ApplicationListModel.runApplication(storageId);
|
||||||
|
gridView.launched();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,134 @@
|
||||||
|
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
|
||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Controls 2.15 as QQC2
|
||||||
|
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.extras 2.0 as PlasmaExtras
|
||||||
|
import org.kde.plasma.components 3.0 as PC3
|
||||||
|
import org.kde.draganddrop 2.0 as DragDrop
|
||||||
|
|
||||||
|
import org.kde.kirigami 2.19 as Kirigami
|
||||||
|
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool interactive: true
|
||||||
|
property var searchWidget
|
||||||
|
|
||||||
|
property alias page: swipeView.currentIndex
|
||||||
|
|
||||||
|
function triggerHomescreen() {
|
||||||
|
swipeView.setCurrentIndex(0);
|
||||||
|
favouritesList.contentY = favouritesList.originY;
|
||||||
|
}
|
||||||
|
|
||||||
|
QQC2.SwipeView {
|
||||||
|
id: swipeView
|
||||||
|
opacity: 1 - searchWidget.openFactor
|
||||||
|
interactive: root.interactive
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.topMargin: MobileShell.Shell.topMargin
|
||||||
|
anchors.bottomMargin: MobileShell.Shell.bottomMargin
|
||||||
|
anchors.leftMargin: MobileShell.Shell.leftMargin
|
||||||
|
anchors.rightMargin: MobileShell.Shell.rightMargin
|
||||||
|
|
||||||
|
Item {
|
||||||
|
height: swipeView.height
|
||||||
|
width: swipeView.width
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: favouritesList
|
||||||
|
clip: true
|
||||||
|
interactive: root.interactive
|
||||||
|
property real delegateHeight: PlasmaCore.Units.gridUnit * 3
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: Math.round(parent.width * 0.1)
|
||||||
|
anchors.rightMargin: Math.round(parent.width * 0.1)
|
||||||
|
|
||||||
|
// open wallpaper menu when held on click
|
||||||
|
TapHandler {
|
||||||
|
onLongPressed: {
|
||||||
|
plasmoid.action("configure").trigger();
|
||||||
|
plasmoid.editMode = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
model: MobileShell.FavoritesModel
|
||||||
|
header: MobileShell.BaseItem {
|
||||||
|
topPadding: Math.round(swipeView.height * 0.2)
|
||||||
|
bottomPadding: PlasmaCore.Units.largeSpacing
|
||||||
|
implicitWidth: favouritesList.width
|
||||||
|
|
||||||
|
contentItem: Clock {}
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: DrawerListDelegate {
|
||||||
|
id: delegate
|
||||||
|
|
||||||
|
width: favouritesList.width
|
||||||
|
height: visible ? favouritesList.delegateHeight : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: placeholder
|
||||||
|
spacing: PlasmaCore.Units.gridUnit
|
||||||
|
visible: favouritesList.count == 0
|
||||||
|
opacity: 0.9
|
||||||
|
|
||||||
|
anchors.topMargin: Math.round(swipeView.height * 0.2) - (favouritesList.contentY - favouritesList.originY)
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Kirigami.Icon {
|
||||||
|
id: icon
|
||||||
|
Layout.alignment: Qt.AlignBottom | Qt.AlignHCenter
|
||||||
|
implicitWidth: PlasmaCore.Units.iconSizes.large
|
||||||
|
implicitHeight: width
|
||||||
|
source: "emblem-favorite"
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaExtras.Heading {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.maximumWidth: placeholder.width * 0.75
|
||||||
|
Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
|
||||||
|
color: "white"
|
||||||
|
level: 3
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
text: i18n("Add applications to your favourites so they show up here.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: column
|
||||||
|
height: swipeView.height
|
||||||
|
width: swipeView.width
|
||||||
|
|
||||||
|
property real horizontalMargin: Math.max(Kirigami.Units.largeSpacing, column.width * 0.1 / 2)
|
||||||
|
|
||||||
|
GridAppList {
|
||||||
|
interactive: root.interactive
|
||||||
|
Layout.leftMargin: column.horizontalMargin
|
||||||
|
Layout.rightMargin: column.horizontalMargin
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
// open search widget when pulled down
|
||||||
|
onDraggingChanged: {
|
||||||
|
if (!dragging && (contentY < originY - PlasmaCore.Units.gridUnit * 3)) {
|
||||||
|
searchWidget.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Window 2.15
|
||||||
|
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.mobileshell 1.0 as MobileShell
|
||||||
|
|
||||||
|
MobileShell.HomeScreen {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
onResetHomeScreenPosition: {
|
||||||
|
homescreen.triggerHomescreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
onHomeTriggered: {
|
||||||
|
search.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
MobileShell.ApplicationListModel.loadApplications();
|
||||||
|
MobileShell.FavoritesModel.applet = plasmoid;
|
||||||
|
MobileShell.FavoritesModel.loadApplications();
|
||||||
|
|
||||||
|
forceActiveFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: darkenBackground
|
||||||
|
color: homescreen.page == 1 ? Qt.rgba(0, 0, 0, 0.7) : Qt.rgba(0, 0, 0, 0.2)
|
||||||
|
anchors.fill: parent
|
||||||
|
z: -1
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation { duration: PlasmaCore.Units.longDuration }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// homescreen component
|
||||||
|
contentItem: Item {
|
||||||
|
HomeScreen {
|
||||||
|
id: homescreen
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
// make the homescreen not interactable when task switcher or startup feedback is on
|
||||||
|
interactive: !root.overlayShown
|
||||||
|
searchWidget: search
|
||||||
|
}
|
||||||
|
|
||||||
|
// search component
|
||||||
|
MobileShell.KRunnerWidget {
|
||||||
|
id: search
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: openFactor > 0
|
||||||
|
|
||||||
|
// close search component when task switcher is shown or hidden
|
||||||
|
Connections {
|
||||||
|
target: MobileShell.HomeScreenControls.taskSwitcher
|
||||||
|
function onVisibleChanged() {
|
||||||
|
searchWidget.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
23
containments/homescreens/halcyon/package/metadata.desktop
Normal file
23
containments/homescreens/halcyon/package/metadata.desktop
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
# SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
[Desktop Entry]
|
||||||
|
Encoding=UTF-8
|
||||||
|
Keywords=
|
||||||
|
Name=Halcyon
|
||||||
|
Description=A mobile homescreen focused on simplicity and ease-of-use.
|
||||||
|
Type=Service
|
||||||
|
|
||||||
|
X-KDE-ServiceTypes=Plasma/Applet,Plasma/Containment
|
||||||
|
X-Plasma-API=declarativeappletscript
|
||||||
|
X-KDE-Library=plasma_containment_phone_homescreen_halcyon
|
||||||
|
X-KDE-PluginInfo-Author=Devin Lin
|
||||||
|
X-KDE-PluginInfo-Category=Containments
|
||||||
|
X-KDE-PluginInfo-Email=devin@kde.org
|
||||||
|
X-KDE-PluginInfo-License=GPLv2+
|
||||||
|
X-KDE-PluginInfo-Name=org.kde.phone.homescreen.halcyon
|
||||||
|
X-KDE-PluginInfo-Version=
|
||||||
|
X-KDE-PluginInfo-Website=
|
||||||
|
X-Plasma-ContainmentType=Desktop
|
||||||
|
X-Plasma-MainScript=ui/main.qml
|
||||||
|
X-Plasma-Provides=org.kde.plasma.launchermenu
|
||||||
Loading…
Reference in a new issue