mirror of https://github.com/espruino/BangleApps
Initial release of presentor app.
parent
d9d5926416
commit
d03749ed92
|
@ -0,0 +1,277 @@
|
|||
// Presentor by 7kasper
|
||||
// Licensed under MIT.
|
||||
// Version 2.1
|
||||
|
||||
const MouseReport = new Uint8Array([
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x02, // USAGE (Mouse)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x85, 0x01, // REPORT_ID (1)
|
||||
0x09, 0x01, // USAGE (Pointer)
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 0x05, // USAGE_MAXIMUM (Button 5)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x95, 0x05, // REPORT_COUNT (5)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x03, // REPORT_SIZE (3)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x30, // USAGE (X)
|
||||
0x09, 0x31, // USAGE (Y)
|
||||
0x09, 0x38, // USAGE (Wheel)
|
||||
0x15, 0x81, // LOGICAL_MINIMUM (-127)
|
||||
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x81, 0x06, // INPUT (Data,Var,Rel)
|
||||
0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
|
||||
0x0a, 0x38, 0x02, // USAGE (AC Pan)
|
||||
0x15, 0x81, // LOGICAL_MINIMUM (-127)
|
||||
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x06, // INPUT (Data,Var,Rel)
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0, // END_COLLECTION
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x85, 0x02, // REPORT_ID (2)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
|
||||
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x08, // REPORT_COUNT (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x01, // INPUT (Cnst,Ary,Abs)
|
||||
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
|
||||
0x29, 0x73, // USAGE_MAXIMUM (Keyboard F24)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x73, // LOGICAL_MAXIMUM (115)
|
||||
0x95, 0x05, // REPORT_COUNT (5)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
0xc0 // END_COLLECTION
|
||||
]);
|
||||
|
||||
const MouseButton = {
|
||||
NONE : 0,
|
||||
LEFT : 1,
|
||||
RIGHT : 2,
|
||||
MIDDLE : 4,
|
||||
BACK : 8,
|
||||
FORWARD: 16
|
||||
};
|
||||
|
||||
const kb = require("ble_hid_keyboard");
|
||||
|
||||
function drawMain() {
|
||||
g.clear();
|
||||
E.showMessage('Presentor');
|
||||
}
|
||||
|
||||
let HIDenabled = true;
|
||||
let lastx = 0;
|
||||
let lasty = 0;
|
||||
let timeoutId = -1;
|
||||
let holding = false;
|
||||
let timeoutHolding = -1;
|
||||
|
||||
let homeRoll = 0;
|
||||
let homePitch = 0;
|
||||
|
||||
let trackPadMode = false;
|
||||
|
||||
let mCal = 0;
|
||||
|
||||
let clearToSend = true;
|
||||
let mttl = 0;
|
||||
let cttl = 0;
|
||||
|
||||
NRF.setServices(undefined, { hid : MouseReport });
|
||||
NRF.on('HID', function() {
|
||||
HIDenabled = true;
|
||||
});
|
||||
|
||||
function moveMouse(x,y,b,wheel,hwheel,callback) {
|
||||
if (!HIDenabled) return;
|
||||
if (!b) b = 0;
|
||||
if (!wheel) wheel = 0;
|
||||
if (!hwheel) hwheel = 0;
|
||||
NRF.sendHIDReport([1,b,x,y,wheel,hwheel,0,0], function() {
|
||||
if (callback) callback();
|
||||
});
|
||||
}
|
||||
|
||||
function getSign(x) {
|
||||
return ((x > 0) - (x < 0)) || +x;
|
||||
}
|
||||
|
||||
function scroll(wheel,hwheel,callback) {
|
||||
moveMouse(0,0,0,wheel,hwheel,callback);
|
||||
}
|
||||
|
||||
// Single click a certain button (immidiatly release).
|
||||
function clickMouse(b, callback) {
|
||||
if (!HIDenabled) return;
|
||||
NRF.sendHIDReport([1,b,0,0,0,0,0,0], function() {
|
||||
NRF.sendHIDReport([1,0,0,0,0,0,0,0], function() {
|
||||
if (callback) callback();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function pressKey(keyCode, modifiers, callback) {
|
||||
if (!HIDenabled) return;
|
||||
if (!modifiers) modifiers = 0;
|
||||
NRF.sendHIDReport([2, modifiers,0,keyCode,0,0,0,0], function() {
|
||||
NRF.sendHIDReport([2,0,0,0,0,0,0,0], function() {
|
||||
if (callback) callback();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function handleAcc(acc) {
|
||||
let rRoll = acc.y * -50;
|
||||
let rPitch = acc.x * -100;
|
||||
if (mCal > 10) {
|
||||
//console.log("x: " + (rRoll - homeRoll) + " y:" + (rPitch - homePitch));
|
||||
moveMouse(acc.y * -50 - homeRoll, acc.x * -100 - homePitch);
|
||||
} else {
|
||||
//console.log("homeroll: " +homeRoll +"homepitch: " + homePitch);
|
||||
homeRoll = rRoll * 0.7 + homeRoll * 0.3;
|
||||
homePitch = rPitch * 0.7 + homePitch * 0.3;
|
||||
mCal = mCal + 1;
|
||||
}
|
||||
}
|
||||
Bangle.on('lock', function(on) {
|
||||
if (on && holding) {
|
||||
Bangle.setLocked(false);
|
||||
Bangle.setLCDPower(1);
|
||||
}
|
||||
});
|
||||
|
||||
function startHolding() {
|
||||
pressKey(kb.KEY.F10);
|
||||
holding = true;
|
||||
Bangle.buzz();
|
||||
E.showMessage('Holding');
|
||||
Bangle.on('accel', handleAcc);
|
||||
Bangle.setLCDPower(1);
|
||||
}
|
||||
function stopHolding() {
|
||||
clearTimeout(timeoutId);
|
||||
if (holding) {
|
||||
pressKey(kb.KEY.F10);
|
||||
homePitch = 0;
|
||||
homeRoll = 0;
|
||||
holding = false;
|
||||
mCal = 0;
|
||||
Bangle.removeListener('accel', handleAcc);
|
||||
Bangle.buzz();
|
||||
drawMain();
|
||||
} else {
|
||||
timeoutId = setTimeout(drawMain, 1000);
|
||||
}
|
||||
clearTimeout(timeoutHolding);
|
||||
timeoutHolding = -1;
|
||||
}
|
||||
|
||||
Bangle.on('drag', function(e) {
|
||||
if (cttl == 0) { cttl = getTime(); }
|
||||
if (trackPadMode) {
|
||||
if (lastx + lasty == 0) {
|
||||
lastx = e.x;
|
||||
lasty = e.y;
|
||||
mttl = getTime();
|
||||
}
|
||||
if (clearToSend) {
|
||||
clearToSend = false;
|
||||
let difX = e.x - lastx, difY = e.y - lasty;
|
||||
let dT = getTime() - mttl;
|
||||
let vX = difX / dT, vY = difY / dT;
|
||||
//let qX = getSign(difX) * Math.pow(Math.abs(difX), 1.2);
|
||||
//let qY = getSign(difY) * Math.pow(Math.abs(difY), 1.2);
|
||||
let qX = difX + 0.02 * vX, qY = difY + 0.02 * vY;
|
||||
moveMouse(qX, qY, 0, 0, 0, function() {
|
||||
setTimeout(function() {clearToSend = true;}, 50);
|
||||
});
|
||||
lastx = e.x;
|
||||
lasty = e.y;
|
||||
mttl = getTime();
|
||||
console.log("Dx: " + (qX) + " Dy: " + (qY));
|
||||
}
|
||||
if (!e.b) {
|
||||
// short press
|
||||
if (getTime() - cttl < 0.2) {
|
||||
clickMouse(MouseButton.LEFT);
|
||||
console.log("click left");
|
||||
}
|
||||
// longer press in center
|
||||
else if (getTime() - cttl < 0.6 && e.x > g.getWidth()/4 && e.x < 3 * g.getWidth()/4 && e.y > g.getHeight() / 4 && e.y < 3 * g.getHeight() / 4) {
|
||||
clickMouse(MouseButton.RIGHT);
|
||||
console.log("click right");
|
||||
}
|
||||
cttl = 0;
|
||||
lastx = 0;
|
||||
lasty = 0;
|
||||
}
|
||||
} else {
|
||||
if(!e.b){
|
||||
Bangle.buzz(100);
|
||||
if(lasty > 40){
|
||||
E.showMessage('down');
|
||||
scroll(0,1);
|
||||
} else if(lasty < -40){
|
||||
E.showMessage(kb.KEY.A);
|
||||
pressKey(kb.KEY.A);
|
||||
} else if(lastx > 40){
|
||||
E.showMessage('right');
|
||||
//kb.tap(kb.KEY.RIGHT, 0);
|
||||
scroll(-1);
|
||||
} else if(lastx < -40){
|
||||
E.showMessage('left');
|
||||
//kb.tap(kb.KEY.LEFT, 0);
|
||||
scroll(1);
|
||||
} else if(lastx==0 && lasty==0 && holding == false){
|
||||
E.showMessage('press');
|
||||
clickMouse(MouseButton.LEFT);
|
||||
}
|
||||
stopHolding();
|
||||
lastx = 0;
|
||||
lasty = 0;
|
||||
} else{
|
||||
lastx = lastx + e.dx;
|
||||
lasty = lasty + e.dy;
|
||||
if (timeoutHolding == -1) {
|
||||
timeoutHolding = setTimeout(startHolding, 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function onBtn() {
|
||||
if (trackPadMode) {
|
||||
trackPadMode = false;
|
||||
stopHolding();
|
||||
drawMain();
|
||||
} else {
|
||||
clearToSend = true;
|
||||
trackPadMode = true;
|
||||
E.showMessage('Mouse');
|
||||
}
|
||||
Bangle.buzz();
|
||||
}
|
||||
setWatch(onBtn, (process.env.HWVERSION==2) ? BTN1 : BTN2, {repeat: true});
|
||||
|
||||
drawMain();
|
Loading…
Reference in New Issue