From 422ddd076c85a957da699006bfd64c679553b89f Mon Sep 17 00:00:00 2001 From: neris Date: Tue, 12 Sep 2023 19:52:44 +0300 Subject: [PATCH] LCD Clock Plus app added. --- apps/lcdclockplus/ChangeLog | 1 + apps/lcdclockplus/README.md | 19 ++++++ apps/lcdclockplus/app-icon.js | 1 + apps/lcdclockplus/app.js | 108 ++++++++++++++++++++++++++++++ apps/lcdclockplus/app.png | Bin 0 -> 2703 bytes apps/lcdclockplus/metadata.json | 15 +++++ apps/lcdclockplus/screenshot.png | Bin 0 -> 2260 bytes apps/lcdclockplus/screenshot2.png | Bin 0 -> 3462 bytes 8 files changed, 144 insertions(+) create mode 100644 apps/lcdclockplus/ChangeLog create mode 100644 apps/lcdclockplus/README.md create mode 100644 apps/lcdclockplus/app-icon.js create mode 100644 apps/lcdclockplus/app.js create mode 100644 apps/lcdclockplus/app.png create mode 100644 apps/lcdclockplus/metadata.json create mode 100644 apps/lcdclockplus/screenshot.png create mode 100644 apps/lcdclockplus/screenshot2.png diff --git a/apps/lcdclockplus/ChangeLog b/apps/lcdclockplus/ChangeLog new file mode 100644 index 000000000..2286a7f70 --- /dev/null +++ b/apps/lcdclockplus/ChangeLog @@ -0,0 +1 @@ +0.01: New App! \ No newline at end of file diff --git a/apps/lcdclockplus/README.md b/apps/lcdclockplus/README.md new file mode 100644 index 000000000..e473d1e25 --- /dev/null +++ b/apps/lcdclockplus/README.md @@ -0,0 +1,19 @@ +# LCD Clock Plus + +A Casio-style clock, with four ClockInfo areas at the top and bottom. Tap them and swipe up/down and left/right to toggle between different information. + +Forked from [LCD Clock](https://banglejs.com/apps/?id=lcdclock), inspired by [Cassio Watch](https://banglejs.com/apps/?id=cassioWatch). + +--- + +Recommended to be used together with the [Casio Logo Widget](https://banglejs.com/apps/?id=widcasiologo). + +--- + +Differences from the original LCD Clock: + +* Two extra (4 total) ClockInfo areas at the bottom of the screen. ClockInfo areas are now smaller and only include the icon and the data. +* AM/PM labels moved to the right of the time and are only visible when 12-hour mode is enabled in the system locale settings. +* Month name label added. +* Background color changed to better mimic old-style LCD screens. +* Various small alignment ajustments. diff --git a/apps/lcdclockplus/app-icon.js b/apps/lcdclockplus/app-icon.js new file mode 100644 index 000000000..065a2f663 --- /dev/null +++ b/apps/lcdclockplus/app-icon.js @@ -0,0 +1 @@ +atob("MDCI/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5OTk5OUBAQEBAQEBAQEBAQEBAQEBAQDlAOTlAQEBAQEBAQEBAQEBAQEBAQEBABxU5BwAAB0BHR0dHR0dHR0dHR0dHR0dHR0BAOTJHR0dHR0dHR0dHR0dHR0dHR0dHRzkAAAAAAABHR0dAOUBHR0dAQDlAR0dHRzk5OTI5MjJHR0dAQEBHQEA5OUBAR0BHRwcAAAAAAABHR0dHRzJHR0A5DkdHR0dHRxU5OTlAQDJHR0cOQEBHOTlHQEAyRzlHRwcAAAAAAABHR0c5MkdHR0dAQEdHR0dHRzlAOTk5OUBHR0dAQDIyQEAyOUdAMjJHRw4AAAAAAABHR0A5R0dHR0A5DkdHR0dHRzk5OTk5DkdHR0cOQEBHOTlHR0cyRzlHR0AHAAAAAA5HR0c5DkdHR0dHQA45R0dHR0BHRzkVDkdHR0dAR0dHQEBHR0dAR0BHR0BHOTk5QEdHR0dHR0dHR0dHR0dHR0dHR0BHR0dAQEdHR0dHR0dHR0dHR0dHR0dHRw4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODkBHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0BHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0BAOUBAR0dAQDlAR0dHR0dHR0dHR0dHRzI5R0c5OUdAOTlAR0dHR0dAR0A5OUdHR0BHRw45QEA5MkdHR0dHR0dHR0dHR0dHRzJHR0A5R0c5QEA5R0dHR0cOR0dHMkdHR0BHR0BAR0dAQA45R0dHR0dHR0dHR0dHR0AOQEcODkdADjlHR0dHR0dARzkOQEdHR0BHRw45QEA5MkdHR0dHR0dHR0dHR0dHR0dHMkA5R0c5QEdHR0dHR0cORzJHR0dHR0BHR0BHOTlHQDI5R0dHR0dHR0dHR0dHR0AyQEc5MkdHR0dHR0dHR0dARzkyR0dHR0BHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0BHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0BHR0dHR0dHR0dHR0dHQAAAAABHR0dHR0dHR0AAAAAAQEdHR0dHR0dHR0dHR0dHR0BHR0dHR0dHR0dHOTk5MkdHR0cHQEdHR0dHR0dHR0dHB0BHR0dHR0AHR0dHR0dHR0BHR0dHR0dHR0dHDjI5K0dHR0cAQEcyBzlHR0dHR0dHB0BHR0dHR0AAR0dHR0dHR0BHR0dHR0dHR0dHDjI5K0dHR0cAQEcOADJHR0dHR0dHB0BHR0dHR0AAR0dHR0dHR0BHR0dHR0dHR0dHDjI5K0dHR0cAQEdAOUBHR0dHR0dHB0BHR0dHR0AAR0dHR0dHR0BHR0dHR0dHR0dHQEBAOTIyMjI5R0dHR0dHR0cyMjIyOUBHR0dHR0c5R0dHR0dHR0BHR0dHR0dHR0dHQEBHQA4ODg45R0dHR0dHQDkODg4OR0dHR0dHR0c5R0dHR0dHR0BHR0dHR0dHR0dHDjJHR0dHR0cAQEdAOUBHQAdHR0dHR0dHR0dHR0AAR0dHR0dHR0BHR0dHR0dHR0dHDjJHR0dHR0cAQEcOADJHQAdHR0dHR0dHR0dHR0AAR0dHR0dHR0BHR0dHR0dHR0dHDjJHR0dHR0cAQEcOBzlHQAdHR0dHR0dHR0dHR0AAR0dHR0dHR0BHR0dHR0dHR0dHFTlHR0dHR0cHQEdHR0dHQAdHR0dHR0dHR0dHR0AHR0dHR0dHR0BHR0dHR0dHR0dHR0dHQAAAAABHR0dHR0dHR0AAAAAAQEdHR0dHR0dHR0dHR0dHR0BHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0BHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHRzlAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBVAOUBAQEBAQEBAQEBAQEBAQEBAQEBAQBVAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEA5AEBHR0dHR0dHR0dHR0dHR0dHR0dHR0BHRzlAR0dHR0dHR0dHR0dHR0dHR0dHR0A5ABVAOUdHQDk5Rzk5QEc5OUBHOTlHR0BHRzlAR0dHR0BAOTlAR0dHOTlARzk5R0A5ADkOAEBHR0cOR0dHOUdHQEBHRzlHR0BHR0BHR0dHRw45QEA5Rw5HR0A5R0c5QEBHDjkHAEdHQA5AR0dHQEdHQEBHDg5HR0BAQEBHOUdHR0BHOQ5AR0BAMhVHQA4VR0BHFRU5DkdHR0cOR0dHOUdHQEBHRzlHR0BHQAAHR0dHRw5HR0A5RxU5QEdHMkdHR0BHR0cAOUdHQDJAR0dHQEdHR0dHMjlHR0A5MjIyMkBHR0BHOTlHR0dHOTlHQDI5RzlHR0dAR0dHR0dHR0dHR0dHR0dHR0dHR0BHR0dHR0dHR0dHR0dHR0dHR0dHR0dHRwAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMg4yMjIyMjIyMjIyMjIyMjIyMjIyMjIyBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==") diff --git a/apps/lcdclockplus/app.js b/apps/lcdclockplus/app.js new file mode 100644 index 000000000..c809be6bd --- /dev/null +++ b/apps/lcdclockplus/app.js @@ -0,0 +1,108 @@ +Graphics.prototype.setFont7Seg = function() { + return this.setFontCustom(atob("AAAAAAAAAAAACAQCAAAAAAIAd0BgMBdwAAAAAAAADuAAAB0RiMRcAAAAAiMRiLuAAAcAQCAQdwAADgiMRiIOAAAd0RiMRBwAAAAgEAgDuAAAd0RiMRdwAADgiMRiLuAAAABsAAAd0QiEQdwAADuCIRCIOAAAd0BgMBAAAAAOCIRCLuAAAd0RiMRAAAADuiEQiAAAAAd0BgMBBwAADuCAQCDuAAAdwAAAAAAAAAAAIBALuAAAdwQCAQdwAADuAIBAIAAAAd0AgEAcEAgEAdwAd0AgEAdwAADugMBgLuAAAd0QiEQcAAADgiEQiDuAAAd0AgEAAAAADgiMRiIOAAAAEAgEAdwAADuAIBALuAAAdwBAIBdwAADuAIBAIOAIBALuADuCAQCDuAAAcAQCAQdwAAAOiMRiLgAAAA=="), 32, atob("BwAAAAAAAAAAAAAAAAcCAAcHBwcHBwcHBwcEAAAAAAAABwcHBwcHBwcHBwcHCgcHBwcHBwcHBwoHBwc="), 9); +}; + + +{ // must be inside our own scope here so that when we are unloaded everything disappears + // we also define functions using 'let fn = function() {..}' for the same reason. function decls are global +let drawTimeout; + +require("Font7x11Numeric7Seg").add(Graphics); +const is12Hour = (require("Storage").readJSON("setting.json", 1) || {})["12hour"]; + +// Actually draw the watch face +let draw = function() { + var x = R.x + R.w/2; + var y = R.y + 48; + g.reset().setColor(g.theme.bg).setBgColor(g.theme.fg); + g.clearRect(R.x,bar1Y+2,R.x2,bar2Y-2); + var date = new Date(); + var timeStr = require("locale").time(date, 1); // Hour and minute + + // Time + if (is12Hour) { + g.setFontAlign(-1, 0).setFont("7x11Numeric7Seg:4").drawString(timeStr, R.x, y+39); + g.setFontAlign(1, 0).setFont("7Seg:2").drawString(require("locale").meridian(date).toUpperCase(), R.x2, y+30+(date.getHours() >= 12 ? 20 : 0)); + } else { + g.setFontAlign(0, 0).setFont("7x11Numeric7Seg:4").drawString(timeStr, x, y+39); + } + + // Day of week + g.setFontAlign(-1, 0).setFont("7Seg:2").drawString(require("locale").dow(date, 1).toUpperCase(), R.x+2, y); + + // Date + g.setFontAlign(-1, 0).setFont("7Seg:2").drawString(require("locale").month(new Date(), 2).toUpperCase(), x, y); + g.setFontAlign(1, 0).setFont("7Seg:2").drawString(date.getDate(), R.x2 - 6, y); + + // queue next draw + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); +}; + +let clockInfoDraw = (itm, info, options) => { + let texty = options.y+41; + g.reset().setFont("7Seg").setColor(g.theme.bg).setBgColor(g.theme.fg); + if (options.focus) g.setBgColor("#FF0"); + g.clearRect({x:options.x,y:options.y,w:options.w,h:options.h,r:8}); + + if (info.img) { + g.drawImage(info.img, options.x+1,options.y+2); + } + var text = info.text.toString().toUpperCase(); + if (g.setFont("7Seg:2").stringWidth(text)+24-2>options.w) g.setFont("7Seg"); + g.setFontAlign(0,-1).drawString(text, options.x+options.w/2+13, options.y+6); +}; + +// Show launcher when middle button pressed +Bangle.setUI({ + mode : "clock", + remove : function() { + // Called to unload all of the clock app + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + delete Graphics.prototype.setFont7Seg; + // remove info menu + clockInfoMenu.remove(); + delete clockInfoMenu; + clockInfoMenu2.remove(); + delete clockInfoMenu2; + clockInfoMenu3.remove(); + delete clockInfoMenu3; + clockInfoMenu4.remove(); + delete clockInfoMenu4; + // reset theme + g.setTheme(oldTheme); + }}); +// Load widgets +Bangle.loadWidgets(); +// Work out sizes +let R = Bangle.appRect; +R.x+=1; +R.y+=1; +R.x2-=1; +R.y2-=1; +R.w-=1; +R.h-=1; +let midX = R.x+R.w/2; +let bar1Y = R.y+30; +let bar2Y = R.y2-30; +// Clear the screen once, at startup +let oldTheme = g.theme; +g.setTheme({bg:"#000",fg:"#3ff",dark:true}).clear(1); +g.fillRect({x:R.x, y:R.y, w:R.w, h:R.h, r:8}) + .clearRect(R.x,bar1Y,R.w,bar1Y+1) + .clearRect(midX,R.y,midX,bar1Y) + .clearRect(R.x,bar2Y,R.w,bar2Y+1) + .clearRect(midX,bar2Y,midX,R.y2+1); +draw(); +Bangle.drawWidgets(); +// Allocate and draw clockinfos +let clockInfoItems = require("clock_info").load(); +let clockInfoMenu = require("clock_info").addInteractive(clockInfoItems, { app:"lcdclock", x:R.x, y:R.y, w:midX-2, h:bar1Y-R.y-2, draw : clockInfoDraw}); +let clockInfoMenu2 = require("clock_info").addInteractive(clockInfoItems, { app:"lcdclock", x:midX+1, y:R.y, w:midX-2, h:bar1Y-R.y-2, draw : clockInfoDraw}); +let clockInfoMenu3 = require("clock_info").addInteractive(clockInfoItems, { app:"lcdclock", x:R.x, y:bar2Y+2, w:midX-2, h:bar1Y-R.y-2, draw : clockInfoDraw}); +let clockInfoMenu4 = require("clock_info").addInteractive(clockInfoItems, { app:"lcdclock", x:midX+1, y:bar2Y+2, w:midX-2, h:bar1Y-R.y-2, draw : clockInfoDraw}); +} diff --git a/apps/lcdclockplus/app.png b/apps/lcdclockplus/app.png new file mode 100644 index 0000000000000000000000000000000000000000..b1a1a0debb1aa7f5571b8065fba781db502aa021 GIT binary patch literal 2703 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 JPDHLkV1f{uAVUBE literal 0 HcmV?d00001 diff --git a/apps/lcdclockplus/metadata.json b/apps/lcdclockplus/metadata.json new file mode 100644 index 000000000..e7d61db1a --- /dev/null +++ b/apps/lcdclockplus/metadata.json @@ -0,0 +1,15 @@ +{ "id": "lcdclockplus", + "name": "LCD Clock Plus", + "version":"0.01", + "description": "A Casio-style clock, with four ClockInfo areas at the top and bottom. Tap them and swipe up/down and left/right to toggle between different information.", + "icon": "app.png", + "screenshots": [{"url":"screenshot.png"},{"url":"screenshot2.png"}], + "type": "clock", + "tags": "clock,clkinfo", + "supports" : ["BANGLEJS2"], + "dependencies" : { "clock_info":"module" }, + "storage": [ + {"name":"lcdclockplus.app.js","url":"app.js"}, + {"name":"lcdclockplus.img","url":"app-icon.js","evaluate":true} + ] +} diff --git a/apps/lcdclockplus/screenshot.png b/apps/lcdclockplus/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..40acd527d84dceebb997c222e84239356a948240 GIT binary patch literal 2260 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