on 555cc15 help sign in
unity8/qml/OrientedShell.qml
222 lines 8.4 kB history raw
1/*
2 * Copyright (C) 2015 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
17import QtQuick 2.0
18import QtQuick.Window 2.0
19import Unity.Session 0.1
20import GSettings 1.0
21import "Components"
22import "Components/UnityInputInfo"
23import "Rotation"
24// Backup Workaround https://bugs.launchpad.net/ubuntu/+source/unity8/+bug/1473471
25// in case we remove the UnityInputInfo import
26import Ubuntu.Components 1.2
28Rectangle {
29 id: root
30 color: "black"
32 implicitWidth: units.gu(40)
33 implicitHeight: units.gu(71)
35 // NB: native and primary orientations here don't map exactly to their QScreen counterparts
36 readonly property int nativeOrientation: width > height ? Qt.LandscapeOrientation : Qt.PortraitOrientation
38 readonly property int primaryOrientation:
39 deviceConfiguration.primaryOrientation == deviceConfiguration.useNativeOrientation
40 ? nativeOrientation : deviceConfiguration.primaryOrientation
42 DeviceConfiguration {
43 id: deviceConfiguration
44 name: applicationArguments.deviceName
45 }
48 // to be overwritten by tests
49 property var unity8Settings: Unity8Settings {}
50 property var oskSettings: GSettings { schema.id: "com.canonical.keyboard.maliit" }
52 property int physicalOrientation: Screen.orientation
53 property bool orientationLocked: OrientationLock.enabled
54 property var orientationLock: OrientationLock
56 property int orientation
57 onPhysicalOrientationChanged: {
58 if (!orientationLocked) {
59 orientation = physicalOrientation;
60 }
61 }
62 onOrientationLockedChanged: {
63 if (orientationLocked) {
64 orientationLock.savedOrientation = physicalOrientation;
65 } else {
66 orientation = physicalOrientation;
67 }
68 }
69 Component.onCompleted: {
70 if (orientationLocked) {
71 orientation = orientationLock.savedOrientation;
72 }
73 // We need to manually update this on startup as the binding
74 // below doesn't seem to have any effect at that stage
75 oskSettings.stayHidden = UnityInputInfo.keyboards > 0
76 oskSettings.disableHeight = shell.usageScenario == "desktop"
77 }
79 // we must rotate to a supported orientation regardless of shell's preference
80 property bool orientationChangesEnabled:
81 (orientation & supportedOrientations) === 0 ? true
82 : shell.orientationChangesEnabled
85 Binding {
86 target: oskSettings
87 property: "stayHidden"
88 value: UnityInputInfo.keyboards > 0
89 }
91 Binding {
92 target: oskSettings
93 property: "disableHeight"
94 value: shell.usageScenario == "desktop"
95 }
97 readonly property int supportedOrientations: shell.supportedOrientations
98 & (deviceConfiguration.supportedOrientations == deviceConfiguration.useNativeOrientation
99 ? nativeOrientation
100 : deviceConfiguration.supportedOrientations)
102 property int acceptedOrientationAngle: {
103 if (orientation & supportedOrientations) {
104 return Screen.angleBetween(nativeOrientation, orientation);
105 } else if (shell.orientation & supportedOrientations) {
106 // stay where we are
107 return shell.orientationAngle;
108 } else if (angleToOrientation(shell.mainAppWindowOrientationAngle) & supportedOrientations) {
109 return shell.mainAppWindowOrientationAngle;
110 } else {
111 // rotate to some supported orientation as we can't stay where we currently are
112 // TODO: Choose the closest to the current one
113 if (supportedOrientations & Qt.PortraitOrientation) {
114 return Screen.angleBetween(nativeOrientation, Qt.PortraitOrientation);
115 } else if (supportedOrientations & Qt.LandscapeOrientation) {
116 return Screen.angleBetween(nativeOrientation, Qt.LandscapeOrientation);
117 } else if (supportedOrientations & Qt.InvertedPortraitOrientation) {
118 return Screen.angleBetween(nativeOrientation, Qt.InvertedPortraitOrientation);
119 } else if (supportedOrientations & Qt.InvertedLandscapeOrientation) {
120 return Screen.angleBetween(nativeOrientation, Qt.InvertedLandscapeOrientation);
121 } else {
122 // if all fails, fallback to primary orientation
123 return Screen.angleBetween(nativeOrientation, primaryOrientation);
124 }
125 }
126 }
128 function angleToOrientation(angle) {
129 switch (angle) {
130 case 0:
131 return nativeOrientation;
132 case 90:
133 return nativeOrientation === Qt.PortraitOrientation ? Qt.InvertedLandscapeOrientation
134 : Qt.PortraitOrientation;
135 case 180:
136 return nativeOrientation === Qt.PortraitOrientation ? Qt.InvertedPortraitOrientation
137 : Qt.InvertedLandscapeOrientation;
138 case 270:
139 return nativeOrientation === Qt.PortraitOrientation ? Qt.LandscapeOrientation
140 : Qt.InvertedPortraitOrientation;
141 default:
142 console.warn("angleToOrientation: Invalid orientation angle: " + angle);
143 return primaryOrientation;
144 }
145 }
147 RotationStates {
148 id: rotationStates
149 objectName: "rotationStates"
150 orientedShell: root
151 shell: shell
152 shellCover: shellCover
153 windowScreenshot: windowScreenshot
154 }
156 Shell {
157 id: shell
158 objectName: "shell"
159 width: root.width
160 height: root.height
161 orientation: root.angleToOrientation(orientationAngle)
162 primaryOrientation: root.primaryOrientation
163 nativeOrientation: root.nativeOrientation
164 nativeWidth: root.width
165 nativeHeight: root.height
166 mode: applicationArguments.mode
167 hasMouse: UnityInputInfo.mice > deviceConfiguration.ignoredMice
169 // TODO: Factor in the connected input devices (eg: physical keyboard, mouse, touchscreen),
170 // what's the output device (eg: big TV, desktop monitor, phone display), etc.
171 usageScenario: {
172 if (root.unity8Settings.usageMode === "Windowed") {
173 return "desktop";
174 } else if (root.unity8Settings.usageMode === "Staged") {
175 if (deviceConfiguration.category === "phone") {
176 return "phone";
177 } else {
178 return "tablet";
179 }
180 } else { // automatic
181 if (UnityInputInfo.mice > deviceConfiguration.ignoredMice) {
182 return "desktop";
183 } else {
184 return deviceConfiguration.category;
185 }
186 }
187 }
189 property real transformRotationAngle
190 property real transformOriginX
191 property real transformOriginY
193 transform: Rotation {
194 origin.x: shell.transformOriginX; origin.y: shell.transformOriginY; axis { x: 0; y: 0; z: 1 }
195 angle: shell.transformRotationAngle
196 }
197 }
199 Rectangle {
200 id: shellCover
201 color: "black"
202 anchors.fill: parent
203 visible: false
204 }
206 WindowScreenshot {
207 id: windowScreenshot
208 visible: false
209 width: root.width
210 height: root.height
212 property real transformRotationAngle
213 property real transformOriginX
214 property real transformOriginY
216 transform: Rotation {
217 origin.x: windowScreenshot.transformOriginX; origin.y: windowScreenshot.transformOriginY;
218 axis { x: 0; y: 0; z: 1 }
219 angle: windowScreenshot.transformRotationAngle
220 }
221 }