From 517c35a37ddaed8716ea19785d77dc5c4aaa1432 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 28 Apr 2020 15:23:02 +0100 Subject: [PATCH] Added BLE HID option for Joystick and bare Keyboard, update HID apps to send correct info --- apps.json | 13 +- apps/boot/ChangeLog | 1 + apps/boot/boot0.js | 4 +- apps/boot/hid_info.txt | 88 ++++++++++++ apps/hidbkbd/ChangeLog | 2 + apps/hidbkbd/hid-binary-keyboard.js | 38 +++-- apps/hidcam/ChangeLog | 1 + apps/hidcam/app.js | 11 +- apps/hidkbd/ChangeLog | 2 + apps/hidkbd/hid-keyboard.js | 45 ++++-- apps/hidmsic/ChangeLog | 1 + apps/hidmsic/hid-music.js | 11 +- apps/mclock/clock-morphing-faster.js | 206 +++++++++++++++++++++++++++ apps/setting/ChangeLog | 1 + apps/setting/README.md | 18 +++ apps/setting/settings.js | 10 +- 16 files changed, 411 insertions(+), 41 deletions(-) create mode 100644 apps/boot/hid_info.txt create mode 100644 apps/hidbkbd/ChangeLog create mode 100644 apps/hidkbd/ChangeLog create mode 100644 apps/hidmsic/ChangeLog create mode 100644 apps/mclock/clock-morphing-faster.js create mode 100644 apps/setting/README.md diff --git a/apps.json b/apps.json index d275b0e44..7c4eed0ed 100644 --- a/apps.json +++ b/apps.json @@ -2,7 +2,7 @@ { "id": "boot", "name": "Bootloader", "icon": "bootloader.png", - "version":"0.14", + "version":"0.15", "description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings", "tags": "tool,system", "type":"bootloader", @@ -122,9 +122,10 @@ { "id": "setting", "name": "Settings", "icon": "settings.png", - "version":"0.18", + "version":"0.19", "description": "A menu for setting up Bangle.js", "tags": "tool,system", + "readme": "README.md", "storage": [ {"name":"setting.app.js","url":"settings.js"}, {"name":"setting.boot.js","url":"boot.js"}, @@ -480,7 +481,7 @@ "name": "Bluetooth Music Controls", "shortName": "Music Control", "icon": "hid-music.png", - "version":"0.01", + "version":"0.02", "description": "Enable HID in settings, pair with your phone, then use this app to control music from your watch!", "tags": "bluetooth", "storage": [ @@ -492,7 +493,7 @@ "name": "Bluetooth Keyboard", "shortName": "Bluetooth Kbd", "icon": "hid-keyboard.png", - "version":"0.01", + "version":"0.02", "description": "Enable HID in settings, pair with your phone/PC, then use this app to control other apps", "tags": "bluetooth", "storage": [ @@ -504,7 +505,7 @@ "name": "Binary Bluetooth Keyboard", "shortName": "Binary BT Kbd", "icon": "hid-binary-keyboard.png", - "version":"0.01", + "version":"0.02", "description": "Enable HID in settings, pair with your phone/PC, then type messages using the onscreen keyboard by tapping repeatedly on the key you want", "tags": "bluetooth", "storage": [ @@ -1437,7 +1438,7 @@ "name": "Camera shutter", "shortName":"Cam shutter", "icon": "app.png", - "version":"0.01", + "version":"0.02", "description": "Enable HID, connect to your phone, start your camera and trigger the shot on your Bangle", "tags": "tools", "storage": [ diff --git a/apps/boot/ChangeLog b/apps/boot/ChangeLog index 7ab79a5a5..cf5c243f8 100644 --- a/apps/boot/ChangeLog +++ b/apps/boot/ChangeLog @@ -13,3 +13,4 @@ 0.13: Now automatically load *.boot.js at startup Move alarm code into alarm.boot.js 0.14: Move welcome loaders to *.boot.js +0.15: Added BLE HID option for Joystick and bare Keyboard diff --git a/apps/boot/boot0.js b/apps/boot/boot0.js index dd3b3a9ba..332e33177 100644 --- a/apps/boot/boot0.js +++ b/apps/boot/boot0.js @@ -4,7 +4,9 @@ E.setFlags({pretokenise:1}); var s = require('Storage').readJSON('setting.json',1)||{}; if (s.ble!==false) { if (s.HID) { // Human interface device - Bangle.HID = E.toUint8Array(atob("BQEJBqEBhQIFBxngKecVACUBdQGVCIEClQF1CIEBlQV1AQUIGQEpBZEClQF1A5EBlQZ1CBUAJXMFBxkAKXOBAAkFFQAm/wB1CJUCsQLABQwJAaEBhQEVACUBdQGVAQm1gQIJtoECCbeBAgm4gQIJzYECCeKBAgnpgQIJ6oECwA==")); + if (s.HID=="joy") Bangle.HID = E.toUint8Array(atob("BQEJBKEBhQMJAaEABQkZASkFFQAlAZUFdQGBApUDdQGBAwUBCTAJMRWBJX91CJUCgQLAwA==")); + else if (s.HID=="kb") Bangle.HID = E.toUint8Array(atob("BQEJBqEBBQcZ4CnnFQAlAXUBlQiBApUBdQiBAZUFdQEFCBkBKQWRApUBdQORAZUGdQgVACVzBQcZAClzgQAJBRUAJv8AdQiVArECwA==")); + else /*kbmedia*/Bangle.HID = E.toUint8Array(atob("BQEJBqEBhQIFBxngKecVACUBdQGVCIEClQF1CIEBlQV1AQUIGQEpBZEClQF1A5EBlQZ1CBUAJXMFBxkAKXOBAAkFFQAm/wB1CJUCsQLABQwJAaEBhQEVACUBdQGVAQm1gQIJtoECCbeBAgm4gQIJzYECCeKBAgnpgQIJ6oECwA==")); NRF.setServices({}, {uart:true, hid:Bangle.HID}); } } diff --git a/apps/boot/hid_info.txt b/apps/boot/hid_info.txt new file mode 100644 index 000000000..873b50f63 --- /dev/null +++ b/apps/boot/hid_info.txt @@ -0,0 +1,88 @@ + +## Joystick: + +https://github.com/espruino/BangleApps/issues/349#issuecomment-620231524 + +``` +0x05, 0x01, // Usage Page (Generic Desktop) +0x09, 0x04, // Usage (Joystick) +0xA1, 0x01, // Collection (Application) + 0x09, 0x01, // Usage (Pointer) + 0xA1, 0x00, // Collection (Physical) + // Buttons + 0x05, 0x09, // Usage Page (Buttons) + 0x19, 0x01, // Usage Minimum (1) + 0x29, 0x05, // Usage Maximum (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, Variable, Absolute) + + // padding bits + 0x95, 0x03, // Report Count (3) + 0x75, 0x01, // Report Size (1) + 0x81, 0x03, // Input (Constant) + + // Stick + 0x05, 0x01, // Usage Page (Generic Desktop) + 0x09, 0x30, // Usage (X) + 0x09, 0x31, // Usage (Y) + 0x15, 0x81, // Logical Minimum (-127) + 0x25, 0x7f, // Logical Maximum (127) + 0x75, 0x08, // Report Size (8) + 0x95, 0x02, // Report Count (2) + 0x81, 0x02, // Input (Data, Variable, Absolute) + 0xC0, // End Collection (Physical) +0xC0 // End Collection (Application) +``` + +## Keyboard + +http://www.espruino.com/BLE+Keyboard + +``` +0x05, 0x01, // Usage Page (Generic Desktop) +0x09, 0x06, // Usage (Keyboard) +0xA1, 0x01, // Collection (Application) +0x05, 0x07, // Usage Page (Key Codes) +0x19, 0xe0, // Usage Minimum (224) +0x29, 0xe7, // Usage Maximum (231) +0x15, 0x00, // Logical Minimum (0) +0x25, 0x01, // Logical Maximum (1) +0x75, 0x01, // Report Size (1) +0x95, 0x08, // Report Count (8) +0x81, 0x02, // Input (Data, Variable, Absolute) + +0x95, 0x01, // Report Count (1) +0x75, 0x08, // Report Size (8) +0x81, 0x01, // Input (Constant) reserved byte(1) + +0x95, 0x05, // Report Count (5) +0x75, 0x01, // Report Size (1) +0x05, 0x08, // Usage Page (Page# for LEDs) +0x19, 0x01, // Usage Minimum (1) +0x29, 0x05, // Usage Maximum (5) +0x91, 0x02, // Output (Data, Variable, Absolute), Led report +0x95, 0x01, // Report Count (1) +0x75, 0x03, // Report Size (3) +0x91, 0x01, // Output (Data, Variable, Absolute), Led report padding + +0x95, 0x06, // Report Count (6) +0x75, 0x08, // Report Size (8) +0x15, 0x00, // Logical Minimum (0) +0x25, 0x73, // Logical Maximum (115 - include F13, etc) +0x05, 0x07, // Usage Page (Key codes) +0x19, 0x00, // Usage Minimum (0) +0x29, 0x73, // Usage Maximum (115 - include F13, etc) +0x81, 0x00, // Input (Data, Array) Key array(6 bytes) + +0x09, 0x05, // Usage (Vendor Defined) +0x15, 0x00, // Logical Minimum (0) +0x26, 0xFF, 0x00, // Logical Maximum (255) +0x75, 0x08, // Report Count (2) +0x95, 0x02, // Report Size (8 bit) +0xB1, 0x02, // Feature (Data, Variable, Absolute) + +0xC0 // End Collection (Application) +``` diff --git a/apps/hidbkbd/ChangeLog b/apps/hidbkbd/ChangeLog new file mode 100644 index 000000000..459bf40b9 --- /dev/null +++ b/apps/hidbkbd/ChangeLog @@ -0,0 +1,2 @@ +0.01: Core functionnality +0.02: Offer to enable HID if disabled. Handle with/without media keys diff --git a/apps/hidbkbd/hid-binary-keyboard.js b/apps/hidbkbd/hid-binary-keyboard.js index fa1017714..81838b42d 100644 --- a/apps/hidbkbd/hid-binary-keyboard.js +++ b/apps/hidbkbd/hid-binary-keyboard.js @@ -45,13 +45,7 @@ const KEY = { 0 : 39 }; -function sendHID(code) { - return new Promise(resolve=>{ - NRF.sendHIDReport([2,0,0,code,0,0,0,0,0], () => { - NRF.sendHIDReport([2,0,0,0,0,0,0,0,0], resolve); - }); - }); -}; +var sendHID; function showChars(x,chars) { var lines = Math.round(Math.sqrt(chars.length)*2); @@ -103,10 +97,24 @@ function startKeyboardHID() { }).then(startKeyboardHID); }; -if (!settings.HID) { - E.showMessage('HID disabled'); - setTimeout(load, 1000); -} else { +if (settings.HID=="kb" || settings.HID=="kbmedia") { + if (settings.HID=="kbmedia") { + sendHID = function(code) { + return new Promise(resolve=>{ + NRF.sendHIDReport([2,0,0,code,0,0,0,0,0], () => { + NRF.sendHIDReport([2,0,0,0,0,0,0,0,0], resolve); + }); + }); + }; + } else { + sendHID = function(code) { + return new Promise(resolve=>{ + NRF.sendHIDReport([0,0,code,0,0,0,0,0], () => { + NRF.sendHIDReport([0,0,0,0,0,0,0,0], resolve); + }); + }); + }; + } startKeyboardHID(); setWatch(() => { sendHID(44); // space @@ -114,4 +122,12 @@ if (!settings.HID) { setWatch(() => { sendHID(40); // enter }, BTN3, {repeat:true}); +} else { + E.showPrompt("Enable HID?",{title:"HID disabled"}).then(function(enable) { + if (enable) { + settings.HID = "kb"; + require("Storage").write('setting.json', settings); + setTimeout(load, 1000, "hidbkbd.app.js"); + } else setTimeout(load, 1000); + }); } diff --git a/apps/hidcam/ChangeLog b/apps/hidcam/ChangeLog index 73b3268b7..2823e1f1d 100644 --- a/apps/hidcam/ChangeLog +++ b/apps/hidcam/ChangeLog @@ -1 +1,2 @@ 0.01: Core functionnality +0.02: Offer to enable HID if disabled diff --git a/apps/hidcam/app.js b/apps/hidcam/app.js index 89b8ac4a1..adb1a4b29 100644 --- a/apps/hidcam/app.js +++ b/apps/hidcam/app.js @@ -4,7 +4,7 @@ const settings = storage.readJSON('setting.json',1) || { HID: false }; var sendHid, camShot, profile; -if (settings.HID) { +if (settings.HID=="kbmedia") { profile = 'camShutter'; sendHid = function (code, cb) { try { @@ -19,8 +19,13 @@ if (settings.HID) { }; camShot = function (cb) { sendHid(0x80, cb); }; } else { - E.showMessage('HID disabled'); - setTimeout(load, 1000); + E.showPrompt("Enable HID?",{title:"HID disabled"}).then(function(enable) { + if (enable) { + settings.HID = "kbmedia"; + require("Storage").write('setting.json', settings); + setTimeout(load, 1000, "hidcam.app.js"); + } else setTimeout(load, 1000); + }); } function drawApp() { g.clear(); diff --git a/apps/hidkbd/ChangeLog b/apps/hidkbd/ChangeLog new file mode 100644 index 000000000..459bf40b9 --- /dev/null +++ b/apps/hidkbd/ChangeLog @@ -0,0 +1,2 @@ +0.01: Core functionnality +0.02: Offer to enable HID if disabled. Handle with/without media keys diff --git a/apps/hidkbd/hid-keyboard.js b/apps/hidkbd/hid-keyboard.js index ed406e093..0d489bc0d 100644 --- a/apps/hidkbd/hid-keyboard.js +++ b/apps/hidkbd/hid-keyboard.js @@ -4,27 +4,46 @@ const settings = storage.readJSON('setting.json',1) || { HID: false }; var sendHid, next, prev, toggle, up, down, profile; -if (settings.HID) { +if (settings.HID=="kb" || settings.HID=="kbmedia") { profile = 'Keyboard'; - sendHid = function (code, cb) { - try { - NRF.sendHIDReport([2,0,0,code,0,0,0,0,0], () => { - NRF.sendHIDReport([2,0,0,0,0,0,0,0,0], () => { - if (cb) cb(); + if (settings.HID=="kbmedia") { + sendHid = function (code, cb) { + try { + NRF.sendHIDReport([2,0,0,code,0,0,0,0,0], () => { + NRF.sendHIDReport([2,0,0,0,0,0,0,0,0], () => { + if (cb) cb(); + }); }); - }); - } catch(e) { - print(e); - } - }; + } catch(e) { + print(e); + } + }; + } else { + sendHid = function (code, cb) { + try { + NRF.sendHIDReport([0,0,code,0,0,0,0,0], () => { + NRF.sendHIDReport([0,0,0,0,0,0,0,0], () => { + if (cb) cb(); + }); + }); + } catch(e) { + print(e); + } + }; + } next = function (cb) { sendHid(0x4f, cb); }; prev = function (cb) { sendHid(0x50, cb); }; toggle = function (cb) { sendHid(0x2c, cb); }; up = function (cb) {sendHid(0x52, cb); }; down = function (cb) { sendHid(0x51, cb); }; } else { - E.showMessage('HID disabled'); - setTimeout(load, 1000); + E.showPrompt("Enable HID?",{title:"HID disabled"}).then(function(enable) { + if (enable) { + settings.HID = "kb"; + require("Storage").write('setting.json', settings); + setTimeout(load, 1000, "hidkbd.app.js"); + } else setTimeout(load, 1000); + }); } function drawApp() { diff --git a/apps/hidmsic/ChangeLog b/apps/hidmsic/ChangeLog new file mode 100644 index 000000000..73b3268b7 --- /dev/null +++ b/apps/hidmsic/ChangeLog @@ -0,0 +1 @@ +0.01: Core functionnality diff --git a/apps/hidmsic/hid-music.js b/apps/hidmsic/hid-music.js index 034bbd231..db81744f3 100644 --- a/apps/hidmsic/hid-music.js +++ b/apps/hidmsic/hid-music.js @@ -4,7 +4,7 @@ const settings = storage.readJSON('setting.json',1) || { HID: false }; var sendHid, next, prev, toggle, up, down, profile; -if (settings.HID) { +if (settings.HID=="kbmedia") { profile = 'Music'; sendHid = function (code, cb) { try { @@ -23,8 +23,13 @@ if (settings.HID) { up = function (cb) {sendHid(0x40, cb); }; down = function (cb) { sendHid(0x80, cb); }; } else { - E.showMessage('HID disabled'); - setTimeout(load, 1000); + E.showPrompt("Enable HID?",{title:"HID disabled"}).then(function(enable) { + if (enable) { + settings.HID = "kbmedia"; + require("Storage").write('setting.json', settings); + setTimeout(load, 1000, "hidmsc.app.js"); + } else setTimeout(load, 1000); + }); } function drawApp() { diff --git a/apps/mclock/clock-morphing-faster.js b/apps/mclock/clock-morphing-faster.js new file mode 100644 index 000000000..69cd72707 --- /dev/null +++ b/apps/mclock/clock-morphing-faster.js @@ -0,0 +1,206 @@ +var locale = require("locale"); +var CHARW = 34; +var CHARP = 2; +var Y = 50; +// Offscreen buffer +var buf = Graphics.createArrayBuffer(CHARW+CHARP*2,CHARW*2 + CHARP*2,1,{msb:true}); +var bufimg = {width:buf.getWidth(),height:buf.getHeight(),buffer:buf.buffer}; +// The last time that we displayed +var lastTime = " "; +// If animating, this is the interval's id +var animInterval; +var timeInterval; + +/* Get array of lines from digit d to d+1. + n is the amount (0..1) + maxFive is true is this digit only counts 0..5 */ +const DIGITS = { +" ":(g,s,p,n)=>{}, +"0":(g,s,p,n)=>{ +g.fillRect(1+s*n,1-p, 1+s,1+p); +g.fillRect(1+s-p,1, 1+s+p,1+s); +g.fillRect(1+s-p,1+s, 1+s+p,1+2*s); +g.fillRect(1+s*n,1+2*s-p, 1+s,1+2*s+p); +g.fillRect(1+s*n,1+s-p, 1+s*n,1+2*s+p); +g.fillRect(1+s*n-p,1, 1+s*n+p,1+s)}, +"1":(g,s,p,n)=>{ +g.fillRect(1+(1-n)*s,1-p, 1+s,1+p); +g.fillRect(1+s-p,1, 1+s+p,1+s); +g.fillRect(1+(1-n)*s,1+s-p, 1+s,1+s+p); +g.fillRect(1-p+(1-n)*s,1+s, 1+p+(1-n)*s,1+2*s); +g.fillRect(1+(1-n)*s,1-p+2*s, 1+s,1+p+2*s)}, +"2":(g,s,p,n)=>{ +g.fillRect(1,1-p, 1+s,1+p); +g.fillRect(1+s-p,1, 1+s+p,1+s); +g.fillRect(1,1+s-p, 1+s,1+s+p); +g.fillRect(1-p,1+(1+n)*s, 1+p,1+2*s); +g.fillRect(1+s-p,1+(2-n)*s, 1+s+p,1+2*s); +g.fillRect(1,1+2*s-p, 1+s,1+2*s+p)}, +"3":(g,s,p,n)=>{ +g.fillRect(1,1-p, 1+(1-n)*s,1+p); +g.fillRect(1-p,1, 1+p,n); +g.fillRect(1+s-p,1, 1+s+p,1+s); +g.fillRect(1,1+s-p, 1+s,1+s+p); +g.fillRect(1+s-p,1+s, 1+s+p,1+2*s); +g.fillRect(1+s*n,1+2*s-p, 1+s,1+2*s+p)}, +"4":(g,s,p,n)=>{ +g.fillRect(1-p,1, 1+p,1+s); +g.fillRect(1+s,1-p, 1+(1-n)*s,1+p); +g.fillRect(1+s-p,1, 1+s+p,1+(1-n)*s); +g.fillRect(1,1+s-p, 1+s,1+s+p); +g.fillRect(1+s-p,1+s, 1+s+p,1+2*s); +g.fillRect(1+(1-n)*s,1+2*s-p, 1+s,1+2*s+p)}, +"5to0": (g,s,p,n)=>{ // 5 -> 0 +g.fillRect(1-p,1, 1+p,1+s); +g.fillRect(1,1-p, 1+s,1+p); +g.fillRect(1+s*n,1+s-p, 1+s,1+s+p); +g.fillRect(1+s-p,1+s, 1+s+p,1+2*s); +g.fillRect(1,1+2*s*p, 1+s,1+2*s+p); +g.fillRect(1,1+2*s-p, 1,1+2*s+p); +g.fillRect(1+s-p,1+(1-n)*s, 1+s+p,1+s); +g.fillRect(1-p,1+s, 1+p,1+(1+n)*s)}, +"5to6": (g,s,p,n)=>{ // 5 -> 6 +g.fillRect(1-p,1, 1+p,1+s); +g.fillRect(1,1-p, 1+s,1+p); +g.fillRect(1,1+s-p, 1+s,1+s+p); +g.fillRect(1+s-p,1+s, 1+s+p,1+2*s); +g.fillRect(1,1+2*s-p, 1+s,1+2*s+p); +g.fillRect(1-p,2-n, 1+p,1+2*s)}, +"6":(g,s,p,n)=>{ +g.fillRect(1-p,1, 1+p,1+(1-n)*s); +g.fillRect(1,1-p, 1+s,1+p); +g.fillRect(1+s*n,1+s-p, 1+s,1+s+p); +g.fillRect(1+s-p,1+(1-n)*s, 1+s+p,1+s); +g.fillRect(1+s-p,1+s, 1+s+p,1+2*s); +g.fillRect(1+s*n,1+2*s-p, 1+s,1+2*s+p); +g.fillRect(1-p,1+(1-n)*s, 1+p,1+s*(2-2*n))}, +"7":(g,s,p,n)=>{ +g.fillRect(1-p,1, 1+p,n); +g.fillRect(1,1-p, 1+s,1+p); +g.fillRect(1+s-p,1, 1+s+p,1+s); +g.fillRect(1+(1-n)*s,1+s-p, 1+s,1+s+p); +g.fillRect(1+s-p,1+s, 1+s+p,1+2*s); +g.fillRect(1+(1-n)*s,1+2*s-p, 1+s,1+2*s+p); +g.fillRect(1+(1-n)*s-p,1+s, 1+(1-n)*s+p,1+2*s)}, +"8":(g,s,p,n)=>{ +g.fillRect(1-p,1, 1+p,1+s); +g.fillRect(1,1-p, 1+s,1+p); +g.fillRect(1+s-p,1, 1+s+p,1+s); +g.fillRect(1,1+s-p, 1+s,1+s+p); +g.fillRect(1+s-p,1+s, 1+s+p,1+2*s); +g.fillRect(1,1+2*s-p, 1+s,1+2*s+p); +g.fillRect(1-p,1+s, 1+p,1+s*(2-n))}, +"9":(g,s,p,n)=>{ +g.fillRect(1-p,1, 1+p,1+s); +g.fillRect(1,1-p, 1+s,1+p); +g.fillRect(1+s-p,1, 1+s+p,1+s); +g.fillRect(1,1+s-p, 1+(1-n)*s,1+s+p); +g.fillRect(1-p,1+s, 1+p,1+(1+n)*s); +g.fillRect(1+s-p,1+s, 1+s+p,1+2*s); +g.fillRect(1,1+2*s-p, 1+s,1+2*s+p)}, +":":(g,s,p,n)=>{ +g.fillRect(1+s*0.4,1+s*0.4-p, 1+s*0.6,1+s*0.4+p); +g.fillRect(1+s*0.6-p,1+s*0.4, 1+s*0.6+p,1+s*0.6); +g.fillRect(1+s*0.6,1+s*0.6-p, 1+s*0.4,1+s*0.6+p); +g.fillRect(1+s*0.4-p,1+s*0.4, 1+s*0.4+p,1+s*0.6); +g.fillRect(1+s*0.4,1+s*1.4-p, 1+s*0.6,1+s*1.4+p); +g.fillRect(1+s*0.6-p,1+s*1.4, 1+s*0.6+p,1+s*1.6); +g.fillRect(1+s*0.6,1+s*1.6-p, 1+s*0.4,1+s*1.6+p); +g.fillRect(1+s*0.4-p,1+s*1.4, 1+s*0.4+p,1+s*1.6) +}}; + +/* Draw a transition between lastText and thisText. + 'n' is the amount - 0..1 */ +function drawDigits(lastText,thisText,n) { + const p = CHARP; // padding around digits + const s = CHARW; // character size + var x = p; // x offset + var y = Y+p; // y offset + g.reset(); + for (var i=0;i=1) { + n=1; + clearInterval(animInterval); + animInterval = undefined; + } + drawDigits(l,t,n); + }, 20); + lastTime = t; +} + +Bangle.on('lcdPower',function(on) { + if (animInterval) { + clearInterval(animInterval); + animInterval = undefined; + } + if (timeInterval) { + clearInterval(timeInterval); + timeInterval = undefined; + } + if (on) { + showTime(); + timeInterval = setInterval(showTime, 1000); + } +}); + +g.clear(); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +// Update time once a second +timeInterval = setInterval(showTime, 1000); +showTime(); + +// Show launcher when middle button pressed +setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"}); diff --git a/apps/setting/ChangeLog b/apps/setting/ChangeLog index 9263b3b13..f168a1fe5 100644 --- a/apps/setting/ChangeLog +++ b/apps/setting/ChangeLog @@ -20,3 +20,4 @@ 0.16: Reduce memory usage further when running app settings page 0.17: Remove need for "settings" in appid.info 0.18: Don't overwrite existing settings on app update +0.19: Allow BLE HID settings, add README.md diff --git a/apps/setting/README.md b/apps/setting/README.md new file mode 100644 index 000000000..4052da0ff --- /dev/null +++ b/apps/setting/README.md @@ -0,0 +1,18 @@ +# Settings + +This is Bangle.js's settings menu + +* **Make Connectable** regardless of the current Bluetooth settings, makes Bangle.js so you can connect to it (while the window is up) +* **App/Widget Settings** settings specific to installed applications +* **BLE** is Bluetooth LE enabled and the watch connectable? +* **Programmable** if BLE is on, can the watch be connected to in order to program/upload apps? +* **Debug Info** should debug info be shown on the watch's screen or not? +* **Beep** most Bangle.js do not have a speaker inside, but they can use the vibration motor to beep in different pitches. You can change the behaviour here to use a Piezo speaker if one is connected +* **Vibration** enable/disable the vibration motor +* **Locale** set time zone/whether the clock is 12/24 hour (for supported clocks) +* **Select Clock** if you have more than one clock face, select the default one +* **HID** When Bluetooth is enabled, Bangle.js can appear as a Bluetooth Keyboard/Joystick/etc to send keypresses to a connected device. **Note:** on some platforms enabling HID can cause you problems when trying to connect to Bangle.js to upload apps. +* **Set Time** Configure the current time - Note that this can be done much more easily by choosing 'Set Time' from the App Loader +* **LCD** Configure settings about the screen. How long it stays on, how bright it is, and when it turns on. +* **Reset Settings** Reset the settings to defaults +* **Turn Off** Turn Bangle.js off diff --git a/apps/setting/settings.js b/apps/setting/settings.js index 97ce464ad..328708d70 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -61,6 +61,8 @@ const boolFormat = v => v ? "On" : "Off"; function showMainMenu() { var beepV = [false, true, "vib"]; var beepN = ["Off", "Piezo", "Vibrate"]; + var hidV = [false, "kbmedia", "kb", "joy"]; + var hidN = ["Off", "Kbrd & Media", "Kbrd","Joystick"]; const mainmenu = { '': { 'title': 'Settings' }, 'Make Connectable': ()=>makeConnectable(), @@ -115,10 +117,10 @@ function showMainMenu() { 'Locale': ()=>showLocaleMenu(), 'Select Clock': ()=>showClockMenu(), 'HID': { - value: settings.HID, - format: boolFormat, - onchange: () => { - settings.HID = !settings.HID; + value: 0 | hidV.indexOf(settings.HID), + format: v => hidN[v], + onchange: v => { + settings.HID = hidV[v]; updateSettings(); } },