Skip to content

Commit

Permalink
Bangle.js2: Bangle.setLCDOverlay can now take an object with {id:str,…
Browse files Browse the repository at this point in the history
… onRemove:fn} to deal with multiple users of overlays better

espruino/BangleApps#3417
  • Loading branch information
gfwilliams committed May 17, 2024
1 parent e3e68c7 commit 1c94d85
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 8 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
- also speed up ObjectGetInteger by not requiring a new var to be allocated to unpack a NAME_INT
jsvSkipName speed improvements by avoiding repeated masking of flags
No longer call jsvKill/Init when resetting, but just jsvReset (this avoids free+malloc on ESP32)
Bangle.js2: Bangle.setLCDOverlay can now take an object with {id:str, onRemove:fn} to deal with multiple users of overlays better

2v21 : nRF52: free up 800b more flash by removing vector table padding
Throw Exception when a Promise tries to resolve with another Promise (#2450)
Expand Down
60 changes: 53 additions & 7 deletions libs/banglejs/jswrap_bangle.c
Original file line number Diff line number Diff line change
Expand Up @@ -2403,13 +2403,16 @@ void jswrap_banglejs_setLCDOffset(int y) {
"generate" : "jswrap_banglejs_setLCDOverlay",
"params" : [
["img","JsVar","An image, or undefined to clear"],
["x","int","The X offset the graphics instance should be overlaid on the screen with"],
["y","int","The Y offset the graphics instance should be overlaid on the screen with"]
["x","JsVar","The X offset the graphics instance should be overlaid on the screen with"],
["y","int","The Y offset the graphics instance should be overlaid on the screen with"],
["options","JsVar","[Optional] object `{onRemove:fn, id:\"str\"}`"]
],
"#if" : "defined(BANGLEJS_Q3) || defined(DICKENS)",
"typescript" : [
"setLCDOverlay(img: any, x: number, y: number): void;",
"setLCDOverlay(): void;"
"setLCDOverlay(): void;",
"setLCDOverlay(img: any, x: number, y: number, options: { id : string, onRemove: () => void }): void;",
"setLCDOverlay(img: any, options: { id : string }}): void;"
]
}
Overlay an image or graphics instance on top of the contents of the graphics buffer.
Expand All @@ -2432,7 +2435,7 @@ Or use a `Graphics` instance:
var ovr = Graphics.createArrayBuffer(100,100,1,{msb:true}); // 1bpp
ovr.drawLine(0,0,100,100);
ovr.drawRect(0,0,99,99);
Bangle.setLCDOverlay(ovr,38,38);
Bangle.setLCDOverlay(ovr,38,38, {id: "myOverlay"});
```
Although `Graphics` can be specified directly, it can often make more sense to
Expand All @@ -2450,10 +2453,53 @@ Bangle.setLCDOverlay({
bpp:2, transparent:0,
palette:new Uint16Array([0,0,g.toColor("#F00"),g.toColor("#FFF")]),
buffer:ovr.buffer
},38,38);
},38,38, {id: "myOverlay", onRemove: () => print("Removed")});
```
To remove an overlay, simply call:
```
Bangle.setLCDOverlay(undefined, {id: "myOverlay"});
```
Before 2v22 the `options` object isn't parsed, and as a result
the remove callback won't be called, and `Bangle.setLCDOverlay(undefined)` will
remove *any* active overlay.
*/
void jswrap_banglejs_setLCDOverlay(JsVar *imgVar, int x, int y) {
void jswrap_banglejs_setLCDOverlay(JsVar *imgVar, JsVar *xv, int y, JsVar *options) {
bool removingOverlay = jsvIsUndefined(imgVar);
int x = jsvGetInteger(xv);
if (removingOverlay) // handle Bangle.setLCDOverlay(undefined, {id: "myOverlay"});
options = xv;
JsVar *id = 0;
if (jsvIsObject(options)) {
id = jsvObjectGetChildIfExists(options, "id");
}
JsVar *ovrId = jsvObjectGetChildIfExists(execInfo.hiddenRoot, "lcdOvrId");
// if we are removing overlay, and supplied an ID, and it's different to the current one, don't do anything
if (removingOverlay && id && !jsvIsEqual(id, ovrId)) {
jsvUnLock2(ovrId, id);
return;
}
jsvUnLock(ovrId);
// We're definitely changing overlay now... run the remove callback if it exists
JsVar *removeCb = jsvObjectGetChildIfExists(execInfo.hiddenRoot, "lcdOvrCb");
if (removeCb) {
jsiQueueEvents(0, removeCb, NULL, 0);
jsvUnLock(removeCb);
}
// update the fields in the Bangle object
if (imgVar) {
jsvObjectSetOrRemoveChild(execInfo.hiddenRoot, "lcdOvrId", id);
removeCb = jsvIsObject(options) ? jsvObjectGetChildIfExists(options, "onRemove") : NULL;
jsvObjectSetOrRemoveChild(execInfo.hiddenRoot, "lcdOvrCb", removeCb);
jsvUnLock(removeCb);
} else { // we're removing the overlay, remove all callbacks
jsvObjectRemoveChild(execInfo.hiddenRoot, "lcdOvrId");
jsvObjectRemoveChild(execInfo.hiddenRoot, "lcdOvrCb");
}
jsvUnLock(id);
// Send the command to the LCD
#ifdef LCD_CONTROLLER_LPM013M126
lcdMemLCD_setOverlay(imgVar, x, y);
#endif
Expand Down Expand Up @@ -2835,7 +2881,7 @@ void _jswrap_banglejs_setLocked(bool isLocked, const char *reason) {
}
#endif
if ((bangleFlags&JSBF_LOCKED) != isLocked) {
JsVar *bangle =jsvObjectGetChildIfExists(execInfo.root, "Bangle");
JsVar *bangle = jsvObjectGetChildIfExists(execInfo.root, "Bangle");
if (bangle) {
JsVar *v[2] = {
jsvNewFromBool(isLocked),
Expand Down
2 changes: 1 addition & 1 deletion libs/banglejs/jswrap_bangle.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ void jswrap_banglejs_setLCDBrightness(JsVarFloat v);
void jswrap_banglejs_setLCDMode(JsVar *mode);
JsVar *jswrap_banglejs_getLCDMode();
void jswrap_banglejs_setLCDOffset(int y);
void jswrap_banglejs_setLCDOverlay(JsVar *imgVar, int x, int y);
void jswrap_banglejs_setLCDOverlay(JsVar *imgVar, JsVar *xv, int y, JsVar *options);
void jswrap_banglejs_setLCDTimeout(JsVarFloat timeout);
int jswrap_banglejs_isLCDOn();
int jswrap_banglejs_isBacklightOn();
Expand Down

0 comments on commit 1c94d85

Please sign in to comment.