Warning, /plasma/qqc2-breeze-style/style/impl/CursorHandle.qml is written in an unsupported language. File is not indexed.

0001 /* SPDX-FileCopyrightText: 2018 Marco Martin <mart@kde.org>
0002  * SPDX-FileCopyrightText: 2021 Noah Davis <noahadvs@gmail.com>
0003  * SPDX-License-Identifier: LGPL-2.0-or-later
0004  */
0005 
0006 import QtQuick
0007 import QtQuick.Window
0008 import QtQuick.Templates
0009 import org.kde.kirigami as Kirigami
0010 
0011 import "." as Impl
0012 
0013 Loader {
0014     id: root
0015     property Item target
0016     property bool isSelectionEnd: false
0017     visible: Kirigami.Settings.tabletMode && target.selectByMouse && target.activeFocus && (isSelectionEnd ? target.selectionStart !== target.selectionEnd : true)
0018     active: visible
0019     sourceComponent: Kirigami.ShadowedRectangle {
0020         id: handle
0021         property real selectionStartX: Math.floor(Qt.inputMethod.anchorRectangle.x + (Qt.inputMethod.cursorRectangle.width - width)/2)
0022         property real selectionStartY: Math.floor(Qt.inputMethod.anchorRectangle.y + Qt.inputMethod.cursorRectangle.height + pointyBitVerticalOffset)
0023         property real selectionEndX: Math.floor(Qt.inputMethod.cursorRectangle.x + (Qt.inputMethod.cursorRectangle.width - width)/2)
0024         property real selectionEndY: Math.floor(Qt.inputMethod.cursorRectangle.y + Qt.inputMethod.cursorRectangle.height + pointyBitVerticalOffset)
0025         property real pointyBitVerticalOffset: Math.abs(pointyBit.y*2)
0026         parent: Overlay.overlay
0027         x: isSelectionEnd ? selectionEndX : selectionStartX
0028         y: isSelectionEnd ? selectionEndY : selectionStartY
0029 
0030         // HACK: make it appear above most popups that show up in the
0031         // overlay in case any of them use TextField or TextArea
0032         z: 999
0033 
0034         //opacity: target.activeFocus ? 1 : 0
0035         implicitHeight: {
0036             let h = Kirigami.Units.gridUnit
0037             return h - (h % 2 == 0 ? 1 : 0)
0038         }
0039         implicitWidth: implicitHeight
0040         radius: width/2
0041 
0042         color: target.selectionColor
0043 
0044         shadow {
0045             color: Qt.rgba(0,0,0,0.2)
0046             size: 3
0047             yOffset: 1
0048         }
0049 
0050         Rectangle {
0051             id: pointyBit
0052             x: (parent.width - width)/2
0053             y: -height/4 + 0.2 // magic number to get it to line up with the edge of the circle
0054             implicitHeight: parent.implicitHeight/2
0055             implicitWidth: implicitHeight
0056             antialiasing: true
0057             rotation: 45
0058             color: parent.color
0059         }
0060 
0061         Kirigami.ShadowedRectangle {
0062             id: inner
0063             visible: target.selectionStart !== target.selectionEnd && (handle.y < selectionStartY || handle.y < selectionEndY)
0064             anchors.fill: parent
0065             anchors.margins: Impl.Units.smallBorder
0066             color: target.selectedTextColor
0067             radius: height/2
0068             Rectangle {
0069                 id: innerPointyBit
0070                 x: (parent.width - width)/2
0071                 y: -height/4 + 0.8 // magic number to get it to line up with the edge of the circle
0072                 implicitHeight: pointyBit.implicitHeight
0073                 implicitWidth: implicitHeight
0074                 antialiasing: true
0075                 rotation: 45
0076                 color: parent.color
0077             }
0078         }
0079 
0080         MouseArea {
0081             enabled: handle.visible
0082             anchors.fill: parent
0083     //         preventStealing: true
0084             onPositionChanged: {
0085                 let pos = mapToItem(root.target, mouse.x, mouse.y);
0086                 pos = root.target.positionAt(pos.x, pos.y - handle.height - handle.pointyBitVerticalOffset);
0087 
0088                 if (target.selectionStart !== target.selectionEnd) {
0089                     if (!isSelectionEnd) {
0090                         root.target.select(Math.min(pos, root.target.selectionEnd - 1), root.target.selectionEnd);
0091                     } else {
0092                         root.target.select(root.target.selectionStart, Math.max(pos, root.target.selectionStart + 1));
0093                     }
0094                 } else {
0095                     root.target.cursorPosition = pos;
0096                 }
0097             }
0098         }
0099 
0100         // NumberAnimations/SmoothedAnimations appear smoother than X/Y Animators for some reason.
0101         // The animations feel a bit janky when moving handles while text is selected.
0102         /*Behavior on x {
0103             enabled: enableXYAnimations && target.selectionStart === target.selectionEnd
0104             SmoothedAnimation {
0105                 velocity: 200
0106                 reversingMode: SmoothedAnimation.Immediate
0107                 duration: Kirigami.Units.shortDuration
0108             }
0109         }
0110         Behavior on y {
0111             enabled: enableXYAnimations && target.selectionStart === target.selectionEnd
0112             SmoothedAnimation {
0113                 velocity: 200
0114                 reversingMode: SmoothedAnimation.Immediate
0115                 duration: Kirigami.Units.shortDuration
0116             }
0117         }
0118 
0119         //HACK
0120         property bool enableXYAnimations: false
0121         Timer {
0122             id: animationHackTimer
0123             running: true
0124             interval: 1
0125             onTriggered: handle.enableXYAnimations = true
0126         }
0127         */
0128     }
0129 }