on xenial help sign in
Fix app thumbnails on rotated Shell

- Also fix stage position when rotated while on foreground

commit9e775f28b6ea56003309e4c9c8916c214e4f66b7 authorDaniel d'Andrada <daniel.dandrada@canonical.com> dateMon 19 May 2014, 16:11 (12 years ago) parent784c062
7 files changed+138−36
qml/Dash/Apps/RunningApplicationTile.qml+95−33 qml/Dash/Apps/RunningApplicationsGrid.qml+3 qml/Dash/Dash.qml+3 qml/Dash/DashContent.qml+5 qml/Dash/GenericScopeView.qml+6 qml/Shell.qml+3−1 tests/qmltests/Dash/Apps/tst_RunningApplicationsGrid.qml+23−2
qml/Dash/Apps/RunningApplicationTile.qml+95−33
@@ -29,11 +29,11 @@ AbstractButton {
2929 signal requestedActivationMode()
3030 signal requestedTerminationMode()
3131
32− // Was: childrenRect.height
33− // To avoid "binding loop" warning
34− height: shapedApplicationImage.height + labelContainer.height
32+ width: thumbnail.width
33+ height: thumbnail.height + labelContainer.height
3534
36− width: shapedApplicationImage.width <= units.gu(11) ? units.gu(11) : height
35+ // Orientation angle of the Shell UI, relative to the scene (QQuickView's) root item.
36+ property int orientationAngle
3737
3838 property bool terminationModeEnabled: false
3939
@@ -50,42 +50,104 @@ AbstractButton {
5050 }
5151 }
5252
53− UbuntuShape {
54− id: shapedApplicationImage
55− anchors { top: parent.top; horizontalCenter: parent.horizontalCenter }
56−
57− height: units.gu(17)
58− width: applicationImage.width
59− radius: "medium"
60−
61− image: Image {
62− id: applicationImage
63− source: application.screenshot
64− // height : width = ss.height : ss.width
65− height: shapedApplicationImage.height
66− fillMode: Image.PreserveAspectCrop
67− width: Math.min(height, height * sourceSize.width / sourceSize.height)
68− }
53+ Item {
54+ id: thumbnail
55+
56+ width: thumbnailHelper.flippedDimensions ? shapedApplicationImage.height : shapedApplicationImage.width
57+ height: thumbnailHelper.flippedDimensions ? shapedApplicationImage.width : shapedApplicationImage.height
58+
59+ onWidthChanged: {console.log("thumbnail.width = " + width);}
60+ onHeightChanged: {console.log("thumbnail.height = " + height);}
61+
62+
63+ Item {
64+ id: thumbnailHelper
65+
66+ property bool flippedDimensions: root.orientationAngle == 90 || root.orientationAngle == 270
67+
68+ // Compensate for the UI rotation that is done by the application itself
69+ // TODO: Only counter-rotate if the application UI is rotated in the first place
70+ // Currently we don't have this info, so we just assume every single app rotate
71+ // its UI
72+ transformOrigin: Item.TopLeft
73+ state: orientationAngle.toString()
74+ states: [
75+ State {
76+ name: "0"
77+ PropertyChanges {
78+ target: thumbnailHelper
79+ rotation: 0
80+ x: 0
81+ y: 0
82+ }
83+ },
84+ State {
85+ name: "90"
86+ PropertyChanges {
87+ target: thumbnailHelper
88+ rotation: -90
89+ x: 0
90+ y: shapedApplicationImage.width
91+ }
92+ },
93+ State {
94+ name: "180"
95+ PropertyChanges {
96+ target: thumbnailHelper
97+ rotation: -180
98+ x: shapedApplicationImage.width
99+ y: shapedApplicationImage.height
100+ }
101+ },
102+ State {
103+ name: "270"
104+ PropertyChanges {
105+ target: thumbnailHelper
106+ rotation: -270
107+ x: shapedApplicationImage.height
108+ y: 0
109+ }
110+ }
111+ ]
112+
113+ UbuntuShape {
114+ id: shapedApplicationImage
115+ x: 0
116+ y: 0
117+ height: applicationImage.height
118+ width: applicationImage.width
119+ radius: "medium"
120+
121+ image: Image {
122+ id: applicationImage
123+ source: application.screenshot
124+ // height : width = ss.height : ss.width
125+ height: units.gu(17)
126+ fillMode: Image.PreserveAspectCrop
127+ width: Math.min(height, height * sourceSize.width / sourceSize.height)
128+ }
69129
70− }
130+ }
71131
72− UbuntuShape {
73− id: borderPressed
132+ UbuntuShape {
133+ id: borderPressed
74134
75− anchors.fill: shapedApplicationImage
76− radius: "medium"
77− borderSource: "radius_pressed.sci"
78− opacity: root.pressed ? 1.0 : 0.0
79− Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.OutQuint } }
135+ anchors.fill: shapedApplicationImage
136+ radius: "medium"
137+ borderSource: "radius_pressed.sci"
138+ opacity: root.pressed ? 1.0 : 0.0
139+ Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.OutQuint } }
140+ }
141+ }
80142 }
81143
82144 // FIXME: label code duplicated with Tile
83145 Item {
84146 id: labelContainer
85147 anchors {
86− left: parent.left
87− right: parent.right
88− top: shapedApplicationImage.bottom
148+ left: thumbnail.left
149+ right: thumbnail.right
150+ top: thumbnail.bottom
89151 }
90152 height: units.gu(2)
91153
@@ -110,9 +172,9 @@ AbstractButton {
110172 CloseIcon {
111173 objectName: "closeIcon " + model.name
112174 anchors {
113− left: shapedApplicationImage.left
175+ left: thumbnail.left
114176 leftMargin: -units.gu(1)
115− top: parent.top
177+ top: thumbnail.top
116178 topMargin: -units.gu(1)
117179 }
118180 height: units.gu(6)
qml/Dash/Apps/RunningApplicationsGrid.qml+3
@@ -28,6 +28,8 @@ ResponsiveFlowView {
2828 property alias enableHeightBehavior: heightBehaviour.enabled
2929 property bool enableHeightBehaviorOnNextCreation: model.count === 0
3030
31+ property int orientationAngle
32+
3133 Behavior on height {
3234 id: heightBehaviour
3335 enabled: false
@@ -63,6 +65,7 @@ ResponsiveFlowView {
6365 RunningApplicationTile {
6466 id: runningAppTile
6567 objectName: "runningAppTile " + model.name
68+ orientationAngle: root.orientationAngle
6669 anchors {
6770 top: parent.top
6871 horizontalCenter: parent.horizontalCenter
qml/Dash/Dash.qml+3
@@ -26,6 +26,8 @@ Showable {
2626
2727 visible: shown
2828
29+ property int orientationAngle
30+
2931 property ListModel searchHistory: SearchHistoryModel {}
3032 property bool searchable: !dashContent.previewOpen && !scopeItem.previewOpen
3133
@@ -74,6 +76,7 @@ Showable {
7476 objectName: "dashContent"
7577 width: parent.width
7678 height: parent.height
79+ orientationAngle: dash.orientationAngle
7780 model: filteredScopes
7881 scopes: scopes
7982 searchHistory: dash.searchHistory
qml/Dash/DashContent.qml+5
@@ -23,6 +23,7 @@ import "../Components"
2323Item {
2424 id: dashContent
2525
26+ property int orientationAngle
2627 property var model: null
2728 property var scopes: null
2829 readonly property alias currentIndex: dashContentList.currentIndex
@@ -153,6 +154,10 @@ Item {
153154 item.isCurrent = Qt.binding(function() { return visible && ListView.isCurrentItem })
154155 item.tabBarHeight = dashPageHeader.implicitHeight;
155156 dashContent.scopeLoaded(item.scope.id)
157+
158+ if ("orientationAngle" in item) {
159+ item.orientationAngle = Qt.binding(function() { return dashContent.orientationAngle })
160+ }
156161 }
157162 Connections {
158163 target: isCurrent ? scope : null
qml/Dash/GenericScopeView.qml+6
@@ -25,6 +25,7 @@ import "../Components/ListItems" as ListItems
2525FocusScope {
2626 id: scopeView
2727
28+ property int orientationAngle
2829 property Scope scope: null
2930 property SortFilterProxyModel categories: categoryFilter
3031 property bool isCurrent: false
@@ -165,6 +166,11 @@ FocusScope {
165166 } else {
166167 item.model = Qt.binding(function() { return results })
167168 }
169+
170+ if ("orientationAngle" in item) {
171+ item.orientationAngle = Qt.binding(function() { return scopeView.orientationAngle })
172+ }
173+
168174 item.objectName = Qt.binding(function() { return categoryId })
169175 if (item.expandable) {
170176 var shouldFilter = categoryId != categoryView.expandedCategoryId;
qml/Shell.qml+3−1
@@ -121,6 +121,8 @@ FocusScope {
121121 id: dash
122122 objectName: "dash"
123123
124+ orientationAngle: shell.orientationAngle
125+
124126 available: !greeter.shown && !lockscreen.shown
125127 hides: [stages, launcher, panel.indicators]
126128 shown: disappearingAnimationProgress !== 1.0 && greeterWrapper.showProgress !== 1.0
@@ -164,7 +166,7 @@ FocusScope {
164166 if (!stages.empty && progress < stages.width - units.gu(10)) {
165167 stages.show();
166168 }
167− stagesDragArea.progress = stages.width;
169+ stagesDragArea.progress = Qt.binding(function () { return stages.width; });
168170 }
169171 }
170172 }
tests/qmltests/Dash/Apps/tst_RunningApplicationsGrid.qml+23−2
@@ -19,10 +19,11 @@ import QtTest 1.0
1919import "../../../../qml/Dash/Apps"
2020import Unity.Test 0.1 as UT
2121import Unity.Application 0.1
22+import Ubuntu.Components 1.1
2223
2324// Using Rectangle to have an opaque surface because AppManager paints app surfaces behind it.
2425Rectangle {
25− width: units.gu(50)
26+ width: units.gu(70)
2627 height: units.gu(40)
2728
2829 function resetRunningApplications() {
@@ -41,10 +42,30 @@ Rectangle {
4142 // The component under test
4243 RunningApplicationsGrid {
4344 id: runningApplicationsGrid
44− anchors.fill: parent
45+ orientationAngle: orientationAngleSelector.selectedIndex * 90
46+ anchors.left: parent.left
47+ anchors.right: controlPanel.left
48+ anchors.top: parent.top
49+ anchors.bottom: parent.bottom
4550 model: ApplicationManager
4651 }
4752
53+ Rectangle {
54+ id: controlPanel
55+ anchors.right: parent.right
56+ anchors.top: parent.top
57+ anchors.bottom: parent.bottom
58+ width: units.gu(20)
59+ color: "black"
60+
61+ OptionSelector {
62+ id: orientationAngleSelector
63+ model: ["0","90","180","270"]
64+ text: "Orientation Angle"
65+ width: parent.width
66+ }
67+ }
68+
4869 UT.UnityTestCase {
4970 name: "RunningApplicationsGrid"
5071 when: windowShown