diff --git a/apps.json b/apps.json index 4c557e847..f74288128 100644 --- a/apps.json +++ b/apps.json @@ -4,7 +4,7 @@ "tags": "tool,system,b2", "type":"bootloader", "icon": "bootloader.png", - "version":"0.30", + "version":"0.31", "description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings", "storage": [ {"name":".boot0","url":"boot0.js"}, @@ -3599,5 +3599,18 @@ "storage": [ {"name":"menusmall.boot.js","url":"boot.js"} ] +}, +{ "id": "ffcniftya", + "name": "Nifty-A Clock", + "icon": "app.png", + "version":"0.01", + "description": "A nifty clock with time and date", + "tags":"clock,b2", + "type":"clock", + "allow_emulator":true, + "storage": [ + {"name":"ffcniftya.app.js","url":"app.js"}, + {"name":"ffcniftya.img","url":"app-icon.js","evaluate":true} + ] } ] diff --git a/apps/accellog/app.js b/apps/accellog/app.js index fdb4d52be..c54c5002b 100644 --- a/apps/accellog/app.js +++ b/apps/accellog/app.js @@ -99,12 +99,12 @@ function startRecord(force) { {type:"txt", id:"time", font:"6x8:2", label:" - ", pad:5, bgCol:g.theme.bg}, {type:"txt", font:"6x8:2", label:"RECORDING", bgCol:"#f00", pad:5, fillx:1}, ] - },[ // Buttons... + },{btns:[ // Buttons... {label:"STOP", cb:()=>{ Bangle.removeListener('accel', accelHandler); showMenu(); }} - ]); + ]}); layout.render(); // now start writing diff --git a/apps/barclock/clock-bar.js b/apps/barclock/clock-bar.js index c2b4bde12..2c6d66e45 100644 --- a/apps/barclock/clock-bar.js +++ b/apps/barclock/clock-bar.js @@ -40,7 +40,7 @@ const layout = new Layout({ {height: 40}, {id: "date", type: "txt", font: "10%", valign: 1}, ], -}, false, {lazy: true}); +}, {lazy: true}); // adjustments based on screen size and whether we display am/pm let thickness; // bar thickness, same as time font "pixel block" size if (is12Hour) { diff --git a/apps/boot/ChangeLog b/apps/boot/ChangeLog index 7f2220572..6cdf1b0e5 100644 --- a/apps/boot/ChangeLog +++ b/apps/boot/ChangeLog @@ -30,3 +30,4 @@ 0.29: Update boot0 to avoid code block (faster execution) Fix issues where 'Uncaught Error: Function not found' could happen with multiple .boot.js 0.30: Remove 'Get GPS time' at boot. Latest firmwares keep time through reboots, so this is not needed now +0.31: Add polyfills for g.wrapString, g.imageMetrics, g.stringMetrics diff --git a/apps/boot/bootupdate.js b/apps/boot/bootupdate.js index 199bff6e3..7210ae731 100644 --- a/apps/boot/bootupdate.js +++ b/apps/boot/bootupdate.js @@ -131,6 +131,41 @@ else if (mode=="updown") { throw new Error("Unknown UI mode"); };\n`; } +if (!g.imageMetrics) { // added in 2v11 - this is a limited functionality polyfill + boot += `Graphics.prototype.imageMetrics=function(src) { + if (src[0]) return {width:src[0],height:src[1]}; + else if ('object'==typeof src) return { + width:("width" in src) ? src.width : src.getWidth(), + height:("height" in src) ? src.height : src.getHeight()}; + var im = E.toString(src); + return {width:im.charCodeAt(0), height:im.charCodeAt(1)}; +};\n`; +} +if (!g.stringMetrics) { // added in 2v11 - this is a limited functionality polyfill + boot += `Graphics.prototype.stringMetrics=function(txt) { + return {width:this.stringWidth(txt), height:this.getFontHeight()}; +};\n`; +} +if (!g.wrapString) { // added in 2v11 - this is a limited functionality polyfill + boot += `Graphics.prototype.wrapString=function(str, maxWidth) { + var lines = []; + for (var unwrappedLine of str.split("\n")) { + var words = unwrappedLine.split(" "); + var line = words.shift(); + for (var word of words) { + if (g.stringWidth(line + " " + word) > maxWidth) { + lines.push(line); + line = word; + } else { + line += " " + word; + } + } + lines.push(line); + } + return lines; +};\n`; +} + // Append *.boot.js files require('Storage').list(/\.boot\.js/).forEach(bootFile=>{ // we add a semicolon so if the file is wrapped in (function(){ ... }() diff --git a/apps/ffcniftya/ChangeLog b/apps/ffcniftya/ChangeLog new file mode 100644 index 000000000..18bc264a3 --- /dev/null +++ b/apps/ffcniftya/ChangeLog @@ -0,0 +1 @@ +0.01: New Clock Nifty A diff --git a/apps/ffcniftya/app-icon.js b/apps/ffcniftya/app-icon.js new file mode 100644 index 000000000..f0a2393b1 --- /dev/null +++ b/apps/ffcniftya/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwkEIf4A5gX/+AGEn//mIWLgP/C4gGCAAMgC5UvC4sDC4YICkIhBgMQiEBE4Uxn4XDj//iEAn/yA4ICBgUikEikYXBBAIXEn/xJYURAYMygERkQHBiYLBKYIXF+AVDC4czgUSmIXBCQgED+ZeBR4YXBLYICDC5CPGC4IAIC40zmaPDC4MSLQQXK+ayCR4QXCiRoEC44ECh4bCC4MTiTDBC6ZHOC5B3NLYcvC4kBgL5BAAUikT+BfIIrB/8ykf/eYQXBkUTI4cBW4YQCgQGDmAXDkJfEC46GBAoJKCR4geCAAMRAAZRDAoIODO4UBPRIAJR5QXWgKNCTApNDC5Mv/6/DAwR3GAAyHCC4anJIo3/+bvEa4Uia4oXHkEvC4cvIgUf+YXKHYIvEAgcPC5QSGC5UBSwYXJLYQXFkUhgABBC5Ef/4mBl4XEmETmIXKgaXBmYCBC4cTkMxiQXJS4IACL4p3MgESCwJHFR5oxCiB3FkERC5cSToQXFmUyiAZFR48Bn7zCAQMjkfykQkBN4n/XgKPBAAQgCUQIfBUwYXHFgIGCdI4XDmYADmIIEkAWJAH4A4A==")) \ No newline at end of file diff --git a/apps/ffcniftya/app.js b/apps/ffcniftya/app.js new file mode 100644 index 000000000..0b8865bec --- /dev/null +++ b/apps/ffcniftya/app.js @@ -0,0 +1,95 @@ +const locale = require("locale"); +const is12Hour = (require("Storage").readJSON("setting.json", 1) || {})["12hour"]; + +/* Clock *********************************************/ +const scale = g.getWidth() / 176; + +const widget = 24; + +const viewport = { + width: g.getWidth(), + height: g.getHeight(), +} + +const center = { + x: viewport.width / 2, + y: Math.round(((viewport.height - widget) / 2) + widget), +} + +function d02(value) { + return ('0' + value).substr(-2); +} + +function draw() { + g.reset(); + g.clearRect(0, widget, viewport.width, viewport.height); + const now = new Date(); + + const hour = d02(now.getHours() - (is12Hour && now.getHours() > 12 ? 12 : 0)); + const minutes = d02(now.getMinutes()); + const day = d02(now.getDay()); + const month = d02(now.getMonth() + 1); + const year = now.getFullYear(); + + const month2 = locale.month(now, 3); + const day2 = locale.dow(now, 3); + + g.setFontAlign(1, 0).setFont("Vector", 90 * scale); + g.drawString(hour, center.x + 32 * scale, center.y - 31 * scale); + g.drawString(minutes, center.x + 32 * scale, center.y + 46 * scale); + + g.fillRect(center.x + 30 * scale, center.y - 72 * scale, center.x + 32 * scale, center.y + 74 * scale); + + g.setFontAlign(-1, 0).setFont("Vector", 16 * scale); + g.drawString(year, center.x + 40 * scale, center.y - 62 * scale); + g.drawString(month, center.x + 40 * scale, center.y - 44 * scale); + g.drawString(day, center.x + 40 * scale, center.y - 26 * scale); + g.drawString(month2, center.x + 40 * scale, center.y + 48 * scale); + g.drawString(day2, center.x + 40 * scale, center.y + 66 * scale); +} + + +/* Minute Ticker *************************************/ + +let tickTimer; + +function clearTickTimer() { + if (tickTimer) { + clearTimeout(tickTimer); + tickTimer = undefined; + } +} + +function queueNextTick() { + clearTickTimer(); + tickTimer = setTimeout(tick, 60000 - (Date.now() % 60000)); + // tickTimer = setTimeout(tick, 3000); +} + +function tick() { + draw(); + queueNextTick(); +} + +/* Init **********************************************/ + +// Clear the screen once, at startup +g.clear(); +// Start ticking +tick(); + +// Stop updates when LCD is off, restart when on +Bangle.on('lcdPower', (on) => { + if (on) { + tick(); // Start ticking + } else { + clearTickTimer(); // stop ticking + } +}); + +// Load widgets +Bangle.loadWidgets(); +Bangle.drawWidgets(); + +// Show launcher when middle button pressed +Bangle.setUI("clock"); \ No newline at end of file diff --git a/apps/ffcniftya/app.png b/apps/ffcniftya/app.png new file mode 100644 index 000000000..1cd8a49b7 Binary files /dev/null and b/apps/ffcniftya/app.png differ diff --git a/apps/gpsinfo/gps-info.js b/apps/gpsinfo/gps-info.js index 047c1bc17..df888651a 100644 --- a/apps/gpsinfo/gps-info.js +++ b/apps/gpsinfo/gps-info.js @@ -68,7 +68,7 @@ function onGPS(fix) { {type:"txt", font:"6x8", label:"", fillx:true, id:"time" }, {type:"txt", font:"6x8", label:"", fillx:true, id:"sat" }, {type:"txt", font:"6x8", label:"", fillx:true, id:"maidenhead" }, - ]},[],{lazy:true}); + ]},{lazy:true}); } else { layout = new Layout( { type:"v", c: [ @@ -80,9 +80,9 @@ function onGPS(fix) { {type:"txt", font:"6x8", pad:3, label:"Satellites" } ]}, {type:"txt", font:"6x8", label:"", id:"progress" } - ]},[],{lazy:true}); + ]},{lazy:true}); } - g.clearRect(0,24,g.getWidth(),g.getHeight()); + g.clearRect(0,24,g.getWidth(),g.getHeight()); layout.render(); } lastFix = fix; @@ -103,7 +103,7 @@ function onGPS(fix) { nofix = (nofix+1) % 4; layout.progress.label = ".".repeat(nofix) + " ".repeat(4-nofix); } - layout.render(); + layout.render(); } Bangle.loadWidgets(); diff --git a/apps/health/app.js b/apps/health/app.js index cb8651f4c..f2df52972 100644 --- a/apps/health/app.js +++ b/apps/health/app.js @@ -10,6 +10,7 @@ function menuMain() { function menuStepCount() { E.showMenu({ "":{title:"Step Counting"}, + "< Back":()=>menuMain(), "per hour":()=>stepsPerHour() }); } @@ -17,6 +18,7 @@ function menuStepCount() { function menuMovement() { E.showMenu({ "":{title:"Movement"}, + "< Back":()=>menuMain(), "per hour":()=>movementPerHour() }); } diff --git a/apps/speedo/speedo.js b/apps/speedo/speedo.js index 2e729c114..1d87859a8 100644 --- a/apps/speedo/speedo.js +++ b/apps/speedo/speedo.js @@ -23,7 +23,7 @@ function onGPS(fix) { {type:"txt", font:"10%", label:fix.satellites, pad:2, id:"sat" }, {type:"txt", font:"6x8", pad:3, label:"Satellites" } ]}, - ]},[],{lazy:true}); + ]},{lazy:true}); } else { layout = new Layout( { type:"v", c: [ @@ -34,7 +34,7 @@ function onGPS(fix) { {type:"txt", font:"10%", label:fix.satellites, pad:2, id:"sat" }, {type:"txt", font:"6x8", pad:3, label:"Satellites" } ]}, - ]},[],{lazy:true}); + ]},{lazy:true}); } g.clearRect(0,24,g.getWidth(),g.getHeight()); layout.render(); diff --git a/apps/weather/app.js b/apps/weather/app.js index 6dba14143..6a0852f81 100644 --- a/apps/weather/app.js +++ b/apps/weather/app.js @@ -35,7 +35,7 @@ var layout = new Layout({type:"v", bgCol: g.theme.bg, c: [ {type: "txt", font: "6x8", pad: 4, id: "updateTime", label: "15 minutes ago"}, ]}, {filly: 1}, -]}, null, {lazy: true}); +]}, {lazy: true}); function formatDuration(millis) { let pluralize = (n, w) => n + " " + w + (n == 1 ? "" : "s"); diff --git a/modules/Layout.js b/modules/Layout.js index 09e2a3d8c..03aa6249b 100644 --- a/modules/Layout.js +++ b/modules/Layout.js @@ -4,7 +4,7 @@ Usage: ``` var Layout = require("Layout"); -var layout = new Layout( layoutObject, btns, options ) +var layout = new Layout( layoutObject, options ) layout.render(optionalObject); ``` @@ -29,7 +29,7 @@ layoutObject has: * `undefined` - blank, can be used for padding * `"txt"` - a text label, with value `label` and `r` for text rotation. 'font' is required * `"btn"` - a button, with value `label` and callback `cb` - * `"img"` - an image where the function `src` is called to return an image to draw + * `"img"` - an image where `src` is an image, or a function which is called to return an image to draw * `"custom"` - a custom block where `render(layoutObj)` is called to render * `"h"` - Horizontal layout, `c` is an array of more `layoutObject` * `"v"` - Veritical layout, `c` is an array of more `layoutObject` @@ -47,15 +47,13 @@ layoutObject has: * A `filly` int to choose if the object should fill available space in y. 0=no, 1=yes, 2=2x more space * `width` and `height` fields to optionally specify minimum size -btns is an array of objects containing: - -* `label` - the text on the button -* `cb` - a callback function -* `cbl` - a callback function for long presses - options is an object containing: * `lazy` - a boolean specifying whether to enable automatic lazy rendering +* `btns` - array of objects containing: + * `label` - the text on the button + * `cb` - a callback function + * `cbl` - a callback function for long presses If automatic lazy rendering is enabled, calls to `layout.render()` will attempt to automatically determine what objects have changed or moved, clear their previous locations, and re-render just those objects. @@ -78,9 +76,8 @@ Other functions: */ -function Layout(layout, buttons, options) { +function Layout(layout, options) { this._l = this.l = layout; - this.b = buttons; // Do we have >1 physical buttons? this.physBtns = (process.env.HWVERSION==2) ? 1 : 3; this.yOffset = Object.keys(global.WIDGETS).length ? 24 : 0; @@ -88,7 +85,43 @@ function Layout(layout, buttons, options) { options = options || {}; this.lazy = options.lazy || false; - if (buttons) { + var btnList; + if (process.env.HWVERSION!=2) { + // no touchscreen, find any buttons in 'layout' + btnList = []; + function btnRecurser(l) { + if (l.type=="btn") btnList.push(l); + if (l.c) l.c.forEach(btnRecurser); + } + btnRecurser(layout); + if (btnList.length) { // there are buttons in 'layout' + // disable physical buttons - use them for back/next/select + this.physBtns = 0; + this.buttons = btnList; + this.selectedButton = -1; + Bangle.setUI("updown", dir=>{ + var s = this.selectedButton, l=this.buttons.length; + if (dir===undefined && this.buttons[s]) + return this.buttons[s].cb(); + if (this.buttons[s]) { + delete this.buttons[s].selected; + this.render(this.buttons[s]); + } + s += dir; + if (s<0) s+=lh; + if (s>=l) s-=l; + if (this.buttons[s]) { + this.buttons[s].selected = 1; + this.render(this.buttons[s]); + } + this.selectedButton = s; + }); + } + } + + if (options.btns) { + var buttons = options.btns; + this.b = buttons; if (this.physBtns >= buttons.length) { // Handler for button watch events function pressHandler(btn,e) { @@ -114,22 +147,25 @@ function Layout(layout, buttons, options) { {type:"v", pad:1, filly:1, c: buttons.map(b=>(b.type="txt",b.font="6x8",b.height=btnHeight,b.r=1,b))} ]}; } else { - let btnHeight = Math.floor((g.getHeight()-this.yOffset) / buttons.length); - this._l.width = g.getWidth()-20; // button width + // add 'soft' buttons + this._l.width = g.getWidth()-32; // button width this._l = {type:"h", c: [ this._l, - {type:"v", c: buttons.map(b=>(b.type="btn",b.h=btnHeight,b.w=32,b.r=1,b))} + {type:"v", c: buttons.map(b=>(b.type="btn",b.filly=1,b.width=32,b.r=1,b))} ]}; + // if we're selecting with physical buttons, add these to the list + if (btnList) btnList.push.apply(btnList, this._l.c[1].c); } } if (process.env.HWVERSION==2) { // Handler for touch events function touchHandler(l,e) { - if (l.type=="btn" && l.cb && e.x>=l.x && e.y>=l.y && e.x<=l.x+l.w && e.y<=l.y+l.h) - l.cb(e); + if (l.type=="btn" && l.cb && e.x>=l.x && e.y>=l.y && e.x<=l.x+l.w && e.y<=l.y+l.h) { + if (e.type==2 && l.cbl) l.cbl(e); else if (l.cb) l.cb(e); + } if (l.c) l.c.forEach(n => touchHandler(n,e)); } - Bangle.touchHandler = function(_,e){touchHandler(layout,e)}; + Bangle.touchHandler = (_,e)=>touchHandler(this._l,e); Bangle.on('touch',Bangle.touchHandler); } @@ -155,24 +191,6 @@ Layout.prototype.remove = function (l) { } }; -function wrappedLines(str, maxWidth) { - var lines = []; - for (var unwrappedLine of str.split("\n")) { - var words = unwrappedLine.split(" "); - var line = words.shift(); - for (var word of words) { - if (g.stringWidth(line + " " + word) > maxWidth) { - lines.push(line); - line = word; - } else { - line += " " + word; - } - } - lines.push(line); - } - return lines; -} - function prepareLazyRender(l, rectsToClear, drawList, rects, parentBg) { var bgCol = l.bgCol == null ? parentBg : g.toColor(l.bgCol); if (bgCol != parentBg || l.type == "txt" || l.type == "btn" || l.type == "img" || l.type == "custom") { @@ -211,8 +229,9 @@ Layout.prototype.render = function (l) { "txt":function(l){ if (l.wrap) { g.setFont(l.font,l.fsz).setFontAlign(0,-1); - var lines = wrappedLines(l.label, l.w); + var lines = g.wrapString(l.label, l.w); var y = l.y+((l.h-g.getFontHeight()*lines.length)>>1); + // TODO: on 2v11 we can just render in a single drawString call lines.forEach((line, i) => g.drawString(line, l.x+(l.w>>1), y+g.getFontHeight()*i)); } else { g.setFont(l.font,l.fsz).setFontAlign(0,0,l.r).drawString(l.label, l.x+(l.w>>1), l.y+(l.h>>1)); @@ -233,9 +252,9 @@ Layout.prototype.render = function (l) { x,y+h-5, x,y+4 ]; - g.setColor(g.theme.bgH).fillPoly(poly).setColor(l.selected ? g.theme.fgH : g.theme.fg).drawPoly(poly).setFont("4x6",2).setFontAlign(0,0,l.r).drawString(l.label,l.x+l.w/2,l.y+l.h/2); + g.setColor(l.selected?g.theme.bgH:g.theme.bg2).fillPoly(poly).setColor(l.selected ? g.theme.fgH : g.theme.fg2).drawPoly(poly).setFont("6x8",2).setFontAlign(0,0,l.r).drawString(l.label,l.x+l.w/2,l.y+l.h/2); }, "img":function(l){ - g.drawImage(l.src(), l.x + (0|l.pad), l.y + (0|l.pad)); + g.drawImage("function"==typeof l.src?l.src():l.src, l.x + (0|l.pad), l.y + (0|l.pad)); }, "custom":function(l){ l.render(l); },"h":function(l) { l.c.forEach(render); }, @@ -342,26 +361,16 @@ Layout.prototype.update = function() { if (l.wrap) { l._h = l._w = 0; } else { - g.setFont(l.font,l.fsz); - l._h = g.getFontHeight(); - l._w = g.stringWidth(l.label); + var m = g.setFont(l.font,l.fsz).stringMetrics(l.label); + l._w = m.width; l._h = m.height; } }, "btn": function(l) { - l._h = 24; - l._w = 14 + l.label.length*8; + l._h = 32; + l._w = 20 + l.label.length*12; }, "img": function(l) { - var src = l.src(); // get width and height out of image - if (src[0]) { - l._w = src[0]; - l._h = src[1]; - } else if ('object'==typeof src) { - l._w = ("width" in src) ? src.width : src.getWidth(); - l._h = ("height" in src) ? src.height : src.getHeight(); - } else { - var im = E.toString(src); - l._w = im.charCodeAt(0); - l._h = im.charCodeAt(1); - } + var m = g.imageMetrics("function"==typeof l.src?l.src():l.src); // get width and height out of image + l._w = m.width; + l._h = m.height; }, "": function(l) { // size should already be set up in width/height l._w = 0; diff --git a/tests/Layout/bin/espruino b/tests/Layout/bin/espruino index 3a423c185..8f9c1d878 100755 Binary files a/tests/Layout/bin/espruino and b/tests/Layout/bin/espruino differ diff --git a/tests/Layout/bin/runtest.sh b/tests/Layout/bin/runtest.sh index 5ce2ab21f..c85b3fe6c 100755 --- a/tests/Layout/bin/runtest.sh +++ b/tests/Layout/bin/runtest.sh @@ -1,7 +1,7 @@ #!/bin/bash # Requires Linux x64 (for ./espruino) # Also imagemagick for display - + cd `dirname $0`/.. if [ "$#" -ne 1 ]; then echo "USAGE:" @@ -19,7 +19,7 @@ SRCBMP=$SRCDIR/`basename $SRCJS .js`.bmp echo "TEST $SRCJS ($SRCBMP)" cat ../../modules/Layout.js > $TESTJS -echo 'Bangle = {};BTN1=0;process.env = process.env;process.env.HWVERSION=2;' >> $TESTJS +echo 'Bangle = { setUI : function(){} };BTN1=0;process.env = process.env;process.env.HWVERSION=2;' >> $TESTJS echo 'g = Graphics.createArrayBuffer(176,176,4);' >> $TESTJS cat $SRCJS >> $TESTJS || exit 1 echo 'layout.render()' >> $TESTJS @@ -39,5 +39,3 @@ else echo Files are the same exit 0 fi - - diff --git a/tests/Layout/tests/accellog.js b/tests/Layout/tests/accellog.js index 4ae865f4f..63b2ab410 100644 --- a/tests/Layout/tests/accellog.js +++ b/tests/Layout/tests/accellog.js @@ -6,8 +6,8 @@ var layout = new Layout({ type: "v", c: [ {type:"txt", id:"time", font:"6x8:2", label:" - ", pad:5}, {type:"txt", font:"6x8:2", label:"RECORDING", bgCol:"#f00", pad:5, fillx:1}, ] -},[ // Buttons... +}{btns:[ // Buttons... {label:"STOP", cb:()=>{}} -]); +]}); layout.samples.label = "123"; layout.time.label = "123s"; diff --git a/tests/Layout/tests/buttons_1_bangle1.bmp b/tests/Layout/tests/buttons_1_bangle1.bmp new file mode 100644 index 000000000..8da6d1e8a Binary files /dev/null and b/tests/Layout/tests/buttons_1_bangle1.bmp differ diff --git a/tests/Layout/tests/buttons_1_bangle1.js b/tests/Layout/tests/buttons_1_bangle1.js new file mode 100644 index 000000000..fb6fb29fa --- /dev/null +++ b/tests/Layout/tests/buttons_1_bangle1.js @@ -0,0 +1,9 @@ +var BTN2 = 1, BTN3=2; +process.env = process.env;process.env.HWVERSION=1; +g = Graphics.createArrayBuffer(240,240,4); + +var layout = new Layout({ type: "v", c: [ + {type:"txt", font:"6x8", label:"A test"}, +]},{btns:[ // Buttons... + {label:"STOP", cb:()=>{}}, +]}); diff --git a/tests/Layout/tests/buttons_1_bangle2.bmp b/tests/Layout/tests/buttons_1_bangle2.bmp new file mode 100644 index 000000000..2e4d1a256 Binary files /dev/null and b/tests/Layout/tests/buttons_1_bangle2.bmp differ diff --git a/tests/Layout/tests/buttons_1_bangle2.js b/tests/Layout/tests/buttons_1_bangle2.js new file mode 100644 index 000000000..74b6c96af --- /dev/null +++ b/tests/Layout/tests/buttons_1_bangle2.js @@ -0,0 +1,6 @@ + +var layout = new Layout({ type: "v", c: [ + {type:"txt", font:"6x8", label:"A test"}, +]},{btns:[ // Buttons... + {label:"STOP", cb:()=>{}}, +]}); diff --git a/tests/Layout/tests/buttons_3_bangle1.bmp b/tests/Layout/tests/buttons_3_bangle1.bmp new file mode 100644 index 000000000..4edc88d08 Binary files /dev/null and b/tests/Layout/tests/buttons_3_bangle1.bmp differ diff --git a/tests/Layout/tests/buttons_3_bangle1.js b/tests/Layout/tests/buttons_3_bangle1.js new file mode 100644 index 000000000..c8346f449 --- /dev/null +++ b/tests/Layout/tests/buttons_3_bangle1.js @@ -0,0 +1,11 @@ +var BTN2 = 1, BTN3=2; +process.env = process.env;process.env.HWVERSION=1; +g = Graphics.createArrayBuffer(240,240,4); + +var layout = new Layout({ type: "v", c: [ + {type:"txt", font:"6x8", label:"A test"}, +]},{btns:[ // Buttons... + {label:"A", cb:()=>{}}, + {label:"STOP", cb:()=>{}}, + {label:"B", cb:()=>{}}, +]}); diff --git a/tests/Layout/tests/buttons_3_bangle2.bmp b/tests/Layout/tests/buttons_3_bangle2.bmp new file mode 100644 index 000000000..4b9fa5b42 Binary files /dev/null and b/tests/Layout/tests/buttons_3_bangle2.bmp differ diff --git a/tests/Layout/tests/buttons_3_bangle2.js b/tests/Layout/tests/buttons_3_bangle2.js new file mode 100644 index 000000000..bf70fcb38 --- /dev/null +++ b/tests/Layout/tests/buttons_3_bangle2.js @@ -0,0 +1,8 @@ + +var layout = new Layout({ type: "v", c: [ + {type:"txt", font:"6x8", label:"A test"}, +]},{btns:[ // Buttons... + {label:"A", cb:()=>{}}, + {label:"STOP", cb:()=>{}}, + {label:"B", cb:()=>{}}, +]}); diff --git a/tests/Layout/tests/buttons_osd_bangle1.bmp b/tests/Layout/tests/buttons_osd_bangle1.bmp new file mode 100644 index 000000000..723075385 Binary files /dev/null and b/tests/Layout/tests/buttons_osd_bangle1.bmp differ diff --git a/tests/Layout/tests/buttons_osd_bangle1.js b/tests/Layout/tests/buttons_osd_bangle1.js new file mode 100644 index 000000000..108cb62b0 --- /dev/null +++ b/tests/Layout/tests/buttons_osd_bangle1.js @@ -0,0 +1,17 @@ +var BTN2 = 1, BTN3=2; +process.env = process.env;process.env.HWVERSION=1; +g = Graphics.createArrayBuffer(240,240,4); + +/* When displaying OSD buttons on Bangle.js 1 we should turn +the side buttons into 'soft' buttons and then use the physical +buttons for up/down selection */ + +var layout = new Layout({ type: "v", c: [ + {type:"txt", font:"6x8", label:"A test"}, + {type:"btn", label:"Button 1"}, + {type:"btn", label:"Button 2"} +]},{btns:[ // Buttons... + {label:"A", cb:()=>{}}, + {label:"STOP", cb:()=>{}}, + {label:"B", cb:()=>{}}, +]}); diff --git a/tests/Layout/tests/buttons_osd_bangle2.bmp b/tests/Layout/tests/buttons_osd_bangle2.bmp new file mode 100644 index 000000000..397c9e871 Binary files /dev/null and b/tests/Layout/tests/buttons_osd_bangle2.bmp differ diff --git a/tests/Layout/tests/buttons_osd_bangle2.js b/tests/Layout/tests/buttons_osd_bangle2.js new file mode 100644 index 000000000..8733eb691 --- /dev/null +++ b/tests/Layout/tests/buttons_osd_bangle2.js @@ -0,0 +1,10 @@ + +var layout = new Layout({ type: "v", c: [ + {type:"txt", font:"6x8", label:"A test"}, + {type:"btn", label:"Button 1"}, + {type:"btn", label:"Button 2"} +]},{btns:[ // Buttons... + {label:"A", cb:()=>{}}, + {label:"STOP", cb:()=>{}}, + {label:"B", cb:()=>{}}, +]}); diff --git a/tests/Layout/tests/padding.bmp b/tests/Layout/tests/padding.bmp index b2d192750..84ae4dc1b 100644 Binary files a/tests/Layout/tests/padding.bmp and b/tests/Layout/tests/padding.bmp differ diff --git a/tests/Layout/tests/padding_with_fill.bmp b/tests/Layout/tests/padding_with_fill.bmp index 2c785bbc0..9f82ed09f 100644 Binary files a/tests/Layout/tests/padding_with_fill.bmp and b/tests/Layout/tests/padding_with_fill.bmp differ