From b4cd690c48b57eb9702b005725860147379955b9 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 3 May 2024 11:31:33 +0100 Subject: [PATCH] clockinfo: Add drawFilledImage to allow drawing icons with a separately coloured middle0.12: Add drawFilledImage to allow drawing icons with a separately coloured middle pebblepp/analogquadclk: not use drawFilledImage fn Add twotwoclock, a 2x2 digital clock with clockinfos --- apps/analogquadclk/ChangeLog | 3 +- apps/analogquadclk/app.js | 18 +--- apps/analogquadclk/metadata.json | 2 +- apps/clock_info/ChangeLog | 1 + apps/clock_info/lib.js | 40 ++++++++ apps/clock_info/metadata.json | 4 +- apps/pebblepp/ChangeLog | 3 +- apps/pebblepp/app.js | 14 +-- apps/pebblepp/metadata.json | 2 +- apps/twotwoclock/ChangeLog | 1 + apps/twotwoclock/app-icon.js | 1 + apps/twotwoclock/app.js | 159 +++++++++++++++++++++++++++++++ apps/twotwoclock/icon.png | Bin 0 -> 23734 bytes apps/twotwoclock/metadata.json | 16 ++++ apps/twotwoclock/screenshot.png | Bin 0 -> 7438 bytes 15 files changed, 231 insertions(+), 33 deletions(-) create mode 100644 apps/twotwoclock/ChangeLog create mode 100644 apps/twotwoclock/app-icon.js create mode 100644 apps/twotwoclock/app.js create mode 100644 apps/twotwoclock/icon.png create mode 100644 apps/twotwoclock/metadata.json create mode 100644 apps/twotwoclock/screenshot.png diff --git a/apps/analogquadclk/ChangeLog b/apps/analogquadclk/ChangeLog index 841543254..d1bd8762f 100644 --- a/apps/analogquadclk/ChangeLog +++ b/apps/analogquadclk/ChangeLog @@ -1,2 +1,3 @@ 0.01: New Clock! -0.02: Fix fastloading memory leak and clockinfo overwritten by hands \ No newline at end of file +0.02: Fix fastloading memory leak and clockinfo overwritten by hands +0.03: Use new clockinfo lib with function to render images wirh borders \ No newline at end of file diff --git a/apps/analogquadclk/app.js b/apps/analogquadclk/app.js index 9fd81a6f4..dbaa49825 100644 --- a/apps/analogquadclk/app.js +++ b/apps/analogquadclk/app.js @@ -102,6 +102,7 @@ // Show launcher when middle button pressed Bangle.setUI({ mode: "clock", + redraw : draw, remove: function() { if (drawTimeout) clearTimeout(drawTimeout); drawTimeout = undefined; @@ -116,9 +117,6 @@ Bangle.loadWidgets(); require("widget_utils").hide(); - // used for clockinfo image rendering - let clockInfoG = Graphics.createArrayBuffer(28, 28, 2, {msb:true}); - clockInfoG.transparent = 3; // render clockinfos let clockInfoDraw = function(itm, info, options) { // itm: the item containing name/hasRange/etc @@ -139,18 +137,8 @@ fg = g.toColor("#f00"); } - if (info.img) { - //g.drawImage(info.img, left ? 2 : W - 27, top ? 18 : H - 41); // draw the image - // fiddle around colouring the border and inside of the image - clockInfoG.clear(1); - // do a border - images need to be transparent for this - clockInfoG.setColor(2).drawImage(info.img, 1,1).drawImage(info.img, 3,1). - drawImage(info.img, 1,3).drawImage(info.img, 3,3); - clockInfoG.setColor(1).drawImage(info.img, 2,2); // main image - clockInfoG.floodFill(27,27,3); // flood fill edge to transparent - clockInfoG.palette = new Uint16Array([bg,fg,bg/*border*/, g.toColor("#888")]); - g.drawImage(clockInfoG, imgx-1, imgy-1); - } + if (info.img) + require("clock_info").drawBorderedImage(info.img,imgx,imgy); g.setFont("6x8:2").setFontAlign(left ? -1 : 1, -1); g.setColor(bg).drawString(info.text, textx-2, texty). // draw the text background diff --git a/apps/analogquadclk/metadata.json b/apps/analogquadclk/metadata.json index 00d46e160..0afc15e99 100644 --- a/apps/analogquadclk/metadata.json +++ b/apps/analogquadclk/metadata.json @@ -1,7 +1,7 @@ { "id": "analogquadclk", "name": "Analog Quad Clock", "shortName":"Quad Clock", - "version":"0.02", + "version":"0.03", "description": "An analog clock with clockinfos in each of the 4 corners, allowing 4 different data types to be rendered at once", "icon": "icon.png", "screenshots" : [ { "url":"screenshot.png" }, { "url":"screenshot2.png" } ], diff --git a/apps/clock_info/ChangeLog b/apps/clock_info/ChangeLog index 81c879311..8276321ac 100644 --- a/apps/clock_info/ChangeLog +++ b/apps/clock_info/ChangeLog @@ -10,3 +10,4 @@ 0.09: Save clkinfo settings on kill and remove 0.10: Fix focus bug when changing focus between two clock infos 0.11: Prepend swipe listener if possible +0.12: Add drawFilledImage to allow drawing icons with a separately coloured middle \ No newline at end of file diff --git a/apps/clock_info/lib.js b/apps/clock_info/lib.js index b44df9b18..a9ca7de31 100644 --- a/apps/clock_info/lib.js +++ b/apps/clock_info/lib.js @@ -371,6 +371,46 @@ exports.addInteractive = function(menu, options) { return options; }; +/* clockinfos usually return a 24x24 image. This draws that image but +recolors it such that it is transparent, with the middle of the image as background +and the image itself as foreground. options is passed to g.drawImage */ +exports.drawFilledImage = function(img,x,y,options) { + if (!img) return; + if (!g.floodFill/*2v18+*/) return g.drawImage(img,x,y,options); + let gfx = exports.imgGfx; + if (!gfx) { + gfx = exports.imgGfx = Graphics.createArrayBuffer(26, 26, 2, {msb:true}); + gfx.transparent = 3; + gfx.palette = new Uint16Array([g.theme.bg, g.theme.fg, g.toColor("#888"), g.toColor("#888")]); + } + /* img is (usually) a black and white transparent image. But we really would like the bits in + the middle of it to be white. So what we do is we draw a slightly bigger rectangle in white, + draw the image, and then flood-fill the rectangle back to the background color. floodFill + was only added in 2v18 so we have to check for it and fallback if not. */ + gfx.clear(1).setColor(1).drawImage(img, 1,1).floodFill(0,0,3); + var scale = (options && options.scale) || 1; + return g.drawImage(gfx, x-scale,y-scale,options); +}; + +/* clockinfos usually return a 24x24 image. This creates a 26x26 gfx of the image but +recolors it such that it is transparent, with the middle and border of the image as background +and the image itself as foreground. options is passed to g.drawImage */ +exports.drawBorderedImage = function(img,x,y,options) { + if (!img) return; + if (!g.floodFill/*2v18+*/) return g.drawImage(img,x,y,options); + let gfx = exports.imgGfxB; + if (!gfx) { + gfx = exports.imgGfxB = Graphics.createArrayBuffer(28, 28, 2, {msb:true}); + gfx.transparent = 3; + gfx.palette = new Uint16Array([g.theme.bg, g.theme.fg, g.theme.bg/*border*/, g.toColor("#888")]); + } + gfx.clear(1).setColor(2).drawImage(img, 1,1).drawImage(img, 3,1).drawImage(img, 1,3).drawImage(img, 3,3); // border + gfx.setColor(1).drawImage(img, 2,2); // main image + gfx.floodFill(27,27,3); // flood fill edge to transparent + var o = ((options && options.scale) || 1)*2; + return g.drawImage(gfx, x-o,y-o,options); +}; + // Code for testing (plots all elements from first list) /* g.clear(); diff --git a/apps/clock_info/metadata.json b/apps/clock_info/metadata.json index 921a6fc4e..3d47c5062 100644 --- a/apps/clock_info/metadata.json +++ b/apps/clock_info/metadata.json @@ -1,11 +1,11 @@ { "id": "clock_info", "name": "Clock Info Module", "shortName": "Clock Info", - "version":"0.11", + "version":"0.12", "description": "A library used by clocks to provide extra information on the clock face (Altitude, BPM, etc)", "icon": "app.png", "type": "module", - "tags": "clkinfo", + "tags": "clkinfo,clockinfo", "supports" : ["BANGLEJS2"], "provides_modules" : ["clock_info"], "readme": "README.md", diff --git a/apps/pebblepp/ChangeLog b/apps/pebblepp/ChangeLog index 35c67281d..552258649 100644 --- a/apps/pebblepp/ChangeLog +++ b/apps/pebblepp/ChangeLog @@ -5,4 +5,5 @@ 0.04: Ensure we only scale down clockinfo text if it really won't fit 0.05: Minor code improvements 0.06: Use the clockbg library to allow custom image backgrounds -0.07: Fix automatic coloring of middle of clockinfo images if clockinfo image goes right to the top or left \ No newline at end of file +0.07: Fix automatic coloring of middle of clockinfo images if clockinfo image goes right to the top or left +0.08: Use new clockinfo lib with function to render images wirh borders \ No newline at end of file diff --git a/apps/pebblepp/app.js b/apps/pebblepp/app.js index 50e35034b..2c8e24192 100644 --- a/apps/pebblepp/app.js +++ b/apps/pebblepp/app.js @@ -86,18 +86,7 @@ let clockInfoDraw = (itm, info, options) => { if (info.img) { // draw the image // TODO: we could replace certain images with our own ones here... y = options.y+8; - if (g.floodFill) { - /* img is (usually) a black and white transparent image. But we really would like the bits in - the middle of it to be white. So what we do is we draw a slightly bigger rectangle in white, - draw the image, and then flood-fill the rectangle back to the background color. floodFill - was only added in 2v18 so we have to check for it and fallback if not. */ - clockInfoG.setBgColor(0).clearRect(0,0,25,25); - clockInfoG.setColor(1).drawImage(info.img, 1,1); - clockInfoG.floodFill(0,0,3); - g.drawImage(clockInfoG, midx-26,y-2,{scale:2}); - } else { // fallback - g.drawImage(info.img, midx-24,y,{scale:2}); - } + require("clock_info").drawFilledImage(info.img,midx-24,y,{scale:2}); } g.setFontLECO1976Regular22().setFontAlign(0, 0); var txt = info.text.toString().toUpperCase(); @@ -125,6 +114,7 @@ let clockInfoMenuB = require("clock_info").addInteractive(clockInfoItems, { // Show launcher when middle button pressed Bangle.setUI({ mode : "clock", + redraw : draw, remove : function() { // Called to unload all of the clock app if (drawTimeout) clearTimeout(drawTimeout); diff --git a/apps/pebblepp/metadata.json b/apps/pebblepp/metadata.json index 4f328e0f5..9097e3346 100644 --- a/apps/pebblepp/metadata.json +++ b/apps/pebblepp/metadata.json @@ -2,7 +2,7 @@ "id": "pebblepp", "name": "Pebble++ Clock", "shortName": "Pebble++", - "version": "0.07", + "version": "0.08", "description": "A pebble style clock (based on the 'Pebble Clock' app) but with two configurable ClockInfo items at the top", "icon": "app.png", "screenshots": [{"url":"screenshot.png"}], diff --git a/apps/twotwoclock/ChangeLog b/apps/twotwoclock/ChangeLog new file mode 100644 index 000000000..09953593e --- /dev/null +++ b/apps/twotwoclock/ChangeLog @@ -0,0 +1 @@ +0.01: New Clock! diff --git a/apps/twotwoclock/app-icon.js b/apps/twotwoclock/app-icon.js new file mode 100644 index 000000000..36d955549 --- /dev/null +++ b/apps/twotwoclock/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwgcgyUEy/f5HwgENy3bl//AAkkyMky3f4vkDoMarUly/7CImBCIP/pvggFIgVJokSpO/CIUAgMk239t/9yVAgFBlEXGokfHgoAEjhbDn4RMv4DB/wRBwAXCg/8DokcuAEBvwRRg4RBg//AQIRBn4CCCKOcI40H+4RH3g7DnwRHI4efOAf+CJeSpX9k1JkxHHCIlP/9s5IRGFoRHCGon8CJccgP4jkPa4IRKzlxZAKzN7/xEAPwUIQRNxwRBfZRZECgIRKyVpgmypIXB5k/VIjSC7EQpMgyShBz+MnH/x0AAQP4gf//EGCIMSpMkz+AnBNBnHjx9/8f//c/5MkiwRB34RBjkOgHgh9/gf9/N/5M0GoIRB+AgC/H8IwX77c//M2CIW3+BZE+4CB/vbv/7k2W6EM2fQCIu///v7YGBk3/yENSooAHk3j+ENCBiYD9p9Ba5IPB4BOCPoIRLAAQRBAgWAg4ECCgIRBQYQRBLIYRIAAgRLHYkHLJojECJSiC75HHIgvbt5ZJCJRZGCIx9KCIwDC+IRBWaEfCKA1DABnty4RPtsCvcmdgLuDAA3btsAp8mAgO3CBH+BgMgp/2CJw=")) \ No newline at end of file diff --git a/apps/twotwoclock/app.js b/apps/twotwoclock/app.js new file mode 100644 index 000000000..57be691e1 --- /dev/null +++ b/apps/twotwoclock/app.js @@ -0,0 +1,159 @@ +/* +// to calculate 'numerals' by adding a border around text +require("Font4x5Numeric").add(Graphics); +function getImageForNumber(n) { + g.setFont("4x5Numeric:3x2"); + var sz = g.stringMetrics(n), s=1; + var b = Graphics.createArrayBuffer(12 + s*2, sz.height+s*2, 2, {msb:true}); + b.setFont("4x5Numeric:3x2").setFontAlign(0,-1); + b.transparent = 2; + b.setColor(b.transparent); + b.fillRect(0,0,b.getWidth(),b.getHeight()); + b.setColor(0); + var x = s+6, y = s; + for (var ix=-s;ix<=s;ix++) + for (var iy=-s;iy<=s;iy++) + b.drawString(n, x+ix, y+iy); + b.setColor(3); + b.drawString(n, x, y); + print('atob("'+btoa((b.asImage("string")))+'"),'); +} +for (var i=0;i<10;i++) + getImageForNumber(i); +*/ +{ + let numerals = [ + atob("DgyCAgAAAqP//yo///Kj8D8qPyPyo/I/Kj8j8qPyPyo/A/Kj//8qP//yoAAAKg=="), + atob("DgyCAqgAqqqPyqqo/Kqqj8qqqPyqqo/Kqqj8qqqPyqqo/Kqqj8qqqPyqqoAKqg=="), + atob("DgyCAgAAAqP//yo///KgAD8qAAPyo///Kj//8qPwACo/AAKj//8qP//yoAAAKg=="), + atob("DgyCAgAAAqP//yo///KgAD8qAAPyo///Kj//8qAAPyoAA/Kj//8qP//yoAAAKg=="), + atob("DgyCAgAgAqPyPyo/I/Kj8j8qPwPyo///Kj//8qAAPyqqo/Kqqj8qqqPyqqoAKg=="), + atob("DgyCAgAAAqP//yo///Kj8AAqPwACo///Kj//8qAAPyoAA/Kj//8qP//yoAAAKg=="), + atob("DgyCAgAAAqP//yo///Kj8AAqPwACo///Kj//8qPwPyo/A/Kj//8qP//yoAAAKg=="), + atob("DgyCAgAAAqP//yo///KgAD8qqqPyqqo/Kqqj8qqqPyqqo/Kqqj8qqqPyqqoAKg=="), + atob("DgyCAgAAAqP//yo///Kj8D8qPwPyo///Kj//8qPwPyo/A/Kj//8qP//yoAAAKg=="), + atob("DgyCAgAAAqP//yo///Kj8D8qPwPyo///Kj//8qAAPyoAA/Kj//8qP//yoAAAKg==") + ]; + + Graphics.prototype.setFontLECO1976Regular = function() { + // Actual height 24 (23 - 0) + return this.setFontCustom( + E.toString(require('heatshrink').decompress(atob('ADX/+eA//3AQwUI/wCKByIAFh04HYP/GoICHj08gACFChYjCAAsf/FwAQPwAQsevHw/14/4CFBYUev4CGjk/+CSG4ACFwHh4ICB45HB55KCBwJ7BgP4gEDEQMHDQMfLIM/AQN9AQP54YgBAQPBBAMBAQjUJQZXzIIICMCIQCE8YCBgZKBd6gAJvxxBQ4JuB/H/86CD/kAn/gP4IZFBASOBDIJqCDQIgCEwQsCABESAQNzRwM/AQTOJBYd/CIMzLxUBCgMBJAICFh5dBARAUIAA0DfIQCHHaYCJaI4pBNIMHAQ4AICgUfwEBfAMPAQKyBSQbvCMhDJBCgICH+A1BARYaLfwxKBDqp0N/IRB/YCH+fHARn/ARHDKZnxExosGQCC8CAREDARosS54LBAQ5cPTAQCE8IsIHxQsg/ACH+ACNQaRWZFiXDBYIXCAQgsgh0DwEeg4CGCIoUE/EeAQ4UIgfgAQ0HUQICCh94AQcOnEAj08AQY7JCI4CXAAscjgOGh4vBI4UHuBWGMQsB4AmGPwQCI+P3wACG+YCBEAP/ART4G//4ARBJBvH3/4CKx4CDC4ICGVpALBwACI+ZHBARYaLFiXHARgXGv+A/0/FiXwg4CV8EDFj34h4RDv//gE//0Aj/8WaaGNAQpZXcBwCF+AjB8CDT+JTLHYQCE8ICBKyMDIgICLDRYsRYYx0CUILpLARA+dL4UPAQMfAQM/NAQCB/aVE4YCBwJrUJoICSEyBHCj/wDIP+CoQdBj4CEv5oBBwMf/AHBZz//BwKJCh/gfAIsBgBBCn6/edlnzLIICLU4QCIFI/AAQpKBARgRB/ACIFAN4AQhZM+KwB+LyB+P8AQKzB+IRC54CB44CB4ICB4CGH4YREAQnzARyYCAQnhWY5JBARLsMCg5tBbR8AfYICLDRgABb4S3C/4CCHIM/BIMHBIYXBj4CBv+AgYIBn62BC4QTCEYQpCLgTEBCIgGBj4mCAQU/EwhNCEIIQDEgP/GQIaCgJEEAoQLCFgQXCCwJBDCoOA8EDVoKGB/gdB/w7Bn4aBh50CW4IFCBYV+n4mBC4IdCEYQpCZAZQCAQ8DAQRNBAQwXKAQQAF8IXB+YCI44CM/4CI4ZWDAAV/f4IAIP4QCFuCLBDQTmCVoRZDSoMPZYqqBPYI4GFhA+IJQQXCA'))), + 32, + atob("CAcMDw8WEAcKCg0NBwoHCg8NDw8PDw8ODw8HBw0NDQ8RDw8PDw8ODw8HDg8NFBAPDhAPDw0PDxYPDw8JCgk="), + 24|65536 + ); + }; + Graphics.prototype.setFontLECO1976Regular14 = function() { + // Actual height 14 (13 - 0) + return this.setFontCustom( + atob('AAAAAAAAAAAD+w/sAAAAA8APAAAA8APAAAAMwP/D/wMwDMD/w/8DMAAAAAD8w/M8z/M/zPM/DPwAAAAPwD8QzcP/D/AHgD/D/wzMI/APwAAAAD/w/8MzDMwzMM/DPwDAAADwA8AAAAAAD8H/74f4BwAAAA4B/z8/8D8AAAAAeAPwD8AeAHgAAAAAAAAYAGAH4B+AGABgAAAAAAHgB4AAAAAYAGABgAYAAAAAABgAYAAAAQA8D/D+A8AAAAAA/8P/DAwwMMDD/w/8AAAAAwMMDD/w/8ADAAwAAO/DvwzMMzDMw/MPzAAAAAMDDMwzMMzDMw/8P/AAAAAPwD8ADAAwAMA/8P/AAAAAP3D9wzMMzDMwz8M/AAAAAP/D/wzMMzDMwz8M/AAA4AOADAAwAMAD/w/8AAAAA/8P/DMwzMMzD/w/8AAAAA/MPzDMwzMMzD/w/8AAAAAYYGGAAAAAGHhh4AABwAcAPgDYB3AYwAAAAAZgGYBmAZgGYBmAAAAABjAdwDYA+AHABwAAA4AOADOwzsMwD8A/AAAAAA//P/zAM37N+zZs/7P+wAAAAP/D/wzAMwDMA/8P/AAAAAP/D/wzMMzDMw/8P/AAAAAP/D/wwMMDDAwwMMDAAAAAP/D/wwMMDDhw/8H+AAAAAP/D/wzMMzDMwzMMDAAAAAP/D/wzAMwDMAzAMAAAA/8P/DAwzMMzDPwz8AAAAA/8P/AMADAAwD/w/8AAAAA/8P/AAAwMMDDAwwMMDD/w/8AAAAA/8P/AcAPAPwDvwj8AAAAA/8P/AAwAMADAAwAAP/D/w/AB+AHwA8B+B+A/8P/AAA/8P/D/wfAB8AHw/8P/AAAAAP/D/wwMMDDAw/8P/AAAAAP/D/wzAMwDMA/APwAAA/8P/DAwwMMDD/8//AAwAA/8P/DOAzwM/D9w/EAAAAA/MPzDMwzMMzDPwz8AADAAwAMAD/w/8MADAAwAAAD/w/8ADAAwAMP/D/wAAPAD8AP4AfAHwP4PwDgAAAPgD/gH8AfB/w/AP4A/wA8D/D/A8AAADAw4cP/A/APwH+DzwwMAAAAA/APwAPwD8A/D8A/AAAAAAz8M/DMwzMMzD8w/MAAAAA/////ADwA4ADwA/wB/ADwAAMAPAD////8A'), + 32, + atob("BAQHCQkNCQQGBggIBAYEBgkHCQkJCQkICQkEBAcIBwkKCQkJCQkICQkECAkHDAkJCAkJCQgJCQ0JCQkFBgU="), + 14|65536 + ); + }; + + // timeout used to update every minute + let drawTimeout; + + // schedule a draw for the next minute + let queueDraw = function() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); + }; + + let draw = function() { + queueDraw(); + var d = new Date(); + var hr = d.getHours().toString().padStart(2,0); + var mn = d.getMinutes().toString().padStart(2,0); + var date = require("locale").date(new Date()).split(" ").slice(0,2).join(" ").toUpperCase(); + var x = 6, y = 16, w = 55, h = 67, datesz = 20, s=5; + g.reset(); + background.fillRect(x, y, x + w*2, y + h*2 + datesz); + var dx = x+w, dy = y+h+datesz-10; + g.setFont("LECO1976Regular").setFontAlign(0,0); + g.setColor(g.theme.bg).drawString(date, dx+3,dy-3).drawString(date, dx+3,dy+3); + g.drawString(date, dx-3,dy-3).drawString(date, dx-3,dy+3); + g.drawString(date, dx,dy-3).drawString(date, dx,dy+3); + g.drawString(date, dx-3,dy).drawString(date, dx+3,dy); + g.setColor(g.theme.fg).drawString(date, dx,dy); + g.drawImage(numerals[hr[0]], x, y, {scale:s}); + g.drawImage(numerals[hr[1]], x+w, y, {scale:s}); + g.drawImage(numerals[mn[0]], x, y+h+datesz, {scale:s}); + g.drawImage(numerals[mn[1]], x+w, y+h+datesz, {scale:s}); + }; + + let clockInfoMenuA, clockInfoMenuB; + // Show launcher when middle button pressed + Bangle.setUI({ + mode: "clock", + redraw : draw, + remove: function() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + if (clockInfoMenuA) clockInfoMenuA.remove(); + if (clockInfoMenuB) clockInfoMenuB.remove(); + require("widget_utils").show(); // re-show widgets + } + }); + + Bangle.loadWidgets(); + require("widget_utils").swipeOn(); + let R = Bangle.appRect; + let background = require("clockbg"); + background.fillRect(R); + draw(); + g.flip(); + + // Load the clock infos + let clockInfoW = 54; + let clockInfoH = g.getHeight()>>1; + let clockInfoItems = require("clock_info").load(); + let clockInfoDraw = (itm, info, options) => { + // itm: the item containing name/hasRange/etc + // info: data returned from itm.get() containing text/img/etc + // options: options passed into addInteractive + // Clear the background - if focussed, add a border + g.reset().setBgColor(g.theme.bg).setColor(g.theme.fg); + var b = 0; // border + if (options.focus) { // white border + b = 4; + g.clearRect(options.x, options.y, options.x+options.w-1, options.y+options.h-1); + } + background.fillRect(options.x+b, options.y+b, options.x+options.w-1-b, options.y+options.h-1-b); + // we're drawing center-aligned here + if (info.img) + require("clock_info").drawBorderedImage(info.img,options.x+3, options.y+3, {scale:2}); + g.setFont("LECO1976Regular").setFontAlign(0, -1); + var txt = info.text.toString().toUpperCase(); + if (g.stringWidth(txt) > options.w) // if too big, smaller font + g.setFont("LECO1976Regular14"); + if (g.stringWidth(txt) > options.w) {// if still too big, split to 2 lines + var l = g.wrapString(txt, options.w); + txt = l.slice(0,2).join("\n") + (l.length>2)?"...":""; + } + var x = options.x+options.w/2, y = options.y+54; + g.setColor(g.theme.bg).drawString(txt, x-2, y). // draw the text background + drawString(txt, x+2, y). + drawString(txt, x, y-2). + drawString(txt, x, y+2); + // draw the text, with border + g.setColor(g.theme.fg).drawString(txt, x, y); + }; + + clockInfoMenuA = require("clock_info").addInteractive(clockInfoItems, { + app:"pebblepp", + x : g.getWidth()-clockInfoW, y: 0, w: clockInfoW, h:clockInfoH, + draw : clockInfoDraw + }); + clockInfoMenuB = require("clock_info").addInteractive(clockInfoItems, { + app:"pebblepp", + x : g.getWidth()-clockInfoW, y: clockInfoH, w: clockInfoW, h:clockInfoH, + draw : clockInfoDraw + }); + } \ No newline at end of file diff --git a/apps/twotwoclock/icon.png b/apps/twotwoclock/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a4258a7f356418096c4832b684d0f39171426210 GIT binary patch literal 23734 zcmZs?V{|4_w=JBcV?MEMTTg5|Pi)(^ZFTI9ZFcOWlXPsmW3z9+=iYn1d&c;FRMoE9 zbI!H)svosSjWwf{6{V2i@!-M0z>s95#Z~`ZS^jgtLjOB!LcB(TfeFC+sB5{Y8hesB zxj0%_+nJNNc{`btn0r}UfPs0f*XCJg5Omg+{&mH4gv*UQa^f%doSV9yJrUxZnbr3EX# zMNbAaFDFpX28BY2=C0L8CsH`?uYcdXQr{%q*N3#-kDlX_^mxr%o&P?~FOis4`RiKDpMUZ* z`WeZgNLO=cu8Hv@r$f9mko&7n>v0$(BhTaJ*=@!<{1fml4}lAc^`>(aI#LXd?`XS#;2ZLjO>uXMhGtDd6gJt-V#3idmi zk_4`|VLyvp>tk(;Jo~33O|9Lr$?BS}_45sTdF!z}k8SgnEf1m0b-3f58 z4lpO!$4fbN73oLeM=$+=SEiS7fg0-c&xW-*w6{}TuYuhzl5)=|npe;6?+!~DgL6If zPhLe-OVB;nt1|>>Cr)|5P7!U}))sEHgOE!9upYapvDRFS+n5~s&gGKprDbhZOAd!z zQKOyahXosks|MK(%j25-O|7rftyTAYb-%rdtSpWd>Dr^-C~1aSc!3|7-g7Nk#JX^U zyt%8LK2;wn+^t3$xRukxKC^=R)(ra=gL0Mv8m`@-?Y$1r>J;Y2bIpa3WsvbEVm*tb z20K340Zps%$LryQ>?L5~wq~^-KtkioNyTmIFl`8o_J$O>>yNV~w3Lr%zvSY-0vb2F zRljcq>E+wH)ikUT_zw_$U#h@vVEeNyC5IzG@WF z`eAbtFRBI8F`C zh|t4gr(d=+%lMuXwql@;)DvxBraq?cX!feA;fUjLz|y*qo+Tvl zGi&dDHfLU{36IxrJcnTpJ`W)!3qkF7(FPX7RNu|! zw7$mv6K>My#_CruRlD>mrp1{ED+37+tg637xSToHI=uA@htvozRZ&q>M0aaC4t7FFD1<}VlyeP%?f6$M3m02w5TwQ_ z$E|e}w7efKi5{B9pS5r$Mdn)+hY<6~mef!h534l;gdOOLrc=fawV`7)%gdi&hXY-^ z;P?*EefQ0?tQKN8EpTz_yXe(9t7a7?f1+cJVy1b$_*k80kTkBzR{NHZ6&=oLwGvgR zoGN_nL&r2DxYDen@!A{p=IaLwQMdR@5t&z)woX(-p?(Q?Uohs>a)Vyfx)>e`hxRpPFojTqd||x; z%i{R}HZ$z9jYhXmqBq2qTr)bK}NKlh{;^18noQ z5J1w@A+ZEibigBqc#Sl%sX5UI1MrGiXqlmsXRt^Qag!R7b+L3v zkWd3pB-0L;fQU7y8S7f1!!yorM7U;QlU^?fH-GkIN$}3WHV5btMAC8^z*zp8zAgaV zS#kWxb6JJgrp!tq%f4~i4f#@a+aHrM5Wu!{SHNtH=G-I^I>U4rg#Q4hqN!KW^6pm= z3-;%Ann4hKhIf0gK>f*^7ktWZXK~;08kjpm>jz85GJT%)8SqqEo4?>%W%NS@1%Gp4 z)}oy@fxtw=k$94YtqPAFs<#kd1mrCom>d6^l_L}Pio_unHQVF{(87v8qr&alqFL14 zubmyamED)}!$wHvLcm6MW|0P2zl@wA7yJPrq6DECAM@ZpDQmS{M51+Hu#Sr)x$fsJ zgm!LG`C(ay5K&nKi&gMOW{^ICQABZ?(5#b|Ba>lFckEqeVTLR>tm~<_e7*t6Z>;=HLqd)XNHVCkAFIO3?-%fa#0i(x*ClUA zc9)HUbPs~ANtB;Di=9j;eK;zR=85^?Ng;0FhnHV_^ciqy#Pj=g2P*qfv>*p5_W#U{ zhD^~2lByPAEz>MGdue5kqbHFRZ|)2w30J^5hLf%jNv#viq18agZt%~zYbyWb1q;Xt z9}gOfZ6if-s-?sy?%m;DXF3Q#Y))`T7MH0vwYuY##tRI=7H%PeJtGFFS~{v2oT{KE zqdND+JcvVVdjf6;!bXnFmB?t5*r}$o8J2+*$|ZK+F};{&y%tceleWQWi#qco-`Hr5 zY&e;MzK~-`&B4hCh}X~A4^iIv;4v8JMx&ymoDoe9y&bTjOg4yzwXwOKKy!5BC6r|%`7|8%s5H^!BQH#u z9A*kRpcb=!jK9%Sc|g%S=ugYS>VUC}-EA32aC;o2NC3#35r zUTOws<`>%hjsk%ftc+Q0;fq-2q#dr+!_OlZ%xq_Bv;8{e2Y9}E%;5ibZz)QnDT z05mo8Z8g1dRT&(8U(gTsdWuL&#tD2llb(g^#bBVGZ9wmpH*ql6#ki-;p#CgQ+YJ&= z{4_kS6vk@`p$GFgh=`r$+1JttXwPlt6LxibYcP-HmUmzR?%`%)z<(`#h|GcH(k$8k z9bjbx882XlULpJlm@TZ<$4!d=X5}-_e9$kdr9X}7&-(Mdbw1LTU&ieL?Dq+TU4fi; zb_Gh|n3g5uHtd|-25W{l%Yy>Vv(#a%mw8e%zzgQy?dC5JYeV!82-ta6U0G41?_qyT z(Ipi!C0R41ZRO7Sb@k|#2-XVb6I5@(pgaF-bK7RW%8p6RBMuz&oS8^3w-u=kG zREO7P^{qZVE`8}PJQC0@;nm*Ci+0l^L{u4yVV(d;d&lGZjo=Ica9Md^MeBZy;WzmO zW)QaDa=Ht;h*J<|Y=LiuuScn~Cw1(Q$(5P8UyV7_* zH@>vkim$|TB13h{a(o!2I=jiRcp-@J&=yn2q-$}NaWTy>ZD77H5{;-^^tTR{AEdTu zw-Q3+Ajnn`nTKA_D6MC^^qZK679W+6CqmC{PwRv)^x?MgW8ek&Y214YRU^(QIN1e& zVcJK=OH-0pA-ghiO9KS_pj87ISFO*u4O-Y8jYPqz4PG8smbGZZneYF~2L@nWT&Pa0 zz{-D{8{IAGHRT&BTfMp~88&9^jX5_J*o|I!ENMy!kBX`inG~Vj+m%g^%R(({6S?L7 zRa%;lQObjvxKN%FB|oPyPKQMOyp)Tyr(5;;QpPR#gk+5Q;l_+G{1m4(k&9+;#ST~Q zKexmz7Q(hdIk2%2PYm{SD6;E|1)XQM%y5wn$wclpSMnaqE%Ts|Wll6DA_%UtA2^AL z61+(EqfJy+vRWt7?pt~TmtPmTL~5G*-3lf7Av`x>_*siGrxr-&M)?%!G)%8SIt+h- zW&6~~B<$PpA_0}?cS^^P^A3XbbKZXbNeZ3;=v8M?|b`E`a$DD)FZnQu<^t2Br}EwO41os_879Rp0%qumZ~CMPmAp z!+ty^64}HL3T+2z^@M90*0W1;n{(z5UhX}+zT(8)urR(!Z<|CLYn!w`mOq(*CX+=| z!C;!~Zm6&Rm*1}=JZK>%-OtcGa}bi}iAEt_KcBFWabEFLB~57gXQH&8TpcmI?^h8< z`z1VMRQSDZ<%Z1)<<$9#>C^5fezap{XLkRlX0Np?7!#I9*f-NJ)^_b&N^ z=*W9SSpHjp#RTItedmLWx!X6zIU$BH$Yr=~zR8b z(FopMC-QiB(rD62M_J5desEe~8cB~>9%eoLgwqu*zg2A;HU!{OmaOgAOdpD!0);Gk zn(d}R{94P%QWrZ#=vRyxHBsRVJ>kxPtq~UPhKjWs{c@vD2ftO3h8y62+rM$^Wd1Bd zU-&%iHqS&Z-SP2(z{i||BOW+hVKBj9+8$;m&R$weGm`tubMI7_U%uq>0iR-9I(MH^ zYjB8ck9Tj)XlRIeJ03N2SKB_iL%K%@ad-;Zn4U=_mbGL=NF@k7iGPE3l>R6a5T6=^ zG*zACWN~lc(@c>~i_(~h!t-;ECS~bUtm!WKkc-RK9E_KiM_yt9BeIG6$|jRwY--cQ zr_AdzpxLGugV~-y2NzvuVI^FWfgC#-kC${)0W;VeP!bcEimM6MAhV}FA`4C z^6IPM6T; zHl`;fLi?nld@bPXAAd{c>sW(|Q*K4!{G{}#2qiB@epbqFq7 zQ%rHlDY6z3UcR9UXge#hd$C{hHs5Sm&BONmV`ZXjaeEs1S>~S;py|CD5XE|H_VHVLC+lBF<%8&j+g@R`8VZ z-(@edSRO>i_-1R^GQ!>5iG!F-KIeS43O^XaivvYAr!IG*e#m;FOhxp0XlNk3DDsYG zlZjrF(?KnPZ#w`g5h?0}#2+kbGEpytpa&0r}Ef%-I7HUdpD!Cg$XSf(R}@4~^# zM7&A&@TwULsnE-jV;djohjDbe5yLS`FfI5TE-qUa45T+1qnL`jjv6j>p_#7g-oV#% zD-AV8E!h?{6t4*FsBWwqdHyTqp@PXbXS`S_52bG1LvYf0(r+f#@Q*HttG+7?j>M=S ztmA^@sRXYCFa_q0nE=-cF<)WqtJ@GFOhcXS>xy@qjPW!p*Zd`i5t`t}AGX({yvLy# z^|L90O;^|0Jxo8^GhbKFSDruorf#`;5J|}S*xBe!kv+HyT)#XwiekM6jXxgb5 zOXB_{fR-i_AAYss-i6cj;?doKH>jYk{$$Q2XWm3J$kRTFQC*kaFCR3c+VbQyFLFf= z%2hE5nurr?RTc-1kl)$$-Jb&M(E?&NpN zce(^dh1f*KQzE~#aH$%sc-e5iLZpz1%G1f)%t`2F)qE2&%*x>_HNstfy8*BXqr>?K z^oRp7%(_|+Iny`o!d|paj~jUgFb+V6hG2u$(x9?_p?aESQzT?3d|#BsMOj94vbbfL zVJfzEd&EeEP2>w?fyyJ^f+_xK^>B!ze4jBxdxw_u=wO7Xq%${BQ&2Y|?g$FuTvVba zX{;<_A$YqoRR|T2A_bL0^Zm3GWOrp6?zz}Ydy!x|OA}Rx&4s)ZaVMjG(|t`oOE8=Q zCbb5FKdgo6CmkAsN_V-D@b^XXw%uk#L7VS~$E#DO^Ta^J@RQ;fQNP?Nnlf5P?!>Ck zD3F>p`Q_Pw$=FQgW?BgfBu#QISC1Ot+-u5iy*XrQ{}TcG77K#N!#YH%{toi1)gOS9 z`snb{63R#P@W)f^%=qL4B5VHVg_?GWG6JWn0~UEm=bA%0{T{1WMN05w1My{3uH}Jp z#uAexR_@b8c$j6$AOG2zh|On=BbA*?C$B=#2z1dZctPg4(s!;t!*^mmJkRiT;Jy<3 z!4?#=7jGOveZWf*ooFm%ob=SlI{MgFXJyF#v$@D^C$nJ|=2$lhM_R4l=;b#4FaS{O z%}6n5L)YSdz=-n=%|#g+cXHp@F4IFf-*kW@f#Y+T-Mlf#@9V&wqmTJ;#ht-1Pej=R zH4i-R#p7~XD1X;*MX`UPb!JBh=dTraLA#>nD#f=+5juXotWKp@D?ascut+3XKfiWS zL#)&Eh2z;N2AOI%L9@WT_UYlR&viKD=nc=Mt)lN_w$}X~R=NG=6*T}t5a<;czFI*T z0#004MXbweMU6%x8eaYhhSqH>VGVqLE z$ut}XGy;qXy>_JT4kQ_skllhTL$fP)VFY{G(XhF|vTuzeaIX~|q7~ecY&t929Y
Y&BhZ0sH&!~MCM*TJh)=m(iZcJ^Eh1zT6xIgo8HvgTfVG8)~M4~EqE;@537W#=?ulVE#`Q)=!yH*v3x5YQnoILF%t<^-u8*2HiiH9oB6nq zEx%^I*7>(w)E7+#%qZgx*z_8|Y9$`VFOIUdgVMSVi0R2{(Uu&rRNM1$)uajV#+@X6(*cJh?R1SVS17^IUD~z<(;oj7Av5u5z zk85$~Vf$Ca_c&&~!Ud-(6tG^Q(2_WpM_1QUsLzAm#xoER&(W}8#8S6OH+iZa5-_-R zgBj1yFgZGx?&pGaS7ElJ27v^1;=_&VXA~iJM6_E86w*S0_0J4ayr_~=3C;Mxf;4ikia>lAH~1NuPJcGED@DhfR^p1>RzMP%%t zCTdI&X=Cgt;M!6$a_*E3u^VBjeL^hrV4=7LK@|}m{ZUVe9U$OVo&#e=g=aStmlzrL zT8p|cWoI)Dzju&)s)YEWNyHhZHL`6W2Wm6N@7H9LDG>dvHjDGH@_Sq@bp% zbdnRmO=L+d`{YPN@CzB=W2w5vM~r)*g)GXVPMH+F4zYeTF7upAK&>`@a7n0}%!}u5 zzg?HE?vP$75_PpWj^5T}kSHr>Zg8ZPCDuM;>%oteLJEZWNeEy>$(B#~)*E^}n{^Ow z@)$k)b~_r4c^{=A=G2fB3Fk2P11797%>FKtWL1&kq(ZoHKY@kBQYQ{WzHE=oy@xm{ zqPky`M`)_`LY8pi1;tVvI*A%6ntgzmM%4X4h%UVxE29GeD}=gnq@rp5t7O$+27%iE zdNfZK)+P1+fBw9kiy0(pHRk~VQ4v?>U z8RZpvO9S+_C#gF4Hhd%8AFuEtFsIjopL`E8_?EY4Dq;Onnk&&tOo00%F2f(&I;xwny2NxL;nL<2r&&Eb1ceJvHx~D~ygUtV372r9fyo(1Lhci6}xQV=hvCpu>vRa#iMYEsXw?9uX&rwY-W7mqK#09MXG~g#E%; zVxs5iz2U1&58@Uf?WswYx67nS?KzchU0s&@0uLJYK>;cj%H+r0kctsBT-BahVtVY<5Y`2Kw|o0$ zKz?rzC$}k{e*d$wDl?HbJjDl>Hw0-4bh0KKG+NWe_aHrIhC+PueVOpjhKKN6*vq07 zGUmm%Z3hwzEm$5Dmt0tOVM68B%1jIM%e%;S!f29MS{SpU*sXqh!iTS^>9q6MCGfU~ty1GMGh7bG81ao{SvA_r;bw2?6m zBOp6M4c(*%&ajaKVgb4eiDx_1CbjUayF$7ss=cL%>U8+#2y`l%X6d~!*ElwJ><*3e;@Od)6cc*u{erGu5R83_bt3q(LuKc=NS)Q7ttMksfsgr}KHAp)9)h1Z zNAU_sD`&dorvD3E+$w5P%4M6_yq%r{^=7|wu4N9ROAReTAu1bT&*g*H)>Lj zlT|CsPpUN(=bJ}GipV%jArJWAc~LJXL-KNqP2GC?oMK{^UsbHg*5FB5nu7uM>6A^| zmPCuqIr8LsWeDg2kg=6U8a0e`l+Mv+RX6D+li))IBCN~1a;w(U)lAiotHK4hEyDM# zhfNBOu&0qvbwhvSh6)?5JW~=(KXEVDm@p39l+}RHe!|}BakcaTL&*Hb#$52 z0M%gKtvWIwx1{JQWYw>F6;E+U#M22;)yGFr_@2wWxQ@^&CSbR}X7oF1x5n#9w)l@V zFs~wLe>|ZAItNh~72k#ne8yWu#s(rZym2xPR?Ff}T(%@_Jsn^QRuwxS`$Kx~4&e0Y zB5ImCOdaQ^vk6TXfg9ClV)Q$&Ouv<7@dDzo8p^k#7W3oh4@Gbm^Sa@6FpfybO6tnM z!pH8;h!Mt-}kMU>c4`sQdc-*~ZC6SVWs_JIh#e7fq z^=U|T(!hXfYy=PNeCy%Xt)7h~7L+4i3IpnSB>Q4BbDTTE^at}x`Yg_#rnNa{&T;-c zYcbrn^QM2D2yt|yh$%0g-IASI9%Y$DKAcX~`j_GaJ73>f3fw5~_n_8oa+k_XmOTi+ z6f4xTD48s)vw0TdE4Iawn^mBHWOJ`mF_#i35UU5N=-M)hvV<27Ue zqI3ZiAl@>y$RuzH%)Gf5OoY*QRvVKbWcW4aqeB>J`K0~@XYx$NS+(9jVeI0x;NLQ= zwWK>a{M5RCfOM(xN{6Uf*_Vs>;BrX5srt5JpvB32ZaEPk^^tl-x5P-UMy~IuOXy+< zes=|H2IkLkT9ISo(KJ;&)HF#-K)G?3Z?ypXo#3IFB>VgJss?(5 ze7aWuhJHhY)8H4cq?dYg4rK$6w(kAici>wh9fRXo#uE?jv58Fv!6po$aL}!1b-zvU zda(pJA7KN$0}MsVq_sm=7h2_uYqqTbn?G#=L_Cr%0nqr6&4?A-mA)Xhid0XBpWLe4 z6$f*46=^g z{Ec3%7q2TJ%J0`ueNdKk-KtHQ4gTdN~AWm;{un8!OCP^cZKR781dK4Vd9E`m!MUqP#1(W*N`GgUnI6f0Cr zQm`kIPK(gMUmus9!~}y??mtcAu@XrioFHS>ZCvF`hk z+xK@kRY2>LjA=6X3azavSx6C%uS=z&04{(Io4f0aoI_KD3H$On zu?qH~55Upg(Y8+Ip5H{4wW}y-{kFJu>(`9NY^)k@sd}xn3XPKk|F$6Mw>emu#)6r6 zRyDA5zJ_1|EZeeC#x#+E5Kg4hQ;dJ)X-a`b3AG3Rj0p?2l5jW3?RXwKmPGHwovOf5 z>n4>2b>NN=nrkY;MMlWoeYMW<3{ytwE3-R{wb3W9$d*|&=m~s`p230EBPVrG>%im| z%B9ox$Y^4Jh*^XtVFQ>^JpCxA=CIN#4i*^)GVa7C+bFF!upu2L&CJVwnB(8?5 z=4~z$-2yHXy+jcG0{y|Cu9nQVE!4Oq-o5eds$a?o1e>YWGTaxOi)d_g*^AYWUIx@v z$F%;}t@j@Rm5))uMkTcO)9o|roKf~e1J2FJMrg0p^Hf8MKFhdNtGTmOoRt2-9>Q#N zgE9N^`!t(w6&8lAZ?ffEm+wEW_R3;*YV{HRE`k@ECG1I1N*Il5$Z%$aFNQs;#%+Dtt^ z51CBrZ|$U7OVm$!&P>c$vd`5^g>(C^O5shPR;#uC z3As6@-+#wjB_|qIVcqv;b9r7pjt1aAZTZ{#`!gb?-@Em#G$=G0-u^i(8Ujo35YxSA zrS<&v#vh0^UX9ypVgFPesM7iG>k)GD2w1<8tgVAEsz3&fRGa#MpFVsR`w#0=HW ztx60jFVt3bHlis7-M0hOj%jBnR8fxft6w*Cwg}H1HBloaj~bY)l7XQvEh^(PiwObv zRvMB16(9E7d}0(E0&l|N$}>9><$gU!+h-+3Y}1zHMg`>;qTLMmSPcdFYdZ!bie0~u z&JDIsxUB1O+17pQjJPP|P$Q+;-naS#bR0peezy7!aJHZ!zu%)X1K>OG8ykj2kb|{2 z{iwxv0I)yvU!Gv8OB(Ua9CAsqKemfSa4(!Zx!xBhhjNdqNrbN4?J4Uvj9#06#5pAj zk{(unGpkNk=`~dd?#|eV{)UzrhKzT+9F}LfVoArd3hp#Gpk?JHn;Jx(?=KC38AOk( z{d?h6EKEHfi>eL=hOJlgt*2t6&TSO=dQw)n!V!=ESc(Q~UWu3O6wM{oSG;wW;ajr2 zYz&=G2((IfYSK@E6YrEvy~*^_d&AAk?zyi-5MnmI2*>?zYs&Y`VI06S>L1f_7T+H? z_>$Lk_m$FrF<@B165g(a0YjC`A{qt|oUI3Cj0L0{VwSg8b&GSBWl&PqYGYM2_yaRx zgUaJ6^y1KOTj^Yy5dkaN^6CQ=K(X>-KrIR#DSPgZdo?l~6krjqT@T^jlT?}W&`ty3 zh_cg4r4f6YE#rg0yHv09JY=aT7=(vP1lg z0h$r5(BKeUp2QrbAxHwGrKqCTwh~4?zMok&YQnjs9=lHEg(Hzzo&_wbX;J$Y%OJr~ ztNrq7l0~AG#B6^vTFGydvD(`1_3aEXRO}QdLxdxq_h6!oat_=6)F&^e#E+-9Yz=ZSo)YzPOE2l)wV=<1!#4n$iyQ7~Z-1|NoEMBWDd zprwlPsd4hJ}hsAwp1I>7q!H}*?E!7i|R(7K( z2+M9t{z8|OGfYI0S7x9yN^Av!p1G_z(_&wNeXOHfcJ~IMRWTfif*>!(>jH86*J`bU zTs_dPfxR7TsjDXvAS7RsyP#{Y0;T!#{NOlM*qf*EeDdH-_U*71=BNxr@pqAg+&qD^ zy&Ja#6CEhTgcs0toJfD}qm*;&_?>O+YfrWCMP5PT?>xDrY84QQk)Bhze@kw2bU~o3i1!}qw`?w7U! z;DTe$(Iwd8JicCFrGxS714Suvri)xuHCG@=WnYM1HsEJkaP-%dTyU+6oI4gtkelrE zoH5c1Z!@IP#fyrJ25g&B$_}c$Mzx++0cXaJTPRLz@6)yAe0Q7)cvuyaN6OuVv`hnR zV;Y&3K4=OQ2<5L{Lb%&6H4OHoX2I+voa8ruX0i}xxvpM&jKj*VEET2MWVf1h@HfV$+`_9f*+yfun7rnGN=Z!m*t8yJ2ACQ||&OR(Io2jY1`N zZ42#ESBVPZ?)}HiiYKwS@X9N$ruQ}gmTkm$bn zJ(`ms*yh+PI}| zICl))c$1&}e=J)+{S;Xkg9`E5^LslYmaM)fqmZq5@mTP~96MC!t$Wssm5f{frrPS( zLe|6GWmgv%YX~bbcNCHKmp61erWSNo3zkLI+;b-ce#S>t(q(u%yv#K^%#!LWty5l% zlR(e!?03F;$apWOj=Ld}yMJE3c{x5GS#*tv?Z)s0^3X`nEI&i0Z7m`;)sfEve>L6u4AyIjgrcXR<4iW1V;8e=uQ4u= zUSYcJ`zA-CO6KDLhqgIUf!2DuOE$bPpXCf}-Hz#b^L{AS|x^@#mtNs7pG{;L})t=R@Ft7o~8z6B05$%Ck}%fVF{CUv&1r9 zDxb!cz9AqWF#@fLP}$<^hJTIAr!z+FatSa-wvm*SupKLbJo1VAH3SOxP`RK{livJ| zixpI+nQlmmVWT7glWmciMD%cGq@a{xPhS~Ul>N+-#lACi?1lw@-OzCFtQ*FB;-B!R zJN|=BKl<003JI&p8F^Map|aFbMk3cH@$>5=S75->2X~1Vj5B9K=Z{V2hx^qXSNM`Z zlr+<(5D)!AJIn$Z6{kvby2ZID=d4}Rj zCyWrAYHJcLD{IcvN)!XCZl5mOvn{MT<7e*ENQZssk1dU=S}y0#rxBVw5`?K%Ssz|b zXFNh8Nsc+mdU)iv7~^n3d8;K{tt9_EhzK^T-UQ70$E?x--QBBWp)tD_!SG5F9PfVw#pwH{L*+#R~WEc8YB0rdF>0;k3=|oCis|B`5lCrRk>|3v#2CR1FQ4j@m&fJ zywLCTV`{xcH9gT|?F2}W@-Svps1R-n&dW7O9Tv22x(9)B>zY7QnRN#j`ieJJZpugg`r!V17ayZ$L-(JRB*&%R@OGfPvu z#Trt+_N79md(p#@p@w$8UH#EroxRGyYSd3R=J6v@_O;U24&g&>?o3y;kWN9)ru64g znBvLaVu|Rs?{F*-+7OpYFafl>rXKN5&}XI^m^fI_UF|1GOlXI0X1-3&yUp#b=a4wo ziIV6Gdp9=Ert)f+$LJb-$qz$b`C@x+g^CGx5hTTVv)`n(ak(?&7&s`~-W*VhfOy=W z1NHL$Zf0{;I^uN2Z`?Vs)r`7^ z9=TNidqz-zB+dg~<5E{8sjh>+u*fY#VNZM}PW4A7a&3Eoj&0mW+w8r+a6TWxmXJCm zEm+@%TGoAZtgI|v2UO2vxyX-^qbefzvN74mM|?Bd`s~;5I5?xa>e- zNv)Z*UGeo3N`Gwmv$k&8psl-{Z*YT@Z*sc|+zf8zTJVP5GqVzTg#rg(8Oa0AD>zAa z!hlIwdWGA%rJbbyCm$Gnl&Rhod&4l5?a_+LGy;$9E1-n4CO308f!*ce)bIf#RnX9p&LJm<;5+ zv%cdwth#kqK}GCJ$VNMKn-;pK&I(uj6#*%+q>>@J2x}QbIuV}9Sz00$6P?tm`am3j z?O~-)$ew>KYU14S5-O#?eUiKX(imM8H;ZE;Js*^hyzN zFS0wBO`@{9X74-y;}YWw{X+++M&93pBq*V#ZAZ_C=u9lJJG^lcl7zqbDi^ghv3 zh`ETo+V!YTHh6Ui&K%}g($rU7c* zWWD69n|?A?SnDD~M}Fzq0CphwiF`cy$}zDjK@Fo_3)l(R2iW(WSo^kiZZ+G^5OJ#& zTwSqmQ|By;?8lJ`KScau?s3o9Su73GbwqIV!E+Ugyl2g{q?r}|y|s>mW2?DR@RLb; zZ3mh3{sSVS??YsvtLTox-y4D5S!veOKAyVzcrz8G=HEPt<)EQ(l*SDcQP9WBf@wq- zbBZ9=B@5fzrd`~I0#ANc^)~pU94Ni~W_YZ!qmKG_1(yZ|W(A_M@2dBQD)}1U793ZK z8dKGD(y!~;?`|DT+m+0@wm^Amxinio8V}C5XI#H7fz@pBketNeB(s*l^1;hKoQcTr z4|f%L0<9O_!eXi>$-ewu}Hfp_6e+tS*-aMDRVIZ=t_GPGkN?|KyOe8q|?eGwOpkyLsN_RBO_I+x6 z45!u}YpKHh=8JBGE(c^~Vy?fZe!xVN9HTxtBsi@glONPa>pC0Pwtx{&*jH6*Covgl zKk-6}Huhr(-_xAb|fwqd+NpL{~&rRijB=6W~-@S<(!6+zT-5 zH*?w=ZpU*WsE?~qi<)u#_^zl z>UkhzDDCq8Yiq-^t|T@R=x&sU`TOjOn|xccwlH+i8^B)}Dy7D!3JmJC*2S7~tpe8& zYOzZ^ijX=}SFSH%w)@>KpdGL7BT#9o2y^vj(ZPiv0=DqVF;QKldGx+y3+4n{y?QCm zgHAy$nV9H(ghIim?f^+g8I^CGjavm#pTIpBRx;Y-c#XS4R?M>N<1?gnqxcxBQC3S$ zs6zeG@*wito#k*Xo9UAP>&_8mFD-0RcMJq#kl*LH>jh4b zEFJ4lZGf0CtIEcf4s?16&t`fKe2ba{Af6!9AHRBCExIllqx7F~C<#d^14rSSCKp=y z&tEK@Zw$AQ9YMcN*y?;8;uDO!3X|PoXEcB)$wSvglV<_iKN1GjBHe#a2qFWPDly-5 zzI)6r3<7jmvkNNG_1NYSepc4=D=R4*_;>mEqN1t)O2l!KPe)Gvxf4<9ito0b-E4a{ z4uyWOApYVZf>GS;W4L74T&%<9rWYWIRdJWC;wYVRM@T}`)B4A^pMaR7lf*19A>Z^- z)?M835Cf9(%*dLNlbtV8HC~FEH|sA9T`eJ@)`UVP7#Mh%wV0T)jF{N}^+f-3Lg)G? z3rG(M6O0(@%EhV^{2?g@GyvBmBnWIVW0Xl3;cJ1JdT&q)cqtgzQUk5KyJIFx10&j+ zFq$HO4=`sBCsns(w7=gmbcVg0HWNLci9D~t0-Gn*o2kJovdzs@Wk|mpVv5$ok_E9y zvXZf?6`+rB@Q|@-E<+oJWk~DNx-!w=Qs1}U&n&h{yPoZ=aoXOm(YUDbSNa;1 z7SYu{2F@6lHbhZI0Z2*`;Hw${D+?ml`gwO*b6!z=ADzWiMWA6^x!zA0(w>3Bf-%`bXTQQlEpS z2#s!Jz9UW~LvVbKklh4G?xev$I|OfYwzoeCDiQ}VxTpUFM@A05MKiDW?cv+p+UT=f z|NI0q*L5k{i_T&F=UvCM{^wEGQjiClI@&WCn>m`8GkMuN{qwMcf$x3*vlSrIQcxxlb96B$;b7umVqui zcQLa7s)|egABlf=0%TThZcadEW=~H~CQo)IM;A+GR$g9SW)?PPHa5n82u4?L2RCCc zMh92&|496A4RLcf0=36PQfn5_nJKfmow@x#sO!I|tp6jVl#GJ%e>4750!wRqr~hL8EB60Dx>;NNf5rMA zx&3G6zn1g=Ci0K|-@5+;{eRc~U*LZz1qGnEqpACU(vuMvAp1{zpqZnowHfe#4>>uF zd0C8E7`e?^IT$&3|Gf_$V^dbf|J9y#Mm4o<>(GNJT?sw(W*`I-LX+NmRXQPr-a8__ zBT7|@G~v)eKtK@?0#ZakdIyPuf)oKkilDrp=e~RHc<;{{uI2?_ENZKRe5OFjTKN}cQ6e5a( zN=iuD!%!Ge#4jj&w3Mo+k2?yVPG@(NBSyr_!|_+g1>sT(`WmvFFyY@`f3@hlq5K^1 z17tb1ojv@6{%vaP?2a+=LtU^bDj_N^0fUPnVG=M&eCYo+GR64#;+1%TDGC)9``vSq z7Abr%cw$i(I>iJ08i9{RO34R<^7HgD_Vjd<<-C{x_+sQQd4pwsCq>=a7jF@Kq4+;F zZ-nvwefN6_xH`0guXgAEC0Q60 zT2j&uB>@o?MM^@%QQ|NNO2Qt`wF44uFNzWqvqzx+6W!O-!7mWygHdqAM~aUIFQ8x1 zfcbw>De#}xflinUo}e&s2ow&1iWx&CrNj_YFqjZjR0;~^6!|k?k&9LRuZU$t{s$*A zzYP9T2Jqv4x8chRzFLX=ce(nLvkMykA3uNQ;{VYD9{L|Ae~aIL==z7Qzs11cGX6(h z|Iqcf82DSp|ETN#jIK-nKJZ{X@VlTu{Bfpq3R#Xn3X$4rsVVoGvG+>{6>Ej3q4NsY zC!bs+)KpP0hGr7u!9VFJrfa1?T9o-R9GWK^zUaEE&|NYCcMWsR4}Uw?+1Pn;_5a-F z!by_5%S+jkihF!SJt0YoM1t2&nZ4HZib71T=D7N%O$=QRDbG4u4lblJeW&un)iuW- z2hPWz5U=0zVxD{B=Wwp#_+=ydph9A_wJd_l>G5fRh|R>pvAGZL+X1s%bh-MV6hv=a zIuk)gLN@?QnM~*hCiVm5$TNWfa)LuW#Jh$kS*-$)xo+n=rPU zg=Vv@dAkVZBVAfWe`KZT2Y?Kg?wik(Na}h?$zSgCDkY*RMrHt%hUAF^hs=p!4hB^9 z1;N*`I&cJ-&ri--tq*63>(6$Lt}NW$*a->hW2aOl8(GeKSadp_Z!q#u8bj%>5^X%qGzLpaJB9#t+5?MuVWf%;9i zWhu(^_{gQ3i|@4uB}!Ts#nl{y+r4_oPDR>9Vt{Tkq~4`F84@G8ehW$iEba|r|3<1n z=zRRS$Bu-B8kAZQCR7CiG!{W>?2>xkr&=2qT@hk!jo1Z1L67tS0mio*`lsg-()8qN z*8-QrV&k>48UuGsnV6Yhu#EZVvq}fpA|8#&^N5MXCermA-MmRA8c5zt8nS1Fv$WYN z6Sxf0(9+;qqP2R{+WK?$74#4!C*t*BR&XJ)$5IRexd)_?SqF$C5KnJ^b2$q;ug9w0 zV~QPiKyS@9sLwH@uTTx%vtfoyYEQCrkZ`N9vnF$b>nVSnT2wU<~ zvB@BdbupOINq?)d^76rNn=^x7zIaq(&3<+!R#nxQHz(PSrjWLIc^#>ceOY);l`%k% zX`ptSZ%TAucxE-tomK8i*l`+|JswSJ%lgUN+gtRS4i_jBZqxyIjN?^@$QDJ5n;MbiOGEO3Ky7&R4H9 zzf-Di&na+9lLJ;Fgt2?1PFYdY!nd6@HePUNZ`O4dY(8o8m|c7D;DNZf_?y*2wtJB+JbIu7*vvq|fcKHA zz^=pX1vQra9y-1Hupi$=HfSLBTbt8k7RE7j$Go;%T4mE7e00bJMT^4x_C&&0AJ)9s zZfIL85_U}*Cu2rRVuauKsPxWhw}pR@<1Q#9dq==8X!pKYrQO*4&G=MxrLLykLdZ@- zb5o{cVQ8FjTZ)a_ndGDM13p;iJ}aX6`NV^4;7Op`P1_de?XRl?k8iyjA6E$pIjy(V z%|k|J`pjN!&3?k%!t6!3x3@=6Pd~c2n0#r`f5Dwa)|;?yh9ctCd+c^VezejrBp@PE zURg3o}=g-A#EUjpxv`OQm9d$(EgMG3xOD+u|Y7nAslWPo>=w zOitrBI|DRk)}K??iG-wfewpu{Z9qG_xF{y93p>pm<|}iC0%<@#Z$_SoNLOd3Yv}E8 zQLif|05}Ntx?|>Oxv3-em%^mne#iti6*BHiJiQvr>497I4d+CE+fQ!prfNhH7;wFv zPyrF49**iFZg@YWgTuv5Lp57|$Rzbd@aR1j27StrEe%o;0+^YZxy{x`9v%j;g&nsk z@znIMpiaJi%*@Q(T`x%)pPK58BqDn~F!26n=l83W<#f&9_@*Xp(@td+@kPs5yCqmH?6WnK}+5wp#Eb5O4zuYcb! zbY5;r(+fW#Ok-G<&(Rg+&OWXv$?azDP|&Kqax~$Lo_ArQI(4*Zu;TjwcpPZTTT_5G}lg)iDBq$j7#`4NR(wD2^W0jKQ{)>pB)y*l zHI1aF9E~p2yit6Y;z!1aVke=XF(NJPeb48-fw(IK(_8Ok>6f!aY~H5xXtk`|mj;0n zT91lV?%sOt!Aed}zWV9Y(?dr&^x@Xrnf>-eQyiIOSY3ogr>dbL?Og^DhrVP+K(&P|$19H0i$93+j?7V$N-qI*A@Sq_T z@$fOX@WkiajpSrZit?VGLBO-_Sc;q*p;8w?`+gci4d=pJEQRqdh_JbES76Bp3Plu( zpQRl$8$E8Mn|xu<_}Qt6y9v_M#RSePqKK@T?+7&#RhAhT z!gz8`q6Jk;sK%=q>ut13T_O%|==+69)=_5+kXK~aTGb1t3=j72kH|WDA%^1F-}apj z-suZAdA2+^uvrTbW3+|6R9D{2Sk5wkdwKB)!cnoQ%xP1rch%UK({lD@WznS=P9P0M z>0|YpA7n`e3QB8@F^q{oW0M}Aj!1CPX1d<(+y-z?YAW5-J@JW#wa~X`wM?=s4(UrN zXIXqf-*ard*75^C=%>H%_%xWxj{7;WpK~wH!Cz0A>596^%J$2UC;X4DF)(CgXD4K) z%Z4ns+ASp}CW5@J*PjXOwd{Xo^mnIWXP4F7NoI5l`Pdn})zE)YCOI|Go67|scEj=~ z(R}spLTVGs)hh2E0I}nxT6GoR>e^Z!(Y>9q;gdU^kk)~Q*15JdosG@S;G<}&mX8lD z@GGB#i!1u3b#Sc3m)2|kqdM{GkG(Ajlh#CX)SVgUw{2?AWLv3YM!gTZ!ruK{rN`Hk z8jI)m$=L6tzVKZmv=wK1aq{U=@V7t_*mH0~U{vClQ@T-l&V*#Y7-|-|usc1@(@(4h z@sAK;^BtR7VE`*x(INFW?`1_`S9|b2fS;fLSd$=V=jGAYuC7j>=f1r0!zE*i#Oevk zN{)tx;|bsn^Lne)>ai=Np`d$VUiZqhWO~@G=ezOYsol{tHN7Ssuw}bdi_ZBme7T8$ z^SHE!kPBfdqLNWPcC|Rm)`FsM(#`b7Ph$44V-9?!$$FPmAUE<5ViC0RQDStlf;a|y zou@?g9@BicRpRUFNq9^s?hL4Zt22zm@CM7K#6iC<+K$yzKz=o9QsEFbdQ~qxC}Pnx za#}5Qb#`NZ`>+~@tMVsP^g0x+Uy73s<(Op|V~XNxm~JPph{hga7s;&I{rqX00=zc3 z=+=H#GS{Z;-`cuF8+175sFwV(?&Tqq=gV)?7}P?0u$XFz_v{*eSBBe;ekHFcAif%5 z6zv?_U;f?M@@`~@Q$nx~ejSmV9bF%K@2U~|$}nMpRuc_U+Rq=^%6HP`GX$!t?&IF5(EN)>67Zi&ryJ{U%vw5UrkO;c~4AM zuC5bSSviqXmK3zn}j+BEB%R32<_fIF>5`E|Q=zUnrU)A|j$@Aakr4<1(&}fh;+_uphmz z+D_fn)MQDMFv8AZmH&jWsppLs&-BJU`Npefmq0v0Atl%=*DAh{q6k#5IRV&|vb3Zc z;EK+5E|d#`#W`y7MnX0R<1SGBX&>#NBgBkcQNElo7ZBfL_e{PuS{}@}Z>#6G;(~}a zNFmrF>a*;jcdZ#?OYqlF!aW@2EcT5lnaFoFZXmYguD}M%ot04~fVDGU@A$+#YG|-!Y&A zG`xi~>Ein=&A0A};DnQnuc@dKcL`EU%j5c!Q><~}0D_RwC85lN){DO_G*onzpD5Z! F{TEHmO`QM$ literal 0 HcmV?d00001 diff --git a/apps/twotwoclock/metadata.json b/apps/twotwoclock/metadata.json new file mode 100644 index 000000000..76364501a --- /dev/null +++ b/apps/twotwoclock/metadata.json @@ -0,0 +1,16 @@ +{ "id": "twotwoclock", + "name": "TwoTwo Clock", + "shortName":"22 Clock", + "version":"0.01", + "description": "A clock with the time split over two lines, with custom backgrounds and two ClockInfos", + "icon": "icon.png", + "type": "clock", + "tags": "clock,clkinfo", + "supports" : ["BANGLEJS2"], + "dependencies" : { "clock_info":"module", "clockbg":"module" }, + "screenshots": [{"url":"screenshot.png"}], + "storage": [ + {"name":"twotwoclock.app.js","url":"app.js"}, + {"name":"twotwoclock.img","url":"app-icon.js","evaluate":true} + ] +} diff --git a/apps/twotwoclock/screenshot.png b/apps/twotwoclock/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..4d31d1520729f4950f7b7f95870793cebef513c9 GIT binary patch literal 7438 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 M07*qoM6N<$f^6MerT_o{ literal 0 HcmV?d00001