From 7525a0db40648af081ed7e7d81744a53cdd233e7 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 15 Jul 2015 19:23:30 +0200 Subject: [PATCH 01/13] experimental brnch for inline edit menu --- .../plasmastyle/EditMenuTouch.qml | 196 ++++++++++++++++++ .../plasmastyle/TextAreaStyle.qml | 3 + .../plasmastyle/TextFieldStyle.qml | 4 + 3 files changed, 203 insertions(+) create mode 100644 src/declarativeimports/plasmastyle/EditMenuTouch.qml diff --git a/src/declarativeimports/plasmastyle/EditMenuTouch.qml b/src/declarativeimports/plasmastyle/EditMenuTouch.qml new file mode 100644 index 000000000..07afde7d8 --- /dev/null +++ b/src/declarativeimports/plasmastyle/EditMenuTouch.qml @@ -0,0 +1,196 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 +import QtQuick.Controls.Private 1.0 +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.components 2.0 as PlasmaComponents + +Item { + anchors.fill: parent + property bool __showMenuFromTouchAndHold: false + + property Component defaultMenu: PlasmaCore.FrameSvgItem { + id: popup + imagePath: "widgets/background" + visible: false + width: childrenRect.width + margins.left + margins.right + height: childrenRect.height + margins.top + margins.bottom + z: 9999 + function __popup(pos) { + popup.x = pos.x; + popup.y = pos.y; + popup.visible = true; + input.z = 9999 + print("POPUP MENU"+pos.y+" "+popup.x+" "+popup.width+" "+popup.parent) + //popup.y = 0 + //popup.parent = input.parent.parent.parent.parent.parent + var par = popup.parent + while (par) { + popup.parent = par + par = parent.parent + } + popup.z = 9999 + } + function __dismissMenu() { + popup.visible = false; + input.z = 0 + } + Row { + x: parent.margins.left + y: parent.margins.top + property Item checkedButton + PlasmaComponents.ToolButton { + iconSource: "edit-cut" + flat: false + onClicked: { + cut(); + select(input.cursorPosition, input.cursorPosition); + } + } + PlasmaComponents.ToolButton { + iconSource: "edit-copy" + flat: false + onClicked: { + copy(); + select(input.cursorPosition, input.cursorPosition); + } + } + PlasmaComponents.ToolButton { + iconSource: "edit-paste" + flat: false + onClicked: { + paste(); + } + } + } + } + Connections { + target: mouseArea + + function clearFocusFromOtherItems() + { + var selectionItem = TextSingleton.selectionItem; + if (!selectionItem) + return; + var otherPos = selectionItem.cursorPosition; + selectionItem.select(otherPos, otherPos) + } + + onClicked: { + if (control.menu && getMenuInstance().__popupVisible) { + select(input.cursorPosition, input.cursorPosition); + } else { + input.activate(); + clearFocusFromOtherItems(); + } + + if (input.activeFocus) { + var pos = input.positionAt(mouse.x, mouse.y) + input.moveHandles(pos, pos) + } + } + + onPressAndHold: { + var pos = input.positionAt(mouseArea.mouseX, mouseArea.mouseY); + input.select(pos, pos); + var hasSelection = selectionStart != selectionEnd; + selectWord(); + } + + onReleased: __showMenuFromTouchAndHold = false + onCanceled: __showMenuFromTouchAndHold = false + } + + Connections { + target: cursorHandle ? cursorHandle : null + ignoreUnknownSignals: true + onPressedChanged: menuTimer.start() + } + + Connections { + target: selectionHandle ? selectionHandle : null + ignoreUnknownSignals: true + onPressedChanged: menuTimer.start() + } + + Connections { + target: flickable + ignoreUnknownSignals: true + onMovingChanged: menuTimer.start() + } + + Connections { + id: selectionConnections + target: input + ignoreUnknownSignals: true + onSelectionStartChanged: menuTimer.start() + onSelectionEndChanged: menuTimer.start() + onActiveFocusChanged: menuTimer.start() + } + + Timer { + // We use a timer so that we end up with one update when multiple connections fire at the same time. + // Basically we wan't the menu to be open if the user does a press and hold, or if we have a selection. + // The exceptions are if the user is moving selection handles or otherwise touching the screen (e.g flicking). + // What is currently missing are showing a magnifyer to place the cursor, and to reshow the edit menu when + // flicking stops. + id: menuTimer + interval: 1 + onTriggered: { + if (!control.menu) + return; + + if ((__showMenuFromTouchAndHold || selectionStart !== selectionEnd) + && control.activeFocus + && (!cursorHandle.pressed && !selectionHandle.pressed) + && (!flickable || !flickable.moving) + && (cursorHandle.delegate)) { + var p1 = input.positionToRectangle(input.selectionStart); + var p2 = input.positionToRectangle(input.selectionEnd); + var topLeft = input.mapToItem(input, p1.x, input.height); + var size = Qt.size(p2.x - p1.x + p1.width, p2.y - p1.y + p1.height) + var targetRect = Qt.rect(topLeft.x, topLeft.y, size.width, size.height); + getMenuInstance().__dismissMenu(); + getMenuInstance().__popup(targetRect, -1, MenuPrivate.EditMenu); + } else { + getMenuInstance().__dismissMenu(); + } + } + } +} diff --git a/src/declarativeimports/plasmastyle/TextAreaStyle.qml b/src/declarativeimports/plasmastyle/TextAreaStyle.qml index 114c32208..15a987e95 100644 --- a/src/declarativeimports/plasmastyle/TextAreaStyle.qml +++ b/src/declarativeimports/plasmastyle/TextAreaStyle.qml @@ -67,4 +67,7 @@ QtQuickControlStyle.TextAreaStyle { incrementControl: svs.incrementControl decrementControl: svs.decrementControl + __cursorHandle: CursorHandleStyle {} + __selectionHandle: SelectionHandleStyle {} + __editMenu: EditMenuTouch {} } diff --git a/src/declarativeimports/plasmastyle/TextFieldStyle.qml b/src/declarativeimports/plasmastyle/TextFieldStyle.qml index 635c938f1..d90b1a88d 100644 --- a/src/declarativeimports/plasmastyle/TextFieldStyle.qml +++ b/src/declarativeimports/plasmastyle/TextFieldStyle.qml @@ -65,4 +65,8 @@ QtQuickControlStyle.TextFieldStyle { root.padding.bottom = base.margins.bottom } } + + __cursorHandle: CursorHandleStyle {} + __selectionHandle: SelectionHandleStyle {} + __editMenu: EditMenuTouch {} } From b88f84e703670bf0eb5246d805f81596ab5cde1a Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 16 Jul 2015 12:51:03 +0200 Subject: [PATCH 02/13] reparent the menu to root this makes the menu to be corectly positioned and correct Z it may happen of menus not getting deleted in dynamic cases such as things in pagestacks --- .../plasmastyle/EditMenuTouch.qml | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/declarativeimports/plasmastyle/EditMenuTouch.qml b/src/declarativeimports/plasmastyle/EditMenuTouch.qml index 07afde7d8..4c92ebf1a 100644 --- a/src/declarativeimports/plasmastyle/EditMenuTouch.qml +++ b/src/declarativeimports/plasmastyle/EditMenuTouch.qml @@ -52,19 +52,23 @@ Item { width: childrenRect.width + margins.left + margins.right height: childrenRect.height + margins.top + margins.bottom z: 9999 - function __popup(pos) { - popup.x = pos.x; - popup.y = pos.y; - popup.visible = true; - input.z = 9999 - print("POPUP MENU"+pos.y+" "+popup.x+" "+popup.width+" "+popup.parent) - //popup.y = 0 - //popup.parent = input.parent.parent.parent.parent.parent + Component.onCompleted: { var par = popup.parent while (par) { popup.parent = par par = parent.parent } + } + + function __popup(pos) { + //pos = input.mapToItem(popup, pos.x, pos.y); + popup.x = pos.x; + popup.y = pos.y; + popup.visible = true; + print("POPUP MENU"+pos.y+" "+popup.x+" "+popup.width+" "+popup.parent) + //popup.y = 0 + //popup.parent = input.parent.parent.parent.parent.parent + popup.z = 9999 } function __dismissMenu() { @@ -183,7 +187,7 @@ Item { && (cursorHandle.delegate)) { var p1 = input.positionToRectangle(input.selectionStart); var p2 = input.positionToRectangle(input.selectionEnd); - var topLeft = input.mapToItem(input, p1.x, input.height); + var topLeft = input.mapToItem(null, p1.x, p1.y + units.gridUnit); var size = Qt.size(p2.x - p1.x + p1.width, p2.y - p1.y + p1.height) var targetRect = Qt.rect(topLeft.x, topLeft.y, size.width, size.height); getMenuInstance().__dismissMenu(); From 9e318ed6d9b84647c7d8186cfcee487d42e86c3e Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 16 Jul 2015 13:52:46 +0200 Subject: [PATCH 03/13] use the mobile menu only conditionally --- src/declarativeimports/plasmastyle/EditMenuTouch.qml | 5 ----- src/declarativeimports/plasmastyle/TextAreaStyle.qml | 8 +++++++- src/declarativeimports/plasmastyle/TextFieldStyle.qml | 8 +++++++- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/declarativeimports/plasmastyle/EditMenuTouch.qml b/src/declarativeimports/plasmastyle/EditMenuTouch.qml index 4c92ebf1a..d01eb7eee 100644 --- a/src/declarativeimports/plasmastyle/EditMenuTouch.qml +++ b/src/declarativeimports/plasmastyle/EditMenuTouch.qml @@ -61,14 +61,9 @@ Item { } function __popup(pos) { - //pos = input.mapToItem(popup, pos.x, pos.y); popup.x = pos.x; popup.y = pos.y; popup.visible = true; - print("POPUP MENU"+pos.y+" "+popup.x+" "+popup.width+" "+popup.parent) - //popup.y = 0 - //popup.parent = input.parent.parent.parent.parent.parent - popup.z = 9999 } function __dismissMenu() { diff --git a/src/declarativeimports/plasmastyle/TextAreaStyle.qml b/src/declarativeimports/plasmastyle/TextAreaStyle.qml index 15a987e95..1ee6fd6b3 100644 --- a/src/declarativeimports/plasmastyle/TextAreaStyle.qml +++ b/src/declarativeimports/plasmastyle/TextAreaStyle.qml @@ -20,6 +20,7 @@ import QtQuick 2.1 import QtQuick.Controls.Styles 1.1 as QtQuickControlStyle +import QtQuick.Controls.Private 1.0 as QtQuickControlsPrivate import QtQuick.Controls 1.1 import org.kde.plasma.core 2.0 as PlasmaCore @@ -67,7 +68,12 @@ QtQuickControlStyle.TextAreaStyle { incrementControl: svs.incrementControl decrementControl: svs.decrementControl + Component { + id: editMenuTouch + EditMenuTouch {} + } + __cursorHandle: CursorHandleStyle {} __selectionHandle: SelectionHandleStyle {} - __editMenu: EditMenuTouch {} + __editMenu: QtQuickControlsPrivate.Settings.isMobile ? editMenuTouch : null } diff --git a/src/declarativeimports/plasmastyle/TextFieldStyle.qml b/src/declarativeimports/plasmastyle/TextFieldStyle.qml index d90b1a88d..1f5c9179e 100644 --- a/src/declarativeimports/plasmastyle/TextFieldStyle.qml +++ b/src/declarativeimports/plasmastyle/TextFieldStyle.qml @@ -19,6 +19,7 @@ import QtQuick 2.0 import QtQuick.Controls.Styles 1.1 as QtQuickControlStyle +import QtQuick.Controls.Private 1.0 as QtQuickControlsPrivate import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents @@ -66,7 +67,12 @@ QtQuickControlStyle.TextFieldStyle { } } + Component { + id: editMenuTouch + EditMenuTouch {} + } + __cursorHandle: CursorHandleStyle {} __selectionHandle: SelectionHandleStyle {} - __editMenu: EditMenuTouch {} + __editMenu: QtQuickControlsPrivate.Settings.isMobile ? editMenuTouch : null } From eef99055e629628366b0bcb146c2ec2bd7ffe092 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 16 Jul 2015 15:26:18 +0200 Subject: [PATCH 04/13] rewrite the EditMenu implementation license reasons --- .../plasmastyle/EditMenuTouch.qml | 130 +++++------------- 1 file changed, 34 insertions(+), 96 deletions(-) diff --git a/src/declarativeimports/plasmastyle/EditMenuTouch.qml b/src/declarativeimports/plasmastyle/EditMenuTouch.qml index d01eb7eee..07529859b 100644 --- a/src/declarativeimports/plasmastyle/EditMenuTouch.qml +++ b/src/declarativeimports/plasmastyle/EditMenuTouch.qml @@ -1,38 +1,21 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Quick Controls module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +/* + * Copyright (C) 2015 by Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA. + */ import QtQuick 2.1 import QtQuick.Controls 1.1 @@ -43,7 +26,6 @@ import org.kde.plasma.components 2.0 as PlasmaComponents Item { anchors.fill: parent - property bool __showMenuFromTouchAndHold: false property Component defaultMenu: PlasmaCore.FrameSvgItem { id: popup @@ -60,13 +42,13 @@ Item { } } - function __popup(pos) { + function popup(pos) { popup.x = pos.x; popup.y = pos.y; popup.visible = true; popup.z = 9999 } - function __dismissMenu() { + function dismiss() { popup.visible = false; input.z = 0 } @@ -99,96 +81,52 @@ Item { } } } + Connections { target: mouseArea - function clearFocusFromOtherItems() - { - var selectionItem = TextSingleton.selectionItem; - if (!selectionItem) - return; - var otherPos = selectionItem.cursorPosition; - selectionItem.select(otherPos, otherPos) - } - onClicked: { if (control.menu && getMenuInstance().__popupVisible) { select(input.cursorPosition, input.cursorPosition); } else { input.activate(); - clearFocusFromOtherItems(); } if (input.activeFocus) { var pos = input.positionAt(mouse.x, mouse.y) input.moveHandles(pos, pos) } + popupTimer.restart(); } - onPressAndHold: { var pos = input.positionAt(mouseArea.mouseX, mouseArea.mouseY); input.select(pos, pos); var hasSelection = selectionStart != selectionEnd; selectWord(); + popupTimer.restart(); } - - onReleased: __showMenuFromTouchAndHold = false - onCanceled: __showMenuFromTouchAndHold = false } Connections { - target: cursorHandle ? cursorHandle : null - ignoreUnknownSignals: true - onPressedChanged: menuTimer.start() - } - - Connections { - target: selectionHandle ? selectionHandle : null - ignoreUnknownSignals: true - onPressedChanged: menuTimer.start() - } - - Connections { - target: flickable - ignoreUnknownSignals: true - onMovingChanged: menuTimer.start() - } - - Connections { - id: selectionConnections target: input - ignoreUnknownSignals: true - onSelectionStartChanged: menuTimer.start() - onSelectionEndChanged: menuTimer.start() - onActiveFocusChanged: menuTimer.start() + onSelectionStartChanged: popupTimer.restart() + onSelectionEndChanged: popupTimer.restart() + onActiveFocusChanged: popupTimer.restart() } Timer { - // We use a timer so that we end up with one update when multiple connections fire at the same time. - // Basically we wan't the menu to be open if the user does a press and hold, or if we have a selection. - // The exceptions are if the user is moving selection handles or otherwise touching the screen (e.g flicking). - // What is currently missing are showing a magnifyer to place the cursor, and to reshow the edit menu when - // flicking stops. - id: menuTimer + id: popupTimer interval: 1 onTriggered: { - if (!control.menu) - return; + if (selectionStart !== selectionEnd && control.activeFocus) { + var startRect = input.positionToRectangle(input.selectionStart); + var endRect = input.positionToRectangle(input.selectionEnd); - if ((__showMenuFromTouchAndHold || selectionStart !== selectionEnd) - && control.activeFocus - && (!cursorHandle.pressed && !selectionHandle.pressed) - && (!flickable || !flickable.moving) - && (cursorHandle.delegate)) { - var p1 = input.positionToRectangle(input.selectionStart); - var p2 = input.positionToRectangle(input.selectionEnd); - var topLeft = input.mapToItem(null, p1.x, p1.y + units.gridUnit); - var size = Qt.size(p2.x - p1.x + p1.width, p2.y - p1.y + p1.height) - var targetRect = Qt.rect(topLeft.x, topLeft.y, size.width, size.height); - getMenuInstance().__dismissMenu(); - getMenuInstance().__popup(targetRect, -1, MenuPrivate.EditMenu); + var pos = getMenuInstance().mapFromItem(input, startRect.x, startRect.y + units.gridUnit); + getMenuInstance().dismiss(); + getMenuInstance().popup(pos); } else { - getMenuInstance().__dismissMenu(); + getMenuInstance().dismiss(); } } } From 797c622f7f2a8611afa6ecc4ac7e75ac868c9ecf Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 16 Jul 2015 15:33:34 +0200 Subject: [PATCH 05/13] whitespace-- --- src/declarativeimports/plasmastyle/EditMenuTouch.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarativeimports/plasmastyle/EditMenuTouch.qml b/src/declarativeimports/plasmastyle/EditMenuTouch.qml index 07529859b..d30d6f911 100644 --- a/src/declarativeimports/plasmastyle/EditMenuTouch.qml +++ b/src/declarativeimports/plasmastyle/EditMenuTouch.qml @@ -41,7 +41,7 @@ Item { par = parent.parent } } - + function popup(pos) { popup.x = pos.x; popup.y = pos.y; From 3689d5472f719038b93d187b54a107cc199a0851 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 16 Jul 2015 15:40:16 +0200 Subject: [PATCH 06/13] add missing cursot handles delegates --- .../plasmastyle/CursorHandleStyle.qml | 51 ++++++++++++++++++ .../plasmastyle/SelectionHandleStyle.qml | 52 +++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 src/declarativeimports/plasmastyle/CursorHandleStyle.qml create mode 100644 src/declarativeimports/plasmastyle/SelectionHandleStyle.qml diff --git a/src/declarativeimports/plasmastyle/CursorHandleStyle.qml b/src/declarativeimports/plasmastyle/CursorHandleStyle.qml new file mode 100644 index 000000000..baec252b3 --- /dev/null +++ b/src/declarativeimports/plasmastyle/CursorHandleStyle.qml @@ -0,0 +1,51 @@ +/* +* Copyright (C) 2015 by Marco MArtin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License as +* published by the Free Software Foundation; either version 2, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Library General Public License for more details +* +* You should have received a copy of the GNU Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA. +*/ + +import QtQuick 2.2 +import org.kde.plasma.core 2.0 as PlasmaCore + +Item { + width: units.gridUnit + height: styleData.lineHeight + units.gridUnit + visible: styleData.hasSelection + + Rectangle { + id: handle + width: units.gridUnit + height: width + radius: width + color: theme.highlightColor + anchors.bottom: parent.bottom + } + Rectangle { + width: units.gridUnit/2 + height: width + anchors { + left: handle.left + top: handle.top + } + color: theme.highlightColor + } + Rectangle { + width: units.smallSpacing + height: styleData.lineHeight + units.gridUnit/2 + color: theme.highlightColor + anchors.left: parent.left + } +} diff --git a/src/declarativeimports/plasmastyle/SelectionHandleStyle.qml b/src/declarativeimports/plasmastyle/SelectionHandleStyle.qml new file mode 100644 index 000000000..44def9cdc --- /dev/null +++ b/src/declarativeimports/plasmastyle/SelectionHandleStyle.qml @@ -0,0 +1,52 @@ +/* +* Copyright (C) 2015 by Marco MArtin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License as +* published by the Free Software Foundation; either version 2, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Library General Public License for more details +* +* You should have received a copy of the GNU Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA. +*/ + +import QtQuick 2.2 +import org.kde.plasma.core 2.0 as PlasmaCore + +Item { + width: units.gridUnit + x: -width + height: styleData.lineHeight + units.gridUnit + visible: styleData.hasSelection + + Rectangle { + id: handle + width: units.gridUnit + height: width + radius: width + color: theme.highlightColor + anchors.bottom: parent.bottom + } + Rectangle { + width: units.gridUnit/2 + height: width + anchors { + right: handle.right + top: handle.top + } + color: theme.highlightColor + } + Rectangle { + width: units.smallSpacing + height: styleData.lineHeight + units.gridUnit/2 + color: theme.highlightColor + anchors.right: parent.right + } +} From 03560b5a5baeec346fe9672b8ba12f2a5f103508 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 21 Jul 2015 10:57:56 +0200 Subject: [PATCH 07/13] declare __editMenu this makes the patch not fail also on non patched Qt --- src/declarativeimports/plasmastyle/TextAreaStyle.qml | 2 +- src/declarativeimports/plasmastyle/TextFieldStyle.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/declarativeimports/plasmastyle/TextAreaStyle.qml b/src/declarativeimports/plasmastyle/TextAreaStyle.qml index 1ee6fd6b3..c1fb9f4b2 100644 --- a/src/declarativeimports/plasmastyle/TextAreaStyle.qml +++ b/src/declarativeimports/plasmastyle/TextAreaStyle.qml @@ -75,5 +75,5 @@ QtQuickControlStyle.TextAreaStyle { __cursorHandle: CursorHandleStyle {} __selectionHandle: SelectionHandleStyle {} - __editMenu: QtQuickControlsPrivate.Settings.isMobile ? editMenuTouch : null + property Component __editMenu: QtQuickControlsPrivate.Settings.isMobile ? editMenuTouch : null } diff --git a/src/declarativeimports/plasmastyle/TextFieldStyle.qml b/src/declarativeimports/plasmastyle/TextFieldStyle.qml index 1f5c9179e..9352b7891 100644 --- a/src/declarativeimports/plasmastyle/TextFieldStyle.qml +++ b/src/declarativeimports/plasmastyle/TextFieldStyle.qml @@ -74,5 +74,5 @@ QtQuickControlStyle.TextFieldStyle { __cursorHandle: CursorHandleStyle {} __selectionHandle: SelectionHandleStyle {} - __editMenu: QtQuickControlsPrivate.Settings.isMobile ? editMenuTouch : null + property Component __editMenu: QtQuickControlsPrivate.Settings.isMobile ? editMenuTouch : null } From ee94a3ad3e60a738b4fd73055b8c1e390670178c Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 21 Jul 2015 11:34:01 +0200 Subject: [PATCH 08/13] fix parenting and popping up policy --- .../plasmastyle/EditMenuTouch.qml | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/declarativeimports/plasmastyle/EditMenuTouch.qml b/src/declarativeimports/plasmastyle/EditMenuTouch.qml index d30d6f911..301f8000d 100644 --- a/src/declarativeimports/plasmastyle/EditMenuTouch.qml +++ b/src/declarativeimports/plasmastyle/EditMenuTouch.qml @@ -35,11 +35,11 @@ Item { height: childrenRect.height + margins.top + margins.bottom z: 9999 Component.onCompleted: { - var par = popup.parent - while (par) { - popup.parent = par - par = parent.parent + var par = control + while (par.parent) { + par = par.parent } + popup.parent = par } function popup(pos) { @@ -59,6 +59,7 @@ Item { PlasmaComponents.ToolButton { iconSource: "edit-cut" flat: false + enabled: input.selectedText != "" onClicked: { cut(); select(input.cursorPosition, input.cursorPosition); @@ -66,6 +67,7 @@ Item { } PlasmaComponents.ToolButton { iconSource: "edit-copy" + enabled: input.selectedText != "" flat: false onClicked: { copy(); @@ -74,6 +76,7 @@ Item { } PlasmaComponents.ToolButton { iconSource: "edit-paste" + enabled: input.canPaste flat: false onClicked: { paste(); @@ -99,9 +102,9 @@ Item { popupTimer.restart(); } onPressAndHold: { + input.activate(); var pos = input.positionAt(mouseArea.mouseX, mouseArea.mouseY); input.select(pos, pos); - var hasSelection = selectionStart != selectionEnd; selectWord(); popupTimer.restart(); } @@ -114,15 +117,21 @@ Item { onActiveFocusChanged: popupTimer.restart() } + Connections { + target: flickable + onMovingChanged: popupTimer.restart() + } + Timer { id: popupTimer interval: 1 onTriggered: { - if (selectionStart !== selectionEnd && control.activeFocus) { + if (((input.canPaste && mouseArea.pressed) || selectionStart !== selectionEnd) && control.activeFocus) { var startRect = input.positionToRectangle(input.selectionStart); var endRect = input.positionToRectangle(input.selectionEnd); - var pos = getMenuInstance().mapFromItem(input, startRect.x, startRect.y + units.gridUnit); + var pos = getMenuInstance().parent.mapFromItem(input, startRect.x, startRect.y + units.gridUnit); + getMenuInstance().dismiss(); getMenuInstance().popup(pos); } else { From 669f807fa8fe6a886c566e8d14937d72cb927db5 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 5 Aug 2015 13:52:22 +0200 Subject: [PATCH 09/13] touch friendly text cursor --- .../plasmastyle/CursorDelegate.qml | 66 +++++++++++++++++++ .../plasmastyle/TextAreaStyle.qml | 1 + .../plasmastyle/TextFieldStyle.qml | 1 + 3 files changed, 68 insertions(+) create mode 100644 src/declarativeimports/plasmastyle/CursorDelegate.qml diff --git a/src/declarativeimports/plasmastyle/CursorDelegate.qml b/src/declarativeimports/plasmastyle/CursorDelegate.qml new file mode 100644 index 000000000..3b335a018 --- /dev/null +++ b/src/declarativeimports/plasmastyle/CursorDelegate.qml @@ -0,0 +1,66 @@ +/* +* Copyright (C) 2015 by Marco MArtin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License as +* published by the Free Software Foundation; either version 2, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Library General Public License for more details +* +* You should have received a copy of the GNU Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA. +*/ + +import QtQuick 2.2 +import org.kde.plasma.core 2.0 as PlasmaCore + +Item { + id: root + + property Item input: parent + + width: units.smallSpacing + height: input.cursorRectangle.height + visible: input.activeFocus && input.selectionStart === input.selectionEnd + + + Rectangle { + width: units.smallSpacing + height: parent.height + units.gridUnit + radius: width + color: theme.highlightColor + } + + Rectangle { + id: handle + x: -width/2 + parent.width/2 + width: units.gridUnit + height: width + radius: width + color: theme.highlightColor + anchors.top: parent.bottom + } + MouseArea { + drag { + target: root + minimumX: 0 + minimumY: 0 + maximumX: input.width + maximumY: input.height - root.height + } + width: handle.width * 2 + height: parent.height + handle.height + x: -width/2 + onReleased: { + var pos = mapToItem(input, mouse.x, mouse.y); + input.cursorPosition = input.positionAt(pos.x, pos.y); + } + } +} + diff --git a/src/declarativeimports/plasmastyle/TextAreaStyle.qml b/src/declarativeimports/plasmastyle/TextAreaStyle.qml index c1fb9f4b2..91d54eb26 100644 --- a/src/declarativeimports/plasmastyle/TextAreaStyle.qml +++ b/src/declarativeimports/plasmastyle/TextAreaStyle.qml @@ -74,6 +74,7 @@ QtQuickControlStyle.TextAreaStyle { } __cursorHandle: CursorHandleStyle {} + __cursorDelegate: CursorDelegate{} __selectionHandle: SelectionHandleStyle {} property Component __editMenu: QtQuickControlsPrivate.Settings.isMobile ? editMenuTouch : null } diff --git a/src/declarativeimports/plasmastyle/TextFieldStyle.qml b/src/declarativeimports/plasmastyle/TextFieldStyle.qml index 9352b7891..171abd0b4 100644 --- a/src/declarativeimports/plasmastyle/TextFieldStyle.qml +++ b/src/declarativeimports/plasmastyle/TextFieldStyle.qml @@ -73,6 +73,7 @@ QtQuickControlStyle.TextFieldStyle { } __cursorHandle: CursorHandleStyle {} + __cursorDelegate: CursorDelegate{} __selectionHandle: SelectionHandleStyle {} property Component __editMenu: QtQuickControlsPrivate.Settings.isMobile ? editMenuTouch : null } From ba69d19c633f6427f811ca30af516c51fdae5ec5 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 5 Aug 2015 13:55:26 +0200 Subject: [PATCH 10/13] custom cursor delegate only if mobile --- src/declarativeimports/plasmastyle/TextAreaStyle.qml | 6 +++++- src/declarativeimports/plasmastyle/TextFieldStyle.qml | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/declarativeimports/plasmastyle/TextAreaStyle.qml b/src/declarativeimports/plasmastyle/TextAreaStyle.qml index 91d54eb26..0beb0c002 100644 --- a/src/declarativeimports/plasmastyle/TextAreaStyle.qml +++ b/src/declarativeimports/plasmastyle/TextAreaStyle.qml @@ -72,9 +72,13 @@ QtQuickControlStyle.TextAreaStyle { id: editMenuTouch EditMenuTouch {} } + Component { + id: cursorTouch + CursorDelegate {} + } __cursorHandle: CursorHandleStyle {} - __cursorDelegate: CursorDelegate{} + __cursorDelegate: QtQuickControlsPrivate.Settings.isMobile ? cursorTouch : null __selectionHandle: SelectionHandleStyle {} property Component __editMenu: QtQuickControlsPrivate.Settings.isMobile ? editMenuTouch : null } diff --git a/src/declarativeimports/plasmastyle/TextFieldStyle.qml b/src/declarativeimports/plasmastyle/TextFieldStyle.qml index 171abd0b4..8daaa0b83 100644 --- a/src/declarativeimports/plasmastyle/TextFieldStyle.qml +++ b/src/declarativeimports/plasmastyle/TextFieldStyle.qml @@ -71,9 +71,13 @@ QtQuickControlStyle.TextFieldStyle { id: editMenuTouch EditMenuTouch {} } + Component { + id: cursorTouch + CursorDelegate {} + } __cursorHandle: CursorHandleStyle {} - __cursorDelegate: CursorDelegate{} + __cursorDelegate: QtQuickControlsPrivate.Settings.isMobile ? cursorTouch : null __selectionHandle: SelectionHandleStyle {} property Component __editMenu: QtQuickControlsPrivate.Settings.isMobile ? editMenuTouch : null } From d5b71611e2f8553295f12663813c4116ab43ac92 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 6 Aug 2015 15:25:30 +0200 Subject: [PATCH 11/13] always show the edit menu when the cursor is visible not super nice but needed functionality-wise, since i cannot trigger the menu from CursorDelegate --- src/declarativeimports/plasmastyle/CursorDelegate.qml | 1 + src/declarativeimports/plasmastyle/EditMenuTouch.qml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/declarativeimports/plasmastyle/CursorDelegate.qml b/src/declarativeimports/plasmastyle/CursorDelegate.qml index 3b335a018..8995540bb 100644 --- a/src/declarativeimports/plasmastyle/CursorDelegate.qml +++ b/src/declarativeimports/plasmastyle/CursorDelegate.qml @@ -61,6 +61,7 @@ Item { var pos = mapToItem(input, mouse.x, mouse.y); input.cursorPosition = input.positionAt(pos.x, pos.y); } + onPressAndHold: print("AAAAAA"+control.getMenuInstance()) } } diff --git a/src/declarativeimports/plasmastyle/EditMenuTouch.qml b/src/declarativeimports/plasmastyle/EditMenuTouch.qml index 301f8000d..d3208e870 100644 --- a/src/declarativeimports/plasmastyle/EditMenuTouch.qml +++ b/src/declarativeimports/plasmastyle/EditMenuTouch.qml @@ -126,7 +126,7 @@ Item { id: popupTimer interval: 1 onTriggered: { - if (((input.canPaste && mouseArea.pressed) || selectionStart !== selectionEnd) && control.activeFocus) { + if ((input.canPaste || selectionStart !== selectionEnd) && control.activeFocus) { var startRect = input.positionToRectangle(input.selectionStart); var endRect = input.positionToRectangle(input.selectionEnd); From e688b3d483bb2e8297f695ceab9b07abc09d3d2e Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 2 Sep 2015 10:44:12 +0200 Subject: [PATCH 12/13] remove extra debug output --- src/declarativeimports/plasmastyle/CursorDelegate.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/declarativeimports/plasmastyle/CursorDelegate.qml b/src/declarativeimports/plasmastyle/CursorDelegate.qml index 8995540bb..3b335a018 100644 --- a/src/declarativeimports/plasmastyle/CursorDelegate.qml +++ b/src/declarativeimports/plasmastyle/CursorDelegate.qml @@ -61,7 +61,6 @@ Item { var pos = mapToItem(input, mouse.x, mouse.y); input.cursorPosition = input.positionAt(pos.x, pos.y); } - onPressAndHold: print("AAAAAA"+control.getMenuInstance()) } } From b2bfd6cdf5786976a7ee71ddef48e369b125850e Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 2 Sep 2015 11:43:27 +0200 Subject: [PATCH 13/13] reparent to flickable if possible --- .../plasmastyle/CursorDelegate.qml | 2 +- .../plasmastyle/EditMenuTouch.qml | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/declarativeimports/plasmastyle/CursorDelegate.qml b/src/declarativeimports/plasmastyle/CursorDelegate.qml index 3b335a018..07a817589 100644 --- a/src/declarativeimports/plasmastyle/CursorDelegate.qml +++ b/src/declarativeimports/plasmastyle/CursorDelegate.qml @@ -1,5 +1,5 @@ /* -* Copyright (C) 2015 by Marco MArtin +* Copyright (C) 2015 by Marco Martin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as diff --git a/src/declarativeimports/plasmastyle/EditMenuTouch.qml b/src/declarativeimports/plasmastyle/EditMenuTouch.qml index d3208e870..4c818ffc5 100644 --- a/src/declarativeimports/plasmastyle/EditMenuTouch.qml +++ b/src/declarativeimports/plasmastyle/EditMenuTouch.qml @@ -36,9 +36,12 @@ Item { z: 9999 Component.onCompleted: { var par = control - while (par.parent) { + //heuristic: if a flickable is found in the parents, + //reparent to it, so it scrolls together + while (par.parent && par.parent.contentY === undefined) { par = par.parent } + popup.parent = par } @@ -46,11 +49,9 @@ Item { popup.x = pos.x; popup.y = pos.y; popup.visible = true; - popup.z = 9999 } function dismiss() { popup.visible = false; - input.z = 0 } Row { x: parent.margins.left @@ -59,18 +60,18 @@ Item { PlasmaComponents.ToolButton { iconSource: "edit-cut" flat: false - enabled: input.selectedText != "" + visible: input.selectedText != "" onClicked: { - cut(); + control.cut(); select(input.cursorPosition, input.cursorPosition); } } PlasmaComponents.ToolButton { iconSource: "edit-copy" - enabled: input.selectedText != "" + visible: input.selectedText != "" flat: false onClicked: { - copy(); + control.copy(); select(input.cursorPosition, input.cursorPosition); } } @@ -79,7 +80,7 @@ Item { enabled: input.canPaste flat: false onClicked: { - paste(); + control.paste(); } } }