2 import Lomiri.Components 1.3
10 property TextEdit textEdit
11 property Flickable flickable
12 property Item visibleArea: Item {
16 property real lineSpacing: units.dp(3)
17 property real lineSize: textEdit.font.pixelSize + lineSpacing
18 property point frameDistance: Qt.point(flickable.x, flickable.y)
19 property string oldText:
""
20 property var flickableList:
new Array()
21 property
bool textChanged: false
23 property
bool suppressReleaseEvent: false
24 property
int pressedPosition: -1
25 property
int moveStarts: -1
26 property
int moveEnds: -1
27 property
bool doubleTapInProgress: doubleTap.running
28 property Item cursorPositionCursor: null
29 property Item selectionStartCursor: null
30 property Item selectionEndCursor: null
33 signal pressAndHold(
int pos,
bool fromTouch)
39 touchPoints: TouchPoint {
43 if (!doubleTap.running) {
45 }
else if (doubleTap.tapCount > 0) {
46 doubleTap.running =
false;
47 handleDblClick(touchPoint,
true);
51 longTap.running =
false;
54 longTap.running =
false;
55 doubleTap.running =
false;
59 onPressed: handlePressed(touchPoints[0])
60 onReleased: handleReleased(touchPoints[0])
63 Mouse.forwardTo: [root]
64 Mouse.onPressed: handlePressed(mouse)
65 Mouse.onReleased: handleReleased(mouse)
66 Mouse.onPositionChanged: handleMove(mouse)
67 Mouse.onDoubleClicked: handleDblClick(mouse)
68 Keys.onMenuPressed: overlay.pressAndHold(input.cursorPosition,
false);
71 if (event.key === Qt.Key_PageUp && event.modifiers === Qt.NoModifier) {
73 }
else if (event.key === Qt.Key_PageDown && event.modifiers === Qt.NoModifier) {
79 function activateInput() {
80 if (!textEdit.activeFocus) {
81 textEdit.forceActiveFocus();
86 function showInputPanel() {
87 if (!LomiriApplication.inputMethod.visible) {
88 LomiriApplication.inputMethod.show();
94 function ensureVisible(rect)
96 var headHeight = root.headerHeight + root.frameSpacing + units.gu(2)
97 if (flickable.moving || flickable.flicking)
99 if (flickable.contentX >= rect.x)
100 flickable.contentX = rect.x;
101 else if (flickable.contentX + flickable.width <= rect.x + rect.width)
102 flickable.contentX = rect.x + rect.width - flickable.width;
103 if (flickable.contentY >= rect.y)
104 flickable.contentY = rect.y;
105 else if (flickable.contentY + (flickable.height - headHeight) <= rect.y + rect.height)
106 flickable.contentY = rect.y + rect.height - (flickable.height - headHeight);
110 function unadulteratedCursorPosition(x, y) {
111 return textEdit.positionAt(x, y, TextInput.CursorOnCharacter);
115 function cursorPosition(x, y) {
116 var frameSpacing = root.frameSpacing;
117 var cursorPosition = unadulteratedCursorPosition(x, y);
122 return cursorPosition
126 function mousePosition(mouse) {
127 return cursorPosition(mouse.x, mouse.y);
130 function positionInSelection(pos) {
131 return (textEdit.selectionStart !== textEdit.selectionEnd)
132 && (pos >= Math.min(textEdit.selectionStart, textEdit.selectionEnd))
133 && (pos <= Math.max(textEdit.selectionStart, textEdit.selectionEnd));
137 function mouseInSelection(mouse) {
138 var pos = mousePosition(mouse);
139 return positionInSelection(pos);
143 function selectText(mouse) {
145 moveEnds = mousePosition(mouse);
146 if (moveStarts < 0) {
147 moveStarts = moveEnds;
149 textEdit.select(moveStarts, moveEnds);
153 function firstFlickableParent(item) {
154 var p = item ? item.parent :
null;
155 while (p && !p.hasOwnProperty(
"flicking")) {
162 function openContextMenu(mouse, noAutoselect) {
163 var pos = mousePosition(mouse);
164 if (!root.focus || !mouseInSelection(mouse)) {
166 textEdit.cursorPosition = pressedPosition = mousePosition(mouse);
168 textEdit.selectWord();
172 overlay.pressAndHold(textEdit.cursorPosition, mouse.touch);
175 if (mouse.button === Qt.LeftButton) {
181 function toggleFlickablesInteractive(turnOn) {
182 flickable.interactive = turnOn
187 function positionCaret(positioner, x, y) {
188 if (positioner ===
"cursorPosition") {
189 textEdit[positioner] = cursorPosition(x, y);
191 var pos = cursorPosition(x, y);
192 if (positioner ===
"selectionStart" && (pos < textEdit.selectionEnd)) {
193 textEdit.select(pos, input.selectionEnd);
194 }
else if (positioner ===
"selectionEnd" && (pos > textEdit.selectionStart)) {
195 textEdit.select(textEdit.selectionStart, pos);
201 function movePage(forward) {
202 var cx = textEdit.cursorRectangle.x;
203 var cy = textEdit.cursorRectangle.y;
205 cy += visibleArea.height;
208 cy -= visibleArea.height;
210 textEdit.cursorPosition = cursorPosition(cx, cy);
214 function handlePressed(event) {
220 event.accepted =
true;
223 pressedPosition = mousePosition(event);
225 function handleReleased(event) {
229 if ((!root.focus && !root.activeFocusOnPress) || suppressReleaseEvent ===
true) {
230 suppressReleaseEvent =
false;
235 if (state ===
"" || event.touch) {
236 textEdit.cursorPosition = mousePosition(event);
238 moveStarts = moveEnds = -1;
241 if (event.button === Qt.RightButton) {
243 overlay.pressAndHold(textEdit.cursorPosition, event.touch);
245 overlay.tap(textEdit.cursorPosition);
248 function handleMove(event) {
250 if (!textEdit.activeFocus || (!event.touch && event.button !== Qt.LeftButton) || !textEdit.selectByMouse) {
255 function handleDblClick(event) {
256 if (root.selectByMouse) {
257 openContextMenu(event,
false);
260 suppressReleaseEvent =
true;
271 ignoreUnknownSignals:
true
272 onActiveFocusChanged: {
273 textEdit.focus = root.activeFocus;
275 onKeyNavigationFocusChanged: {
276 if (root.keyNavigationFocus) {
277 textEdit.forceActiveFocus();
281 LomiriApplication.inputMethod.commit()
282 state = (root.focus) ?
"" :
"inactive";
284 textEdit.forceActiveFocus()
296 onCursorRectangleChanged: ensureVisible(textEdit.cursorRectangle)
299 if (oldText != textEdit.text) {
301 oldText = textEdit.text
305 onActiveFocusChanged: {
306 if (!textEdit.activeFocus && popover)
307 PopupUtils.close(popover);
316 onFlickStarted: toggleScrollingState(
true)
317 onMovementStarted: toggleScrollingState(true)
319 onMovementEnded: toggleScrollingState(false)
321 function toggleScrollingState(turnOn) {
325 overlay.state = (turnOn) ?
"scrolling" :
""
332 onSelectedTextChanged: {
333 if (textEdit.selectedText !==
"") {
334 if (!selectionStartCursor) {
335 selectionStartCursor = textEdit.cursorDelegate.createObject(
337 "positionProperty":
"selectionStart",
341 moveSelectionCursor(selectionStartCursor);
342 selectionEndCursor = textEdit.cursorDelegate.createObject(
344 "positionProperty":
"selectionEnd",
348 moveSelectionCursor(selectionEndCursor);
351 if (selectionStartCursor) {
352 selectionStartCursor.destroy();
353 selectionStartCursor =
null;
354 selectionEndCursor.destroy();
355 selectionEndCursor =
null;
359 onSelectionStartChanged: moveSelectionCursor(selectionStartCursor,
true);
360 onSelectionEndChanged: moveSelectionCursor(selectionEndCursor,
true);
362 function moveSelectionCursor(cursor, updateProperty) {
368 if (updateProperty && QuickUtils.className(textEdit) ===
"QQuickTextEdit") {
369 textEdit.selectedTextChanged();
372 var pos = textEdit.positionToRectangle(textEdit[cursor.positionProperty]);
375 cursor.height = pos.height;
383 acceptedButtons: Qt.RightButton
385 onReleased: openContextMenu(mouse,
true)
386 cursorShape: Qt.IBeamCursor
391 property int tapCount: 0
408 if (touchPoint.startY - touchPoint.y < -units.gu(2))
411 openContextMenu(touchPoint,
false);
412 suppressReleaseEvent =
true;
423 script: toggleFlickablesInteractive(
true);
449 toggleFlickablesInteractive(
false);
450 if (!positionInSelection(pressedPosition)) {
451 textEdit.cursorPosition = pressedPosition;