on 9f59192 help sign in
unity8/qml/OrientedShell.qml
216 lines 7.8 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 "Rotation"
24Rectangle {
25 id: root
26 color: "black"
28 // NB: native and primary orientations here don't map exactly to their QScreen counterparts
29 readonly property int nativeOrientation: width > height ? Qt.LandscapeOrientation : Qt.PortraitOrientation
31 readonly property int primaryOrientation:
32 deviceConfiguration.primaryOrientation == deviceConfiguration.useNativeOrientation
33 ? nativeOrientation : deviceConfiguration.primaryOrientation
35 DeviceConfiguration {
36 id: deviceConfiguration
37 name: applicationArguments.deviceName
38 }
40 UnityInputInfo {
41 id: inputInfo
42 Component.onCompleted: {
43 // We need to manually update this on startup as the binding
44 // below doesn't seem to have any effect at that stage
45 oskSettings.stayHidden = keyboards > 0
46 oskSettings.disableHeight = shell.usageScenario == "desktop"
47 }
48 }
50 GSettings {
51 id: oskSettings
52 schema.id: "com.canonical.keyboard.maliit"
53 }
55 Binding {
56 target: oskSettings
57 property: "stayHidden"
58 value: inputInfo.keyboards > 0
59 }
61 Binding {
62 target: oskSettings
63 property: "disableHeight"
64 value: shell.usageScenario == "desktop"
65 }
67 // to be overwritten by tests
68 property var usageModeSettings: GSettings { schema.id: "com.canonical.Unity8" }
69 property int physicalOrientation: Screen.orientation
70 property bool orientationLocked: OrientationLock.enabled
71 property var orientationLock: OrientationLock
73 property int orientation
74 onPhysicalOrientationChanged: {
75 if (!orientationLocked) {
76 orientation = physicalOrientation;
77 }
78 }
79 onOrientationLockedChanged: {
80 if (orientationLocked) {
81 orientationLock.savedOrientation = physicalOrientation;
82 } else {
83 orientation = physicalOrientation;
84 }
85 }
86 Component.onCompleted: {
87 if (orientationLocked) {
88 orientation = orientationLock.savedOrientation;
89 }
90 }
92 readonly property int supportedOrientations: shell.supportedOrientations
93 & deviceConfiguration.supportedOrientations
94 property int acceptedOrientationAngle: {
95 if (orientation & supportedOrientations) {
96 return Screen.angleBetween(nativeOrientation, orientation);
97 } else if (shell.orientation & supportedOrientations) {
98 // stay where we are
99 return shell.orientationAngle;
100 } else if (angleToOrientation(shell.mainAppWindowOrientationAngle) & supportedOrientations) {
101 return shell.mainAppWindowOrientationAngle;
102 } else {
103 // rotate to some supported orientation as we can't stay where we currently are
104 // TODO: Choose the closest to the current one
105 if (supportedOrientations & Qt.PortraitOrientation) {
106 return Screen.angleBetween(nativeOrientation, Qt.PortraitOrientation);
107 } else if (supportedOrientations & Qt.LandcscapeOrientation) {
108 return Screen.angleBetween(nativeOrientation, Qt.LandscapeOrientation);
109 } else if (supportedOrientations & Qt.InvertedPortraitOrientation) {
110 return Screen.angleBetween(nativeOrientation, Qt.InvertedPortraitOrientation);
111 } else if (supportedOrientations & Qt.InvertedLandscapeOrientation) {
112 return Screen.angleBetween(nativeOrientation, Qt.InvertedLandscapeOrientation);
113 } else {
114 // if all fails, fallback to primary orientation
115 return Screen.angleBetween(nativeOrientation, primaryOrientation);
116 }
117 }
118 }
120 function angleToOrientation(angle) {
121 switch (angle) {
122 case 0:
123 return nativeOrientation;
124 break;
125 case 90:
126 return nativeOrientation === Qt.PortraitOrientation ? Qt.InvertedLandscapeOrientation
127 : Qt.PortraitOrientation;
128 break;
129 case 180:
130 return nativeOrientation === Qt.PortraitOrientation ? Qt.InvertedPortraitOrientation
131 : Qt.InvertedLandscapeOrientation;
132 break;
133 case 270:
134 return nativeOrientation === Qt.PortraitOrientation ? Qt.LandscapeOrientation
135 : Qt.InvertedPortraitOrientation;
136 break;
137 default:
138 console.warn("angleToOrientation: Invalid orientation angle: " + angle);
139 return primaryOrientation;
140 }
141 }
143 RotationStates {
144 id: rotationStates
145 objectName: "rotationStates"
146 orientedShell: root
147 shell: shell
148 shellCover: shellCover
149 windowScreenshot: windowScreenshot
150 }
152 Shell {
153 id: shell
154 objectName: "shell"
155 width: root.width
156 height: root.height
157 orientation: root.angleToOrientation(orientationAngle)
158 primaryOrientation: root.primaryOrientation
159 nativeOrientation: root.nativeOrientation
160 nativeWidth: root.width
161 nativeHeight: root.height
163 // TODO: Factor in the connected input devices (eg: physical keyboard, mouse, touchscreen),
164 // what's the output device (eg: big TV, desktop monitor, phone display), etc.
165 usageScenario: {
166 if (root.usageModeSettings.usageMode === "Windowed") {
167 return "desktop";
168 } else if (root.usageModeSettings.usageMode === "Staged") {
169 if (deviceConfiguration.category === "phone") {
170 return "phone";
171 } else {
172 return "tablet";
173 }
174 } else { // automatic
175 if (inputInfo.mice > 0) {
176 return "desktop";
177 } else {
178 return deviceConfiguration.category;
179 }
180 }
181 }
183 property real transformRotationAngle
184 property real transformOriginX
185 property real transformOriginY
187 transform: Rotation {
188 origin.x: shell.transformOriginX; origin.y: shell.transformOriginY; axis { x: 0; y: 0; z: 1 }
189 angle: shell.transformRotationAngle
190 }
191 }
193 Rectangle {
194 id: shellCover
195 color: "black"
196 anchors.fill: parent
197 visible: false
198 }
200 WindowScreenshot {
201 id: windowScreenshot
202 visible: false
203 width: root.width
204 height: root.height
206 property real transformRotationAngle
207 property real transformOriginX
208 property real transformOriginY
210 transform: Rotation {
211 origin.x: windowScreenshot.transformOriginX; origin.y: windowScreenshot.transformOriginY;
212 axis { x: 0; y: 0; z: 1 }
213 angle: windowScreenshot.transformRotationAngle
214 }
215 }