From 98ecd6c9c770ddadafbb5e2a97a94edcfd738414 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 3 Nov 2023 15:20:03 +0100 Subject: [PATCH 01/14] tetris: implement level/mode selection Implement level selection, and allow user to slect controls. --- apps/tetris/ChangeLog | 1 + apps/tetris/metadata.json | 2 +- apps/tetris/tetris.app.js | 141 ++++++++++++++++++++++++++++++++------ 3 files changed, 121 insertions(+), 23 deletions(-) diff --git a/apps/tetris/ChangeLog b/apps/tetris/ChangeLog index 6366af6c0..aae9b12d7 100644 --- a/apps/tetris/ChangeLog +++ b/apps/tetris/ChangeLog @@ -1,2 +1,3 @@ 0.01: New app! 0.02: Better controls, implement game over. +0.03: Implement mode and level selection screens. diff --git a/apps/tetris/metadata.json b/apps/tetris/metadata.json index f10c06c54..f0a7fd9ab 100644 --- a/apps/tetris/metadata.json +++ b/apps/tetris/metadata.json @@ -1,7 +1,7 @@ { "id": "tetris", "name": "Tetris", "shortName":"Tetris", - "version":"0.02", + "version":"0.03", "description": "Tetris", "icon": "tetris.png", "readme": "README.md", diff --git a/apps/tetris/tetris.app.js b/apps/tetris/tetris.app.js index 77c40de9a..ac9954093 100644 --- a/apps/tetris/tetris.app.js +++ b/apps/tetris/tetris.app.js @@ -36,11 +36,27 @@ const tiles = [ const ox = 176/2 - 5*8; const oy = 8; -var pf = Array(23).fill().map(()=>Array(12).fill(0)); // field is really 10x20, but adding a border for collision checks -pf[20].fill(1); -pf[21].fill(1); -pf[22].fill(1); -pf.forEach((x,i) => { pf[i][0] = 1; pf[i][11] = 1; }); +/* 0 .. simulated arrows + 1 .. drag piece + 2 .. accelerometer. 12 lines record. + 3 .. altimeter + */ +var control = 0, level = 0; +var alt_start = -9999; /* For altimeter control */ +/* 0 .. menu + 1 .. game + 2 .. game over */ +var state = 0; + +var pf; + +function initGame() { + pf = Array(23).fill().map(()=>Array(12).fill(0)); // field is really 10x20, but adding a border for collision checks + pf[20].fill(1); + pf[21].fill(1); + pf[22].fill(1); + pf.forEach((x,i) => { pf[i][0] = 1; pf[i][11] = 1; }); +} function rotateTile(t, r) { var nt = JSON.parse(JSON.stringify(t)); @@ -98,6 +114,8 @@ function redrawPF(ly) { function gameOver() { g.setColor(1, 1, 1).setFontAlign(0, 1, 0).setFont("Vector",22) .drawString("Game Over", 176/2, 76); + state = 0; + E.showAlert("Game Over").then(selectGame, print); } function insertAndCheck() { @@ -138,6 +156,8 @@ function moveOk(t, dx, dy) { } function gameStep() { + if (state != 1) + return; if (Date.now()-time > dropInterval) { // drop one step time = Date.now(); if (moveOk(ct, 0, 1)) { @@ -169,12 +189,50 @@ function move(x, y) { } } -Bangle.setUI(); -Bangle.on("drag", (e) => { - let h = 176/2; - if (!e.b) +function linear(x) { + print("Linear: ", x); + let now = px / 10; + if (x < now-0.06) + move(-1, 0); + if (x > now+0.06) + move(1, 0); +} + +function newGame() { + E.showMenu(); + Bangle.setUI(); + if (control == 2) { + Bangle.on("accel", (e) => { + if (state != 1) return; + if (control != 2) return; + print(e.x); + linear((0.2-e.x) * 2.5); + }); + } + if (control == 3) { + Bangle.setBarometerPower(true); + Bangle.on("pressure", (e) => { + if (state != 1) return; + if (control != 3) return; + let a = e.altitude; + if (alt_start == -9999) + alt_start = a; + a = a - alt_start; + print(e.altitude, a); + linear(a); + }); + } + Bangle.on("drag", (e) => { + let h = 176/2; + if (state == 2) { + if (e.b) + selectGame(); + return; + } + if (!e.b) return; - if (e.y < h) { + if (state == 0) return; + if (e.y < h) { if (e.x < h) rotate(); else { @@ -184,21 +242,60 @@ Bangle.on("drag", (e) => { g.flip(); } } - } else { + } else { + if (control == 1) + linear((e.x - 20) / 156); + if (control != 0) + return; if (e.x < h) move(-1, 0); else move(1, 0); - } -}); + } + }); -Bangle.on("swipe", (x,y) => { - if (y<0) y = 0; - move(x, y); -}); + initGame(); + drawGame(); + state = 1; + var step = 450 - 50*level; + if (control == 3) + step = step*2; + dropInterval = step; + var gi = setInterval(gameStep, 50); +} -drawBoundingBox(); -g.setColor(1, 1, 1).setFontAlign(0, 1, 0).setFont("6x15", 1).drawString("Lines", 22, 30).drawString("Next", 176-22, 30); -showNext(ntn, ntr); -g.setColor(0).fillRect(5, 30, 41, 80).setColor(1, 1, 1).drawString(nlines.toString(), 22, 50); -var gi = setInterval(gameStep, 20); +function drawGame() { + drawBoundingBox(); + g.setColor(1, 1, 1).setFontAlign(0, 1, 0) + .setFont("6x15", 1).drawString("Lines", 22, 30) + .drawString("Next", 176-22, 30); + showNext(ntn, ntr); + g.setColor(0).fillRect(5, 30, 41, 80) + .setColor(1, 1, 1).drawString(nlines.toString(), 22, 50); +} + +function selectLevel() { + print("Level selection menu"); + + var menu = {}; + menu["Level 1"] = () => { level = 0; selectGame(); }; + menu["Level 2"] = () => { level = 1; selectGame(); }; + menu["Level 3"] = () => { level = 2; selectGame(); }; + E.showMenu(menu); +} + +function selectGame() { + state = 0; + print("Game selection menu"); + //for (let i = 0; i < 100000; i++) ; + + var menu = {}; + menu["Normal"] = () => { control = 0; newGame(); }; + menu["Drag"] = () => { control = 1; newGame(); }; + menu["Tilt"] = () => { control = 2; newGame(); }; + menu["Move"] = () => { control = 3; newGame(); }; + menu["Level"] = () => { selectLevel(); }; + E.showMenu(menu); +} + +selectGame(); From 0bc7cb491891853c89cb5b5ecebf343173bac1e3 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sat, 28 Oct 2023 11:36:34 +0200 Subject: [PATCH 02/14] stacker: Add documentation, allow on emulator. --- apps/stacker/README.md | 3 ++- apps/stacker/metadata.json | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/stacker/README.md b/apps/stacker/README.md index 5be5b7bee..e1019f970 100644 --- a/apps/stacker/README.md +++ b/apps/stacker/README.md @@ -5,7 +5,8 @@ A simple game of stacking cubes. ## Usage -Press the button to stack! +Boxes move horizontally. Use button to stack them on top of existing +boxes. You win when you reach top of the screen. ## Creator diff --git a/apps/stacker/metadata.json b/apps/stacker/metadata.json index abaf49a6d..3516625a1 100644 --- a/apps/stacker/metadata.json +++ b/apps/stacker/metadata.json @@ -6,6 +6,7 @@ "icon": "app.png", "tags": "game", "supports" : ["BANGLEJS", "BANGLEJS2"], + "allow_emulator": true, "readme": "README.md", "storage": [ {"name":"stacker.app.js","url":"app.js"}, From 4ca2f69e9903a42924c4916974f6a63bc0b458b4 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Thu, 12 Oct 2023 14:22:43 +0200 Subject: [PATCH 03/14] [] sixths: Implemented compass / navigating back to waypoints. These are summary changes from devel_clock branch. --- apps/sixths/README.md | 8 +- apps/sixths/app.js | 450 +++++++++++++++++++++++++++----------- apps/sixths/metadata.json | 3 +- 3 files changed, 335 insertions(+), 126 deletions(-) diff --git a/apps/sixths/README.md b/apps/sixths/README.md index e5d76d5ad..18f6bdf99 100644 --- a/apps/sixths/README.md +++ b/apps/sixths/README.md @@ -48,4 +48,10 @@ night. I'd like to make display nicer, and likely more dynamic, displaying whatever application believes is most important at the time (and -possibly allowing scrolling). \ No newline at end of file +possibly allowing scrolling). + +Todo: + +*) only turn on compass when needed + +*) adjust draw timeouts to save power \ No newline at end of file diff --git a/apps/sixths/app.js b/apps/sixths/app.js index ce036f79d..40a35590d 100644 --- a/apps/sixths/app.js +++ b/apps/sixths/app.js @@ -1,20 +1,45 @@ +// Sixth sense + +// Options you'll want to edit +const rest_altitude = 354; +const geoid_to_sea_level = 0; // Maybe BangleJS2 already compensates? + const W = g.getWidth(); const H = g.getHeight(); var cx = 100; cy = 105; sc = 70; -var buzz = "", msg = ""; temp = 0; alt = 0; bpm = 0; -var buzz = "", msg = "", inm = "", l = "", note = "(NOTEHERE)"; -var mode = 0, mode_time = 0; // 0 .. normal, 1 .. note +var buzz = "", /* Set this to transmit morse via vibrations */ + inm = "", l = "", /* For incoming morse handling */ + in_str = "", + note = "(NOTEHERE)", + debug = "v930", debug2 = "(otherdb)", debug3 = "(short)"; +var mode = 0, mode_time = 0; // 0 .. normal, 1 .. note, 2.. mark name +var disp_mode = 0; // 0 .. normal, 1 .. small time -var gps_on = 0, last_fix = 0, last_restart = 0, last_pause = 0, last_fstart = 0; // utime -var gps_needed = 0, gps_limit = 0; // seconds +// GPS handling +var gps_on = 0, // time GPS was turned on + last_fix = 0, // time of last fix + last_restart = 0, last_pause = 0, last_fstart = 0; // utime +var gps_needed = 0, // how long to wait for a fix + gps_limit = 0, // timeout -- when to stop recording + gps_speed_limit = 0; var prev_fix = null; var gps_dist = 0; -var is_active = false; -var cur_altitude = 0, cur_temperature = 0, alt_adjust = 0; -const rest_altitude = 354; +var mark_heading = -1; + +// Is the human present? +var is_active = false, last_active = getTime(); +var is_level = false; + +// For altitude handling. +var cur_altitude = 0; +var cur_temperature = 0, alt_adjust = 0; +var alt_adjust_mode = ""; + +// Marks +var cur_mark = null; function toMorse(x) { r = ""; @@ -28,12 +53,10 @@ function toMorse(x) { } return r; } - function aload(s) { buzz += toMorse(' E'); load(s); } - function gpsRestart() { print("gpsRestart"); Bangle.setGPSPower(1, "sixths"); @@ -41,33 +64,154 @@ function gpsRestart() { last_pause = 0; last_fstart = 0; } - function gpsPause() { print("gpsPause"); Bangle.setGPSPower(0, "sixths"); last_restart = 0; last_pause = getTime(); } - function gpsOn() { gps_on = getTime(); gps_needed = 1000; - gps_limit = 60*60*4; last_fix = 0; prev_fix = null; gps_dist = 0; gpsRestart(); } - function gpsOff() { Bangle.setGPSPower(0, "sixths"); gps_on = 0; } +function fmtDist(km) { return km.toFixed(1) + "km"; } +function fmtSteps(n) { return fmtDist(0.001 * 0.719 * n); } +function fmtTimeDiff(d) { + if (d < 180) + return ""+d.toFixed(0); + d = d/60; + return ""+d.toFixed(0)+"m"; +} +function gpsHandleFix(fix) { + if (!prev_fix) { + show("GPS acquired", 10); + buzz += " ."; + prev_fix = fix; + } + if (0) { + /* GPS altitude fluctuates a lot, not really usable */ + alt_adjust = cur_altitude - (fix.alt + geoid_to_sea_level); + alt_adjust_mode = "g"; + } + if (1) { + debug = ""+fix.alt+"m "+alt_adjust; + } + if (1) { + let now1 = Date(); + let now2 = fix.time; + n1 = now1.getMinutes() * 60 + now1.getSeconds(); + n2 = now2.getMinutes() * 60 + now2.getSeconds(); + debug2 = "te "+(n2-n1)+"s"; + } + loggps(fix); + d = calcDistance(fix, prev_fix); + if (d > 30) { + prev_fix = fix; + gps_dist += d/1000; + } +} +function gpsHandle() { + let msg = ""; + if (!last_restart) { + d = (getTime()-last_pause); + if (last_fix) + msg = "PL"+ fmtTimeDiff(getTime()-last_fix); + else + msg = "PN"+ fmtTimeDiff(getTime()-gps_on); + print("gps on, paused ", d, gps_needed); + if (d > gps_needed * 2) { + gpsRestart(); + } + } else { + fix = Bangle.getGPSFix(); + if (fix && fix.fix && fix.lat) { + gpsHandleFix(fix); + msg = fix.speed.toFixed(1) + " km/h"; + print("GPS FIX", msg); + + if (!last_fstart) + last_fstart = getTime(); + last_fix = getTime(); + gps_needed = 60; + } else { + if (last_fix) + msg = "L"+ fmtTimeDiff(getTime()-last_fix); + else { + msg = "N"+ fmtTimeDiff(getTime()-gps_on); + if (fix) { + msg += " " + fix.satellites + "sats"; + } + } + } + + d = (getTime()-last_restart); + d2 = (getTime()-last_fstart); + print("gps on, restarted ", d, gps_needed, d2, fix.lat); + if (getTime() > gps_speed_limit && + (d > gps_needed || (last_fstart && d2 > 10))) { + gpsPause(); + gps_needed = gps_needed * 1.5; + print("Pausing, next try", gps_needed); + } + } + msg += " "+gps_dist.toFixed(1)+"km"; + return msg; +} +function markNew() { + let r = {}; + r.time = getTime(); + r.fix = prev_fix; + r.steps = Bangle.getHealthStatus("day").steps; + r.gps_dist = gps_dist; + r.altitude = cur_altitude; + r.name = "auto"; + return r; +} +function markHandle() { + let m = cur_mark; + msg = m.name + ">" + fmtTimeDiff(getTime()- m.time); + if (m.fix && m.fix.fix) { + let s = fmtDist(calcDistance(m.fix, prev_fix)/1000) + "km"; + msg += " " + s; + debug = "wp>" + s; + mark_heading = 180 + calcBearing(m.fix, prev_fix); + debug2 = "wp>" + mark_heading; + } else { + msg += " w" + fmtDist(gps_dist - m.gps_dist); + } + return msg; +} +function entryDone() { + show(":" + in_str); + buzz += " ."; + switch (mode) { + case 1: logstamp(">" + in_str); break; + case 2: cur_mark.name = in_str; break; + } + in_str = 0; + mode = 0; +} function inputHandler(s) { - print("Ascii: ", s); - if (mode == 1) { - note = note + s; + print("Ascii: ", s, s[0], s[1]); + if (s[0] == '^') { + switch (s[1]) { + case 'E': mode = 0; break; + case 'T': entryDone(); break; + } + return; + } + if ((mode == 1) || (mode == 2)){ + in_str = in_str + s; + show(">"+in_str, 10); mode_time = getTime(); return; } @@ -80,12 +224,21 @@ function inputHandler(s) { else s = s+(bat/5); buzz += toMorse(s); + show("Bat "+bat+"%", 60); + break; + case 'F': gpsOff(); show("GPS off", 3); break; + case 'G': gpsOn(); gps_limit = getTime() + 60*60*4; show("GPS on", 3); break; + case 'I': + disp_mode += 1; + if (disp_mode == 2) { + disp_mode = 0; + } break; - case 'F': gpsOff(); break; - case 'G': gpsOn(); break; case 'L': aload("altimeter.app.js"); break; - case 'N': mode = 1; note = ">"; mode_time = getTime(); break; + case 'M': mode = 2; show("M>", 10); cur_mark = markNew(); mode_time = getTime(); break; + case 'N': mode = 1; show(">", 10); mode_time = getTime(); break; case 'O': aload("orloj.app.js"); break; + case 'S': gpsOn(); gps_limit = getTime() + 60*30; gps_speed_limit = gps_limit; show("GPS on", 3); break; case 'T': s = ' T'; d = new Date(); @@ -94,9 +247,9 @@ function inputHandler(s) { buzz += toMorse(s); break; case 'R': aload("run.app.js"); break; + case 'Y': buzz += " ."; Bangle.resetCompass(); break; } } - const morseDict = { '.-': 'A', '-...': 'B', @@ -135,37 +288,46 @@ const morseDict = { '-....': '6', '-----': '0', }; - let asciiDict = {}; - for (let k in morseDict) { print(k, morseDict[k]); asciiDict[morseDict[k]] = k; } - - function morseToAscii(morse) { return morseDict[morse]; } - function asciiToMorse(char) { return asciiDict[char]; } - function morseHandler() { - inputHandler(morseToAscii(inm)); + if (inm[0] == "^") { + inputHandler("^"+morseToAscii(inm.substr(1))); + } else { + inputHandler(morseToAscii(inm)); + } + inm = ""; l = ""; } - function touchHandler(d) { let x = Math.floor(d.x); let y = Math.floor(d.y); - g.setColor(0.25, 0, 0); - g.fillCircle(W-x, W-y, 5); - - if (d.b) { + if (1) { /* Just a debugging feature */ + g.setColor(0.25, 0, 0); + if (0) + g.fillCircle(W-x, W-y, 5); + else + g.fillCircle(x, y, 5); + } + if (!d.b) { + morseHandler(); + l = ""; + return; + } + if (y > H/2 && l == "") { + inm = "^"; + } if (x < W/2 && y < H/2 && l != ".u") { inm = inm + "."; l = ".u"; @@ -181,14 +343,10 @@ function touchHandler(d) { if (x > W/2 && y > H/2 && l != "-d") { inm = inm + "-"; l = "-d"; - } + } - } else - morseHandler(); - - print(inm, "drag:", d); + //print(inm, "drag:", d); } - function add0(i) { if (i > 9) { return ""+i; @@ -196,18 +354,14 @@ function add0(i) { return "0"+i; } } - var lastHour = -1, lastMin = -1; - function logstamp(s) { logfile.write("utime=" + getTime() + " " + s + "\n"); } - function loggps(fix) { logfile.write(fix.lat + " " + fix.lon + " "); logstamp(""); } - function hourly() { print("hourly"); s = ' T'; @@ -215,31 +369,35 @@ function hourly() { buzz += toMorse(s); logstamp(""); } - +function show(msg, timeout) { + note = msg; +} function fivemin() { print("fivemin"); s = ' B'; bat = E.getBattery(); - if (bat < 45) { - s = s+(bat/5); + if (bat < 25) { if (is_active) buzz += toMorse(s); + show("Bat "+bat+"%", 60); } - if (0) + try { Bangle.getPressure().then((x) => { cur_altitude = x.altitude; cur_temperature = x.temperature; }, - print) - .catch(print); + print); + } catch (e) { + print("Altimeter error", e); + } + } - function every(now) { - if ((mode > 0) && (mode_time - getTime() > 60)) { + if ((mode > 0) && (getTime() - mode_time > 10)) { if (mode == 1) { - logstamp(">" + note); + entryDone(); } mode = 0; } - if (gps_on && getTime() - gps_on > gps_limit) { + if (gps_on && getTime() > gps_limit && getTime() > gps_speed_limit) { Bangle.setGPSPower(0, "sixths"); gps_on = 0; } @@ -255,96 +413,136 @@ function every(now) { } +function radians(a) { return a*Math.PI/180; } +function degrees(a) { return a*180/Math.PI; } // distance between 2 lat and lons, in meters, Mean Earth Radius = 6371km // https://www.movable-type.co.uk/scripts/latlong.html // (Equirectangular approximation) function calcDistance(a,b) { - function radians(a) { return a*Math.PI/180; } var x = radians(b.lon-a.lon) * Math.cos(radians((a.lat+b.lat)/2)); var y = radians(b.lat-a.lat); return Math.sqrt(x*x + y*y) * 6371000; } +// thanks to waypointer +function calcBearing(a,b){ + var delta = radians(b.lon-a.lon); + var alat = radians(a.lat); + var blat = radians(b.lat); + var y = Math.sin(delta) * Math.cos(blat); + var x = Math.cos(alat)*Math.sin(blat) - + Math.sin(alat)*Math.cos(blat)*Math.cos(delta); + return Math.round(degrees(Math.atan2(y, x))); +} +function testBearing() { + let p1 = {}, p2 = {}; + p1.lat = 40; p2.lat = 50; + p1.lon = 14; p2.lon = 14; + print("bearing = ", calcBearing(p1, p2)); +} +function radA(p) { return p*(Math.PI*2); } +function radD(d) { return d*(H/2); } +function radX(p, d) { + let a = radA(p); + return H/2 + Math.sin(a)*radD(d); +} +function radY(p, d) { + let a = radA(p); + return W/2 - Math.cos(a)*radD(d); +} +function drawDot(h, d, s) { + let x = radX(h/360, d); + let y = radY(h/360, d); + g.fillCircle(x,y, 10); +} +function drawBackground() { + acc = Bangle.getAccel(); + is_level = (acc.z < -0.95); + if (is_level) { + let obj = Bangle.getCompass(); + if (obj) { + let h = 360-obj.heading; + print("Compass", h); + g.setColor(0.5, 0.5, 1); + drawDot(h, 0.7, 10); + } + } + if (prev_fix && prev_fix.fix) { + g.setColor(0.5, 1, 0.5); + drawDot(prev_fix.course, 0.5, 6); + } + if (mark_heading != -1) { + g.setColor(1, 0.5, 0.5); + drawDot(mark_heading, 0.6, 8); + } +} +function drawTime(now) { + if (disp_mode == 0) + g.setFont('Vector', 60); + else + g.setFont('Vector', 26); + g.setFontAlign(1, 1); + g.drawString(now.getHours() + ":" + add0(now.getMinutes()), W, 90); +} function draw() { + if (disp_mode == 2) { + draw_all(); + return; + } g.setColor(1, 1, 1); - g.fillRect(0, 25, W, H); - g.setFont('Vector', 60); + g.fillRect(0, 24, W, H); + + if (0) { + g.setColor(0.25, 1, 1); + g.fillPoly([ W/2, 24, W, 80, 0, 80 ]); + } + let msg = ""; + if (gps_on) { + msg = gpsHandle(); + } else { + msg = note; + } + drawBackground(); - g.setColor(0, 0, 0); - g.setFontAlign(-1, 1); let now = new Date(); - g.drawString(now.getHours() + ":" + add0(now.getMinutes()), 10, 90); + g.setColor(0, 0, 0); + drawTime(now); every(now); let km = 0.001 * 0.719 * Bangle.getHealthStatus("day").steps; + g.setFontAlign(-1, 1); g.setFont('Vector', 26); const weekday = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]; - g.drawString(weekday[now.getDay()] + "" + now.getDate() + ". " + km.toFixed(1) + "km", 10, 115); + g.drawString(weekday[now.getDay()] + "" + now.getDate() + ". " + + fmtSteps(Bangle.getHealthStatus("day").steps), 10, 115); - if (gps_on) { - if (!last_restart) { - d = (getTime()-last_pause); - if (last_fix) - msg = "PL"+ (getTime()-last_fix).toFixed(0); - else - msg = "PN"+ (getTime()-gps_on).toFixed(0); - - print("gps on, paused ", d, gps_needed); - if (d > gps_needed * 2) { - gpsRestart(); - } - } else { - fix = Bangle.getGPSFix(); - if (fix.fix && fix.lat) { - if (!prev_fix) { - prev_fix = fix; - } - msg = fix.speed.toFixed(1) + " km/h"; - if (!last_fstart) - last_fstart = getTime(); - last_fix = getTime(); - gps_needed = 60; - loggps(fix); - print("GPS FIX", msg); - d = calcDistance(fix, prev_fix); - if (d > 30) { - prev_fix = fix; - gps_dist += d/1000; - } - } else { - if (last_fix) - msg = "L"+ (getTime()-last_fix).toFixed(0); - else - msg = "N"+ (getTime()-gps_on).toFixed(0); - } - - d = (getTime()-last_restart); - d2 = (getTime()-last_fstart); - print("gps on, restarted ", d, gps_needed, d2, fix.lat); - if (d > gps_needed || (last_fstart && d2 > 10)) { - gpsPause(); - gps_needed = gps_needed * 1.5; - print("Pausing, next try", gps_needed); - } - } - msg += " "+gps_dist.toFixed(1)+"km"; - } else { - msg = note; - } g.drawString(msg, 10, 145); - if (is_active) { - g.drawString("act " + (cur_altitude - alt_adjust).toFixed(0), 10, 175); - } else { + + if (getTime() - last_active > 15*60) { alt_adjust = cur_altitude - rest_altitude; - g.drawString(alt_adjust.toFixed(0) + "m " + cur_temperature.toFixed(1)+"C", 10, 175); + alt_adjust_mode = "h"; + msg = "H)" + alt_adjust.toFixed(0) + "m"; + } else { + msg = alt_adjust_mode+")"+(cur_altitude - alt_adjust).toFixed(0) + "m"; } + msg = msg + " " + cur_temperature.toFixed(1)+"C"; + if (cur_mark) { + msg = markHandle(); + } + g.drawString(msg, 10, 175); + + if (disp_mode == 1) { + g.drawString(debug, 10, 45); + g.drawString(debug2, 10, 65); + g.drawString(debug3, 10, 85); + } + queueDraw(); } - function draw_all() { g.setColor(0, 0, 0); g.fillRect(0, 0, W, H); @@ -394,14 +592,13 @@ function draw_all() { g.setFont('Vector', 22); g.drawString(now.getDate()+"."+(now.getMonth()+1)+" "+now.getDay(), 3, 60); - g.drawString(msg, 3, 80); + g.drawString("(message here)", 3, 80); g.drawString("S" + step + " B" + Math.round(bat/10) + (Bangle.isCharging()?"c":""), 3, 100); g.drawString("A" + Math.round(alt) + " T" + Math.round(temp), 3, 120); g.drawString("C" + Math.round(co.heading) + " B" + bpm, 3, 140); queueDraw(); } - function accelTask() { tm = 100; acc = Bangle.getAccel(); @@ -424,7 +621,6 @@ function accelTask() { setTimeout(accelTask, tm); } - function buzzTask() { if (buzz != "") { now = buzz[0]; @@ -442,9 +638,8 @@ function buzzTask() { setTimeout(buzzTask, 6*dot); } else print("Unknown character -- ", now, buzz); } else - setTimeout(buzzTask, 60000); + setTimeout(buzzTask, 1000); } - function aliveTask() { function cmp(s) { let d = acc[s] - last_acc[s]; @@ -456,6 +651,7 @@ function aliveTask() { if (cmp("x") || cmp("y") || cmp("z")) { print("active"); is_active = true; + last_active = getTime(); } last_acc = acc; @@ -476,14 +672,15 @@ function queueDraw() { }, next - (Date.now() % next)); } - function start() { Bangle.on("drag", touchHandler); if (0) Bangle.on("accel", accelHandler); - if (0) { + if (1) { Bangle.setCompassPower(1, "sixths"); Bangle.setBarometerPower(1, "sixths"); + } + if (0) { Bangle.setHRMPower(1, "sixths"); Bangle.setGPSPower(1, "sixths"); Bangle.on("HRM", (hrm) => { bpm = hrm.bpm; } ); @@ -500,9 +697,14 @@ function start() { } g.reset(); -Bangle.setUI(); +Bangle.setUI({ + mode : "clock" +}); Bangle.loadWidgets(); Bangle.drawWidgets(); let logfile = require("Storage").open("sixths.egt", "a"); -start(); +if (0) { + testBearing(); +} else + start(); diff --git a/apps/sixths/metadata.json b/apps/sixths/metadata.json index ece88348d..7580623dc 100644 --- a/apps/sixths/metadata.json +++ b/apps/sixths/metadata.json @@ -5,7 +5,8 @@ "icon": "app.png", "readme": "README.md", "supports" : ["BANGLEJS2"], - "tags": "", + "type": "clock", + "tags": "clock", "storage": [ {"name":"sixths.app.js","url":"app.js"}, {"name":"sixths.img","url":"app-icon.js","evaluate":true} From b24e9ca07953a2202d8c3810900b03af1f3313b1 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 3 Nov 2023 16:13:32 +0100 Subject: [PATCH 04/14] [] sixths: update docs. --- apps/sixths/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/sixths/README.md b/apps/sixths/README.md index 18f6bdf99..17369c7a0 100644 --- a/apps/sixths/README.md +++ b/apps/sixths/README.md @@ -25,8 +25,9 @@ minutes, real distance will be usually higher than approximation. Useful gestures: F -- disable GPS. -G -- enable GPS for 4 hours. +G -- enable GPS for 4 hours in low power mode. N -- take a note and write it to the log. +S -- enable GPS for 30 minutes in high power mode. When application detects watch is being worn, it will use vibrations to communicate back to the user. From 7eb9d6cd86fd9e5fe5307a5e959baf881a47c38f Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 3 Nov 2023 16:13:43 +0100 Subject: [PATCH 05/14] [] sixths: use icons to save screen space. --- apps/sixths/app.js | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/apps/sixths/app.js b/apps/sixths/app.js index 40a35590d..ddb41ab0e 100644 --- a/apps/sixths/app.js +++ b/apps/sixths/app.js @@ -41,6 +41,14 @@ var alt_adjust_mode = ""; // Marks var cur_mark = null; +// Icons + +icon_alt = "\0\x08\x1a\1\x00\x00\x00\x20\x30\x78\x7C\xFE\xFF\x00\xC3\xE7\xFF\xDB\xC3\xC3\xC3\xC3\x00\x00\x00\x00\x00\x00\x00\x00"; +icon_m = "\0\x08\x1a\1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC3\xE7\xFF\xDB\xC3\xC3\xC3\xC3\x00\x00\x00\x00\x00\x00\x00\x00"; +icon_km = "\0\x08\x1a\1\xC3\xC6\xCC\xD8\xF0\xD8\xCC\xC6\xC3\x00\xC3\xE7\xFF\xDB\xC3\xC3\xC3\xC3\x00\x00\x00\x00\x00\x00\x00\x00"; +icon_kph = "\0\x08\x1a\1\xC3\xC6\xCC\xD8\xF0\xD8\xCC\xC6\xC3\x00\xC3\xE7\xFF\xDB\xC3\xC3\xC3\xC3\x00\xFF\x00\xC3\xC3\xFF\xC3\xC3"; +icon_c = "\0\x08\x1a\1\x00\x00\x60\x90\x90\x60\x00\x7F\xFF\xC0\xC0\xC0\xC0\xC0\xFF\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; + function toMorse(x) { r = ""; for (var i = 0; i < x.length; i++) { @@ -82,8 +90,9 @@ function gpsOff() { Bangle.setGPSPower(0, "sixths"); gps_on = 0; } -function fmtDist(km) { return km.toFixed(1) + "km"; } +function fmtDist(km) { return km.toFixed(1) + icon_km; } function fmtSteps(n) { return fmtDist(0.001 * 0.719 * n); } +function fmtAlt(m) { return m.toFixed(0) + icon_alt; } function fmtTimeDiff(d) { if (d < 180) return ""+d.toFixed(0); @@ -135,7 +144,7 @@ function gpsHandle() { fix = Bangle.getGPSFix(); if (fix && fix.fix && fix.lat) { gpsHandleFix(fix); - msg = fix.speed.toFixed(1) + " km/h"; + msg = fix.speed.toFixed(1) + icon_kph; print("GPS FIX", msg); if (!last_fstart) @@ -163,7 +172,7 @@ function gpsHandle() { print("Pausing, next try", gps_needed); } } - msg += " "+gps_dist.toFixed(1)+"km"; + msg += " "+gps_dist.toFixed(1)+icon_km; return msg; } function markNew() { @@ -180,7 +189,7 @@ function markHandle() { let m = cur_mark; msg = m.name + ">" + fmtTimeDiff(getTime()- m.time); if (m.fix && m.fix.fix) { - let s = fmtDist(calcDistance(m.fix, prev_fix)/1000) + "km"; + let s = fmtDist(calcDistance(m.fix, prev_fix)/1000) + icon_km; msg += " " + s; debug = "wp>" + s; mark_heading = 180 + calcBearing(m.fix, prev_fix); @@ -525,11 +534,11 @@ function draw() { if (getTime() - last_active > 15*60) { alt_adjust = cur_altitude - rest_altitude; alt_adjust_mode = "h"; - msg = "H)" + alt_adjust.toFixed(0) + "m"; + msg = "H)" + fmtAlt(alt_adjust.toFixed(0)); } else { - msg = alt_adjust_mode+")"+(cur_altitude - alt_adjust).toFixed(0) + "m"; + msg = alt_adjust_mode+")"+fmtAlt(cur_altitude - alt_adjust); } - msg = msg + " " + cur_temperature.toFixed(1)+"C"; + msg = msg + " " + cur_temperature.toFixed(1)+icon_c; if (cur_mark) { msg = markHandle(); } From c03776c767e0e02af3fcea201f6cdbb6cb1994f4 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 3 Nov 2023 16:20:12 +0100 Subject: [PATCH 06/14] [] sixths: v0.02, allow on emulator --- apps/sixths/ChangeLog | 1 + apps/sixths/metadata.json | 5 +++-- apps/sixths/{app.js => sixths.app.js} | 0 3 files changed, 4 insertions(+), 2 deletions(-) rename apps/sixths/{app.js => sixths.app.js} (100%) diff --git a/apps/sixths/ChangeLog b/apps/sixths/ChangeLog index 263d4078d..454f6d101 100644 --- a/apps/sixths/ChangeLog +++ b/apps/sixths/ChangeLog @@ -1 +1,2 @@ 0.01: attempt to import +0.02: better GPS support, adding altitude and temperature support diff --git a/apps/sixths/metadata.json b/apps/sixths/metadata.json index 7580623dc..d79e72ced 100644 --- a/apps/sixths/metadata.json +++ b/apps/sixths/metadata.json @@ -1,14 +1,15 @@ { "id": "sixths", "name": "Sixth sense", - "version":"0.01", + "version":"0.02", "description": "Clock for outdoor use with GPS support", "icon": "app.png", "readme": "README.md", "supports" : ["BANGLEJS2"], + "allow_emulator": true, "type": "clock", "tags": "clock", "storage": [ - {"name":"sixths.app.js","url":"app.js"}, + {"name":"sixths.app.js","url":"sixths.app.js"}, {"name":"sixths.img","url":"app-icon.js","evaluate":true} ] } diff --git a/apps/sixths/app.js b/apps/sixths/sixths.app.js similarity index 100% rename from apps/sixths/app.js rename to apps/sixths/sixths.app.js From 35751aae3b1d1510afc536f9f81413008e5b4f9c Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 3 Nov 2023 18:32:10 +0100 Subject: [PATCH 07/14] sixths: Fix altitude display. --- apps/sixths/sixths.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/sixths/sixths.app.js b/apps/sixths/sixths.app.js index ddb41ab0e..2749a02c0 100644 --- a/apps/sixths/sixths.app.js +++ b/apps/sixths/sixths.app.js @@ -534,7 +534,7 @@ function draw() { if (getTime() - last_active > 15*60) { alt_adjust = cur_altitude - rest_altitude; alt_adjust_mode = "h"; - msg = "H)" + fmtAlt(alt_adjust.toFixed(0)); + msg = "H)" + fmtAlt(alt_adjust); } else { msg = alt_adjust_mode+")"+fmtAlt(cur_altitude - alt_adjust); } From 9690e8128b5d184a5c3606415057acd9eb6b9479 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Thu, 12 Oct 2023 14:30:30 +0200 Subject: [PATCH 08/14] [] wp_edit: implement marking. These are changes from devel_wp branch. Graphical cleanups would be good, otherwise it should work. --- apps/waypoint_editor/app.js | 104 ++++++++++++++++++++++++----- apps/waypoint_editor/metadata.json | 1 + 2 files changed, 87 insertions(+), 18 deletions(-) diff --git a/apps/waypoint_editor/app.js b/apps/waypoint_editor/app.js index 48a956d82..6bba59a1d 100644 --- a/apps/waypoint_editor/app.js +++ b/apps/waypoint_editor/app.js @@ -13,6 +13,10 @@ var wp = require('Storage').readJSON("waypoints.json", true) || []; 2 .. DD MM'ss" */ var mode = 1; +var key; /* Shared between functions, typically wp name */ +var fix; /* GPS fix */ +var cancel_gps; +var gps_start; function writeWP() { require('Storage').writeJSON("waypoints.json", wp); @@ -30,12 +34,72 @@ function mainMenu() { menu["Add"]=addCard; menu["Remove"]=removeCard; menu["Format"]=setFormat; + menu["Mark GPS"]=markGps; g.clear(); E.showMenu(menu); } +function updateGps() { + let have = false, lat = "lat", lon = "lon", alt = "alt", speed = "speed"; + + if (cancel_gps) + return; + fix = Bangle.getGPSFix(); + + speed = getTime() - gps_start; + + if (fix && fix.fix && fix.lat) { + lat = "" + fix.lat; + lon = "" + fix.lon; + alt = "" + fix.alt; + speed = "" + fix.speed; + have = true; + } + + g.reset().setFont("Vector", 20) + .setColor(1,1,1) + .fillRect(0, 0, 176, 120) + .setColor(0,0,0) + .drawString(key, 0, 0) + .drawString(lat, 0, 20) + .drawString(lon, 0, 40) + .drawString(alt, 0, 60) + .drawString(speed, 0, 80); + + setTimeout(updateGps, 100); +} + +function stopGps() { + cancel_gps=true; + Bangle.setGPSPower(0, "waypoint_editor"); +} + +function confirmGps() { + var la = new Layout ( + {type:"v", c: [ + {type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:""}, + {type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:""}, + {type:"h", c: [ + {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: "YES", cb:l=>{ + print("should mark", key, fix); createWP(fix.lat, fix.lon, key); cancel_gps=true; mainMenu(); + }}, + {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: " NO", cb:l=>{ cancel_gps=true; mainMenu(); }} + ]} + ], lazy:true}); + g.clear(); + la.render(); + updateGps(); +} + +function markGps() { + cancel_gps = false; + Bangle.setGPSPower(1, "waypoint_editor"); + gps_start = getTime(); + showNumpad("mkXX", "mark", confirmGps); +} + function setFormat() { - var confirmRemove = new Layout ( + var la = new Layout ( {type:"v", c: [ {type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:"Format"}, {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: "DD.dddd", cb:l=>{ mode = 0; mainMenu(); }}, @@ -43,7 +107,7 @@ function setFormat() { {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: "DD MM'ss"+'"', cb:l=>{ mode = 2; mainMenu(); }}, ], lazy:true}); g.clear(); - confirmRemove.render(); + la.render(); } function format(x) { @@ -87,14 +151,14 @@ function lon(x) { function decode(pin) { print(pin); var i = wp[pin]; - var pinDecrypted=i["name"] + "\n" + lat(i["lat"]) + "\n" + lon(i["lon"]); - var showPin = new Layout ({ + var l = i["name"] + "\n" + lat(i["lat"]) + "\n" + lon(i["lon"]); + var la = new Layout ({ type:"v", c: [ - {type:"txt", font:"10%", pad:1, fillx:1, filly:1, label: pinDecrypted}, + {type:"txt", font:"10%", pad:1, fillx:1, filly:1, label: l}, {type:"btn", font:"10%", pad:1, fillx:1, filly:1, label:"OK", cb:l=>{mainMenu();}} ], lazy:true}); g.clear(); - showPin.render(); + la.render(); } function showNumpad(text, key_, callback) { @@ -155,10 +219,10 @@ function showNumpad(text, key_, callback) { function removeCard() { var menu = { - "" : {title : "select card"}, + "" : {title : "Select WP"}, "< Back" : mainMenu }; - if (Object.keys(wp).length==0) Object.assign(menu, {"NO CARDS":""}); + if (Object.keys(wp).length==0) Object.assign(menu, {"No WPs":""}); else { wp.forEach((val, card) => { const name = wp[card].name; @@ -186,14 +250,14 @@ function removeCard() { } function ask01(t, cb) { - var confirmRemove = new Layout ( + var la = new Layout ( {type:"v", c: [ - {type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:"Format"}, + {type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:"Select"}, {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: t[0], cb:l=>{ cb(1); }}, {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: t[1], cb:l=>{ cb(-1); }}, ], lazy:true}); g.clear(); - confirmRemove.render(); + la.render(); } @@ -237,6 +301,16 @@ function askPosition(callback) { }); } +function createWP(lat, lon, name) { + let n = {}; + n["name"] = name; + n["lat"] = lat; + n["lon"] = lon; + wp.push(n); + print("add -- waypoints", wp); + writeWP(); +} + function addCard() { showNumpad("wpXX", "wp", function() { result = key; @@ -257,13 +331,7 @@ function addCard() { g.clear(); askPosition(function(lat, lon) { print("position -- ", lat, lon); - let n = {}; - n["name"] = result; - n["lat"] = lat; - n["lon"] = lon; - wp.push(n); - print("add -- waypoints", wp); - writeWP(); + createWP(lat, lon, result); mainMenu(); }); }); diff --git a/apps/waypoint_editor/metadata.json b/apps/waypoint_editor/metadata.json index 12ff6e095..be3e14d76 100644 --- a/apps/waypoint_editor/metadata.json +++ b/apps/waypoint_editor/metadata.json @@ -5,6 +5,7 @@ "icon": "app.png", "readme": "README.md", "supports" : ["BANGLEJS2"], + "allow_emulator": true, "tags": "tool,outdoors,gps", "storage": [ {"name":"waypoint_editor.app.js","url":"app.js"}, From 73375ebe964bc1bf72b8506869fa0e6b6718239a Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Wed, 1 Nov 2023 11:36:59 +0100 Subject: [PATCH 09/14] [] wp_edit: use text entry for waypoint names --- apps/waypoint_editor/app.js | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/apps/waypoint_editor/app.js b/apps/waypoint_editor/app.js index 6bba59a1d..cdc752c79 100644 --- a/apps/waypoint_editor/app.js +++ b/apps/waypoint_editor/app.js @@ -26,8 +26,10 @@ function mainMenu() { var menu = { "< Back" : Bangle.load }; - if (Object.keys(wp).length==0) Object.assign(menu, {"NO WPs":""}); - else for (let id in wp) { + if (Object.keys(wp).length==0) { + //Object.assign(menu, {"NO WPs":""}); + print("(no waypoints)"); + } else for (let id in wp) { let i = id; menu[wp[id]["name"]]=()=>{ decode(i); }; } @@ -74,7 +76,8 @@ function stopGps() { Bangle.setGPSPower(0, "waypoint_editor"); } -function confirmGps() { +function confirmGps(s) { + key = s; var la = new Layout ( {type:"v", c: [ {type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:""}, @@ -95,7 +98,9 @@ function markGps() { cancel_gps = false; Bangle.setGPSPower(1, "waypoint_editor"); gps_start = getTime(); - showNumpad("mkXX", "mark", confirmGps); + require("textinput").input({text:"wp"}).then(key => { + confirmGps(key); + }); } function setFormat() { @@ -311,8 +316,17 @@ function createWP(lat, lon, name) { writeWP(); } +function addCardName(name) { + g.clear(); + askPosition(function(lat, lon) { + print("position -- ", lat, lon); + createWP(lat, lon, result); + mainMenu(); + }); +} + function addCard() { - showNumpad("wpXX", "wp", function() { + require("textinput").input({text:"wp"}).then(key => { result = key; if (wp[result]!=undefined) { E.showMenu(); @@ -321,19 +335,14 @@ function addCard() { {type:"txt", font:Math.min(15,100/result.length)+"%", pad:1, fillx:1, filly:1, label:result}, {type:"txt", font:"12%", pad:1, fillx:1, filly:1, label:"already exists."}, {type:"h", c: [ - {type:"btn", font:"10%", pad:1, fillx:1, filly:1, label: "REPLACE", cb:l=>{encodeCard(result);}}, + {type:"btn", font:"10%", pad:1, fillx:1, filly:1, label: "REPLACE", cb:l=>{addCardName(result);}}, {type:"btn", font:"10%", pad:1, fillx:1, filly:1, label: "CANCEL", cb:l=>{mainMenu();}} ]} ], lazy:true}); g.clear(); alreadyExists.render(); - } - g.clear(); - askPosition(function(lat, lon) { - print("position -- ", lat, lon); - createWP(lat, lon, result); - mainMenu(); - }); + } + addCardName(result); }); } From dbde4923c61566ca64db33def196332625c4f1c8 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 3 Nov 2023 21:56:10 +0100 Subject: [PATCH 10/14] [] wp_editor: reindent, minor cleanups. --- apps/waypoint_editor/app.js | 87 ++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 45 deletions(-) diff --git a/apps/waypoint_editor/app.js b/apps/waypoint_editor/app.js index cdc752c79..c9327d621 100644 --- a/apps/waypoint_editor/app.js +++ b/apps/waypoint_editor/app.js @@ -31,7 +31,7 @@ function mainMenu() { print("(no waypoints)"); } else for (let id in wp) { let i = id; - menu[wp[id]["name"]]=()=>{ decode(i); }; + menu[wp[id]["name"]]=()=>{ show(i); }; } menu["Add"]=addCard; menu["Remove"]=removeCard; @@ -78,17 +78,17 @@ function stopGps() { function confirmGps(s) { key = s; - var la = new Layout ( - {type:"v", c: [ - {type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:""}, - {type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:""}, - {type:"h", c: [ - {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: "YES", cb:l=>{ - print("should mark", key, fix); createWP(fix.lat, fix.lon, key); cancel_gps=true; mainMenu(); - }}, - {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: " NO", cb:l=>{ cancel_gps=true; mainMenu(); }} - ]} - ], lazy:true}); + var la = new Layout ( + {type:"v", c: [ + {type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:""}, + {type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:""}, + {type:"h", c: [ + {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: "YES", cb:l=>{ + print("should mark", key, fix); createWP(fix.lat, fix.lon, key); cancel_gps=true; mainMenu(); + }}, + {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: " NO", cb:l=>{ cancel_gps=true; mainMenu(); }} + ]} + ], lazy:true}); g.clear(); la.render(); updateGps(); @@ -105,12 +105,12 @@ function markGps() { function setFormat() { var la = new Layout ( - {type:"v", c: [ - {type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:"Format"}, - {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: "DD.dddd", cb:l=>{ mode = 0; mainMenu(); }}, - {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: "DD MM.mmm'", cb:l=>{ mode = 1; mainMenu(); }}, - {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: "DD MM'ss"+'"', cb:l=>{ mode = 2; mainMenu(); }}, - ], lazy:true}); + {type:"v", c: [ + {type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:"Format"}, + {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: "DD.dddd", cb:l=>{ mode = 0; mainMenu(); }}, + {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: "DD MM.mmm'", cb:l=>{ mode = 1; mainMenu(); }}, + {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: "DD MM'ss"+'"', cb:l=>{ mode = 2; mainMenu(); }}, + ], lazy:true}); g.clear(); la.render(); } @@ -134,7 +134,6 @@ function format(x) { return "" + d + " " + mf + "'" + s + '"'; } } - function lat(x) { c = "N"; if (x<0) { @@ -143,7 +142,6 @@ function lat(x) { } return c+format(x); } - function lon(x) { c = "E"; if (x<0) { @@ -153,17 +151,17 @@ function lon(x) { return c+format(x); } -function decode(pin) { - print(pin); - var i = wp[pin]; - var l = i["name"] + "\n" + lat(i["lat"]) + "\n" + lon(i["lon"]); - var la = new Layout ({ - type:"v", c: [ - {type:"txt", font:"10%", pad:1, fillx:1, filly:1, label: l}, - {type:"btn", font:"10%", pad:1, fillx:1, filly:1, label:"OK", cb:l=>{mainMenu();}} - ], lazy:true}); - g.clear(); - la.render(); +function show(pin) { + print(pin); + var i = wp[pin]; + var l = i["name"] + "\n" + lat(i["lat"]) + "\n" + lon(i["lon"]); + var la = new Layout ({ + type:"v", c: [ + {type:"txt", font:"10%", pad:1, fillx:1, filly:1, label: l}, + {type:"btn", font:"10%", pad:1, fillx:1, filly:1, label:"OK", cb:l=>{mainMenu();}} + ], lazy:true}); + g.clear(); + la.render(); } function showNumpad(text, key_, callback) { @@ -307,22 +305,22 @@ function askPosition(callback) { } function createWP(lat, lon, name) { - let n = {}; - n["name"] = name; - n["lat"] = lat; - n["lon"] = lon; - wp.push(n); - print("add -- waypoints", wp); - writeWP(); + let n = {}; + n["name"] = name; + n["lat"] = lat; + n["lon"] = lon; + wp.push(n); + print("add -- waypoints", wp); + writeWP(); } function addCardName(name) { - g.clear(); - askPosition(function(lat, lon) { - print("position -- ", lat, lon); - createWP(lat, lon, result); - mainMenu(); - }); + g.clear(); + askPosition(function(lat, lon) { + print("position -- ", lat, lon); + createWP(lat, lon, result); + mainMenu(); + }); } function addCard() { @@ -346,7 +344,6 @@ function addCard() { }); } - g.reset(); Bangle.setUI(); mainMenu(); From b814454d90f70e9d839c492364840f7dda1e6286 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 3 Nov 2023 22:03:44 +0100 Subject: [PATCH 11/14] [] wp_edit: Graphical fixes for waypoint marking. --- apps/waypoint_editor/app.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/waypoint_editor/app.js b/apps/waypoint_editor/app.js index c9327d621..db77cf794 100644 --- a/apps/waypoint_editor/app.js +++ b/apps/waypoint_editor/app.js @@ -48,13 +48,13 @@ function updateGps() { return; fix = Bangle.getGPSFix(); - speed = getTime() - gps_start; + speed = "no fix for " + (getTime() - gps_start).toFixed(0) + "s"; if (fix && fix.fix && fix.lat) { - lat = "" + fix.lat; - lon = "" + fix.lon; - alt = "" + fix.alt; - speed = "" + fix.speed; + lat = "" + lat(fix.lat); + lon = "" + lon(fix.lon); + alt = "alt " + fix.alt.toFixed(0) + "m"; + speed = "speed " + fix.speed.toFixed(1) + "kt"; have = true; } @@ -80,6 +80,7 @@ function confirmGps(s) { key = s; var la = new Layout ( {type:"v", c: [ + {type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:""}, {type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:""}, {type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:""}, {type:"h", c: [ @@ -263,7 +264,6 @@ function ask01(t, cb) { la.render(); } - function askCoordinate(t1, t2, callback) { let sign = 1; ask01(t1, function(sign) { From 9dd09945a1d06498bcbb03e2be9f93752a16f8ab Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 3 Nov 2023 22:05:47 +0100 Subject: [PATCH 12/14] [] wp_edit: mark this as v0.03 --- apps/waypoint_editor/ChangeLog | 1 + apps/waypoint_editor/metadata.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/waypoint_editor/ChangeLog b/apps/waypoint_editor/ChangeLog index 0ec5d2df8..0f45b79cc 100644 --- a/apps/waypoint_editor/ChangeLog +++ b/apps/waypoint_editor/ChangeLog @@ -1,2 +1,3 @@ 0.01: New App! 0.02: Display waypoint name instead of its index in remove menu and fix icon +0.03: Use text input for waypoint names, allow marking waypoint with current GPS position diff --git a/apps/waypoint_editor/metadata.json b/apps/waypoint_editor/metadata.json index be3e14d76..d43c6b6bf 100644 --- a/apps/waypoint_editor/metadata.json +++ b/apps/waypoint_editor/metadata.json @@ -1,6 +1,6 @@ { "id": "waypoint_editor", "name": "Waypoint editor", - "version":"0.02", + "version":"0.03", "description": "Allows editing waypoints on device", "icon": "app.png", "readme": "README.md", From b735ae13e46bd0273b6903b2fe4367511c2b3f20 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 3 Nov 2023 22:19:08 +0100 Subject: [PATCH 13/14] waypoint_editor: fix tabs vs. spaces. --- apps/waypoint_editor/app.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/waypoint_editor/app.js b/apps/waypoint_editor/app.js index db77cf794..cbdcdbfd3 100644 --- a/apps/waypoint_editor/app.js +++ b/apps/waypoint_editor/app.js @@ -84,10 +84,10 @@ function confirmGps(s) { {type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:""}, {type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:""}, {type:"h", c: [ - {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: "YES", cb:l=>{ - print("should mark", key, fix); createWP(fix.lat, fix.lon, key); cancel_gps=true; mainMenu(); - }}, - {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: " NO", cb:l=>{ cancel_gps=true; mainMenu(); }} + {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: "YES", cb:l=>{ + print("should mark", key, fix); createWP(fix.lat, fix.lon, key); cancel_gps=true; mainMenu(); + }}, + {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: " NO", cb:l=>{ cancel_gps=true; mainMenu(); }} ]} ], lazy:true}); g.clear(); From 3f064961f025ef80134702213690ef943a6fd367 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sat, 4 Nov 2023 09:08:53 +0100 Subject: [PATCH 14/14] wp_edit: we use textinput, include it in dependencies --- apps/waypoint_editor/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/waypoint_editor/metadata.json b/apps/waypoint_editor/metadata.json index d43c6b6bf..87f0ed8ce 100644 --- a/apps/waypoint_editor/metadata.json +++ b/apps/waypoint_editor/metadata.json @@ -7,6 +7,7 @@ "supports" : ["BANGLEJS2"], "allow_emulator": true, "tags": "tool,outdoors,gps", + "dependencies": {"textinput":"type"}, "storage": [ {"name":"waypoint_editor.app.js","url":"app.js"}, {"name":"waypoint_editor.img","url":"app-icon.js","evaluate":true}