diff --git a/apps/meridian/ChangeLog b/apps/meridian/ChangeLog new file mode 100644 index 000000000..09953593e --- /dev/null +++ b/apps/meridian/ChangeLog @@ -0,0 +1 @@ +0.01: New Clock! diff --git a/apps/meridian/README.md b/apps/meridian/README.md new file mode 100644 index 000000000..1fdd03546 --- /dev/null +++ b/apps/meridian/README.md @@ -0,0 +1,11 @@ +# Meridian Clock + +An elegant clock with 2 clock info + +## Usage + +Tap on a widget and swipe left/right/up/down to change the displayed info + +## Creator + +Spioune diff --git a/apps/meridian/app-icon.js b/apps/meridian/app-icon.js new file mode 100644 index 000000000..8c37d4e1b --- /dev/null +++ b/apps/meridian/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwgMAkEAwEEBIMQAo8IDpMYAq0wAoosCAoU8gNgAoV+gwRDvgXDsAFFEYgFR4AFQIgQFHgIFC8AFDg4HBhwWEngFE+AEDgYuEh4QEDgoASiGII4kMAYLWBgDKBggzEgb/YICSJBGwIFDghCDAoQ")) \ No newline at end of file diff --git a/apps/meridian/app.js b/apps/meridian/app.js new file mode 100644 index 000000000..26de3df5f --- /dev/null +++ b/apps/meridian/app.js @@ -0,0 +1,153 @@ +function getArcXY(centerX,centerY,radius,angle){ + var s,r = []; + s = 2 * Math.PI * angle / 360; + r.push(centerX + Math.round(Math.cos(s) * radius)); + r.push(centerY + Math.round(Math.sin(s) * radius)); + return r; +} + +function getArc(centerX,centerY,radius,startAngle,endAngle){ + var r = [], actAngle = startAngle; + var stepAngle = (radius + radius) * Math.PI / 60; + stepAngle = 6; + while(actAngle < endAngle){ + r = r.concat(getArcXY(centerX,centerY,radius,actAngle)); + actAngle += stepAngle; + actAngle = Math.min(actAngle,endAngle); + } + return r.concat(getArcXY(centerX,centerY,radius,endAngle)); +} + +function fillLine(x1,y1,x2,y2,thickness){ + const angle = Math.atan2(y2 - y1, x2 - x1); + const offset_x = thickness * Math.sin(angle) / 2; + const offset_y = thickness * Math.cos(angle) / 2; + g.fillPoly([ + x1 + offset_x, + y1 - offset_y, + x1 - offset_x, + y1 + offset_y, + x2 - offset_x, + y2 + offset_y, + x2 + offset_x, + y2 - offset_y + ],true); +} + +function drawInfoClock(itm,info,options){ + g.reset(); + + if (options.focus) + g.drawCircle(options.x+options.w/2, options.y+options.h/2, options.w/2+3); + + if (info.img) + g.drawImage(info.img, info.img.width ? options.x+options.w/2-info.img.width/2 : options.x, options.y); + + if(info.text) + g.setFont("6x8").setFontAlign(0,1).drawString(info.text, options.x+options.w/2,options.y+options.h); +} + +var clockInfoItems = require("clock_info").load(); + +clockInfoItems[0].items.unshift({ + name : "BatteryRing", + hasRange : true, + get : () => { + var s = 30; + var mid=s/2; + var v = E.getBattery(); + var g = Graphics.createArrayBuffer(s,s,4); + + const outerarc = getArc(mid,mid,14,-90,Math.max(v*3.6, 10)-90); + const innerarc = getArc(mid,mid,11,-92,Math.max(v*3.6, 10)-88); + + g.reset(); + g.transparent=0; + g.setColor('#00FF00').fillPoly([mid, mid].concat(outerarc)); + g.setColor('#000').fillPoly([mid, mid].concat(innerarc)); + g.setFont("6x8").setColor('#FFF').setFontAlign(0, 0).drawString(v, mid, mid); + return { v : v, min:0, max:100, img : g.asImage("object") }; + }, + show : function() { }, + hide : function() { }, +}); + +var topleft = require("clock_info").addInteractive(clockInfoItems, { + x : g.getWidth()*(1/4)-15, y: g.getHeight()*(1/4)-15, w: 30, h:30, + draw : (itm,info,options)=>{ + topleft.info = info; + topleft.options = options; + if(typeof draw === 'function') draw(); + } +}); + +var topright = require("clock_info").addInteractive(clockInfoItems, { + x : g.getWidth()*(3/4)-15, y: g.getHeight()*(1/4)-15, w: 30, h:30, + draw : (itm,info,options)=>{ + topright.info = info; + topright.options = options; + if(typeof draw === 'function') draw(); + } +}); + +var timeout; + +function draw(){ + if(timeout){ + clearTimeout(timeout); + timeout = undefined; + } + + g.setTheme({fg:0xFFFF, bg:0}); + g.reset().clear(); + + const mid=g.getWidth()/2; + + for(let i = 0; i<12;i++){ + const angle = i*Math.PI/6; + fillLine(mid, mid, mid+Math.cos(angle)*120, mid+Math.sin(angle)*120, 3); + } + + g.clearRect(10,10,g.getWidth()-10,g.getHeight()-10); + + if(topleft && topleft.info && topleft.options) + drawInfoClock(topleft.itm, topleft.info, topleft.options); + if(topright && topright.info && topright.options) + drawInfoClock(topright.itm, topright.info, topright.options); + + const now = new Date(); + + g.setFont("Vector",14); + g.setColor('#FFF'); + g.setFontAlign(0,0); + // Date (ex. MON 8) + g.drawString(require("locale").dow(now, 1).toUpperCase() + " " + now.getDate(), g.getWidth()/2, g.getHeight()*(3/4)); + + + let rhour = (now.getHours()*Math.PI/6)+(now.getMinutes()*Math.PI/30/12)-Math.PI/2; + let rmin = now.getMinutes()*Math.PI/30-Math.PI/2; + + // Middle circle + g.fillCircle(mid,mid,4); + + // Hour hand + fillLine(mid, mid, mid+Math.cos(rhour)*10, mid+Math.sin(rhour)*10,3); + fillLine(mid+Math.cos(rhour)*10, mid+Math.sin(rhour)*10, mid+Math.cos(rhour)*50, mid+Math.sin(rhour)*50,7); + + // Minute hand + fillLine(mid, mid, mid+Math.cos(rmin)*10, mid+Math.sin(rmin)*10,3); + fillLine(mid+Math.cos(rmin)*10, mid+Math.sin(rmin)*10, mid+Math.cos(rmin)*76, mid+Math.sin(rmin)*76,7); + + + if(new Date().getMinutes()==0){ + Bangle.buzz(); + } + + timeout = setTimeout(()=>{ + timeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); +} + +draw(); +Bangle.setUI("clock"); diff --git a/apps/meridian/icon.png b/apps/meridian/icon.png new file mode 100644 index 000000000..3edf38218 Binary files /dev/null and b/apps/meridian/icon.png differ diff --git a/apps/meridian/metadata.json b/apps/meridian/metadata.json new file mode 100644 index 000000000..ab4cdbed2 --- /dev/null +++ b/apps/meridian/metadata.json @@ -0,0 +1,17 @@ +{ + "id": "meridian", + "name": "Meridian Clock", + "shortName": "Meridian", + "version": "0.01", + "description": "An elegant clock", + "screenshots": [{ "url": "screenshot.png" }], + "icon": "icon.png", + "type": "clock", + "tags": "clock", + "supports": ["BANGLEJS2"], + "readme": "README.md", + "storage": [ + { "name": "meridian.app.js", "url": "app.js" }, + { "name": "meridian.img", "url": "app-icon.js", "evaluate": true } + ] +} diff --git a/apps/meridian/screenshot.png b/apps/meridian/screenshot.png new file mode 100644 index 000000000..2c86aca9b Binary files /dev/null and b/apps/meridian/screenshot.png differ