mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-27 14:33:08 +00:00
components: Introduce ExtendedAbstractButton, port homescreen to it
This commit is contained in:
parent
d158549525
commit
9922c8d5d2
10 changed files with 161 additions and 77 deletions
|
|
@ -69,6 +69,7 @@ void MobileShellPlugin::registerTypes(const char *uri)
|
||||||
|
|
||||||
// /components
|
// /components
|
||||||
qmlRegisterType(resolvePath("components/BaseItem.qml"), uri, 1, 0, "BaseItem");
|
qmlRegisterType(resolvePath("components/BaseItem.qml"), uri, 1, 0, "BaseItem");
|
||||||
|
qmlRegisterType(resolvePath("components/ExtendedAbstractButton.qml"), uri, 1, 0, "ExtendedAbstractButton");
|
||||||
qmlRegisterSingletonType(resolvePath("components/Haptics.qml"), uri, 1, 0, "Haptics");
|
qmlRegisterSingletonType(resolvePath("components/Haptics.qml"), uri, 1, 0, "Haptics");
|
||||||
qmlRegisterType(resolvePath("components/StartupFeedback.qml"), uri, 1, 0, "StartupFeedback");
|
qmlRegisterType(resolvePath("components/StartupFeedback.qml"), uri, 1, 0, "StartupFeedback");
|
||||||
qmlRegisterType(resolvePath("components/VelocityCalculator.qml"), uri, 1, 0, "VelocityCalculator");
|
qmlRegisterType(resolvePath("components/VelocityCalculator.qml"), uri, 1, 0, "VelocityCalculator");
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15 as QQC2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is an AbstractButton with some added functionality to simulate a MouseArea.
|
||||||
|
*
|
||||||
|
* The hovered property of AbstractButton is much more accurate than the containsMouse property of MouseArea,
|
||||||
|
* and so this is useful for creating custom buttons.
|
||||||
|
*/
|
||||||
|
|
||||||
|
QQC2.AbstractButton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The cursor shape when the mouse is over the button.
|
||||||
|
*/
|
||||||
|
property alias cursorShape: mouseArea.cursorShape
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This property holds the elapsed time in milliseconds before pressAndHold is emitted.
|
||||||
|
*/
|
||||||
|
property real pressAndHoldInterval: 1000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signal that is emitted when the button has been held for a certain amount of time.
|
||||||
|
*/
|
||||||
|
signal pressAndHold()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signal that is emitted when the right click button is pressed.
|
||||||
|
*/
|
||||||
|
signal rightClickPressed()
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: timer
|
||||||
|
interval: pressAndHoldInterval
|
||||||
|
repeat: false
|
||||||
|
running: false
|
||||||
|
onTriggered: root.pressAndHold()
|
||||||
|
}
|
||||||
|
|
||||||
|
onPressedChanged: {
|
||||||
|
if (pressed) {
|
||||||
|
timer.restart();
|
||||||
|
} else {
|
||||||
|
timer.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
onPressed: {
|
||||||
|
if (mouse.button === Qt.RightButton) {
|
||||||
|
root.rightClickPressed();
|
||||||
|
} else {
|
||||||
|
mouse.accepted = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
<file>qml/actiondrawer/PortraitContentContainer.qml</file>
|
<file>qml/actiondrawer/PortraitContentContainer.qml</file>
|
||||||
|
|
||||||
<file>qml/components/BaseItem.qml</file>
|
<file>qml/components/BaseItem.qml</file>
|
||||||
|
<file>qml/components/ExtendedAbstractButton.qml</file>
|
||||||
<file>qml/components/Haptics.qml</file>
|
<file>qml/components/Haptics.qml</file>
|
||||||
<file>qml/components/HapticsEffectWrapper.qml</file>
|
<file>qml/components/HapticsEffectWrapper.qml</file>
|
||||||
<file>qml/components/MarqueeLabel.qml</file>
|
<file>qml/components/MarqueeLabel.qml</file>
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,6 @@ QHash<int, QByteArray> ApplicationListModel::roleNames() const
|
||||||
|
|
||||||
void ApplicationListModel::sycocaDbChanged()
|
void ApplicationListModel::sycocaDbChanged()
|
||||||
{
|
{
|
||||||
m_applicationList.clear();
|
|
||||||
loadApplications();
|
loadApplications();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ ContainmentLayoutManager.ItemContainer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
contentItem: MouseArea {
|
contentItem: MobileShell.ExtendedAbstractButton {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
|
|
||||||
// grow/shrink animation
|
// grow/shrink animation
|
||||||
|
|
@ -187,7 +187,7 @@ ContainmentLayoutManager.ItemContainer {
|
||||||
|
|
||||||
// darken effect when hovered/pressed
|
// darken effect when hovered/pressed
|
||||||
layer {
|
layer {
|
||||||
enabled: mouseArea.pressed || mouseArea.containsMouse
|
enabled: mouseArea.pressed || mouseArea.hovered
|
||||||
effect: ColorOverlay {
|
effect: ColorOverlay {
|
||||||
color: Qt.rgba(0, 0, 0, 0.3)
|
color: Qt.rgba(0, 0, 0, 0.3)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import org.kde.kquickcontrolsaddons 2.0
|
||||||
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
|
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.mobileshell 1.0 as MobileShell
|
||||||
|
|
||||||
MouseArea {
|
MobileShell.ExtendedAbstractButton {
|
||||||
id: delegate
|
id: delegate
|
||||||
width: GridView.view.cellWidth
|
width: GridView.view.cellWidth
|
||||||
height: GridView.view.cellHeight
|
height: GridView.view.cellHeight
|
||||||
|
|
@ -129,7 +129,7 @@ MouseArea {
|
||||||
|
|
||||||
// darken effect when hovered/pressed
|
// darken effect when hovered/pressed
|
||||||
layer {
|
layer {
|
||||||
enabled: delegate.pressed || delegate.containsMouse
|
enabled: delegate.pressed || delegate.hovered
|
||||||
effect: ColorOverlay {
|
effect: ColorOverlay {
|
||||||
color: Qt.rgba(0, 0, 0, 0.3)
|
color: Qt.rgba(0, 0, 0, 0.3)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import org.kde.kquickcontrolsaddons 2.0
|
||||||
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
|
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.mobileshell 1.0 as MobileShell
|
||||||
|
|
||||||
MouseArea {
|
MobileShell.ExtendedAbstractButton {
|
||||||
id: delegate
|
id: delegate
|
||||||
property int reservedSpaceForLabel
|
property int reservedSpaceForLabel
|
||||||
property alias iconItem: icon
|
property alias iconItem: icon
|
||||||
|
|
@ -45,7 +45,7 @@ MouseArea {
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: delegate.pressed ? Qt.rgba(255, 255, 255, 0.2) : (delegate.containsMouse ? Qt.rgba(255, 255, 255, 0.05) : "transparent")
|
color: delegate.pressed ? Qt.rgba(255, 255, 255, 0.2) : (delegate.hovered ? Qt.rgba(255, 255, 255, 0.05) : "transparent")
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
ColorAnimation { duration: PlasmaCore.Units.shortDuration }
|
ColorAnimation { duration: PlasmaCore.Units.shortDuration }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,6 @@ QHash<int, QByteArray> ApplicationListModel::roleNames() const
|
||||||
|
|
||||||
void ApplicationListModel::sycocaDbChanged()
|
void ApplicationListModel::sycocaDbChanged()
|
||||||
{
|
{
|
||||||
m_applicationList.clear();
|
|
||||||
loadApplications();
|
loadApplications();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import org.kde.phone.homescreen.halcyon 1.0 as Halcyon
|
||||||
|
|
||||||
import org.kde.kirigami 2.19 as Kirigami
|
import org.kde.kirigami 2.19 as Kirigami
|
||||||
|
|
||||||
MouseArea {
|
MobileShell.ExtendedAbstractButton {
|
||||||
id: delegate
|
id: delegate
|
||||||
|
|
||||||
property alias iconItem: icon
|
property alias iconItem: icon
|
||||||
|
|
@ -44,11 +44,15 @@ MouseArea {
|
||||||
application.runApplication();
|
application.runApplication();
|
||||||
}
|
}
|
||||||
|
|
||||||
onPressAndHold: {
|
function openContextMenu() {
|
||||||
dialogLoader.active = true;
|
dialogLoader.active = true;
|
||||||
dialogLoader.item.open();
|
dialogLoader.item.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hoverEnabled: true
|
||||||
|
onPressAndHold: openContextMenu()
|
||||||
|
onRightClickPressed: openContextMenu()
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
// launch app
|
// launch app
|
||||||
if (application.running) {
|
if (application.running) {
|
||||||
|
|
@ -57,7 +61,6 @@ MouseArea {
|
||||||
delegate.launch(delegate.x + (PlasmaCore.Units.smallSpacing * 2), delegate.y + (PlasmaCore.Units.smallSpacing * 2), icon.source, applicationName, applicationStorageId);
|
delegate.launch(delegate.x + (PlasmaCore.Units.smallSpacing * 2), delegate.y + (PlasmaCore.Units.smallSpacing * 2), icon.source, applicationName, applicationStorageId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hoverEnabled: true
|
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: dialogLoader
|
id: dialogLoader
|
||||||
|
|
@ -65,6 +68,7 @@ MouseArea {
|
||||||
|
|
||||||
sourceComponent: PlasmaComponents.Menu {
|
sourceComponent: PlasmaComponents.Menu {
|
||||||
title: label.text
|
title: label.text
|
||||||
|
closePolicy: PlasmaComponents.Menu.CloseOnReleaseOutside | PlasmaComponents.Menu.CloseOnEscape
|
||||||
|
|
||||||
PlasmaComponents.MenuItem {
|
PlasmaComponents.MenuItem {
|
||||||
icon.name: "emblem-favorite"
|
icon.name: "emblem-favorite"
|
||||||
|
|
@ -77,80 +81,83 @@ MouseArea {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
background: Rectangle {
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
radius: height / 2
|
radius: height / 2
|
||||||
|
color: delegate.pressed ? Qt.rgba(255, 255, 255, 0.2) : (delegate.hovered ? Qt.rgba(255, 255, 255, 0.1) : "transparent")
|
||||||
color: delegate.pressed ? Qt.rgba(255, 255, 255, 0.2) : (delegate.containsMouse ? Qt.rgba(255, 255, 255, 0.1) : "transparent")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
contentItem: Item {
|
||||||
anchors {
|
implicitHeight: rowLayout.height + rowLayout.anchors.topMargin + rowLayout.anchors.bottomMargin
|
||||||
fill: parent
|
implicitWidth: rowLayout.width + rowLayout.anchors.rightMargin + rowLayout.anchors.leftMargin
|
||||||
leftMargin: PlasmaCore.Units.smallSpacing * 2
|
|
||||||
topMargin: PlasmaCore.Units.smallSpacing
|
|
||||||
rightMargin: PlasmaCore.Units.smallSpacing * 2
|
|
||||||
bottomMargin: PlasmaCore.Units.smallSpacing
|
|
||||||
}
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
PlasmaCore.IconItem {
|
RowLayout {
|
||||||
id: icon
|
id: rowLayout
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
leftMargin: PlasmaCore.Units.smallSpacing * 2
|
||||||
|
topMargin: PlasmaCore.Units.smallSpacing
|
||||||
|
rightMargin: PlasmaCore.Units.smallSpacing * 2
|
||||||
|
bottomMargin: PlasmaCore.Units.smallSpacing
|
||||||
|
}
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignLeft
|
PlasmaCore.IconItem {
|
||||||
Layout.minimumWidth: Layout.minimumHeight
|
id: icon
|
||||||
Layout.preferredWidth: Layout.minimumHeight
|
|
||||||
Layout.minimumHeight: parent.height
|
|
||||||
Layout.preferredHeight: Layout.minimumHeight
|
|
||||||
|
|
||||||
usesPlasmaTheme: false
|
Layout.alignment: Qt.AlignLeft
|
||||||
source: applicationIcon
|
Layout.minimumWidth: Layout.minimumHeight
|
||||||
|
Layout.preferredWidth: Layout.minimumHeight
|
||||||
|
Layout.minimumHeight: parent.height
|
||||||
|
Layout.preferredHeight: Layout.minimumHeight
|
||||||
|
|
||||||
Rectangle {
|
usesPlasmaTheme: false
|
||||||
anchors {
|
source: applicationIcon
|
||||||
horizontalCenter: parent.horizontalCenter
|
|
||||||
bottom: parent.bottom
|
Rectangle {
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
bottom: parent.bottom
|
||||||
|
}
|
||||||
|
visible: application ? application.running : false
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
visible: application.running
|
|
||||||
radius: width
|
|
||||||
width: PlasmaCore.Units.smallSpacing
|
|
||||||
height: width
|
|
||||||
color: PlasmaCore.Theme.highlightColor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
layer.enabled: true
|
PlasmaComponents.Label {
|
||||||
layer.effect: DropShadow {
|
id: label
|
||||||
verticalOffset: 1
|
visible: text.length > 0
|
||||||
radius: 4
|
|
||||||
samples: 6
|
|
||||||
color: Qt.rgba(0, 0, 0, 0.5)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PlasmaComponents.Label {
|
Layout.fillWidth: true
|
||||||
id: label
|
Layout.leftMargin: PlasmaCore.Units.smallSpacing * 2
|
||||||
visible: text.length > 0
|
Layout.rightMargin: PlasmaCore.Units.largeSpacing
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
maximumLineCount: 1
|
||||||
|
elide: Text.ElideRight
|
||||||
|
|
||||||
Layout.fillWidth: true
|
text: applicationName
|
||||||
Layout.leftMargin: PlasmaCore.Units.smallSpacing * 2
|
|
||||||
Layout.rightMargin: PlasmaCore.Units.largeSpacing
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
maximumLineCount: 1
|
|
||||||
elide: Text.ElideRight
|
|
||||||
|
|
||||||
text: applicationName
|
font.pointSize: PlasmaCore.Theme.defaultFont.pointSize
|
||||||
|
font.weight: Font.Bold
|
||||||
|
color: "white"
|
||||||
|
|
||||||
font.pointSize: PlasmaCore.Theme.defaultFont.pointSize
|
layer.enabled: true
|
||||||
font.weight: Font.Bold
|
layer.effect: DropShadow {
|
||||||
color: "white"
|
verticalOffset: 1
|
||||||
|
radius: 4
|
||||||
layer.enabled: true
|
samples: 6
|
||||||
layer.effect: DropShadow {
|
color: Qt.rgba(0, 0, 0, 0.5)
|
||||||
verticalOffset: 1
|
}
|
||||||
radius: 4
|
|
||||||
samples: 6
|
|
||||||
color: Qt.rgba(0, 0, 0, 0.5)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import org.kde.phone.homescreen.halcyon 1.0 as Halcyon
|
||||||
|
|
||||||
import org.kde.kirigami 2.19 as Kirigami
|
import org.kde.kirigami 2.19 as Kirigami
|
||||||
|
|
||||||
MouseArea {
|
MobileShell.ExtendedAbstractButton {
|
||||||
id: delegate
|
id: delegate
|
||||||
width: GridView.view.cellWidth
|
width: GridView.view.cellWidth
|
||||||
height: GridView.view.cellHeight
|
height: GridView.view.cellHeight
|
||||||
|
|
@ -34,11 +34,16 @@ MouseArea {
|
||||||
|
|
||||||
signal launch(int x, int y, var source, string title, string storageId)
|
signal launch(int x, int y, var source, string title, string storageId)
|
||||||
|
|
||||||
onPressAndHold: {
|
function openContextMenu() {
|
||||||
dialogLoader.active = true;
|
dialogLoader.active = true;
|
||||||
dialogLoader.item.open();
|
dialogLoader.item.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
hoverEnabled: true
|
||||||
|
onPressAndHold: openContextMenu()
|
||||||
|
onRightClickPressed: openContextMenu()
|
||||||
|
|
||||||
function launchApp() {
|
function launchApp() {
|
||||||
// launch app
|
// launch app
|
||||||
if (application.running) {
|
if (application.running) {
|
||||||
|
|
@ -54,6 +59,7 @@ MouseArea {
|
||||||
|
|
||||||
sourceComponent: PlasmaComponents.Menu {
|
sourceComponent: PlasmaComponents.Menu {
|
||||||
title: label.text
|
title: label.text
|
||||||
|
closePolicy: PlasmaComponents.Menu.CloseOnReleaseOutside | PlasmaComponents.Menu.CloseOnEscape
|
||||||
|
|
||||||
PlasmaComponents.MenuItem {
|
PlasmaComponents.MenuItem {
|
||||||
icon.name: "emblem-favorite"
|
icon.name: "emblem-favorite"
|
||||||
|
|
@ -102,8 +108,6 @@ MouseArea {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
hoverEnabled: true
|
|
||||||
onPressedChanged: {
|
onPressedChanged: {
|
||||||
if (pressed) {
|
if (pressed) {
|
||||||
growAnim.stop();
|
growAnim.stop();
|
||||||
|
|
@ -147,6 +151,14 @@ MouseArea {
|
||||||
height: width
|
height: width
|
||||||
color: theme.highlightColor
|
color: theme.highlightColor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// darken effect when hovered/pressed
|
||||||
|
layer {
|
||||||
|
enabled: delegate.pressed || delegate.hovered
|
||||||
|
effect: ColorOverlay {
|
||||||
|
color: Qt.rgba(0, 0, 0, 0.3)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PlasmaComponents.Label {
|
PlasmaComponents.Label {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue