Merge lp:~zsombi/ubuntu-ui-toolkit/83-rtl-support into lp:ubuntu-ui-toolkit/staging

Proposed by Zsombor Egri
Status: Merged
Approved by: Tim Peeters
Approved revision: 1423
Merged at revision: 1424
Proposed branch: lp:~zsombi/ubuntu-ui-toolkit/83-rtl-support
Merge into: lp:ubuntu-ui-toolkit/staging
Prerequisite: lp:~zsombi/ubuntu-ui-toolkit/82-dragging-mode
Diff against target: 302 lines (+108/-35)
3 files modified
modules/Ubuntu/Components/Themes/Ambiance/ListItemStyle.qml (+12/-6)
tests/resources/listitems/ListItemDragging.qml (+13/-2)
tests/unit_x11/tst_components/tst_listitem.qml (+83/-27)
To merge this branch: bzr merge lp:~zsombi/ubuntu-ui-toolkit/83-rtl-support
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Tim Peeters Approve
Review via email: mp+250948@code.launchpad.net

Commit message

RTL (Right To Left) support in ListItem.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1422. By Zsombor Egri

prereq sync

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Tim Peeters (tpeeters) wrote :

32 - snapIn = leadingPanel;
33 + snapIn = listItemStyle.LayoutMirroring.enabled ? !leadingPanel : leadingPanel;
34 snapChangerLimit = listItemStyle.x - threshold;
35 } else if (prevX > listItemStyle.x && (listItemStyle.x < snapChangerLimit)) {
36 - snapIn = !leadingPanel;
37 + snapIn = listItemStyle.LayoutMirroring.enabled ? leadingPanel : !leadingPanel;

this is a bit shorter:
33 + snapIn = (listItemStyle.LayoutMirroring.enabled !== leadingPanel)
37 + snapIn = (listItemStyle.LayoutMirroring.enabled === leadingPanel)

1423. By Zsombor Egri

review comment addressed

Revision history for this message
Zsombor Egri (zsombi) wrote :

> 32 - snapIn = leadingPanel;
> 33 + snapIn = listItemStyle.LayoutMirroring.enabled ?
> !leadingPanel : leadingPanel;
> 34 snapChangerLimit = listItemStyle.x - threshold;
> 35 } else if (prevX > listItemStyle.x && (listItemStyle.x <
> snapChangerLimit)) {
> 36 - snapIn = !leadingPanel;
> 37 + snapIn = listItemStyle.LayoutMirroring.enabled ?
> leadingPanel : !leadingPanel;
>
> this is a bit shorter:
> 33 + snapIn = (listItemStyle.LayoutMirroring.enabled !== leadingPanel)
> 37 + snapIn = (listItemStyle.LayoutMirroring.enabled === leadingPanel)

Done :)

Revision history for this message
Tim Peeters (tpeeters) wrote :

nice, thanks

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'modules/Ubuntu/Components/Themes/Ambiance/ListItemStyle.qml'
2--- modules/Ubuntu/Components/Themes/Ambiance/ListItemStyle.qml 2015-02-25 11:21:57 +0000
3+++ modules/Ubuntu/Components/Themes/Ambiance/ListItemStyle.qml 2015-02-27 14:20:38 +0000
4@@ -37,6 +37,7 @@
5 right: styledItem.contentItem.right
6 rightMargin: -styledItem.contentItem.anchors.rightMargin
7 }
8+ LayoutMirroring.childrenInherit: true
9
10 // leading/trailing panels
11 Component {
12@@ -316,10 +317,11 @@
13 // action triggered
14 property Action selectedAction
15 // swipe handling
16- readonly property bool swiped: listItemStyle.x != styledItem.x && !styledItem.selectMode
17- readonly property Item swipedPanel: listItemStyle.x > 0 ? leadingLoader.item : trailingLoader.item
18- readonly property bool leadingPanel: listItemStyle.x > 0
19- readonly property real swipedOffset: leadingPanel ? listItemStyle.x : -listItemStyle.x
20+ readonly property bool swiped: listItemStyle.x != styledItem.x && !styledItem.selectMode && !styledItem.dragMode
21+ readonly property Item swipedPanel: leadingPanel ? leadingLoader.item : trailingLoader.item
22+ readonly property bool leadingPanel: listItemStyle.LayoutMirroring.enabled ? (listItemStyle.x < 0) : (listItemStyle.x > 0)
23+ readonly property real swipedOffset: (leadingPanel ? listItemStyle.x : -listItemStyle.x) *
24+ (listItemStyle.LayoutMirroring.enabled ? -1 : 1)
25 readonly property real panelWidth: swipedPanel && swipedPanel.hasOwnProperty("panelWidth") ? swipedPanel.panelWidth : 0
26 property real prevX: 0.0
27 property real snapChangerLimit: 0.0
28@@ -329,10 +331,10 @@
29 // update snap direction
30 function updateSnapDirection() {
31 if (prevX < listItemStyle.x && (snapChangerLimit <= listItemStyle.x)) {
32- snapIn = leadingPanel;
33+ snapIn = (listItemStyle.LayoutMirroring.enabled !== leadingPanel);
34 snapChangerLimit = listItemStyle.x - threshold;
35 } else if (prevX > listItemStyle.x && (listItemStyle.x < snapChangerLimit)) {
36- snapIn = !leadingPanel;
37+ snapIn = (listItemStyle.LayoutMirroring.enabled === leadingPanel);
38 snapChangerLimit = listItemStyle.x + threshold;
39 }
40 prevX = listItemStyle.x;
41@@ -341,12 +343,16 @@
42 function snap() {
43 var snapPos = (swipedOffset > units.gu(2) && snapIn) ? panelWidth : 0.0;
44 snapPos *= leadingPanel ? 1 : -1;
45+ // invert snapPos on RTL
46+ snapPos *= listItemStyle.LayoutMirroring.enabled ? -1 : 1;
47 snapAnimation.snapTo(snapPos);
48 }
49 // handle elasticity on overshoot
50 function overshoot(event) {
51 var offset = event.content.x - styledItem.contentItem.anchors.leftMargin;
52 offset *= leadingPanel ? 1 : -1;
53+ // invert offset on RTL
54+ offset *= listItemStyle.LayoutMirroring.enabled ? -1 : 1;
55 if (offset > panelWidth) {
56 // do elastic move
57 event.content.x = styledItem.contentItem.x + (event.to.x - event.from.x) / 2;
58
59=== modified file 'tests/resources/listitems/ListItemDragging.qml'
60--- tests/resources/listitems/ListItemDragging.qml 2015-02-25 11:21:57 +0000
61+++ tests/resources/listitems/ListItemDragging.qml 2015-02-27 14:20:38 +0000
62@@ -26,6 +26,8 @@
63
64 property bool restrictDragging: true
65
66+ LayoutMirroring.childrenInherit: true
67+
68 Action {
69 id: deleteAction
70 iconName: "delete"
71@@ -135,14 +137,23 @@
72 anchors.fill: parent
73 color: item.dragging ? UbuntuColors.blue : "#69aa69"
74 }
75- Label {
76- text: label + " from index #" + index
77+ Column {
78+ anchors.fill: parent
79+ Label {
80+ text: label + " from index #" + index
81+ anchors.left: parent.left
82+ }
83+ Label {
84+ text: "Click to turn LTR<->RTL"
85+ anchors.right: parent.right
86+ }
87 }
88
89 onPressAndHold: {
90 print("entering/leaving draggable mode")
91 ListView.view.ViewItems.dragMode = !ListView.view.ViewItems.dragMode;
92 }
93+ onClicked: main.LayoutMirroring.enabled = !main.LayoutMirroring.enabled
94 }
95 }
96 }
97
98=== modified file 'tests/unit_x11/tst_components/tst_listitem.qml'
99--- tests/unit_x11/tst_components/tst_listitem.qml 2015-02-27 07:17:37 +0000
100+++ tests/unit_x11/tst_components/tst_listitem.qml 2015-02-27 14:20:38 +0000
101@@ -120,6 +120,7 @@
102 clip: true
103 model: objectModel
104 ViewItems.selectMode: false
105+ LayoutMirroring.childrenInherit: true
106 delegate: ListItem {
107 objectName: "listItem" + index
108 color: "lightgray"
109@@ -224,6 +225,18 @@
110 signalName: "stopped"
111 }
112
113+ function toggleSelectMode(view, enabled, scrollToTop) {
114+ if (view.hasOwnProperty("positionViewAtBeginning") && scrollToTop) {
115+ // use the topmost listItem to wait for rendering completion
116+ view.positionViewAtBeginning();
117+ }
118+ var listItem = findChild(view, "listItem0");
119+ verify(listItem);
120+ view.ViewItems.selectMode = enabled;
121+ // waitForRendering aint seems to be reliable here, so we wait ~400 msecs
122+ wait(400);
123+ }
124+
125 function toggleDragMode(view, enabled) {
126 // use the topmost listItem to wait for rendering completion
127 view.positionViewAtBeginning();
128@@ -310,8 +323,9 @@
129 compare(defaults.divider.visible, true, "divider is visible by default");
130 compare(defaults.divider.anchors.leftMargin, 0, "divider's left margin is 0");
131 compare(defaults.divider.anchors.rightMargin, 0, "divider's right margin is 0");
132- compare(defaults.divider.anchors.left, defaults.left, "divider's left anchor is wrong");
133- compare(defaults.divider.anchors.right, defaults.right, "divider's right anchor is wrong");
134+ var mappedDividerPos = defaults.mapFromItem(defaults.divider, defaults.divider.x, defaults.divider.y);
135+ compare(mappedDividerPos.x, 0, "divider's left anchor is wrong");
136+ compare(mappedDividerPos.x + defaults.divider.width, defaults.width, "divider's right anchor is wrong");
137 compare(defaults.divider.height, units.dp(2), "divider's thickness is wrong");
138 compare(defaults.divider.colorFrom, "#000000", "colorFrom differs.");
139 fuzzyCompare(defaults.divider.colorFrom.a, 0.14, 0.01, "colorFrom alpha differs");
140@@ -841,16 +855,14 @@
141
142 function test_select_indices_updates_selected_items() {
143 listView.ViewItems.selectedIndices = [0,1,2];
144- listView.ViewItems.selectMode = true;
145- waitForRendering(listView, 500);
146+ toggleSelectMode(listView, true);
147 for (var i in listView.ViewItems.selectedIndices) {
148 var index = listView.ViewItems.selectedIndices[i];
149 var listItem = findChild(listView, "listItem" + index);
150 compare(listItem.selected, true, "ListItem at index " + index + " is not selected!");
151 }
152- listView.ViewItems.selectMode = false;
153+ toggleSelectMode(listView, false);
154 listView.ViewItems.selectedIndices = [];
155- waitForRendering(listView, 500);
156 }
157
158 function test_toggle_selectMode_data() {
159@@ -863,9 +875,7 @@
160 var listItem = findChild(listView, "listItem" + data.index)
161 verify(listItem, "Cannot get test item");
162 listItem.selected = data.selected;
163- listView.ViewItems.selectMode = true;
164- // wait few milliseconds
165- wait(400);
166+ toggleSelectMode(listView, true);
167 // testItem is the 4th child, so index is 3
168 verify(findChild(listItem, "selection_panel" + data.index), "Cannot find selection panel");
169 compare(listItem.contentItem.enabled, true, "contentItem is not disabled.");
170@@ -886,8 +896,7 @@
171 }
172 function test_toggle_selected(data) {
173 // make test item selectable first, so the panel is created
174- data.selectableHolder.ViewItems.selectMode = true;
175- wait(400);
176+ toggleSelectMode(data.selectableHolder, true);
177 // get the control to click on
178 var clickOn = findChild(data.item, data.clickOn);
179 verify(clickOn, "control to be clicked on not found");
180@@ -912,8 +921,7 @@
181 listView.positionViewAtEnd();
182 var listItem = findChild(listView, "listItem" + (listView.count - 1));
183 verify(listItem, "Cannot get tested list item");
184- listView.ViewItems.selectMode = true;
185- waitForRendering(listItem);
186+ toggleSelectMode(listView, true, false);
187 selectedSpy.target = listItem;
188 selectedSpy.clear();
189
190@@ -924,9 +932,7 @@
191
192 function test_no_tug_when_selectable() {
193 movingSpy.target = testItem;
194- testColumn.ViewItems.selectMode = true;
195- // wait till animation to selection mode ends
196- waitForRendering(testItem.contentItem);
197+ toggleSelectMode(testColumn, true);
198
199 // try to tug leading
200 movingSpy.clear();
201@@ -935,9 +941,7 @@
202 }
203
204 function test_selectable_and_click() {
205- testColumn.ViewItems.selectMode = true;
206- // wait till animation to selection mode ends
207- waitForRendering(testItem.contentItem);
208+ toggleSelectMode(testColumn, true);
209
210 clickSpy.target = testItem;
211 mouseClick(testItem, centerOf(testItem).x, centerOf(testItem).y);
212@@ -945,9 +949,7 @@
213 }
214
215 function test_selectable_and_pressandhold() {
216- testColumn.ViewItems.selectMode = true;
217- // wait till animation to selection mode ends
218- waitForRendering(testItem.contentItem);
219+ toggleSelectMode(testColumn, true);
220
221 pressAndHoldSpy.target = testItem;
222 mouseLongPress(testItem, centerOf(testItem).x, centerOf(testItem).y);
223@@ -964,14 +966,11 @@
224 function test_proper_attached_properties(data) {
225 var listItem = findChild(data.item, "listItem0");
226 verify(listItem, "ListItem not found!");
227- data.item.ViewItems.selectMode = true;
228- // wait few milliseconds to get the selection panel opened
229- wait(400);
230+ toggleSelectMode(data.item, true);
231 // check if the selection mode was activated by looking after the first selection panel
232 var panel = findChild(listItem, "selection_panel0");
233 // turn off selection mode so we have a proper cleanup
234- data.item.ViewItems.selectMode = false;
235- wait(400);
236+ toggleSelectMode(data.item, true);
237 verify(panel, "Selection panel not found, wrong attached property target?");
238 }
239
240@@ -1204,5 +1203,62 @@
241 toggleDragMode(listView, false);
242 listView.ViewItems.dragUpdated.disconnect(dummyFunc);
243 }
244+
245+ function test_rtl_actions_data() {
246+ return [
247+ {tag: "Leading actions", item: "listItem0", leading: true, expected: ["leading_1", "leading_2", "leading_3"]},
248+ {tag: "Trailing actions", item: "listItem0", leading: false, expected: ["stockAction"]},
249+ ];
250+ }
251+ function test_rtl_actions(data) {
252+ listView.LayoutMirroring.enabled = true;
253+ waitForRendering(listView, 500);
254+ var listItem = findChild(listView, data.item);
255+ movingSpy.target = listItem;
256+ swipe(listItem, centerOf(listItem).x, centerOf(listItem).y, data.leading ? -units.gu(20) : units.gu(20), 0);
257+ movingSpy.wait();
258+
259+ // check if the action is visible
260+ var panel = panelItem(listItem, data.leading);
261+ verify(panel, "Panel not visible");
262+ for (var i in data.expected) {
263+ var actionItem = findChild(panel, data.expected[i]);
264+ verify(actionItem, data.expected[i] + " action not found");
265+ }
266+ // dismiss
267+ rebound(listItem);
268+ listView.LayoutMirroring.enabled = false;
269+ waitForRendering(listView, 500);
270+ }
271+
272+ function test_rtl_selection_panel_position() {
273+ listView.LayoutMirroring.enabled = true;
274+ waitForRendering(listView, 500);
275+ toggleSelectMode(listView, true);
276+ // get the panel
277+ var listItem = findChild(listView, "listItem0");
278+ verify(listItem, "ListItem cannot be found");
279+ var panel = findChild(listView, "selection_panel0");
280+ verify(panel, "Selection panel not found.");
281+ verify(listItem.mapFromItem(panel, panel.x, panel.y).x > centerOf(listItem).x, "Panel is not in its proper place!");
282+ toggleSelectMode(listView, false);
283+ listView.LayoutMirroring.enabled = false;
284+ waitForRendering(listView, 500);
285+ }
286+
287+ function test_rtl_drag_panel_position() {
288+ listView.LayoutMirroring.enabled = true;
289+ waitForRendering(listView, 500);
290+ toggleDragMode(listView, true);
291+ // get the panel
292+ var listItem = findChild(listView, "listItem0");
293+ verify(listItem, "ListItem cannot be found");
294+ var panel = findChild(listView, "drag_panel0");
295+ verify(panel, "Drag panel not found.");
296+ verify(listItem.mapFromItem(panel, panel.x, panel.y).x < centerOf(listItem).x, "Panel is not in its proper place!");
297+ toggleDragMode(listView, false);
298+ listView.LayoutMirroring.enabled = false;
299+ waitForRendering(listView, 500);
300+ }
301 }
302 }

Subscribers

People subscribed via source and target branches