-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclicks.ts
149 lines (132 loc) · 4.65 KB
/
clicks.ts
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
//% color=#cf64ed
//% icon="\uf0a7"
//% block="Button clicks"
//% groups="['Advanced']"
namespace buttonClicks {
// Button.A = 1, B = 2, AB = 3
const SINGLECLICK = 0
const DOUBLECLICK = 1
const LONGCLICK = 2
const BUTTONDOWN = 3
const BUTTONUP = 4
const singleClickCheckTime = 100 // ms
const longClickTime = 800
const shortClickTime = 500
const doubleClickTime = 300
// Times for buttons
let lastClickEnd = [0, 0]
let lastPressedStart = [0, 0]
let inLongClick = [false, false]
export enum AorB { // Thanks Martin Williams / https://support.microbit.org/support/tickets/55867
A = 0,
B = 1
}
// Array of handlers
let actions : [[Action]] = [
[null, null, null, null, null], // A Handlers
[null, null, null, null, null] // B Handlers
];
// Button is AorB (0-based)
function doActions(button: AorB, kind: number) {
// Optional/Null chaining would be nice...
let handlers = actions.get(button)
if(handlers) {
let action = handlers.get(kind)
if(action) action()
}
}
function button(i: number) { // i is the Button Index (1,2)
let currentTime = control.millis()
let pressed = input.buttonIsPressed(i)
i--; // Adjust to 0-based AorB and array index.
if(pressed) {
doActions(i, BUTTONDOWN)
lastPressedStart[i] = currentTime
// Haven't started a long click yet
inLongClick[i] = false
} else {
// Release
doActions(i, BUTTONUP)
const holdTime = currentTime - lastPressedStart[i]
if (holdTime < shortClickTime) {
if ((lastClickEnd[i] > 0) && (currentTime - lastClickEnd[i] < doubleClickTime)) {
lastClickEnd[i] = 0 // Click ended
doActions(i, DOUBLECLICK)
} else {
// If we're in a long click, end it
if(inLongClick[i] == true) {
inLongClick[i] = false
lastClickEnd[i] = 0
} else {
// Otherwise, note the time for short click checks
lastClickEnd[i] = currentTime
}
}
} else {
// Intermediate clicks are ignored
lastClickEnd[i] = 0
}
}
}
loops.everyInterval(singleClickCheckTime, function() {
let currentTime = control.millis()
// i is index and AorB (0-based)
for(let i=Button.A-1;i<=Button.B-1;i++) {
if ((lastClickEnd[i] > 0) && (currentTime - lastClickEnd[i] > doubleClickTime)) {
lastClickEnd[i] = 0
doActions(i, SINGLECLICK)
}
// Check if we're in a long press
// Button indices are 1-based (i+1).
let pressed = input.buttonIsPressed(i+1)
const holdTime = currentTime - lastPressedStart[i]
if(pressed && (holdTime > longClickTime) ) {
lastClickEnd[i] = 0 // Click ended / not a short click
inLongClick[i] = true
lastPressedStart[i] = currentTime // Prepare for 2nd long click
doActions(i, LONGCLICK)
}
}
})
// Register Handlers
control.onEvent(EventBusSource.MICROBIT_ID_BUTTON_A,
EventBusValue.MICROBIT_BUTTON_EVT_DOWN, () => button(Button.A))
control.onEvent(EventBusSource.MICROBIT_ID_BUTTON_A,
EventBusValue.MICROBIT_BUTTON_EVT_UP, () => button(Button.A))
control.onEvent(EventBusSource.MICROBIT_ID_BUTTON_B,
EventBusValue.MICROBIT_BUTTON_EVT_DOWN, () => button(Button.B))
control.onEvent(EventBusSource.MICROBIT_ID_BUTTON_B,
EventBusValue.MICROBIT_BUTTON_EVT_UP, () => button(Button.B))
//% blockId=onButtonSingleClicked block="on button |%NAME single clicked"
//% weight=100
export function onButtonSingleClicked(button: AorB, body: Action) {
let buttonHandlers = actions.get(button)
buttonHandlers.set(SINGLECLICK, body)
}
//% blockId=onButtonDoubleClicked block="on button |%NAME double clicked "
//% weight=75
export function onButtonDoubleClicked(button: AorB, body: Action) {
let buttonHandlers = actions.get(button)
buttonHandlers.set(DOUBLECLICK, body)
}
//% blockId=onButtonHeld block="on button |%NAME held"
//% weight=50
export function onButtonHeld(button: AorB, body: Action) {
let buttonHandlers = actions.get(button)
buttonHandlers.set(LONGCLICK, body)
}
//% blockId=onButtonDown block="on button |%NAME down "
//% weight=25
//% group="Advanced"
export function onButtonDown(button: AorB, body: Action) {
let buttonHandlers = actions.get(button)
buttonHandlers.set(BUTTONDOWN, body)
}
//% blockId=onButtonUp block="on button |%NAME up "
//% weight=10
//% group="Advanced"
export function onButtonUp(button: AorB, body: Action) {
let buttonHandlers = actions.get(button)
buttonHandlers.set(BUTTONUP, body)
}
}