Merge lp:~ubuntu-sdk-team/ubuntu-ui-toolkit/textHandlerCleanUpRTM into lp:ubuntu-ui-toolkit/rtm

Proposed by Christian Dywan on 2015-01-23
Status: Rejected
Rejected by: Christian Dywan on 2015-03-10
Proposed branch: lp:~ubuntu-sdk-team/ubuntu-ui-toolkit/textHandlerCleanUpRTM
Merge into: lp:ubuntu-ui-toolkit/rtm
Diff against target: 1349 lines (+395/-290)
25 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)
modules/Ubuntu/Components/plugin/quickutils.cpp (+4/-1)
modules/Ubuntu/Components/plugin/quickutils.h (+1/-0)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py (+5/-0)
tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.header.qml (+69/-0)
tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.py (+42/-24)
tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textarea.qml (+10/-1)
tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textfield.qml (+11/-1)
tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textfield_custom.qml (+47/-12)
tests/launcher/launcher.cpp (+5/-3)
tests/unit/tst_quickutils/tst_quickutils.cpp (+60/-0)
tests/unit/tst_quickutils/tst_quickutils.pro (+2/-0)
tests/unit/unit.pro (+2/-1)
tests/unit_x11/tst_components/tst_textinput_touch.qml (+22/-6)
To merge this branch: bzr merge lp:~ubuntu-sdk-team/ubuntu-ui-toolkit/textHandlerCleanUpRTM
Reviewer Review Type Date Requested Status
Zsombor Egri (community) 2015-01-23 Approve on 2015-02-23
Review via email: mp+247388@code.launchpad.net

Commit Message

New text handler visuals and improved behavior

To post a comment you must log in.
1160. By Christian Dywan on 2015-02-17

Remove intentional CI trap and disable debugging visuals

Zsombor Egri (zsombi) wrote :

Cool stuff, it is good to see the text input shaping nicely.

review: Approve
1161. By Christian Dywan on 2015-02-17

Put some labels in the textinput test to avoid overlapping

1162. By Christian Dywan on 2015-02-18

Ensure text field overlays have priority

1163. By Christian Dywan on 2015-02-19

Anchor text popover to draggedItem so it doesn't overlap handlers

1164. By Christian Dywan on 2015-02-19

Parent handlers on root item and demo in custom textfield case

1165. By Christian Dywan on 2015-02-19

Take offset of input to main into account

1166. By Christian Dywan on 2015-02-20

Consider parent flickable contentY to catch scrolling

1167. By Christian Dywan on 2015-02-23

Change scrolling hack to properties absX and absY

Zsombor Egri (zsombi) wrote :

latest changes are also good to go.

review: Approve
1168. By Christian Dywan on 2015-02-26

Assign properties to ensure unit tests finds handlers

1169. By Christian Dywan on 2015-02-27

Ensure test_textinput can tap in the bottom right of the textfield

1170. By Christian Dywan on 2015-03-02

Backport launcher build fix for Qt5.4 from staging

1171. By Christian Dywan on 2015-03-02

Reposition draggedItem once it receives its width

Otherwise the area may be placed at absolute 0/0

Unmerged revisions

1171. By Christian Dywan on 2015-03-02

Reposition draggedItem once it receives its width

Otherwise the area may be placed at absolute 0/0

1170. By Christian Dywan on 2015-03-02

Backport launcher build fix for Qt5.4 from staging

1169. By Christian Dywan on 2015-02-27

Ensure test_textinput can tap in the bottom right of the textfield

1168. By Christian Dywan on 2015-02-26

Assign properties to ensure unit tests finds handlers

1167. By Christian Dywan on 2015-02-23

Change scrolling hack to properties absX and absY

1166. By Christian Dywan on 2015-02-20

Consider parent flickable contentY to catch scrolling

1165. By Christian Dywan on 2015-02-19

Take offset of input to main into account

1164. By Christian Dywan on 2015-02-19

Parent handlers on root item and demo in custom textfield case

1163. By Christian Dywan on 2015-02-19

Anchor text popover to draggedItem so it doesn't overlap handlers

1162. By Christian Dywan on 2015-02-18

Ensure text field overlays have priority

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'examples/ubuntu-ui-toolkit-gallery/TextInputs.qml'
2--- examples/ubuntu-ui-toolkit-gallery/TextInputs.qml 2014-10-09 09:09:12 +0000
3+++ examples/ubuntu-ui-toolkit-gallery/TextInputs.qml 2015-03-02 12:00:38 +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 2014-11-12 10:28:55 +0000
35+++ modules/Ubuntu/Components/InputHandler.qml 2015-03-02 12:00:38 +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)
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 2014-11-12 03:51:45 +0000
196+++ modules/Ubuntu/Components/TextArea.qml 2015-03-02 12:00:38 +0000
197@@ -759,8 +759,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@@ -804,9 +803,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@@ -871,7 +870,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 2014-11-12 03:51:45 +0000
230+++ modules/Ubuntu/Components/TextCursor.qml 2015-03-02 12:00:38 +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);
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 2014-11-12 03:51:45 +0000
474+++ modules/Ubuntu/Components/TextField.qml 2015-03-02 12:00:38 +0000
475@@ -846,9 +846,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@@ -873,6 +871,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@@ -893,6 +893,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@@ -1010,12 +1012,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 2014-11-12 03:51:45 +0000
520+++ modules/Ubuntu/Components/TextInputPopover.qml 2015-03-02 12:00:38 +0000
521@@ -69,11 +69,14 @@
522 }
523
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@@ -85,7 +88,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 2014-04-23 08:50:20 +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.0
569-import Ubuntu.Components 1.1
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 2014-10-08 17:32:09 +0000
647+++ modules/Ubuntu/Components/Themes/Ambiance/TextAreaStyle.qml 2015-03-02 12:00:38 +0000
648@@ -36,16 +36,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 2014-11-12 03:51:45 +0000
670+++ modules/Ubuntu/Components/Themes/Ambiance/TextCursorStyle.qml 2015-03-02 12:00:38 +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 2014-04-30 07:10:06 +0000
711+++ modules/Ubuntu/Components/Themes/Ambiance/TextFieldStyle.qml 2015-03-02 12:00:38 +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 2014-08-11 12:44:43 +0000
721+++ modules/Ubuntu/Components/Themes/Ambiance/ToolbarButtonStyle.qml 2015-03-02 12:00:38 +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'
745Binary 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-02 12:00:38 +0000 differ
746=== modified file 'modules/Ubuntu/Components/Themes/Ambiance/qmldir'
747--- modules/Ubuntu/Components/Themes/Ambiance/qmldir 2014-08-07 19:24:52 +0000
748+++ modules/Ubuntu/Components/Themes/Ambiance/qmldir 2015-03-02 12:00:38 +0000
749@@ -10,7 +10,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 internal SwitchStyle SwitchStyle.qml
757@@ -48,6 +47,4 @@
758 PageHeadStyle 1.1 PageHeadStyle.qml
759 Palette 1.1 Palette.qml
760
761-internal TextSelectionStartCursorStyle TextSelectionStartCursorStyle.qml
762-internal TextSelectionEndCursorStyle TextSelectionEndCursorStyle.qml
763 internal OverflowPanel OverflowPanel.qml
764
765=== modified file 'modules/Ubuntu/Components/plugin/quickutils.cpp'
766--- modules/Ubuntu/Components/plugin/quickutils.cpp 2014-08-12 10:58:30 +0000
767+++ modules/Ubuntu/Components/plugin/quickutils.cpp 2015-03-02 12:00:38 +0000
768@@ -35,6 +35,7 @@
769 m_rootView(0)
770 {
771 QGuiApplication::instance()->installEventFilter(this);
772+ m_omitIM << "ibus" << "none" << "compose";
773 }
774
775 /*!
776@@ -107,7 +108,9 @@
777
778 QString QuickUtils::inputMethodProvider() const
779 {
780- return QString(getenv("QT_IM_MODULE"));
781+ QString im(getenv("QT_IM_MODULE"));
782+
783+ return m_omitIM.contains(im) ? QString() : im;
784 }
785
786 bool QuickUtils::touchScreenAvailable() const
787
788=== modified file 'modules/Ubuntu/Components/plugin/quickutils.h'
789--- modules/Ubuntu/Components/plugin/quickutils.h 2014-06-10 11:47:09 +0000
790+++ modules/Ubuntu/Components/plugin/quickutils.h 2015-03-02 12:00:38 +0000
791@@ -58,6 +58,7 @@
792 private:
793 explicit QuickUtils(QObject *parent = 0);
794 QPointer<QQuickView> m_rootView;
795+ QStringList m_omitIM;
796
797 void lookupQuickView();
798 };
799
800=== modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py'
801--- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py 2014-08-20 06:45:28 +0000
802+++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py 2015-03-02 12:00:38 +0000
803@@ -56,6 +56,7 @@
804
805 def _get_button(self, text):
806 buttons = self.select_many('AbstractButton')
807+ texts = []
808 for button in buttons:
809 # workaround used in the text input's context menu to access
810 # action.text so we can get the proper button by text, action
811@@ -63,6 +64,10 @@
812 # https://bugs.launchpad.net/autopilot/+bug/1334599
813 if button.text == text:
814 return button
815+ texts.append(button.text)
816+ raise _common.ToolkitException(
817+ 'Could not find a button with text %s (Available buttons are %s)'
818+ % (text, ','.join(texts)))
819
820
821 class ActionSelectionPopover(_common.UbuntuUIToolkitCustomProxyObjectBase):
822
823=== added file 'tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.header.qml'
824--- tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.header.qml 1970-01-01 00:00:00 +0000
825+++ tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.header.qml 2015-03-02 12:00:38 +0000
826@@ -0,0 +1,69 @@
827+/*
828+ * Copyright 2015 Canonical Ltd.
829+ *
830+ * This program is free software; you can redistribute it and/or modify
831+ * it under the terms of the GNU Lesser General Public License as published by
832+ * the Free Software Foundation; version 3.
833+ *
834+ * This program is distributed in the hope that it will be useful,
835+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
836+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
837+ * GNU Lesser General Public License for more details.
838+ *
839+ * You should have received a copy of the GNU Lesser General Public License
840+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
841+ */
842+
843+import QtQuick 2.0
844+import Ubuntu.Components 1.1
845+
846+MainView {
847+ id: root
848+ width: units.gu(48)
849+ height: units.gu(60)
850+ useDeprecatedToolbar: false
851+
852+ Page {
853+ title: "Header"
854+ head.contents: TextField {
855+ id: searchTextField
856+ objectName: "textfield"
857+ placeholderText: "Header"
858+ inputMethodHints: Qt.ImhNoPredictiveText
859+ hasClearButton: false
860+
861+ text: "Then two bears came out of the woods and mauled forty-two of the youths."
862+
863+ anchors {
864+ fill: parent
865+ leftMargin: units.gu(1)
866+ topMargin: units.gu(0.5)
867+ bottomMargin: units.gu(0.5)
868+ rightMargin: units.gu(1)
869+ }
870+
871+ secondaryItem: AbstractButton {
872+ height: searchTextField.height
873+ width: height
874+ enabled: searchTextField.text.length > 0
875+ Image {
876+ objectName: "clearIcon"
877+ anchors.fill: parent
878+ anchors.margins: units.gu(.75)
879+ source: "image://theme/clear"
880+ opacity: searchTextField.text.length > 0
881+ visible: opacity > 0
882+ Behavior on opacity {
883+ UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
884+ }
885+ }
886+ }
887+ }
888+
889+ Column {
890+ Label {
891+ text: "Above is a text field in the header"
892+ }
893+ }
894+ }
895+}
896
897=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.py'
898--- tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.py 2014-11-12 03:51:45 +0000
899+++ tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.py 2015-03-02 12:00:38 +0000
900@@ -36,6 +36,8 @@
901 dir_path, 'test_textinput.textarea.qml')
902 customfield_qml_file_path = os.path.join(
903 dir_path, 'test_textinput.textfield_custom.qml')
904+ header_qml_file_path = os.path.join(
905+ dir_path, 'test_textinput.header.qml')
906
907 scenarios = [
908 ('textfield',
909@@ -47,6 +49,9 @@
910 ('customfield',
911 dict(test_qml_file_path=customfield_qml_file_path,
912 objectName='textfield')),
913+ ('header',
914+ dict(test_qml_file_path=header_qml_file_path,
915+ objectName='textfield')),
916 ]
917
918 def get_command_line(self, command_line):
919@@ -59,20 +64,23 @@
920 objectName=self.objectName)
921 self.assertFalse(self.textfield.focus)
922
923+ def select_cursor(self, positionProperty):
924+ # The cursor may not receive events right away
925+ sleep(1)
926+ return self.main_view.select_single(
927+ objectName=positionProperty + '_draggeditem')
928+
929 def test_caret_visible_on_focus(self):
930 cursorName = 'text_cursor_style_caret_cursorPosition'
931 self._assert_not_visible(objectName=cursorName)
932 self.pointing_device.click_object(self.textfield)
933 self.assertTrue(self.textfield.focus)
934- cursor = self.main_view.select_single(objectName=cursorName)
935- self.assertTrue(cursor.visible)
936+ self.main_view.select_single(objectName=cursorName)
937
938 def test_caret_hide_while_typing(self):
939 self.pointing_device.click_object(self.textfield)
940 self.assertTrue(self.textfield.focus)
941- cursor = self.main_view.select_single(
942- objectName='text_cursor_style_caret_cursorPosition')
943- self.assertTrue(cursor.visible)
944+ cursor = self.select_cursor('cursorPosition')
945
946 self.textfield.keyboard.type('Lorem ipsum')
947 self.assertFalse(cursor.visible)
948@@ -80,17 +88,13 @@
949 def test_caret_visible_after_tapping(self):
950 self.test_caret_hide_while_typing()
951 self.pointing_device.click_object(self.textfield)
952- cursor = self.main_view.select_single(
953- objectName='text_cursor_style_caret_cursorPosition')
954- self.assertTrue(cursor.visible)
955+ self.select_cursor('cursorPosition')
956
957 def test_caret_visible_after_selecting(self):
958 self.test_caret_hide_while_typing()
959 # Select a character
960 self.keyboard.press_and_release('Shift+Left')
961- cursor = self.main_view.select_single(
962- objectName='text_cursor_style_caret_selectionEnd')
963- self.assertTrue(cursor.visible)
964+ self.select_cursor('selectionEnd')
965
966
967 class InsertModeTextInputTestCase(tests.QMLFileAppTestCase):
968@@ -137,44 +141,58 @@
969 # Discard popover by tap
970 self.pointing_device.move(
971 self.textfield.globalRect.x + self.textfield.width * 0.7,
972- self.textfield.globalRect.y + self.textfield.height / 10)
973+ self.textfield.globalRect.y + self.textfield.height * 0.9)
974 self.pointing_device.click()
975
976 self._assert_not_visible(objectName='text_input_contextmenu')
977
978- @testtools.skipIf(platform.model() == 'Desktop', 'Touch only')
979+ def select_cursor(self, positionProperty):
980+ # The cursor may not receive events right away
981+ sleep(1)
982+ return self.main_view.select_single(
983+ objectName=positionProperty + '_draggeditem')
984+
985+ def test_header_undisturbed_by_text_handlers(self):
986+ # Verify that handlers aren't accidentally placed at absolute 0/0
987+ self.pointing_device.click_object(self.textfield)
988+ # Back will hide when pressed
989+ back = self.main_view.select_single(objectName='customBackButton')
990+ self.main_view.get_header().click_custom_back_button()
991+ self.assertFalse(back.visible)
992+
993 def test_popover_visible_after_tapping_caret(self):
994 # Insert Mode
995 self.pointing_device.click_object(self.textfield)
996- sleep(1)
997- cursor = self.main_view.select_single(
998- objectName='text_cursor_style_cursorPosition')
999+ cursor = self.select_cursor('cursorPosition')
1000 self.pointing_device.click_object(cursor)
1001 self.assert_buttons(['Select All', 'Paste'])
1002 self.assert_discard_popover()
1003
1004- @testtools.skipIf(platform.model() == 'Desktop', 'Touch only')
1005 def test_popover_visible_after_dragging_caret(self):
1006 # Insert Mode
1007 self.pointing_device.click_object(self.textfield)
1008 self.textfield.keyboard.type('Lorem ipsum')
1009- cursor = self.main_view.select_single(
1010- objectName='text_cursor_style_cursorPosition')
1011+ self.pointing_device.click_object(self.textfield)
1012+ cursor = self.select_cursor('cursorPosition')
1013 x, y = get_center_point(cursor)
1014 self.pointing_device.drag(x, y, 0, y)
1015 self.assert_buttons(['Select All', 'Paste'])
1016 self.assert_discard_popover()
1017
1018 @testtools.skipIf(platform.model() == 'Desktop', 'Touch only')
1019- def test_popover_visible_after_selecting(self):
1020+ def test_popover_visible_after_long_press(self):
1021 # Select Mode
1022 self.pointing_device.click_object(self.textfield)
1023 self.textfield.keyboard.type('Lorem ipsum')
1024 self.pointing_device.move(
1025- self.textfield.globalRect.x + self.textfield.width / 8,
1026- self.textfield.globalRect.y + self.textfield.height / 2)
1027+ self.textfield.globalRect.x + self.textfield.width // 8,
1028+ self.textfield.globalRect.y + self.textfield.height // 2)
1029 # Long press to select a word
1030- self.pointing_device.click()
1031- self.pointing_device.click()
1032+ # FIXME: input.Mouse doesn't support long press
1033+ # press_duration doesn't work here
1034+ # self.pointing_device.click(press_duration=2.0)
1035+ self.pointing_device.press()
1036+ sleep(2)
1037+ self.pointing_device.release()
1038 self.assert_buttons(['Cut', 'Copy', 'Paste'])
1039 self.assert_discard_popover()
1040
1041=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textarea.qml'
1042--- tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textarea.qml 2014-09-17 15:11:08 +0000
1043+++ tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textarea.qml 2015-03-02 12:00:38 +0000
1044@@ -20,14 +20,23 @@
1045 MainView {
1046 width: units.gu(48)
1047 height: units.gu(60)
1048+ useDeprecatedToolbar: false
1049
1050 Page {
1051 title: "Textarea"
1052+ tools: ToolbarItems {
1053+ back: ToolbarButton {
1054+ action: Action {
1055+ iconName: "back"
1056+ text: i18n.tr("Back")
1057+ onTriggered: visible = false
1058+ }
1059+ }
1060+ }
1061
1062 Column {
1063 TextArea {
1064 objectName: "textarea"
1065- text: "Lorem ipsum dolor sit amet."
1066 width: units.gu(25)
1067 height: units.gu(25)
1068 }
1069
1070=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textfield.qml'
1071--- tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textfield.qml 2014-09-17 15:11:08 +0000
1072+++ tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textfield.qml 2015-03-02 12:00:38 +0000
1073@@ -20,15 +20,25 @@
1074 MainView {
1075 width: units.gu(48)
1076 height: units.gu(60)
1077+ useDeprecatedToolbar: false
1078
1079 Page {
1080 title: "Textfield"
1081+ tools: ToolbarItems {
1082+ back: ToolbarButton {
1083+ action: Action {
1084+ iconName: "back"
1085+ text: i18n.tr("Back")
1086+ onTriggered: visible = false
1087+ }
1088+ }
1089+ }
1090
1091 Column {
1092 TextField {
1093 objectName: "textfield"
1094 placeholderText: "Type here"
1095- width: units.gu(15)
1096+ width: units.gu(35)
1097 }
1098 }
1099 }
1100
1101=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textfield_custom.qml'
1102--- tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textfield_custom.qml 2014-09-17 15:11:08 +0000
1103+++ tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.textfield_custom.qml 2015-03-02 12:00:38 +0000
1104@@ -21,21 +21,56 @@
1105 MainView {
1106 width: units.gu(48)
1107 height: units.gu(60)
1108+ useDeprecatedToolbar: false
1109
1110 Page {
1111 title: "Textfield"
1112-
1113- Column {
1114- TextField {
1115- objectName: "textfield"
1116- placeholderText: "Type here"
1117- width: units.gu(15)
1118-
1119- style: TextFieldStyle {
1120- overlaySpacing: 0
1121- frameSpacing: 0
1122- background: Item {}
1123- color: UbuntuColors.lightAubergine
1124+ tools: ToolbarItems {
1125+ back: ToolbarButton {
1126+ action: Action {
1127+ iconName: "back"
1128+ text: i18n.tr("Back")
1129+ onTriggered: visible = false
1130+ }
1131+ }
1132+ }
1133+
1134+ Flickable {
1135+ anchors.fill: parent
1136+ contentHeight: childrenRect.height
1137+
1138+ Column {
1139+ anchors.fill: parent
1140+
1141+ Label {
1142+ text: "Below is a customized text field with clipping"
1143+ }
1144+
1145+ Item {
1146+ clip: true // Mustn't affect handler visibility
1147+ width: childrenRect.width
1148+ height: childrenRect.height
1149+
1150+ TextField {
1151+ objectName: "textfield"
1152+ placeholderText: "Type here"
1153+ width: units.gu(35)
1154+ height: units.gu(2)
1155+
1156+ style: TextFieldStyle {
1157+ overlaySpacing: 0
1158+ frameSpacing: 0
1159+ background: Item {}
1160+ color: UbuntuColors.lightAubergine
1161+ }
1162+ }
1163+ }
1164+
1165+ Repeater {
1166+ model: 30
1167+ Label {
1168+ text: "These labels are here to necessitate scrolling"
1169+ }
1170 }
1171 }
1172 }
1173
1174=== modified file 'tests/launcher/launcher.cpp'
1175--- tests/launcher/launcher.cpp 2014-06-16 09:19:23 +0000
1176+++ tests/launcher/launcher.cpp 2015-03-02 12:00:38 +0000
1177@@ -53,10 +53,12 @@
1178 // Oxide and QWebEngine need a shared context
1179 QScopedPointer<QOpenGLContext> shareContext;
1180 shareContext.reset(new QOpenGLContext);
1181-#if QT_VERSION < QT_VERSION_CHECK(5, 3, 0)
1182+#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
1183+ qt_gl_set_global_share_context(shareContext.data());
1184+#elif QT_VERSION >= QT_VERSION_CHECK(5, 3, 0)
1185+ QOpenGLContextPrivate::setGlobalShareContext(shareContext.data());
1186+#else
1187 QSGContext::setSharedOpenGLContext(shareContext.data());
1188-#else
1189- QOpenGLContextPrivate::setGlobalShareContext(shareContext.data());
1190 #endif
1191 QGuiApplication::setApplicationName("UITK Launcher");
1192 QGuiApplication application(argc, (char**)argv);
1193
1194=== added directory 'tests/unit/tst_quickutils'
1195=== added file 'tests/unit/tst_quickutils/tst_quickutils.cpp'
1196--- tests/unit/tst_quickutils/tst_quickutils.cpp 1970-01-01 00:00:00 +0000
1197+++ tests/unit/tst_quickutils/tst_quickutils.cpp 2015-03-02 12:00:38 +0000
1198@@ -0,0 +1,60 @@
1199+/*
1200+ * Copyright 2014 Canonical Ltd.
1201+ *
1202+ * This program is free software; you can redistribute it and/or modify
1203+ * it under the terms of the GNU Lesser General Public License as published by
1204+ * the Free Software Foundation; version 3.
1205+ *
1206+ * This program is distributed in the hope that it will be useful,
1207+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1208+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1209+ * GNU Lesser General Public License for more details.
1210+ *
1211+ * You should have received a copy of the GNU Lesser General Public License
1212+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1213+ *
1214+ */
1215+
1216+#include "uctestcase.h"
1217+#include "quickutils.h"
1218+
1219+class tst_QuickUtils : public QObject
1220+{
1221+ Q_OBJECT
1222+public:
1223+ tst_QuickUtils() {}
1224+
1225+private:
1226+ QString imEnvVar;
1227+
1228+private Q_SLOTS:
1229+ void initTestCase()
1230+ {
1231+ imEnvVar = qgetenv("QT_IM_MODULE");
1232+ QuickUtils::instance();
1233+ }
1234+ void cleanupTestCase()
1235+ {
1236+ qputenv("QT_IM_MODULE", imEnvVar.toLocal8Bit());
1237+ }
1238+
1239+ void test_inputmethod_data()
1240+ {
1241+ QTest::addColumn<QByteArray>("envVar");
1242+
1243+ QTest::newRow("(empty)") << QByteArray("");
1244+ QTest::newRow("ibus") << QByteArray("ibus");
1245+ QTest::newRow("compose") << QByteArray("compose");
1246+ QTest::newRow("none") << QByteArray("none");
1247+ }
1248+ void test_inputmethod()
1249+ {
1250+ QFETCH(QByteArray, envVar);
1251+ qputenv("QT_IM_MODULE", envVar);
1252+ QVERIFY(QuickUtils::instance().inputMethodProvider().isEmpty());
1253+ }
1254+};
1255+
1256+QTEST_MAIN(tst_QuickUtils)
1257+
1258+#include "tst_quickutils.moc"
1259
1260=== added file 'tests/unit/tst_quickutils/tst_quickutils.pro'
1261--- tests/unit/tst_quickutils/tst_quickutils.pro 1970-01-01 00:00:00 +0000
1262+++ tests/unit/tst_quickutils/tst_quickutils.pro 2015-03-02 12:00:38 +0000
1263@@ -0,0 +1,2 @@
1264+include(../test-include.pri)
1265+SOURCES += tst_quickutils.cpp
1266
1267=== modified file 'tests/unit/unit.pro'
1268--- tests/unit/unit.pro 2014-11-26 15:39:39 +0000
1269+++ tests/unit/unit.pro 2015-03-02 12:00:38 +0000
1270@@ -23,4 +23,5 @@
1271 tst_arguments \
1272 tst_argument \
1273 tst_alarms \
1274- tst_theme
1275+ tst_theme \
1276+ tst_quickutils
1277
1278=== modified file 'tests/unit_x11/tst_components/tst_textinput_touch.qml'
1279--- tests/unit_x11/tst_components/tst_textinput_touch.qml 2014-11-13 19:43:48 +0000
1280+++ tests/unit_x11/tst_components/tst_textinput_touch.qml 2015-03-02 12:00:38 +0000
1281@@ -26,10 +26,22 @@
1282
1283 Column {
1284 spacing: units.gu(1)
1285+ Label {
1286+ text: "Text fields are awesome"
1287+ width: parent.width
1288+ height: units.gu(10)
1289+ verticalAlignment: Text.AlignVCenter
1290+ }
1291 TextField {
1292 id: textField
1293 text: "This is a single line text input called TextField."
1294 }
1295+ Label {
1296+ text: "Text areas are even more amazing"
1297+ width: parent.width
1298+ height: units.gu(5)
1299+ verticalAlignment: Text.AlignVCenter
1300+ }
1301 TextArea {
1302 id: textArea
1303 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."
1304@@ -246,7 +258,9 @@
1305 }
1306 function test_drag_cursor_handler(data) {
1307 data.input.focus = true;
1308- var caret = findChild(data.input, "cursorPosition_draggeditem");
1309+ data.input.cursorPosition = 0;
1310+ var caret = findChild(data.input, "input_handler").cursorPositionCursor;
1311+ verify(caret, "Caret \"" + data.cursorName + "\" cannot be found!");
1312 var cursorPosition = data.input.cursorPosition;
1313
1314 TestExtras.touchDrag(0, caret, centerOf(caret), data.delta);
1315@@ -258,8 +272,8 @@
1316 return [
1317 {tag: "TextField", input: textField, initialCursorPosition: 0, cursorName: "selectionEnd", delta: guPoint(10, 0)},
1318 {tag: "TextArea", input: textArea, initialCursorPosition: 0, cursorName: "selectionEnd", delta: guPoint(10, 5)},
1319- {tag: "TextField", input: textField, initialCursorPosition: 48, cursorName: "selectionStart", delta: guPoint(-10, 0)},
1320- {tag: "TextArea", input: textArea, initialCursorPosition: 50, cursorName: "selectionStart", delta: guPoint(-20, -5)},
1321+ {tag: "TextField(end)", input: textField, initialCursorPosition: 48, cursorName: "selectionStart", delta: guPoint(-10, 0)},
1322+ {tag: "TextArea(end)", input: textArea, initialCursorPosition: 50, cursorName: "selectionStart", delta: guPoint(-20, -5)},
1323 ];
1324 }
1325 function test_select_text_by_dragging_cursor_handler(data) {
1326@@ -268,9 +282,11 @@
1327 data.input.selectWord();
1328 var selectedText = data.input.selectedText;
1329
1330- var caret = findChild(data.input, data.cursorName + "_draggeditem");
1331+ var caret = findChild(data.input, "input_handler")[data.cursorName + "Cursor"];
1332 verify(caret, "Caret \"" + data.cursorName + "\" cannot be found!");
1333
1334+ // The caret may not receive events right away
1335+ sleep(500)
1336 TestExtras.touchDrag(0, caret, centerOf(caret), data.delta);
1337 verify(data.input.selectedText !== "", "Selection cleared!");
1338 verify(data.input.selectedText != selectedText, "Selection did not change");
1339@@ -280,8 +296,8 @@
1340 return [
1341 {tag: "TextField", input: textField, withSelectedText: false, from: guPoint(2, 2), delta: guPoint(10, 0)},
1342 {tag: "TextArea", input: textArea, withSelectedText: false, from: guPoint(2, 2), delta: guPoint(10, 4)},
1343- {tag: "TextField", input: textField, withSelectedText: true, from: guPoint(2, 2), delta: guPoint(10, 0)},
1344- {tag: "TextArea", input: textArea, withSelectedText: true, from: guPoint(2, 2), delta: guPoint(10, 4)},
1345+ {tag: "TextField(selected)", input: textField, withSelectedText: true, from: guPoint(2, 2), delta: guPoint(10, 0)},
1346+ {tag: "TextArea(selected)", input: textArea, withSelectedText: true, from: guPoint(2, 2), delta: guPoint(10, 4)},
1347 ];
1348 }
1349 function test_z_scroll_when_tap_dragged(data) {

Subscribers

People subscribed via source and target branches

to all changes: