Warning, /plasma/plasma-desktop/applets/kimpanel/package/contents/ui/InputPanel.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2014-2017 Weng Xuetian <wengxt@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 import QtQuick 2.6
0008 import QtQuick.Layouts 1.1
0009 import org.kde.plasma.plasmoid 2.0
0010 import org.kde.plasma.core as PlasmaCore
0011 import org.kde.plasma.components 3.0 as PlasmaComponents3
0012 import org.kde.plasma.private.kimpanel 0.1 as Kimpanel
0013 import org.kde.kirigami 2.20 as Kirigami
0014 import org.kde.plasma.plasmoid 2.0
0015 
0016 PlasmaCore.Dialog {
0017     id: inputpanel
0018     type: PlasmaCore.Dialog.PopupMenu
0019     flags: {
0020         var flag = Qt.WindowTransparentForInput | Qt.WindowStaysOnTopHint | Qt.WindowDoesNotAcceptFocus;
0021         if (Qt.platform.pluginName.includes("wayland")) {
0022             flag |= Qt.ToolTip;
0023         } else {
0024             flag |= Qt.Popup;
0025         }
0026         return flag;
0027     }
0028     location: PlasmaCore.Types.Floating
0029     visible: helper.auxVisible || helper.preeditVisible || helper.lookupTableVisible
0030     readonly property bool verticalLayout: (helper.lookupTableLayout === 1) || (helper.lookupTableLayout === 0 && Plasmoid.configuration.vertical_lookup_table);
0031     property int highlightCandidate: helper.lookupTableCursor
0032     property int hoveredCandidate: -1
0033     property font preferredFont: Plasmoid.configuration.use_default_font ? Kirigami.Theme.defaultFont : Plasmoid.configuration.font
0034     readonly property alias textOffset: fontMetrics.ascent
0035     readonly property alias labelHeight: fontMetrics.height
0036     property rect position: helper.spotRect
0037 
0038     onPositionChanged : updatePosition();
0039     onWidthChanged : updatePosition();
0040     onHeightChanged : updatePosition();
0041 
0042     mainItem: Item {
0043         Layout.minimumWidth: childrenRect.width
0044         Layout.minimumHeight: childrenRect.height
0045         Layout.maximumWidth: childrenRect.width
0046         Layout.maximumHeight: childrenRect.height
0047         FontMetrics {
0048             id: fontMetrics
0049             font: preferredFont
0050         }
0051         Column {
0052             spacing: Kirigami.Units.smallSpacing
0053             Row {
0054                 id: textLabel
0055                 width: auxLabel.width + preedit.width
0056                 height: inputpanel.labelHeight
0057                 visible: helper.auxVisible || helper.preeditVisible
0058                 baselineOffset: inputpanel.textOffset
0059                 PlasmaComponents3.Label {
0060                     id: auxLabel
0061                     anchors.baseline: parent.baseline
0062                     font: preferredFont
0063                     text: helper.auxText
0064                     textFormat: Text.PlainText
0065                     visible: helper.auxVisible
0066                 }
0067                 Item {
0068                     id: preedit
0069                     width: preeditLabel1.width + preeditLabel2.width + 2
0070                     height: parent.height
0071                     clip: true
0072                     visible: helper.preeditVisible
0073                     baselineOffset: inputpanel.textOffset
0074                     PlasmaComponents3.Label {
0075                         id: preeditLabel1
0076                         anchors.baseline: parent.baseline
0077                         anchors.left: parent.left
0078                         font: preferredFont
0079                         textFormat: Text.PlainText
0080                     }
0081                     Rectangle {
0082                         color: Kirigami.Theme.textColor
0083                         height: parent.height
0084                         width: 1
0085                         opacity: 0.8
0086                         z: 1
0087                         anchors.verticalCenter: parent.verticalCenter
0088                         anchors.left: preeditLabel1.right
0089                     }
0090                     PlasmaComponents3.Label {
0091                         id: preeditLabel2
0092                         anchors.baseline: parent.baseline
0093                         anchors.left: preeditLabel1.right
0094                         font: preferredFont
0095                         textFormat: Text.PlainText
0096                     }
0097                 }
0098             }
0099 
0100             GridLayout {
0101                 flow: inputpanel.verticalLayout ? GridLayout.TopToBottom : GridLayout.LeftToRight
0102                 columns: inputpanel.verticalLayout ? 1 : tableList.count + 1
0103                 rows: inputpanel.verticalLayout ? tableList.count + 1 : 1
0104 
0105                 Repeater {
0106                     model: ListModel {
0107                         id: tableList
0108                         dynamicRoles: true
0109                     }
0110                     delegate: Item {
0111                         id: candidateDelegate
0112                         width: candidate.width + highlight.marginHints.left + highlight.marginHints.right
0113                         height: inputpanel.labelHeight + highlight.marginHints.top + highlight.marginHints.bottom
0114                         Layout.minimumWidth: width
0115                         Layout.minimumHeight: height
0116                         Layout.maximumWidth: width
0117                         Layout.maximumHeight: height
0118 
0119                         readonly property bool selected: inputpanel.highlightCandidate === model.index || candidateMouseArea.pressed
0120 
0121                         Row {
0122                             id: candidate
0123                             width: childrenRect.width
0124                             height: childrenRect.height
0125                             x: highlight.marginHints.left
0126                             y: highlight.marginHints.top
0127                             baselineOffset: inputpanel.textOffset
0128                             spacing: Kirigami.Units.smallSpacing
0129                             PlasmaComponents3.Label {
0130                                 id: tableLabel
0131                                 text: model.label
0132                                 textFormat: Text.PlainText
0133                                 font: preferredFont
0134                                 opacity: 0.8
0135                                 color: Kirigami.Theme.textColor
0136                                 anchors.baseline: parent.baseline
0137                             }
0138                             PlasmaComponents3.Label {
0139                                 id: textLabel
0140                                 text: model.text
0141                                 textFormat: Text.PlainText
0142                                 font: preferredFont
0143                                 color: Kirigami.Theme.textColor
0144                                 anchors.baseline: parent.baseline
0145                             }
0146                         }
0147                         MouseArea {
0148                             id: candidateMouseArea
0149                             anchors.fill: parent
0150                             hoverEnabled: true
0151                             onReleased: helper.selectCandidate(model.index)
0152                             onContainsMouseChanged: {
0153                                 inputpanel.hoveredCandidate = containsMouse ? model.index : -1;
0154                             }
0155                         }
0156                         CandidateHighlight {
0157                             id: highlight
0158                             z: -1
0159                             visible: inputpanel.highlightCandidate === model.index || inputpanel.hoveredCandidate === model.index
0160                             selected: candidateDelegate.selected
0161                             anchors {
0162                                 fill: parent
0163                             }
0164                         }
0165                     }
0166                 }
0167                 Row {
0168                     id: button
0169                     width: inputpanel.labelHeight * 2
0170                     height: inputpanel.labelHeight
0171                     Layout.minimumWidth: width
0172                     Layout.minimumHeight: height
0173                     Layout.maximumWidth: width
0174                     Layout.maximumHeight: height
0175                     spacing: Kirigami.Units.smallSpacing
0176                     Kirigami.Icon {
0177                         id: prevButton
0178                         source: inputpanel.verticalLayout ? "arrow-up" : "arrow-left"
0179                         width: inputpanel.labelHeight
0180                         height: width
0181                         scale: prevButtonMouseArea.pressed ? 0.9 : 1
0182                         active: prevButtonMouseArea.containsMouse
0183                         MouseArea {
0184                             id: prevButtonMouseArea
0185                             anchors.fill: parent
0186                             hoverEnabled: true
0187                             onReleased: helper.lookupTablePageUp()
0188                         }
0189                     }
0190                     Kirigami.Icon {
0191                         id: nextButton
0192                         source: inputpanel.verticalLayout ? "arrow-down" : "arrow-right"
0193                         width: inputpanel.labelHeight
0194                         height: width
0195                         scale: nextButtonMouseArea.pressed ? 0.9 : 1
0196                         active: nextButtonMouseArea.containsMouse
0197                         MouseArea {
0198                             id: nextButtonMouseArea
0199                             anchors.fill: parent
0200                             hoverEnabled: true
0201                             onReleased: helper.lookupTablePageDown()
0202                         }
0203                     }
0204                 }
0205             }
0206         }
0207 
0208         Kimpanel.Screen {
0209             id: screen
0210         }
0211 
0212         // Kimpanel's update may come in with in several DBus message. Use
0213         // timer to delegate the update so we get less flicker.
0214         Timer {
0215             id: timer
0216             interval: 1
0217             onTriggered: updateLookupTable()
0218         }
0219 
0220         Connections {
0221             target: helper
0222 
0223             function onPreeditTextChanged() {
0224                 var charArray = [...helper.preeditText];
0225                 preeditLabel1.text = charArray.slice(0, helper.caretPos).join('');
0226                 preeditLabel2.text = charArray.slice(helper.caretPos).join('');
0227             }
0228 
0229             function onLookupTableChanged() {
0230                 timer.restart();
0231             }
0232         }
0233     }
0234 
0235     function updateLookupTable() {
0236         inputpanel.hoveredCandidate = -1;
0237         button.visible = helper.lookupTableVisible && (helper.hasPrev || helper.hasNext);
0238 
0239         var labels = helper.labels;
0240         var texts = helper.texts;
0241 
0242         var length = Math.min(labels.length, texts.length);
0243 
0244         if (helper.lookupTableVisible) {
0245             if (length< tableList.count) {
0246                 tableList.remove(length, tableList.count - length);
0247             }
0248             for (var i = 0; i < length; i ++) {
0249                 if (i >= tableList.count) {
0250                     tableList.append({'label' : labels[i], 'text': texts[i], 'index': i});
0251                 } else {
0252                     tableList.set(i, {'label' : labels[i], 'text': texts[i], 'index': i});
0253                 }
0254             }
0255         } else {
0256             tableList.clear();
0257         }
0258     }
0259 
0260     function updatePosition() {
0261         var rect = screen.geometryForPoint(position.x, position.y);
0262         var devicePerPixelRatio = screen.devicePixelRatioForPoint(position.x, position.y);
0263         var x, y;
0264         var width = inputpanel.width * devicePerPixelRatio;
0265         var height = inputpanel.height * devicePerPixelRatio;
0266         if (position.x < rect.x) {
0267             x = rect.x;
0268         } else {
0269             x = position.x;
0270         }
0271         if (position.y < rect.y) {
0272             y = rect.y;
0273         } else {
0274             y = position.y + position.height;
0275         }
0276 
0277         if (x + width > rect.x + rect.width) {
0278             x = rect.x + rect.width - width;
0279         }
0280 
0281         if (y + height > rect.y + rect.height) {
0282             if (y > rect.y + rect.height) {
0283                 y = rect.y + rect.height - height - 40;
0284             } else {
0285                 y = y - height - (position.height === 0 ? 40 : position.height);
0286             }
0287         }
0288 
0289         var newRect = screen.geometryForPoint(x, y);
0290         devicePerPixelRatio = screen.devicePixelRatioForPoint(x, y);
0291 
0292         inputpanel.x = newRect.x + (x - newRect.x) / devicePerPixelRatio;
0293         inputpanel.y = newRect.y + (y - newRect.y) / devicePerPixelRatio;
0294     }
0295 }