mobileshell/components: implement popup menu

This commit is contained in:
Yari Polla 2023-03-08 12:48:14 +01:00
parent b9492348b6
commit a2f6c51665
3 changed files with 99 additions and 0 deletions

View file

@ -74,6 +74,7 @@ void MobileShellPlugin::registerTypes(const char *uri)
qmlRegisterType(resolvePath("components/GridView.qml"), uri, 1, 0, "GridView");
qmlRegisterType(resolvePath("components/HapticsEffectLoader.qml"), uri, 1, 0, "HapticsEffectLoader");
qmlRegisterType(resolvePath("components/ListView.qml"), uri, 1, 0, "ListView");
qmlRegisterType(resolvePath("components/PopupMenu.qml"), uri, 1, 0, "PopupMenu");
qmlRegisterType(resolvePath("components/StartupFeedback.qml"), uri, 1, 0, "StartupFeedback");
qmlRegisterType(resolvePath("components/VelocityCalculator.qml"), uri, 1, 0, "VelocityCalculator");

View file

@ -0,0 +1,97 @@
import QtQuick
import QtQuick.Layouts
import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.plasma.private.nanoshell as NanoShell
import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.plasma.private.mobileshell.state as MobileShellState
import org.kde.kirigami as Kirigami
/*
* A context popup menu closable by tapping outside it.
* Being it a FullScreenOverlay, no event is delivered to underlying components until it's closed.
*
* - property relatedTo: Item to which the popup is related; the popup will spawn either above or below it, depending on its y value.
* If no item is supplied, the popup will spawn at the centre of the screen.
* - property title: The title for the menu.
* - property menuActions: The menu will be composed of these actions.
* - function showOverlay(): Spawns the popup.
*/
NanoShell.FullScreenOverlay {
id: overlay
visible: false
color: "transparent"
property point mappedGlobalCoordinates
property Item relatedTo: null
property string title
property list<Kirigami.Action> menuActions
function showOverlay() {
if (!overlay.visible) {
overlay.showMaximized();
menu.open();
}
}
Item {
id: containerItem
height: menu.implicitHeight
width: menu.implicitWidth
readonly property point coordinates: {
if (relatedTo) { // Place next to Item
return mapFromGlobal(mappedGlobalCoordinates.x, mappedGlobalCoordinates.y);
} else { // Place at the centre of the screen
return Qt.point((overlay.width - width) / 2, (overlay.height - height) / 2);
}
}
x: coordinates.x
y: coordinates.y
transform: Translate {
x: 0
y: (containerItem.coordinates.y <= overlay.height/2 ? relatedTo.height : -containerItem.height) - MobileShellState.TopPanelControls.panelHeight
}
PlasmaComponents.Menu {
id: menu
title: overlay.title
closePolicy: PlasmaComponents.Menu.CloseOnReleaseOutside | PlasmaComponents.Menu.CloseOnEscape
onClosed: overlay.hide()
Component.onCompleted: {
for (var i = 0; i < menuActions.length; i++) {
appendItem(menuActions[i]);
}
}
function appendItem(button) {
menu.addItem(menuItem.createObject(
menu,
{
iconName: button.iconName,
text: i18n(button.text),
callback: button.triggered
}));
}
Component {
id: menuItem
PlasmaComponents.MenuItem {
property string iconName: ""
property var callback: () => {}
icon.name: iconName
onClicked: callback()
}
}
}
}
}

View file

@ -28,6 +28,7 @@
<file>qml/components/HapticsEffectWrapper.qml</file>
<file>qml/components/ListView.qml</file>
<file>qml/components/MarqueeLabel.qml</file>
<file>qml/components/PopupMenu.qml</file>
<file>qml/components/StartupFeedback.qml</file>
<file>qml/components/util.js</file>
<file>qml/components/VelocityCalculator.qml</file>