Warning, /plasma/kscreen/kcm/ui/Output.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2019 Roman Gilg <subdiff@gmail.com>
0003     SPDX-FileCopyrightText: 2012 Dan Vratil <dvratil@redhat.com>
0004     SPDX-FileCopyrightText: 2022 Kai Uwe Broulik <kde@broulik.de>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 import QtQuick 2.15
0009 import QtQuick.Layouts 1.15
0010 import QtQuick.Controls 2.15 as QQC2
0011 import org.kde.kirigami 2.20 as Kirigami
0012 
0013 Item {
0014     id: output
0015 
0016     readonly property bool isSelected: root.selectedOutput === model.index
0017     property size outputSize: model.size
0018 
0019     onIsSelectedChanged: {
0020         if (isSelected) {
0021             z = 89;
0022         } else {
0023             z = 0;
0024         }
0025     }
0026 
0027     function getAbsolutePosition(pos) {
0028         return Qt.point((pos.x - screen.xOffset) * screen.relativeFactor,
0029                         (pos.y - screen.yOffset) * screen.relativeFactor);
0030     }
0031 
0032     visible: model.enabled && model.replicationSourceIndex === 0
0033 
0034     onVisibleChanged: screen.resetTotalSize()
0035     onOutputSizeChanged: screen.resetTotalSize()
0036 
0037     x: model.position ? model.position.x / screen.relativeFactor + screen.xOffset : 0
0038     y: model.position ? model.position.y / screen.relativeFactor + screen.yOffset : 0
0039 
0040     width: model.size ? model.size.width / screen.relativeFactor : 1
0041     height: model.size ? model.size.height / screen.relativeFactor : 1
0042 
0043     Rectangle {
0044         id: outline
0045 
0046         readonly property int orientationPanelWidth: 10
0047         readonly property real orientationPanelPosition: 1 - (orientationPanelWidth / outline.height)
0048 
0049         anchors.centerIn: parent
0050         width: parent.width
0051         height: parent.height
0052         radius: Kirigami.Units.smallSpacing
0053 
0054         gradient: Gradient {
0055             GradientStop {
0056                 position: 0.0
0057                 color: Kirigami.Theme.alternateBackgroundColor
0058             }
0059             GradientStop {
0060                 // Create a hard cut. Can't use the same number otherwise it gets confused.
0061                 position: outline.orientationPanelPosition - Number.EPSILON
0062                 color: Kirigami.Theme.alternateBackgroundColor
0063             }
0064             GradientStop {
0065                 position: outline.orientationPanelPosition
0066                 color: outline.border.color
0067             }
0068             GradientStop {
0069                 position: 1.0
0070                 color: outline.border.color
0071             }
0072         }
0073 
0074         border {
0075             color: isSelected ? Kirigami.Theme.highlightColor : Kirigami.Theme.disabledTextColor
0076             width: 1
0077 
0078             Behavior on color {
0079                 PropertyAnimation {
0080                     duration: Kirigami.Units.longDuration
0081                 }
0082             }
0083         }
0084     }
0085 
0086     Item {
0087         anchors.fill: parent
0088         // So we can show a grabby hand cursor when hovered over
0089         HoverHandler {
0090             cursorShape: kcm.multipleScreensAvailable ? Qt.SizeAllCursor : undefined
0091         }
0092         z: 2
0093     }
0094 
0095     Item {
0096         id: labelContainer
0097         anchors {
0098             fill: parent
0099             margins: outline.border.width
0100         }
0101 
0102         // so the text is drawn above orientationPanelContainer
0103         z: 1
0104         ColumnLayout {
0105             anchors.centerIn: parent
0106             spacing: 0
0107             width: parent.width
0108             Layout.maximumHeight: parent.height
0109 
0110             QQC2.Label {
0111                 Layout.fillWidth: true
0112                 Layout.maximumHeight: labelContainer.height - resolutionLabel.implicitHeight
0113 
0114                 text: model.display
0115                 wrapMode: Text.Wrap
0116                 horizontalAlignment: Text.AlignHCenter
0117                 elide: Text.ElideRight
0118             }
0119 
0120             QQC2.Label {
0121                 id: resolutionLabel
0122                 Layout.fillWidth: true
0123 
0124                 text: "(" + model.resolution.width + "x" + model.resolution.height +
0125                       (model.scale !== 1 ? "\u200B@" + Math.round(model.scale * 100.0) + "%": "") + ")"
0126                 wrapMode: Text.Wrap
0127                 horizontalAlignment: Text.AlignHCenter
0128                 elide: Text.ElideRight
0129             }
0130         }
0131     }
0132 
0133     states: [
0134         State {
0135             name: "transposed"
0136             PropertyChanges {
0137                 target: outline
0138                 width: output.height
0139                 height: output.width
0140             }
0141         },
0142 
0143         State {
0144             name: "rot0"
0145             when: model.rotation === 1
0146             PropertyChanges {
0147                 target: labelContainer
0148                 anchors.bottomMargin: outline.orientationPanelWidth + outline.border.width
0149             }
0150         },
0151         State {
0152             name: "rot90"
0153             extend: "transposed"
0154             when: model.rotation === 2
0155             PropertyChanges {
0156                 target: outline
0157                 rotation: 90
0158             }
0159             PropertyChanges {
0160                 target: labelContainer
0161                 anchors.leftMargin: outline.orientationPanelWidth + outline.border.width
0162             }
0163         },
0164         State {
0165             name: "rot180"
0166             when: model.rotation === 4
0167             PropertyChanges {
0168                 target: outline
0169                 rotation: 180
0170             }
0171             PropertyChanges {
0172                 target: labelContainer
0173                 anchors.topMargin: outline.orientationPanelWidth + outline.border.width
0174             }
0175         },
0176         State {
0177             name: "rot270"
0178             extend: "transposed"
0179             when: model.rotation === 8
0180             PropertyChanges {
0181                 target: outline
0182                 rotation: 270
0183             }
0184             PropertyChanges {
0185                 target: labelContainer
0186                 anchors.rightMargin: outline.orientationPanelWidth + outline.border.width
0187             }
0188         }
0189     ]
0190 
0191     Rectangle {
0192         id: posLabel
0193 
0194         y: 4
0195         x: 4
0196         width: childrenRect.width + 5
0197         height: childrenRect.height + 2
0198         radius: 4
0199 
0200         opacity: model.enabled &&
0201                  (tapHandler.isLongPressed || dragHandler.active) ? 0.9 : 0.0
0202 
0203 
0204         color: Kirigami.Theme.disabledTextColor
0205 
0206         Text {
0207             id: posLabelText
0208 
0209             y: 2
0210             x: 2
0211 
0212             text: model.normalizedPosition.x + "," + model.normalizedPosition.y
0213             color: "white"
0214         }
0215 
0216         Behavior on opacity {
0217             PropertyAnimation {
0218                 duration: Kirigami.Units.longDuration
0219             }
0220         }
0221     }
0222 
0223     QQC2.ToolButton {
0224         id: replicas
0225 
0226         property int selectedReplica: -1
0227 
0228         height: output.height / 4
0229         width: output.width / 5
0230         anchors.top: output.top
0231         anchors.right: output.right
0232         anchors.margins: 5
0233 
0234         visible: model.replicasModel.length > 0
0235         icon.name: "osd-duplicate"
0236 
0237         QQC2.ToolTip {
0238             text: i18n("Replicas")
0239         }
0240 
0241         onClicked: {
0242             var index = selectedReplica + 1;
0243             if (index >= model.replicasModel.length) {
0244                 index = 0;
0245             }
0246             if (root.selectedOutput !== model.replicasModel[index]) {
0247                 root.selectedOutput = model.replicasModel[index];
0248             }
0249         }
0250     }
0251 
0252     property point dragStartPosition
0253 
0254     TapHandler {
0255         id: tapHandler
0256         property bool isLongPressed: false
0257         gesturePolicy: TapHandler.WithinBounds
0258 
0259         onPressedChanged: {
0260             if (pressed) {
0261                 root.selectedOutput = model.index;
0262                 dragStartPosition = Qt.point(output.x, output.y)
0263             } else {
0264                 isLongPressed = false;
0265             }
0266         }
0267         onLongPressed: isLongPressed = true;
0268         longPressThreshold: 0.3
0269     }
0270     DragHandler {
0271         id: dragHandler
0272         enabled: kcm.multipleScreensAvailable
0273         acceptedButtons: Qt.LeftButton
0274         grabPermissions: PointerHandler.CanTakeOverFromAnything | PointerHandler.TakeOverForbidden
0275         target: null
0276 
0277         onTranslationChanged: {
0278             var newX = dragStartPosition.x + translation.x;
0279             var newY = dragStartPosition.y + translation.y;
0280             model.position = getAbsolutePosition(Qt.point(newX, newY));
0281         }
0282         onActiveChanged: {
0283             model.interactiveMove = active;
0284             if (!active) {
0285                 screen.resetTotalSize();
0286             }
0287         }
0288     }
0289 }
0290