File: PressArea.qml

package info (click to toggle)
maliit-keyboard 2.3.1-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 40,348 kB
  • sloc: cpp: 9,618; python: 1,548; javascript: 291; xml: 112; makefile: 16; sh: 6
file content (163 lines) | stat: -rw-r--r-- 5,550 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
 * Copyright 2013 Canonical Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 3.
 *
 * 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

import QtQuick 2.4

import MaliitKeyboard 2.0

/*!
  MultiPointTouchArea is similar to the MouseArea
  But to enable multiple PressAreas to be touched at the same time, this is based
  on MultiPointTouchArea
 */
MultiPointTouchArea {
    id: root

    /// Is true while the area is touched, and the finger did not yet lift
    property bool pressed: false
    // Track whether we've swiped out of a key press to dismiss the keyboard
    property bool swipedOut: false
    property bool horizontalSwipe: false
    property bool held: false
    property alias mouseX: point.x
    property alias mouseY: point.y
    // Keep track of the touch start position ourselves instead of using
    // point.startY, as this always reports 0 for mouse interaction 
    // (https://bugreports.qt.io/browse/QTBUG-41692)
    property real startY

    property bool acceptDoubleClick: false
    maximumTouchPoints: 1

    /// Same as MouseArea pressAndHold()
    signal pressAndHold()

    signal doubleClicked()

    /// Cancels the current pressed state of the mouse are
    function cancelPress() {
        pressed = false;
        holdTimer.stop();
    }

    touchPoints: [
        TouchPoint { 
            id: point
            property double lastY
            property double lastYChange

            // Dragging implemented here rather than in higher level
            // mouse area to avoid conflict with swipe selection
            // of extended keys
            onYChanged: {
                if (point.y > root.y + root.height) {
                    if (!swipedOut) {
                        // We've swiped out of the key
                        swipedOut = true;
                        cancelPress();
                    }
                    
                    // Dirty hack, see onReleased below
                    if (point.y > panel.height) {
                        // Touch point released past height of keyboard.
                        return;
                    }

                    var distance = point.y - lastY;
                    // If changing direction wait until movement passes 1 gu
                    // to avoid jitter
                    if ((lastYChange * distance > 0 || Math.abs(distance) > Device.gu(1)) && !held) {
                        keyboardSurface.y += distance;
                        lastY = point.y;
                        lastYChange = distance;
                    }
                    // Hide if we get close to the bottom of the screen.
                    // This works around issues with devices with touch buttons
                    // below the screen preventing release events when swiped
                    // over
                    if(point.sceneY > fullScreenItem.height - Device.gu(4) && point.y > startY + Device.gu(8) && !held) {
                        Keyboard.hide();
                    }
                } else {
                    lastY = point.y;
                }
            }
        }
    ]

    Timer {
        id: holdTimer
        interval: 300
        onTriggered: {
            if (root.pressed) {
                root.pressAndHold();
                held = true;
            }
        }
    }

    Timer {
        id: doubleClickTimer
        interval: 400 // Default Qt double click interval
    }

    onPressed: {
        pressed = true;
        held = false;
        swipedOut = false;
        startY = point.y;
        holdTimer.restart();

        // We keep a global view of whether any other keys have been
        // pressed in between the first tap on this key and the second
        // one, so that quickly tapping one key, then tapping another,
        // then tapping the first again doesn't trigger a double click.

        if (doubleClickTimer.running) {
            if (panel.lastKeyPressed == root) {
                doubleClicked();
            }
        } else {
            if (acceptDoubleClick) {
                doubleClickTimer.restart();
            }
            panel.lastKeyPressed = root
        }
    }

    onReleased: {
        // Don't evaluate if the release point is above the start point
        // or further away from its start than the height of the whole keyboard.
        // This works around touches sometimes being recognized as ending below
        // the bottom of the screen.
        if (point.y > panel.height) {
            console.warn("Touch point released past height of keyboard. Ignoring.");
        } else if (!(point.y <= startY)) {
            // Handles swiping away the keyboard
            // Hide if the end point is more than 8 grid units from the start
            if (!held && point.y > startY + Device.gu(8)) {
                Keyboard.hide();
            } else {
                bounceBackAnimation.from = keyboardSurface.y;
                bounceBackAnimation.start();
            }
        }

        pressed = false;
        held = false;
        holdTimer.stop();
    }
}