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 }