Merge lp:~ubuntu-sdk-team/ubuntu-ui-toolkit/textHandlerCleanUpVivid into lp:ubuntu-ui-toolkit/staging
- textHandlerCleanUpVivid
- Merge into staging
Status: | Merged | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Approved by: | Zsombor Egri | ||||||||||||
Approved revision: | 1173 | ||||||||||||
Merged at revision: | 1446 | ||||||||||||
Proposed branch: | lp:~ubuntu-sdk-team/ubuntu-ui-toolkit/textHandlerCleanUpVivid | ||||||||||||
Merge into: | lp:ubuntu-ui-toolkit/staging | ||||||||||||
Diff against target: |
1199 lines (+276/-291) 19 files modified
examples/ubuntu-ui-toolkit-gallery/TextInputs.qml (+5/-2) modules/Ubuntu/Components/InputHandler.qml (+15/-37) modules/Ubuntu/Components/TextArea.qml (+3/-5) modules/Ubuntu/Components/TextCursor.qml (+70/-67) modules/Ubuntu/Components/TextField.qml (+5/-9) modules/Ubuntu/Components/TextInputPopover.qml (+6/-3) modules/Ubuntu/Components/Themes/Ambiance/SelectionCursorStyle.qml (+0/-92) modules/Ubuntu/Components/Themes/Ambiance/TextAreaStyle.qml (+2/-10) modules/Ubuntu/Components/Themes/Ambiance/TextCursorStyle.qml (+5/-10) modules/Ubuntu/Components/Themes/Ambiance/TextFieldStyle.qml (+1/-0) modules/Ubuntu/Components/Themes/Ambiance/ToolbarButtonStyle.qml (+3/-3) modules/Ubuntu/Components/Themes/Ambiance/qmldir (+0/-3) tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py (+5/-0) tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.header.qml (+43/-3) tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.py (+34/-24) tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textarea.qml (+6/-2) tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textfield.qml (+7/-2) tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textfield_custom.qml (+44/-13) tests/unit_x11/tst_components/tst_textinput_touch.qml (+22/-6) |
||||||||||||
To merge this branch: | bzr merge lp:~ubuntu-sdk-team/ubuntu-ui-toolkit/textHandlerCleanUpVivid | ||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Approve | |
Zsombor Egri | Approve | ||
Review via email: mp+252418@code.launchpad.net |
Commit message
New text handler visuals and improved behavior
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
Francis Ginther (fginther) wrote : | # |
The above mako testing failed due to an unbootable image making it into the pipeline. The ci job has been restarted.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1173
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Zsombor Egri (zsombi) wrote : | # |
Feels good to have it here :)
PS Jenkins bot (ps-jenkins) : | # |
Preview Diff
1 | === modified file 'examples/ubuntu-ui-toolkit-gallery/TextInputs.qml' |
2 | --- examples/ubuntu-ui-toolkit-gallery/TextInputs.qml 2015-03-03 13:20:06 +0000 |
3 | +++ examples/ubuntu-ui-toolkit-gallery/TextInputs.qml 2015-03-10 16:30:01 +0000 |
4 | @@ -33,8 +33,9 @@ |
5 | "ligula tortor, luctus id elementum vel, varius vel augue. "+ |
6 | "Nunc porta mattis bibendum. Nam vitae sapien ipsum, non viverra neque." |
7 | |
8 | - property string richText: "<i>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</i> "+ |
9 | - "<b>Nunc pretium iaculis risus, sed vehicula odio varius ac.</b> "+ |
10 | + // http://qt-project.org/doc/qt-5/richtext-html-subset.html |
11 | + property string richText: "<big>Lorem ipsum dolor sit amet</big>, <i>consectetur adipiscing elit.</i>" + |
12 | + "<b>Nunc pretium iaculis risus</b>, <small>sed vehicula odio varius ac.</small>" + |
13 | "<u>Etiam orci lectus, bibendum in vulputate ac, tristique quis dui.</u>" |
14 | |
15 | TemplateSection { |
16 | @@ -81,6 +82,7 @@ |
17 | text: i18n.tr("Nobody type here") |
18 | readOnly: true |
19 | width: parent.width |
20 | + horizontalAlignment: TextInput.AlignHCenter |
21 | } |
22 | } |
23 | |
24 | @@ -92,6 +94,7 @@ |
25 | text: i18n.tr("No interaction allowed") |
26 | enabled: false |
27 | width: parent.width |
28 | + horizontalAlignment: TextInput.AlignRight |
29 | } |
30 | } |
31 | } |
32 | |
33 | === modified file 'modules/Ubuntu/Components/InputHandler.qml' |
34 | --- modules/Ubuntu/Components/InputHandler.qml 2015-03-03 13:47:48 +0000 |
35 | +++ modules/Ubuntu/Components/InputHandler.qml 2015-03-10 16:30:01 +0000 |
36 | @@ -32,11 +32,8 @@ |
37 | property Item input |
38 | // the Flickable holding the input instance |
39 | property Flickable flickable |
40 | - // selection cursor mode |
41 | - property bool selectionCursor: input && input.selectedText !== "" |
42 | |
43 | - // item filling the text input visible area, used to check teh caret handler |
44 | - // visibility |
45 | + // item filling the visible text input area used to check handler visibility |
46 | property Item visibleArea: Item { |
47 | parent: flickable |
48 | anchors.fill: parent |
49 | @@ -46,7 +43,7 @@ |
50 | property real lineSpacing: units.dp(3) |
51 | property real lineSize: input.font.pixelSize + lineSpacing |
52 | // input x/y distance from the frame |
53 | - property point frameDistance: Qt.point(0,0) |
54 | + property point frameDistance: Qt.point(flickable.x, flickable.y) |
55 | |
56 | // signal triggered when popup should be opened |
57 | signal pressAndHold(int pos, bool fromTouch) |
58 | @@ -76,7 +73,7 @@ |
59 | } |
60 | |
61 | // internal properties/functions |
62 | - readonly property bool singleLine: input && input.hasOwnProperty("validator") |
63 | + readonly property bool singleLine: input.hasOwnProperty("validator") |
64 | property var flickableList: new Array() |
65 | property bool textChanged: false |
66 | property var popover |
67 | @@ -94,12 +91,9 @@ |
68 | readonly property Flickable grandScroller: firstFlickableParent(main) |
69 | readonly property Flickable scroller: (scrollingDisabled && grandScroller) ? grandScroller : flickable |
70 | |
71 | - // ensures the text cusrorRectangle is always in the internal Flickable's visible area |
72 | + // ensures the text cursorRectangle is always in the internal Flickable's visible area |
73 | function ensureVisible(rect) |
74 | { |
75 | - if (rect === undefined) { |
76 | - rect = input.cursorRectangle; |
77 | - } |
78 | if (flickable.moving || flickable.flicking) |
79 | return; |
80 | if (flickable.contentX >= rect.x) |
81 | @@ -165,7 +159,7 @@ |
82 | if (!main.focus || !mouseInSelection(mouse)) { |
83 | activateInput(); |
84 | input.cursorPosition = pressedPosition = mousePosition(mouse); |
85 | - if (noAutoselect === undefined || !noAutoselect) { |
86 | + if (!noAutoselect) { |
87 | input.selectWord(); |
88 | } |
89 | } |
90 | @@ -216,15 +210,6 @@ |
91 | } |
92 | } |
93 | |
94 | - // returns the styles for the cursors depending on the position property given |
95 | - function textCursorStyle(positionProperty) { |
96 | - switch (positionProperty) { |
97 | - case "cursorPosition": return main.__styleInstance.mainCursorStyle; |
98 | - case "selectionStart": return main.__styleInstance.selectionStartCursorStyle; |
99 | - case "selectionEnd": return main.__styleInstance.selectionEndCursorStyle; |
100 | - } |
101 | - } |
102 | - |
103 | // moves the cursor one page forward with or without positioning the cursor |
104 | function movePage(forward) { |
105 | var cx = input.cursorRectangle.x; |
106 | @@ -320,7 +305,7 @@ |
107 | // input specific signals |
108 | Connections { |
109 | target: input |
110 | - onCursorRectangleChanged: ensureVisible() |
111 | + onCursorRectangleChanged: ensureVisible(input.cursorRectangle) |
112 | onTextChanged: { |
113 | textChanged = true; |
114 | if (oldText != input.text) { |
115 | @@ -402,12 +387,10 @@ |
116 | } |
117 | function handleDblClick(event, touch) { |
118 | if (main.selectByMouse) { |
119 | - openContextMenu(event, false); |
120 | + openContextMenu(event, false, touch); |
121 | // turn selection state temporarily so the selection is not cleared on release |
122 | state = "selection"; |
123 | - if (touch) { |
124 | - suppressReleaseEvent = true; |
125 | - } |
126 | + suppressReleaseEvent = true; |
127 | } |
128 | } |
129 | |
130 | @@ -416,7 +399,7 @@ |
131 | Mouse.onPressed: handlePressed(mouse, false) |
132 | Mouse.onReleased: handleReleased(mouse, false) |
133 | Mouse.onPositionChanged: handleMove(mouse, false) |
134 | - Mouse.onDoubleClicked: handleDblClick(mouse) |
135 | + Mouse.onDoubleClicked: handleDblClick(mouse, false) |
136 | |
137 | // right button handling |
138 | MouseArea { |
139 | @@ -478,31 +461,27 @@ |
140 | onPressed: handlePressed(touchPoints[0], true) |
141 | onReleased: handleReleased(touchPoints[0], true) |
142 | |
143 | + property Item cursorPositionCursor: null |
144 | + property Item selectionStartCursor: null |
145 | + property Item selectionEndCursor: null |
146 | + |
147 | // cursors to use when text is selected |
148 | Connections { |
149 | - property Item selectionStartCursor: null |
150 | - property Item selectionEndCursor: null |
151 | target: input |
152 | onSelectedTextChanged: { |
153 | - if (selectedText !== "" && input.cursorDelegate) { |
154 | + if (selectedText !== "") { |
155 | if (!selectionStartCursor) { |
156 | selectionStartCursor = input.cursorDelegate.createObject( |
157 | input, { |
158 | "positionProperty": "selectionStart", |
159 | - "height": lineSize, |
160 | "handler": inputHandler, |
161 | - "objectName": "selectionStartCursor" |
162 | } |
163 | ); |
164 | moveSelectionCursor(selectionStartCursor); |
165 | - } |
166 | - if (!selectionEndCursor) { |
167 | selectionEndCursor = input.cursorDelegate.createObject( |
168 | input, { |
169 | "positionProperty": "selectionEnd", |
170 | - "height": lineSize, |
171 | "handler": inputHandler, |
172 | - "objectName": "selectionEndCursor" |
173 | } |
174 | ); |
175 | moveSelectionCursor(selectionEndCursor); |
176 | @@ -511,8 +490,6 @@ |
177 | if (selectionStartCursor) { |
178 | selectionStartCursor.destroy(); |
179 | selectionStartCursor = null; |
180 | - } |
181 | - if (selectionEndCursor) { |
182 | selectionEndCursor.destroy(); |
183 | selectionEndCursor = null; |
184 | } |
185 | @@ -534,6 +511,7 @@ |
186 | var pos = input.positionToRectangle(input[cursor.positionProperty]); |
187 | cursor.x = pos.x; |
188 | cursor.y = pos.y; |
189 | + cursor.height = pos.height; |
190 | ensureVisible(pos); |
191 | } |
192 | } |
193 | |
194 | === modified file 'modules/Ubuntu/Components/TextArea.qml' |
195 | --- modules/Ubuntu/Components/TextArea.qml 2015-03-03 13:47:48 +0000 |
196 | +++ modules/Ubuntu/Components/TextArea.qml 2015-03-10 16:30:01 +0000 |
197 | @@ -758,8 +758,7 @@ |
198 | |
199 | function linesHeight(lines) |
200 | { |
201 | - var lineHeight = editor.font.pixelSize * lines + inputHandler.lineSpacing * lines |
202 | - return lineHeight + 2 * frameSpacing; |
203 | + return inputHandler.lineSize * lines + 2 * frameSpacing; |
204 | } |
205 | |
206 | function frameSize() |
207 | @@ -803,9 +802,9 @@ |
208 | margins: internal.frameSpacing |
209 | } |
210 | // hint is shown till user types something in the field |
211 | - visible: (editor.getText(0, editor.length) == "") && !editor.inputMethodComposing |
212 | + visible: (editor.text == "") && !editor.inputMethodComposing |
213 | color: Theme.palette.normal.backgroundText |
214 | - fontSize: "medium" |
215 | + font: editor.font |
216 | elide: Text.ElideRight |
217 | wrapMode: Text.WordWrap |
218 | } |
219 | @@ -870,7 +869,6 @@ |
220 | main: control |
221 | input: editor |
222 | flickable: flicker |
223 | - frameDistance: Qt.point(flicker.x, flicker.y) |
224 | } |
225 | } |
226 | } |
227 | |
228 | === modified file 'modules/Ubuntu/Components/TextCursor.qml' |
229 | --- modules/Ubuntu/Components/TextCursor.qml 2015-03-03 13:47:48 +0000 |
230 | +++ modules/Ubuntu/Components/TextCursor.qml 2015-03-10 16:30:01 +0000 |
231 | @@ -21,10 +21,10 @@ |
232 | Ubuntu.StyledItem { |
233 | id: cursorItem |
234 | |
235 | - width: units.dp(1) |
236 | + height: cursorRectangle.height |
237 | |
238 | /* |
239 | - Property holding the text input's custor position property. Can be one of |
240 | + Property holding the text input's cursor position property. Can be one of |
241 | the following ones: cursorPosition, selectionStart and selectionEnd. |
242 | */ |
243 | property string positionProperty: "cursorPosition" |
244 | @@ -41,21 +41,29 @@ |
245 | handler.main.cursorDelegate : |
246 | __styleInstance.cursorDelegate |
247 | |
248 | - // depending on the positionProperty, we chose different styles |
249 | - style: Theme.createStyleComponent(handler.textCursorStyle(positionProperty), cursorItem); |
250 | + style: Theme.createStyleComponent("TextCursorStyle.qml", cursorItem); |
251 | |
252 | objectName: "textCursor" |
253 | //Caret instance from the style. |
254 | property Item caret: __styleInstance.caret |
255 | - property real caretX: caret ? caret.x : 0 |
256 | - property real caretY: caret ? caret.y : 0 |
257 | + property int absX: { |
258 | + return fakeCursor.parent.mapFromItem(handler.main, cursorItem.x, cursorItem.y).x |
259 | + } |
260 | + property int absY: { |
261 | + // Take parent flickable movement into account |
262 | + var flickable = handler.main; |
263 | + do { |
264 | + flickable = flickable.parent; |
265 | + } while (!flickable.contentY && flickable != fakeCursor.parent); |
266 | + return fakeCursor.parent.mapFromItem(handler.main, cursorItem.x, cursorItem.y).y |
267 | + } |
268 | |
269 | - // returns the mapped cursor position to a position relative to the main component |
270 | - function mappedCursorPosition(pos) { |
271 | - var cpos = cursorItem[pos]; |
272 | - if (handler) { |
273 | - cpos += handler.frameDistance[pos] - handler.flickable["content"+pos.toUpperCase()]; |
274 | - } |
275 | + // Returns "x" or "y" relative to the item handlers are a child of |
276 | + function mappedCursorPosition(coordinate) { |
277 | + var cpos = cursorItem["abs" + coordinate.toUpperCase()]; |
278 | + cpos += handler.frameDistance[coordinate]; |
279 | + cpos += handler.input[coordinate]; |
280 | + cpos -= handler.flickable["content" + coordinate.toUpperCase()]; |
281 | return cpos; |
282 | } |
283 | /* |
284 | @@ -79,12 +87,16 @@ |
285 | } |
286 | } |
287 | |
288 | + Binding { |
289 | + target: handler |
290 | + property: "cursorPositionCursor" |
291 | + value: cursorItem |
292 | + } |
293 | + |
294 | function openPopover() { |
295 | - if (!visible || opacity === 0.0 || dragger.dragActive) { |
296 | - return; |
297 | - } |
298 | - |
299 | - if (contextMenuVisible) { |
300 | + if (!visible |
301 | + || opacity === 0.0 |
302 | + || dragger.dragActive) { |
303 | return; |
304 | } |
305 | |
306 | @@ -96,19 +108,15 @@ |
307 | if (component === undefined) |
308 | component = Qt.resolvedUrl("TextInputPopover.qml"); |
309 | |
310 | - var popup; |
311 | - if (fakeCursor.visible) { |
312 | - popup = PopupUtils.open(component, cursorItem, { |
313 | - "target": handler.main, |
314 | - }); |
315 | - } else { |
316 | - // if the cursor is out of the visible viewport, anchor the |
317 | - // contextual menu to the input field |
318 | - popup = PopupUtils.open(component, handler.main, { |
319 | - "target": handler.main, |
320 | - }); |
321 | - cursorItem.Component.onDestruction.connect(popup.__closePopup); |
322 | - } |
323 | + // if the cursor is out of the visible viewport, anchor the |
324 | + // contextual menu to the input field |
325 | + var anchor = fakeCursor.visible ? draggedItem : handler.main |
326 | + var popup = PopupUtils.open(component, anchor, { |
327 | + "target": handler.main, |
328 | + }); |
329 | + // hide the arrow |
330 | + popup.__foreground.direction = "none"; |
331 | + cursorItem.Component.onDestruction.connect(popup.__closePopup); |
332 | contextMenuVisible = true; |
333 | popup.onVisibleChanged.connect(contextMenuHidden.bind(undefined, popup)); |
334 | // do not grab focus! |
335 | @@ -116,28 +124,14 @@ |
336 | handler.popover = popup; |
337 | } |
338 | |
339 | - visible: handler.main.cursorVisible |
340 | - // change opacity to 0 if text is selected and the positionProperty is cursorPosition |
341 | - // note: we should not touch visibility as cursorVisible alters that! |
342 | - opacity: (positionProperty === "cursorPosition") && (handler.main.selectedText !== "") ? 0.0 : 1.0 |
343 | + visible: handler.main.cursorVisible && |
344 | + !(positionProperty === "cursorPosition" && handler.main.selectedText !== "") |
345 | |
346 | // cursor visual loader |
347 | Loader { |
348 | id: cursorLoader |
349 | sourceComponent: cursorDelegate |
350 | height: parent.height |
351 | - onItemChanged: { |
352 | - if (item) { |
353 | - cursorItem.width = item.width; |
354 | - } |
355 | - } |
356 | - // bind the cursor height as it may change depending on the text size |
357 | - Binding { |
358 | - target: cursorLoader.item |
359 | - property: "height" |
360 | - value: cursorLoader.height |
361 | - when: cursorLoader.item |
362 | - } |
363 | } |
364 | |
365 | /* |
366 | @@ -159,18 +153,14 @@ |
367 | contextMenuVisible = false |
368 | } |
369 | |
370 | - onXChanged: if (!draggedItemMouseArea.pressed) draggedItem.moveToCaret() |
371 | - onYChanged: if (!draggedItemMouseArea.pressed) draggedItem.moveToCaret() |
372 | - Component.onCompleted: draggedItem.moveToCaret() |
373 | - |
374 | //dragged item |
375 | - Item { |
376 | - id: draggedItem |
377 | + property Item draggedItem: Item { |
378 | objectName: cursorItem.positionProperty + "_draggeditem" |
379 | - width: caret ? units.gu(4) : 0 |
380 | - height: caret ? cursorItem.height : 0 |
381 | - parent: handler.main |
382 | - visible: cursorItem.visible && (cursorItem.opacity > 0.0) && QuickUtils.touchScreenAvailable |
383 | + width: caret.width + units.gu(4) |
384 | + onWidthChanged: draggedItem.moveToCaret() |
385 | + height: caret.height + units.gu(4) |
386 | + parent: fakeCursor.parent |
387 | + visible: caret.visible |
388 | |
389 | /* |
390 | Mouse area to turn on dragging or selection mode when pressed |
391 | @@ -197,23 +187,33 @@ |
392 | handler.pressAndHold(-1, false); |
393 | } |
394 | Ubuntu.Mouse.onDoubleClicked: handler.main.selectWord() |
395 | - Ubuntu.Mouse.clickAndHoldThreshold: units.gu(2) |
396 | Ubuntu.Mouse.enabled: enabled |
397 | + |
398 | + // Visible touch target area for debugging purposes |
399 | + Rectangle { |
400 | + anchors.fill: parent |
401 | + color: 'red' |
402 | + opacity: 0.1 |
403 | + visible: false // draggedItemMouseArea.enabled |
404 | + } |
405 | } |
406 | |
407 | // aligns the draggedItem to the caret and resets the dragger |
408 | function moveToCaret() { |
409 | - draggedItem.x = mappedCursorPosition("x") - draggedItem.width / 2; |
410 | - draggedItem.y = mappedCursorPosition("y"); |
411 | + if (!caret) { |
412 | + return; |
413 | + } |
414 | + draggedItem.x = fakeCursor.x - draggedItem.width / 2; |
415 | + draggedItem.y = fakeCursor.y + caret.y - caret.height / 2; |
416 | } |
417 | - // positions caret to the dragged posinotion |
418 | + // positions caret to the dragged position |
419 | function positionCaret() { |
420 | if (dragger.dragActive) { |
421 | var dx = dragger.dragStartX + dragger.dragAmountX + handler.flickable.contentX; |
422 | var dy = dragger.dragStartY + dragger.dragAmountY + handler.flickable.contentY; |
423 | - // consider only the x-distance because of the overlays |
424 | dx -= handler.frameDistance.x; |
425 | dy -= handler.frameDistance.y; |
426 | + dy -= draggedItem.height / 2; |
427 | handler.positionCaret(positionProperty, dx, dy); |
428 | } |
429 | } |
430 | @@ -224,7 +224,7 @@ |
431 | // fill the entire component area |
432 | parent: handler.main |
433 | anchors.fill: parent |
434 | - enabled: draggedItemMouseArea.enabled && draggedItemMouseArea.pressed && QuickUtils.touchScreenAvailable |
435 | + enabled: draggedItemMouseArea.enabled && draggedItemMouseArea.pressed && caret.visible |
436 | onEnabledChanged: { |
437 | if (enabled) { |
438 | dragAmountX = 0; |
439 | @@ -292,14 +292,16 @@ |
440 | // fake cursor, caret is reparented to it to avoid caret clipping |
441 | Item { |
442 | id: fakeCursor |
443 | - parent: handler.main |
444 | + objectName: positionProperty + "FakeCursor" |
445 | + parent: QuickUtils.rootItem(handler.main) |
446 | width: cursorItem.width |
447 | height: cursorItem.height |
448 | - //reparent caret to it |
449 | - Component.onCompleted: if (caret) caret.parent = fakeCursor |
450 | + Component.onCompleted: caret.parent = fakeCursor |
451 | |
452 | x: mappedCursorPosition("x") |
453 | y: mappedCursorPosition("y") |
454 | + onXChanged: draggedItem.moveToCaret() |
455 | + onYChanged: draggedItem.moveToCaret() |
456 | |
457 | // manual clipping: the caret should be visible only while the cursor's |
458 | // top/bottom falls into the text area |
459 | @@ -307,8 +309,9 @@ |
460 | if (!caret || !cursorItem.visible || cursorItem.opacity < 1.0) |
461 | return false; |
462 | |
463 | - var leftTop = Qt.point(x - handler.frameDistance.x, y + handler.frameDistance.y + handler.lineSpacing); |
464 | - var rightBottom = Qt.point(x - handler.frameDistance.x, y + height - handler.frameDistance.y - handler.lineSpacing); |
465 | + var pos = handler.main.mapFromItem(fakeCursor.parent, fakeCursor.x, fakeCursor.y); |
466 | + var leftTop = Qt.point(pos.x - handler.frameDistance.x, pos.y + handler.frameDistance.y + handler.lineSpacing); |
467 | + var rightBottom = Qt.point(pos.x - handler.frameDistance.x, pos.y + height - handler.frameDistance.y - handler.lineSpacing); |
468 | return (handler.visibleArea.contains(leftTop) || handler.visibleArea.contains(rightBottom)); |
469 | } |
470 | } |
471 | |
472 | === modified file 'modules/Ubuntu/Components/TextField.qml' |
473 | --- modules/Ubuntu/Components/TextField.qml 2015-03-05 09:35:06 +0000 |
474 | +++ modules/Ubuntu/Components/TextField.qml 2015-03-10 16:30:01 +0000 |
475 | @@ -844,9 +844,7 @@ |
476 | QtObject { |
477 | id: internal |
478 | // array of borders in left, top, right, bottom order |
479 | - property real spacing: control.__styleInstance.overlaySpacing |
480 | - property real lineSpacing: units.dp(3) |
481 | - property real lineSize: editor.font.pixelSize + lineSpacing |
482 | + property real spacing: control.__styleInstance.frameSpacing |
483 | |
484 | property int type: action ? action.parameterType : Ubuntu.Action.None |
485 | onTypeChanged: { |
486 | @@ -871,6 +869,8 @@ |
487 | // the left pane width depends on its children width |
488 | height: parent.height |
489 | width: childrenRect.width |
490 | + // Overlay needs to have priority |
491 | + z: 1 |
492 | onChildrenChanged: { |
493 | // reparenting |
494 | for (var i = 0; i < children.length; i++) { |
495 | @@ -891,6 +891,8 @@ |
496 | // the right pane width depends on its children width |
497 | height: parent.height |
498 | width: childrenRect.width |
499 | + // Overlay needs to have priority |
500 | + z: 1 |
501 | onChildrenChanged: { |
502 | // reparenting |
503 | for (var i = 0; i < children.length; i++) { |
504 | @@ -1008,12 +1010,6 @@ |
505 | main: control |
506 | input: editor |
507 | flickable: flicker |
508 | - /* |
509 | - In x direction we use the Flickable x position as we can have overlays |
510 | - which can shift the cursor caret. On y direction we only use the topMargin |
511 | - spacing. |
512 | - */ |
513 | - frameDistance: Qt.point(flicker.x, flicker.topMargin) |
514 | } |
515 | } |
516 | } |
517 | |
518 | === modified file 'modules/Ubuntu/Components/TextInputPopover.qml' |
519 | --- modules/Ubuntu/Components/TextInputPopover.qml 2015-03-06 07:55:23 +0000 |
520 | +++ modules/Ubuntu/Components/TextInputPopover.qml 2015-03-10 16:30:01 +0000 |
521 | @@ -74,11 +74,14 @@ |
522 | */ |
523 | y: parent ? (parent.height - height) / 2 : 0 |
524 | autoClose: false |
525 | - contentHeight: row.childrenRect.height |
526 | - contentWidth: row.childrenRect.width |
527 | + contentHeight: row.childrenRect.height + padding * 2 |
528 | + contentWidth: row.childrenRect.width + padding * 2 |
529 | + property int padding: units.gu(1) |
530 | Row { |
531 | id: row |
532 | height: units.gu(6) |
533 | + x: popover.padding |
534 | + y: popover.padding |
535 | |
536 | Repeater { |
537 | model: actions.length |
538 | @@ -90,7 +93,7 @@ |
539 | accessible. https://bugs.launchpad.net/autopilot/+bug/1334599 |
540 | */ |
541 | property string text: action.text |
542 | - width: Math.max(units.gu(4), implicitWidth) + units.gu(2) |
543 | + width: Math.max(units.gu(5), implicitWidth) + units.gu(2) |
544 | height: units.gu(6) |
545 | action: actions[modelData] |
546 | style: Theme.createStyleComponent("ToolbarButtonStyle.qml", button) |
547 | |
548 | === removed file 'modules/Ubuntu/Components/Themes/Ambiance/SelectionCursorStyle.qml' |
549 | --- modules/Ubuntu/Components/Themes/Ambiance/SelectionCursorStyle.qml 2015-03-03 13:47:48 +0000 |
550 | +++ modules/Ubuntu/Components/Themes/Ambiance/SelectionCursorStyle.qml 1970-01-01 00:00:00 +0000 |
551 | @@ -1,92 +0,0 @@ |
552 | -/* |
553 | - * Copyright 2012 Canonical Ltd. |
554 | - * |
555 | - * This program is free software; you can redistribute it and/or modify |
556 | - * it under the terms of the GNU Lesser General Public License as published by |
557 | - * the Free Software Foundation; version 3. |
558 | - * |
559 | - * This program is distributed in the hope that it will be useful, |
560 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
561 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
562 | - * GNU Lesser General Public License for more details. |
563 | - * |
564 | - * You should have received a copy of the GNU Lesser General Public License |
565 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
566 | - */ |
567 | - |
568 | -import QtQuick 2.4 |
569 | -import Ubuntu.Components 1.2 |
570 | - |
571 | -EditorCursorStyle { |
572 | - id: cursor |
573 | - |
574 | - blinking: false |
575 | - property bool startPin: (styledItem.positionProperty === "selectionStart") |
576 | - property int cursorPosition: styledItem.editorItem[styledItem.positionProperty] |
577 | - |
578 | - visible: true |
579 | - |
580 | - function updatePosition(pos) |
581 | - { |
582 | - if (undefined === pos) |
583 | - return; |
584 | - var rect = styledItem.editorItem.positionToRectangle(pos); |
585 | - x = rect.x; |
586 | - y = rect.y; |
587 | - } |
588 | - onCursorPositionChanged: updatePosition(cursorPosition) |
589 | - |
590 | - Rectangle { |
591 | - id: pinBall |
592 | - width: cursor.pinSize |
593 | - height: width |
594 | - radius: width |
595 | - smooth: true |
596 | - color: cursor.pinColor |
597 | - anchors { |
598 | - horizontalCenter: cursor.horizontalCenter |
599 | - bottom: startPin ? cursor.top : undefined |
600 | - top: !startPin ? cursor.bottom : undefined |
601 | - } |
602 | - |
603 | - MouseArea { |
604 | - id: dragArea |
605 | - anchors.fill: parent |
606 | - anchors.margins: -cursor.pinSensingOffset |
607 | - |
608 | - drag { |
609 | - target: Item{} |
610 | - axis: Drag.XandYAxis |
611 | - onActiveChanged: { |
612 | - if (drag.active) { |
613 | - cursorStartX = cursor.x |
614 | - cursorStartY = cursor.y |
615 | - dragStartX = dragArea.drag.target.x |
616 | - dragStartY = dragArea.drag.target.y |
617 | - } |
618 | - } |
619 | - } |
620 | - |
621 | - property real dragStartX |
622 | - property real dragStartY |
623 | - property real cursorStartX |
624 | - property real cursorStartY |
625 | - property real dragDX: dragArea.drag.target.x - dragArea.dragStartX |
626 | - property real dragDY: dragArea.drag.target.y - dragArea.dragStartY |
627 | - |
628 | - onDragDXChanged: updateEditorCursorPosition() |
629 | - onDragDYChanged: updateEditorCursorPosition() |
630 | - |
631 | - function updateEditorCursorPosition() |
632 | - { |
633 | - var pos = styledItem.editorItem.mapFromItem(styledItem, cursor.x, cursor.y + cursor.height / 2); |
634 | - var dx = dragArea.cursorStartX + dragDX; |
635 | - var dy = dragArea.cursorStartY + dragDY; |
636 | - if (startPin) |
637 | - styledItem.editorItem.select(styledItem.editorItem.positionAt(dx, dy), styledItem.editorItem.selectionEnd); |
638 | - else |
639 | - styledItem.editorItem.select(styledItem.editorItem.selectionStart, styledItem.editorItem.positionAt(dx, dy)); |
640 | - } |
641 | - } |
642 | - } |
643 | -} |
644 | |
645 | === modified file 'modules/Ubuntu/Components/Themes/Ambiance/TextAreaStyle.qml' |
646 | --- modules/Ubuntu/Components/Themes/Ambiance/TextAreaStyle.qml 2015-03-03 13:47:48 +0000 |
647 | +++ modules/Ubuntu/Components/Themes/Ambiance/TextAreaStyle.qml 2015-03-10 16:30:01 +0000 |
648 | @@ -38,16 +38,8 @@ |
649 | Spacing between the frame and the text editor area |
650 | */ |
651 | property real frameSpacing: units.gu(1) |
652 | - property real overlaySpacing: frameSpacing / 2 |
653 | - |
654 | - /*! |
655 | - The following properties define the name of the style components declaring |
656 | - the styles for the main and the selection cursors. All cursors must defive |
657 | - from TextCursorStyle. |
658 | - */ |
659 | - property string mainCursorStyle: "TextCursorStyle.qml" |
660 | - property string selectionStartCursorStyle: "TextCursorStyle.qml" |
661 | - property string selectionEndCursorStyle: "TextCursorStyle.qml" |
662 | + // Obsolete |
663 | + property alias overlaySpacing: visuals.frameSpacing |
664 | |
665 | // style body |
666 | anchors.fill: parent |
667 | |
668 | === modified file 'modules/Ubuntu/Components/Themes/Ambiance/TextCursorStyle.qml' |
669 | --- modules/Ubuntu/Components/Themes/Ambiance/TextCursorStyle.qml 2015-03-03 13:47:48 +0000 |
670 | +++ modules/Ubuntu/Components/Themes/Ambiance/TextCursorStyle.qml 2015-03-10 16:30:01 +0000 |
671 | @@ -57,17 +57,16 @@ |
672 | width: cursorWidth |
673 | // FIXME: Extend the palette and use palette values here |
674 | color: UbuntuColors.blue |
675 | - visible: blinkTimer.timerShowCursor || !blinkTimer.running |
676 | + visible: styledItem.positionProperty === "cursorPosition" && (blinkTimer.timerShowCursor || !blinkTimer.running) |
677 | Timer { |
678 | id: blinkTimer |
679 | interval: cursorStyle.cursorVisibleTimeout |
680 | running: (cursorStyle.cursorVisibleTimeout > 0) && |
681 | (cursorStyle.cursorHiddenTimeout > 0) && |
682 | styledItem.visible && |
683 | - !styledItem.readOnly && |
684 | - !styledItem.contextMenuVisible && |
685 | - styledItem.positionProperty === "cursorPosition" |
686 | + shouldBlink |
687 | repeat: true |
688 | + property bool shouldBlink: !styledItem.readOnly && !styledItem.contextMenuVisible |
689 | property bool timerShowCursor: true |
690 | onTriggered: { |
691 | interval = (interval == cursorStyle.cursorVisibleTimeout) ? |
692 | @@ -84,13 +83,9 @@ |
693 | source: "artwork/caret_noshadow.png" |
694 | objectName: "text_cursor_style_caret_" + styledItem.positionProperty |
695 | anchors { |
696 | - top: styledItem.positionProperty === "selectionStart" ? undefined : parent.bottom |
697 | - bottom: styledItem.positionProperty === "selectionStart" ? parent.top : undefined |
698 | + top: parent.bottom |
699 | horizontalCenter: parent.horizontalCenter |
700 | - horizontalCenterOffset: styledItem.positionProperty === "cursorPosition" |
701 | - ? 0 |
702 | - : (LayoutMirroring.enabled ? -1 : 1) * (implicitWidth / 2 - cursorWidth) |
703 | + horizontalCenterOffset: cursorWidth / 2 |
704 | } |
705 | - rotation: styledItem.positionProperty === "selectionStart" ? 180 : 0 |
706 | } |
707 | } |
708 | |
709 | === modified file 'modules/Ubuntu/Components/Themes/Ambiance/TextFieldStyle.qml' |
710 | --- modules/Ubuntu/Components/Themes/Ambiance/TextFieldStyle.qml 2015-03-03 13:47:48 +0000 |
711 | +++ modules/Ubuntu/Components/Themes/Ambiance/TextFieldStyle.qml 2015-03-10 16:30:01 +0000 |
712 | @@ -18,4 +18,5 @@ |
713 | |
714 | TextAreaStyle { |
715 | objectName: "textfield_style" |
716 | + frameSpacing: units.gu(0.5) |
717 | } |
718 | |
719 | === modified file 'modules/Ubuntu/Components/Themes/Ambiance/ToolbarButtonStyle.qml' |
720 | --- modules/Ubuntu/Components/Themes/Ambiance/ToolbarButtonStyle.qml 2015-03-03 13:47:48 +0000 |
721 | +++ modules/Ubuntu/Components/Themes/Ambiance/ToolbarButtonStyle.qml 2015-03-10 16:30:01 +0000 |
722 | @@ -37,9 +37,10 @@ |
723 | top: parent.top |
724 | horizontalCenter: parent.horizontalCenter |
725 | } |
726 | - width: iconWidth |
727 | - height: iconWidth |
728 | + sourceSize.width: iconWidth |
729 | + sourceSize.height: iconWidth |
730 | source: styledItem.iconSource |
731 | + smooth: true |
732 | } |
733 | |
734 | Label { |
735 | @@ -52,7 +53,6 @@ |
736 | width: paintedWidth |
737 | text: styledItem.text |
738 | fontSize: "x-small" |
739 | - color: Theme.palette.normal.overlayText |
740 | } |
741 | } |
742 | |
743 | |
744 | === modified file 'modules/Ubuntu/Components/Themes/Ambiance/artwork/caret_noshadow@27.png' |
745 | Binary files modules/Ubuntu/Components/Themes/Ambiance/artwork/caret_noshadow@27.png 2014-11-07 11:03:45 +0000 and modules/Ubuntu/Components/Themes/Ambiance/artwork/caret_noshadow@27.png 2015-03-10 16:30:01 +0000 differ |
746 | === modified file 'modules/Ubuntu/Components/Themes/Ambiance/qmldir' |
747 | --- modules/Ubuntu/Components/Themes/Ambiance/qmldir 2015-02-13 13:27:51 +0000 |
748 | +++ modules/Ubuntu/Components/Themes/Ambiance/qmldir 2015-03-10 16:30:01 +0000 |
749 | @@ -9,7 +9,6 @@ |
750 | OptionSelectorStyle 0.1 OptionSelectorStyle.qml |
751 | PopoverForegroundStyle 0.1 PopoverForegroundStyle.qml |
752 | internal ScrollbarStyle ScrollbarStyle.qml |
753 | -internal SelectionCursorStyle SelectionCursorStyle.qml |
754 | internal SheetForegroundStyle SheetForegroundStyle.qml |
755 | internal SliderStyle SliderStyle.qml |
756 | TabBarStyle 0.1 TabBarStyle.qml |
757 | @@ -50,8 +49,6 @@ |
758 | SwitchStyle 1.1 SwitchStyle.qml |
759 | CheckBoxStyle 1.1 CheckBoxStyle.qml |
760 | |
761 | -internal TextSelectionStartCursorStyle TextSelectionStartCursorStyle.qml |
762 | -internal TextSelectionEndCursorStyle TextSelectionEndCursorStyle.qml |
763 | internal OverflowPanel OverflowPanel.qml |
764 | internal HeadDividerStyle HeadDividerStyle.qml |
765 | |
766 | |
767 | === modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py' |
768 | --- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py 2014-12-18 12:48:05 +0000 |
769 | +++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py 2015-03-10 16:30:01 +0000 |
770 | @@ -60,6 +60,7 @@ |
771 | |
772 | def _get_button(self, text): |
773 | buttons = self.select_many('AbstractButton') |
774 | + texts = [] |
775 | for button in buttons: |
776 | # workaround used in the text input's context menu to access |
777 | # action.text so we can get the proper button by text, action |
778 | @@ -67,6 +68,10 @@ |
779 | # https://bugs.launchpad.net/autopilot/+bug/1334599 |
780 | if button.text == text: |
781 | return button |
782 | + texts.append(button.text) |
783 | + raise _common.ToolkitException( |
784 | + 'Could not find a button with text %s (Available buttons are %s)' |
785 | + % (text, ','.join(texts))) |
786 | |
787 | |
788 | class ActionSelectionPopover(_common.UbuntuUIToolkitCustomProxyObjectBase): |
789 | |
790 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.header.qml' |
791 | --- tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.header.qml 2015-03-06 21:24:04 +0000 |
792 | +++ tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.header.qml 2015-03-10 16:30:01 +0000 |
793 | @@ -15,20 +15,60 @@ |
794 | */ |
795 | |
796 | import QtQuick 2.0 |
797 | -import Ubuntu.Components 1.1 |
798 | +import Ubuntu.Components 1.2 |
799 | |
800 | MainView { |
801 | + id: root |
802 | width: units.gu(48) |
803 | height: units.gu(60) |
804 | - useDeprecatedToolbar: false |
805 | objectName: "mainView" |
806 | |
807 | Page { |
808 | title: "Header" |
809 | + head.backAction: Action { |
810 | + iconName: "back" |
811 | + text: i18n.tr("Back") |
812 | + onTriggered: visible = false |
813 | + } |
814 | head.contents: TextField { |
815 | + id: searchTextField |
816 | objectName: "textfield" |
817 | placeholderText: "Header" |
818 | - width: parent ? parent.width : 0 |
819 | + inputMethodHints: Qt.ImhNoPredictiveText |
820 | + hasClearButton: false |
821 | + |
822 | + text: "Then two bears came out of the woods and mauled forty-two of the youths." |
823 | + |
824 | + anchors { |
825 | + fill: parent |
826 | + leftMargin: units.gu(1) |
827 | + topMargin: units.gu(0.5) |
828 | + bottomMargin: units.gu(0.5) |
829 | + rightMargin: units.gu(1) |
830 | + } |
831 | + |
832 | + secondaryItem: AbstractButton { |
833 | + height: searchTextField.height |
834 | + width: height |
835 | + enabled: searchTextField.text.length > 0 |
836 | + Image { |
837 | + objectName: "clearIcon" |
838 | + anchors.fill: parent |
839 | + anchors.margins: units.gu(.75) |
840 | + source: "image://theme/clear" |
841 | + opacity: searchTextField.text.length > 0 |
842 | + visible: opacity > 0 |
843 | + Behavior on opacity { |
844 | + UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration } |
845 | + } |
846 | + } |
847 | + } |
848 | + } |
849 | + |
850 | + Column { |
851 | + Label { |
852 | + text: "Above is a text field in the header" |
853 | + } |
854 | } |
855 | } |
856 | } |
857 | |
858 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.py' |
859 | --- tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.py 2015-03-04 22:57:28 +0000 |
860 | +++ tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.py 2015-03-10 16:30:01 +0000 |
861 | @@ -36,6 +36,8 @@ |
862 | dir_path, 'test_textinput.textarea.qml') |
863 | customfield_qml_file_path = os.path.join( |
864 | dir_path, 'test_textinput.textfield_custom.qml') |
865 | + header_qml_file_path = os.path.join( |
866 | + dir_path, 'test_textinput.header.qml') |
867 | |
868 | scenarios = [ |
869 | ('textfield', |
870 | @@ -47,6 +49,9 @@ |
871 | ('customfield', |
872 | dict(test_qml_file_path=customfield_qml_file_path, |
873 | objectName='textfield')), |
874 | + ('header', |
875 | + dict(test_qml_file_path=header_qml_file_path, |
876 | + objectName='textfield')), |
877 | ] |
878 | |
879 | def get_command_line(self, command_line): |
880 | @@ -59,20 +64,23 @@ |
881 | objectName=self.objectName) |
882 | self.assertFalse(self.textfield.focus) |
883 | |
884 | + def select_cursor(self, positionProperty): |
885 | + # The cursor may not receive events right away |
886 | + sleep(1) |
887 | + return self.main_view.select_single( |
888 | + objectName=positionProperty + '_draggeditem') |
889 | + |
890 | def test_caret_visible_on_focus(self): |
891 | cursorName = 'text_cursor_style_caret_cursorPosition' |
892 | self._assert_not_visible(objectName=cursorName) |
893 | self.pointing_device.click_object(self.textfield) |
894 | self.assertTrue(self.textfield.focus) |
895 | - cursor = self.main_view.select_single(objectName=cursorName) |
896 | - self.assertTrue(cursor.visible) |
897 | + self.main_view.select_single(objectName=cursorName) |
898 | |
899 | def test_caret_hide_while_typing(self): |
900 | self.pointing_device.click_object(self.textfield) |
901 | self.assertTrue(self.textfield.focus) |
902 | - cursor = self.main_view.select_single( |
903 | - objectName='text_cursor_style_caret_cursorPosition') |
904 | - self.assertTrue(cursor.visible) |
905 | + cursor = self.select_cursor('cursorPosition') |
906 | |
907 | self.textfield.keyboard.type('Lorem ipsum') |
908 | self.assertFalse(cursor.visible) |
909 | @@ -80,17 +88,13 @@ |
910 | def test_caret_visible_after_tapping(self): |
911 | self.test_caret_hide_while_typing() |
912 | self.pointing_device.click_object(self.textfield) |
913 | - cursor = self.main_view.select_single( |
914 | - objectName='text_cursor_style_caret_cursorPosition') |
915 | - self.assertTrue(cursor.visible) |
916 | + self.select_cursor('cursorPosition') |
917 | |
918 | def test_caret_visible_after_selecting(self): |
919 | self.test_caret_hide_while_typing() |
920 | # Select a character |
921 | self.keyboard.press_and_release('Shift+Left') |
922 | - cursor = self.main_view.select_single( |
923 | - objectName='text_cursor_style_caret_selectionEnd') |
924 | - self.assertTrue(cursor.visible) |
925 | + self.select_cursor('selectionEnd') |
926 | |
927 | |
928 | class InsertModeTextInputTestCase(tests.QMLFileAppTestCase): |
929 | @@ -142,31 +146,38 @@ |
930 | # Discard popover by tap |
931 | self.pointing_device.move( |
932 | self.textfield.globalRect.x + self.textfield.width * 0.7, |
933 | - self.textfield.globalRect.y + self.textfield.height // 10) |
934 | + self.textfield.globalRect.y + self.textfield.height * 0.9) |
935 | self.pointing_device.click() |
936 | |
937 | self._assert_not_visible(objectName='text_input_contextmenu') |
938 | |
939 | + def select_cursor(self, positionProperty): |
940 | + # The cursor may not receive events right away |
941 | + sleep(1) |
942 | + return self.main_view.select_single( |
943 | + objectName=positionProperty + '_draggeditem') |
944 | + |
945 | def test_popover_not_obscured(self): |
946 | self.pointing_device.click_object(self.textfield) |
947 | - cursor = self.main_view.select_single( |
948 | - objectName='text_cursor_style_cursorPosition') |
949 | - sleep(1) |
950 | + cursor = self.select_cursor('cursorPosition') |
951 | self.pointing_device.click_object(cursor) |
952 | popover = self.main_view.get_text_input_context_menu( |
953 | 'text_input_contextmenu') |
954 | self.assertTrue(popover.globalRect.y > 0, |
955 | '%s <= 0' % popover.globalRect.y) |
956 | |
957 | + def test_header_undisturbed_by_text_handlers(self): |
958 | + # Verify that handlers aren't accidentally placed at absolute 0/0 |
959 | + self.pointing_device.click_object(self.textfield) |
960 | + # Back will hide when pressed |
961 | + back = self.main_view.select_single(objectName='customBackButton') |
962 | + self.main_view.get_header().click_custom_back_button() |
963 | + self.assertFalse(back.visible) |
964 | + |
965 | def test_popover_visible_after_tapping_caret(self): |
966 | # Insert Mode |
967 | self.pointing_device.click_object(self.textfield) |
968 | - sleep(1) |
969 | - cursor = self.main_view.select_single( |
970 | - objectName='text_cursor_style_cursorPosition') |
971 | - if (self.textfield.text): |
972 | - # Let the cursor stabilize |
973 | - sleep(1) |
974 | + cursor = self.select_cursor('cursorPosition') |
975 | self.pointing_device.click_object(cursor) |
976 | self.assert_buttons(['Select All', 'Paste']) |
977 | self.assert_discard_popover() |
978 | @@ -175,9 +186,8 @@ |
979 | # Insert Mode |
980 | self.pointing_device.click_object(self.textfield) |
981 | self.textfield.keyboard.type('Lorem ipsum') |
982 | - sleep(1) |
983 | - cursor = self.main_view.select_single( |
984 | - objectName='text_cursor_style_cursorPosition') |
985 | + self.pointing_device.click_object(self.textfield) |
986 | + cursor = self.select_cursor('cursorPosition') |
987 | x, y = get_center_point(cursor) |
988 | self.pointing_device.drag(x, y, x + self.textfield.width // 2, y) |
989 | self.assert_buttons(['Select All', 'Paste']) |
990 | |
991 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textarea.qml' |
992 | --- tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textarea.qml 2015-03-03 13:20:06 +0000 |
993 | +++ tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textarea.qml 2015-03-10 16:30:01 +0000 |
994 | @@ -15,7 +15,7 @@ |
995 | */ |
996 | |
997 | import QtQuick 2.0 |
998 | -import Ubuntu.Components 1.1 |
999 | +import Ubuntu.Components 1.2 |
1000 | |
1001 | MainView { |
1002 | width: units.gu(48) |
1003 | @@ -24,11 +24,15 @@ |
1004 | |
1005 | Page { |
1006 | title: "Textarea" |
1007 | + head.backAction: Action { |
1008 | + iconName: "back" |
1009 | + text: i18n.tr("Back") |
1010 | + onTriggered: visible = false |
1011 | + } |
1012 | |
1013 | Column { |
1014 | TextArea { |
1015 | objectName: "textarea" |
1016 | - text: "Lorem ipsum dolor sit amet." |
1017 | width: units.gu(25) |
1018 | height: units.gu(25) |
1019 | } |
1020 | |
1021 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textfield.qml' |
1022 | --- tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textfield.qml 2015-03-03 13:20:06 +0000 |
1023 | +++ tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textfield.qml 2015-03-10 16:30:01 +0000 |
1024 | @@ -15,7 +15,7 @@ |
1025 | */ |
1026 | |
1027 | import QtQuick 2.0 |
1028 | -import Ubuntu.Components 1.1 |
1029 | +import Ubuntu.Components 1.2 |
1030 | |
1031 | MainView { |
1032 | width: units.gu(48) |
1033 | @@ -24,12 +24,17 @@ |
1034 | |
1035 | Page { |
1036 | title: "Textfield" |
1037 | + head.backAction: Action { |
1038 | + iconName: "back" |
1039 | + text: i18n.tr("Back") |
1040 | + onTriggered: visible = false |
1041 | + } |
1042 | |
1043 | Column { |
1044 | TextField { |
1045 | objectName: "textfield" |
1046 | placeholderText: "Type here" |
1047 | - width: units.gu(15) |
1048 | + width: units.gu(35) |
1049 | } |
1050 | } |
1051 | } |
1052 | |
1053 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textfield_custom.qml' |
1054 | --- tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textfield_custom.qml 2015-03-03 13:20:06 +0000 |
1055 | +++ tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textfield_custom.qml 2015-03-10 16:30:01 +0000 |
1056 | @@ -15,7 +15,7 @@ |
1057 | */ |
1058 | |
1059 | import QtQuick 2.0 |
1060 | -import Ubuntu.Components 1.1 |
1061 | +import Ubuntu.Components 1.2 |
1062 | import Ubuntu.Components.Themes.Ambiance 1.1 |
1063 | |
1064 | MainView { |
1065 | @@ -25,18 +25,49 @@ |
1066 | |
1067 | Page { |
1068 | title: "Textfield" |
1069 | - |
1070 | - Column { |
1071 | - TextField { |
1072 | - objectName: "textfield" |
1073 | - placeholderText: "Type here" |
1074 | - width: units.gu(15) |
1075 | - |
1076 | - style: TextFieldStyle { |
1077 | - overlaySpacing: 0 |
1078 | - frameSpacing: 0 |
1079 | - background: Item {} |
1080 | - color: UbuntuColors.lightAubergine |
1081 | + head.backAction: Action { |
1082 | + iconName: "back" |
1083 | + text: i18n.tr("Back") |
1084 | + onTriggered: visible = false |
1085 | + } |
1086 | + |
1087 | + Flickable { |
1088 | + anchors.fill: parent |
1089 | + contentHeight: childrenRect.height |
1090 | + |
1091 | + Column { |
1092 | + anchors.fill: parent |
1093 | + anchors.leftMargin: units.gu(2) |
1094 | + |
1095 | + Label { |
1096 | + text: "Below is a customized text field with clipping" |
1097 | + } |
1098 | + |
1099 | + Item { |
1100 | + clip: true // Mustn't affect handler visibility |
1101 | + width: childrenRect.width |
1102 | + height: childrenRect.height |
1103 | + |
1104 | + TextField { |
1105 | + objectName: "textfield" |
1106 | + placeholderText: "Type here" |
1107 | + width: units.gu(35) |
1108 | + height: units.gu(2) |
1109 | + |
1110 | + style: TextFieldStyle { |
1111 | + overlaySpacing: 0 |
1112 | + frameSpacing: 0 |
1113 | + background: Item {} |
1114 | + color: UbuntuColors.lightAubergine |
1115 | + } |
1116 | + } |
1117 | + } |
1118 | + |
1119 | + Repeater { |
1120 | + model: 30 |
1121 | + Label { |
1122 | + text: "These labels are here to necessitate scrolling" |
1123 | + } |
1124 | } |
1125 | } |
1126 | } |
1127 | |
1128 | === modified file 'tests/unit_x11/tst_components/tst_textinput_touch.qml' |
1129 | --- tests/unit_x11/tst_components/tst_textinput_touch.qml 2015-03-03 13:20:06 +0000 |
1130 | +++ tests/unit_x11/tst_components/tst_textinput_touch.qml 2015-03-10 16:30:01 +0000 |
1131 | @@ -26,10 +26,22 @@ |
1132 | |
1133 | Column { |
1134 | spacing: units.gu(1) |
1135 | + Label { |
1136 | + text: "Text fields are awesome" |
1137 | + width: parent.width |
1138 | + height: units.gu(10) |
1139 | + verticalAlignment: Text.AlignVCenter |
1140 | + } |
1141 | TextField { |
1142 | id: textField |
1143 | text: "This is a single line text input called TextField." |
1144 | } |
1145 | + Label { |
1146 | + text: "Text areas are even more amazing" |
1147 | + width: parent.width |
1148 | + height: units.gu(5) |
1149 | + verticalAlignment: Text.AlignVCenter |
1150 | + } |
1151 | TextArea { |
1152 | id: textArea |
1153 | text: "This is a multiline text input component called TextArea. It supports fix size as well as auto-expanding behavior. The content is scrollable only if it exceeds the visible area." |
1154 | @@ -249,7 +261,9 @@ |
1155 | } |
1156 | function test_drag_cursor_handler(data) { |
1157 | data.input.focus = true; |
1158 | - var caret = findChild(data.input, "cursorPosition_draggeditem"); |
1159 | + data.input.cursorPosition = 0; |
1160 | + var caret = findChild(data.input, "input_handler").cursorPositionCursor; |
1161 | + verify(caret, "Caret \"" + data.cursorName + "\" cannot be found!"); |
1162 | var cursorPosition = data.input.cursorPosition; |
1163 | |
1164 | TestExtras.touchDrag(0, caret, centerOf(caret), data.delta); |
1165 | @@ -261,8 +275,8 @@ |
1166 | return [ |
1167 | {tag: "TextField", input: textField, initialCursorPosition: 0, cursorName: "selectionEnd", delta: guPoint(10, 0)}, |
1168 | {tag: "TextArea", input: textArea, initialCursorPosition: 0, cursorName: "selectionEnd", delta: guPoint(10, 5)}, |
1169 | - {tag: "TextField", input: textField, initialCursorPosition: 48, cursorName: "selectionStart", delta: guPoint(-10, 0)}, |
1170 | - {tag: "TextArea", input: textArea, initialCursorPosition: 50, cursorName: "selectionStart", delta: guPoint(-20, -5)}, |
1171 | + {tag: "TextField(end)", input: textField, initialCursorPosition: 48, cursorName: "selectionStart", delta: guPoint(-10, 0)}, |
1172 | + {tag: "TextArea(end)", input: textArea, initialCursorPosition: 50, cursorName: "selectionStart", delta: guPoint(-20, -5)}, |
1173 | ]; |
1174 | } |
1175 | function test_select_text_by_dragging_cursor_handler(data) { |
1176 | @@ -271,9 +285,11 @@ |
1177 | data.input.selectWord(); |
1178 | var selectedText = data.input.selectedText; |
1179 | |
1180 | - var caret = findChild(data.input, data.cursorName + "_draggeditem"); |
1181 | + var caret = findChild(data.input, "input_handler")[data.cursorName + "Cursor"]; |
1182 | verify(caret, "Caret \"" + data.cursorName + "\" cannot be found!"); |
1183 | |
1184 | + // The caret may not receive events right away |
1185 | + sleep(500) |
1186 | TestExtras.touchDrag(0, caret, centerOf(caret), data.delta); |
1187 | verify(data.input.selectedText !== "", "Selection cleared!"); |
1188 | verify(data.input.selectedText != selectedText, "Selection did not change"); |
1189 | @@ -283,8 +299,8 @@ |
1190 | return [ |
1191 | {tag: "TextField", input: textField, withSelectedText: false, from: guPoint(2, 2), delta: guPoint(10, 0)}, |
1192 | {tag: "TextArea", input: textArea, withSelectedText: false, from: guPoint(2, 2), delta: guPoint(10, 4)}, |
1193 | - {tag: "TextField", input: textField, withSelectedText: true, from: guPoint(2, 2), delta: guPoint(10, 0)}, |
1194 | - {tag: "TextArea", input: textArea, withSelectedText: true, from: guPoint(2, 2), delta: guPoint(10, 4)}, |
1195 | + {tag: "TextField(selected)", input: textField, withSelectedText: true, from: guPoint(2, 2), delta: guPoint(10, 0)}, |
1196 | + {tag: "TextArea(selected)", input: textArea, withSelectedText: true, from: guPoint(2, 2), delta: guPoint(10, 4)}, |
1197 | ]; |
1198 | } |
1199 | function test_z_scroll_when_tap_dragged(data) { |
FAILED: Continuous integration, rev:1173 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- ci/1536/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 1710/console jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-amd64- ci/263 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-armhf- ci/266 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-armhf- ci/266/ artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-i386- ci/263 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- vivid-mako/ 1516/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 1708 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 1708/artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 18726
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/ubuntu- sdk-team- ubuntu- ui-toolkit- staging- ci/1536/ rebuild
http://