diff --git a/apps/trail/trail.app.js b/apps/trail/trail.app.js index 601a9f089..591f30b49 100644 --- a/apps/trail/trail.app.js +++ b/apps/trail/trail.app.js @@ -181,42 +181,72 @@ let gps = { }, }; -/* ui library 0.1.2 */ +/* ui library 0.2.0 -- see skyspy */ +//Bangle.on("drag", (b) => ui.touchHandler(b)); let ui = { display: 0, numScreens: 2, + name: ".oO busy", + screens: [ "Screen 1", "Screen 2", "Screen 3", "Screen 4", "Screen 5", "Screen 6" ], + help: [ "F1", "F2", "<", ">" ], + clear: function() { + g.reset() + .setColor(g.theme.bg) + .fillRect(0, this.wi, this.w, this.y2) + .setColor(g.theme.fg); + }, + draw: function(screen) {}, drawMsg: function(msg) { - g.reset().setFont("Vector", 35) - .setColor(1,1,1) - .fillRect(0, this.wi, 176, 176) - .setColor(0,0,0) + this.clear(); + g.setFont("Vector", 35) .drawString(msg, 5, 30) .flip(); }, drawBusy: function() { - this.drawMsg("\n.oO busy"); + this.clear(); + g.setFont("Vector", 35); + let help = this.help; + g.setFontAlign(-1, -1).drawString(help[0], 0, this.wi); + g.setFontAlign(1, -1).drawString(help[1], this.w, this.wi); + g.setFontAlign(-1, 1).drawString(help[2], 0, this.h+this.wi); + g.setFontAlign(1, 1).drawString(help[3], this.w, this.h+this.wi); + g.setFontAlign(0, 0) + .drawString(this.name, this.w/2, this.h/2); + g.reset(); + }, + drawScreen: function() { + this.drawMsg(this.screens[this.display]); + let t1 = getTime(); + this.draw(); + let t = getTime() - t1; + if (t > 30) { + print("Draw took", t, "msec"); + } }, nextScreen: function() { print("nextS"); this.display = this.display + 1; if (this.display == this.numScreens) this.display = 0; - this.drawBusy(); + this.drawScreen(); }, prevScreen: function() { print("prevS"); this.display = this.display - 1; if (this.display < 0) this.display = this.numScreens - 1; - this.drawBusy(); + this.drawScreen(); }, onSwipe: function(dir) { this.nextScreen(); }, - h: 176, + wi: 24, + y2: 176, + h: 152, w: 176, - wi: 32, last_b: 0, + topLeft: function() { this.drawMsg("Unimpl"); }, + topRight: function() { this.drawMsg("Unimpl"); }, touchHandler: function(d) { let x = Math.floor(d.x); let y = Math.floor(d.y); @@ -228,46 +258,85 @@ let ui = { print("touch", x, y, this.h, this.w); - /* - if ((xthis.h/2) && (ythis.w/2)) { + if ((xthis.w/2) && (ythis.y2/2)) { print("prev"); this.prevScreen(); } - if ((x>this.h/2) && (y>this.w/2)) { + if ((x>this.w/2) && (y>this.y2/2)) { print("next"); this.nextScreen(); } }, init: function() { + this.h = this.y2 - this.wi; this.drawBusy(); - } + }, + /* radial angle -- convert 0..1 to 0..2pi */ + radA: function(p) { return p*(Math.PI*2); }, + /* radial distance -- convert 0..1 to something that fits on screen */ + radD: function(d) { return d*(ui.h/2); }, + + /* given angle/distance, get X coordinate */ + radX: function(p, d) { + let a = this.radA(p); + return this.w/2 + Math.sin(a)*this.radD(d); + }, + /* given angle/distance, get Y coordinate */ + radY: function(p, d) { + let a = this.radA(p); + return this.h/2 - Math.cos(a)*this.radD(d) + this.wi; + }, + radLine: function(a1, d1, a2, d2) { + g.drawLine(this.radX(a1, d1), this.radY(a1, d1), this.radX(a2, d2), this.radY(a2, d2)); + }, + radCircle: function(d) { + g.drawCircle(this.radX(0, 0), this.radY(0, 0), this.radD(d)); + if (1) + return; + let step = 0.05; + for (let i = 0; i < 1; i += 0.05) { + this.radLine(i - step, d, i, d); + } + }, }; -/* egt 0.0.1 */ +/* egt 0.0.3 */ let egt = { init: function() { }, + removeCRLF: function(s) { + let end = s.length; + while (end > 0) { + let ch = s[end - 1]; + if (ch === '\n' || ch === '\r') { + end--; + } else { + break; + } + } + return s.slice(0, end); + }, + parse: function(l) { + l = this.removeCRLF(l); let r = {}; let s = l.split(' '); - + if (s === undefined) return r; - + if (s[1] === undefined) return r; - + if (s[1].split('=')[1] === undefined) { r.lat = 1 * s[0]; r.lon = 1 * s[1]; if (!r.lat || !r.lon) { - print("Parse error at ", l); + print("Parse error at ", l, "have (", s[0], s[1], ")"); } } @@ -282,6 +351,7 @@ let egt = { }, }; + /* zoom library v0.0.4 */ var zoom = { buf : 0, @@ -367,9 +437,8 @@ var zoom = { } }; - function toCartesian(v) { - const R = 6371; // Poloměr Země v km + const R = 6371; // Earth radius in km const latRad = v.lat * Math.PI / 180; const lonRad = v.lon * Math.PI / 180; @@ -424,6 +493,7 @@ function angleDifference(angle1, angle2) { return difference; } +/* These are initialized by read() function, below */ var start = {}, destination = {}, num = 0, dist = 0; function read(pp, n) { @@ -447,13 +517,15 @@ function read(pp, n) { start = p; pp.lat = p.lat; pp.lon = p.lon; + /* FIXME: won't init destination */ + return; } prev = p; } l = f.readLine(); if (!(num % 30)) { g.clear(); - zoom.geoPaint(prev, 0, 1500); + zoom.geoPaint(prev, 0, 2500); g.drawString(num + "\n" + fmt.fmtDist(dist / 1000), 3, 3); g.flip(); print(num, "points"); @@ -467,7 +539,9 @@ function read(pp, n) { destination = prev; } +/* Convert to storagefile, and find out start/stop points (and display some eye-candy) */ function time_read(n) { + ui.drawMsg("Converting"); print("Converting..."); to_storage(n); print("Running..."); @@ -488,6 +562,8 @@ function time_read(n) { setTimeout(step, 100); } +/* Main code for displaying track */ + var track_name = "", inf, point_num, track = [], track_points = 30, north = {}, point_drawn; function step_init() { @@ -524,6 +600,7 @@ function paint(pp, p1, p2, thick) { zoom.geoLine(p1, p2); } +/* Paint points in window around current position */ function paint_all(pp) { let prev = 0; let mDist = 99999999999, m = 0; @@ -557,10 +634,13 @@ function paint_all(pp) { if (fast) return { quiet: 0, offtrack : 0 }; print("Best segment was", m, "dist", mDist); - if (fmt.distance(track[m], zoom.origin) > 1500) { + /* If we are too far from ... */ + if (fmt.distance(track[m], zoom.origin) > 2500) { zoom.geoNew(track[m], 3000); // FIXME: this will flicker point_drawn = 0; } + + /* Estimate distance to next turn/intersection */ let ahead = 0, a = fmt.bearing(track[m-1], track[m]), quiet = -1; for (let i = m+1; i < track.length; i++) { let a2 = fmt.bearing(track[i-1], track[i]); @@ -583,6 +663,8 @@ function drop_last() { track.shift(); } +/* Display data for given position -- pp. + Drop data that are more than 150 meters behind current position */ function step_to(pp, pass_all) { if (0) { g.setColor(0.5, 0.5, 1); @@ -591,9 +673,7 @@ function step_to(pp, pass_all) { g.setColor(1, 0.5, 0.5); paint(pp, pp, north, 1); } - let quiet = paint_all(pp); - while (distSegment(track[0], track[1], pp) > 150 && track.length > 10) { drop_last(); @@ -626,17 +706,25 @@ function step() { let quiet = step_to(pp, 1); if (1) { g.setColor(0, 0, 0); - zoom.geoPaint(pp, -pp.course, 500); + let zoom_scale = 0; + switch (ui.display) { + case 0: zoom_scale = 500; break; + case 1: zoom_scale = 1500; break; + case 2: zoom_scale = 2500; break; + case 3: /* draw some statistics? */ break; + } + if (zoom_scale) + zoom.geoPaint(pp, -pp.course, zoom_scale); } { - pp.x = ui.w/2; - pp.y = ui.h*0.5; - - g.setColor(0, 0, 1); - let sc = 2.5; - g.drawPoly([ pp.x, pp.y, pp.x - 5*sc, pp.y + 12*sc, pp.x + 5*sc, pp.y + 12*sc ], true); + /* Draw arrow representing current position */ + pp.x = ui.w/2; + pp.y = ui.h*0.5; + g.setColor(0, 0, 1); + let sc = 2.5; + g.drawPoly([ pp.x, pp.y, pp.x - 5*sc, pp.y + 12*sc, pp.x + 5*sc, pp.y + 12*sc ], true); } g.setColor(0, 0, 0); @@ -668,6 +756,10 @@ function step() { setTimeout(step, 1000); } +/* Recovery: If we get completely lost, we can do this. + It works similar to main loop, but faster. + It simply drop points until we are 400meters from the fix, then main code can take over. +*/ function recover() { ui.drawMsg("Recover..."); step_init(); @@ -676,7 +768,7 @@ function recover() { pp.ppm = 0.08 * 3; /* Pixels per meter */ if (!fix.fix) { print("Can't recover with no fix\n"); - fix.lat = 50.010507; + fix.lat = 50.010507; /* FIXME */ fix.lon = 14.765840; } load_next(); @@ -693,10 +785,11 @@ function recover() { step_to(pp, 1); if (!load_next()) break; - ui.drawMsg("Recover\n" + fmt.fmtDist(d / 1000)); + ui.drawMsg("Recover\n" + fmt.fmtDist(d / 1000) + "\n" + point_num + "/" + num); } } +/* Convert "normal" file to storagefile... so that we can read lines from it */ function to_storage(n) { let f2 = require("Storage").open(n+".st", "w"); let pos = 0; @@ -711,7 +804,6 @@ function to_storage(n) { } } -ui.init(); fmt.init(); egt.init(); gps.init(); @@ -725,23 +817,27 @@ l = st.list(l, {sf:false}); print(l); +/* After user selected the track, we can switch to main interface */ function load_track(x) { + ui.init(); + ui.numScreens = 4; +ui.screens = [ "Detail", "Mid", "Overview", "Stats" ]; + Bangle.buzz(50, 1); ui.drawMsg("Loading\n"+x); track_name = x; time_read(x); - - Bangle.setUI("clockupdown", btn => { - print("Button", btn); - if (btn == -1) { - recover(); - } - if (btn == 1) { - demo_mode = 1; - } + + Bangle.on("drag", (b) => ui.touchHandler(b)); + Bangle.setUI({ + mode : "custom", + clock : 0 }); + ui.topLeft = () => { ui.drawMsg("Demo mode"); demo_mode = 1; } + ui.topRight = () => { ui.drawMsg("Recover"); recover(); }; } +/* Display menu with tracks. */ var menu = { "< Back" : Bangle.load }; diff --git a/apps/waypoints/waypoints.app.js b/apps/waypoints/waypoints.app.js index a9b06af71..462438776 100644 --- a/apps/waypoints/waypoints.app.js +++ b/apps/waypoints/waypoints.app.js @@ -1,5 +1,7 @@ /* Thanks to pinsafe from BangleApps repository */ +/* create waypoint is unusable on watch -- button takes us back to menu */ + var Layout = require("Layout"); /* fmt library v0.2.3 */