diff --git a/apps/fontkorean/ChangeLog b/apps/fontkorean/ChangeLog new file mode 100644 index 000000000..7b83706bf --- /dev/null +++ b/apps/fontkorean/ChangeLog @@ -0,0 +1 @@ +0.01: First release diff --git a/apps/fontkorean/README.md b/apps/fontkorean/README.md new file mode 100644 index 000000000..6d9eecd45 --- /dev/null +++ b/apps/fontkorean/README.md @@ -0,0 +1,17 @@ +# Fonts (Korean) + +This library provides an Korean font that can be used to display messages. + +The font is the 16px high [GNU Unifont](https://unifoundry.com/unifont/index.html). +Korean characters from Unicode codepoint 32-255, 0x1100-0x11FF, 0x3130-0x318F, 0xA960-0xA97F + +## Usage + +See [the BangleApps README file](https://github.com/espruino/BangleApps/blob/master/README.md#api-reference) +for more information on fonts. + + +## Recreating fontkorean.pbf + +* Go to `bin` directory +* Run `./font_creator.js "Korean" ../apps/fontkorean/font.pbf` diff --git a/apps/fontkorean/boot.js b/apps/fontkorean/boot.js new file mode 100644 index 000000000..5f3a24433 --- /dev/null +++ b/apps/fontkorean/boot.js @@ -0,0 +1 @@ +Graphics.prototype.setFontIntl = function() { return this.setFontPBF(require("Storage").read("fontkorean.pbf")); }; \ No newline at end of file diff --git a/apps/fontkorean/font.pbf b/apps/fontkorean/font.pbf new file mode 100644 index 000000000..f08545b85 Binary files /dev/null and b/apps/fontkorean/font.pbf differ diff --git a/apps/fontkorean/fontkorean_icon.png b/apps/fontkorean/fontkorean_icon.png new file mode 100644 index 000000000..a4b02ea3a Binary files /dev/null and b/apps/fontkorean/fontkorean_icon.png differ diff --git a/apps/fontkorean/lib.js b/apps/fontkorean/lib.js new file mode 100644 index 000000000..bcb3b4bca --- /dev/null +++ b/apps/fontkorean/lib.js @@ -0,0 +1,3 @@ +exports.getFont = (options) => { + return "Intl"; // placeholder for now - see https://github.com/espruino/BangleApps/issues/3109 +}; \ No newline at end of file diff --git a/apps/fontkorean/metadata.json b/apps/fontkorean/metadata.json new file mode 100644 index 000000000..c21bdf87c --- /dev/null +++ b/apps/fontkorean/metadata.json @@ -0,0 +1,16 @@ +{ "id": "fontkorean", + "name": "Korean font", + "version":"0.01", + "description": "Installs a font data, Unifont characters for Korean **Requires 420 KB storage**", + "icon": "fontkorean_icon.png", + "tags": "font", + "type": "module", + "provides_modules" : ["font"], + "supports" : ["BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"font","url":"lib.js"}, + {"name":"fontkorean.boot.js","url":"boot.js"}, + {"name":"fontkorean.pbf","url":"font.pbf"} + ] +} diff --git a/apps/jclock/ChangeLog b/apps/jclock/ChangeLog new file mode 100644 index 000000000..c530930a6 --- /dev/null +++ b/apps/jclock/ChangeLog @@ -0,0 +1,2 @@ +0.01: Created +0.02: Changed side bar color to blue for better clarity when it's locked diff --git a/apps/jclock/README.md b/apps/jclock/README.md new file mode 100644 index 000000000..7ddb346dc --- /dev/null +++ b/apps/jclock/README.md @@ -0,0 +1,26 @@ +# jclock + +I have used Rebble clock since I bought my Banglejs 2, and wanted to make my own clock with much simpler features and to switch the time window and the feature window because I'm wearing my watch on my left wrist and about a half (left side) of the screen is covered by the sleeve of my jacket or shirts. Of course it won't happen during summer, but I decided to make my first Bagle app with these changes. See Features below for the items displayed on the screen. +- The layout is inspired by the Rebble clock. +- The big font KdamThmor is copied from the Rebble clock. + +## Features +- Single screen +- No settings +- Time on the right side with big font +- On the sidebar on the left + - Day of week + - Day + - Month + - Steps + - Bluetooth connection status + - Battery % +- Update time and status every 1 minute + +## Screenshots +![](jclock_screenshot_no_BT.png) +![](jclock_screenshot_BT.png) + +## Creator + +Written by [JeonLab](https://jeonlab.wordpress.com) diff --git a/apps/jclock/app-icon.js b/apps/jclock/app-icon.js new file mode 100644 index 000000000..7744de49f --- /dev/null +++ b/apps/jclock/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEw4f/AAIHB7ue4cYrPO0cQtUy2WUHU0kyVJARAQEhIRLkgQCgQOKAQWACIYbHIImQAYMSpQRLgmSCIVSCJcACIWSKJARPzO9gETm+4BwNACI8Etu28GN23fIgIRIg14hnw/UI7wRGltvCIMjuEO7BCBCI97twRCsEICIMO7gRKnYRCju2/A1Hr4RHEY5ZDGokJzeACJRZB+EAgPbCIxrDgd4g347kBEY8rLIUHUIPA9qhICIcA/LFBj830ARLAAwR/CMkd3wOBozXHCIcE5oRCswRLg/RCIMD3gRLcoIRBgOwCJ8Z+ARIfYQRDx8ACI97CI1uCI9K7YRFglt23b4ARGuQROpPXAQI1EAAJHHkgCCg4gB+ARVyQRIdI+SdgVSCKFKCJcEyADBgVJlIRJhMkCIUAEQgCIwAXECJUgHYoRJPQIAlA=")) diff --git a/apps/jclock/app.js b/apps/jclock/app.js new file mode 100644 index 000000000..5c4d709d6 --- /dev/null +++ b/apps/jclock/app.js @@ -0,0 +1,68 @@ +// single screen, clock on the right, sidebar without image (date/steps/bluetooth connection status/batt%) + +// Large font KdamThmor taken from Rebble clock +Graphics.prototype.setFontKdamThmor = function(scale) { + // Actual height 70 (69 - 0) + this.setFontCustom( + E.toString(require('heatshrink').decompress(atob('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'))), + 46, + atob("GBo2NjY2NjY2NjY2Gg=="), + 94+(scale<<8)+(1<<16) + ); + return this; +}; + +var drawTimeout; + +// schedule a draw for the next minute +function queueDraw() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); +} + +const zeroPad = (num, places) => String(num).padStart(places, '0'); + +function draw() { + let barWidth = 64; + let date = new Date(); + + // queue next draw in one minute + queueDraw(); + + // clean screen + g.reset().clearRect(Bangle.appRect); + + // draw side bar in blue + g.setColor('#00f'); + g.fillRect(0, 0, barWidth, g.getHeight()); + + // show time on the right + g.setColor(g.theme.fg); + g.setFontKdamThmor().setFontAlign(0,-1).drawString(zeroPad(date.getHours(),2), 120, 10); + g.setFontKdamThmor().setFontAlign(0,-1).drawString(zeroPad(date.getMinutes(),2), 120, g.getHeight()/2+10); + + // show date + g.setFont('Vector', 20).setFontAlign(0, -1).setColor('#fff'); + g.drawString(require("date_utils").dow(date.getDay(),1).toUpperCase(), barWidth/2, 3); + g.drawString(date.getDate(), barWidth/2, 28); + g.drawString(require("date_utils").month(date.getMonth()+1,1).toUpperCase(), barWidth/2, 53); + + // divider, place holder for any other info + g.drawString('=====', barWidth/2, 78); + + // show daily steps + g.drawString(Bangle.getHealthStatus("day").steps, barWidth/2, 103); + + // show battery remaining percentage + g.drawString(E.getBattery() + '%', barWidth/2, 153); + + // Bluetooth connection status + if (NRF.getSecurityStatus().connected) g.drawString('>BT<', barWidth/2, 128); +} + +draw(); + +Bangle.setUI("clock"); diff --git a/apps/jclock/app.png b/apps/jclock/app.png new file mode 100644 index 000000000..a0bf26562 Binary files /dev/null and b/apps/jclock/app.png differ diff --git a/apps/jclock/jclock_screenshot_BT.png b/apps/jclock/jclock_screenshot_BT.png new file mode 100644 index 000000000..e4eac99d0 Binary files /dev/null and b/apps/jclock/jclock_screenshot_BT.png differ diff --git a/apps/jclock/jclock_screenshot_no_BT.png b/apps/jclock/jclock_screenshot_no_BT.png new file mode 100644 index 000000000..a312d23ed Binary files /dev/null and b/apps/jclock/jclock_screenshot_no_BT.png differ diff --git a/apps/jclock/metadata.json b/apps/jclock/metadata.json new file mode 100644 index 000000000..9a7ddd337 --- /dev/null +++ b/apps/jclock/metadata.json @@ -0,0 +1,16 @@ +{ "id":"jclock", + "name":"jclock", + "shortName":"jclock", + "icon":"app.png", + "version":"0.02", + "description":"Similar layout to Rebble clock, but much simpler features with switched time and the feature window. The time is on the right side. This is my first Bangle app.", + "type": "clock", + "tags": "clock", + "supports" : ["BANGLEJS2"], + "screenshots": [{"url":"jclock_screenshot_no_BT.png"},{"url":"jclock_screenshot_BT.png"}], + "storage": [ + {"name":"jclock.app.js","url":"app.js"}, + {"name":"jclock.img","url":"app-icon.js","evaluate":true} + ], + "readme":"README.md" +}