Added patriot clock - show your country's flag!
|
|
@ -0,0 +1 @@
|
||||||
|
0.01: New App!
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
require("heatshrink").decompress(atob("mEwwJC/AH4A/AH4AgA=="))
|
||||||
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
|
@ -0,0 +1,71 @@
|
||||||
|
Graphics.prototype.setFontAudiowide = function() {
|
||||||
|
// Actual height 33 (36 - 4)
|
||||||
|
return this.setFontCustom(
|
||||||
|
E.toString(require('heatshrink').decompress(atob('AB/wAgcB/AFVgFgHbkYAok4AogvEgYFEg4FEj4FEn4FE//gKQf/4AcD/4QDh/8Djf+DhN/T4YcFgYcKh4cEh68Eh4cDAoOAAocORYkMf1JxBIYcf/6PDn//MIYEB/5KBOIIABKwIFFO4V/UQMHEIMfFQMHAQP3AQJ3BDIKABh/ggf7ApHAg/5AonxAocPAokf8IFE4IFDn4FEv+BAokBAof/AofB/wFE/gFD4YFE4/4AohgBAoXPAonvMAIFD4AFCVgIFBQYX3wCGCR4T+CTYqtLX4rLC/zXIcYoAQQYIFiJoR9CArgAlToIpDRQIFDSwI7C4CiBApN/Apb1D4F+Av4Fd8H+Aof/AoaTB/gFIgaBBAoSrB+AFCgF/8AFDAESP/Av3wv0HZYYABYoYAB+AFGZYIAB8DLCAAPAZYQFBZUhHC/gFE/wFaAAN+Av4Fqv53EboYFdAFIvB4EBGofwAon4Aon8ApX+AofAAot+Av4Fev8DAojFDAo0/S4IFGAAMf//gV4mAAoUD/zYgFwP8AoRGB/4FCAgI1CgIFC4A5BAoRHBg4FCKYMH/l+n5fC+F+g5rC8F+PoYFFZf7XVw7XNAALXNTYLXCVoYAQF4IFZjAFEnAFELIZCBAojRDAoMfAol/AohrCAoJfBNYIFBNYOAAoUf/xBDv/8AoXBRAcP4aCDh/PDgSNCDgQFCHIIFDUoafFAoJ3EGYQFCDgYFBXgZuBGYQAba4pDEhzvE/4ABKoMBAogbBAAJKBg4EBw4FEX4Z9BgIFC8AFE4F+Av5HFKYhfFAoRxCO4qDFgF/AokATYgfCZwcD/zTdAAV/Z4RBCHIZNBJYI5D/gFFOJEP+DF/a7N+ZYQFG+F+g7XFRYIFFbobLBboajCAoTRCcYTiEUQYAdgYCBsACBMwJlCAqUHJYLxDAAMgHSQ'))),
|
||||||
|
46,
|
||||||
|
atob("CiAsESQjJSQkHyQkDA=="),
|
||||||
|
48|65536
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
let img = require("Storage").read("patriotclk.bg.img");
|
||||||
|
let options = require("Storage").readJSON("patriotclk.opts",1)||{};
|
||||||
|
|
||||||
|
// timeout used to update every minute
|
||||||
|
let drawTimeout;
|
||||||
|
|
||||||
|
// draw everything
|
||||||
|
let draw = function() {
|
||||||
|
var x = g.getWidth()/2;
|
||||||
|
var y;
|
||||||
|
if (options.bottomText)
|
||||||
|
y = g.getHeight() - 24;
|
||||||
|
else
|
||||||
|
y = 4+(g.getHeight())/2; // middle
|
||||||
|
g.reset();
|
||||||
|
g.drawImage(img,0,0);
|
||||||
|
// work out locale-friendly date/time
|
||||||
|
var date = new Date();
|
||||||
|
var timeStr = require("locale").time(date,1);
|
||||||
|
var dateStr = require("locale").date(date);
|
||||||
|
// draw time
|
||||||
|
g.setFontAlign(0,0).setFont("Audiowide");
|
||||||
|
// draw a shadow by shifting left/right/up/down
|
||||||
|
g.drawString(timeStr,x-6,y);
|
||||||
|
g.drawString(timeStr,x+6,y);
|
||||||
|
g.drawString(timeStr,x,y-6);
|
||||||
|
g.drawString(timeStr,x,y+6);
|
||||||
|
g.drawString(timeStr,x-4,y+4);
|
||||||
|
g.drawString(timeStr,x+4,y+4);
|
||||||
|
g.drawString(timeStr,x-4,y-4);
|
||||||
|
g.drawString(timeStr,x+4,y-4);
|
||||||
|
// finally draw in the foreground color
|
||||||
|
g.setColor(g.theme.bg).drawString(timeStr,x,y);
|
||||||
|
// draw date
|
||||||
|
//y += 35;
|
||||||
|
//g.setFontAlign(0,0).setFont("6x8").g.setColor(g.theme.fg);
|
||||||
|
//g.drawString(dateStr,x,y);
|
||||||
|
// queue draw in one minute
|
||||||
|
if (drawTimeout) clearTimeout(drawTimeout);
|
||||||
|
drawTimeout = setTimeout(function() {
|
||||||
|
drawTimeout = undefined;
|
||||||
|
draw();
|
||||||
|
}, 60000 - (Date.now() % 60000));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Clear the screen once, at startup
|
||||||
|
g.clear();
|
||||||
|
// draw immediately at first, queue update
|
||||||
|
draw();
|
||||||
|
// Show launcher when middle button pressed
|
||||||
|
Bangle.setUI({mode:"clock", remove:function() { //f ree memory
|
||||||
|
if (drawTimeout) clearTimeout(drawTimeout);
|
||||||
|
delete Graphics.prototype.setFontAudiowide;
|
||||||
|
require("widget_utils").cleanup();
|
||||||
|
}});
|
||||||
|
// Load widgets (make them swipeable)
|
||||||
|
Bangle.loadWidgets();
|
||||||
|
require("widget_utils").swipeOn();
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 446 B |
|
|
@ -0,0 +1,133 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="../../css/spectre.min.css">
|
||||||
|
<style>
|
||||||
|
.flag {
|
||||||
|
width : 100px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
#preview {
|
||||||
|
width : 176px;
|
||||||
|
height: 176px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>Please choose your country's flag:</p>
|
||||||
|
<div id="flaglist"></div>
|
||||||
|
<p>Is your flag not here? Please <a href="https://github.com/espruino/BangleApps/tree/master/apps/patriotclk/img" target="_blank">add it here</a>! </p>
|
||||||
|
<div style="float:right">Preview:<br/><canvas width="176" height="176" id="preview"></canvas></div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-switch">
|
||||||
|
<input type="checkbox" id="box_zoom">
|
||||||
|
<i class="form-icon"></i> Zoom
|
||||||
|
</label>
|
||||||
|
<label class="form-switch">
|
||||||
|
<input type="checkbox" id="box_textbottom">
|
||||||
|
<i class="form-icon"></i> Time at bottom
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<p>Click <button id="upload" class="btn btn-primary disabled" style>Upload</button></p>
|
||||||
|
|
||||||
|
<img id="preview_overlay" src="app-preview.png" style="display:none">
|
||||||
|
<img id="preview_overlay_btm" src="app-preview-btm.png" style="display:none">
|
||||||
|
|
||||||
|
|
||||||
|
<script src="../../core/lib/customize.js"></script>
|
||||||
|
<script src="../../webtools/imageconverter.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var FLAGS = `
|
||||||
|
icons8-australia-480.png
|
||||||
|
icons8-belgium-480.png
|
||||||
|
icons8-england-480.png
|
||||||
|
icons8-flag-of-europe-480.png
|
||||||
|
icons8-france-480.png
|
||||||
|
icons8-germany-480.png
|
||||||
|
icons8-great-britain-480.png
|
||||||
|
icons8-greece-480.png
|
||||||
|
icons8-hungary-480.png
|
||||||
|
icons8-italy-480.png
|
||||||
|
icons8-lgbt-flag-480.png
|
||||||
|
icons8-scotland-480.png
|
||||||
|
icons8-switzerland-480.png
|
||||||
|
icons8-ukraine-480.png
|
||||||
|
icons8-usa-480.png
|
||||||
|
icons8-wales-480.png
|
||||||
|
`.trim().split("\n").map(s=>s.trim());
|
||||||
|
// If we can't map a flag direct to 3 bit color, enable dithering
|
||||||
|
var DITHERED_FLAGS = `
|
||||||
|
icons8-lgbt-flag-480.png
|
||||||
|
icons8-ukraine-480.png
|
||||||
|
`.trim().split("\n").map(s=>s.trim());
|
||||||
|
|
||||||
|
var selectedImage;
|
||||||
|
var bgImageData;
|
||||||
|
var clockOptions = {
|
||||||
|
bottomText : false
|
||||||
|
};
|
||||||
|
|
||||||
|
document.getElementById("flaglist").innerHTML =
|
||||||
|
FLAGS.map(f => `<img class="flag" src="img/${f}" data-file="${f}"/>`).join("\n");
|
||||||
|
var elements = document.querySelectorAll(".flag");
|
||||||
|
for (var i=0;i<elements.length;i++)
|
||||||
|
elements[i].addEventListener("click", function(e) {
|
||||||
|
selectedImage = e.target;
|
||||||
|
drawPreview();
|
||||||
|
document.getElementById("upload").classList.remove("disabled")
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function drawPreview() {
|
||||||
|
if (!selectedImage) return;
|
||||||
|
var imgFile = selectedImage.getAttribute("data-file");
|
||||||
|
var zoom = document.getElementById("box_zoom").checked;
|
||||||
|
clockOptions.bottomText = document.getElementById("box_textbottom").checked;
|
||||||
|
const canvas = document.getElementById("preview");
|
||||||
|
canvas.width = 176; // setting size clears canvas
|
||||||
|
canvas.height = 176;
|
||||||
|
const ctx = canvas.getContext("2d");
|
||||||
|
var y = 0;
|
||||||
|
if (clockOptions.bottomText)
|
||||||
|
y = -28;
|
||||||
|
if (zoom)
|
||||||
|
ctx.drawImage(selectedImage, 90, 90, 300, 300, 0, y, 176, 176);
|
||||||
|
else
|
||||||
|
ctx.drawImage(selectedImage, 20, 20, 440, 440, 0, y, 176, 176);
|
||||||
|
var options = {
|
||||||
|
mode:"3bit",
|
||||||
|
output:"raw",
|
||||||
|
compression:false,
|
||||||
|
updateCanvas:true,
|
||||||
|
transparent:false,
|
||||||
|
contrast:128
|
||||||
|
};
|
||||||
|
if (DITHERED_FLAGS.includes(imgFile))
|
||||||
|
options.diffusion = "bayer2";
|
||||||
|
bgImageData = imageconverter.canvastoString(canvas, options);
|
||||||
|
ctx.drawImage(document.getElementById(clockOptions.bottomText?"preview_overlay_btm":"preview_overlay"),0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If options changed
|
||||||
|
document.getElementById("box_zoom").addEventListener("click", function() {
|
||||||
|
drawPreview();
|
||||||
|
});
|
||||||
|
document.getElementById("box_textbottom").addEventListener("click", function() {
|
||||||
|
drawPreview();
|
||||||
|
});
|
||||||
|
// When the 'upload' button is clicked...
|
||||||
|
document.getElementById("upload").addEventListener("click", function() {
|
||||||
|
// send finished app (in addition to contents of metadata.json)
|
||||||
|
if (bgImageData) sendCustomizedApp({
|
||||||
|
storage:[
|
||||||
|
{name:"patriotclk.bg.img", content:bgImageData},
|
||||||
|
{name:"patriotclk.opts", content:JSON.stringify(clockOptions)}, // we don't save as .json or we'd have a sanitycheck warning
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
Flags
|
||||||
|
------
|
||||||
|
|
||||||
|
These flags come from https://icons8.com/icon/set/flags/color and are 480x480px
|
||||||
|
|
||||||
|
If you want to add your own flag ensure it's in the same style and then also list the image file in custom.html in the root directory.
|
||||||
|
|
||||||
|
If your flag is listed in https://icons8.com/icon/set/flags/color and you can't download it in the right size, please file an issue and we'll download it with our account.
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 7.8 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
|
@ -0,0 +1,18 @@
|
||||||
|
{ "id": "patriotclk",
|
||||||
|
"name": "Patriotic Clock",
|
||||||
|
"shortName":"Patriot",
|
||||||
|
"version":"0.01",
|
||||||
|
"description": "Show your Patriotism with your Country's flag as a clock face (configurable)",
|
||||||
|
"icon": "app.png",
|
||||||
|
"screenshots": [{"url":"screenshot.png"}],
|
||||||
|
"type": "clock",
|
||||||
|
"tags": "clock,flag",
|
||||||
|
"supports" : ["BANGLEJS2"],
|
||||||
|
"custom": "custom.html",
|
||||||
|
"storage": [
|
||||||
|
{"name":"patriotclk.app.js","url":"app.js"},
|
||||||
|
{"name":"patriotclk.bg.img"},
|
||||||
|
{"name":"patriotclk.opts"},
|
||||||
|
{"name":"patriotclk.img","url":"app-icon.js","evaluate":true}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 3.2 KiB |