loupedeck-commander 1.4.1 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,381 +1,393 @@
1
- import {discover, HAPTIC,LoupedeckDevice } from 'loupedeck'
2
- import { ApplicationConfig } from './ApplicationConfig.mjs'
3
- import { ButtonField } from './ButtonField.mjs'
4
-
5
- import { InitializeInterfaces, StopInterfaces, opcuainterface, profileEmitter } from '../interfaces/interfaces.mjs'
6
-
7
- export class BaseLoupeDeckHandler {
8
- device = undefined
9
- appConfig = undefined
10
- profileConfigs = []
11
- currentProfile = 0
12
- brightness = 1
13
- screens = {}
14
- buttons = {}
15
- knobs = {}
16
- screenUpdate = {}
17
- stopping = false
18
- IntervalID = undefined
19
-
20
- constructor (config) {
21
- console.log(`INIT with config ${config}`)
22
- let result = this.loadConfig(config)
23
- if (!result){
24
- process.exit(-1)
25
- }
26
- }
27
-
28
- /**
29
- * event handler - start
30
- */
31
- async start () {
32
- console.info('Start')
33
- while (!this.device && !this.stopping) {
34
- try {
35
- var list = await LoupedeckDevice.list()
36
- if (list.length>0){
37
- var element = list[0]
38
- console.log("Connecting to device")
39
- console.log("Path: ", element.path)
40
- console.log("vendorId: ", element.vendorId, element.productId)
41
- console.log("serialNumber: ", element.serialNumber)
42
- }
43
-
44
- this.device = await discover()
45
-
46
-
47
-
48
- } catch (e) {
49
- console.error(`${e}. Reattempting in 3 seconds...`)
50
- await new Promise(resolve => setTimeout(resolve, 3000))
51
- }
52
-
53
- if (this.stopping){
54
- return
55
- }
56
- }
57
- console.info(`✅ Discovered Device ${this.device.type}`)
58
-
59
- const self = this
60
-
61
- this.device.on('connect', (address) => { self.onConnected(address) })
62
- this.device.on('down', (event) => { self.onButtonDown(event) })
63
- this.device.on('up', (event) => { self.onButtonUp(event) })
64
- this.device.on('rotate', (event) => { self.onRotate(event) })
65
- this.device.on('touchstart', (event) => { self.onTouchStart(event) })
66
- this.device.on('touchmove', (event) => { self.onTouchMove(event) })
67
- this.device.on('touchend', (event) => { self.onTouchEnd(event) })
68
- this.device.on('disconnect', (event) => { self.disconnectDevice(event) })
69
-
70
- console.info(`✅ Registered callbacks`)
71
- }
72
-
73
- /**
74
- * event handler - loupedeck device disconnected
75
- */
76
- async disconnectDevice (event) {
77
- console.info("Device Disconnected")
78
- this.device=undefined
79
- }
80
-
81
- /**
82
- * stop handler - close the dipslay-connection and also stop all interface handlers
83
- */
84
- async stop () {
85
- console.info('Stopping Handler')
86
-
87
- try {
88
- console.info(`Closing Device`)
89
- this.stopping = true
90
-
91
- clearInterval(this.IntervalID)
92
-
93
- /* if (this.device){
94
- this.device.vibrate(HAPTIC.DESCEND_MED)
95
- await new Promise(resolve => setTimeout(resolve, 250))
96
- }
97
- */
98
- this.changeBrightness(0)
99
- await new Promise(resolve => setTimeout(resolve, 250))
100
- if (this.device){
101
- this.device.reconnectInterval = 0
102
- await this.device.close()
103
- await new Promise(resolve => setTimeout(resolve, 2000))
104
- console.info(`Device Closed`)
105
- }
106
- console.info(`Stopping interfaces`)
107
- await StopInterfaces()
108
- await new Promise(resolve => setTimeout(resolve, 1000))
109
-
110
- } catch (e) {
111
- console.info(`e`,e)
112
-
113
- }
114
-
115
- process.exit()
116
-
117
- }
118
-
119
- /**
120
- * load Application config file from JSON
121
- * @param filename
122
- */
123
- loadConfig (fileName) {
124
- console.info(`Loading Config File ${fileName}`)
125
- this.appConfig = new ApplicationConfig()
126
- return this.appConfig.loadFromFile(fileName)
127
- }
128
-
129
- vibrate (pattern) {
130
- console.info(`Vibrate with pattern ${pattern}`)
131
- if (this.device) {
132
- this.device.vibrate(pattern)
133
- } else {
134
- console.warn("No Device connected, cannot vibrate")
135
- }
136
- }
137
-
138
- changeBrightness (brightness) {
139
- console.info(`Change Brightness to ${brightness}`)
140
- this.brightness = brightness
141
- if (this.device) {
142
- this.device.setBrightness(brightness)
143
- } else {
144
- console.warn("No Device connected, cannot change brightness")
145
- }
146
- }
147
-
148
- /**
149
- * activate the profile with the givven ID
150
- */
151
- async activateProfile (id) {
152
- // todo Profile-change implementation
153
- id = Number(id)
154
- var oldProfile = this.currentProfile
155
- if (this.appConfig.profiles.length > id) {
156
- this.currentProfile = id
157
- }else{
158
- return
159
- }
160
- const profile = this.getCurrentProfile()
161
- console.info("ACTIVATE PROFILE",id,profile.name)
162
- const dLeft = this.device.displays.left
163
- const dRight = this.device.displays.right
164
- const dCenter = this.device.displays.center
165
-
166
- this.screens.center = undefined
167
- this.screens.left = undefined
168
- this.screens.right = undefined
169
- this.buttons = undefined
170
- this.knobs = undefined
171
-
172
-
173
- this.screens.center = new ButtonField('center', this.device.rows, this.device.columns, dCenter.width, dCenter.height, profile.touch.center,profile)
174
- this.screens.left = new ButtonField('left', 1, 1, dLeft.width, dLeft.height, profile.touch.left,profile)
175
- this.screens.right = new ButtonField('right', 1, 1, dRight.width, dRight.height, profile.touch.right,profile)
176
-
177
- // knobs are only available in the CT-version:
178
- if (this.device.knobs) {
179
- this.knobs = new ButtonField('knob', 1, 1, 0, 0, profile.knobs,profile)
180
- }
181
- if (this.device.buttons) {
182
- this.buttons = new ButtonField('buttons', 1, 1, 0, 0, profile.buttons,profile)
183
- }
184
- await this.screens.center.load()
185
- await this.screens.right.load()
186
- await this.screens.left.load()
187
- await this.buttons.load()
188
- await this.knobs.load()
189
-
190
- // Force a screen Update on all screens:
191
- this.screenUpdate["center"] = true
192
- this.screenUpdate["left"] = true
193
- this.screenUpdate["right"] = true
194
- //await this.updateScreens()
195
-
196
- await this.buttons.draw(this.device)
197
- // Initialize the Interfaces
198
- await InitializeInterfaces(profile)
199
-
200
- }
201
-
202
- /**
203
- * get the dictionary iwth the current profile settings
204
- */
205
- getCurrentProfile () {
206
- return this.appConfig.profiles[this.currentProfile]
207
- }
208
-
209
- /**
210
- * Triggered, when LoupeDeck Device is connected
211
- * - Initialize the profile from config-file and
212
- * - start the interface handlers accordingly
213
- */
214
- async onConnected (address) {
215
- console.info(`✅ Connected to ${this.device.type}, ${address}`)
216
-
217
- await this.activateProfile(0)
218
-
219
- const self = this
220
-
221
- // Register callback on monitored item change:
222
- opcuainterface.on("monitored item changed",(buttonID,attribute,nodeid,val) => { self.buttonStateChanged(buttonID,attribute,nodeid,val) })
223
- profileEmitter.on("profileChanged",(profileID) => { self.activateProfile(profileID) })
224
- profileEmitter.on("brightnessChanged",(brightness) => { self.changeBrightness(brightness) })
225
- profileEmitter.on("vibrate",(pattern) => { self.vibrate(pattern) })
226
-
227
-
228
-
229
- this.changeBrightness(1)
230
- this.vibrate(HAPTIC.ASCEND_MED)
231
-
232
- // Fore update of all screens
233
- console.info('✅ Force Screen update')
234
- this.screenUpdate["center"] = true
235
- this.screenUpdate["left"] = true
236
- this.screenUpdate["right"] = true
237
- //await this.updateScreens()
238
-
239
- this.IntervalID = setInterval(() => {
240
- // runs every 500ms seconds
241
- this.screenUpdate["center"] = true
242
- self.updateScreens()
243
- }, 500);
244
-
245
-
246
- console.info('✅ Done initializing')
247
- }
248
-
249
- /**
250
- * Fore an update of all screens
251
- */
252
- async updateScreens () {
253
- const keys = Object.keys(this.screenUpdate)
254
- for (let i = 0; i < keys.length; i++) {
255
- const screen = keys[i]
256
- //ok = await this.screens.center.updateAllButtons()
257
- await this.screens[screen].draw(this.device)
258
- }
259
- this.screenUpdate = {}
260
- }
261
-
262
- /**
263
- * Button Down Handler - triggered through Event Button Down - connected to LoupeDeck Event
264
- */
265
- async onButtonDown (event) {
266
- let ok = false
267
- const id = event.id
268
- if (Number.isInteger(id)){
269
- ok = await this.buttons.pressed(id)
270
- //await this.buttons.draw(this.device)
271
- }else{
272
- ok = await this.knobs.pressed(id)
273
- }
274
- return ok
275
- }
276
-
277
- /**
278
- * Button Up Handler - triggered through Event Button Up - connected to LoupeDeck Event
279
- */
280
- async onButtonUp (event) {
281
- let ok = false
282
- const id = event.id
283
- if (Number.isInteger(id) && this.buttons){
284
- ok = await this.buttons.released(id)
285
- //await this.buttons.draw(this.device)
286
- }else{
287
- if(this.knobs)
288
- ok = await this.knobs.released(id)
289
- }
290
- return ok
291
- }
292
-
293
- /**
294
- * Button Rotate Handler - triggered through Event Rotate available with knob-Buttons - connected to LoupeDeck Event
295
- */
296
- async onRotate (event) {
297
- const id = event.id
298
- const delta = event.delta
299
- if (this.knobs)
300
- return await this.knobs.rotated(id, delta)
301
- }
302
-
303
- /**
304
- * TouchStart Handler - triggered through Event touch available on all touchbuttons on the loupedeck display - connected to LoupeDeck Event
305
- */
306
- async onTouchStart (event) {
307
- let ok = false
308
- const changedTouches = event.changedTouches
309
- for (let i = 0; i < changedTouches.length; i++) {
310
- const screen = changedTouches[i].target.screen
311
- let id = changedTouches[i].target.key
312
- this.screenUpdate[screen] = true
313
- if (id === undefined) {
314
- id = 0
315
- }
316
- if (this.screens[screen])
317
- ok = await this.screens[screen].pressed(id)
318
- }
319
- //await this.updateScreens()
320
- return ok
321
- }
322
-
323
- /**
324
- * TouchMove Handler - triggered through Event touch available on all touchbuttons on the loupedeck display - connected to LoupeDeck Event
325
- */
326
- async onTouchMove (event) {
327
- let ok = false
328
- const changedTouches = event.changedTouches
329
- for (let i = 0; i < changedTouches.length; i++) {
330
- const x = changedTouches[i].x
331
- const y = changedTouches[i].y
332
- const screen = changedTouches[i].target.screen
333
- let id = changedTouches[i].target.key
334
- if (id === undefined) {
335
- id = 0 // for left/right
336
- }
337
- if (this.screens[screen])
338
- ok = await this.screens[screen].touchmove(id, x, y)
339
- }
340
- return ok
341
- }
342
-
343
- /**
344
- * TouchEnd Handler - triggered through Event touch available on all touchbuttons on the loupedeck display - connected to LoupeDeck Event
345
- */
346
- async onTouchEnd (event) {
347
- let ok = false
348
- const changedTouches = event.changedTouches
349
- for (let i = 0; i < changedTouches.length; i++) {
350
- const elem = changedTouches[i].target
351
- let id = changedTouches[i].target.key
352
- if (id === undefined) {
353
- id = 0
354
- }
355
- this.screenUpdate[elem.screen] = true
356
-
357
- if (this.screens[elem.screen])
358
- ok = await this.screens[elem.screen].released(id)
359
- }
360
- //await this.updateScreens()
361
- return ok
362
- }
363
-
364
- /**
365
- * Handler for StateChanged through OPC/UA Interface - only connected with touch-buttons on center field (yet)
366
- */
367
- async buttonStateChanged(buttonID,attribute,nodeid,val) {
368
- let ok = false
369
- this.screenUpdate["center"] = true
370
- this.screenUpdate["left"] = true
371
- this.screenUpdate["right"] = true
372
-
373
- ok = await this.screens.center.buttonStateChanged(buttonID,attribute,nodeid,val)
374
- ok = await this.knobs.buttonStateChanged(buttonID,attribute,nodeid,val)
375
-
376
- //await this.updateScreens()
377
- return ok
378
- }
379
-
380
-
381
- }
1
+ import {discover, HAPTIC,LoupedeckDevice } from 'loupedeck'
2
+ import { ApplicationConfig } from './ApplicationConfig.mjs'
3
+ import { ButtonField } from './ButtonField.mjs'
4
+
5
+ import { InitializeInterfaces, StopInterfaces, opcuainterface, profileEmitter } from '../interfaces/interfaces.mjs'
6
+
7
+ export class BaseLoupeDeckHandler {
8
+ device = undefined
9
+ appConfig = undefined
10
+ profileConfigs = []
11
+ currentProfile = 0
12
+ brightness = 1
13
+ screens = {}
14
+ buttons = {}
15
+ knobs = {}
16
+ screenUpdate = {}
17
+ stopping = false
18
+ IntervalID = undefined
19
+
20
+ constructor (config) {
21
+ console.log(`INIT with config ${config}`)
22
+ let result = this.loadConfig(config)
23
+ if (!result){
24
+ process.exit(-1)
25
+ }
26
+ }
27
+
28
+ /**
29
+ * event handler - start
30
+ */
31
+ async start () {
32
+ console.info('Start')
33
+ while (!this.device && !this.stopping) {
34
+ try {
35
+ var list = await LoupedeckDevice.list()
36
+ if (list.length>0){
37
+ var element = list[0]
38
+ console.log("Connecting to device")
39
+ console.log("Path: ", element.path)
40
+ console.log("vendorId: ", element.vendorId, element.productId)
41
+ console.log("serialNumber: ", element.serialNumber)
42
+ }
43
+
44
+ this.device = await discover()
45
+
46
+
47
+
48
+ } catch (e) {
49
+ console.error(`${e}. Reattempting in 3 seconds...`)
50
+ await new Promise(resolve => setTimeout(resolve, 3000))
51
+ }
52
+
53
+ if (this.stopping){
54
+ return
55
+ }
56
+ }
57
+ console.info(`✅ Discovered Device ${this.device.type}`)
58
+
59
+ const self = this
60
+
61
+ this.device.on('connect', (address) => { self.onConnected(address) })
62
+ this.device.on('down', (event) => { self.onButtonDown(event) })
63
+ this.device.on('up', (event) => { self.onButtonUp(event) })
64
+ this.device.on('rotate', (event) => { self.onRotate(event) })
65
+ this.device.on('touchstart', (event) => { self.onTouchStart(event) })
66
+ this.device.on('touchmove', (event) => { self.onTouchMove(event) })
67
+ this.device.on('touchend', (event) => { self.onTouchEnd(event) })
68
+ this.device.on('disconnect', (event) => { self.disconnectDevice(event) })
69
+
70
+ console.info(`✅ Registered callbacks`)
71
+ }
72
+
73
+ /**
74
+ * event handler - loupedeck device disconnected
75
+ */
76
+ async disconnectDevice (event) {
77
+ console.info("Device Disconnected")
78
+ this.device=undefined
79
+ }
80
+
81
+ /**
82
+ * stop handler - close the dipslay-connection and also stop all interface handlers
83
+ */
84
+ async stop () {
85
+ console.info('Stopping Handler')
86
+
87
+ try {
88
+ console.info(`Closing Device`)
89
+ this.stopping = true
90
+
91
+ clearInterval(this.IntervalID)
92
+
93
+ /* if (this.device){
94
+ this.device.vibrate(HAPTIC.DESCEND_MED)
95
+ await new Promise(resolve => setTimeout(resolve, 250))
96
+ }
97
+ */
98
+ this.changeBrightness(0)
99
+ await new Promise(resolve => setTimeout(resolve, 250))
100
+ if (this.device){
101
+ this.device.reconnectInterval = 0
102
+ await this.device.close()
103
+ await new Promise(resolve => setTimeout(resolve, 2000))
104
+ console.info(`Device Closed`)
105
+ }
106
+ console.info(`Stopping interfaces`)
107
+ await StopInterfaces()
108
+ await new Promise(resolve => setTimeout(resolve, 1000))
109
+
110
+ } catch (e) {
111
+ console.info(`e`,e)
112
+
113
+ }
114
+
115
+ process.exit()
116
+
117
+ }
118
+
119
+ /**
120
+ * load Application config file from JSON
121
+ * @param filename
122
+ */
123
+ loadConfig (fileName) {
124
+ console.info(`Loading Config File ${fileName}`)
125
+ this.appConfig = new ApplicationConfig()
126
+ return this.appConfig.loadFromFile(fileName)
127
+ }
128
+
129
+ vibrate (pattern) {
130
+ console.info(`Vibrate with pattern ${pattern}`)
131
+ if (this.device) {
132
+ this.device.vibrate(pattern)
133
+ } else {
134
+ console.warn("No Device connected, cannot vibrate")
135
+ }
136
+ }
137
+
138
+ changeBrightness (brightness) {
139
+ console.info(`Change Brightness to ${brightness}`)
140
+ this.brightness = brightness
141
+ if (this.device) {
142
+ this.device.setBrightness(brightness)
143
+ } else {
144
+ console.warn("No Device connected, cannot change brightness")
145
+ }
146
+ }
147
+
148
+ /**
149
+ * activate the profile with the givven ID
150
+ */
151
+ async activateProfile (id) {
152
+ // todo Profile-change implementation
153
+ id = Number(id)
154
+ var oldProfile = this.currentProfile
155
+ if (this.appConfig.profiles.length > id) {
156
+ this.currentProfile = id
157
+ }else{
158
+ return
159
+ }
160
+ const profile = this.getCurrentProfile()
161
+ console.info("ACTIVATE PROFILE",id,profile.name)
162
+ const dLeft = this.device.displays.left
163
+ const dRight = this.device.displays.right
164
+ const dCenter = this.device.displays.center
165
+
166
+ this.screens.center = undefined
167
+ this.screens.left = undefined
168
+ this.screens.right = undefined
169
+ this.buttons = undefined
170
+ this.knobs = undefined
171
+
172
+ if (dCenter){
173
+ this.screens.center = new ButtonField('center', this.device.rows, this.device.columns, dCenter.width, dCenter.height, profile.touch.center,profile)
174
+ await this.screens.center.load()
175
+ this.screenUpdate["center"] = true
176
+ }
177
+
178
+ if (dLeft){
179
+ this.screens.left = new ButtonField('left', 1, 1, dLeft.width, dLeft.height, profile.touch.left,profile)
180
+ await this.screens.left.load()
181
+ this.screenUpdate["left"] = true
182
+ }
183
+
184
+ if (dRight){
185
+ this.screens.right = new ButtonField('right', 1, 1, dRight.width, dRight.height, profile.touch.right,profile)
186
+ await this.screens.right.load()
187
+ this.screenUpdate["right"] = true
188
+ }
189
+
190
+ // knobs are only available in the CT-version:
191
+ if (this.device.knobs) {
192
+ this.knobs = new ButtonField('knob', 1, 1, 0, 0, profile.knobs,profile)
193
+ await this.knobs.load()
194
+ }
195
+ if (this.device.buttons) {
196
+ this.buttons = new ButtonField('buttons', 1, 1, 0, 0, profile.buttons,profile)
197
+ await this.buttons.load()
198
+ }
199
+
200
+ //await this.updateScreens()
201
+
202
+ await this.buttons.draw(this.device)
203
+ // Initialize the Interfaces
204
+ await InitializeInterfaces(profile)
205
+
206
+ }
207
+
208
+ /**
209
+ * get the dictionary iwth the current profile settings
210
+ */
211
+ getCurrentProfile () {
212
+ return this.appConfig.profiles[this.currentProfile]
213
+ }
214
+
215
+ /**
216
+ * Triggered, when LoupeDeck Device is connected
217
+ * - Initialize the profile from config-file and
218
+ * - start the interface handlers accordingly
219
+ */
220
+ async onConnected (address) {
221
+ console.info(`✅ Connected to ${this.device.type}, ${address}`)
222
+
223
+ await this.activateProfile(0)
224
+
225
+ const self = this
226
+
227
+ // Register callback on monitored item change:
228
+ opcuainterface.on("monitored item changed",(buttonID,attribute,nodeid,val) => { self.buttonStateChanged(buttonID,attribute,nodeid,val) })
229
+ profileEmitter.on("profileChanged",(profileID) => { self.activateProfile(profileID) })
230
+ profileEmitter.on("brightnessChanged",(brightness) => { self.changeBrightness(brightness) })
231
+ profileEmitter.on("vibrate",(pattern) => { self.vibrate(pattern) })
232
+
233
+
234
+
235
+ this.changeBrightness(1)
236
+ this.vibrate(HAPTIC.ASCEND_MED)
237
+
238
+ // Fore update of all screens
239
+ console.info('✅ Force Screen update')
240
+
241
+ if (this.device.displays.center)
242
+ this.screenUpdate["center"] = true
243
+ if (this.device.displays.left)
244
+ this.screenUpdate["left"] = true
245
+ if (this.device.displays.right)
246
+ this.screenUpdate["right"] = true
247
+ //await this.updateScreens()
248
+
249
+ this.IntervalID = setInterval(() => {
250
+ // runs every 500ms seconds
251
+ if (this.device.displays.center)
252
+ this.screenUpdate["center"] = true
253
+ self.updateScreens()
254
+ }, 500);
255
+
256
+
257
+ console.info('✅ Done initializing')
258
+ }
259
+
260
+ /**
261
+ * Fore an update of all screens
262
+ */
263
+ async updateScreens () {
264
+ const keys = Object.keys(this.screenUpdate)
265
+ for (let i = 0; i < keys.length; i++) {
266
+ const screen = keys[i]
267
+ //ok = await this.screens.center.updateAllButtons()
268
+ if (this.screens[screen])
269
+ await this.screens[screen].draw(this.device)
270
+ }
271
+ this.screenUpdate = {}
272
+ }
273
+
274
+ /**
275
+ * Button Down Handler - triggered through Event Button Down - connected to LoupeDeck Event
276
+ */
277
+ async onButtonDown (event) {
278
+ let ok = false
279
+ const id = event.id
280
+ if (Number.isInteger(id)){
281
+ ok = await this.buttons.pressed(id)
282
+ //await this.buttons.draw(this.device)
283
+ }else{
284
+ ok = await this.knobs.pressed(id)
285
+ }
286
+ return ok
287
+ }
288
+
289
+ /**
290
+ * Button Up Handler - triggered through Event Button Up - connected to LoupeDeck Event
291
+ */
292
+ async onButtonUp (event) {
293
+ let ok = false
294
+ const id = event.id
295
+ if (Number.isInteger(id) && this.buttons){
296
+ ok = await this.buttons.released(id)
297
+ //await this.buttons.draw(this.device)
298
+ }else{
299
+ if(this.knobs)
300
+ ok = await this.knobs.released(id)
301
+ }
302
+ return ok
303
+ }
304
+
305
+ /**
306
+ * Button Rotate Handler - triggered through Event Rotate available with knob-Buttons - connected to LoupeDeck Event
307
+ */
308
+ async onRotate (event) {
309
+ const id = event.id
310
+ const delta = event.delta
311
+ if (this.knobs)
312
+ return await this.knobs.rotated(id, delta)
313
+ }
314
+
315
+ /**
316
+ * TouchStart Handler - triggered through Event touch available on all touchbuttons on the loupedeck display - connected to LoupeDeck Event
317
+ */
318
+ async onTouchStart (event) {
319
+ let ok = false
320
+ const changedTouches = event.changedTouches
321
+ for (let i = 0; i < changedTouches.length; i++) {
322
+ const screen = changedTouches[i].target.screen
323
+ let id = changedTouches[i].target.key
324
+ this.screenUpdate[screen] = true
325
+ if (id === undefined) {
326
+ id = 0
327
+ }
328
+ if (this.screens[screen])
329
+ ok = await this.screens[screen].pressed(id)
330
+ }
331
+ //await this.updateScreens()
332
+ return ok
333
+ }
334
+
335
+ /**
336
+ * TouchMove Handler - triggered through Event touch available on all touchbuttons on the loupedeck display - connected to LoupeDeck Event
337
+ */
338
+ async onTouchMove (event) {
339
+ let ok = false
340
+ const changedTouches = event.changedTouches
341
+ for (let i = 0; i < changedTouches.length; i++) {
342
+ const x = changedTouches[i].x
343
+ const y = changedTouches[i].y
344
+ const screen = changedTouches[i].target.screen
345
+ let id = changedTouches[i].target.key
346
+ if (id === undefined) {
347
+ id = 0 // for left/right
348
+ }
349
+ if (this.screens[screen])
350
+ ok = await this.screens[screen].touchmove(id, x, y)
351
+ }
352
+ return ok
353
+ }
354
+
355
+ /**
356
+ * TouchEnd Handler - triggered through Event touch available on all touchbuttons on the loupedeck display - connected to LoupeDeck Event
357
+ */
358
+ async onTouchEnd (event) {
359
+ let ok = false
360
+ const changedTouches = event.changedTouches
361
+ for (let i = 0; i < changedTouches.length; i++) {
362
+ const elem = changedTouches[i].target
363
+ let id = changedTouches[i].target.key
364
+ if (id === undefined) {
365
+ id = 0
366
+ }
367
+ this.screenUpdate[elem.screen] = true
368
+
369
+ if (this.screens[elem.screen])
370
+ ok = await this.screens[elem.screen].released(id)
371
+ }
372
+ //await this.updateScreens()
373
+ return ok
374
+ }
375
+
376
+ /**
377
+ * Handler for StateChanged through OPC/UA Interface - only connected with touch-buttons on center field (yet)
378
+ */
379
+ async buttonStateChanged(buttonID,attribute,nodeid,val) {
380
+ let ok = false
381
+ this.screenUpdate["center"] = true
382
+ this.screenUpdate["left"] = true
383
+ this.screenUpdate["right"] = true
384
+
385
+ ok = await this.screens.center.buttonStateChanged(buttonID,attribute,nodeid,val)
386
+ ok = await this.knobs.buttonStateChanged(buttonID,attribute,nodeid,val)
387
+
388
+ //await this.updateScreens()
389
+ return ok
390
+ }
391
+
392
+
393
+ }