Warning, /plasma/kscreen/osd/qml/OsdSelector.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 SPDX-FileCopyrightText: 2017 Daniel Vrátil <dvratil@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 import QtQuick 2.15 0008 import QtQuick.Controls 2.15 0009 import QtQuick.Layouts 1.10 0010 0011 import org.kde.ksvg 1.0 as KSvg 0012 import org.kde.kirigami 2.20 as Kirigami 0013 import org.kde.plasma.components 3.0 as PlasmaComponents 0014 0015 import org.kde.KScreen 1.0 0016 0017 0018 Control { 0019 id: root 0020 property string infoText 0021 property var actions 0022 signal clicked(int actionId) 0023 0024 leftPadding: shadow.margins.left + background.margins.left 0025 rightPadding: shadow.margins.right + background.margins.right 0026 topPadding: shadow.margins.top + background.margins.top 0027 bottomPadding: shadow.margins.bottom + background.margins.bottom 0028 0029 contentItem : ColumnLayout { 0030 RowLayout { 0031 Repeater { 0032 id: actionRepeater 0033 property int currentIndex: 0 0034 model: root.actions 0035 delegate: PlasmaComponents.Button { 0036 property int actionId: modelData.action 0037 0038 Accessible.name: modelData.label 0039 0040 icon.name: modelData.iconName 0041 icon.height: Kirigami.Units.gridUnit * 8 0042 icon.width: Kirigami.Units.gridUnit * 8 0043 0044 onClicked: root.clicked(actionId) 0045 onHoveredChanged: { 0046 if (hovered) { 0047 actionRepeater.currentIndex = index 0048 } 0049 } 0050 0051 activeFocusOnTab: true 0052 0053 // use checked only indirectly, since its binding will break 0054 property bool current: index == actionRepeater.currentIndex 0055 onCurrentChanged: { 0056 if (current) { 0057 checked = true 0058 root.infoText = modelData.label 0059 forceActiveFocus() 0060 } else { 0061 checked = false 0062 } 0063 } 0064 onActiveFocusChanged: { 0065 if (activeFocus) { 0066 actionRepeater.currentIndex = index 0067 } 0068 } 0069 } 0070 } 0071 } 0072 0073 Kirigami.Heading { 0074 text: root.infoText 0075 horizontalAlignment: Text.AlignHCenter 0076 maximumLineCount: 2 0077 wrapMode: Text.WordWrap 0078 0079 Layout.fillWidth: true 0080 Layout.margins: Math.floor(Kirigami.Units.smallSpacing / 2) 0081 } 0082 0083 // Shift current by delta, but do not wrap around when repeat is true. 0084 function wrappingAdd(count: int, current: int, delta: int, repeat: bool): int { 0085 const next = current + delta; 0086 // Rule out invalid states. 0087 if (count === 0 || current < 0 || current >= count) { 0088 return current; 0089 } 0090 // Don't wrap on autorepeat. 0091 if (repeat && (next < 0 || next >= count)) { 0092 return current; 0093 } 0094 // Add an extra `count`, so that wrapping % works predictably with positive values only. 0095 // This assumes that delta is not smaller than `-count` (usually just -1, 0 or +1). 0096 return (next + count) % count; 0097 } 0098 0099 function move(event) { 0100 actionRepeater.currentIndex = wrappingAdd(actionRepeater.count, actionRepeater.currentIndex, 0101 (event.key === Qt.Key_Left) ? -1 : 1, event.isAutoRepeat); 0102 } 0103 0104 Keys.onPressed: (event) => { 0105 switch (event.key) { 0106 case Qt.Key_Return: 0107 case Qt.Key_Enter: 0108 clicked(actionRepeater.itemAt(actionRepeater.currentIndex).actionId) 0109 break 0110 case Qt.Key_Right: 0111 case Qt.Key_Left: 0112 move(event) 0113 break 0114 case Qt.Key_Escape: 0115 clicked(OsdAction.NoAction) 0116 break 0117 } 0118 } 0119 } 0120 0121 background: KSvg.FrameSvgItem { 0122 id: shadow 0123 imagePath: "dialogs/background" 0124 prefix: "shadow" 0125 0126 KSvg.FrameSvgItem { 0127 id: background 0128 anchors.leftMargin: shadow.margins.left 0129 anchors.rightMargin: shadow.margins.right 0130 anchors.topMargin: shadow.margins.top 0131 anchors.bottomMargin: shadow.margins.bottom 0132 anchors.fill: parent 0133 imagePath: "solid/dialogs/background" 0134 } 0135 } 0136 }