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 }