diff --git a/apps/btadv/app.js b/apps/btadv/app.js index fe6e05be6..e2c79490e 100644 --- a/apps/btadv/app.js +++ b/apps/btadv/app.js @@ -11,6 +11,8 @@ var __assign = (this && this.__assign) || function () { return __assign.apply(this, arguments); }; var Layout = require("Layout"); +Bangle.loadWidgets(); +Bangle.drawWidgets(); var services = ["0x180d", "0x181a", "0x1819"]; var acc; var bar; @@ -32,6 +34,7 @@ var idToName = { hrm: "HRM", mag: "Magnetometer", }; +var infoFont = "6x8:2"; var colour = { on: "#0f0", off: "#fff", @@ -88,129 +91,71 @@ var btnLayout = new Layout({ }); var setBtnsShown = function (b) { btnsShown = b; - g.clearRect(Bangle.appRect); redraw(); }; -var infoFont = "6x8:2"; -var infoCommon = { - type: "txt", - label: "", - font: infoFont, - pad: 5, -}; -var infoLayout = new Layout({ - type: "v", - c: [ - { - type: "h", - c: [ - __assign({ id: "bar_alti" }, infoCommon), - __assign({ id: "bar_pres" }, infoCommon), - __assign({ id: "bar_temp" }, infoCommon), - ] - }, - { - type: "h", - c: [ - __assign({ id: "gps_lat" }, infoCommon), - __assign({ id: "gps_lon" }, infoCommon), - __assign({ id: "gps_altitude" }, infoCommon), - __assign({ id: "gps_satellites" }, infoCommon), - __assign({ id: "gps_hdop" }, infoCommon), - ] - }, - { - type: "h", - c: [ - __assign({ id: "hrm_bpm" }, infoCommon), - __assign({ id: "hrm_confidence" }, infoCommon), - ] - }, - { - type: "h", - c: [ - __assign({ id: "mag_x" }, infoCommon), - __assign({ id: "mag_y" }, infoCommon), - __assign({ id: "mag_z" }, infoCommon), - __assign({ id: "mag_heading" }, infoCommon), - ] - }, - __assign({ type: "btn", label: "Set", cb: function () { - setBtnsShown(true); - } }, btnStyle), - ] -}, { - lazy: true, -}); -var showElem = function (layout, s) { - layout.label = s; - delete layout.height; -}; -var hideElem = function (layout) { - layout.height = 0; -}; -var populateInfo = function () { +var drawInfo = function () { + var _a = Bangle.appRect, y = _a.y, x = _a.x, w = _a.w; + var mid = x + w / 2; + var drawn = false; + g.reset() + .clearRect(Bangle.appRect) + .setFont(infoFont) + .setFontAlign(0, -1); if (bar) { - showElem(infoLayout["bar_alti"], "".concat(bar.altitude.toFixed(1), "m")); - showElem(infoLayout["bar_pres"], "".concat(bar.pressure.toFixed(1), "mbar")); - showElem(infoLayout["bar_temp"], "".concat(bar.temperature.toFixed(1), "C")); - } - else { - hideElem(infoLayout["bar_alti"]); - hideElem(infoLayout["bar_pres"]); - hideElem(infoLayout["bar_temp"]); + g.drawString("".concat(bar.altitude.toFixed(1), "m"), mid, y); + y += g.getFontHeight(); + g.drawString("".concat(bar.pressure.toFixed(1), "mbar"), mid, y); + y += g.getFontHeight(); + g.drawString("".concat(bar.temperature.toFixed(1), "C"), mid, y); + y += g.getFontHeight(); + drawn = true; } if (gps) { - showElem(infoLayout["gps_lat"], gps.lat.toFixed(4)); - showElem(infoLayout["gps_lon"], gps.lon.toFixed(4)); - showElem(infoLayout["gps_altitude"], "".concat(gps.alt, "m")); - showElem(infoLayout["gps_satellites"], "".concat(gps.satellites)); - showElem(infoLayout["gps_hdop"], "".concat((gps.hdop * 5).toFixed(1), "m")); - } - else { - hideElem(infoLayout["gps_lat"]); - hideElem(infoLayout["gps_lon"]); - hideElem(infoLayout["gps_altitude"]); - hideElem(infoLayout["gps_satellites"]); - hideElem(infoLayout["gps_hdop"]); + g.drawString("".concat(gps.lat.toFixed(4), " lat, ").concat(gps.lon.toFixed(4), " lon"), mid, y); + y += g.getFontHeight(); + g.drawString("".concat(gps.alt, "m (").concat(gps.satellites, " sat)"), mid, y); + y += g.getFontHeight(); + drawn = true; } if (hrm) { - showElem(infoLayout["hrm_bpm"], "".concat(hrm.bpm)); - showElem(infoLayout["hrm_confidence"], "".concat(hrm.confidence, "%")); - } - else { - hideElem(infoLayout["hrm_bpm"]); - hideElem(infoLayout["hrm_confidence"]); + g.drawString("".concat(hrm.bpm, " BPM (").concat(hrm.confidence, "%)"), mid, y); + y += g.getFontHeight(); + drawn = true; } if (mag) { - showElem(infoLayout["mag_x"], "".concat(mag.x)); - showElem(infoLayout["mag_y"], "".concat(mag.y)); - showElem(infoLayout["mag_z"], "".concat(mag.z)); - showElem(infoLayout["mag_heading"], mag.heading.toFixed(1)); + g.drawString("".concat(mag.x, " ").concat(mag.y, " ").concat(mag.z), mid, y); + y += g.getFontHeight(); + g.drawString("heading: ".concat(mag.heading.toFixed(1)), mid, y); + y += g.getFontHeight(); + drawn = true; } - else { - hideElem(infoLayout["mag_x"]); - hideElem(infoLayout["mag_y"]); - hideElem(infoLayout["mag_z"]); - hideElem(infoLayout["mag_heading"]); + if (!drawn) { + g.drawString("swipe to enable", mid, y); + y += g.getFontHeight(); } }; +var onTap = function (_) { + setBtnsShown(true); +}; var redraw = function () { - var layout; if (btnsShown) { - layout = btnLayout; + if (!prevBtnsShown) { + prevBtnsShown = btnsShown; + Bangle.removeListener("swipe", onTap); + btnLayout.setUI(); + btnLayout.forgetLazyState(); + g.clearRect(Bangle.appRect); + } + btnLayout.render(); } else { - populateInfo(); - infoLayout.update(); - layout = infoLayout; + if (prevBtnsShown) { + prevBtnsShown = btnsShown; + Bangle.setUI(); + Bangle.on("swipe", onTap); + } + drawInfo(); } - if (btnsShown !== prevBtnsShown) { - prevBtnsShown = btnsShown; - layout.forgetLazyState(); - layout.setUI(); - } - layout.render(); }; var encodeHrm = function (hrm) { return [0, hrm.bpm]; @@ -277,7 +222,7 @@ var enableSensors = function () { mag = undefined; console.log("enableSensors():", settings); }; -var serviceActive = function (serv) { +var haveServiceData = function (serv) { switch (serv) { case "0x180d": return !!hrm; case "0x181a": return !!(bar || mag); @@ -297,6 +242,7 @@ var serviceToAdvert = function (serv, initial) { }; if (hrm) { o.value = encodeHrm(hrm); + hrm = undefined; } return _a = {}, _a["0x2a37"] = o, _a; } @@ -310,6 +256,7 @@ var serviceToAdvert = function (serv, initial) { }; if (gps) { o.value = encodeGps(gps); + gps = undefined; } return _b = {}, _b["0x2a67"] = o, _b; } @@ -336,6 +283,7 @@ var serviceToAdvert = function (serv, initial) { o["0x2a6c"].value = encodeElevation(bar); o["0x2A1F"].value = encodeTemp(bar); o["0x2a6d"].value = encodePressure(bar); + bar = undefined; } } if (mag || initial) { @@ -346,6 +294,7 @@ var serviceToAdvert = function (serv, initial) { }; if (mag) { o["0x2aa1"].value = encodeMag(mag); + mag = undefined; } } return o; @@ -357,7 +306,7 @@ var getBleAdvert = function (map, all) { var advert = {}; for (var _i = 0, services_1 = services; _i < services_1.length; _i++) { var serv = services_1[_i]; - if (all || serviceActive(serv)) { + if (all || haveServiceData(serv)) { advert[serv] = map(serv); } } @@ -385,12 +334,10 @@ Bangle.on('pressure', function (newBar) { return bar = newBar; }); Bangle.on('GPS', function (newGps) { return gps = newGps; }); Bangle.on('HRM', function (newHrm) { return hrm = newHrm; }); Bangle.on('mag', function (newMag) { return mag = newMag; }); -Bangle.loadWidgets(); -Bangle.drawWidgets(); setBtnsShown(true); -var redrawInterval = setInterval(redraw, 1000); +var redrawInterval = setInterval(redraw, 2000); Bangle.on("lock", function (locked) { - changeInterval(redrawInterval, locked ? 30000 : 1000); + changeInterval(redrawInterval, locked ? 15000 : 2000); }); enableSensors(); { @@ -416,3 +363,10 @@ var setIntervals = function (connected) { iv = undefined; } }; +setIntervals(NRF.getSecurityStatus().connected); +NRF.on("connect", function () { + setIntervals(true); +}); +NRF.on("disconnect", function () { + setIntervals(false); +}); diff --git a/apps/btadv/app.ts b/apps/btadv/app.ts index 430127088..6a7435a3f 100644 --- a/apps/btadv/app.ts +++ b/apps/btadv/app.ts @@ -1,10 +1,13 @@ const Layout = require("Layout") as Layout_.Layout; +Bangle.loadWidgets(); +Bangle.drawWidgets(); + const enum Intervals { - BLE_ADVERT = 60 * 1000, + // BLE_ADVERT = 60 * 1000, BLE = 1000, - MENU_WAKE = 1000, - MENU_SLEEP = 30 * 1000, + MENU_WAKE = 2 * 1000, + MENU_SLEEP = 15 * 1000, } type Hrm = { bpm: number, confidence: number }; @@ -100,6 +103,8 @@ const idToName: BtAdvMap = { mag: "Magnetometer", }; +const infoFont: FontNameWithScaleFactor = "6x8:2"; + const colour = { on: "#0f0", off: "#fff", @@ -213,149 +218,107 @@ const btnLayout = new Layout( const setBtnsShown = (b: boolean) => { btnsShown = b; - g.clearRect(Bangle.appRect); redraw(); }; -const infoFont: FontNameWithScaleFactor = "6x8:2"; -const infoCommon = { - type: "txt", - label: "", - font: infoFont, - pad: 5, -} as const; +const drawInfo = () => { + let { y, x, w } = Bangle.appRect; + const mid = x + w / 2 + let drawn = false; -const infoLayout = new Layout( - { - type: "v", - c: [ - { - type: "h", - c: [ - { id: "bar_alti", ...infoCommon }, - { id: "bar_pres", ...infoCommon }, - { id: "bar_temp", ...infoCommon }, - ] - }, - { - type: "h", - c: [ - { id: "gps_lat", ...infoCommon }, - { id: "gps_lon", ...infoCommon }, - { id: "gps_altitude", ...infoCommon }, - { id: "gps_satellites", ...infoCommon }, - { id: "gps_hdop", ...infoCommon }, - ] - }, - { - type: "h", - c: [ - { id: "hrm_bpm", ...infoCommon }, - { id: "hrm_confidence", ...infoCommon }, - ] - }, - { - type: "h", - c: [ - { id: "mag_x", ...infoCommon }, - { id: "mag_y", ...infoCommon }, - { id: "mag_z", ...infoCommon }, - { id: "mag_heading", ...infoCommon }, - ] - }, - { - type: "btn", - label: "Set", - cb: () => { - setBtnsShown(true); - }, - ...btnStyle, - }, - ] - }, - { - lazy: true, - // back: () => (load as any)(), - } -); + g.reset() + .clearRect(Bangle.appRect) + .setFont(infoFont) + .setFontAlign(0, -1); -const showElem = ( - layout: Layout_.Hierarchy & { type: "txt" }, - s: string, -) => { - layout.label = s; - // delete layout.width; TODO? - delete layout.height; -}; - -const hideElem = (layout: Layout_.Hierarchy) => { - layout.height = 0; -}; - -const populateInfo = () => { if (bar) { - showElem(infoLayout["bar_alti"]!, `${bar.altitude.toFixed(1)}m`); - showElem(infoLayout["bar_pres"]!, `${bar.pressure.toFixed(1)}mbar`); - showElem(infoLayout["bar_temp"]!, `${bar.temperature.toFixed(1)}C`); - } else { - hideElem(infoLayout["bar_alti"]!); - hideElem(infoLayout["bar_pres"]!); - hideElem(infoLayout["bar_temp"]!); + g.drawString(`${bar.altitude.toFixed(1)}m`, mid, y); + y += g.getFontHeight(); + + g.drawString(`${bar.pressure.toFixed(1)}mbar`, mid, y); + y += g.getFontHeight(); + + g.drawString(`${bar.temperature.toFixed(1)}C`, mid, y); + y += g.getFontHeight(); + + drawn = true; } if (gps) { - showElem(infoLayout["gps_lat"]!, gps.lat.toFixed(4)); - showElem(infoLayout["gps_lon"]!, gps.lon.toFixed(4)); - showElem(infoLayout["gps_altitude"]!, `${gps.alt}m`); - showElem(infoLayout["gps_satellites"]!, `${gps.satellites}`); - showElem(infoLayout["gps_hdop"]!, `${(gps.hdop * 5).toFixed(1)}m`); - } else { - hideElem(infoLayout["gps_lat"]!); - hideElem(infoLayout["gps_lon"]!); - hideElem(infoLayout["gps_altitude"]!); - hideElem(infoLayout["gps_satellites"]!); - hideElem(infoLayout["gps_hdop"]!); + g.drawString( + `${gps.lat.toFixed(4)} lat, ${gps.lon.toFixed(4)} lon`, + mid, + y, + ); + y += g.getFontHeight(); + + g.drawString( + `${gps.alt}m (${gps.satellites} sat)`, + mid, + y, + ); + y += g.getFontHeight(); + + drawn = true; } if (hrm) { - showElem(infoLayout["hrm_bpm"]!, `${hrm.bpm}`); - showElem(infoLayout["hrm_confidence"]!, `${hrm.confidence}%`); - } else { - hideElem(infoLayout["hrm_bpm"]!); - hideElem(infoLayout["hrm_confidence"]!); + g.drawString(`${hrm.bpm} BPM (${hrm.confidence}%)`, mid, y); + y += g.getFontHeight(); + + drawn = true; } if (mag) { - showElem(infoLayout["mag_x"]!, `${mag.x}`); - showElem(infoLayout["mag_y"]!, `${mag.y}`); - showElem(infoLayout["mag_z"]!, `${mag.z}`); - showElem(infoLayout["mag_heading"]!, mag.heading.toFixed(1)); - } else { - hideElem(infoLayout["mag_x"]!); - hideElem(infoLayout["mag_y"]!); - hideElem(infoLayout["mag_z"]!); - hideElem(infoLayout["mag_heading"]!); + g.drawString( + `${mag.x} ${mag.y} ${mag.z}`, + mid, + y + ); + y += g.getFontHeight(); + + g.drawString( + `heading: ${mag.heading.toFixed(1)}`, + mid, + y + ); + y += g.getFontHeight(); + + drawn = true; + } + + if (!drawn) { + g.drawString(`swipe to enable`, mid, y); + y += g.getFontHeight(); } }; +const onTap = (_: { /* ... */ }) => { + setBtnsShown(true); +}; + const redraw = () => { - let layout; - if (btnsShown) { - layout = btnLayout; + if (!prevBtnsShown) { + prevBtnsShown = btnsShown; + + Bangle.removeListener("swipe", onTap); + + btnLayout.setUI(); + btnLayout.forgetLazyState(); + g.clearRect(Bangle.appRect); // in case btnLayout isn't full screen + } + + btnLayout.render(); } else { - populateInfo(); - infoLayout.update(); + if (prevBtnsShown) { + prevBtnsShown = btnsShown; - layout = infoLayout; + Bangle.setUI(); // remove all existing input handlers + Bangle.on("swipe", onTap); + } + drawInfo(); } - - if (btnsShown !== prevBtnsShown) { - prevBtnsShown = btnsShown; - layout.forgetLazyState(); - layout.setUI(); - } - layout.render(); }; const encodeHrm: LenFunc = (hrm: Hrm) => @@ -617,10 +580,6 @@ Bangle.on('GPS', newGps => gps = newGps); Bangle.on('HRM', newHrm => hrm = newHrm); Bangle.on('mag', newMag => mag = newMag); -// show UI -Bangle.loadWidgets(); -Bangle.drawWidgets(); - setBtnsShown(true); const redrawInterval = setInterval(redraw, Intervals.MENU_WAKE);