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