mirror of https://github.com/espruino/BangleApps
Moved clock_info to a module
parent
e8599be168
commit
de40f314c7
|
@ -5,3 +5,4 @@
|
||||||
0.05: Support for clkinfo.
|
0.05: Support for clkinfo.
|
||||||
0.06: ClockInfo Fix: Use .get instead of .show as .show is not implemented for weather etc.
|
0.06: ClockInfo Fix: Use .get instead of .show as .show is not implemented for weather etc.
|
||||||
0.07: Use clock_info.addInteractive instead of a custom implementation
|
0.07: Use clock_info.addInteractive instead of a custom implementation
|
||||||
|
0.08: Use clock_info module as an app
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
"name": "AI Clock",
|
"name": "AI Clock",
|
||||||
"shortName":"AI Clock",
|
"shortName":"AI Clock",
|
||||||
"icon": "aiclock.png",
|
"icon": "aiclock.png",
|
||||||
"version":"0.07",
|
"version":"0.08",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"supports": ["BANGLEJS2"],
|
"supports": ["BANGLEJS2"],
|
||||||
|
"dependencies" : { "clock_info":"module" },
|
||||||
"description": "A watch face that was designed by an AI (stable diffusion) and implemented by a human.",
|
"description": "A watch face that was designed by an AI (stable diffusion) and implemented by a human.",
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
|
|
|
@ -29,4 +29,5 @@
|
||||||
clkinfo.addInteractive that would cause ReferenceError.
|
clkinfo.addInteractive that would cause ReferenceError.
|
||||||
0.28: Option to show (1) time only and (2) week of year.
|
0.28: Option to show (1) time only and (2) week of year.
|
||||||
0.29: use setItem of clockInfoMenu to change the active item
|
0.29: use setItem of clockInfoMenu to change the active item
|
||||||
0.30: Use widget_utils.
|
0.30: Use widget_utils
|
||||||
|
0.31: Use clock_info module as an app
|
||||||
|
|
|
@ -132,6 +132,7 @@ clockInfoItems[0].items.unshift({ name : "nop",
|
||||||
|
|
||||||
|
|
||||||
let clockInfoMenu = clock_info.addInteractive(clockInfoItems, {
|
let clockInfoMenu = clock_info.addInteractive(clockInfoItems, {
|
||||||
|
app: "bwclk",
|
||||||
x : 0,
|
x : 0,
|
||||||
y: 135,
|
y: 135,
|
||||||
w: W,
|
w: W,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"id": "bwclk",
|
"id": "bwclk",
|
||||||
"name": "BW Clock",
|
"name": "BW Clock",
|
||||||
"version": "0.30",
|
"version": "0.31",
|
||||||
"description": "A very minimalistic clock.",
|
"description": "A very minimalistic clock.",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
|
@ -9,6 +9,7 @@
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
"tags": "clock,clkinfo",
|
"tags": "clock,clkinfo",
|
||||||
"supports": ["BANGLEJS2"],
|
"supports": ["BANGLEJS2"],
|
||||||
|
"dependencies" : { "clock_info":"module" },
|
||||||
"allow_emulator": true,
|
"allow_emulator": true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"bwclk.app.js","url":"app.js"},
|
{"name":"bwclk.app.js","url":"app.js"},
|
||||||
|
|
|
@ -41,3 +41,4 @@
|
||||||
0.22: Fixed crash if item has no image and cutting long overflowing text
|
0.22: Fixed crash if item has no image and cutting long overflowing text
|
||||||
0.23: Setting circles colours per clkinfo and not position
|
0.23: Setting circles colours per clkinfo and not position
|
||||||
0.24: Using suggested color from clock_info if set as default and available
|
0.24: Using suggested color from clock_info if set as default and available
|
||||||
|
0.25: Use clock_info module as an app
|
||||||
|
|
|
@ -356,6 +356,7 @@ for(var i=0;i<circleCount; i++) {
|
||||||
let w = circlePosX[i];
|
let w = circlePosX[i];
|
||||||
let y = h3-radiusBorder;
|
let y = h3-radiusBorder;
|
||||||
clockInfoMenu[i] = require("clock_info").addInteractive(clockInfoItems, {
|
clockInfoMenu[i] = require("clock_info").addInteractive(clockInfoItems, {
|
||||||
|
app:"circlesclock",
|
||||||
x:w-radiusBorder, y:y, w:radiusBorder*2, h:g.getHeight()-(y+1),
|
x:w-radiusBorder, y:y, w:radiusBorder*2, h:g.getHeight()-(y+1),
|
||||||
draw : clockInfoDraw, circlePosition : i+1
|
draw : clockInfoDraw, circlePosition : i+1
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
{ "id": "circlesclock",
|
{ "id": "circlesclock",
|
||||||
"name": "Circles clock",
|
"name": "Circles clock",
|
||||||
"shortName":"Circles clock",
|
"shortName":"Circles clock",
|
||||||
"version":"0.24",
|
"version":"0.25",
|
||||||
"description": "A clock with three or four circles for different data at the bottom in a probably familiar style",
|
"description": "A clock with three or four circles for different data at the bottom in a probably familiar style",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"screenshots": [{"url":"screenshot-dark.png"}, {"url":"screenshot-light.png"}, {"url":"screenshot-dark-4.png"}, {"url":"screenshot-light-4.png"}],
|
"screenshots": [{"url":"screenshot-dark.png"}, {"url":"screenshot-light.png"}, {"url":"screenshot-dark-4.png"}, {"url":"screenshot-light-4.png"}],
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"supports" : ["BANGLEJS2"],
|
"supports" : ["BANGLEJS2"],
|
||||||
"allow_emulator":true,
|
"dependencies" : { "clock_info":"module" },
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"circlesclock.app.js","url":"app.js"},
|
{"name":"circlesclock.app.js","url":"app.js"},
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
0.01: Moved from modules/clock_info.js
|
|
@ -0,0 +1,99 @@
|
||||||
|
# Clock Info module
|
||||||
|
|
||||||
|
Module that allows for loading of clock 'info' displays
|
||||||
|
that can be scrolled through on the clock face.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
In most clocks that use Clock Info, you can interact with it the following way:
|
||||||
|
|
||||||
|
* Tap on an info menu to 'focus' it (this will highlight it in some way)
|
||||||
|
* Swipe up/down to change which info is displayed within the category
|
||||||
|
* Tap to activate (if supported), eg for a Stopwatch, Home Assistant, etc
|
||||||
|
* Swipe left/right to change between categories (Bangle.js/Agenda/etc)
|
||||||
|
* Tap outside the area of the Clock Info to 'defocus' it
|
||||||
|
|
||||||
|
## Extensions
|
||||||
|
|
||||||
|
By default Clock Info provides:
|
||||||
|
|
||||||
|
* Battery
|
||||||
|
* Steps
|
||||||
|
* Heart Rate (HRM)
|
||||||
|
* Altitude
|
||||||
|
|
||||||
|
But by installing other apps that are tagged with the type `clkinfo` you can
|
||||||
|
add extra features. For example [Sunrise Clockinfo](http://banglejs.com/apps/?id=clkinfosunrise)
|
||||||
|
|
||||||
|
A full list is available at https://banglejs.com/apps/?q=clkinfo
|
||||||
|
|
||||||
|
## Settings
|
||||||
|
|
||||||
|
Available from `Settings -> Apps -> Clock Info`
|
||||||
|
|
||||||
|
* `Defocus on Lock` - (default=on) when the watch screen auto-locks, defocus
|
||||||
|
and previously focussed Clock Infos
|
||||||
|
* `HRM` - (default=always) when does the HRM stay on?
|
||||||
|
* `Always` - When a HRM ClockInfo is shown, keep the HRM on
|
||||||
|
* `Tap` - When a HRM ClockInfo is shown, turn HRM on for 1 minute. Turn on again when tapped.
|
||||||
|
* `Max Altitude` - on clocks like [Circles Clock](https://banglejs.com/apps/?id=circlesclock) a
|
||||||
|
progress/percent indicator may be shown. The percentage for altitude will be how far towards
|
||||||
|
the Max Altitude you are. If you go higher than `Max Altitude` the correct altitude will still
|
||||||
|
be shown - the percent indicator will just read 100%
|
||||||
|
|
||||||
|
## API (Software development)
|
||||||
|
|
||||||
|
See http://www.espruino.com/Bangle.js+Clock+Info for details on using
|
||||||
|
this module inside your apps (or generating your own Clock Info
|
||||||
|
extensions).
|
||||||
|
|
||||||
|
`load()` returns an array of menu objects, where each object contains a list of menu items:
|
||||||
|
* `name` : text to display and identify menu object (e.g. weather)
|
||||||
|
* `img` : a 24x24px image
|
||||||
|
* `dynamic` : if `true`, items are not constant but are sorted (e.g. calendar events sorted by date)
|
||||||
|
* `items` : menu items such as temperature, humidity, wind etc.
|
||||||
|
|
||||||
|
Note that each item is an object with:
|
||||||
|
|
||||||
|
* `item.name` : friendly name to identify an item (e.g. temperature)
|
||||||
|
* `item.hasRange` : if `true`, `.get` returns `v/min/max` values (for progress bar/guage)
|
||||||
|
* `item.get` : function that returns an object:
|
||||||
|
|
||||||
|
```JS
|
||||||
|
{
|
||||||
|
'text' // the text to display for this item
|
||||||
|
'short' // optional: a shorter text to display for this item (at most 6 characters)
|
||||||
|
'img' // optional: a 24x24px image to display for this item
|
||||||
|
'color' // optional: a color string (like "#f00") to color the icon in compatible clocks
|
||||||
|
'v' // (if hasRange==true) a numerical value
|
||||||
|
'min','max' // (if hasRange==true) a minimum and maximum numerical value (if this were to be displayed as a guage)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* `item.show` : called when item should be shown. Enables updates. Call BEFORE 'get'
|
||||||
|
* `item.hide` : called when item should be hidden. Disables updates.
|
||||||
|
* `.on('redraw', ...)` : event that is called when 'get' should be called again (only after 'item.show')
|
||||||
|
* `item.run` : (optional) called if the info screen is tapped - can perform some action. Return true if the caller should feedback the user.
|
||||||
|
|
||||||
|
See the bottom of `lib.js` for example usage...
|
||||||
|
|
||||||
|
example.clkinfo.js :
|
||||||
|
|
||||||
|
```JS
|
||||||
|
(function() {
|
||||||
|
return {
|
||||||
|
name: "Bangle",
|
||||||
|
img: atob("GBiBAAD+AAH+AAH+AAH+AAH/AAOHAAYBgAwAwBgwYBgwYBgwIBAwOBAwOBgYIBgMYBgAYAwAwAYBgAOHAAH/AAH+AAH+AAH+AAD+AA==") }),
|
||||||
|
items: [
|
||||||
|
{ name : "Item1",
|
||||||
|
get : () => ({ text : "TextOfItem1", v : 10, min : 0, max : 100,
|
||||||
|
img : atob("GBiBAAD+AAH+AAH+AAH+AAH/AAOHAAYBgAwAwBgwYBgwYBgwIBAwOBAwOBgYIBgMYBgAYAwAwAYBgAOHAAH/AAH+AAH+AAH+AAD+AA==")
|
||||||
|
}),
|
||||||
|
show : () => {},
|
||||||
|
hide : () => {}
|
||||||
|
// run : () => {} optional (called when tapped)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}) // must not have a semi-colon!
|
||||||
|
```
|
|
@ -0,0 +1 @@
|
||||||
|
require("heatshrink").decompress(atob("mEwwJC/AH4A/AH4AgA=="))
|
Binary file not shown.
After Width: | Height: | Size: 390 B |
|
@ -1,54 +1,4 @@
|
||||||
/* Module that allows for loading of clock 'info' displays
|
/* See the README for more info... */
|
||||||
that can be scrolled through on the clock face.
|
|
||||||
|
|
||||||
`load()` returns an array of menu objects, where each object contains a list of menu items:
|
|
||||||
* `name` : text to display and identify menu object (e.g. weather)
|
|
||||||
* `img` : a 24x24px image
|
|
||||||
* `dynamic` : if `true`, items are not constant but are sorted (e.g. calendar events sorted by date)
|
|
||||||
* `items` : menu items such as temperature, humidity, wind etc.
|
|
||||||
|
|
||||||
Note that each item is an object with:
|
|
||||||
|
|
||||||
* `item.name` : friendly name to identify an item (e.g. temperature)
|
|
||||||
* `item.hasRange` : if `true`, `.get` returns `v/min/max` values (for progress bar/guage)
|
|
||||||
* `item.get` : function that returns an object:
|
|
||||||
|
|
||||||
{
|
|
||||||
'text' // the text to display for this item
|
|
||||||
'short' // optional: a shorter text to display for this item (at most 6 characters)
|
|
||||||
'img' // optional: a 24x24px image to display for this item
|
|
||||||
'color' // optional: a color string (like "#ffffff") to color the icon in compatible clocks
|
|
||||||
'v' // (if hasRange==true) a numerical value
|
|
||||||
'min','max' // (if hasRange==true) a minimum and maximum numerical value (if this were to be displayed as a guage)
|
|
||||||
}
|
|
||||||
|
|
||||||
* `item.show` : called when item should be shown. Enables updates. Call BEFORE 'get'
|
|
||||||
* `item.hide` : called when item should be hidden. Disables updates.
|
|
||||||
* `.on('redraw', ...)` : event that is called when 'get' should be called again (only after 'item.show')
|
|
||||||
* `item.run` : (optional) called if the info screen is tapped - can perform some action. Return true if the caller should feedback the user.
|
|
||||||
|
|
||||||
See the bottom of this file for example usage...
|
|
||||||
|
|
||||||
example.clkinfo.js :
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
return {
|
|
||||||
name: "Bangle",
|
|
||||||
img: atob("GBiBAAD+AAH+AAH+AAH+AAH/AAOHAAYBgAwAwBgwYBgwYBgwIBAwOBAwOBgYIBgMYBgAYAwAwAYBgAOHAAH/AAH+AAH+AAH+AAD+AA==") }),
|
|
||||||
items: [
|
|
||||||
{ name : "Item1",
|
|
||||||
get : () => ({ text : "TextOfItem1", v : 10, min : 0, max : 100,
|
|
||||||
img : atob("GBiBAAD+AAH+AAH+AAH+AAH/AAOHAAYBgAwAwBgwYBgwYBgwIBAwOBAwOBgYIBgMYBgAYAwAwAYBgAOHAAH/AAH+AAH+AAH+AAD+AA==")
|
|
||||||
}),
|
|
||||||
show : () => {},
|
|
||||||
hide : () => {}
|
|
||||||
// run : () => {} optional (called when tapped)
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
}) // must not have a semi-colon!
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
let storage = require("Storage");
|
let storage = require("Storage");
|
||||||
let stepGoal = undefined;
|
let stepGoal = undefined;
|
||||||
|
@ -60,7 +10,21 @@ if (stepGoal == undefined) {
|
||||||
stepGoal = d != undefined && d.settings != undefined ? d.settings.goal : 10000;
|
stepGoal = d != undefined && d.settings != undefined ? d.settings.goal : 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load the settings, with defaults
|
||||||
|
exports.loadSettings = function() {
|
||||||
|
return Object.assign({
|
||||||
|
hrmOn : 0, // 0(Always), 1(Tap)
|
||||||
|
defocusOnLock : true,
|
||||||
|
maxAltitude : 3000,
|
||||||
|
apps : {}
|
||||||
|
},
|
||||||
|
require("Storage").readJSON("clock_info.json",1)||{}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
exports.load = function() {
|
exports.load = function() {
|
||||||
|
var settings = exports.loadSettings();
|
||||||
|
delete settings.apps; // keep just the basic settings in memory
|
||||||
// info used for drawing...
|
// info used for drawing...
|
||||||
var hrm = 0;
|
var hrm = 0;
|
||||||
var alt = "--";
|
var alt = "--";
|
||||||
|
@ -111,8 +75,31 @@ exports.load = function() {
|
||||||
text : (hrm||"--") + " bpm", v : hrm, min : 40, max : 200,
|
text : (hrm||"--") + " bpm", v : hrm, min : 40, max : 200,
|
||||||
img : atob("GBiBAAAAAAAAAAAAAAAAAAAAAADAAADAAAHAAAHjAAHjgAPngH9n/n82/gA+AAA8AAA8AAAcAAAYAAAYAAAAAAAAAAAAAAAAAAAAAA==")
|
img : atob("GBiBAAAAAAAAAAAAAAAAAAAAAADAAADAAAHAAAHjAAHjgAPngH9n/n82/gA+AAA8AAA8AAAcAAAYAAAYAAAAAAAAAAAAAAAAAAAAAA==")
|
||||||
}},
|
}},
|
||||||
show : function() { Bangle.setHRMPower(1,"clkinfo"); Bangle.on("HRM", hrmUpdateHandler); hrm = Math.round(Bangle.getHealthStatus().bpm||Bangle.getHealthStatus("last").bpm); hrmUpdateHandler(); },
|
run : function() {
|
||||||
hide : function() { Bangle.setHRMPower(0,"clkinfo"); Bangle.removeListener("HRM", hrmUpdateHandler); hrm = 0; },
|
Bangle.setHRMPower(1,"clkinfo");
|
||||||
|
if (settings.hrmOn==1/*Tap*/) {
|
||||||
|
/* turn off after 1 minute. If Health HRM monitoring is
|
||||||
|
enabled we will still get HRM events every so often */
|
||||||
|
this.timeout = setTimeout(function() {
|
||||||
|
this.timeout = undefined;
|
||||||
|
Bangle.setHRMPower(0,"clkinfo");
|
||||||
|
}, 60000);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
show : function() {
|
||||||
|
Bangle.on("HRM", hrmUpdateHandler);
|
||||||
|
hrm = Math.round(Bangle.getHealthStatus().bpm||Bangle.getHealthStatus("last").bpm); hrmUpdateHandler();
|
||||||
|
this.run(); // start HRM
|
||||||
|
},
|
||||||
|
hide : function() {
|
||||||
|
Bangle.setHRMPower(0,"clkinfo");
|
||||||
|
Bangle.removeListener("HRM", hrmUpdateHandler);
|
||||||
|
if (this.timeout) {
|
||||||
|
clearTimeout(this.timeout);
|
||||||
|
this.timeout = undefined;
|
||||||
|
}
|
||||||
|
hrm = 0;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
}];
|
}];
|
||||||
|
@ -123,7 +110,7 @@ exports.load = function() {
|
||||||
hasRange : true,
|
hasRange : true,
|
||||||
get : () => ({
|
get : () => ({
|
||||||
text : alt, v : parseInt(alt),
|
text : alt, v : parseInt(alt),
|
||||||
min : 0, max : 3000,
|
min : 0, max : settings.maxAltitude,
|
||||||
img : atob("GBiBAAAAAAAAAAAAAAAAAAAAAAACAAAGAAAPAAEZgAOwwAPwQAZgYAwAMBgAGBAACDAADGAABv///////wAAAAAAAAAAAAAAAAAAAA==")
|
img : atob("GBiBAAAAAAAAAAAAAAAAAAAAAAACAAAGAAAPAAEZgAOwwAPwQAZgYAwAMBgAGBAACDAADGAABv///////wAAAAAAAAAAAAAAAAAAAA==")
|
||||||
}),
|
}),
|
||||||
show : function() { this.interval = setInterval(altUpdateHandler, 60000); alt = "--"; altUpdateHandler(); },
|
show : function() { this.interval = setInterval(altUpdateHandler, 60000); alt = "--"; altUpdateHandler(); },
|
||||||
|
@ -148,9 +135,18 @@ exports.load = function() {
|
||||||
return menu;
|
return menu;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** Adds an interactive menu that could be used on a clock face by swiping.
|
/** Adds an interactive menu that could be used on a clock face by swiping.
|
||||||
Simply supply the menu data (from .load) and a function to draw the clock info.
|
Simply supply the menu data (from .load) and a function to draw the clock info.
|
||||||
|
|
||||||
|
options = {
|
||||||
|
app : "str", // optional: app ID used when saving clock_info positions
|
||||||
|
// if defined, your app will remember its own positions,
|
||||||
|
// otherwise all apps share the same ones
|
||||||
|
x : 20, y: 20, w: 80, h:80, // dimensions of area used for clock_info
|
||||||
|
draw : (itm, info, options) // draw function
|
||||||
|
}
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
let clockInfoItems = require("clock_info").load();
|
let clockInfoItems = require("clock_info").load();
|
||||||
|
@ -181,7 +177,7 @@ clockInfoMenu is the 'options' parameter, with the following added:
|
||||||
* `redraw` : function - force a redraw
|
* `redraw` : function - force a redraw
|
||||||
* `focus` : function - bool to show if menu is focused or not
|
* `focus` : function - bool to show if menu is focused or not
|
||||||
|
|
||||||
You can have more than one clock_info at once as well, sfor instance:
|
You can have more than one clock_info at once as well, for instance:
|
||||||
|
|
||||||
let clockInfoDraw = (itm, info, options) => {
|
let clockInfoDraw = (itm, info, options) => {
|
||||||
g.reset().setBgColor(options.bg).setColor(options.fg).clearRect(options.x, options.y, options.x+options.w-2, options.y+options.h-1);
|
g.reset().setBgColor(options.bg).setColor(options.fg).clearRect(options.x, options.y, options.x+options.w-2, options.y+options.h-1);
|
||||||
|
@ -201,19 +197,19 @@ exports.addInteractive = function(menu, options) {
|
||||||
options.index = 0|exports.loadCount;
|
options.index = 0|exports.loadCount;
|
||||||
exports.loadCount = options.index+1;
|
exports.loadCount = options.index+1;
|
||||||
options.focus = options.index==0 && options.x===undefined; // focus if we're the first one loaded and no position has been defined
|
options.focus = options.index==0 && options.x===undefined; // focus if we're the first one loaded and no position has been defined
|
||||||
const appName = "default:"+options.index;
|
const appName = (options.app||"default")+":"+options.index;
|
||||||
|
|
||||||
{ // load the currently showing clock_infos
|
// load the currently showing clock_infos
|
||||||
let settings = require("Storage").readJSON("clock_info.json",1)||{};
|
let settings = exports.loadSettings()
|
||||||
if (settings[appName]) {
|
if (settings.apps[appName]) {
|
||||||
let a = settings[appName].a|0;
|
let a = settings.apps[appName].a|0;
|
||||||
let b = settings[appName].b|0;
|
let b = settings.apps[appName].b|0;
|
||||||
if (menu[a] && menu[a].items[b]) { // all ok
|
if (menu[a] && menu[a].items[b]) { // all ok
|
||||||
options.menuA = a;
|
options.menuA = a;
|
||||||
options.menuB = b;
|
options.menuB = b;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.menuA===undefined) options.menuA = 0;
|
if (options.menuA===undefined) options.menuA = 0;
|
||||||
if (options.menuB===undefined) options.menuB = Math.min(exports.loadCount, menu[options.menuA].items.length)-1;
|
if (options.menuB===undefined) options.menuB = Math.min(exports.loadCount, menu[options.menuA].items.length)-1;
|
||||||
function drawItem(itm) {
|
function drawItem(itm) {
|
||||||
|
@ -262,21 +258,13 @@ exports.addInteractive = function(menu, options) {
|
||||||
menuShowItem(menu[options.menuA].items[options.menuB]);
|
menuShowItem(menu[options.menuA].items[options.menuB]);
|
||||||
}
|
}
|
||||||
// save the currently showing clock_info
|
// save the currently showing clock_info
|
||||||
let settings = require("Storage").readJSON("clock_info.json",1)||{};
|
let settings = exports.loadSettings();
|
||||||
settings[appName] = {a:options.menuA,b:options.menuB};
|
settings.apps[appName] = {a:options.menuA,b:options.menuB};
|
||||||
require("Storage").writeJSON("clock_info.json",settings);
|
require("Storage").writeJSON("clock_info.json",settings);
|
||||||
}
|
}
|
||||||
Bangle.on("swipe",swipeHandler);
|
Bangle.on("swipe",swipeHandler);
|
||||||
var touchHandler;
|
let touchHandler, lockHandler;
|
||||||
var lockHandler;
|
|
||||||
if (options.x!==undefined && options.y!==undefined && options.w && options.h) {
|
if (options.x!==undefined && options.y!==undefined && options.w && options.h) {
|
||||||
lockHandler = function() {
|
|
||||||
if(options.focus) {
|
|
||||||
options.focus=false;
|
|
||||||
delete Bangle.CLKINFO_FOCUS;
|
|
||||||
options.redraw();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
touchHandler = function(_,e) {
|
touchHandler = function(_,e) {
|
||||||
if (e.x<options.x || e.y<options.y ||
|
if (e.x<options.x || e.y<options.y ||
|
||||||
e.x>(options.x+options.w) || e.y>(options.y+options.h)) {
|
e.x>(options.x+options.w) || e.y>(options.y+options.h)) {
|
||||||
|
@ -300,7 +288,16 @@ exports.addInteractive = function(menu, options) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Bangle.on("touch",touchHandler);
|
Bangle.on("touch",touchHandler);
|
||||||
Bangle.on("lock", lockHandler);
|
if (settings.defocusOnLock) {
|
||||||
|
lockHandler = function() {
|
||||||
|
if(options.focus) {
|
||||||
|
options.focus=false;
|
||||||
|
delete Bangle.CLKINFO_FOCUS;
|
||||||
|
options.redraw();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Bangle.on("lock", lockHandler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// draw the first item
|
// draw the first item
|
||||||
menuShowItem(menu[options.menuA].items[options.menuB]);
|
menuShowItem(menu[options.menuA].items[options.menuB]);
|
||||||
|
@ -333,6 +330,8 @@ exports.addInteractive = function(menu, options) {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete settings; // don't keep settings in RAM - save space
|
||||||
return options;
|
return options;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
{ "id": "clock_info",
|
||||||
|
"name": "Clock Info Module",
|
||||||
|
"shortName": "Clock Info",
|
||||||
|
"version":"0.01",
|
||||||
|
"description": "A library used by clocks to provide extra information on the clock face (Altitude, BPM, etc)",
|
||||||
|
"icon": "app.png",
|
||||||
|
"type": "module",
|
||||||
|
"tags": "clkinfo",
|
||||||
|
"supports" : ["BANGLEJS2"],
|
||||||
|
"provides_modules" : ["clock_info"],
|
||||||
|
"readme": "README.md",
|
||||||
|
"storage": [
|
||||||
|
{"name":"clock_info","url":"lib.js"},
|
||||||
|
{"name":"clock_info.settings.js","url":"settings.js"}
|
||||||
|
], "data": [
|
||||||
|
{"name":"clock_info.json","url":"lib.js"}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
(function(back) {
|
||||||
|
let settings = require("clock_info").loadSettings();
|
||||||
|
|
||||||
|
function save(key, value) {
|
||||||
|
settings[key] = value;
|
||||||
|
require('Storage').write("clock_info.json", settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
let menu ={
|
||||||
|
'': { 'title': 'Clock Info' },
|
||||||
|
/*LANG*/'< Back': back,
|
||||||
|
/*LANG*/'Defocus on Lock': {
|
||||||
|
value: !!settings.defocusOnLock,
|
||||||
|
onchange: x => save('defocusOnLock', x),
|
||||||
|
},
|
||||||
|
/*LANG*/'HRM': {
|
||||||
|
value: settings.hrmOn,
|
||||||
|
min: 0, max: 1, step: 1,
|
||||||
|
format: v => ["Always","Tap"][v],
|
||||||
|
onchange: x => save('hrmOn', x),
|
||||||
|
},
|
||||||
|
/*LANG*/'Max Altitude': {
|
||||||
|
value: settings.maxAltitude,
|
||||||
|
min: 500, max: 10000, step: 500,
|
||||||
|
format: v => v+"m",
|
||||||
|
onchange: x => save('maxAltitude', x),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
E.showMenu(menu);
|
||||||
|
})()
|
|
@ -0,0 +1,2 @@
|
||||||
|
0.01: first release
|
||||||
|
0.02: Use clock_info module as an app
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"id": "lato",
|
"id": "lato",
|
||||||
"name": "Lato",
|
"name": "Lato",
|
||||||
"version": "0.01",
|
"version": "0.02",
|
||||||
"description": "A Lato Font clock with fast load and clock_info",
|
"description": "A Lato Font clock with fast load and clock_info",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
|
@ -9,6 +9,7 @@
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"supports": ["BANGLEJS2"],
|
"supports": ["BANGLEJS2"],
|
||||||
|
"dependencies" : { "clock_info":"module" },
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"lato.app.js","url":"app.js"},
|
{"name":"lato.app.js","url":"app.js"},
|
||||||
{"name":"lato.img","url":"icon.js","evaluate":true}
|
{"name":"lato.img","url":"icon.js","evaluate":true}
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
0.01: New App!
|
0.01: New App!
|
||||||
|
0.02: Use clock_info module as an app
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
{ "id": "lcdclock",
|
{ "id": "lcdclock",
|
||||||
"name": "LCD Clock",
|
"name": "LCD Clock",
|
||||||
"version":"0.01",
|
"version":"0.02",
|
||||||
"description": "A Casio-style clock, with ClockInfo areas at the top and bottom. Tap them and swipe up/down to toggle between different information",
|
"description": "A Casio-style clock, with ClockInfo areas at the top and bottom. Tap them and swipe up/down to toggle between different information",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"screenshots": [{"url":"screenshot.png"}],
|
"screenshots": [{"url":"screenshot.png"}],
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
"tags": "clock,clkinfo",
|
"tags": "clock,clkinfo",
|
||||||
"supports" : ["BANGLEJS2"],
|
"supports" : ["BANGLEJS2"],
|
||||||
|
"dependencies" : { "clock_info":"module" },
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"lcdclock.app.js","url":"app.js"},
|
{"name":"lcdclock.app.js","url":"app.js"},
|
||||||
{"name":"lcdclock.img","url":"app-icon.js","evaluate":true}
|
{"name":"lcdclock.img","url":"app-icon.js","evaluate":true}
|
||||||
|
|
|
@ -2,3 +2,4 @@
|
||||||
0.02: Performance improvements.
|
0.02: Performance improvements.
|
||||||
0.03: Update clock_info to avoid a redraw
|
0.03: Update clock_info to avoid a redraw
|
||||||
0.04: Fix clkinfo -- use .get instead of .show
|
0.04: Fix clkinfo -- use .get instead of .show
|
||||||
|
0.05: Use clock_info module as an app
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"id": "linuxclock",
|
"id": "linuxclock",
|
||||||
"name": "Linux Clock",
|
"name": "Linux Clock",
|
||||||
"version": "0.04",
|
"version": "0.05",
|
||||||
"description": "A Linux inspired clock.",
|
"description": "A Linux inspired clock.",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"supports": ["BANGLEJS2"],
|
"supports": ["BANGLEJS2"],
|
||||||
"allow_emulator": true,
|
"dependencies" : { "clock_info":"module" },
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"linuxclock.app.js","url":"app.js"},
|
{"name":"linuxclock.app.js","url":"app.js"},
|
||||||
{"name":"linuxclock.img","url":"app-icon.js","evaluate":true},
|
{"name":"linuxclock.img","url":"app-icon.js","evaluate":true},
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
0.01: first release
|
0.01: first release
|
||||||
0.02: removed fast load, minimalism is useful for narrowing down on issues
|
0.02: removed fast load, minimalism is useful for narrowing down on issues
|
||||||
|
0.03: Use clock_info module as an app
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"id": "simplestpp",
|
"id": "simplestpp",
|
||||||
"name": "Simplest++ Clock",
|
"name": "Simplest++ Clock",
|
||||||
"shortName": "Simplest++",
|
"shortName": "Simplest++",
|
||||||
"version": "0.02",
|
"version": "0.03",
|
||||||
"description": "The simplest working clock, with clock_info, acts as a tutorial piece",
|
"description": "The simplest working clock, with clock_info, acts as a tutorial piece",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
|
@ -10,6 +10,7 @@
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"supports": ["BANGLEJS2"],
|
"supports": ["BANGLEJS2"],
|
||||||
|
"dependencies" : { "clock_info":"module" },
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"simplestpp.app.js","url":"app.js"},
|
{"name":"simplestpp.app.js","url":"app.js"},
|
||||||
{"name":"simplestpp.img","url":"icon.js","evaluate":true}
|
{"name":"simplestpp.img","url":"icon.js","evaluate":true}
|
||||||
|
|
|
@ -9,3 +9,4 @@
|
||||||
0.07: README file update as UI interaction was not easy to understand
|
0.07: README file update as UI interaction was not easy to understand
|
||||||
0.08: Stability improvements - ensure we continue even if a flat string can't be allocated
|
0.08: Stability improvements - ensure we continue even if a flat string can't be allocated
|
||||||
Stop ClockInfo text drawing outside the allocated area
|
Stop ClockInfo text drawing outside the allocated area
|
||||||
|
0.09: Use clock_info module as an app
|
||||||
|
|
|
@ -141,8 +141,8 @@ let clockInfoDraw = (itm, info, options) => {
|
||||||
g.setClipRect(0,0,g.getWidth()-1, g.getHeight()-1);
|
g.setClipRect(0,0,g.getWidth()-1, g.getHeight()-1);
|
||||||
};
|
};
|
||||||
let clockInfoItems = require("clock_info").load();
|
let clockInfoItems = require("clock_info").load();
|
||||||
let clockInfoMenu = require("clock_info").addInteractive(clockInfoItems, { x:126, y:24, w:50, h:40, draw : clockInfoDraw, bg : g.theme.bg, fg : g.theme.fg, hl : "#f00"/*red*/ });
|
let clockInfoMenu = require("clock_info").addInteractive(clockInfoItems, { app:"slopeclockpp",x:126, y:24, w:50, h:40, draw : clockInfoDraw, bg : g.theme.bg, fg : g.theme.fg, hl : "#f00"/*red*/ });
|
||||||
let clockInfoMenu2 = require("clock_info").addInteractive(clockInfoItems, { x:0, y:115, w:50, h:40, draw : clockInfoDraw, bg : bgColor, fg : g.theme.bg, hl : (bgColor=="#000")?"#f00"/*red*/:g.theme.fg });
|
let clockInfoMenu2 = require("clock_info").addInteractive(clockInfoItems, { app:"slopeclockpp",x:0, y:115, w:50, h:40, draw : clockInfoDraw, bg : bgColor, fg : g.theme.bg, hl : (bgColor=="#000")?"#f00"/*red*/:g.theme.fg });
|
||||||
|
|
||||||
// Show launcher when middle button pressed
|
// Show launcher when middle button pressed
|
||||||
Bangle.setUI({
|
Bangle.setUI({
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
{ "id": "slopeclockpp",
|
{ "id": "slopeclockpp",
|
||||||
"name": "Slope Clock ++",
|
"name": "Slope Clock ++",
|
||||||
"version":"0.08",
|
"version":"0.09",
|
||||||
"description": "A clock where hours and minutes are divided by a sloping line. When the minute changes, the numbers slide off the screen. This is a clone of the original Slope Clock which shows extra information and allows the colors to be selected.",
|
"description": "A clock where hours and minutes are divided by a sloping line. When the minute changes, the numbers slide off the screen. This is a clone of the original Slope Clock which shows extra information and allows the colors to be selected.",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"screenshots": [{"url":"screenshot.png"}],
|
"screenshots": [{"url":"screenshot.png"}],
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"supports" : ["BANGLEJS2"],
|
"supports" : ["BANGLEJS2"],
|
||||||
|
"dependencies" : { "clock_info":"module" },
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"slopeclockpp.app.js","url":"app.js"},
|
{"name":"slopeclockpp.app.js","url":"app.js"},
|
||||||
|
|
Loading…
Reference in New Issue