From a2002c48419b6b3b7c209b0e86fe6c75eed30373 Mon Sep 17 00:00:00 2001 From: storm64 Date: Wed, 6 Apr 2022 22:29:13 +0200 Subject: [PATCH 1/4] lightswitch: masking (espruino/Espruino#2151) + oversize Update ChangeLog and metadata.json Update README.md and settings.json - add oversize setting + description Update settings.js - add oversize setting Update widget.js - add oversize setting - add masking touch and drag input by adding own event listeners first and messing up the handler on a widget related event, using espruino/Espruino#2151 --- apps/lightswitch/ChangeLog | 1 + apps/lightswitch/README.md | 10 +++++++--- apps/lightswitch/metadata.json | 2 +- apps/lightswitch/settings.js | 16 +++++++++++++--- apps/lightswitch/settings.json | 8 ++++++-- apps/lightswitch/widget.js | 22 ++++++++++++++++------ 6 files changed, 44 insertions(+), 15 deletions(-) diff --git a/apps/lightswitch/ChangeLog b/apps/lightswitch/ChangeLog index 4210ccf03..2c6d2b5db 100644 --- a/apps/lightswitch/ChangeLog +++ b/apps/lightswitch/ChangeLog @@ -1,3 +1,4 @@ 0.01: New App! 0.02: Add the option to enable touching the widget only on clock and settings. 0.03: Settings page now uses built-in min/max/wrap (fix #1607) +0.04: Add masking widget input to other apps (using espruino/Espruino#2151), add a oversize option to increase the touch area. diff --git a/apps/lightswitch/README.md b/apps/lightswitch/README.md index d58de7ca4..67d070f5c 100644 --- a/apps/lightswitch/README.md +++ b/apps/lightswitch/README.md @@ -1,8 +1,11 @@ # Light Switch Widget -Whis this widget I wanted to create a solution to quickly en-/disable the LCD backlight and even change the brightness. +With this widget I wanted to create a solution to quickly en-/disable the LCD backlight and even change the brightness. In addition it shows the lock status with the option to personalize the lock icon with a tiny image. +All touch and drag inputs related to this widget are cached/masked to prevent actions in the active app. +(See [espruino/Espruino#2151](https://github.com/espruino/Espruino/issues/2151) for more information.) + --- ### Control --- @@ -39,6 +42,9 @@ In addition it shows the lock status with the option to personalize the lock ico * _clk+launch_ -> on all apps of the types _clock_ and _launch_ * _except apps_ -> on all apps of the types _clock_ and _launch_ and in the settings * _always on_ -> always enabled when the widget is displayed +* __Oversize__ + _0px_ / _1px_ / _..._ / __20px__ / _..._ / _50px_ + To make it easier to hit the widget, this value extends the touch area of the widget in all directions. * __Drag Delay__ _off_ / _50ms_ / _100ms_ / _..._ / __500ms__ / _..._ / _1000ms_ Change the maximum delay between first touch and re-touch/drag to change the brightness or disable changing the brightness completely. @@ -85,8 +91,6 @@ This images are stored in a seperate file _(lightswitch.images.json)_. ### Worth Mentioning --- #### To do list -* Catch the touch and draw input related to this widget to prevent actions in the active app. - _(For now I have no idea how to achieve this, help is appreciated)_ * Manage images for the lock icon through a _Customize and Upload App_ page. #### Requests, Bugs and Feedback diff --git a/apps/lightswitch/metadata.json b/apps/lightswitch/metadata.json index 9ac388eda..54dc8389f 100644 --- a/apps/lightswitch/metadata.json +++ b/apps/lightswitch/metadata.json @@ -2,7 +2,7 @@ "id": "lightswitch", "name": "Light Switch Widget", "shortName": "Light Switch", - "version": "0.03", + "version": "0.04", "description": "A fast way to switch LCD backlight on/off, change the brightness and show the lock status. All in one widget.", "icon": "images/app.png", "screenshots": [ diff --git a/apps/lightswitch/settings.js b/apps/lightswitch/settings.js index bebb16d15..a502324d9 100644 --- a/apps/lightswitch/settings.js +++ b/apps/lightswitch/settings.js @@ -7,6 +7,7 @@ colors: "011", image: "default", touchOn: "clock,launch", + oversize: 20, dragDelay: 500, minValue: 0.1, unlockSide: "", @@ -45,7 +46,7 @@ return { value: entry.value.indexOf(settings[key]), min : 0, - max : entry.value.length-1, + max : entry.value.length - 1, wrap : true, format: v => entry.title ? entry.title[v] : entry.value[v], onchange: function(v) { @@ -57,11 +58,11 @@ // return entry for numerical value return { value: settings[key] * entry.factor, - step: entry.step, - format: v => v > 0 ? v + entry.unit : "off", min : entry.min, max : entry.max, + step: entry.step, wrap : true, + format: v => v > 0 ? v + entry.unit : "off", onchange: function(v) { writeSetting(key, v / entry.factor, entry.drawWidgets); }, @@ -96,6 +97,14 @@ value: ["", "clock", "clock,setting.app.js", "clock,launch", "clock,setting.app.js,launch", "always"], drawWidgets: true }, + oversize: { + factor: 1, + unit: "px", + min: 0, + max: 50, + step: 1, + drawWidgets: true + }, dragDelay: { factor: 1, unit: "ms", @@ -142,6 +151,7 @@ "Image": getEntry("image"), "-- Control": 0, "Touch": getEntry("touchOn"), + "Oversize": getEntry("oversize"), "Drag Delay": getEntry("dragDelay"), "Min Value": getEntry("minValue"), "-- Unlock": 0, diff --git a/apps/lightswitch/settings.json b/apps/lightswitch/settings.json index 3d88e2282..176c3cea0 100644 --- a/apps/lightswitch/settings.json +++ b/apps/lightswitch/settings.json @@ -10,8 +10,8 @@ "101" -> magenta * image: string // - "default" -> - "random" -> + "default" -> image nearest to the default lock + "random" -> a random image from all available * touchOn: string // select when widget touch is active "" -> only on default clock @@ -19,6 +19,9 @@ "clock,launch" -> on all clocks and lanchers (default) "always" -> always + * oversize: int // extends the touch area of the widget in px in all directions + 0 to 50, 20 as default + * dragDelay: int // drag listener reset time in ms // time until a drag is needed to activate backlight changing mode 0 -> disabled @@ -59,6 +62,7 @@ "colors": "011", "image": "default", "touchOn": "clock,launch", + "oversize": 20, "dragDelay": 500, "minValue": 0.1, "unlockSide": "", diff --git a/apps/lightswitch/widget.js b/apps/lightswitch/widget.js index 119a114fe..53f86ee9a 100644 --- a/apps/lightswitch/widget.js +++ b/apps/lightswitch/widget.js @@ -4,6 +4,7 @@ colors: "011", image: "default", touchOn: "clock,launch", + oversize: 20, dragDelay: 500, minValue: 0.1, unlockSide: "", @@ -162,6 +163,11 @@ // change brigthness value, skip write to storage while still touching w.changeValue(value, event.b); + // masks this drag event by messing up the event handler + // see https://github.com/espruino/Espruino/issues/2151 + Bangle.removeListener("drag", w.dragListener); + Bangle["#ondrag"] = [w.dragListener].concat(Bangle["#ondrag"]); + // on touch release remove drag listener and reset drag status to indicate stopped drag action if (!event.b) { Bangle.removeListener("drag", w.dragListener); @@ -184,14 +190,14 @@ if (w.dragStatus === "off") { // check if inside widget area - if (!(!w || cursor.x < w.x || cursor.x > w.x + w.width || - cursor.y < w.y || cursor.y > w.y + 23)) { + if (!(!w || cursor.x < w.x - w.oversize || cursor.x > w.x + w.width + w.oversize || + cursor.y < w.y - w.oversize || cursor.y > w.y + 23 + w.oversize)) { // first touch feedback Bangle.buzz(25); // check if drag is disabled if (w.dragDelay) { - // add drag listener - Bangle.on("drag", w.dragListener); + // add drag listener at first position + Bangle["#ondrag"] = [w.dragListener].concat(Bangle["#ondrag"]); // set drag timeout w.dragStatus = setTimeout((w) => { // remove drag listener @@ -204,6 +210,10 @@ } // switch backlight w.changeValue(); + // masks this touch event by messing up the event handler + // see https://github.com/espruino/Espruino/issues/2151 + Bangle.removeListener("touch", w.touchListener); + Bangle["#ontouch"] = [w.touchListener].concat(Bangle["#ontouch"]); } } @@ -236,11 +246,11 @@ // add lock listener Bangle.on("lock", w.draw); - // add touch listener to control the light depending on settings + // add touch listener to control the light depending on settings at first position if (w.touchOn === "always" || !global.__FILE__ || w.touchOn.includes(__FILE__) || w.touchOn.includes(require("Storage").readJSON(__FILE__.replace("app.js", "info")).type)) - Bangle.on("touch", w.touchListener); + Bangle["#ontouch"] = [w.touchListener].concat(Bangle["#ontouch"]); // add tap listener to unlock and/or flash backlight if (w.unlockSide || w.tapSide) Bangle.on("tap", require("lightswitch.js").tapListener); From 6c6f9c01c7cbcf8cbeb5f3da9025b2c055f7b277 Mon Sep 17 00:00:00 2001 From: storm64 Date: Wed, 6 Apr 2022 23:40:50 +0200 Subject: [PATCH 2/4] lightswitch: Correct default touchOn Change settings.js and widget.js: - Correct default value of touchOn according to value in README.md --- apps/lightswitch/settings.js | 2 +- apps/lightswitch/widget.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/lightswitch/settings.js b/apps/lightswitch/settings.js index a502324d9..5ac70bc28 100644 --- a/apps/lightswitch/settings.js +++ b/apps/lightswitch/settings.js @@ -6,7 +6,7 @@ var settings = Object.assign({ colors: "011", image: "default", - touchOn: "clock,launch", + touchOn: "always", oversize: 20, dragDelay: 500, minValue: 0.1, diff --git a/apps/lightswitch/widget.js b/apps/lightswitch/widget.js index 53f86ee9a..829f75102 100644 --- a/apps/lightswitch/widget.js +++ b/apps/lightswitch/widget.js @@ -3,7 +3,7 @@ var settings = Object.assign({ colors: "011", image: "default", - touchOn: "clock,launch", + touchOn: "always", oversize: 20, dragDelay: 500, minValue: 0.1, From 80d35e4e33646a7395de1451c218b84cab081f63 Mon Sep 17 00:00:00 2001 From: storm64 Date: Thu, 7 Apr 2022 01:22:52 +0200 Subject: [PATCH 3/4] massages: Add option to disable icon flashing Update ChangeLog, metadata.json, README.md and settigns.js: - Add option to toggle icon flashing. Update widget.js: - Add option to toggle icon flashing. - Correct clearRect y2 value. - Moved icon 1px up to be more centered. --- apps/messages/ChangeLog | 1 + apps/messages/README.md | 1 + apps/messages/metadata.json | 2 +- apps/messages/settings.js | 6 ++++++ apps/messages/widget.js | 11 +++++++---- 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/apps/messages/ChangeLog b/apps/messages/ChangeLog index 092a38eb6..3e676c21e 100644 --- a/apps/messages/ChangeLog +++ b/apps/messages/ChangeLog @@ -43,3 +43,4 @@ 0.28: Option to auto-unlock the watch when a new message arrives 0.29: Fix message list overwrites on Bangle.js 1 (fix #1642) 0.30: Add new Icons (Youtube, Twitch, MS TODO, Teams, Snapchat, Signal, Post & DHL, Nina, Lieferando, Kalender, Discord, Corona Warn, Bibel) +0.31: Option to disable icon flashing diff --git a/apps/messages/README.md b/apps/messages/README.md index 780d8e50b..da2701f35 100644 --- a/apps/messages/README.md +++ b/apps/messages/README.md @@ -21,6 +21,7 @@ is chosen if there isn't much message text, but this specifies the smallest the it starts getting clipped. * `Auto-Open Music` - Should the app automatically open when the phone starts playing music? * `Unlock Watch` - Should the app unlock the watch when a new message arrives, so you can touch the buttons at the bottom of the app? +* `Flash Icon` - Toggle flashing of the widget icon. ## New Messages diff --git a/apps/messages/metadata.json b/apps/messages/metadata.json index dfeedaef7..5c1e67702 100644 --- a/apps/messages/metadata.json +++ b/apps/messages/metadata.json @@ -1,7 +1,7 @@ { "id": "messages", "name": "Messages", - "version": "0.30", + "version": "0.31", "description": "App to display notifications from iOS and Gadgetbridge/Android", "icon": "app.png", "type": "app", diff --git a/apps/messages/settings.js b/apps/messages/settings.js index 754347f19..cc0030ec5 100644 --- a/apps/messages/settings.js +++ b/apps/messages/settings.js @@ -7,6 +7,7 @@ settings.unlockWatch=!!settings.unlockWatch; settings.openMusic=!!settings.openMusic; settings.maxUnreadTimeout=240; + if (settings.flash===undefined) settings.flash=true; return settings; } function updateSetting(setting, value) { @@ -47,6 +48,11 @@ format: v => v?/*LANG*/'Yes':/*LANG*/'No', onchange: v => updateSetting("unlockWatch", v) }, + /*LANG*/'Flash Icon': { + value: !!settings().flash, + format: v => v?/*LANG*/'Yes':/*LANG*/'No', + onchange: v => updateSetting("flash", v) + }, }; E.showMenu(mainmenu); }) diff --git a/apps/messages/widget.js b/apps/messages/widget.js index 3ac726e77..4b368ffd6 100644 --- a/apps/messages/widget.js +++ b/apps/messages/widget.js @@ -1,5 +1,5 @@ WIDGETS["messages"]={area:"tl", width:0, iconwidth:24, -draw:function() { +draw:function(recall) { // If we had a setTimeout queued from the last time we were called, remove it if (WIDGETS["messages"].i) { clearTimeout(WIDGETS["messages"].i); @@ -8,15 +8,18 @@ draw:function() { Bangle.removeListener('touch', this.touch); if (!this.width) return; var c = (Date.now()-this.t)/1000; - g.reset().clearRect(this.x, this.y, this.x+this.width, this.y+this.iconwidth); - g.drawImage((c&1) ? atob("GBiBAAAAAAAAAAAAAAAAAAAAAB//+DAADDAADDAADDwAPD8A/DOBzDDn/DA//DAHvDAPvjAPvjAPvjAPvh///gf/vAAD+AAB8AAAAA==") : atob("GBiBAAAAAAAAAAAAAAAAAAAAAB//+D///D///A//8CP/xDj/HD48DD+B8D/D+D/3vD/vvj/vvj/vvj/vvh/v/gfnvAAD+AAB8AAAAA=="), this.x, this.y); let settings = require('Storage').readJSON("messages.settings.json", true) || {}; + if (settings.flash===undefined) settings.flash = true; + if (recall !== true || settings.flash) { + g.reset().clearRect(this.x, this.y, this.x+this.width, this.y+23); + g.drawImage(settings.flash && (c&1) ? atob("GBiBAAAAAAAAAAAAAAAAAAAAAB//+DAADDAADDAADDwAPD8A/DOBzDDn/DA//DAHvDAPvjAPvjAPvjAPvh///gf/vAAD+AAB8AAAAA==") : atob("GBiBAAAAAAAAAAAAAAAAAAAAAB//+D///D///A//8CP/xDj/HD48DD+B8D/D+D/3vD/vvj/vvj/vvj/vvh/v/gfnvAAD+AAB8AAAAA=="), this.x, this.y-1); + } if (settings.repeat===undefined) settings.repeat = 4; if (c<120 && (Date.now()-this.l)>settings.repeat*1000) { this.l = Date.now(); WIDGETS["messages"].buzz(); // buzz every 4 seconds } - WIDGETS["messages"].i=setTimeout(()=>WIDGETS["messages"].draw(), 1000); + WIDGETS["messages"].i=setTimeout(()=>WIDGETS["messages"].draw(true), 1000); if (process.env.HWVERSION>1) Bangle.on('touch', this.touch); },show:function(quiet) { WIDGETS["messages"].t=Date.now(); // first time From 1c93c4bd01b3b5e725487401eaebb701c5fd5f5d Mon Sep 17 00:00:00 2001 From: storm64 Date: Thu, 7 Apr 2022 01:28:15 +0200 Subject: [PATCH 4/4] Revert "massages: Add option to disable icon flashing" This reverts commit 80d35e4e33646a7395de1451c218b84cab081f63. --- apps/messages/ChangeLog | 1 - apps/messages/README.md | 1 - apps/messages/metadata.json | 2 +- apps/messages/settings.js | 6 ------ apps/messages/widget.js | 11 ++++------- 5 files changed, 5 insertions(+), 16 deletions(-) diff --git a/apps/messages/ChangeLog b/apps/messages/ChangeLog index 3e676c21e..092a38eb6 100644 --- a/apps/messages/ChangeLog +++ b/apps/messages/ChangeLog @@ -43,4 +43,3 @@ 0.28: Option to auto-unlock the watch when a new message arrives 0.29: Fix message list overwrites on Bangle.js 1 (fix #1642) 0.30: Add new Icons (Youtube, Twitch, MS TODO, Teams, Snapchat, Signal, Post & DHL, Nina, Lieferando, Kalender, Discord, Corona Warn, Bibel) -0.31: Option to disable icon flashing diff --git a/apps/messages/README.md b/apps/messages/README.md index da2701f35..780d8e50b 100644 --- a/apps/messages/README.md +++ b/apps/messages/README.md @@ -21,7 +21,6 @@ is chosen if there isn't much message text, but this specifies the smallest the it starts getting clipped. * `Auto-Open Music` - Should the app automatically open when the phone starts playing music? * `Unlock Watch` - Should the app unlock the watch when a new message arrives, so you can touch the buttons at the bottom of the app? -* `Flash Icon` - Toggle flashing of the widget icon. ## New Messages diff --git a/apps/messages/metadata.json b/apps/messages/metadata.json index 5c1e67702..dfeedaef7 100644 --- a/apps/messages/metadata.json +++ b/apps/messages/metadata.json @@ -1,7 +1,7 @@ { "id": "messages", "name": "Messages", - "version": "0.31", + "version": "0.30", "description": "App to display notifications from iOS and Gadgetbridge/Android", "icon": "app.png", "type": "app", diff --git a/apps/messages/settings.js b/apps/messages/settings.js index cc0030ec5..754347f19 100644 --- a/apps/messages/settings.js +++ b/apps/messages/settings.js @@ -7,7 +7,6 @@ settings.unlockWatch=!!settings.unlockWatch; settings.openMusic=!!settings.openMusic; settings.maxUnreadTimeout=240; - if (settings.flash===undefined) settings.flash=true; return settings; } function updateSetting(setting, value) { @@ -48,11 +47,6 @@ format: v => v?/*LANG*/'Yes':/*LANG*/'No', onchange: v => updateSetting("unlockWatch", v) }, - /*LANG*/'Flash Icon': { - value: !!settings().flash, - format: v => v?/*LANG*/'Yes':/*LANG*/'No', - onchange: v => updateSetting("flash", v) - }, }; E.showMenu(mainmenu); }) diff --git a/apps/messages/widget.js b/apps/messages/widget.js index 4b368ffd6..3ac726e77 100644 --- a/apps/messages/widget.js +++ b/apps/messages/widget.js @@ -1,5 +1,5 @@ WIDGETS["messages"]={area:"tl", width:0, iconwidth:24, -draw:function(recall) { +draw:function() { // If we had a setTimeout queued from the last time we were called, remove it if (WIDGETS["messages"].i) { clearTimeout(WIDGETS["messages"].i); @@ -8,18 +8,15 @@ draw:function(recall) { Bangle.removeListener('touch', this.touch); if (!this.width) return; var c = (Date.now()-this.t)/1000; + g.reset().clearRect(this.x, this.y, this.x+this.width, this.y+this.iconwidth); + g.drawImage((c&1) ? atob("GBiBAAAAAAAAAAAAAAAAAAAAAB//+DAADDAADDAADDwAPD8A/DOBzDDn/DA//DAHvDAPvjAPvjAPvjAPvh///gf/vAAD+AAB8AAAAA==") : atob("GBiBAAAAAAAAAAAAAAAAAAAAAB//+D///D///A//8CP/xDj/HD48DD+B8D/D+D/3vD/vvj/vvj/vvj/vvh/v/gfnvAAD+AAB8AAAAA=="), this.x, this.y); let settings = require('Storage').readJSON("messages.settings.json", true) || {}; - if (settings.flash===undefined) settings.flash = true; - if (recall !== true || settings.flash) { - g.reset().clearRect(this.x, this.y, this.x+this.width, this.y+23); - g.drawImage(settings.flash && (c&1) ? atob("GBiBAAAAAAAAAAAAAAAAAAAAAB//+DAADDAADDAADDwAPD8A/DOBzDDn/DA//DAHvDAPvjAPvjAPvjAPvh///gf/vAAD+AAB8AAAAA==") : atob("GBiBAAAAAAAAAAAAAAAAAAAAAB//+D///D///A//8CP/xDj/HD48DD+B8D/D+D/3vD/vvj/vvj/vvj/vvh/v/gfnvAAD+AAB8AAAAA=="), this.x, this.y-1); - } if (settings.repeat===undefined) settings.repeat = 4; if (c<120 && (Date.now()-this.l)>settings.repeat*1000) { this.l = Date.now(); WIDGETS["messages"].buzz(); // buzz every 4 seconds } - WIDGETS["messages"].i=setTimeout(()=>WIDGETS["messages"].draw(true), 1000); + WIDGETS["messages"].i=setTimeout(()=>WIDGETS["messages"].draw(), 1000); if (process.env.HWVERSION>1) Bangle.on('touch', this.touch); },show:function(quiet) { WIDGETS["messages"].t=Date.now(); // first time