diff --git a/apps.json b/apps.json index f7a16f6b2..4ff6ba9c2 100644 --- a/apps.json +++ b/apps.json @@ -2522,7 +2522,7 @@ "name": "Cycling speed sensor", "shortName":"CSCSensor", "icon": "icons8-cycling-48.png", - "version":"0.04", + "version":"0.05", "description": "Read BLE enabled cycling speed and cadence sensor and display readings on watch", "tags": "outdoors,exercise,ble,bluetooth", "readme": "README.md", @@ -3540,7 +3540,8 @@ "icon": "app.png", "version":"0.01", "description": "A simple clock using the bold Anton font.", - "tags": "clock,b2", + "tags":"clock,b2", + "type":"clock", "storage": [ {"name":"antonclk.app.js","url":"app.js"}, {"name":"antonclk.img","url":"app-icon.js","evaluate":true} @@ -3551,7 +3552,8 @@ "icon": "app.png", "version":"0.01", "description": "A clock using a wave image by [Lillith May](https://www.instagram.com/_lilustrations_/). **Note: This requires a bugfix for #2049 on Bangle.js 1**", - "tags": "clock,b2", + "tags":"clock,b2", + "type":"clock", "storage": [ {"name":"waveclk.app.js","url":"app.js"}, {"name":"waveclk.img","url":"app-icon.js","evaluate":true} diff --git a/apps/antonclk/app-icon.js b/apps/antonclk/app-icon.js index 00892e9c3..fad03d50f 100644 --- a/apps/antonclk/app-icon.js +++ b/apps/antonclk/app-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("mEwge27dtAX4C+/dt+wFB/wCECIu3/dvBYNv34RC7/tCIu//99EYN9C4IpB74jG3379ovDFIIRBEYxHD/47D2wjHCIX+AQJHBCIIXBNZt/+5QBEZIgBAQX///9EZRWBBARHDEwhlC/9/EAJoBDQIOBNwyPCEYYCDJQ4CJSQ4CB0O2lojL2lwBIXFiwsK0f/KgUbuwRJo6cBPAO34cUmJHH7U/97tBgEGBIODEY/RXoOw7cAgHbtlxoojGx7hCjAjD20ANA1378MEIIAB4d0u5HGNAPYCAYAB2n2SQSPDjv3CIsF2lxEYto//+CoOGCIUt0O3EYtHvqMBvlw4UAgJQBqIjERgQDBsO+7FAhaMH64DB+4qB+3AgARG9uhIgQJD4dghd+7dLBQZoBaISwC4cArf27dpCIf/23f9uHCIQABhoNClsl20ttuwgYKBEAIAChOmCIOH/vx9ttwB2BDgMBAoIRBmnbpkbtk2ltsgAMCJQOwAgMBk+eq3AhiSBsE2GAX//4WCAAOBAoVbtt8mCJBgHHfYMHdgoRBott+zmDsEAn/tEwkC7UAVoYACgPbv4REAASTBEYY0BPIPwCJAjEu3Dvq8BCAnbsEwGgm2jbAC8EAjFvEAQREjuwDQXbvvx7cd2K/EgEb9oRCAoLOBjEAgk/A=")) +require("heatshrink").decompress(atob("mEwgX/AH4A/AAf+14BBAoPq/Wq1QFB+EP+kLAoNA+CdB3//yEP6ALB/sABYf8gEMgALB6ALJqoLB+tVgH//kQhkQhUABYImCIwPwh3whcA94UCgJHD+AXB/4LCcQQLCKYQLB+EDBZQFCBY/Qh4LJ4ALLl4LFioLCgE/KZMAv4XFBYimBC4/+BYw7DRwQLIV4ILWTQQLDOIUA/ALDAC+t1uv/263/6/Pq/YLC3vv//vM4Oq33rBYP6/u//2/C4Pr1YXC12vBwO+BYO69XmJDQA/ACIA==")) diff --git a/apps/cscsensor/ChangeLog b/apps/cscsensor/ChangeLog index 7be2ed3e2..9af9f9926 100644 --- a/apps/cscsensor/ChangeLog +++ b/apps/cscsensor/ChangeLog @@ -2,4 +2,4 @@ 0.02: Add wheel circumference settings dialog 0.03: Save total distance traveled 0.04: Add sensor battery level indicator - +0.05: Add cadence sensor support diff --git a/apps/cscsensor/README.md b/apps/cscsensor/README.md index a31a4dc28..e19ebe60e 100644 --- a/apps/cscsensor/README.md +++ b/apps/cscsensor/README.md @@ -13,6 +13,6 @@ Currently the app displays the following data: Button 1 resets all measurements except total distance traveled. The latter gets preserved by being written to storage every 0.1 miles and upon exiting the app. If the watch app has not received an update from the sensor for at least 10 seconds, pushing button 3 will attempt to reconnect to the sensor. +Button 2 switches between the display for cycling speed and cadence. -I do not have access to a cadence sensor at the moment, so only the speed part is currently implemented. Values displayed are imperial or metric (depending on locale), -the wheel circumference can be adjusted in the global settings app. +Values displayed are imperial or metric (depending on locale), cadence is in RPM, the wheel circumference can be adjusted in the global settings app. diff --git a/apps/cscsensor/cscsensor.app.js b/apps/cscsensor/cscsensor.app.js index c402c06da..3d4120269 100644 --- a/apps/cscsensor/cscsensor.app.js +++ b/apps/cscsensor/cscsensor.app.js @@ -28,6 +28,10 @@ class CSCSensor { this.distFactor = this.qMetric ? 1.609344 : 1; this.screenInit = true; this.batteryLevel = -1; + this.lastCrankTime = 0; + this.lastCrankRevs = 0; + this.showCadence = false; + this.cadence = 0; } reset() { @@ -40,6 +44,11 @@ class CSCSensor { this.screenInit = true; } + toggleDisplayCadence() { + this.showCadence = !this.showCadence; + this.screenInit = true; + } + setBatteryLevel(level) { if (level!=this.batteryLevel) { this.batteryLevel = level; @@ -62,7 +71,7 @@ class CSCSensor { else g.setFontVector(14).setFontAlign(0, 0, 0).setColor(0xffff).drawString("?", 16, 66); } - updateScreen() { + updateScreenRevs() { var dist = this.distFactor*(this.lastRevs-this.lastRevsStart)*this.wheelCirc/63360.0; var ddist = Math.round(100*dist)/100; var tdist = Math.round(this.distFactor*this.totaldist*10)/10; @@ -108,45 +117,88 @@ class CSCSensor { g.setColor(0).fillRect(88, 209, 238, 238); g.setColor(0xffff).drawString(tdist + " " + this.distUnit, 92, 226); } - + + updateScreenCadence() { + if (this.screenInit) { + for (var i=0; i<2; ++i) { + if ((i&1)==0) g.setColor(0, 0, 0); + else g.setColor(0x30cd); + g.fillRect(0, 48+i*32, 86, 48+(i+1)*32); + if ((i&1)==1) g.setColor(0); + else g.setColor(0x30cd); + g.fillRect(87, 48+i*32, 239, 48+(i+1)*32); + g.setColor(0.5, 0.5, 0.5).drawRect(87, 48+i*32, 239, 48+(i+1)*32).drawLine(0, 239, 239, 239);//.drawRect(0, 48, 87, 239); + g.moveTo(0, 80).lineTo(30, 80).lineTo(30, 48).lineTo(87, 48).lineTo(87, 239).lineTo(0, 239).lineTo(0, 80); + } + g.setFontAlign(1, 0, 0).setFontVector(19).setColor(1, 1, 0); + g.drawString("Cadence:", 87, 98); + this.drawBatteryIcon(); + this.screenInit = false; + } + g.setFontAlign(-1, 0, 0).setFontVector(26); + g.setColor(0).fillRect(88, 81, 238, 111); + g.setColor(0xffff).drawString(Math.round(this.cadence), 92, 98); + } + + updateScreen() { + if (!this.showCadence) { + this.updateScreenRevs(); + } else { + this.updateScreenCadence(); + } + } + updateSensor(event) { var qChanged = false; if (event.target.uuid == "0x2a5b") { - var wheelRevs = event.target.value.getUint32(1, true); - var dRevs = (this.lastRevs>0 ? wheelRevs-this.lastRevs : 0); - if (dRevs>0) { - qChanged = true; - this.totaldist += dRevs*this.wheelCirc/63360.0; - if ((this.totaldist-this.settings.totaldist)>0.1) { - this.settings.totaldist = this.totaldist; - storage.writeJSON(SETTINGS_FILE, this.settings); + if (event.target.value.getUint8(0, true) & 0x2) { + // crank revolution + const crankRevs = event.target.value.getUint16(1, true); + const crankTime = event.target.value.getUint16(3, true); + if (crankTime > this.lastCrankTime) { + this.cadence = (crankRevs-this.lastCrankRevs)/(crankTime-this.lastCrankTime)*(60*1024); + qChanged = true; } - } - this.lastRevs = wheelRevs; - if (this.lastRevsStart<0) this.lastRevsStart = wheelRevs; - var wheelTime = event.target.value.getUint16(5, true); - var dT = (wheelTime-this.lastTime)/1024; - var dBT = (Date.now()-this.lastBangleTime)/1000; - this.lastBangleTime = Date.now(); - if (dT<0) dT+=64; - if (Math.abs(dT-dBT)>3) dT = dBT; - this.lastTime = wheelTime; - this.speed = this.lastSpeed; - if (dRevs>0 && dT>0) { - this.speed = (dRevs*this.wheelCirc/63360.0)*3600/dT; - this.speedFailed = 0; - this.movingTime += dT; - } - else { - this.speedFailed++; - qChanged = false; - if (this.speedFailed>3) { - this.speed = 0; - qChanged = (this.lastSpeed>0); + this.lastCrankRevs = crankRevs; + this.lastCrankTime = crankTime; + } else { + // wheel revolution + var wheelRevs = event.target.value.getUint32(1, true); + var dRevs = (this.lastRevs>0 ? wheelRevs-this.lastRevs : 0); + if (dRevs>0) { + qChanged = true; + this.totaldist += dRevs*this.wheelCirc/63360.0; + if ((this.totaldist-this.settings.totaldist)>0.1) { + this.settings.totaldist = this.totaldist; + storage.writeJSON(SETTINGS_FILE, this.settings); + } } + this.lastRevs = wheelRevs; + if (this.lastRevsStart<0) this.lastRevsStart = wheelRevs; + var wheelTime = event.target.value.getUint16(5, true); + var dT = (wheelTime-this.lastTime)/1024; + var dBT = (Date.now()-this.lastBangleTime)/1000; + this.lastBangleTime = Date.now(); + if (dT<0) dT+=64; + if (Math.abs(dT-dBT)>3) dT = dBT; + this.lastTime = wheelTime; + this.speed = this.lastSpeed; + if (dRevs>0 && dT>0) { + this.speed = (dRevs*this.wheelCirc/63360.0)*3600/dT; + this.speedFailed = 0; + this.movingTime += dT; + } + else { + this.speedFailed++; + qChanged = false; + if (this.speedFailed>3) { + this.speed = 0; + qChanged = (this.lastSpeed>0); + } + } + this.lastSpeed = this.speed; + if (this.speed>this.maxSpeed && (this.movingTime>3 || this.speed<20) && this.speed<50) this.maxSpeed = this.speed; } - this.lastSpeed = this.speed; - if (this.speed>this.maxSpeed && (this.movingTime>3 || this.speed<20) && this.speed<50) this.maxSpeed = this.speed; } if (qChanged && this.qUpdateScreen) this.updateScreen(); } @@ -199,6 +251,7 @@ connection_setup(); setWatch(function() { mySensor.reset(); g.clearRect(0, 48, 239, 239); mySensor.updateScreen(); }, BTN1, {repeat:true, debounce:20}); E.on('kill',()=>{ if (gatt!=undefined) gatt.disconnect(); mySensor.settings.totaldist = mySensor.totaldist; storage.writeJSON(SETTINGS_FILE, mySensor.settings); }); setWatch(function() { if (Date.now()-mySensor.lastBangleTime>10000) connection_setup(); }, BTN3, {repeat:true, debounce:20}); +setWatch(function() { mySensor.toggleDisplayCadence(); g.clearRect(0, 48, 239, 239); mySensor.updateScreen(); }, BTN2, {repeat:true, debounce:20}); NRF.on('disconnect', connection_setup); Bangle.loadWidgets(); diff --git a/apps/waveclk/app-icon.js b/apps/waveclk/app-icon.js index fad03d50f..00892e9c3 100644 --- a/apps/waveclk/app-icon.js +++ b/apps/waveclk/app-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("mEwgX/AH4A/AAf+14BBAoPq/Wq1QFB+EP+kLAoNA+CdB3//yEP6ALB/sABYf8gEMgALB6ALJqoLB+tVgH//kQhkQhUABYImCIwPwh3whcA94UCgJHD+AXB/4LCcQQLCKYQLB+EDBZQFCBY/Qh4LJ4ALLl4LFioLCgE/KZMAv4XFBYimBC4/+BYw7DRwQLIV4ILWTQQLDOIUA/ALDAC+t1uv/263/6/Pq/YLC3vv//vM4Oq33rBYP6/u//2/C4Pr1YXC12vBwO+BYO69XmJDQA/ACIA==")) +require("heatshrink").decompress(atob("mEwge27dtAX4C+/dt+wFB/wCECIu3/dvBYNv34RC7/tCIu//99EYN9C4IpB74jG3379ovDFIIRBEYxHD/47D2wjHCIX+AQJHBCIIXBNZt/+5QBEZIgBAQX///9EZRWBBARHDEwhlC/9/EAJoBDQIOBNwyPCEYYCDJQ4CJSQ4CB0O2lojL2lwBIXFiwsK0f/KgUbuwRJo6cBPAO34cUmJHH7U/97tBgEGBIODEY/RXoOw7cAgHbtlxoojGx7hCjAjD20ANA1378MEIIAB4d0u5HGNAPYCAYAB2n2SQSPDjv3CIsF2lxEYto//+CoOGCIUt0O3EYtHvqMBvlw4UAgJQBqIjERgQDBsO+7FAhaMH64DB+4qB+3AgARG9uhIgQJD4dghd+7dLBQZoBaISwC4cArf27dpCIf/23f9uHCIQABhoNClsl20ttuwgYKBEAIAChOmCIOH/vx9ttwB2BDgMBAoIRBmnbpkbtk2ltsgAMCJQOwAgMBk+eq3AhiSBsE2GAX//4WCAAOBAoVbtt8mCJBgHHfYMHdgoRBott+zmDsEAn/tEwkC7UAVoYACgPbv4REAASTBEYY0BPIPwCJAjEu3Dvq8BCAnbsEwGgm2jbAC8EAjFvEAQREjuwDQXbvvx7cd2K/EgEb9oRCAoLOBjEAgk/A=")) diff --git a/modules/Layout.js b/modules/Layout.js index 521b191b6..9f3a805be 100644 --- a/modules/Layout.js +++ b/modules/Layout.js @@ -154,16 +154,20 @@ function touchHandler(l,e) { if (l.c) l.c.forEach(n => touchHandler(n,e)); } -function prepareLazyRender(l, rectsToClear, drawList, rects, bgCol) { - if ((l.bgCol != null && l.bgCol != bgCol) || l.type == "txt" || l.type == "btn" || l.type == "img" || l.type == "custom") { +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") { // Hash the layoutObject without including its children - let c = l.c; + var c = l.c; delete l.c; - let hash = "H"+E.CRC32(E.toJS(l)); // String keys maintain insertion order + var hash = "H"+E.CRC32(E.toJS(l)); // String keys maintain insertion order if (c) l.c = c; if (!delete rectsToClear[hash]) { - rects[hash] = {bg: bgCol, r: [l.x,l.y,l.x+l.w-1,l.y+l.h-1]}; + rects[hash] = { + bg: parentBg == null ? g.theme.bg : parentBg, + r: [l.x,l.y,l.x+l.w-1,l.y+l.h-1] + }; if (drawList) { drawList.push(l); drawList = null; // Prevent children from being redundantly added to the drawList @@ -171,7 +175,7 @@ function prepareLazyRender(l, rectsToClear, drawList, rects, bgCol) { } } - if (l.c) for (let ch of l.c) prepareLazyRender(ch, rectsToClear, drawList, rects, l.bgCol == null ? bgCol : l.bgCol); + if (l.c) for (var ch of l.c) prepareLazyRender(ch, rectsToClear, drawList, rects, bgCol); } Layout.prototype.render = function (l) { @@ -189,20 +193,24 @@ Layout.prototype.render = function (l) { "txt":function(l){ g.setFont(l.font,l.fsz).setFontAlign(0,0,l.r).drawString(l.label, l.x+(l.w>>1), l.y+(l.h>>1)); }, "btn":function(l){ + var x = l.x+(0|l.pad); + var y = l.y+(0|l.pad); + var w = l.w-(l.pad<<1); + var h = l.h-(l.pad<<1); var poly = [ - l.x,l.y+4, - l.x+4,l.y, - l.x+l.w-5,l.y, - l.x+l.w-1,l.y+4, - l.x+l.w-1,l.y+l.h-5, - l.x+l.w-5,l.y+l.h-1, - l.x+4,l.y+l.h-1, - l.x,l.y+l.h-5, - l.x,l.y+4 + x,y+4, + x+4,y, + x+w-5,y, + x+w-1,y+4, + x+w-1,y+h-5, + x+w-5,y+h-1, + x+4,y+h-1, + 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); }, "img":function(l){ - g.drawImage(l.src(), l.x, l.y); + g.drawImage(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); }, @@ -216,7 +224,7 @@ Layout.prototype.render = function (l) { if (!this.rects) this.rects = {}; var rectsToClear = this.rects.clone(); var drawList = []; - prepareLazyRender(l, rectsToClear, drawList, this.rects, g.getBgColor()); + prepareLazyRender(l, rectsToClear, drawList, this.rects, null); for (var h in rectsToClear) delete this.rects[h]; var clearList = Object.keys(rectsToClear).map(k=>rectsToClear[k]).reverse(); // Rects are cleared in reverse order so that the original bg color is restored for (var r of clearList) g.setBgColor(r.bg).clearRect.apply(g, r.r); @@ -231,36 +239,28 @@ Layout.prototype.layout = function (l) { // exw,exh = extra width/height available switch (l.type) { case "h": { - let x = l.x + (l.w-l._w)/2; + var x = l.x + (0|l.pad); var fillx = l.c && l.c.reduce((a,l)=>a+(0|l.fillx),0); - if (fillx) { x = l.x; } + if (!fillx) { x += (l.w-l._w)/2; } l.c.forEach(c => { c.w = c._w + ((0|c.fillx)*(l.w-l._w)/(fillx||1)); - c.h = c.filly ? l.h : c._h; - if (c.pad) { - c.w += c.pad*2; - c.h += c.pad*2; - } + c.h = c.filly ? l.h - (l.pad<<1) : c._h; c.x = x; - c.y = l.y + (1+(0|c.valign))*(l.h-c.h)/2; + c.y = l.y + (0|l.pad) + (1+(0|c.valign))*(l.h-(l.pad<<1)-c.h)/2; x += c.w; if (c.c) this.layout(c); }); break; } case "v": { - let y = l.y + (l.h-l._h)/2; + var y = l.y + (0|l.pad);; var filly = l.c && l.c.reduce((a,l)=>a+(0|l.filly),0); - if (filly) { y = l.y; } + if (!filly) { y += (l.h-l._h)/2 } l.c.forEach(c => { - c.w = c.fillx ? l.w : c._w; + c.w = c.fillx ? l.w - (l.pad<<1) : c._w; c.h = c._h + ((0|c.filly)*(l.h-l._h)/(filly||1)); - if (c.pad) { - c.w += c.pad*2; - c.h += c.pad*2; - } c.y = y; - c.x = l.x + (1+(0|c.halign))*(l.w-c.w)/2; + c.x = l.x + (0|l.pad) + (1+(0|c.halign))*(l.w-(l.pad<<1)-c.w)/2; y += c.h; if (c.c) this.layout(c); }); @@ -288,8 +288,8 @@ Layout.prototype.update = function() { if (l.r&1) { // rotation var t = l._w;l._w=l._h;l._h=t; } - l._w = Math.max(l._w, 0|l.width); - l._h = Math.max(l._h, 0|l.height); + l._w = Math.max(l._w + (l.pad<<1), 0|l.width); + l._h = Math.max(l._h + (l.pad<<1), 0|l.height); } var cb = { "txt" : function(l) { @@ -327,16 +327,16 @@ Layout.prototype.update = function() { l._h = 0; }, "h": function(l) { l.c.forEach(updateMin); - l._h = l.c.reduce((a,b)=>Math.max(a,b._h+(b.pad<<1)),0); - l._w = l.c.reduce((a,b)=>a+b._w+(b.pad<<1),0); - if (l.c.some(c=>c.fillx)) l.fillx = 1; - if (l.c.some(c=>c.filly)) l.filly = 1; + l._h = l.c.reduce((a,b)=>Math.max(a,b._h),0); + l._w = l.c.reduce((a,b)=>a+b._w,0); + if (l.fillx == null && l.c.some(c=>c.fillx)) l.fillx = 1; + if (l.filly == null && l.c.some(c=>c.filly)) l.filly = 1; }, "v": function(l) { l.c.forEach(updateMin); - l._h = l.c.reduce((a,b)=>a+b._h+(b.pad<<1),0); - l._w = l.c.reduce((a,b)=>Math.max(a,b._w+(b.pad<<1)),0); - if (l.c.some(c=>c.fillx)) l.fillx = 1; - if (l.c.some(c=>c.filly)) l.filly = 1; + l._h = l.c.reduce((a,b)=>a+b._h,0); + l._w = l.c.reduce((a,b)=>Math.max(a,b._w),0); + if (l.fillx == null && l.c.some(c=>c.fillx)) l.fillx = 1; + if (l.filly == null && l.c.some(c=>c.filly)) l.filly = 1; } }; updateMin(l); diff --git a/tests/Layout/tests/accellog.bmp b/tests/Layout/tests/accellog.bmp index 7ebe01b21..c0bbaf4fc 100644 Binary files a/tests/Layout/tests/accellog.bmp and b/tests/Layout/tests/accellog.bmp differ diff --git a/tests/Layout/tests/filly_issue820.bmp b/tests/Layout/tests/filly_issue820.bmp new file mode 100644 index 000000000..886ba97d8 Binary files /dev/null and b/tests/Layout/tests/filly_issue820.bmp differ diff --git a/tests/Layout/tests/filly_issue820.js b/tests/Layout/tests/filly_issue820.js new file mode 100644 index 000000000..4b813fadf --- /dev/null +++ b/tests/Layout/tests/filly_issue820.js @@ -0,0 +1,9 @@ +g.clear(); +var layout = new Layout({type:"h", filly: 0, c: [ + {type: "txt", font: "50%", label: "A"}, + {type:"v", c: [ + {type: "txt", font: "10%", label: "B"}, + {filly: 1}, + {type: "txt", font: "10%", label: "C"}, + ]}, +]}); diff --git a/tests/Layout/tests/padding.bmp b/tests/Layout/tests/padding.bmp new file mode 100644 index 000000000..b2d192750 Binary files /dev/null and b/tests/Layout/tests/padding.bmp differ diff --git a/tests/Layout/tests/padding.js b/tests/Layout/tests/padding.js new file mode 100644 index 000000000..355dfd90f --- /dev/null +++ b/tests/Layout/tests/padding.js @@ -0,0 +1,26 @@ +var img = () => ({ + width : 8, height : 8, bpp : 4, + transparent : 1, + buffer : E.toArrayBuffer(atob("Ee7uER7u7uHuDuDu7u7u7u7u7u7g7u4OHgAA4RHu7hE=")) +}); + +var layout = new Layout({type: "v", c: [ + {type: "txt", font: "6x8", bgCol: "#F00", pad: 5, label: "TEXT"}, + {type: "img", font: "6x8", bgCol: "#0F0", pad: 5, src: img}, + {type: "btn", font: "6x8", bgCol: "#00F", pad: 5, label: "BTN"}, + {type: "v", bgCol: "#F0F", pad: 2, c: [ + {type: "txt", font: "6x8", bgCol: "#F00", label: "v with children"}, + {type: "txt", font: "6x8", bgCol: "#0F0", halign: -1, label: "halign -1"}, + {type: "txt", font: "6x8", bgCol: "#00F", halign: 1, label: "halign 1"}, + ]}, + {type: "h", bgCol: "#0FF", pad: 2, c: [ + {type: "txt", font: "6x8:2", bgCol: "#F00", label: "h"}, + {type: "txt", font: "6x8", bgCol: "#0F0", valign: -1, label: "valign -1"}, + {type: "txt", font: "6x8", bgCol: "#00F", valign: 1, label: "valign 1"}, + ]}, + {type: "h", bgCol: "#FF0", pad: 2, c: [ + {type: "v", bgCol: "#0F0", pad: 2, c: [ + {type: "txt", font: "6x8", bgCol: "#F00", pad: 2, label: "nested"}, + ]}, + ]}, +]}); diff --git a/tests/Layout/tests/padding_issue819_2.bmp b/tests/Layout/tests/padding_issue819_2.bmp new file mode 100644 index 000000000..549736065 Binary files /dev/null and b/tests/Layout/tests/padding_issue819_2.bmp differ diff --git a/tests/Layout/tests/padding_issue819_2.js b/tests/Layout/tests/padding_issue819_2.js new file mode 100644 index 000000000..874d28867 --- /dev/null +++ b/tests/Layout/tests/padding_issue819_2.js @@ -0,0 +1,7 @@ +var layout = new Layout({type: "v", c: [ + {type: "h", pad: 20, c: [ + {type: "txt", font: "10%", label: "abcd"}, + {fillx: 1}, + {type: "txt", font: "10%", label: "1234"}, + ]}, +]}); diff --git a/tests/Layout/tests/padding_with_fill.bmp b/tests/Layout/tests/padding_with_fill.bmp new file mode 100644 index 000000000..15e05b0d9 Binary files /dev/null and b/tests/Layout/tests/padding_with_fill.bmp differ diff --git a/tests/Layout/tests/padding_with_fill.js b/tests/Layout/tests/padding_with_fill.js new file mode 100644 index 000000000..dede39722 --- /dev/null +++ b/tests/Layout/tests/padding_with_fill.js @@ -0,0 +1,26 @@ +var img = () => ({ + width : 8, height : 8, bpp : 4, + transparent : 1, + buffer : E.toArrayBuffer(atob("Ee7uER7u7uHuDuDu7u7u7u7u7u7g7u4OHgAA4RHu7hE=")) +}); + +var layout = new Layout({type: "v", c: [ + {type: "txt", font: "6x8", bgCol: "#F00", fillx: 1, pad: 5, label: "TEXT"}, + {type: "img", font: "6x8", bgCol: "#0F0", filly: 1, fillx: 1,pad: 5, src: img}, + {type: "btn", font: "6x8", bgCol: "#00F", fillx: 1, pad: 5, label: "BTN"}, + {type: "v", bgCol: "#F0F", pad: 2, c: [ + {type: "txt", font: "6x8", bgCol: "#F00", fillx: 1, filly: 1, label: "v with children"}, + {type: "txt", font: "6x8", bgCol: "#0F0", halign: -1, label: "halign -1"}, + {type: "txt", font: "6x8", bgCol: "#00F", halign: 1, label: "halign 1"}, + ]}, + {type: "h", bgCol: "#0FF", pad: 2, c: [ + {type: "txt", font: "6x8:2", bgCol: "#F00", fillx: 1, filly: 1, label: "h"}, + {type: "txt", font: "6x8", bgCol: "#0F0", valign: -1, label: "valign -1"}, + {type: "txt", font: "6x8", bgCol: "#00F", valign: 1, label: "valign 1"}, + ]}, + {type: "h", bgCol: "#FF0", pad: 2, c: [ + {type: "v", bgCol: "#0F0", pad: 2, c: [ + {type: "txt", font: "6x8", bgCol: "#F00", fillx: 1, filly: 1, pad: 2, label: "nested"}, + ]}, + ]}, +]});