Warning, /plasma/plasma-desktop/kcms/keyboard/tastenbrett/qml/main.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2019 Harald Sitter <sitter@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 
0007 import QtQuick 2.12
0008 import QtQuick.Window 2.12
0009 import QtQuick.Controls 2.5
0010 import QtQuick.Layouts 1.15
0011 
0012 import org.kde.tastenbrett.private 1.0 as XKB
0013 
0014 Window {
0015     id: window
0016     visible: false
0017     width: 1024
0018     height: 768
0019 
0020     SystemPalette { id: activePalette; colorGroup: SystemPalette.Active }
0021     SystemPalette { id: disabledPalette; colorGroup: SystemPalette.Disabled }
0022 
0023     function createDoodad(doodad, parent, properties) {
0024         var component = null
0025         if (doodad instanceof XKB.LogoDoodad) {
0026             component = doodadLogoComponent
0027         } else if (doodad instanceof XKB.IndicatorDoodad) {
0028             component = doodadIndicatorComponent
0029         } else if (doodad instanceof XKB.TextDoodad) {
0030             component = doodadTextComponent
0031         } else if (doodad instanceof XKB.ShapeDoodad) {
0032             component = doodadShapeComponent
0033         }
0034         if (component) {
0035             return component.createObject(parent, properties)
0036         }
0037         console.error("Unknown doodad type!", doodad)
0038         return null
0039     }
0040 
0041     Rectangle {
0042         anchors.fill: parent
0043         color: activePalette.window
0044     }
0045 
0046     ColumnLayout {
0047         id: errorLayout
0048         visible: false
0049         anchors.fill: parent
0050 
0051         Label {
0052             Layout.fillWidth: true
0053             text: errorDescription
0054             color: activePalette.text
0055             wrapMode: Text.Wrap
0056         }
0057 
0058         TextArea {
0059             Layout.fillWidth: true
0060             text: errorDetails
0061             readOnly: true
0062             color: activePalette.text
0063             wrapMode: TextEdit.Wrap
0064         }
0065     }
0066 
0067     Item {
0068         id: kbd
0069         width: window.width
0070         height: window.height
0071 
0072         // XKB geometries have a consistent coordinate system within a geometry
0073         // all children follow that system instead of QML. To easily convert
0074         // everything wholesale we'll employ a scale factor.
0075         property real childWidth: childrenRect.x + childrenRect.width
0076         property real childHeight: childrenRect.y + childrenRect.height
0077         // We preserve the ratio and as a result will need to scall either
0078         // with height or width, whichever has less space.
0079         scale: Math.min(width / childWidth, height / childHeight)
0080         transformOrigin: Item.TopLeft
0081     }
0082 
0083     Component {
0084         id: keyComponent
0085 
0086         // Interactable Key
0087         Key {
0088             id: root
0089 
0090             MouseArea {
0091                 id: hoverArea
0092                 anchors.fill: parent
0093                 hoverEnabled: true
0094             }
0095 
0096             ToolTip {
0097                 visible: hoverArea.containsMouse
0098 
0099                 contentItem: Item {
0100                     scale: kbd.scale * 3 // make keys easily redable at 2.5 times the regular size
0101 
0102                     Key {
0103                         id: keyItem
0104                         key: root.key
0105                     }
0106                 }
0107 
0108                 background: null
0109             }
0110         }
0111     }
0112 
0113     Component {
0114         id: doodadShapeComponent
0115         ShapeDoodad {}
0116     }
0117 
0118     Component {
0119         id: doodadIndicatorComponent
0120         IndicatorDoodad {}
0121     }
0122 
0123     Component {
0124         id: doodadTextComponent
0125         TextDoodad {}
0126     }
0127 
0128     Component {
0129         id: doodadLogoComponent
0130         ShapeDoodad {
0131             KeyCapLabel {
0132                 anchors.centerIn: parent
0133                 color: disabledPalette.buttonText
0134                 text: doodad.logo_name
0135                 anchors.margins: 22 // arbitrary spacing to key outlines
0136             }
0137         }
0138     }
0139 
0140     Component {
0141         id: rowComponent
0142 
0143         Item {
0144             property QtObject row: null
0145             x: row.left
0146             y: row.top
0147             width: childrenRect.width+4
0148             height: childrenRect.height+4
0149 
0150             Component.onCompleted: {
0151                 for (var i in row.keys) {
0152                     var key = row.keys[i]
0153                     keyComponent.createObject(this, { key: key });
0154                 }
0155             }
0156         }
0157     }
0158 
0159     Component {
0160         id: sectionComponent
0161 
0162         Item {
0163             property QtObject section
0164             x: section.left
0165             y: section.top
0166             z: section.priority
0167             // Dimension definitions can be a bit wonky for sections but overally should not
0168             // cause problems even when they are (so long as we don't actually render the
0169             // sections themself)
0170             width: section.width
0171             height: section.height
0172 
0173             // Fix rotation to mod90, we cannot spin around as that'd put the text upside down ;)
0174             // Unclear if spinning around like that is in fact desired for anything, if so I guess
0175             // we need to counter rotate text or something.
0176             rotation: section.angle != 0 ? section.angle % 90 : section.angle
0177             transformOrigin: Item.TopLeft
0178 
0179             Component.onCompleted: {
0180                 for (var i in section.rows) {
0181                     var row = section.rows[i]
0182                     rowComponent.createObject(this, { row: row });
0183                 }
0184 
0185                 for (var i in section.doodads) {
0186                     var doodad = section.doodads[i]
0187                     createDoodad(doodad, kbd, { doodad: doodad })
0188                 }
0189 
0190             }
0191         }
0192     }
0193 
0194     Component.onCompleted: {
0195         if (errorDetails != "") {
0196             errorLayout.visible = true
0197             visible = true
0198             return
0199         }
0200 
0201         // Based on the geometry aspect we scale either width or height to scale so
0202         // the default size is fitting. NB: geom dimensions are mm!
0203         if (geometry.widthMM >= geometry.heightMM) {
0204             height = width * geometry.heightMM / geometry.widthMM
0205         } else {
0206             width = height * geometry.widthMM / geometry.heightMM
0207         }
0208 
0209         for (var i in geometry.sections) {
0210             var section = geometry.sections[i]
0211             sectionComponent.createObject(kbd, { section: section });
0212         }
0213 
0214         for (var i in geometry.doodads) {
0215             var doodad = geometry.doodads[i]
0216             createDoodad(doodad, kbd, { doodad: doodad })
0217         }
0218 
0219         visible = true
0220     }
0221 }