Changeset View
Changeset View
Standalone View
Standalone View
kcm/package/contents/ui/Output.qml
- This file was added.
1 | /******************************************************************** | ||||
---|---|---|---|---|---|
2 | Copyright © 2019 Roman Gilg <subdiff@gmail.com> | ||||
3 | Copyright © 2012 Dan Vratil <dvratil@redhat.com> | ||||
4 | | ||||
5 | This program is free software; you can redistribute it and/or modify | ||||
6 | it under the terms of the GNU General Public License as published by | ||||
7 | the Free Software Foundation; either version 2 of the License, or | ||||
8 | (at your option) any later version. | ||||
9 | | ||||
10 | This program is distributed in the hope that it will be useful, | ||||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
13 | GNU General Public License for more details. | ||||
14 | | ||||
15 | You should have received a copy of the GNU General Public License | ||||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
17 | *********************************************************************/ | ||||
18 | import QtQuick 2.12 | ||||
19 | import QtQuick.Layouts 1.1 | ||||
20 | import QtQuick.Controls 2.3 as Controls | ||||
21 | import QtGraphicalEffects 1.0 | ||||
22 | | ||||
23 | Rectangle { | ||||
24 | id: output | ||||
25 | | ||||
26 | property bool isSelected: root.selectedOutput === model.index | ||||
27 | | ||||
28 | onIsSelectedChanged: { | ||||
29 | if (isSelected) { | ||||
30 | z = 89; | ||||
31 | } else { | ||||
32 | z = 0; | ||||
33 | } | ||||
34 | } | ||||
35 | | ||||
36 | function getAbsolutePosition(pos) { | ||||
37 | return Qt.point((pos.x - screen.xOffset) * screen.relativeFactor, | ||||
38 | (pos.y - screen.yOffset) * screen.relativeFactor) ; | ||||
39 | } | ||||
40 | | ||||
41 | visible: model.enabled | ||||
42 | onVisibleChanged: screen.resetTotalSize() | ||||
43 | | ||||
44 | x: model.position.x / screen.relativeFactor + screen.xOffset | ||||
45 | y: model.position.y / screen.relativeFactor + screen.yOffset | ||||
46 | | ||||
47 | width: model.size.width / screen.relativeFactor | ||||
48 | height: model.size.height / screen.relativeFactor | ||||
49 | | ||||
50 | SystemPalette { | ||||
51 | id: palette | ||||
52 | } | ||||
53 | | ||||
54 | radius: 4 | ||||
55 | color: palette.window | ||||
56 | smooth: true | ||||
57 | clip: true | ||||
58 | | ||||
59 | border { | ||||
60 | color: isSelected ? palette.highlight : palette.shadow | ||||
61 | width: 1 | ||||
62 | | ||||
63 | Behavior on color { | ||||
64 | PropertyAnimation { | ||||
65 | duration: 150 | ||||
66 | } | ||||
67 | } | ||||
68 | } | ||||
69 | | ||||
70 | Item { | ||||
71 | anchors.fill: parent | ||||
72 | | ||||
73 | ColumnLayout { | ||||
74 | anchors.centerIn: parent | ||||
75 | spacing: units.smallSpacing | ||||
76 | width: parent.width | ||||
77 | Layout.maximumHeight: parent.height | ||||
78 | | ||||
79 | Controls.Label { | ||||
80 | Layout.fillWidth: true | ||||
81 | Layout.margins: units.smallSpacing | ||||
82 | | ||||
83 | text: model.display | ||||
84 | horizontalAlignment: Text.AlignHCenter | ||||
85 | elide: Text.ElideRight | ||||
86 | color: palette.text | ||||
87 | } | ||||
88 | | ||||
89 | Controls.Label { | ||||
90 | Layout.fillWidth: true | ||||
91 | Layout.margins: units.smallSpacing | ||||
92 | | ||||
93 | text: "(" + model.size.width + "x" + model.size.height + ")" | ||||
94 | horizontalAlignment: Text.AlignHCenter | ||||
95 | elide: Text.ElideRight | ||||
96 | color: palette.text | ||||
97 | } | ||||
98 | } | ||||
99 | } | ||||
100 | | ||||
101 | Rectangle { | ||||
102 | id: posLabel | ||||
103 | | ||||
104 | y: 4 | ||||
105 | x: 4 | ||||
106 | width: childrenRect.width + 5 | ||||
107 | height: childrenRect.height + 2 | ||||
108 | radius: 4 | ||||
109 | | ||||
110 | opacity: model.enabled && | ||||
111 | (tapHandler.isLongPressed || dragHandler.active) ? 0.9 : 0.0 | ||||
112 | | ||||
113 | | ||||
114 | color: palette.shadow | ||||
115 | | ||||
116 | Text { | ||||
117 | id: posLabelText | ||||
118 | | ||||
119 | y: 2 | ||||
120 | x: 2 | ||||
121 | | ||||
122 | text: model.normalizedPosition.x + "," + model.normalizedPosition.y | ||||
123 | color: "white" | ||||
124 | } | ||||
125 | | ||||
126 | Behavior on opacity { | ||||
127 | PropertyAnimation { | ||||
128 | duration: 100; | ||||
129 | } | ||||
130 | } | ||||
131 | } | ||||
132 | | ||||
133 | Item { | ||||
134 | id: orientationPanelContainer | ||||
135 | | ||||
136 | anchors.fill: output | ||||
137 | visible: false | ||||
138 | | ||||
139 | Rectangle { | ||||
140 | id: orientationPanel | ||||
141 | anchors { | ||||
142 | left: parent.left | ||||
143 | right: parent.right | ||||
144 | bottom: parent.bottom | ||||
145 | } | ||||
146 | | ||||
147 | height: 10 | ||||
148 | color: isSelected ? palette.highlight : palette.shadow | ||||
149 | smooth: true | ||||
150 | | ||||
151 | Behavior on color { | ||||
152 | PropertyAnimation { | ||||
153 | duration: 150 | ||||
154 | } | ||||
155 | } | ||||
156 | } | ||||
157 | } | ||||
158 | | ||||
159 | states: [ | ||||
160 | State { | ||||
161 | name: "rot90" | ||||
162 | when: model.rotation === 2 | ||||
163 | PropertyChanges { | ||||
164 | target: orientationPanel | ||||
165 | height: undefined | ||||
166 | width: 10 | ||||
167 | } | ||||
168 | AnchorChanges { | ||||
169 | target: orientationPanel | ||||
170 | anchors.right: undefined | ||||
171 | anchors.top: orientationPanelContainer.top | ||||
172 | } | ||||
173 | }, | ||||
174 | State { | ||||
175 | name: "rot180" | ||||
176 | when: model.rotation === 4 | ||||
177 | AnchorChanges { | ||||
178 | target: orientationPanel | ||||
179 | anchors.top: orientationPanelContainer.top | ||||
180 | anchors.bottom: undefined | ||||
181 | } | ||||
182 | }, | ||||
183 | State { | ||||
184 | name: "rot270" | ||||
185 | when: model.rotation === 8 | ||||
186 | PropertyChanges { | ||||
187 | target: orientationPanel | ||||
188 | height: undefined | ||||
189 | width: 10 | ||||
190 | } | ||||
191 | AnchorChanges { | ||||
192 | target: orientationPanel | ||||
193 | anchors.left: undefined | ||||
194 | anchors.top: orientationPanelContainer.top | ||||
195 | } | ||||
196 | } | ||||
197 | ] | ||||
198 | | ||||
199 | OpacityMask { | ||||
200 | anchors.fill: orientationPanelContainer | ||||
201 | source: orientationPanelContainer | ||||
202 | maskSource: output | ||||
203 | } | ||||
204 | | ||||
205 | property point dragStartPosition | ||||
206 | | ||||
207 | TapHandler { | ||||
208 | id: tapHandler | ||||
209 | property bool isLongPressed: false | ||||
210 | | ||||
211 | function bindSelectedOutput() { | ||||
212 | root.selectedOutput | ||||
213 | = Qt.binding(function() { return model.index; }); | ||||
214 | } | ||||
215 | onPressedChanged: { | ||||
216 | if (pressed) { | ||||
217 | bindSelectedOutput(); | ||||
218 | dragStartPosition = Qt.point(output.x, output.y) | ||||
219 | } else { | ||||
220 | isLongPressed = false; | ||||
221 | } | ||||
222 | } | ||||
223 | onLongPressed: isLongPressed = true; | ||||
224 | longPressThreshold: 0.3 | ||||
225 | } | ||||
226 | DragHandler { | ||||
227 | id: dragHandler | ||||
228 | acceptedButtons: Qt.LeftButton | ||||
229 | target: null | ||||
230 | | ||||
231 | onTranslationChanged: { | ||||
232 | var newX = dragStartPosition.x + translation.x; | ||||
233 | var newY = dragStartPosition.y + translation.y; | ||||
234 | model.position = getAbsolutePosition(Qt.point(newX, newY)); | ||||
235 | } | ||||
236 | } | ||||
237 | } | ||||
238 | |