Merge pull request #2830 from stweedo/master

[boxclk] - v0.02 update
master
Gordon Williams 2023-06-20 09:15:45 +01:00 committed by GitHub
commit e52e89f204
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 108 additions and 54 deletions

View File

@ -1 +1,2 @@
0.01: New App! 0.01: New App!
0.02: New config options such as step, meridian, short/long formats, custom prefix/suffix

View File

@ -22,7 +22,7 @@ Here's what an example configuration might look like:
``` ```
{ {
"customBox": { // "customBox": {
"string": "Your text here", "string": "Your text here",
"font": "CustomFont", // Custom fonts must be removed in setUI "font": "CustomFont", // Custom fonts must be removed in setUI
"fontSize": 1, "fontSize": 1,
@ -34,15 +34,23 @@ Here's what an example configuration might look like:
"yPadding": -4, "yPadding": -4,
"xOffset": 0, "xOffset": 0,
"yOffset": 3, "yOffset": 3,
"boxPos": { "x": 0.5, "y": 0.5 } "boxPos": { "x": 0.5, "y": 0.5 },
"prefix": "", // Adds a string to the beginning of the main string
"suffix": "", // Adds a string to the end of the main string
"disableSuffix": true, // Only used to remove the DayOfMonth suffix
"short": false // Gets long format value of time, meridian, date, or DoW
}, },
"bg": { // Can also be removed for no background "bg": { // Can also be removed for no background
"img": "YourImageName.img" "img": "YourImageName.img"
} }
} }
``` ```
__Breakdown of Parameters:__ __Breakdown of Parameters:__
* **Box Name:** The name of your text box. Box Clock includes functional support for "time", "date", "meridian" (AM/PM), "dow" (Day of Week), "batt" (Battery), and "step" (Step count). You can add additional custom boxes with unique titles.
* **string:** The text string to be displayed inside the box. * **string:** The text string to be displayed inside the box.
* **font:** The font name given to g.setFont() * **font:** The font name given to g.setFont()
@ -63,6 +71,14 @@ __Breakdown of Parameters:__
* **boxPos:** Initial position of the box on the screen. Values are fractions of the screen width (x) and height (y), so { "x": 0.5, "y": 0.5 } would be in the middle of the screen. * **boxPos:** Initial position of the box on the screen. Values are fractions of the screen width (x) and height (y), so { "x": 0.5, "y": 0.5 } would be in the middle of the screen.
* **prefix:** Adds a string to the beginning of the main string. For example, you can set "prefix": "Steps: " to display "Steps: 100" for the step count.
* **suffix:** Adds a string to the end of the main string. For example, you can set "suffix": "%" to display "80%" for the battery percentage.
* **disableSuffix:** Applies only to the "date" box. Set to true to disable the DayOfMonth suffix. This is used to remove the "st","nd","rd", or "th" from the DayOfMonth number
* **short:** Set to false to get the long format value of time, meridian, date, or DayOfWeek. Short formats are used by default,
* **bg:** This specifies a custom background image, with the img property defining the name of the image file on the Bangle.js storage. * **bg:** This specifies a custom background image, with the img property defining the name of the image file on the Bangle.js storage.
## Multiple Configurations ## Multiple Configurations

View File

@ -33,7 +33,6 @@
let w = g.getWidth(); let w = g.getWidth();
let h = g.getHeight(); let h = g.getHeight();
let totalWidth, totalHeight; let totalWidth, totalHeight;
let enableSuffix = true;
let drawTimeout; let drawTimeout;
/** /**
@ -165,13 +164,17 @@
/** /**
* --------------------------------------------------------------- * ---------------------------------------------------------------
* 7. Date and time related functions * 7. String forming helper functions
* --------------------------------------------------------------- * ---------------------------------------------------------------
*/ */
let getDate = function() { let isBool = function(val, defaultVal) {
return typeof val !== 'undefined' ? Boolean(val) : defaultVal;
};
let getDate = function(short, disableSuffix) {
const date = new Date(); const date = new Date();
const dayOfMonth = date.getDate(); const dayOfMonth = date.getDate();
const month = locale.month(date, 1); const month = short ? locale.month(date, 0) : locale.month(date, 1);
const year = date.getFullYear(); const year = date.getFullYear();
let suffix; let suffix;
if ([1, 21, 31].includes(dayOfMonth)) { if ([1, 21, 31].includes(dayOfMonth)) {
@ -183,12 +186,24 @@
} else { } else {
suffix = "th"; suffix = "th";
} }
let dayOfMonthStr = enableSuffix ? dayOfMonth + suffix : dayOfMonth; let dayOfMonthStr = disableSuffix ? dayOfMonth : dayOfMonth + suffix;
return month + " " + dayOfMonthStr + ", " + year; return month + " " + dayOfMonthStr + (short ? '' : (", " + year)); // not including year for short version
}; };
let getDayOfWeek = function(date) { let getDayOfWeek = function(date, short) {
return locale.dow(date, 0); return locale.dow(date, short ? 1 : 0);
};
locale.meridian = function(date, short) {
let hours = date.getHours();
let meridian = hours >= 12 ? 'PM' : 'AM';
return short ? meridian[0] : meridian;
};
let modString = function(boxItem, data) {
let prefix = boxItem.prefix || '';
let suffix = boxItem.suffix || '';
return prefix + data + suffix;
}; };
/** /**
@ -196,44 +211,56 @@
* 8. Main draw function * 8. Main draw function
* --------------------------------------------------------------- * ---------------------------------------------------------------
*/ */
let draw = function(boxes) { let draw = (function() {
date = new Date(); let updatePerMinute = true; // variable to track the state of time display
g.clear();
if (bgImage) { return function(boxes) {
g.drawImage(bgImage, 0, 0); date = new Date();
} g.clear();
if (boxes.time) { if (bgImage) {
boxes.time.string = locale.time(date, 1); g.drawImage(bgImage, 0, 0);
}
if (boxes.date) {
boxes.date.string = getDate();
}
if (boxes.dow) {
boxes.dow.string = getDayOfWeek(date);
}
if (boxes.batt) {
boxes.batt.string = E.getBattery() + "%";
}
boxKeys.forEach((boxKey) => {
let boxItem = boxes[boxKey];
calcBoxSize(boxItem);
const pos = calcBoxPos(boxKey);
if (isDragging[boxKey]) {
g.setColor(boxItem.border);
g.drawRect(pos.x1, pos.y1, pos.x2, pos.y2);
} }
g.drawString( if (boxes.time) {
boxItem, boxes.time.string = modString(boxes.time, locale.time(date, isBool(boxes.time.short, true) ? 1 : 0));
boxItem.string, updatePerMinute = isBool(boxes.time.short, true);
boxPos[boxKey].x + boxItem.xOffset, }
boxPos[boxKey].y + boxItem.yOffset if (boxes.meridian) {
); boxes.meridian.string = modString(boxes.meridian, locale.meridian(date, isBool(boxes.meridian.short, true)));
}); }
if (!Object.values(isDragging).some(Boolean)) { if (boxes.date) {
if (drawTimeout) clearTimeout(drawTimeout); boxes.date.string = modString(boxes.date, getDate(isBool(boxes.date.short, true), isBool(boxes.date.disableSuffix, false)));
drawTimeout = setTimeout(() => draw(boxes), 60000 - (Date.now() % 60000)); }
} if (boxes.dow) {
}; boxes.dow.string = modString(boxes.dow, getDayOfWeek(date, isBool(boxes.dow.short, true)));
}
if (boxes.batt) {
boxes.batt.string = modString(boxes.batt, E.getBattery());
}
if (boxes.step) {
boxes.step.string = modString(boxes.step, Bangle.getStepCount());
}
boxKeys.forEach((boxKey) => {
let boxItem = boxes[boxKey];
calcBoxSize(boxItem);
const pos = calcBoxPos(boxKey);
if (isDragging[boxKey]) {
g.setColor(boxItem.border);
g.drawRect(pos.x1, pos.y1, pos.x2, pos.y2);
}
g.drawString(
boxItem,
boxItem.string,
boxPos[boxKey].x + boxItem.xOffset,
boxPos[boxKey].y + boxItem.yOffset
);
});
if (!Object.values(isDragging).some(Boolean)) {
if (drawTimeout) clearTimeout(drawTimeout);
let interval = updatePerMinute ? 60000 - (Date.now() % 60000) : 1000;
drawTimeout = setTimeout(() => draw(boxes), interval);
}
};
})();
/** /**
* --------------------------------------------------------------- * ---------------------------------------------------------------

View File

@ -23,7 +23,8 @@
"yPadding": 0.5, "yPadding": 0.5,
"xOffset": 1, "xOffset": 1,
"yOffset": 1, "yOffset": 1,
"boxPos": { "x": 0.633, "y": 0.3 } "boxPos": { "x": 0.633, "y": 0.3 },
"short": false
}, },
"date": { "date": {
"font": "6x8", "font": "6x8",
@ -36,7 +37,8 @@
"yPadding": 0.5, "yPadding": 0.5,
"xOffset": 1, "xOffset": 1,
"yOffset": 1, "yOffset": 1,
"boxPos": { "x": 0.633, "y": 0.39 } "boxPos": { "x": 0.633, "y": 0.39 },
"short": false
}, },
"batt": { "batt": {
"font": "4x6", "font": "4x6",
@ -47,9 +49,10 @@
"border": "#fff", "border": "#fff",
"xPadding": -0.5, "xPadding": -0.5,
"yPadding": -0.5, "yPadding": -0.5,
"xOffset": 2, "xOffset": 1,
"yOffset": 1, "yOffset": 1,
"boxPos": { "x": 0.92, "y": 0.95 } "boxPos": { "x": 0.9, "y": 0.95 },
"suffix": "%"
}, },
"bg": { "bg": {
"img": "boxclk.beachhouse.img" "img": "boxclk.beachhouse.img"

View File

@ -1,7 +1,7 @@
{ {
"id": "boxclk", "id": "boxclk",
"name": "Box Clock", "name": "Box Clock",
"version": "0.01", "version": "0.02",
"description": "A customizable clock with configurable text boxes that can be positioned to show your favorite background", "description": "A customizable clock with configurable text boxes that can be positioned to show your favorite background",
"icon": "app.png", "icon": "app.png",
"screenshots": [ "screenshots": [

View File

@ -32,11 +32,11 @@
}; };
} }
let configFiles = [];
storage.list().forEach(file => { storage.list().forEach(file => {
let match = file.match(fileRegex); let match = file.match(fileRegex);
if (match) { if (match) {
let configNumber = match[1]; configFiles.push({ file: file, number: parseInt(match[1]) });
configs[configNumber] = handleSelection(configNumber);
} else if (file === "boxclk.json") { } else if (file === "boxclk.json") {
hasDefaultConfig = true; hasDefaultConfig = true;
let defaultConfig = storage.readJSON(file, 1); let defaultConfig = storage.readJSON(file, 1);
@ -56,6 +56,13 @@
} }
}); });
// Sort the config files by number
configFiles.sort((a, b) => a.number - b.number);
configFiles.forEach(configFile => {
configs[configFile.number] = handleSelection(configFile.number);
});
if (!selectedConfig) { if (!selectedConfig) {
if (hasDefaultConfig) { if (hasDefaultConfig) {
selectedConfig = "Default"; selectedConfig = "Default";