ctrlpad: retab
parent
9a864c1488
commit
db52196fcc
|
|
@ -1,97 +1,97 @@
|
||||||
(() => {
|
(() => {
|
||||||
if(!Bangle.prependListener){
|
if(!Bangle.prependListener){
|
||||||
type Event<T> = T extends `#on${infer Evt}` ? Evt : never;
|
type Event<T> = T extends `#on${infer Evt}` ? Evt : never;
|
||||||
|
|
||||||
Bangle.prependListener = function(
|
Bangle.prependListener = function(
|
||||||
evt: Event<keyof BangleEvents>,
|
evt: Event<keyof BangleEvents>,
|
||||||
listener: () => void
|
listener: () => void
|
||||||
){
|
){
|
||||||
// move our drag to the start of the event listener array
|
// move our drag to the start of the event listener array
|
||||||
const handlers = (Bangle as BangleEvents)[`#on${evt}`]
|
const handlers = (Bangle as BangleEvents)[`#on${evt}`]
|
||||||
|
|
||||||
if(!handlers){
|
if(!handlers){
|
||||||
Bangle.on(evt as any, listener);
|
Bangle.on(evt as any, listener);
|
||||||
}else{
|
}else{
|
||||||
if(typeof handlers === "function"){
|
if(typeof handlers === "function"){
|
||||||
// get Bangle to convert to array
|
// get Bangle to convert to array
|
||||||
Bangle.on(evt as any, listener);
|
Bangle.on(evt as any, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
// shuffle array
|
// shuffle array
|
||||||
(Bangle as BangleEvents)[`#on${evt}`] = [listener as any].concat(
|
(Bangle as BangleEvents)[`#on${evt}`] = [listener as any].concat(
|
||||||
(handlers as Array<any>).filter((f: unknown) => f !== listener)
|
(handlers as Array<any>).filter((f: unknown) => f !== listener)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Overlay {
|
class Overlay {
|
||||||
g2: Graphics;
|
g2: Graphics;
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
// x padding: 10 each side
|
// x padding: 10 each side
|
||||||
// y top: 24, y bottom: 10
|
// y top: 24, y bottom: 10
|
||||||
this.width = g.getWidth() - 10 * 2;
|
this.width = g.getWidth() - 10 * 2;
|
||||||
this.height = g.getHeight() - 24 - 10;
|
this.height = g.getHeight() - 24 - 10;
|
||||||
|
|
||||||
this.g2 = Graphics.createArrayBuffer(
|
this.g2 = Graphics.createArrayBuffer(
|
||||||
this.width,
|
this.width,
|
||||||
this.height,
|
this.height,
|
||||||
/*bpp*/1,
|
/*bpp*/1,
|
||||||
{ msb: true }
|
{ msb: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
this.renderG2();
|
this.renderG2();
|
||||||
}
|
}
|
||||||
|
|
||||||
setBottom(bottom: number): void {
|
setBottom(bottom: number): void {
|
||||||
const { g2 } = this;
|
const { g2 } = this;
|
||||||
const y = bottom - this.height;
|
const y = bottom - this.height;
|
||||||
|
|
||||||
Bangle.setLCDOverlay(g2, 10, y - 10);
|
Bangle.setLCDOverlay(g2, 10, y - 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
hide(): void {
|
hide(): void {
|
||||||
Bangle.setLCDOverlay();
|
Bangle.setLCDOverlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
renderG2(): void {
|
renderG2(): void {
|
||||||
const g = this.g2;
|
const g = this.g2;
|
||||||
|
|
||||||
g
|
g
|
||||||
.reset()
|
.reset()
|
||||||
.clearRect(0, 0, this.width, this.height)
|
.clearRect(0, 0, this.width, this.height)
|
||||||
.drawRect(0, 0, this.width - 1, this.height - 1)
|
.drawRect(0, 0, this.width - 1, this.height - 1)
|
||||||
.drawRect(1, 1, this.width - 2, this.height - 2);
|
.drawRect(1, 1, this.width - 2, this.height - 2);
|
||||||
|
|
||||||
const centreY = this.height / 2;
|
const centreY = this.height / 2;
|
||||||
const circleGapY = 30;
|
const circleGapY = 30;
|
||||||
|
|
||||||
g
|
g
|
||||||
.setFontAlign(0, 0)
|
.setFontAlign(0, 0)
|
||||||
.setFont("Vector:20");
|
.setFont("Vector:20");
|
||||||
|
|
||||||
this.drawCtrl(this.width / 4 - 10, centreY - circleGapY, "<");
|
this.drawCtrl(this.width / 4 - 10, centreY - circleGapY, "<");
|
||||||
this.drawCtrl(this.width / 2, centreY - circleGapY, "@");
|
this.drawCtrl(this.width / 2, centreY - circleGapY, "@");
|
||||||
this.drawCtrl(this.width * 3/4 + 10, centreY - circleGapY, ">");
|
this.drawCtrl(this.width * 3/4 + 10, centreY - circleGapY, ">");
|
||||||
|
|
||||||
this.drawCtrl(this.width / 3, centreY + circleGapY, "-");
|
this.drawCtrl(this.width / 3, centreY + circleGapY, "-");
|
||||||
this.drawCtrl(this.width * 2/3, centreY + circleGapY, "+");
|
this.drawCtrl(this.width * 2/3, centreY + circleGapY, "+");
|
||||||
}
|
}
|
||||||
|
|
||||||
drawCtrl(x: number, y: number, label: string): void {
|
drawCtrl(x: number, y: number, label: string): void {
|
||||||
const g = this.g2;
|
const g = this.g2;
|
||||||
|
|
||||||
g
|
g
|
||||||
.setColor("#fff")
|
.setColor("#fff")
|
||||||
.fillCircle(x, y, 23)
|
.fillCircle(x, y, 23)
|
||||||
.setColor("#000")
|
.setColor("#000")
|
||||||
.drawString(label, x, y);
|
.drawString(label, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const settings = require("Storage").readJSON("setting.json", true) as Settings || ({ HID: false } as Settings);
|
const settings = require("Storage").readJSON("setting.json", true) as Settings || ({ HID: false } as Settings);
|
||||||
if (settings.HID !== "kbmedia") {
|
if (settings.HID !== "kbmedia") {
|
||||||
|
|
@ -110,114 +110,114 @@
|
||||||
}
|
}
|
||||||
let state = State.NoConn;
|
let state = State.NoConn;
|
||||||
let startY = 0;
|
let startY = 0;
|
||||||
let startedUpDrag = false;
|
let startedUpDrag = false;
|
||||||
let upDragAnim: IntervalId | undefined;
|
let upDragAnim: IntervalId | undefined;
|
||||||
let overlay: Overlay | undefined;
|
let overlay: Overlay | undefined;
|
||||||
let touchDown = false;
|
let touchDown = false;
|
||||||
|
|
||||||
const onDrag = (e => {
|
const onDrag = (e => {
|
||||||
const dragDistance = 30;
|
const dragDistance = 30;
|
||||||
|
|
||||||
if (e.b === 0) touchDown = startedUpDrag = false;
|
if (e.b === 0) touchDown = startedUpDrag = false;
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case State.NoConn:
|
case State.NoConn:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case State.IgnoreCurrent:
|
case State.IgnoreCurrent:
|
||||||
if(e.b === 0){
|
if(e.b === 0){
|
||||||
state = State.Idle;
|
state = State.Idle;
|
||||||
overlay = undefined;
|
overlay = undefined;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case State.Idle:
|
case State.Idle:
|
||||||
if(e.b && !touchDown){ // no need to check Bangle.CLKINFO_FOCUS
|
if(e.b && !touchDown){ // no need to check Bangle.CLKINFO_FOCUS
|
||||||
if(e.y <= 40){
|
if(e.y <= 40){
|
||||||
state = State.TopDrag
|
state = State.TopDrag
|
||||||
startY = e.y;
|
startY = e.y;
|
||||||
console.log(" topdrag detected, starting @ " + startY);
|
console.log(" topdrag detected, starting @ " + startY);
|
||||||
}else{
|
}else{
|
||||||
console.log(" ignoring this drag (too low @ " + e.y + ")");
|
console.log(" ignoring this drag (too low @ " + e.y + ")");
|
||||||
state = State.IgnoreCurrent;
|
state = State.IgnoreCurrent;
|
||||||
overlay = undefined
|
overlay = undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case State.TopDrag:
|
case State.TopDrag:
|
||||||
if(e.b === 0){
|
if(e.b === 0){
|
||||||
console.log("topdrag stopped, distance: " + (e.y - startY));
|
console.log("topdrag stopped, distance: " + (e.y - startY));
|
||||||
if(e.y > startY + dragDistance){
|
if(e.y > startY + dragDistance){
|
||||||
console.log("activating");
|
console.log("activating");
|
||||||
activate();
|
activate();
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
console.log("returning to idle");
|
|
||||||
state = State.Idle;
|
|
||||||
overlay?.hide();
|
|
||||||
overlay = undefined;
|
|
||||||
}else{
|
|
||||||
// partial drag, show UI feedback:
|
|
||||||
const dragOffset = 32;
|
|
||||||
|
|
||||||
if (!overlay) overlay = new Overlay();
|
|
||||||
overlay.setBottom(e.y - dragOffset);
|
|
||||||
}
|
}
|
||||||
break;
|
console.log("returning to idle");
|
||||||
|
state = State.Idle;
|
||||||
|
overlay?.hide();
|
||||||
|
overlay = undefined;
|
||||||
|
}else{
|
||||||
|
// partial drag, show UI feedback:
|
||||||
|
const dragOffset = 32;
|
||||||
|
|
||||||
|
if (!overlay) overlay = new Overlay();
|
||||||
|
overlay.setBottom(e.y - dragOffset);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case State.Active:
|
case State.Active:
|
||||||
console.log("stolen drag handling, do whatever here");
|
console.log("stolen drag handling, do whatever here");
|
||||||
E.stopEventPropagation?.();
|
E.stopEventPropagation?.();
|
||||||
if(e.b){
|
if(e.b){
|
||||||
if(!touchDown){
|
if(!touchDown){
|
||||||
startY = e.y;
|
startY = e.y;
|
||||||
}else if(startY){
|
}else if(startY){
|
||||||
const dist = Math.max(0, startY - e.y);
|
const dist = Math.max(0, startY - e.y);
|
||||||
|
|
||||||
if (startedUpDrag || (startedUpDrag = dist > 10)) // ignore small drags
|
if (startedUpDrag || (startedUpDrag = dist > 10)) // ignore small drags
|
||||||
overlay!.setBottom(g.getHeight() - dist);
|
overlay!.setBottom(g.getHeight() - dist);
|
||||||
}
|
}
|
||||||
}else if(e.b === 0 && startY > dragDistance){
|
}else if(e.b === 0 && startY > dragDistance){
|
||||||
let bottom = g.getHeight() - Math.max(0, startY - e.y);
|
let bottom = g.getHeight() - Math.max(0, startY - e.y);
|
||||||
|
|
||||||
if (upDragAnim) clearInterval(upDragAnim);
|
if (upDragAnim) clearInterval(upDragAnim);
|
||||||
upDragAnim = setInterval(() => {
|
upDragAnim = setInterval(() => {
|
||||||
if (!overlay || bottom <= 0) {
|
if (!overlay || bottom <= 0) {
|
||||||
clearInterval(upDragAnim!);
|
clearInterval(upDragAnim!);
|
||||||
upDragAnim = undefined;
|
upDragAnim = undefined;
|
||||||
overlay?.hide();
|
overlay?.hide();
|
||||||
overlay = undefined;
|
overlay = undefined;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
overlay?.setBottom(bottom)
|
overlay?.setBottom(bottom)
|
||||||
bottom -= 10;
|
bottom -= 10;
|
||||||
}, 50)
|
}, 50)
|
||||||
deactivate();
|
deactivate();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(e.b) touchDown = true;
|
if(e.b) touchDown = true;
|
||||||
}) satisfies DragCallback;
|
}) satisfies DragCallback;
|
||||||
|
|
||||||
const onTouch = ((_btn, _xy) => {
|
const onTouch = ((_btn, _xy) => {
|
||||||
// TODO: button presses
|
// TODO: button presses
|
||||||
}) satisfies TouchCallback;
|
}) satisfies TouchCallback;
|
||||||
|
|
||||||
const activate = () => {
|
const activate = () => {
|
||||||
state = State.Active;
|
state = State.Active;
|
||||||
startY = 0;
|
startY = 0;
|
||||||
Bangle.prependListener("touch", onTouch);
|
Bangle.prependListener("touch", onTouch);
|
||||||
Bangle.buzz(20);
|
Bangle.buzz(20);
|
||||||
overlay!.setBottom(g.getHeight());
|
overlay!.setBottom(g.getHeight());
|
||||||
};
|
};
|
||||||
|
|
||||||
const deactivate = () => {
|
const deactivate = () => {
|
||||||
Bangle.removeListener("touch", onTouch);
|
Bangle.removeListener("touch", onTouch);
|
||||||
state = State.Idle;
|
state = State.Idle;
|
||||||
};
|
};
|
||||||
|
|
||||||
Bangle.prependListener("drag", onDrag);
|
Bangle.prependListener("drag", onDrag);
|
||||||
|
|
||||||
const redraw = () => setTimeout(Bangle.drawWidgets, 10);
|
const redraw = () => setTimeout(Bangle.drawWidgets, 10);
|
||||||
|
|
||||||
|
|
@ -229,10 +229,10 @@
|
||||||
if(this.width === 0) return;
|
if(this.width === 0) return;
|
||||||
g.drawImage(
|
g.drawImage(
|
||||||
state === State.Active
|
state === State.Active
|
||||||
? require("heatshrink").decompress(atob("jEYxH+AEfH44XXAAYXXDKIXZDYp3pC/6KHUMwWHC/4XvUy4YGdqoA/AFoA=="))
|
? require("heatshrink").decompress(atob("jEYxH+AEfH44XXAAYXXDKIXZDYp3pC/6KHUMwWHC/4XvUy4YGdqoA/AFoA=="))
|
||||||
: require("heatshrink").decompress(atob("jEYxH+AEcdjoXXAAYXXDKIXZDYp3pC/6KHUMwWHC/4XvUy4YGdqoA/AFoA==")),
|
: require("heatshrink").decompress(atob("jEYxH+AEcdjoXXAAYXXDKIXZDYp3pC/6KHUMwWHC/4XvUy4YGdqoA/AFoA==")),
|
||||||
this.x! + 2,
|
this.x! + 2,
|
||||||
this.y! + 2
|
this.y! + 2
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
width: connected ? 24 : 0,
|
width: connected ? 24 : 0,
|
||||||
|
|
@ -255,25 +255,25 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
//const DEBUG = true;
|
//const DEBUG = true;
|
||||||
/*
|
/*
|
||||||
const sendHid = (code: number) => {
|
const sendHid = (code: number) => {
|
||||||
//if(DEBUG) return;
|
//if(DEBUG) return;
|
||||||
try{
|
try{
|
||||||
NRF.sendHIDReport(
|
NRF.sendHIDReport(
|
||||||
[1, code],
|
[1, code],
|
||||||
() => NRF.sendHIDReport([1, 0]),
|
() => NRF.sendHIDReport([1, 0]),
|
||||||
);
|
);
|
||||||
}catch(e){
|
}catch(e){
|
||||||
console.log("sendHIDReport:", e);
|
console.log("sendHIDReport:", e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const hid = {
|
const hid = {
|
||||||
next: () => sendHid(0x01),
|
next: () => sendHid(0x01),
|
||||||
prev: () => sendHid(0x02),
|
prev: () => sendHid(0x02),
|
||||||
toggle: () => sendHid(0x10),
|
toggle: () => sendHid(0x10),
|
||||||
up: () => sendHid(0x40),
|
up: () => sendHid(0x40),
|
||||||
down: () => sendHid(0x80),
|
down: () => sendHid(0x80),
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
})()
|
})()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue