1
0
Fork 0

Merge pull request #2723 from stweedo/master

v0.02 of Shadow Clock with settings menu
master
Gordon Williams 2023-05-09 09:09:53 +01:00 committed by GitHub
commit 763ba8934a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 532 additions and 68 deletions

View File

@ -1 +1,2 @@
0.01: New App!
0.02: New 'Settings Menu' to choose your favorite color and switch between light or dark themes

25
apps/shadowclk/README.md Normal file
View File

@ -0,0 +1,25 @@
# Shadow Clock
Shadow Clock uses the "Londrina" font in a user selectable color and surrounds it in the "Londrina Shadow" font to create a visually appealing way to show the time in a clear, easily readable manner. On the Bangle.js 2, the time can be read easily even if the screen is locked and unlit.
## Usage
* Install Shadow Clock through the Bangle.js app loader.
* Configure it through the default Bangle.js configuration mechanism
(Settings app, "Apps" menu, "Shadow Clock" submenu).
* If you like it, make it your default watch face
(Settings app, "System" menu, "Clock" submenu, select "Shadow Clock").
## Configuration
Anton Clock is configured by the standard settings mechanism of Bangle.js's operating system:
Open the `Settings` app, then the `Apps` submenu and below it the `Shadow Clock` menu.
You configure Shadow Clock by selecting a `Light` or `Dark` system wide theme and then selecting the `Color` of the clock numbers.
## Compatibility
Shadow Clock should be fully compatible with with Bangle.js 1 and Bangle.js 2. However, it was built and tested with Bangle.js 2
## Creator
[stweedo](https://github.com/stweedo)

View File

@ -1 +1 @@
require("heatshrink").decompress(atob("mEwhHXAH4A/AH4A/AH4A/AH4A/AH4A/AFGsAAQOUA4OBDBYfHo8jAAOBByOssgICkdkF6AWEF5IOHxAHDAAVALx4VEF5AOHA4oAD0ovNoEjo6BCF5AOHF4ccp9dAoVdFxh2CioUCa44OIwIFCirwBjgFBqyNPqxJCEAOIKwOIBxYJChwfBwIABJQ7dHnIkCEAsVBxovDdiMcVYIgHFQgOJR4WIxBdMCoccshUCkdkRYJ6DBxIvDAAlkF5wWLBxQKJOAIvTroOOBQkcmU5aoYAKhwACjiqDqwOOTQQqDGwQvMAAawCcoOsAAQOL642DBAI0EAB1AC4QfBJIU5BxQ2DAAp5FF6ZJFF4xgFAAMOOwyPKjkcCgWsAoMyBxQAB1k5BAMcZAQuPDIS6EYBAIRAHKHCAIhPLAoWswIMEL6OBDIgYGHA4qCCwIKBDIgvPDggnIAw7lBF4J4KR5gVJKgZDDIgQCDMITvXXA47EHxD2aFQhOCBAY8DRiiWLD4aEBMYzuCLzgvEEQK4BFAQCDB4TACF7QA/AH4A/AH4A/AAQA=="))
require("heatshrink").decompress(atob("mEwxH+64Afq17AAlWq2sBYOtB4Urq2BFzeBwONAAeyHAQvCrPX1g3BlYvb02BjwADF4QmBwdZF4MrleBgAvlgAwBgqQBlcAF72HF46PBwaPDwK/dVoLpBAAwMBweDFTYA/AH4A/AH4A/AF2lAAOsBRIAF6AMDp9Wp+lFyNWkYABitWFwoKCAAsHBgMyBAkVwIuO6EVCod6F50A6+BBI0VMRxGEF6BfBIwZqHABRGCo5EIF4cOgEHAAUA0scBYQDDCAIvMhx7CCYTfDAYIvDK4McNoaODh1PPgcO1jsNiskOYQTBh0cjlW1iDHfwJfDjmeoDKEABSlCgAlCF4QJGcgwPEfQ5eMFQIvDRYIfClesioADEgcrSAguEwJeNh1AAgQkBwOlkkkQoOBvQACIgRAB685F4wJBF5oAGp4UJ1i6CeQK/Dg4ECZYQvTComsnNdrp+B0rADlaKD1l6X52BgAACJIgvEFIcO0sOF4cAAgeISgYvLMg8HKoOBAAIvEAAsOL4bwGFxyuDg/QGoYZBT5AKBXQYvVCYUH1gvFqwjGTwWBGA0AOwIAN6EOhytBAwIFBh1PAoN6g8VskVmUAZoelBQVABQIuPMAS6DfYWBMgI9CwMrq2lDA2Bq1PFqLpCHBAWKMIJGBAgRDEABiKBlYTDAYcA1gKBqwgFlYMBLoIaBCIKZDABh+BDIQVBC4WsF4YOBGAmsBQSgCAIIvQFYIiBKwReDFQI3DEIlWFIIsBCwIABF6JhClZhBZQo8BAYIOBIoh0CBIJ5DAH4AEPYKBDWwSGCAoKIDAoIwcEwJ/CRYICCFoI8BQ4YKBMDhWBEwIjBYQcAAYQKBZIRfdAIJVCQgLkDAYJjCcX4A/AH4A/AFwA=="))

View File

@ -20,27 +20,57 @@ Graphics.prototype.setFontLondrinaShadow = function() {
);
};
Graphics.prototype.setFontDotGothic16 = function() {
// Actual height 20 (19 - 0)
return this.setFontCustom(
E.toString(require('heatshrink').decompress(atob('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'))),
32,
atob("CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoA"),
20|65536
);
};
let storage = require('Storage');
var settings = Object.assign({
// default values
color: "#0ff",
theme: "light",
}, storage.readJSON("shadowclk.json", true) || {});
(function() {
let drawTimeout;
// Actually draw the watch face
function draw() {
const x = g.getWidth() / 2;
const y = g.getHeight() / 2;
var x = g.getWidth() / 2;
var y = g.getHeight() / 2;
g.reset().clearRect(Bangle.appRect);
const date = new Date();
var date = new Date();
var hour = String(date.getHours()).padStart(2, '0');
if (hour[0] === '0') hour = hour[1];
var minutes = String(date.getMinutes()).padStart(2, '0');
const timeStr = hour + ':' + minutes;
g.setFontAlign(0, 0).setFont("LondrinaSolid").setColor(0, 1, 1).drawString(timeStr, x - 1, y);
var timeStr = hour + ':' + minutes;
var color = settings.color;
g.setFontAlign(0, 0).setFont("LondrinaSolid").setColor(color).drawString(timeStr, x - 1, y);
g.reset().setFontAlign(0, 0).setFont("LondrinaShadow").drawString(timeStr, x - 1, y);
const locale = require("locale");
const dateStr = locale.date(date, 0).toUpperCase() + "\n" +
locale.dow(date, 0).toUpperCase();
g.setFontAlign(0, 0).setFont("6x8", 2).drawString(dateStr, x, y + 48);
var locale = require("locale");
var dayOfMonth = date.getDate();
var month = locale.month(date, 1).slice(0, 1).toUpperCase() + locale.month(date, 1).slice(1).toLowerCase();
var year = date.getFullYear();
var dayOfMonthStr = dayOfMonth.toString();
if (dayOfMonth === 1 || dayOfMonth === 21 || dayOfMonth === 31) {
dayOfMonthStr += "st";
} else if (dayOfMonth === 2 || dayOfMonth === 22) {
dayOfMonthStr += "nd";
} else if (dayOfMonth === 3 || dayOfMonth === 23) {
dayOfMonthStr += "rd";
} else {
dayOfMonthStr += "th";
}
var dayOfWeek = locale.dow(date, 0).slice(0, 1).toUpperCase() + locale.dow(date, 0).slice(1).toLowerCase();
var dateStr = month + " " + dayOfMonthStr + ", " + year + "\n" + dayOfWeek;
g.setFontAlign(0, 0).setFont("DotGothic16").drawString(dateStr, x, y + 48);
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = setTimeout(() => {
@ -54,9 +84,11 @@ Graphics.prototype.setFontLondrinaShadow = function() {
remove: function() {
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = undefined;
delete Graphics.prototype.setFontLondrinaSolid;
delete Graphics.prototype.setFontLondrinaShadow;
delete Graphics.prototype.setFontDotGothic16;
}
});
Bangle.loadWidgets();
draw();
setTimeout(Bangle.drawWidgets, 0);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
apps/shadowclk/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

View File

@ -0,0 +1,283 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="../../css/spectre.min.css">
<link href="https://fonts.googleapis.com/css2?family=Londrina+Solid&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Londrina+Shadow&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=DotGothic16&display=swap" rel="stylesheet">
<title>3-Bit Color Picker</title>
<style>
.main-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
}
.color-button {
width: 30px;
height: 30px;
border: 1px solid black;
margin: 5px;
cursor: pointer;
}
.color-0 {
background: #000
}
.color-1 {
background: #f00
}
.color-2 {
background: #0f0
}
.color-3 {
background: #ff0
}
.color-4 {
background: #00f
}
.color-5 {
background: #f0f
}
.color-6 {
background: #0ff
}
.color-7 {
background: #fff
}
#preview-box {
width: 176px;
height: 176px;
border: 1px solid black;
margin-top: 20px;
display: flex;
align-items: center;
justify-content: center;
background: white;
}
#preview-canvas {
display: block;
}
#toggle-bg {
margin-top: 20px;
}
#upload {
margin-top: 20px;
}
</style>
</head>
<body>
<script src="../../lib/interface.js"></script>
<div class="main-container">
<h1>3-Bit Color Picker</h1>
<div>
<script>
let colors = ['#000', '#f00', '#0f0', '#ff0', '#00f', '#f0f', '#0ff', '#fff'];
colors.forEach((color, i) => {
document.write(`<button class="color-button color-${i}" data-color="${color}"></button>`);
});
</script>
</div>
<button id="toggle-bg" class="btn btn-primary" onclick="toggleBackground()">Light/Dark</button>
<div id="preview-box">
<canvas id="preview-canvas" width="176" height="176"></canvas>
</div>
<button id="upload" class="btn btn-primary">Upload</button>
<script src="../../core/lib/customize.js"></script>
</div>
<script>
let selectedColor = "#0ff";
let isDarkBg = false; // Add this line to track the background state
document.querySelectorAll(".color-button").forEach(button => {
button.addEventListener("click", () => {
selectedColor = button.dataset.color;
drawText(selectedColor);
});
});
function formatTime(date) {
let hours = date.getHours();
let minutes = date.getMinutes();
let formattedHours = hours < 10 ? `${hours}` : `${hours}`;
let formattedMinutes = minutes < 10 ? `0${minutes}` : `${minutes}`;
return `${formattedHours}:${formattedMinutes}`;
}
function getCurrentDate() {
let months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
let suffixes = ["st", "nd", "rd", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th", "th", "st"];
let date = new Date();
let month = months[date.getMonth()];
let day = date.getDate();
let suffix = suffixes[day - 1];
let year = date.getFullYear();
return `${month} ${day}${suffix}, ${year}`;
}
function getCurrentDay() {
let days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
let date = new Date();
return days[date.getDay()];
}
function toggleBackground() {
let previewBox = document.getElementById("preview-box");
isDarkBg = !isDarkBg; // Toggle the background state
previewBox.style.backgroundColor = isDarkBg ? "black" : "white";
drawText(selectedColor); // Redraw the text with updated color
}
function drawText(color) {
let canvas = document.getElementById("preview-canvas");
let ctx = canvas.getContext("2d");
// Clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Set the base font and selected color
ctx.font = "81px Londrina Solid";
ctx.fillStyle = color;
// Get the current local system time
let currentTime = formatTime(new Date());
// Measure the text width and calculate the horizontal position
let timeWidth = ctx.measureText(currentTime).width;
let xPos = (canvas.width - timeWidth) / 2;
// Measure the text height based on the font size and calculate the vertical position
let timeHeight = ctx.measureText('M').actualBoundingBoxAscent + ctx.measureText('M').actualBoundingBoxDescent;
let yPos = (canvas.height + timeHeight) / 2;
// Draw the time
ctx.fillText(currentTime, xPos, yPos);
// Set the outline font and color
ctx.font = "81px Londrina Shadow";
// Set the text color based on the background state
if (isDarkBg) {
ctx.fillStyle = "#fff";
} else {
ctx.fillStyle = "#000";
}
// Draw the time again
ctx.fillText(currentTime, xPos, yPos);
// Set the font for the date
ctx.font = "19px DotGothic16";
// Get the current date
let currentDate = getCurrentDate();
// Measure the date width and calculate the horizontal position
let dateWidth = ctx.measureText(currentDate).width;
xPos = (canvas.width - dateWidth) / 2;
// Draw the date
yPos += 20;
ctx.fillText(currentDate, xPos, yPos);
// Get the current day of the week
let currentDay = getCurrentDay();
// Measure the day width and calculate the horizontal position
let dayWidth = ctx.measureText(currentDay).width;
xPos = (canvas.width - dayWidth) / 2;
// Draw the day of the week
ctx.fillText(currentDay, xPos, yPos + 20);
}
// Update the time every second
setInterval(() => {
drawText(selectedColor);
}, 1000);
function hexToDec(hex) {
if (hex.length === 4) {
hex = `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}`;
}
let r = parseInt(hex.slice(1, 3), 16) >> 3;
let g = parseInt(hex.slice(3, 5), 16) >> 2;
let b = parseInt(hex.slice(5, 7), 16) >> 3;
return (r << 11) | (g << 5) | b;
}
// Colors from 'Light BW' and 'Dark BW' themes
function createThemeColors(isDarkBg) {
return isDarkBg ? {
fg: hexToDec("#fff"),
bg: hexToDec("#000"),
fg2: hexToDec("#fff"),
bg2: hexToDec("#004"),
fgH: hexToDec("#fff"),
bgH: hexToDec("#00f"),
dark: true
} : {
fg: hexToDec("#000"),
bg: hexToDec("#fff"),
fg2: hexToDec("#000"),
bg2: hexToDec("#cff"),
fgH: hexToDec("#000"),
bgH: hexToDec("#0ff"),
dark: false
};
}
function saveThemeToSettings(theme) {
Puck.eval('require("Storage").readJSON("setting.json", true)', (data) => {
if (data) {
// Ensure that data.theme exists
if (!data.theme) {
data.theme = {};
}
// Save all theme values
for (let key in theme) {
data.theme[key] = theme[key];
}
data.clock = "shadowclk.app.js"; // Set Shadow Clock as default
Puck.write(`require("Storage").write("setting.json", ${JSON.stringify(data)});\n`, (result) => {
console.log('Theme saved:', result);
});
}
});
}
document.getElementById("upload").addEventListener("click", function () {
// Save theme settings to Bangle.js
let themeColors = createThemeColors(isDarkBg);
saveThemeToSettings(themeColors);
// Save Shadow Clock color setting
let data = {
color: selectedColor,
theme: isDarkBg ? "dark" : "light"
};
Puck.write(`require("Storage").write("shadowclk.json", ${JSON.stringify(data)});\n`, (result) => {
console.log('Color saved:', result);
});
});
</script>
</body>
</html>

View File

@ -1,16 +1,35 @@
{
"id": "shadowclk",
"name": "Shadow Clock",
"version": "0.01",
"description": "A simple clock using the Londrina font with color and a shadowed outline. Based on the Anton Clock.",
"version": "0.02",
"description": "A simple clock using the Londrina font in color with a shadowed outline. Based on the Anton Clock.",
"icon": "app.png",
"screenshots": [{"url":"screenshot.png"},{"url":"screenshot-1.png"}],
"screenshots": [{
"url": "screenshot.png"
}, {
"url": "screenshot-1.png"
}],
"type": "clock",
"tags": "clock",
"supports": ["BANGLEJS", "BANGLEJS2"],
"readme": "README.md",
"interface": "interface.html",
"allow_emulator": true,
"storage": [
{"name":"shadowclk.app.js","url":"app.js"},
{"name":"shadowclk.img","url":"app-icon.js","evaluate":true}
]
"storage": [{
"name": "shadowclk.app.js",
"url": "app.js"
},
{
"name": "shadowclk.settings.js",
"url": "settings.js"
},
{
"name": "shadowclk.img",
"url": "app-icon.js",
"evaluate": true
}
],
"data": [{
"name": "shadowclk.json"
}]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

104
apps/shadowclk/settings.js Normal file
View File

@ -0,0 +1,104 @@
(function(back) {
let teletextColors = ["#000", "#f00", "#0f0", "#ff0", "#00f", "#f0f", "#0ff", "#fff"];
let teletextColorNames = ["Black", "Red", "Green", "Yellow", "Blue", "Magenta", "Cyan", "White"];
// Load and set default settings
let appSettings = Object.assign({
color: teletextColors[6],
theme: 'light',
}, require('Storage').readJSON("shadowclk.json", true) || {});
// Save settings to storage
function writeSettings() {
require('Storage').writeJSON("shadowclk.json", appSettings);
}
// Colors from 'Light BW' and 'Dark BW' themes
function createThemeColors(mode) {
let cl = x => g.setColor(x).getColor();
return mode ? {
fg: cl("#fff"),
bg: cl("#000"),
fg2: cl("#fff"),
bg2: cl("#004"),
fgH: cl("#fff"),
bgH: cl("#00f"),
dark: true
} : {
fg: cl("#000"),
bg: cl("#fff"),
fg2: cl("#000"),
bg2: cl("#cff"),
fgH: cl("#000"),
bgH: cl("#0ff"),
dark: false
};
}
// Switch theme and save to storage
function switchTheme(mode) {
if (mode === g.theme.dark) return;
let s = require('Storage').readJSON("setting.json", 1) || {};
s.theme = createThemeColors(mode);
require('Storage').writeJSON("setting.json", s);
updateTheme(mode);
}
// Update the current menu with the new theme
function updateTheme(mode) {
let newTheme = createThemeColors(mode);
g.theme = newTheme;
appSettings.theme = mode ? 'dark' : 'light';
writeSettings();
delete g.reset;
g._reset = g.reset;
g.reset = function(n) {
return g._reset().setColor(newTheme.fg).setBgColor(newTheme.bg);
};
g.clear = function(n) {
if (n) g.reset();
return g.clearRect(0, 0, g.getWidth(), g.getHeight());
};
g.clear(1);
Bangle.drawWidgets();
showMenu();
}
// Read the current system theme
function getCurrentTheme() {
let s = require('Storage').readJSON("setting.json", 1) || {};
if (!s.theme) {
return appSettings.theme; // fallback to appSettings.theme (light or dark)
}
return s.theme.dark ? 'dark' : 'light';
}
function showMenu() {
appSettings.theme = getCurrentTheme();
E.showMenu({
"": {
"title": "Shadow Clock"
},
"< Back": () => back(),
'Theme:': {
value: (appSettings.theme === 'dark'),
format: v => v ? "Dark" : "Light",
onchange: v => {
switchTheme(v);
}
},
'Color:': {
value: teletextColors.indexOf(appSettings.color),
min: 0,
max: 7,
onchange: v => {
appSettings.color = teletextColors[v];
writeSettings();
},
format: v => teletextColorNames[v]
}
});
}
// Initially show the menu
showMenu();
});