Merge branch 'master' into master
370
apps.json
|
|
@ -1,10 +1,10 @@
|
||||||
[
|
[
|
||||||
{ "id": "boot",
|
{ "id": "boot",
|
||||||
"name": "Bootloader",
|
"name": "Bootloader",
|
||||||
"tags": "tool,system",
|
"tags": "tool,system,b2",
|
||||||
"type":"bootloader",
|
"type":"bootloader",
|
||||||
"icon": "bootloader.png",
|
"icon": "bootloader.png",
|
||||||
"version":"0.25",
|
"version":"0.28",
|
||||||
"description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings",
|
"description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":".boot0","url":"boot0.js"},
|
{"name":".boot0","url":"boot0.js"},
|
||||||
|
|
@ -44,19 +44,32 @@
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.06",
|
"version":"0.06",
|
||||||
"description": "This is needed by Bangle.js to display a menu allowing you to choose your own applications. You can replace this with a customised launcher.",
|
"description": "This is needed by Bangle.js to display a menu allowing you to choose your own applications. You can replace this with a customised launcher.",
|
||||||
"tags": "tool,system,launcher",
|
"tags": "tool,system,launcher,b2",
|
||||||
"type":"launch",
|
"type":"launch",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"launch.app.js","url":"app.js"}
|
{"name":"launch.app.js","url":"app.js"}
|
||||||
],
|
],
|
||||||
"sortorder" : -10
|
"sortorder" : -10
|
||||||
},
|
},
|
||||||
|
{ "id": "launchb2",
|
||||||
|
"name": "Launcher (Bangle.js 2)",
|
||||||
|
"shortName":"Launcher",
|
||||||
|
"icon": "app.png",
|
||||||
|
"version":"0.01",
|
||||||
|
"description": "This is needed by Bangle.js 2.0 to display a menu allowing you to choose your own applications. It will not work on Bangle.js 1.0.",
|
||||||
|
"tags": "tool,system,launcher,b2,bno1",
|
||||||
|
"type":"launch",
|
||||||
|
"storage": [
|
||||||
|
{"name":"launchb2.app.js","url":"app.js"}
|
||||||
|
],
|
||||||
|
"sortorder" : -10
|
||||||
|
},
|
||||||
{ "id": "about",
|
{ "id": "about",
|
||||||
"name": "About",
|
"name": "About",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.08",
|
"version":"0.08",
|
||||||
"description": "Bangle.js About page - showing software version, stats, and a collaborative mural from the Bangle.js KickStarter backers",
|
"description": "Bangle.js About page - showing software version, stats, and a collaborative mural from the Bangle.js KickStarter backers",
|
||||||
"tags": "tool,system",
|
"tags": "tool,system,b2",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"about.app.js","url":"app.js"},
|
{"name":"about.app.js","url":"app.js"},
|
||||||
|
|
@ -68,7 +81,7 @@
|
||||||
"icon": "locale.png",
|
"icon": "locale.png",
|
||||||
"version":"0.09",
|
"version":"0.09",
|
||||||
"description": "Translations for different countries",
|
"description": "Translations for different countries",
|
||||||
"tags": "tool,system,locale,translate",
|
"tags": "tool,system,locale,translate,b2",
|
||||||
"type": "locale",
|
"type": "locale",
|
||||||
"custom":"locale.html",
|
"custom":"locale.html",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
|
|
@ -81,7 +94,7 @@
|
||||||
"name": "Notifications (default)",
|
"name": "Notifications (default)",
|
||||||
"shortName":"Notifications",
|
"shortName":"Notifications",
|
||||||
"icon": "notify.png",
|
"icon": "notify.png",
|
||||||
"version":"0.08",
|
"version":"0.09",
|
||||||
"description": "A handler for displaying notifications that displays them in a bar at the top of the screen",
|
"description": "A handler for displaying notifications that displays them in a bar at the top of the screen",
|
||||||
"tags": "widget",
|
"tags": "widget",
|
||||||
"type": "notify",
|
"type": "notify",
|
||||||
|
|
@ -94,7 +107,7 @@
|
||||||
"name": "Fullscreen Notifications",
|
"name": "Fullscreen Notifications",
|
||||||
"shortName":"Notifications",
|
"shortName":"Notifications",
|
||||||
"icon": "notify.png",
|
"icon": "notify.png",
|
||||||
"version":"0.08",
|
"version":"0.09",
|
||||||
"description": "A handler for displaying notifications that displays them fullscreen. This may not fully restore the screen after on some apps. See `Notifications (default)` for more information about the notifications library.",
|
"description": "A handler for displaying notifications that displays them fullscreen. This may not fully restore the screen after on some apps. See `Notifications (default)` for more information about the notifications library.",
|
||||||
"tags": "widget",
|
"tags": "widget",
|
||||||
"type": "notify",
|
"type": "notify",
|
||||||
|
|
@ -140,7 +153,7 @@
|
||||||
{ "id": "gbridge",
|
{ "id": "gbridge",
|
||||||
"name": "Gadgetbridge",
|
"name": "Gadgetbridge",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.22",
|
"version":"0.23",
|
||||||
"description": "The default notification handler for Gadgetbridge notifications from Android",
|
"description": "The default notification handler for Gadgetbridge notifications from Android",
|
||||||
"tags": "tool,system,android,widget",
|
"tags": "tool,system,android,widget",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
|
|
@ -158,7 +171,7 @@
|
||||||
{ "id": "mclock",
|
{ "id": "mclock",
|
||||||
"name": "Morphing Clock",
|
"name": "Morphing Clock",
|
||||||
"icon": "clock-morphing.png",
|
"icon": "clock-morphing.png",
|
||||||
"version":"0.06",
|
"version":"0.07",
|
||||||
"description": "7 segment clock that morphs between minutes and hours",
|
"description": "7 segment clock that morphs between minutes and hours",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
|
|
@ -172,9 +185,9 @@
|
||||||
{ "id": "setting",
|
{ "id": "setting",
|
||||||
"name": "Settings",
|
"name": "Settings",
|
||||||
"icon": "settings.png",
|
"icon": "settings.png",
|
||||||
"version":"0.26",
|
"version":"0.28",
|
||||||
"description": "A menu for setting up Bangle.js",
|
"description": "A menu for setting up Bangle.js",
|
||||||
"tags": "tool,system",
|
"tags": "tool,system,b2",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"setting.app.js","url":"settings.js"},
|
{"name":"setting.app.js","url":"settings.js"},
|
||||||
|
|
@ -191,7 +204,7 @@
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.11",
|
"version":"0.11",
|
||||||
"description": "Set and respond to alarms",
|
"description": "Set and respond to alarms",
|
||||||
"tags": "tool,alarm,widget",
|
"tags": "tool,alarm,widget,b2",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"alarm.app.js","url":"app.js"},
|
{"name":"alarm.app.js","url":"app.js"},
|
||||||
{"name":"alarm.boot.js","url":"boot.js"},
|
{"name":"alarm.boot.js","url":"boot.js"},
|
||||||
|
|
@ -206,9 +219,9 @@
|
||||||
{ "id": "wclock",
|
{ "id": "wclock",
|
||||||
"name": "Word Clock",
|
"name": "Word Clock",
|
||||||
"icon": "clock-word.png",
|
"icon": "clock-word.png",
|
||||||
"version":"0.02",
|
"version":"0.03",
|
||||||
"description": "Display Time as Text",
|
"description": "Display Time as Text",
|
||||||
"tags": "clock",
|
"tags": "clock,b2",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
|
|
@ -245,7 +258,7 @@
|
||||||
{ "id": "slidingtext",
|
{ "id": "slidingtext",
|
||||||
"name": "Sliding Clock",
|
"name": "Sliding Clock",
|
||||||
"icon": "slidingtext.png",
|
"icon": "slidingtext.png",
|
||||||
"version":"0.05",
|
"version":"0.06",
|
||||||
"description": "Inspired by the Pebble sliding clock, old times are scrolled off the screen and new times on. You are also able to change language on the fly so you can see the time written in other languages using button 1. Currently English, French, Japanese, Spanish and German are supported",
|
"description": "Inspired by the Pebble sliding clock, old times are scrolled off the screen and new times on. You are also able to change language on the fly so you can see the time written in other languages using button 1. Currently English, French, Japanese, Spanish and German are supported",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
|
|
@ -265,6 +278,33 @@
|
||||||
{"name":"slidingtext.dtfmt.js","url":"slidingtext.dtfmt.js"}
|
{"name":"slidingtext.dtfmt.js","url":"slidingtext.dtfmt.js"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{ "id": "solarclock",
|
||||||
|
"name": "Solar Clock",
|
||||||
|
"icon": "solar_clock.png",
|
||||||
|
"version":"0.01",
|
||||||
|
"description": "Using your current or chosen location the solar watch face shows the Sun's sky position, time and date. Also allows you to wind backwards and forwards in time to see the sun's position",
|
||||||
|
"tags": "clock",
|
||||||
|
"type":"clock",
|
||||||
|
"allow_emulator":false,
|
||||||
|
"readme": "README.md",
|
||||||
|
"custom":"custom.html",
|
||||||
|
"storage": [
|
||||||
|
{"name":"solarclock.app.js","url":"solar_clock.js"},
|
||||||
|
{"name":"solarclock.img","url":"solar_clock-icon.js","evaluate":true},
|
||||||
|
{"name":"solar_colors.js","url":"solar_colors.js"},
|
||||||
|
{"name":"solar_controller.js","url":"solar_controller.js"},
|
||||||
|
{"name":"solar_date_utils.js","url":"solar_date_utils.js"},
|
||||||
|
{"name":"solar_graphic_utils.js","url":"solar_graphic_utils.js"},
|
||||||
|
{"name":"solar_location.js","url":"solar_location.js"},
|
||||||
|
{"name":"solar_math_utils.js","url":"solar_math_utils.js"},
|
||||||
|
{"name":"solar_loc.Reykjavik.json","url":"solar_loc.Reykjavik.json"},
|
||||||
|
{"name":"solar_loc.Hong_Kong.json","url":"solar_loc.Hong_Kong.json"},
|
||||||
|
{"name":"solar_loc.Honolulu.json","url":"solar_loc.Honolulu.json"},
|
||||||
|
{"name":"solar_loc.Rio.json","url":"solar_loc.Rio.json"},
|
||||||
|
{"name":"solar_loc.Tokyo.json","url":"solar_loc.Tokyo.json"},
|
||||||
|
{"name":"solar_loc.Seoul.json","url":"solar_loc.Seoul.json"}
|
||||||
|
]
|
||||||
|
},
|
||||||
{ "id": "sweepclock",
|
{ "id": "sweepclock",
|
||||||
"name": "Sweep Clock",
|
"name": "Sweep Clock",
|
||||||
"icon": "sweepclock.png",
|
"icon": "sweepclock.png",
|
||||||
|
|
@ -283,7 +323,7 @@
|
||||||
"name": "Image background clock",
|
"name": "Image background clock",
|
||||||
"shortName":"Image Clock",
|
"shortName":"Image Clock",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.07",
|
"version":"0.08",
|
||||||
"description": "A clock with an image as a background",
|
"description": "A clock with an image as a background",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type" : "clock",
|
"type" : "clock",
|
||||||
|
|
@ -299,7 +339,7 @@
|
||||||
{ "id": "impwclock",
|
{ "id": "impwclock",
|
||||||
"name": "Imprecise Word Clock",
|
"name": "Imprecise Word Clock",
|
||||||
"icon": "clock-impword.png",
|
"icon": "clock-impword.png",
|
||||||
"version":"0.02",
|
"version":"0.03",
|
||||||
"description": "Imprecise word clock for vacations, weekends, and those who never need accurate time.",
|
"description": "Imprecise word clock for vacations, weekends, and those who never need accurate time.",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
|
|
@ -312,9 +352,9 @@
|
||||||
{ "id": "aclock",
|
{ "id": "aclock",
|
||||||
"name": "Analog Clock",
|
"name": "Analog Clock",
|
||||||
"icon": "clock-analog.png",
|
"icon": "clock-analog.png",
|
||||||
"version": "0.14",
|
"version": "0.15",
|
||||||
"description": "An Analog Clock",
|
"description": "An Analog Clock",
|
||||||
"tags": "clock",
|
"tags": "clock,b2",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
|
|
@ -325,9 +365,9 @@
|
||||||
{ "id": "clock2x3",
|
{ "id": "clock2x3",
|
||||||
"name": "2x3 Pixel Clock",
|
"name": "2x3 Pixel Clock",
|
||||||
"icon": "clock2x3.png",
|
"icon": "clock2x3.png",
|
||||||
"version":"0.04",
|
"version":"0.05",
|
||||||
"description": "This is a simple clock using minimalist 2x3 pixel numerical digits",
|
"description": "This is a simple clock using minimalist 2x3 pixel numerical digits",
|
||||||
"tags": "clock",
|
"tags": "clock,b2",
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
|
|
@ -338,9 +378,9 @@
|
||||||
{ "id": "geissclk",
|
{ "id": "geissclk",
|
||||||
"name": "Geiss Clock",
|
"name": "Geiss Clock",
|
||||||
"icon": "clock.png",
|
"icon": "clock.png",
|
||||||
"version":"0.02",
|
"version":"0.03",
|
||||||
"description": "7 segment clock with animated background in the style of Ryan Geiss' music visualisation. NOTE: The first run will take ~1 minute to do some precalculation",
|
"description": "7 segment clock with animated background in the style of Ryan Geiss' music visualisation. NOTE: The first run will take ~1 minute to do some precalculation",
|
||||||
"tags": "clock",
|
"tags": "clock,bno2",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"geissclk.app.js","url":"clock.js"},
|
{"name":"geissclk.app.js","url":"clock.js"},
|
||||||
|
|
@ -362,13 +402,17 @@
|
||||||
{ "id": "trex",
|
{ "id": "trex",
|
||||||
"name": "T-Rex",
|
"name": "T-Rex",
|
||||||
"icon": "trex.png",
|
"icon": "trex.png",
|
||||||
"version":"0.02",
|
"version":"0.03",
|
||||||
"description": "T-Rex game in the style of Chrome's offline game",
|
"description": "T-Rex game in the style of Chrome's offline game",
|
||||||
"tags": "game",
|
"tags": "game",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"trex.app.js","url":"trex.js"},
|
{"name":"trex.app.js","url":"trex.js"},
|
||||||
{"name":"trex.img","url":"trex-icon.js","evaluate":true}
|
{"name":"trex.img","url":"trex-icon.js","evaluate":true},
|
||||||
|
{"name":"trex.settings.js","url":"settings.js"}
|
||||||
|
],
|
||||||
|
"data": [
|
||||||
|
{"name":"trex.score", "storageFile": true}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "astroid",
|
{ "id": "astroid",
|
||||||
|
|
@ -453,10 +497,11 @@
|
||||||
{ "id": "gpsrec",
|
{ "id": "gpsrec",
|
||||||
"name": "GPS Recorder",
|
"name": "GPS Recorder",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.19",
|
"version":"0.22",
|
||||||
"interface": "interface.html",
|
"interface": "interface.html",
|
||||||
"description": "Application that allows you to record a GPS track. Can run in background",
|
"description": "Application that allows you to record a GPS track. Can run in background",
|
||||||
"tags": "tool,outdoors,gps,widget",
|
"tags": "tool,outdoors,gps,widget",
|
||||||
|
"readme": "README.md",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"gpsrec.app.js","url":"app.js"},
|
{"name":"gpsrec.app.js","url":"app.js"},
|
||||||
{"name":"gpsrec.img","url":"app-icon.js","evaluate":true},
|
{"name":"gpsrec.img","url":"app-icon.js","evaluate":true},
|
||||||
|
|
@ -515,7 +560,7 @@
|
||||||
{ "id": "files",
|
{ "id": "files",
|
||||||
"name": "App Manager",
|
"name": "App Manager",
|
||||||
"icon": "files.png",
|
"icon": "files.png",
|
||||||
"version":"0.06",
|
"version":"0.07",
|
||||||
"description": "Show currently installed apps, free space, and allow their deletion from the watch",
|
"description": "Show currently installed apps, free space, and allow their deletion from the watch",
|
||||||
"tags": "tool,system,files",
|
"tags": "tool,system,files",
|
||||||
"storage": [
|
"storage": [
|
||||||
|
|
@ -526,7 +571,7 @@
|
||||||
{ "id": "weather",
|
{ "id": "weather",
|
||||||
"name": "Weather",
|
"name": "Weather",
|
||||||
"icon": "icon.png",
|
"icon": "icon.png",
|
||||||
"version":"0.03",
|
"version":"0.05",
|
||||||
"description": "Show Gadgetbridge weather report",
|
"description": "Show Gadgetbridge weather report",
|
||||||
"readme": "readme.md",
|
"readme": "readme.md",
|
||||||
"tags": "widget,outdoors",
|
"tags": "widget,outdoors",
|
||||||
|
|
@ -571,9 +616,9 @@
|
||||||
{ "id": "widbat",
|
{ "id": "widbat",
|
||||||
"name": "Battery Level Widget",
|
"name": "Battery Level Widget",
|
||||||
"icon": "widget.png",
|
"icon": "widget.png",
|
||||||
"version":"0.06",
|
"version":"0.07",
|
||||||
"description": "Show the current battery level and charging status in the top right of the clock",
|
"description": "Show the current battery level and charging status in the top right of the clock",
|
||||||
"tags": "widget,battery",
|
"tags": "widget,battery,b2",
|
||||||
"type":"widget",
|
"type":"widget",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"widbat.wid.js","url":"widget.js"}
|
{"name":"widbat.wid.js","url":"widget.js"}
|
||||||
|
|
@ -582,9 +627,9 @@
|
||||||
{ "id": "widlock",
|
{ "id": "widlock",
|
||||||
"name": "Lock Widget",
|
"name": "Lock Widget",
|
||||||
"icon": "widget.png",
|
"icon": "widget.png",
|
||||||
"version":"0.01",
|
"version":"0.03",
|
||||||
"description": "On devices with always-on display (Bangle.js 2) this displays lock icon whenever the display is locked",
|
"description": "On devices with always-on display (Bangle.js 2) this displays lock icon whenever the display is locked",
|
||||||
"tags": "widget,lock",
|
"tags": "widget,lock,b2",
|
||||||
"type":"widget",
|
"type":"widget",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"widlock.wid.js","url":"widget.js"}
|
{"name":"widlock.wid.js","url":"widget.js"}
|
||||||
|
|
@ -627,9 +672,9 @@
|
||||||
{ "id": "widbt",
|
{ "id": "widbt",
|
||||||
"name": "Bluetooth Widget",
|
"name": "Bluetooth Widget",
|
||||||
"icon": "widget.png",
|
"icon": "widget.png",
|
||||||
"version":"0.04",
|
"version":"0.05",
|
||||||
"description": "Show the current Bluetooth connection status in the top right of the clock",
|
"description": "Show the current Bluetooth connection status in the top right of the clock",
|
||||||
"tags": "widget,bluetooth",
|
"tags": "widget,bluetooth,b2",
|
||||||
"type":"widget",
|
"type":"widget",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"widbt.wid.js","url":"widget.js"}
|
{"name":"widbt.wid.js","url":"widget.js"}
|
||||||
|
|
@ -665,7 +710,7 @@
|
||||||
{ "id": "hrm",
|
{ "id": "hrm",
|
||||||
"name": "Heart Rate Monitor",
|
"name": "Heart Rate Monitor",
|
||||||
"icon": "heartrate.png",
|
"icon": "heartrate.png",
|
||||||
"version":"0.04",
|
"version":"0.05",
|
||||||
"description": "Measure your heart rate and see live sensor data",
|
"description": "Measure your heart rate and see live sensor data",
|
||||||
"tags": "health",
|
"tags": "health",
|
||||||
"storage": [
|
"storage": [
|
||||||
|
|
@ -847,9 +892,9 @@
|
||||||
{ "id": "sclock",
|
{ "id": "sclock",
|
||||||
"name": "Simple Clock",
|
"name": "Simple Clock",
|
||||||
"icon": "clock-simple.png",
|
"icon": "clock-simple.png",
|
||||||
"version":"0.04",
|
"version":"0.06",
|
||||||
"description": "A Simple Digital Clock",
|
"description": "A Simple Digital Clock",
|
||||||
"tags": "clock",
|
"tags": "clock,b2",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
|
|
@ -860,9 +905,9 @@
|
||||||
{ "id": "s7clk",
|
{ "id": "s7clk",
|
||||||
"name": "Simple 7 segment Clock",
|
"name": "Simple 7 segment Clock",
|
||||||
"icon": "icon.png",
|
"icon": "icon.png",
|
||||||
"version":"0.02",
|
"version":"0.03",
|
||||||
"description": "A simple 7 segment Clock with date",
|
"description": "A simple 7 segment Clock with date",
|
||||||
"tags": "clock",
|
"tags": "clock,b2",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
|
|
@ -873,7 +918,7 @@
|
||||||
{ "id": "vibrclock",
|
{ "id": "vibrclock",
|
||||||
"name": "Vibrate Clock",
|
"name": "Vibrate Clock",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.02",
|
"version":"0.03",
|
||||||
"description": "When BTN1 is pressed, vibrate out the time as a series of buzzes, one digit at a time. Hours, then Minutes. Zero is signified by one long buzz. Otherwise a simple digital clock.",
|
"description": "When BTN1 is pressed, vibrate out the time as a series of buzzes, one digit at a time. Hours, then Minutes. Zero is signified by one long buzz. Otherwise a simple digital clock.",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
|
|
@ -886,7 +931,7 @@
|
||||||
{ "id": "svclock",
|
{ "id": "svclock",
|
||||||
"name": "Simple V-Clock",
|
"name": "Simple V-Clock",
|
||||||
"icon": "vclock-simple.png",
|
"icon": "vclock-simple.png",
|
||||||
"version":"0.01",
|
"version":"0.02",
|
||||||
"description": "Modification of Simple Clock 0.04 to use Vectorfont",
|
"description": "Modification of Simple Clock 0.04 to use Vectorfont",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
|
|
@ -899,9 +944,9 @@
|
||||||
{ "id": "dclock",
|
{ "id": "dclock",
|
||||||
"name": "Dev Clock",
|
"name": "Dev Clock",
|
||||||
"icon": "clock-dev.png",
|
"icon": "clock-dev.png",
|
||||||
"version":"0.09",
|
"version":"0.10",
|
||||||
"description": "A Digital Clock including timestamp (tst), beats(@), days in current month (dm) and days since new moon (l)",
|
"description": "A Digital Clock including timestamp (tst), beats(@), days in current month (dm) and days since new moon (l)",
|
||||||
"tags": "clock",
|
"tags": "clock,b2",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
|
|
@ -1012,7 +1057,7 @@
|
||||||
{ "id": "miclock",
|
{ "id": "miclock",
|
||||||
"name": "Mixed Clock",
|
"name": "Mixed Clock",
|
||||||
"icon": "clock-mixed.png",
|
"icon": "clock-mixed.png",
|
||||||
"version":"0.04",
|
"version":"0.05",
|
||||||
"description": "A mix of analog and digital Clock",
|
"description": "A mix of analog and digital Clock",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
|
|
@ -1025,7 +1070,7 @@
|
||||||
{ "id": "bclock",
|
{ "id": "bclock",
|
||||||
"name": "Binary Clock",
|
"name": "Binary Clock",
|
||||||
"icon": "clock-binary.png",
|
"icon": "clock-binary.png",
|
||||||
"version":"0.02",
|
"version":"0.03",
|
||||||
"description": "A simple binary clock watch face",
|
"description": "A simple binary clock watch face",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
|
|
@ -1101,9 +1146,9 @@
|
||||||
"name": "Large Digit Blob Clock",
|
"name": "Large Digit Blob Clock",
|
||||||
"shortName" : "Blob Clock",
|
"shortName" : "Blob Clock",
|
||||||
"icon": "clock-blob.png",
|
"icon": "clock-blob.png",
|
||||||
"version":"0.05",
|
"version":"0.06",
|
||||||
"description": "A clock with big digits",
|
"description": "A clock with big digits",
|
||||||
"tags": "clock",
|
"tags": "clock,b2",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
|
|
@ -1114,9 +1159,9 @@
|
||||||
{ "id": "boldclk",
|
{ "id": "boldclk",
|
||||||
"name": "Bold Clock",
|
"name": "Bold Clock",
|
||||||
"icon": "bold_clock.png",
|
"icon": "bold_clock.png",
|
||||||
"version":"0.03",
|
"version":"0.04",
|
||||||
"description": "Simple, readable and practical clock",
|
"description": "Simple, readable and practical clock",
|
||||||
"tags": "clock",
|
"tags": "clock,b2",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
|
|
@ -1127,7 +1172,7 @@
|
||||||
{ "id": "widclk",
|
{ "id": "widclk",
|
||||||
"name": "Digital clock widget",
|
"name": "Digital clock widget",
|
||||||
"icon": "widget.png",
|
"icon": "widget.png",
|
||||||
"version":"0.04",
|
"version":"0.05",
|
||||||
"description": "A simple digital clock widget",
|
"description": "A simple digital clock widget",
|
||||||
"tags": "widget,clock",
|
"tags": "widget,clock",
|
||||||
"type":"widget",
|
"type":"widget",
|
||||||
|
|
@ -1138,9 +1183,9 @@
|
||||||
{ "id": "widpedom",
|
{ "id": "widpedom",
|
||||||
"name": "Pedometer widget",
|
"name": "Pedometer widget",
|
||||||
"icon": "widget.png",
|
"icon": "widget.png",
|
||||||
"version":"0.13",
|
"version":"0.14",
|
||||||
"description": "Daily pedometer widget",
|
"description": "Daily pedometer widget",
|
||||||
"tags": "widget",
|
"tags": "widget,b2",
|
||||||
"type":"widget",
|
"type":"widget",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"widpedom.wid.js","url":"widget.js"},
|
{"name":"widpedom.wid.js","url":"widget.js"},
|
||||||
|
|
@ -1150,7 +1195,7 @@
|
||||||
{ "id": "berlinc",
|
{ "id": "berlinc",
|
||||||
"name": "Berlin Clock",
|
"name": "Berlin Clock",
|
||||||
"icon": "berlin-clock.png",
|
"icon": "berlin-clock.png",
|
||||||
"version":"0.03",
|
"version":"0.04",
|
||||||
"description": "Berlin Clock (see https://en.wikipedia.org/wiki/Mengenlehreuhr)",
|
"description": "Berlin Clock (see https://en.wikipedia.org/wiki/Mengenlehreuhr)",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
|
|
@ -1163,9 +1208,9 @@
|
||||||
{ "id": "ctrclk",
|
{ "id": "ctrclk",
|
||||||
"name": "Centerclock",
|
"name": "Centerclock",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.02",
|
"version":"0.03",
|
||||||
"description": "Watch-centered digital 24h clock with date in dd.mm.yyyy format.",
|
"description": "Watch-centered digital 24h clock with date in dd.mm.yyyy format.",
|
||||||
"tags": "clock",
|
"tags": "clock,bno2",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
|
|
@ -1203,9 +1248,9 @@
|
||||||
"id": "pipboy",
|
"id": "pipboy",
|
||||||
"name": "Pipboy",
|
"name": "Pipboy",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version": "0.03",
|
"version": "0.04",
|
||||||
"description": "Pipboy themed clock",
|
"description": "Pipboy themed clock",
|
||||||
"tags": "clock",
|
"tags": "clock,bno2",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
|
|
@ -1226,6 +1271,19 @@
|
||||||
{"name":"torch.img","url":"app-icon.js","evaluate":true}
|
{"name":"torch.img","url":"app-icon.js","evaluate":true}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{ "id": "rtorch",
|
||||||
|
"name": "Red Torch",
|
||||||
|
"shortName":"RedTorch",
|
||||||
|
"icon": "app.png",
|
||||||
|
"version":"0.01",
|
||||||
|
"description": "Turns screen RED to help you see in the dark without breaking your night vision. Select from the launcher or press BTN3,BTN1,BTN3,BTN1 quickly to start when in any app that shows widgets",
|
||||||
|
"tags": "tool,torch",
|
||||||
|
"storage": [
|
||||||
|
{"name":"rtorch.app.js","url":"app.js"},
|
||||||
|
{"name":"rtorch.wid.js","url":"widget.js"},
|
||||||
|
{"name":"rtorch.img","url":"app-icon.js","evaluate":true}
|
||||||
|
]
|
||||||
|
},
|
||||||
{ "id": "wohrm",
|
{ "id": "wohrm",
|
||||||
"name": "Workout HRM",
|
"name": "Workout HRM",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
|
|
@ -1284,9 +1342,9 @@
|
||||||
"name": "Commandline-Clock",
|
"name": "Commandline-Clock",
|
||||||
"shortName":"CLI-Clock",
|
"shortName":"CLI-Clock",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.12",
|
"version":"0.13",
|
||||||
"description": "Simple CLI-Styled Clock",
|
"description": "Simple CLI-Styled Clock",
|
||||||
"tags": "clock,cli,command,bash,shell",
|
"tags": "clock,cli,command,bash,shell,b2",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
|
|
@ -1308,10 +1366,11 @@
|
||||||
{ "id": "barclock",
|
{ "id": "barclock",
|
||||||
"name": "Bar Clock",
|
"name": "Bar Clock",
|
||||||
"icon": "clock-bar.png",
|
"icon": "clock-bar.png",
|
||||||
"version":"0.05",
|
"version":"0.07",
|
||||||
"description": "A simple digital clock showing seconds as a bar",
|
"description": "A simple digital clock showing seconds as a bar",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
|
"readme": "README.md",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"barclock.app.js","url":"clock-bar.js"},
|
{"name":"barclock.app.js","url":"clock-bar.js"},
|
||||||
|
|
@ -1321,9 +1380,9 @@
|
||||||
{ "id": "dotclock",
|
{ "id": "dotclock",
|
||||||
"name": "Dot Clock",
|
"name": "Dot Clock",
|
||||||
"icon": "clock-dot.png",
|
"icon": "clock-dot.png",
|
||||||
"version":"0.02",
|
"version":"0.03",
|
||||||
"description": "A Minimal Dot Analog Clock",
|
"description": "A Minimal Dot Analog Clock",
|
||||||
"tags": "clock",
|
"tags": "clock,b2",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
|
|
@ -1444,7 +1503,7 @@
|
||||||
{ "id": "minionclk",
|
{ "id": "minionclk",
|
||||||
"name": "Minion clock",
|
"name": "Minion clock",
|
||||||
"icon": "minionclk.png",
|
"icon": "minionclk.png",
|
||||||
"version": "0.04",
|
"version": "0.05",
|
||||||
"description": "Minion themed clock.",
|
"description": "Minion themed clock.",
|
||||||
"tags": "clock,minion",
|
"tags": "clock,minion",
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
|
|
@ -1458,9 +1517,9 @@
|
||||||
"name": "OpenStreetMap",
|
"name": "OpenStreetMap",
|
||||||
"shortName":"OpenStMap",
|
"shortName":"OpenStMap",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.05",
|
"version":"0.08",
|
||||||
"description": "[BETA] Loads map tiles from OpenStreetMap onto your Bangle.js and displays a map of where you are",
|
"description": "[BETA] Loads map tiles from OpenStreetMap onto your Bangle.js and displays a map of where you are",
|
||||||
"tags": "outdoors,gps",
|
"tags": "outdoors,gps,b2",
|
||||||
"custom": "custom.html",
|
"custom": "custom.html",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"openstmap","url":"openstmap.js"},
|
{"name":"openstmap","url":"openstmap.js"},
|
||||||
|
|
@ -1525,9 +1584,9 @@
|
||||||
"name": "Dev Stopwatch",
|
"name": "Dev Stopwatch",
|
||||||
"shortName":"Dev Stopwatch",
|
"shortName":"Dev Stopwatch",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.02",
|
"version":"0.03",
|
||||||
"description": "Stopwatch with 5 laps supported (cyclically replaced)",
|
"description": "Stopwatch with 5 laps supported (cyclically replaced)",
|
||||||
"tags": "stopwatch, chrono, timer, chronometer",
|
"tags": "stopwatch,chrono,timer,chronometer,b2",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"devstopwatch.app.js","url":"app.js"},
|
{"name":"devstopwatch.app.js","url":"app.js"},
|
||||||
|
|
@ -1566,7 +1625,7 @@
|
||||||
"name": "Numerals Clock",
|
"name": "Numerals Clock",
|
||||||
"shortName": "Numerals Clock",
|
"shortName": "Numerals Clock",
|
||||||
"icon": "numerals.png",
|
"icon": "numerals.png",
|
||||||
"version":"0.08",
|
"version":"0.09",
|
||||||
"description": "A simple big numerals clock",
|
"description": "A simple big numerals clock",
|
||||||
"tags": "numerals,clock",
|
"tags": "numerals,clock",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
|
|
@ -1727,7 +1786,7 @@
|
||||||
"name": "Black Jack game",
|
"name": "Black Jack game",
|
||||||
"shortName":"Black Jack game",
|
"shortName":"Black Jack game",
|
||||||
"icon": "blackjack.png",
|
"icon": "blackjack.png",
|
||||||
"version":"0.01",
|
"version":"0.02",
|
||||||
"description": "Simple implementation of card game Black Jack",
|
"description": "Simple implementation of card game Black Jack",
|
||||||
"tags": "game",
|
"tags": "game",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
|
|
@ -1753,7 +1812,7 @@
|
||||||
"name": "SWL Clock / Short Wave Listner Clock",
|
"name": "SWL Clock / Short Wave Listner Clock",
|
||||||
"shortName": "SWL Clock",
|
"shortName": "SWL Clock",
|
||||||
"icon": "swlclk.png",
|
"icon": "swlclk.png",
|
||||||
"version":"0.01",
|
"version":"0.02",
|
||||||
"description": "Display Local, UTC time and some programs on the shorts waves along the day, with the frequencies",
|
"description": "Display Local, UTC time and some programs on the shorts waves along the day, with the frequencies",
|
||||||
"tags": "tool,clock",
|
"tags": "tool,clock",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
|
|
@ -1769,7 +1828,7 @@
|
||||||
"name": "Round clock with seconds, minutes and date",
|
"name": "Round clock with seconds, minutes and date",
|
||||||
"shortName": "Round Clock",
|
"shortName": "Round Clock",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version": "0.05",
|
"version": "0.06",
|
||||||
"description": "Designed round clock with ticks for minutes and seconds and heart rate indication",
|
"description": "Designed round clock with ticks for minutes and seconds and heart rate indication",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
|
|
@ -1783,7 +1842,7 @@
|
||||||
"name": "fclock",
|
"name": "fclock",
|
||||||
"shortName": "F Clock",
|
"shortName": "F Clock",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version": "0.01",
|
"version": "0.02",
|
||||||
"description": "Simple design of a digital clock",
|
"description": "Simple design of a digital clock",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
|
|
@ -1852,9 +1911,9 @@
|
||||||
{ "id": "calendar",
|
{ "id": "calendar",
|
||||||
"name": "Calendar",
|
"name": "Calendar",
|
||||||
"icon": "calendar.png",
|
"icon": "calendar.png",
|
||||||
"version": "0.01",
|
"version": "0.02",
|
||||||
"description": "Simple calendar",
|
"description": "Simple calendar",
|
||||||
"tags": "calendar",
|
"tags": "calendar,b2",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"allow_emulator": true,
|
"allow_emulator": true,
|
||||||
"storage": [
|
"storage": [
|
||||||
|
|
@ -1980,7 +2039,7 @@
|
||||||
"id": "beebclock",
|
"id": "beebclock",
|
||||||
"name": "Beeb Clock",
|
"name": "Beeb Clock",
|
||||||
"icon": "beebclock.png",
|
"icon": "beebclock.png",
|
||||||
"version":"0.03",
|
"version":"0.04",
|
||||||
"description": "Clock face that may be coincidentally familiar to BBC viewers",
|
"description": "Clock face that may be coincidentally familiar to BBC viewers",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
|
|
@ -2024,9 +2083,9 @@
|
||||||
"name": "Time Traveller's Chronometer",
|
"name": "Time Traveller's Chronometer",
|
||||||
"shortName": "Time Travel Clock",
|
"shortName": "Time Travel Clock",
|
||||||
"icon": "gallifr.png",
|
"icon": "gallifr.png",
|
||||||
"version": "0.01",
|
"version": "0.02",
|
||||||
"description": "A clock for time travellers. The light pie segment shows the minutes, the black circle, the hour. The dial itself reads 'time' just in case you forget.",
|
"description": "A clock for time travellers. The light pie segment shows the minutes, the black circle, the hour. The dial itself reads 'time' just in case you forget.",
|
||||||
"tags": "clock",
|
"tags": "clock,b2",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
|
|
@ -2078,6 +2137,20 @@
|
||||||
{ "name": "jbm8b.img", "url": "app-icon.js", "evaluate": true }
|
{ "name": "jbm8b.img", "url": "app-icon.js", "evaluate": true }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "jbm8b_IT",
|
||||||
|
"name": "Magic 8 Ball Italiano",
|
||||||
|
"shortName": "Magic 8 Ball IT",
|
||||||
|
"icon": "app.png",
|
||||||
|
"description": "La palla predice il futuro",
|
||||||
|
"tags": "game",
|
||||||
|
"version": "0.01",
|
||||||
|
"allow_emulator":true,
|
||||||
|
"storage": [
|
||||||
|
{ "name": "jbm8b_IT.app.js", "url": "app.js" },
|
||||||
|
{ "name": "jbm8b_IT.img", "url": "app-icon.js", "evaluate": true }
|
||||||
|
]
|
||||||
|
},
|
||||||
{ "id": "BLEcontroller",
|
{ "id": "BLEcontroller",
|
||||||
"name": "BLE Customisable Controller with Joystick",
|
"name": "BLE Customisable Controller with Joystick",
|
||||||
"shortName": "BLE Controller",
|
"shortName": "BLE Controller",
|
||||||
|
|
@ -2108,7 +2181,7 @@
|
||||||
"name": "Binary Clock",
|
"name": "Binary Clock",
|
||||||
"shortName":"Binary Clock",
|
"shortName":"Binary Clock",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.02",
|
"version":"0.03",
|
||||||
"description": "A binary clock with hours and minutes. BTN1 toggles a digital clock.",
|
"description": "A binary clock with hours and minutes. BTN1 toggles a digital clock.",
|
||||||
"tags": "clock,binary",
|
"tags": "clock,binary",
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
|
|
@ -2135,9 +2208,9 @@
|
||||||
"name": "Animated Clock",
|
"name": "Animated Clock",
|
||||||
"shortName":"Anim Clock",
|
"shortName":"Anim Clock",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.02",
|
"version":"0.03",
|
||||||
"description": "An animated clock face using Mark Ferrari's amazing 8 bit game art and palette cycling: http://www.markferrari.com/art/8bit-game-art",
|
"description": "An animated clock face using Mark Ferrari's amazing 8 bit game art and palette cycling: http://www.markferrari.com/art/8bit-game-art",
|
||||||
"tags": "clock,animated",
|
"tags": "clock,animated,bno2",
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"animclk.app.js","url":"app.js"},
|
{"name":"animclk.app.js","url":"app.js"},
|
||||||
|
|
@ -2151,9 +2224,9 @@
|
||||||
"name": "Analog Clock (Image background)",
|
"name": "Analog Clock (Image background)",
|
||||||
"shortName":"Analog Clock",
|
"shortName":"Analog Clock",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.02",
|
"version":"0.03",
|
||||||
"description": "An analog clock with an image background",
|
"description": "An analog clock with an image background",
|
||||||
"tags": "clock",
|
"tags": "clock,bno2",
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"analogimgclk.app.js","url":"app.js"},
|
{"name":"analogimgclk.app.js","url":"app.js"},
|
||||||
|
|
@ -2166,7 +2239,7 @@
|
||||||
"name": "Vertical watch face",
|
"name": "Vertical watch face",
|
||||||
"shortName":"Vertical Face",
|
"shortName":"Vertical Face",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.08",
|
"version":"0.09",
|
||||||
"description": "A simple vertical watch face with the date. Heart rate monitor is toggled with BTN1",
|
"description": "A simple vertical watch face with the date. Heart rate monitor is toggled with BTN1",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
|
|
@ -2471,7 +2544,7 @@
|
||||||
"name": "World Clock - 4 time zones",
|
"name": "World Clock - 4 time zones",
|
||||||
"shortName":"World Clock",
|
"shortName":"World Clock",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.03",
|
"version":"0.04",
|
||||||
"description": "Current time zone plus up to four others",
|
"description": "Current time zone plus up to four others",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type" : "clock",
|
"type" : "clock",
|
||||||
|
|
@ -2489,9 +2562,9 @@
|
||||||
"name": "Digital Clock Face",
|
"name": "Digital Clock Face",
|
||||||
"shortName":"Digi Clock",
|
"shortName":"Digi Clock",
|
||||||
"icon": "digiclock.png",
|
"icon": "digiclock.png",
|
||||||
"version":"0.01",
|
"version":"0.02",
|
||||||
"description": "A simple digital clock with the time, day, month, and year",
|
"description": "A simple digital clock with the time, day, month, and year",
|
||||||
"tags": "clock",
|
"tags": "clock,bno2",
|
||||||
"type" : "clock",
|
"type" : "clock",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"digiclock.app.js","url":"digiclock.js"},
|
{"name":"digiclock.app.js","url":"digiclock.js"},
|
||||||
|
|
@ -2564,7 +2637,7 @@
|
||||||
"name": "NCR Clock",
|
"name": "NCR Clock",
|
||||||
"shortName":"NCR Clock",
|
"shortName":"NCR Clock",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.01",
|
"version":"0.02",
|
||||||
"description": "NodeConf Remote clock",
|
"description": "NodeConf Remote clock",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
|
|
@ -2577,7 +2650,7 @@
|
||||||
"name": "ISO Compliant Clock Face",
|
"name": "ISO Compliant Clock Face",
|
||||||
"shortName":"ISO Clock",
|
"shortName":"ISO Clock",
|
||||||
"icon": "isoclock.png",
|
"icon": "isoclock.png",
|
||||||
"version":"0.01",
|
"version":"0.02",
|
||||||
"description": "Tweaked fork of digiclock for ISO date and time",
|
"description": "Tweaked fork of digiclock for ISO date and time",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type" : "clock",
|
"type" : "clock",
|
||||||
|
|
@ -2648,7 +2721,7 @@
|
||||||
{ "id": "dtlaunch",
|
{ "id": "dtlaunch",
|
||||||
"name": "Desktop Launcher",
|
"name": "Desktop Launcher",
|
||||||
"icon": "icon.png",
|
"icon": "icon.png",
|
||||||
"version":"0.03",
|
"version":"0.04",
|
||||||
"description": "Desktop style App Launcher with six apps per page - fast access if you have lots of apps installed.",
|
"description": "Desktop style App Launcher with six apps per page - fast access if you have lots of apps installed.",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"tags": "tool,system,launcher",
|
"tags": "tool,system,launcher",
|
||||||
|
|
@ -2735,7 +2808,7 @@
|
||||||
{ "id": "lazyclock",
|
{ "id": "lazyclock",
|
||||||
"name": "Lazy Clock",
|
"name": "Lazy Clock",
|
||||||
"icon": "lazyclock.png",
|
"icon": "lazyclock.png",
|
||||||
"version":"0.02",
|
"version":"0.03",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"description": "Tells the time, roughly",
|
"description": "Tells the time, roughly",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
|
|
@ -2749,7 +2822,7 @@
|
||||||
{ "id": "astral",
|
{ "id": "astral",
|
||||||
"name": "Astral Clock",
|
"name": "Astral Clock",
|
||||||
"icon": "app-icon.png",
|
"icon": "app-icon.png",
|
||||||
"version":"0.02",
|
"version":"0.03",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"description": "Clock that calculates and displays Alt Az positions of all planets, Sun as well as several other astronomy targets (customizable) and current Moon phase. Coordinates are calculated by GPS & time and onscreen compass assists orienting. See Readme before using.",
|
"description": "Clock that calculates and displays Alt Az positions of all planets, Sun as well as several other astronomy targets (customizable) and current Moon phase. Coordinates are calculated by GPS & time and onscreen compass assists orienting. See Readme before using.",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
|
|
@ -2775,13 +2848,13 @@
|
||||||
"name": "Game of Life Clock",
|
"name": "Game of Life Clock",
|
||||||
"shortName":"Conway's Clock",
|
"shortName":"Conway's Clock",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.05",
|
"version":"0.06",
|
||||||
"description": "Modification and clockification of Conway's Game of Life",
|
"description": "Modification and clockification of Conway's Game of Life",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type" : "clock",
|
"type" : "clock",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"lifeclk.app.js","url":"app.js"},
|
{"name":"lifeclk.app.js","url":"app.min.js"},
|
||||||
{"name":"lifeclk.img","url":"app-icon.js","evaluate":true}
|
{"name":"lifeclk.img","url":"app-icon.js","evaluate":true}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
@ -2808,7 +2881,7 @@
|
||||||
"name": "De-Stress",
|
"name": "De-Stress",
|
||||||
"shortName":"De-Stress",
|
"shortName":"De-Stress",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.01",
|
"version":"0.02",
|
||||||
"description": "Simple haptic heartbeat",
|
"description": "Simple haptic heartbeat",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"de-stress.app.js","url":"app.js"},
|
{"name":"de-stress.app.js","url":"app.js"},
|
||||||
|
|
@ -2837,7 +2910,7 @@
|
||||||
"name": "Morph Clock+",
|
"name": "Morph Clock+",
|
||||||
"shortName":"Morph Clock+",
|
"shortName":"Morph Clock+",
|
||||||
"icon": "mclockplus.png",
|
"icon": "mclockplus.png",
|
||||||
"version":"1.0",
|
"version":"0.02",
|
||||||
"description": "Morphing Clock with more readable seconds and date and additional stopwatch",
|
"description": "Morphing Clock with more readable seconds and date and additional stopwatch",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
|
|
@ -3045,7 +3118,7 @@
|
||||||
"version":"0.01",
|
"version":"0.01",
|
||||||
"description": "Displays RGB565 and RGB888 colors, its name and code in screen.",
|
"description": "Displays RGB565 and RGB888 colors, its name and code in screen.",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"tags": "Color, input,buttons,touch,UI",
|
"tags": "Color,input,buttons,touch,UI,bno2",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"color_catalog.app.js","url":"app.js"},
|
{"name":"color_catalog.app.js","url":"app.js"},
|
||||||
{"name":"color_catalog.img","url":"app-icon.js","evaluate":true}
|
{"name":"color_catalog.img","url":"app-icon.js","evaluate":true}
|
||||||
|
|
@ -3067,7 +3140,7 @@
|
||||||
{ "id": "simplest",
|
{ "id": "simplest",
|
||||||
"name": "Simplest Clock",
|
"name": "Simplest Clock",
|
||||||
"icon": "simplest.png",
|
"icon": "simplest.png",
|
||||||
"version":"0.01",
|
"version":"0.02",
|
||||||
"description": "The simplest working clock, acts as a tutorial piece",
|
"description": "The simplest working clock, acts as a tutorial piece",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
|
|
@ -3135,7 +3208,7 @@
|
||||||
{ "id": "kitchen",
|
{ "id": "kitchen",
|
||||||
"name": "Kitchen Combo",
|
"name": "Kitchen Combo",
|
||||||
"icon": "kitchen.png",
|
"icon": "kitchen.png",
|
||||||
"version":"0.10",
|
"version":"0.12",
|
||||||
"description": "Combination of the Stepo, Walkersclock, Arrow and Waypointer apps into a multiclock format. 'Everything but the kitchen sink'. Requires firmware v2.08.167 or later",
|
"description": "Combination of the Stepo, Walkersclock, Arrow and Waypointer apps into a multiclock format. 'Everything but the kitchen sink'. Requires firmware v2.08.167 or later",
|
||||||
"tags": "tool,outdoors,gps",
|
"tags": "tool,outdoors,gps",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
|
|
@ -3143,11 +3216,9 @@
|
||||||
"interface":"waypoints.html",
|
"interface":"waypoints.html",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"kitchen.app.js","url":"kitchen.app.js"},
|
{"name":"kitchen.app.js","url":"kitchen.app.js"},
|
||||||
{"name":"stepo.kit.js","url":"stepo.kit.js"},
|
{"name":"stepo2.kit.js","url":"stepo2.kit.js"},
|
||||||
{"name":"gps.kit.js","url":"gps.kit.js"},
|
|
||||||
{"name":"digi.kit.js","url":"digi.kit.js"},
|
|
||||||
{"name":"heart.kit.js","url":"heart.kit.js"},
|
|
||||||
{"name":"swatch.kit.js","url":"swatch.kit.js"},
|
{"name":"swatch.kit.js","url":"swatch.kit.js"},
|
||||||
|
{"name":"gps.kit.js","url":"gps.kit.js"},
|
||||||
{"name":"compass.kit.js","url":"compass.kit.js"},
|
{"name":"compass.kit.js","url":"compass.kit.js"},
|
||||||
{"name":"kitchen.img","url":"kitchen.icon.js","evaluate":true}
|
{"name":"kitchen.img","url":"kitchen.icon.js","evaluate":true}
|
||||||
],
|
],
|
||||||
|
|
@ -3155,19 +3226,35 @@
|
||||||
{"name":"waypoints.json","url":"waypoints.json"}
|
{"name":"waypoints.json","url":"waypoints.json"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{ "id": "banglebridge",
|
||||||
|
"name": "BangleBridge",
|
||||||
|
"shortName":"BangleBridge",
|
||||||
|
"icon": "widget.png",
|
||||||
|
"version":"0.01",
|
||||||
|
"description": "Widget that allows Bangle Js to record pair and end data using Bluetooth Low Energy in combination with the BangleBridge Android App",
|
||||||
|
"tags": "widget",
|
||||||
|
"type": "widget",
|
||||||
|
"readme": "README.md",
|
||||||
|
"storage": [
|
||||||
|
{"name":"banglebridge.wid.js","url":"widget.js"},
|
||||||
|
{"name":"banglebridge.watch.img","url":"watch.img"},
|
||||||
|
{"name":"banglebridge.heart.img","url":"heart.img"}
|
||||||
|
]
|
||||||
|
},
|
||||||
{ "id": "qmsched",
|
{ "id": "qmsched",
|
||||||
"name": "Quiet Mode Schedule",
|
"name": "Quiet Mode Schedule and Widget",
|
||||||
"shortName":"Quiet Mode",
|
"shortName":"Quiet Mode",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.01",
|
"version":"0.02",
|
||||||
"description": "Automatically turn Quiet Mode on or off at set times",
|
"description": "Automatically turn Quiet Mode on or off at set times",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"tags": "tool",
|
"tags": "tool,widget",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"qmsched","url":"lib.js"},
|
{"name":"qmsched","url":"lib.js"},
|
||||||
{"name":"qmsched.app.js","url":"app.js"},
|
{"name":"qmsched.app.js","url":"app.js"},
|
||||||
{"name":"qmsched.boot.js","url":"boot.js"},
|
{"name":"qmsched.boot.js","url":"boot.js"},
|
||||||
{"name":"qmsched.img","url":"icon.js","evaluate":true}
|
{"name":"qmsched.img","url":"icon.js","evaluate":true},
|
||||||
|
{"name":"qmsched.wid.js","url":"widget.js"}
|
||||||
],
|
],
|
||||||
"data": [
|
"data": [
|
||||||
{"name":"qmsched.json"}
|
{"name":"qmsched.json"}
|
||||||
|
|
@ -3209,7 +3296,6 @@
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"description": "An Omnitrix Showpiece",
|
"description": "An Omnitrix Showpiece",
|
||||||
"tags": "game",
|
"tags": "game",
|
||||||
"readme": "README.md",
|
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"omnitrix.app.js","url":"omnitrix.app.js"},
|
{"name":"omnitrix.app.js","url":"omnitrix.app.js"},
|
||||||
{"name":"omnitrix.img","url":"omnitrix.icon.js","evaluate":true}
|
{"name":"omnitrix.img","url":"omnitrix.icon.js","evaluate":true}
|
||||||
|
|
@ -3219,7 +3305,7 @@
|
||||||
"name": "Bat Clock",
|
"name": "Bat Clock",
|
||||||
"shortName":"Bat Clock",
|
"shortName":"Bat Clock",
|
||||||
"icon": "bat-clock.png",
|
"icon": "bat-clock.png",
|
||||||
"version":"0.01",
|
"version":"0.02",
|
||||||
"description": "Morphing Clock, with an awesome \"The Dark Knight\" themed logo.",
|
"description": "Morphing Clock, with an awesome \"The Dark Knight\" themed logo.",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
|
|
@ -3233,7 +3319,7 @@
|
||||||
"name":"Dozenal Time",
|
"name":"Dozenal Time",
|
||||||
"shortName":"Dozenal Time",
|
"shortName":"Dozenal Time",
|
||||||
"icon":"app.png",
|
"icon":"app.png",
|
||||||
"version":"0.01",
|
"version":"0.04",
|
||||||
"description":"A dozenal Holocene calendar and dozenal diurnal clock",
|
"description":"A dozenal Holocene calendar and dozenal diurnal clock",
|
||||||
"tags":"clock",
|
"tags":"clock",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
|
|
@ -3258,5 +3344,71 @@
|
||||||
{"name":"gbtwist.app.js","url":"app.js"},
|
{"name":"gbtwist.app.js","url":"app.js"},
|
||||||
{"name":"gbtwist.img","url":"app-icon.js","evaluate":true}
|
{"name":"gbtwist.img","url":"app-icon.js","evaluate":true}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{ "id": "thermom",
|
||||||
|
"name": "Thermometer",
|
||||||
|
"icon": "app.png",
|
||||||
|
"version":"0.02",
|
||||||
|
"description": "Displays the current temperature, updated every 20 seconds",
|
||||||
|
"tags": "tool",
|
||||||
|
"allow_emulator":true,
|
||||||
|
"storage": [
|
||||||
|
{"name":"thermom.app.js","url":"app.js"},
|
||||||
|
{"name":"thermom.img","url":"app-icon.js","evaluate":true}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ "id": "mysticdock",
|
||||||
|
"name": "Mystic Dock",
|
||||||
|
"icon": "mystic-dock.png",
|
||||||
|
"version":"1.00",
|
||||||
|
"description": "A retro-inspired dockface that displays the current time and battery charge while plugged in, and which features an interactive mode that shows the time, date, and a rotating data display line.",
|
||||||
|
"tags": "dock",
|
||||||
|
"type":"dock",
|
||||||
|
"readme": "README.md",
|
||||||
|
"storage": [
|
||||||
|
{"name":"mysticdock.app.js","url":"mystic-dock-app.js"},
|
||||||
|
{"name":"mysticdock.boot.js","url":"mystic-dock-boot.js"},
|
||||||
|
{"name":"mysticdock.settings.js","url":"mystic-dock-settings.js"},
|
||||||
|
{"name":"mysticdock.img","url":"mystic-dock-icon.js","evaluate":true}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ "id": "mysticclock",
|
||||||
|
"name": "Mystic Clock",
|
||||||
|
"icon": "mystic-clock.png",
|
||||||
|
"version":"1.01",
|
||||||
|
"description": "A retro-inspired watchface featuring time, date, and an interactive data display line.",
|
||||||
|
"tags": "clock",
|
||||||
|
"type":"clock",
|
||||||
|
"readme": "README.md",
|
||||||
|
"allow_emulator":true,
|
||||||
|
"storage": [
|
||||||
|
{"name":"mysticclock.app.js","url":"mystic-clock-app.js"},
|
||||||
|
{"name":"mysticclock.settings.js","url":"mystic-clock-settings.js"},
|
||||||
|
{"name":"mysticclock.img","url":"mystic-clock-icon.js","evaluate":true}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ "id": "hcclock",
|
||||||
|
"name": "Hi-Contrast Clock",
|
||||||
|
"icon": "hcclock-icon.png",
|
||||||
|
"version":"0.01",
|
||||||
|
"description": "Hi-Contrast Clock : A simple yet very bold clock that aims to be readable in high luninosity environments. Uses big 10x5 pixel digits. Use BTN 1 to switch background and foreground colors.",
|
||||||
|
"tags": "clock",
|
||||||
|
"type":"clock",
|
||||||
|
"allow_emulator":true,
|
||||||
|
"storage": [
|
||||||
|
{"name":"hcclock.app.js","url":"hcclock.app.js"},
|
||||||
|
{"name":"hcclock.img","url":"hcclock-icon.js","evaluate":true}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ "id": "thermomF",
|
||||||
|
"name": "Fahrenheit Temp",
|
||||||
|
"icon": "thermf.png",
|
||||||
|
"version":"0.01",
|
||||||
|
"description": "A modification of the Thermometer App to display temprature in Fahrenheit",
|
||||||
|
"tags": "tool",
|
||||||
|
"storage": [
|
||||||
|
{"name":"thermomF.app.js","url":"app.js"},
|
||||||
|
{"name":"thermomF.img","url":"app-icon.js","evaluate":true}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -37,5 +37,7 @@ g.drawString(NRF.getAddress(),g.getWidth()/2,g.getHeight()-8,true);
|
||||||
g.flip();
|
g.flip();
|
||||||
|
|
||||||
setWatch(_=>load(), BTN1);
|
setWatch(_=>load(), BTN1);
|
||||||
setWatch(_=>load(), BTN2);
|
if (global.BTN2) {
|
||||||
setWatch(_=>load(), BTN3);
|
setWatch(_=>load(), BTN2);
|
||||||
|
setWatch(_=>load(), BTN3);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,3 +9,4 @@
|
||||||
0.12: Fix regression after 0.11
|
0.12: Fix regression after 0.11
|
||||||
0.13: Fix broken date padding (fix #376)
|
0.13: Fix broken date padding (fix #376)
|
||||||
0.14: Remove hardcoded hour buzz (you can install widchime if you miss it)
|
0.14: Remove hardcoded hour buzz (you can install widchime if you miss it)
|
||||||
|
0.15: Add color scheme support
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,16 @@
|
||||||
const locale = require('locale');
|
const locale = require('locale');
|
||||||
const p = Math.PI / 2;
|
const p = Math.PI / 2;
|
||||||
const pRad = Math.PI / 180;
|
const pRad = Math.PI / 180;
|
||||||
const faceWidth = 100; // watch face radius (240/2 - 24px for widget area)
|
const faceWidth = g.getWidth()/2 - 20; // watch face radius (240/2 - 24px for widget area)
|
||||||
const widgetHeight=24+1;
|
const widgetHeight=24+1;
|
||||||
let timer = null;
|
let timer = null;
|
||||||
let currentDate = new Date();
|
let currentDate = new Date();
|
||||||
const centerX = g.getWidth() / 2;
|
const centerX = g.getWidth() / 2;
|
||||||
const centerY = (g.getWidth() / 2) + widgetHeight/2;
|
const centerY = (g.getWidth() / 2) + widgetHeight/2;
|
||||||
|
g.theme.dark=false;
|
||||||
|
let colSecA = g.theme.dark ? "#00A" : "#58F"; // before the second
|
||||||
|
let colSecB = g.theme.dark ? "#58F" : "#00A"; // after the second
|
||||||
|
let colSec1 = g.theme.dark ? "#F83" : "#000"; // ON the second
|
||||||
|
|
||||||
const seconds = (angle) => {
|
const seconds = (angle) => {
|
||||||
const a = angle * pRad;
|
const a = angle * pRad;
|
||||||
|
|
@ -46,40 +49,35 @@ const drawAll = () => {
|
||||||
// draw all secs
|
// draw all secs
|
||||||
|
|
||||||
for (let i = 0; i < 60; i++) {
|
for (let i = 0; i < 60; i++) {
|
||||||
if (i > currentSec) {
|
g.setColor((i > currentSec) ? colSecA : colSecB);
|
||||||
g.setColor(0, 0, 0.6);
|
|
||||||
} else {
|
|
||||||
g.setColor(0.3, 0.3, 1);
|
|
||||||
}
|
|
||||||
seconds((360 * i) / 60);
|
seconds((360 * i) / 60);
|
||||||
}
|
}
|
||||||
onSecond();
|
onSecond();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const resetSeconds = () => {
|
const resetSeconds = () => {
|
||||||
g.setColor(0, 0, 0.6);
|
g.setColor(colSecA);
|
||||||
for (let i = 0; i < 60; i++) {
|
for (let i = 0; i < 60; i++) {
|
||||||
seconds((360 * i) / 60);
|
seconds((360 * i) / 60);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSecond = () => {
|
const onSecond = () => {
|
||||||
g.setColor(0.3, 0.3, 1);
|
g.setColor(colSecB);
|
||||||
seconds((360 * currentDate.getSeconds()) / 60);
|
seconds((360 * currentDate.getSeconds()) / 60);
|
||||||
if (currentDate.getSeconds() === 59) {
|
if (currentDate.getSeconds() === 59) {
|
||||||
resetSeconds();
|
resetSeconds();
|
||||||
onMinute();
|
onMinute();
|
||||||
}
|
}
|
||||||
g.setColor(1, 0.7, 0.2);
|
g.setColor(colSec1);
|
||||||
currentDate = new Date();
|
currentDate = new Date();
|
||||||
seconds((360 * currentDate.getSeconds()) / 60);
|
seconds((360 * currentDate.getSeconds()) / 60);
|
||||||
g.setColor(1, 1, 1);
|
g.setColor(g.theme.fg);
|
||||||
};
|
};
|
||||||
|
|
||||||
const drawDate = () => {
|
const drawDate = () => {
|
||||||
g.reset();
|
g.reset();
|
||||||
g.setColor(1, 0, 0);
|
g.setColor("#f00");
|
||||||
g.setFont('6x8', 2);
|
g.setFont('6x8', 2);
|
||||||
|
|
||||||
const dayString = locale.dow(currentDate, true);
|
const dayString = locale.dow(currentDate, true);
|
||||||
|
|
@ -89,7 +87,7 @@ const drawDate = () => {
|
||||||
// console.log(`${dayString}|${dateString}`);
|
// console.log(`${dayString}|${dateString}`);
|
||||||
// center date
|
// center date
|
||||||
const l = (g.getWidth() - g.stringWidth(dateDisplay)) / 2;
|
const l = (g.getWidth() - g.stringWidth(dateDisplay)) / 2;
|
||||||
const t = centerY + 37;
|
const t = centerY + faceWidth*0.37;
|
||||||
g.drawString(dateDisplay, l, t, true);
|
g.drawString(dateDisplay, l, t, true);
|
||||||
// console.log(l, t);
|
// console.log(l, t);
|
||||||
};
|
};
|
||||||
|
|
@ -99,7 +97,7 @@ const onMinute = () => {
|
||||||
resetSeconds();
|
resetSeconds();
|
||||||
}
|
}
|
||||||
// clear existing hands
|
// clear existing hands
|
||||||
g.setColor(0, 0, 0);
|
g.setColor(g.theme.bg);
|
||||||
// Hour
|
// Hour
|
||||||
hand((360 * (currentDate.getHours() + currentDate.getMinutes() / 60)) / 12, -8, faceWidth - 35);
|
hand((360 * (currentDate.getHours() + currentDate.getMinutes() / 60)) / 12, -8, faceWidth - 35);
|
||||||
// Minute
|
// Minute
|
||||||
|
|
@ -107,10 +105,10 @@ const onMinute = () => {
|
||||||
|
|
||||||
// get new date, then draw new hands
|
// get new date, then draw new hands
|
||||||
currentDate = new Date();
|
currentDate = new Date();
|
||||||
g.setColor(1, 0.9, 0.9);
|
g.setColor(g.theme.fg);
|
||||||
// Hour
|
// Hour
|
||||||
hand((360 * (currentDate.getHours() + currentDate.getMinutes() / 60)) / 12, -8, faceWidth - 35);
|
hand((360 * (currentDate.getHours() + currentDate.getMinutes() / 60)) / 12, -8, faceWidth - 35);
|
||||||
g.setColor(1, 1, 0.9);
|
g.setColor(g.theme.fg);
|
||||||
// Minute
|
// Minute
|
||||||
hand((360 * currentDate.getMinutes()) / 60, -8, faceWidth - 10);
|
hand((360 * currentDate.getMinutes()) / 60, -8, faceWidth - 10);
|
||||||
drawDate();
|
drawDate();
|
||||||
|
|
@ -137,8 +135,9 @@ g.clear();
|
||||||
resetSeconds();
|
resetSeconds();
|
||||||
startTimers();
|
startTimers();
|
||||||
drawAll();
|
drawAll();
|
||||||
|
|
||||||
|
// Show launcher when button pressed
|
||||||
|
Bangle.setUI("clock");
|
||||||
|
|
||||||
Bangle.loadWidgets();
|
Bangle.loadWidgets();
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
|
|
||||||
// Show launcher when middle button pressed
|
|
||||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
0.01: New App!
|
0.01: New App!
|
||||||
0.02: Add BTN2 -> launcher
|
0.02: Add BTN2 -> launcher
|
||||||
|
0.03: Update to use setUI
|
||||||
|
|
|
||||||
|
|
@ -114,5 +114,5 @@ if (g.drawImages) {
|
||||||
E.showMessage("Please update\nBangle.js firmware\nto use this clock","analogimgclk");
|
E.showMessage("Please update\nBangle.js firmware\nto use this clock","analogimgclk");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show launcher when middle button pressed
|
// Show launcher when button pressed
|
||||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
Bangle.setUI("clock");
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
0.01: New App!
|
0.01: New App!
|
||||||
0.02: Fix bug if image clock wasn't installed
|
0.02: Fix bug if image clock wasn't installed
|
||||||
|
0.03: Update to use setUI
|
||||||
|
|
|
||||||
|
|
@ -102,5 +102,5 @@ if (g.drawImages) {
|
||||||
} else {
|
} else {
|
||||||
E.showMessage("Please update\nBangle.js firmware\nto use this clock","animclk");
|
E.showMessage("Please update\nBangle.js firmware\nto use this clock","animclk");
|
||||||
}
|
}
|
||||||
// Show launcher when middle button pressed
|
// Show launcher when button pressed
|
||||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
Bangle.setUI("clock");
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,10 @@ charge.
|
||||||
*BTN3* - invokes calibration ( can be cancelled if pressed accidentally)
|
*BTN3* - invokes calibration ( can be cancelled if pressed accidentally)
|
||||||
|
|
||||||
|
|
||||||
|
## Issues
|
||||||
|
* detect when calibration data is missing
|
||||||
|
|
||||||
## Acknowledgement
|
## Acknowledgement
|
||||||
|
|
||||||
This app is based in the work done by [jeffmer](https://github.com/jeffmer/JeffsBangleAppsDev)
|
This app is based in the work done by [jeffmer](https://github.com/jeffmer/JeffsBangleAppsDev)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
0.01: Create astral clock app
|
0.01: Create astral clock app
|
||||||
0.02: Fixed Whirlpool galaxy RA/DA, larger compass display, fixed moonphase overlapping battery widget
|
0.02: Fixed Whirlpool galaxy RA/DA, larger compass display, fixed moonphase overlapping battery widget
|
||||||
|
0.03: Update to use Bangle.setUI instead of setWatch
|
||||||
|
|
|
||||||
|
|
@ -503,8 +503,8 @@ function coord_to_horizon(utc, ra, dec, lat, lon, h) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// "mean_sidereal_time" returns the Mean Sidereal Time in units of degrees.
|
// "mean_sidereal_time" returns the Mean Sidereal Time in units of degrees.
|
||||||
// Use lon = 0 to get the Greenwich MST.
|
// Use lon = 0 to get the Greenwich MST.
|
||||||
// East longitudes are positive; West longitudes are negative
|
// East longitudes are positive; West longitudes are negative
|
||||||
//
|
//
|
||||||
// returns: time in degrees
|
// returns: time in degrees
|
||||||
|
|
@ -523,7 +523,7 @@ function mean_sidereal_time(lon) {
|
||||||
var c = Math.floor(365.25 * year);
|
var c = Math.floor(365.25 * year);
|
||||||
var da = Math.floor(30.6001 * (month + 1));
|
var da = Math.floor(30.6001 * (month + 1));
|
||||||
|
|
||||||
// days since J2000.0
|
// days since J2000.0
|
||||||
var jd = b + c + da - 730550.5 + day
|
var jd = b + c + da - 730550.5 + day
|
||||||
+ (hour + mins / 60.0 + secs / 3600.0) / 24.0;
|
+ (hour + mins / 60.0 + secs / 3600.0) / 24.0;
|
||||||
|
|
||||||
|
|
@ -796,10 +796,11 @@ Bangle.on('lcdPower', on => {
|
||||||
Bangle.setCompassPower(1);
|
Bangle.setCompassPower(1);
|
||||||
Bangle.setGPSPower(1);
|
Bangle.setGPSPower(1);
|
||||||
|
|
||||||
// Buttons
|
// Show launcher when button pressed
|
||||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
Bangle.setClockMode();
|
||||||
|
|
||||||
setWatch(function () {
|
Bangle.setUI("clockupdown", btn => {
|
||||||
|
if (btn==0) {
|
||||||
if (!processing) {
|
if (!processing) {
|
||||||
if (!modeswitch) {
|
if (!modeswitch) {
|
||||||
modeswitch = true;
|
modeswitch = true;
|
||||||
|
|
@ -809,12 +810,11 @@ setWatch(function () {
|
||||||
else
|
else
|
||||||
modeswitch = false;
|
modeswitch = false;
|
||||||
}
|
}
|
||||||
}, BTN3, { repeat: true });
|
} else {
|
||||||
|
|
||||||
setWatch(function () {
|
|
||||||
if (!processing)
|
if (!processing)
|
||||||
ready_to_compute = true;
|
ready_to_compute = true;
|
||||||
}, BTN1, { repeat: true });
|
}
|
||||||
|
});
|
||||||
|
|
||||||
setWatch(function () {
|
setWatch(function () {
|
||||||
if (!astral_settings.astral_default) {
|
if (!astral_settings.astral_default) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
Widget that allows Bangle Js to record pair and end data using Bluetooth Low Energy in combination with the BangleBridge Android App
|
||||||
|
Part of smartPPE project https://jorgepramos.github.io/Smart_PPE/index.html
|
||||||
|
|
||||||
|
# BangleBridge
|
||||||
|
|
||||||
|
Widget that allows Bangle Js to record pair and end data using Bluetooth Low Energy in combination with the BangleBridge Android App.
|
||||||
|
|
||||||
|
## Full Project
|
||||||
|
|
||||||
|
Part of smartPPE project [SmartPEE](https://jorgepramos.github.io/Smart_PPE/index.html).
|
||||||
|
After Width: | Height: | Size: 3.4 KiB |
|
|
@ -0,0 +1 @@
|
||||||
|
00堽<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><0C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><0C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><0C><><EFBFBD><EFBFBD><EFBFBD><0C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><0C><><EFBFBD><0C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><0C><><0C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><0C>??<0C><><EFBFBD><EFBFBD><EFBFBD><0C><><0C><><EFBFBD><EFBFBD><0C><><0C><><EFBFBD><EFBFBD><0C><><0C><><EFBFBD><0C><><0C><><EFBFBD>?<3F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<0C><><EFBFBD>?<3F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<0C><><EFBFBD><0C><>''''<27><><EFBFBD><0C><>''''<27><><EFBFBD><0C><>'''''<27><><EFBFBD><EFBFBD>'<27><>''''''<27><><EFBFBD><EFBFBD>'??'''''''<27><><EFBFBD><EFBFBD><EFBFBD>''''''''<27><><EFBFBD><EFBFBD><EFBFBD>''''''''<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>'''''''''<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>''''''''''<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>'''''''''''<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>''''''''''''<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>''''''''''''<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>'''''''''''''<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>'''''''''''''<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>''''''''''''''<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>''''''''''''''<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>'''''''''''''''<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>'''''''''''''''<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>''''''''''''''''<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>''''''''''''''<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>''''''''''<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>''''''''<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>''''''<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>''<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
|
@ -0,0 +1,302 @@
|
||||||
|
(() => {
|
||||||
|
/**
|
||||||
|
* Widget measurements
|
||||||
|
* Description:
|
||||||
|
* name: connection.wid.js
|
||||||
|
*icon: conectionIcon.icon
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
//Font
|
||||||
|
|
||||||
|
g.setFont("Vector", 100);
|
||||||
|
//variabangle.Sensorss
|
||||||
|
let acclS, bttS, compssS, gpsS, hrmS, stepS; //Strings
|
||||||
|
let accelN, compssN, gpsN, hrmN, stepN; //Num
|
||||||
|
let prueba = 1;
|
||||||
|
let data = [0, 0, 0, 0, 0, 0];
|
||||||
|
//Constants for redabangle.Sensors code
|
||||||
|
let storage = require('Storage');
|
||||||
|
let deCom = require('heatshrink');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Sensors code
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jorge
|
||||||
|
*/
|
||||||
|
function accel() {
|
||||||
|
|
||||||
|
Bangle.on('accel', function (acc) {
|
||||||
|
// acc = {x,y,z,diff,mag}
|
||||||
|
accelN = acc;
|
||||||
|
});
|
||||||
|
|
||||||
|
setInterval(function () {
|
||||||
|
|
||||||
|
acclS = accelN.x + "##" + accelN.y + "##" + accelN.z + "\n" + accelN.diff + "##" + accelN.mag;
|
||||||
|
data[3] = accelN;
|
||||||
|
}, 2 * 1000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function btt() {
|
||||||
|
|
||||||
|
setInterval(function () {
|
||||||
|
|
||||||
|
bttS = E.getBattery(); //return String
|
||||||
|
data[2] = E.getBattery();
|
||||||
|
}, 15 * 1000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function compss() {
|
||||||
|
|
||||||
|
Bangle.setCompassPower(1);
|
||||||
|
Bangle.on('mag', function (mag) {
|
||||||
|
// mag = {x,y,z,dx,dy,dz,heading}
|
||||||
|
compssN = mag;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
setInterval(function () {
|
||||||
|
|
||||||
|
compssS = "A: " + compssN.x + " ## " + compssN.y + " ## " + compssN.z + "\n" +
|
||||||
|
"B: " + compssN.dx + " ## " + compssN.dy + " ## " + compssN.dz + " ## " + "\n" +
|
||||||
|
"C: " + compssN.heading; //return String
|
||||||
|
data[4] = compssN;
|
||||||
|
}, 2 * 1000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function gps() {
|
||||||
|
|
||||||
|
Bangle.setGPSPower(1);
|
||||||
|
Bangle.on('GPS', function (gps) {
|
||||||
|
// gps = {lat,lon,alt,speed,etc}
|
||||||
|
gpsN = gps;
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
setInterval(function () {
|
||||||
|
|
||||||
|
gpsS = "A: " + gpsN.lat + " ## " + gpsN.lon + " ## " + gpsN.alt + "\n" + "B: " + gpsN.speed + " ## " + gpsN.course + " ## " + gpsN.time + "\n" +
|
||||||
|
"C: " + gpsN.satellites + " ## " + gpsN.fix; //return String
|
||||||
|
// work out how to display the current time
|
||||||
|
var d = new Date();
|
||||||
|
var year = d.getFullYear();
|
||||||
|
|
||||||
|
var month = d.getMonth() + 1;
|
||||||
|
var finalMonth = 0;
|
||||||
|
if (month < 10) {
|
||||||
|
finalMonth = "0" + month;
|
||||||
|
} else {
|
||||||
|
finalMonth = month;
|
||||||
|
}
|
||||||
|
var day = d.getDate();
|
||||||
|
var finalDay = 0;
|
||||||
|
if (day < 10) {
|
||||||
|
finalDay = "0" + day;
|
||||||
|
} else {
|
||||||
|
finalDay = day;
|
||||||
|
}
|
||||||
|
var h = d.getHours(),
|
||||||
|
m = d.getMinutes();
|
||||||
|
var finalh = 0;
|
||||||
|
if (h < 10) {
|
||||||
|
finalh = "0" + h;
|
||||||
|
} else {
|
||||||
|
finalh = h;
|
||||||
|
}
|
||||||
|
var finalM = 0;
|
||||||
|
if (m < 10) {
|
||||||
|
finalM = "0" + m;
|
||||||
|
} else {
|
||||||
|
finalM = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
var s = d.getSeconds();
|
||||||
|
var finalS = 0;
|
||||||
|
if (s < 10) {
|
||||||
|
finalS = "0" + s;
|
||||||
|
} else {
|
||||||
|
finalS = s;
|
||||||
|
}
|
||||||
|
var z = d.getMilliseconds();
|
||||||
|
var zFinal = new String(z);
|
||||||
|
zFinal = zFinal.replace('.', '');
|
||||||
|
var completeTime = year + "-" + finalMonth + "-" + finalDay + "T" + finalh + ":" + finalM + ":" + finalS + "." + z + "Z";
|
||||||
|
var time = h + ":" + ("0" + m).substr(-2);
|
||||||
|
gpsN.time = completeTime;
|
||||||
|
data[5] = gpsN;
|
||||||
|
}, 2 * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
//2021-06-11T19:21:58.000Z
|
||||||
|
|
||||||
|
function hrm() {
|
||||||
|
|
||||||
|
let msr = [0, 0, 0, 0, 0];
|
||||||
|
let lastInsert = -1;
|
||||||
|
|
||||||
|
function roundInsert(nueva) {
|
||||||
|
let indexFinal = (lastInsert + 1) % (msr.length);
|
||||||
|
//console.log("Index ==> "+ index);
|
||||||
|
msr[indexFinal] = nueva;
|
||||||
|
|
||||||
|
item = nueva;
|
||||||
|
lastInsert = indexFinal;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalize(nueva) {
|
||||||
|
|
||||||
|
let normalize = 0;
|
||||||
|
roundInsert(nueva);
|
||||||
|
|
||||||
|
|
||||||
|
msr.forEach(function (number) {
|
||||||
|
normalize += number;
|
||||||
|
});
|
||||||
|
normalize = normalize / msr.length;
|
||||||
|
|
||||||
|
return normalize;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
setInterval(function () {
|
||||||
|
|
||||||
|
if (!isNaN(hrmN)) {
|
||||||
|
|
||||||
|
|
||||||
|
hrmN = normalize(hrmN);
|
||||||
|
var roundedRate = parseFloat(hrmN).toFixed(2);
|
||||||
|
hrmS = String.valueOf(roundedRate); //return String
|
||||||
|
//console.log("array----->" + msr);
|
||||||
|
data[0] = roundedRate;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}, 2 * 1000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function steps() {
|
||||||
|
|
||||||
|
Bangle.on('step', s => {
|
||||||
|
|
||||||
|
stepN = s;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
setInterval(function () {
|
||||||
|
|
||||||
|
stepS = String.valueOf(stepN); //return String
|
||||||
|
data[1] = stepN;
|
||||||
|
}, 2 * 1000);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function initSensors() {
|
||||||
|
|
||||||
|
//need power control
|
||||||
|
Bangle.setHRMPower(1);
|
||||||
|
|
||||||
|
Bangle.on('HRM', function (hrm) {
|
||||||
|
hrmN = hrm.bpm;
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
console.log("Sensors are being Init....");
|
||||||
|
accel();
|
||||||
|
btt();
|
||||||
|
compss();
|
||||||
|
gps();
|
||||||
|
hrm();
|
||||||
|
steps();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var flip = 1;
|
||||||
|
Bangle.on('lcdPower', function (on) {
|
||||||
|
/*
|
||||||
|
prueba ++;
|
||||||
|
Bangle.drawWidgets();
|
||||||
|
g.setFont("Vector", 45);
|
||||||
|
g.drawString(prueba,100,200);*/
|
||||||
|
if (flip == 1) { //when off
|
||||||
|
|
||||||
|
flip = 0;
|
||||||
|
//Bangle.buzz(1000);
|
||||||
|
g.clear();
|
||||||
|
} else { //when on
|
||||||
|
|
||||||
|
flip = 1;
|
||||||
|
g.setFont("Vector", 30);
|
||||||
|
g.drawString(data[0], 65, 180);
|
||||||
|
Bangle.drawWidgets();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function draw() {
|
||||||
|
g.drawImage(storage.read("banglebridge.watch.img"),this.x + 1,this.y + 1);
|
||||||
|
g.drawImage(storage.read("banglebridge.heart.img"), 145, 167);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Finally add widget
|
||||||
|
|
||||||
|
|
||||||
|
initSensors();
|
||||||
|
// Bangle.drawWidgets();
|
||||||
|
// Terminal.println("Running BangleBridge");
|
||||||
|
data[0] = 80.5;
|
||||||
|
g.setFont("Vector", 30);
|
||||||
|
g.drawString(data[0], 65, 180);
|
||||||
|
// Bangle.drawWidgets();
|
||||||
|
setInterval(function () {
|
||||||
|
//console.log("---------------------------------------------------------------");
|
||||||
|
//console.log(data);
|
||||||
|
//Bluetooth.println(data[0]);
|
||||||
|
var measurement = {
|
||||||
|
hrm: data[0],
|
||||||
|
step: data[1],
|
||||||
|
batt: data[2],
|
||||||
|
acc: data[3],
|
||||||
|
com: data[4],
|
||||||
|
gps: data[5]
|
||||||
|
};
|
||||||
|
/* g.clear();
|
||||||
|
g.drawString(compssS,100,200);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Bluetooth.println(JSON.stringify(measurement) + "#");
|
||||||
|
//draw();
|
||||||
|
|
||||||
|
}, 5 * 1000);
|
||||||
|
|
||||||
|
WIDGETS["banglebridge"]={
|
||||||
|
area: "tl",
|
||||||
|
width: 10,
|
||||||
|
draw: draw,
|
||||||
|
};
|
||||||
|
})(); //End of Widget
|
||||||
|
After Width: | Height: | Size: 3.4 KiB |
|
|
@ -2,4 +2,6 @@
|
||||||
0.02: Apply locale, 12-hour setting
|
0.02: Apply locale, 12-hour setting
|
||||||
0.03: Fix dates drawing over each other at midnight
|
0.03: Fix dates drawing over each other at midnight
|
||||||
0.04: Small bugfix
|
0.04: Small bugfix
|
||||||
0.05: Clock does not start if app Languages is not installed
|
0.05: Clock does not start if app Languages is not installed
|
||||||
|
0.06: Improve accuracy
|
||||||
|
0.07: Update to use Bangle.setUI instead of setWatch
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
# Bar Clock
|
||||||
|
A simple digital clock showing seconds as a horizontal bar.
|
||||||
|
|
||||||
|
| 24hr style | 12hr style |
|
||||||
|
| --- | --- |
|
||||||
|
|  |  |
|
||||||
|
|
@ -2,170 +2,168 @@
|
||||||
/**
|
/**
|
||||||
* A simple digital clock showing seconds as a bar
|
* A simple digital clock showing seconds as a bar
|
||||||
**/
|
**/
|
||||||
{
|
// Check settings for what type our clock should be
|
||||||
// Check settings for what type our clock should be
|
const is12Hour = (require('Storage').readJSON('setting.json', 1) || {})['12hour']
|
||||||
const is12Hour = (require('Storage').readJSON('setting.json', 1) || {})['12hour']
|
let locale = require('locale')
|
||||||
let locale = require('locale')
|
{ // add some more info to locale
|
||||||
{ // add some more info to locale
|
let date = new Date()
|
||||||
let date = new Date()
|
date.setFullYear(1111)
|
||||||
date.setFullYear(1111)
|
date.setMonth(1, 3) // februari: months are zero-indexed
|
||||||
date.setMonth(1, 3) // februari: months are zero-indexed
|
const localized = locale.date(date, true)
|
||||||
const localized = locale.date(date, true)
|
locale.dayFirst = /3.*2/.test(localized)
|
||||||
locale.dayFirst = /3.*2/.test(localized)
|
|
||||||
|
locale.hasMeridian = false
|
||||||
locale.hasMeridian = false
|
if(typeof locale.meridian === 'function') { // function does not exists if languages app is not installed
|
||||||
if(typeof locale.meridian === 'function') { // function does not exists if languages app is not installed
|
locale.hasMeridian = (locale.meridian(date) !== '')
|
||||||
locale.hasMeridian = (locale.meridian(date) !== '')
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
const screen = {
|
|
||||||
width: g.getWidth(),
|
|
||||||
height: g.getWidth(),
|
|
||||||
middle: g.getWidth() / 2,
|
|
||||||
center: g.getHeight() / 2,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// hardcoded "settings"
|
}
|
||||||
const settings = {
|
const screen = {
|
||||||
time: {
|
width: g.getWidth(),
|
||||||
|
height: g.getWidth(),
|
||||||
|
middle: g.getWidth() / 2,
|
||||||
|
center: g.getHeight() / 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
// hardcoded "settings"
|
||||||
|
const settings = {
|
||||||
|
time: {
|
||||||
|
color: -1,
|
||||||
|
font: '6x8',
|
||||||
|
size: (is12Hour && locale.hasMeridian) ? 6 : 8,
|
||||||
|
middle: screen.middle,
|
||||||
|
center: screen.center,
|
||||||
|
ampm: {
|
||||||
color: -1,
|
color: -1,
|
||||||
font: '6x8',
|
font: '6x8',
|
||||||
size: (is12Hour && locale.hasMeridian) ? 6 : 8,
|
size: 2,
|
||||||
middle: screen.middle,
|
|
||||||
center: screen.center,
|
|
||||||
ampm: {
|
|
||||||
color: -1,
|
|
||||||
font: '6x8',
|
|
||||||
size: 2,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
date: {
|
},
|
||||||
color: -1,
|
date: {
|
||||||
font: 'Vector',
|
color: -1,
|
||||||
size: 20,
|
font: 'Vector',
|
||||||
middle: screen.height - 20, // at bottom of screen
|
size: 20,
|
||||||
center: screen.center,
|
middle: screen.height - 20, // at bottom of screen
|
||||||
},
|
center: screen.center,
|
||||||
bar: {
|
},
|
||||||
color: -1,
|
bar: {
|
||||||
top: 155, // just below time
|
color: -1,
|
||||||
thickness: 6, // matches 24h time "pixel" size
|
top: 155, // just below time
|
||||||
},
|
thickness: 6, // matches 24h time "pixel" size
|
||||||
}
|
},
|
||||||
|
|
||||||
const SECONDS_PER_MINUTE = 60
|
|
||||||
|
|
||||||
const timeText = function (date) {
|
|
||||||
if (!is12Hour) {
|
|
||||||
return locale.time(date, true)
|
|
||||||
}
|
|
||||||
const date12 = new Date(date.getTime())
|
|
||||||
const hours = date12.getHours()
|
|
||||||
if (hours === 0) {
|
|
||||||
date12.setHours(12)
|
|
||||||
} else if (hours > 12) {
|
|
||||||
date12.setHours(hours - 12)
|
|
||||||
}
|
|
||||||
return locale.time(date12, true)
|
|
||||||
}
|
|
||||||
const ampmText = function (date) {
|
|
||||||
return is12Hour ? locale.meridian(date) : ''
|
|
||||||
}
|
|
||||||
|
|
||||||
const dateText = function (date) {
|
|
||||||
const dayName = locale.dow(date, true),
|
|
||||||
month = locale.month(date, true),
|
|
||||||
day = date.getDate()
|
|
||||||
const dayMonth = locale.dayFirst ? `${day} ${month}` : `${month} ${day}`
|
|
||||||
return `${dayName} ${dayMonth}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const drawDateTime = function (date) {
|
|
||||||
const t = settings.time
|
|
||||||
g.setColor(t.color)
|
|
||||||
g.setFont(t.font, t.size)
|
|
||||||
g.setFontAlign(0, 0) // centered
|
|
||||||
g.drawString(timeText(date), t.center, t.middle, true)
|
|
||||||
if (is12Hour && locale.hasMeridian) {
|
|
||||||
const a = settings.time.ampm
|
|
||||||
g.setColor(a.color)
|
|
||||||
g.setFont(a.font, a.size)
|
|
||||||
g.setFontAlign(1, -1) // right top
|
|
||||||
// at right edge of screen, aligned with time bottom
|
|
||||||
const left = screen.width - a.size * 2,
|
|
||||||
top = t.middle + t.size - a.size
|
|
||||||
g.drawString(ampmText(date), left, top, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
const d = settings.date
|
|
||||||
g.setColor(d.color)
|
|
||||||
g.setFont(d.font, d.size)
|
|
||||||
g.setFontAlign(0, 0) // centered
|
|
||||||
g.drawString(dateText(date), d.center, d.middle, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
const drawBar = function (date) {
|
|
||||||
const b = settings.bar
|
|
||||||
const seconds = date.getSeconds()
|
|
||||||
if (seconds === 0) {
|
|
||||||
// zero-size rect stills draws one line of pixels, we don't want that
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const fraction = seconds / SECONDS_PER_MINUTE,
|
|
||||||
width = fraction * screen.width
|
|
||||||
g.setColor(b.color)
|
|
||||||
g.fillRect(0, b.top, width, b.top + b.thickness)
|
|
||||||
}
|
|
||||||
|
|
||||||
const clearScreen = function () {
|
|
||||||
g.setColor(0)
|
|
||||||
const timeTop = settings.time.middle - (settings.time.size * 4)
|
|
||||||
g.fillRect(0, timeTop, screen.width, screen.height)
|
|
||||||
}
|
|
||||||
|
|
||||||
let lastSeconds
|
|
||||||
const tick = function () {
|
|
||||||
g.reset()
|
|
||||||
const date = new Date()
|
|
||||||
const seconds = date.getSeconds()
|
|
||||||
if (lastSeconds > seconds) {
|
|
||||||
// new minute
|
|
||||||
clearScreen()
|
|
||||||
drawDateTime(date)
|
|
||||||
}
|
|
||||||
// the bar only gets larger, so drawing on top of the previous one is fine
|
|
||||||
drawBar(date)
|
|
||||||
|
|
||||||
lastSeconds = seconds
|
|
||||||
}
|
|
||||||
|
|
||||||
let iTick
|
|
||||||
const start = function () {
|
|
||||||
lastSeconds = 99 // force redraw
|
|
||||||
tick()
|
|
||||||
iTick = setInterval(tick, 1000)
|
|
||||||
}
|
|
||||||
const stop = function () {
|
|
||||||
if (iTick) {
|
|
||||||
clearInterval(iTick)
|
|
||||||
iTick = undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// clean app screen
|
|
||||||
g.clear()
|
|
||||||
Bangle.loadWidgets()
|
|
||||||
Bangle.drawWidgets()
|
|
||||||
// Show launcher when middle button pressed
|
|
||||||
setWatch(Bangle.showLauncher, BTN2, {repeat: false, edge: 'falling'})
|
|
||||||
|
|
||||||
Bangle.on('lcdPower', function (on) {
|
|
||||||
if (on) {
|
|
||||||
start()
|
|
||||||
} else {
|
|
||||||
stop()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
start()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SECONDS_PER_MINUTE = 60
|
||||||
|
|
||||||
|
const timeText = function (date) {
|
||||||
|
if (!is12Hour) {
|
||||||
|
return locale.time(date, true)
|
||||||
|
}
|
||||||
|
const date12 = new Date(date.getTime())
|
||||||
|
const hours = date12.getHours()
|
||||||
|
if (hours === 0) {
|
||||||
|
date12.setHours(12)
|
||||||
|
} else if (hours > 12) {
|
||||||
|
date12.setHours(hours - 12)
|
||||||
|
}
|
||||||
|
return locale.time(date12, true)
|
||||||
|
}
|
||||||
|
const ampmText = function (date) {
|
||||||
|
return is12Hour ? locale.meridian(date) : ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const dateText = function (date) {
|
||||||
|
const dayName = locale.dow(date, true),
|
||||||
|
month = locale.month(date, true),
|
||||||
|
day = date.getDate()
|
||||||
|
const dayMonth = locale.dayFirst ? `${day} ${month}` : `${month} ${day}`
|
||||||
|
return `${dayName} ${dayMonth}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const drawDateTime = function (date) {
|
||||||
|
const t = settings.time
|
||||||
|
g.setColor(t.color)
|
||||||
|
g.setFont(t.font, t.size)
|
||||||
|
g.setFontAlign(0, 0) // centered
|
||||||
|
g.drawString(timeText(date), t.center, t.middle, true)
|
||||||
|
if (is12Hour && locale.hasMeridian) {
|
||||||
|
const a = settings.time.ampm
|
||||||
|
g.setColor(a.color)
|
||||||
|
g.setFont(a.font, a.size)
|
||||||
|
g.setFontAlign(1, -1) // right top
|
||||||
|
// at right edge of screen, aligned with time bottom
|
||||||
|
const left = screen.width - a.size * 2,
|
||||||
|
top = t.middle + t.size - a.size
|
||||||
|
g.drawString(ampmText(date), left, top, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const d = settings.date
|
||||||
|
g.setColor(d.color)
|
||||||
|
g.setFont(d.font, d.size)
|
||||||
|
g.setFontAlign(0, 0) // centered
|
||||||
|
g.drawString(dateText(date), d.center, d.middle, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const drawBar = function (date) {
|
||||||
|
const b = settings.bar
|
||||||
|
const seconds = date.getSeconds()
|
||||||
|
if (seconds === 0) {
|
||||||
|
// zero-size rect stills draws one line of pixels, we don't want that
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const fraction = seconds / SECONDS_PER_MINUTE,
|
||||||
|
width = fraction * screen.width
|
||||||
|
g.setColor(b.color)
|
||||||
|
g.fillRect(0, b.top, width, b.top + b.thickness)
|
||||||
|
}
|
||||||
|
|
||||||
|
const clearScreen = function () {
|
||||||
|
g.setColor(0)
|
||||||
|
const timeTop = settings.time.middle - (settings.time.size * 4)
|
||||||
|
g.fillRect(0, timeTop, screen.width, screen.height)
|
||||||
|
}
|
||||||
|
|
||||||
|
let lastSeconds, tTick
|
||||||
|
const tick = function () {
|
||||||
|
g.reset()
|
||||||
|
const date = new Date()
|
||||||
|
const seconds = date.getSeconds()
|
||||||
|
if (lastSeconds > seconds) {
|
||||||
|
// new minute
|
||||||
|
clearScreen()
|
||||||
|
drawDateTime(date)
|
||||||
|
}
|
||||||
|
// the bar only gets larger, so drawing on top of the previous one is fine
|
||||||
|
drawBar(date)
|
||||||
|
lastSeconds = seconds
|
||||||
|
// schedule next update
|
||||||
|
const millis = date.getMilliseconds()
|
||||||
|
tTick = setTimeout(tick, 1000-millis)
|
||||||
|
}
|
||||||
|
|
||||||
|
const start = function () {
|
||||||
|
lastSeconds = 99 // force redraw
|
||||||
|
tick()
|
||||||
|
}
|
||||||
|
const stop = function () {
|
||||||
|
if (tTick) {
|
||||||
|
clearTimeout(tTick)
|
||||||
|
tTick = undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean app screen
|
||||||
|
g.clear()
|
||||||
|
Bangle.loadWidgets()
|
||||||
|
Bangle.drawWidgets()
|
||||||
|
// Show launcher when button pressed
|
||||||
|
Bangle.setUI("clock");
|
||||||
|
|
||||||
|
Bangle.on('lcdPower', function (on) {
|
||||||
|
if (on) {
|
||||||
|
start()
|
||||||
|
} else {
|
||||||
|
stop()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
start()
|
||||||
|
|
|
||||||
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
|
@ -1 +1,2 @@
|
||||||
0.01: App Created!
|
0.01: App Created!
|
||||||
|
0.02: Update to use Bangle.setUI instead of setWatch
|
||||||
|
|
|
||||||
|
|
@ -256,8 +256,5 @@ Bangle.drawWidgets();
|
||||||
timeInterval = setInterval(showTime, 1000);
|
timeInterval = setInterval(showTime, 1000);
|
||||||
showTime();
|
showTime();
|
||||||
|
|
||||||
// Show launcher when middle button pressed
|
// Show launcher when button pressed
|
||||||
setWatch(Bangle.showLauncher, BTN2, {
|
Bangle.setUI("clock");
|
||||||
repeat: false,
|
|
||||||
edge: "falling"
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
0.02: Modified for use with new bootloader and firmware
|
0.02: Modified for use with new bootloader and firmware
|
||||||
|
0.03: Update to use Bangle.setUI instead of setWatch
|
||||||
|
|
|
||||||
|
|
@ -105,5 +105,5 @@ Bangle.loadWidgets();
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
setInterval(() => { drawClock(); }, 1000);
|
setInterval(() => { drawClock(); }, 1000);
|
||||||
drawClock();
|
drawClock();
|
||||||
// Show launcher when middle button pressed
|
// Show launcher when button pressed
|
||||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
Bangle.setUI("clock");
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
0.01: Initial commit. Not very efficient, and widgets not working for some reason.
|
0.01: Initial commit. Not very efficient, and widgets not working for some reason.
|
||||||
0.02: Fixes; widget support
|
0.02: Fixes; widget support
|
||||||
0.03: Remove hardcoded hour buzz (you can install widchime if you miss it)
|
0.03: Remove hardcoded hour buzz (you can install widchime if you miss it)
|
||||||
|
0.04: Update to use Bangle.setUI instead of setWatch
|
||||||
|
|
|
||||||
|
|
@ -51,341 +51,332 @@ Graphics.prototype.drawRotLine = function (sina, cosa, cx, cy, r1, r2) {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Display modes
|
||||||
|
//
|
||||||
|
// 0: full-screen
|
||||||
|
// 1: with widgets
|
||||||
|
// 2: centred on Bangle (v.1), no widgets or time/date
|
||||||
|
// 3: centred with time above
|
||||||
|
// 4: centred with date above
|
||||||
|
// 5: centred with time and date above
|
||||||
|
let mode;
|
||||||
|
|
||||||
(function(g) {
|
// R1, R2: Outer and inner radii of hour marks
|
||||||
// Display modes
|
// RC1, RC2: Outer and inner radii of hub
|
||||||
//
|
// CX, CY: Centre location, relative to buffer (not screen, necessarily)
|
||||||
// 0: full-screen
|
// HW2, MW2: Half-width of hour and minute hand
|
||||||
// 1: with widgets
|
// HR, MR: Length of hour and minute hand, relative to CX,CY
|
||||||
// 2: centred on Bangle (v.1), no widgets or time/date
|
// M: Half-width of gap in hour marks
|
||||||
// 3: centred with time above
|
// HSCALE: Half-width of hour mark as function(0<h<13)
|
||||||
// 4: centred with date above
|
let R1, R2, RC1, RC2, CX, CY, HW2, MW2, HR, MR, M, HSCALE;
|
||||||
// 5: centred with time and date above
|
|
||||||
let mode;
|
|
||||||
|
|
||||||
// R1, R2: Outer and inner radii of hour marks
|
// Screen size
|
||||||
// RC1, RC2: Outer and inner radii of hub
|
const GW = g.getWidth();
|
||||||
// CX, CY: Centre location, relative to buffer (not screen, necessarily)
|
const GH = g.getHeight();
|
||||||
// HW2, MW2: Half-width of hour and minute hand
|
|
||||||
// HR, MR: Length of hour and minute hand, relative to CX,CY
|
|
||||||
// M: Half-width of gap in hour marks
|
|
||||||
// HSCALE: Half-width of hour mark as function(0<h<13)
|
|
||||||
let R1, R2, RC1, RC2, CX, CY, HW2, MW2, HR, MR, M, HSCALE;
|
|
||||||
|
|
||||||
// Screen size
|
// Top margin: the gap taken from the top of the buffer, except when
|
||||||
const GW = g.getWidth();
|
// in mode 0 (full screen)
|
||||||
const GH = g.getHeight();
|
let TM;
|
||||||
|
|
||||||
// Top margin: the gap taken from the top of the buffer, except when
|
// Buffer image. undefined means it needs regenerating
|
||||||
// in mode 0 (full screen)
|
let faceImg;
|
||||||
let TM;
|
|
||||||
|
|
||||||
// Buffer image. undefined means it needs regenerating
|
// with_seconds flag determines whether the face is updated every
|
||||||
let faceImg;
|
// second or every minute, and to draw the hand or not.
|
||||||
|
let with_seconds = true;
|
||||||
|
|
||||||
// with_seconds flag determines whether the face is updated every
|
// Display flags, determined from `mode` by setMode()
|
||||||
// second or every minute, and to draw the hand or not.
|
let with_widgets = false;
|
||||||
let with_seconds = true;
|
let with_digital_time = true;
|
||||||
|
let with_digital_date = true;
|
||||||
|
|
||||||
// Display flags, determined from `mode` by setMode()
|
// Create offscreen buffer for the once-per-minute face draw
|
||||||
let with_widgets = false;
|
const G1 = Graphics.createArrayBuffer(g.getWidth(), g.getHeight(), 1, {msb:true});
|
||||||
let with_digital_time = true;
|
|
||||||
let with_digital_date = true;
|
|
||||||
|
|
||||||
// Create offscreen buffer for the once-per-minute face draw
|
// Precalculate sin/cos for the hour marks. Might be premature
|
||||||
const G1 = Graphics.createArrayBuffer(g.getWidth(), g.getHeight(), 1, {msb:true});
|
// optimisation, but might as well.
|
||||||
|
let ss = [], cs = [];
|
||||||
|
for (let h=1; h<=12; h++) {
|
||||||
|
const a = Math.PI * h / 6;
|
||||||
|
ss[h] = Math.sin(a);
|
||||||
|
cs[h] = Math.cos(a);
|
||||||
|
}
|
||||||
|
|
||||||
// Precalculate sin/cos for the hour marks. Might be premature
|
// Draw the face with hour and minute hand. Ideally, we'd separate
|
||||||
// optimisation, but might as well.
|
// the face from the hands and double-buffer, but memory is limited,
|
||||||
let ss = [], cs = [];
|
// so we buffer once and minute, and draw the second hand dynamically
|
||||||
|
// (with a bit of flicker)
|
||||||
|
const drawFace = (G) => {
|
||||||
|
const fw = R1 * 2;
|
||||||
|
const fh = R1 * 2;
|
||||||
|
const fw2 = R1;
|
||||||
|
const fh2 = R1;
|
||||||
|
let hs = [];
|
||||||
|
|
||||||
|
// Wipe the image and start with white
|
||||||
|
G.clear();
|
||||||
|
G.setColor(1,1,1);
|
||||||
|
|
||||||
|
// Draw the hour marks.
|
||||||
for (let h=1; h<=12; h++) {
|
for (let h=1; h<=12; h++) {
|
||||||
const a = Math.PI * h / 6;
|
hs[h] = HSCALE(h);
|
||||||
ss[h] = Math.sin(a);
|
G.fillRotRect(ss[h], cs[h], CX, CY, -hs[h], hs[h], R2, R1);
|
||||||
cs[h] = Math.cos(a);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the face with hour and minute hand. Ideally, we'd separate
|
// Draw the hub
|
||||||
// the face from the hands and double-buffer, but memory is limited,
|
G.fillCircle(CX, CY, RC1);
|
||||||
// so we buffer once and minute, and draw the second hand dynamically
|
|
||||||
// (with a bit of flicker)
|
|
||||||
const drawFace = (G) => {
|
|
||||||
const fw = R1 * 2;
|
|
||||||
const fh = R1 * 2;
|
|
||||||
const fw2 = R1;
|
|
||||||
const fh2 = R1;
|
|
||||||
let hs = [];
|
|
||||||
|
|
||||||
// Wipe the image and start with white
|
// Black
|
||||||
G.clear();
|
G.setColor(0,0,0);
|
||||||
G.setColor(1,1,1);
|
|
||||||
|
|
||||||
// Draw the hour marks.
|
// Clear the centre of the hub
|
||||||
for (let h=1; h<=12; h++) {
|
G.fillCircle(CX, CY, RC2);
|
||||||
hs[h] = HSCALE(h);
|
|
||||||
G.fillRotRect(ss[h], cs[h], CX, CY, -hs[h], hs[h], R2, R1);
|
|
||||||
|
|
||||||
|
// Draw the gap in the hour marks
|
||||||
|
for (let h=1; h<=12; h++) {
|
||||||
|
G.fillRotRect(ss[h], cs[h], CX, CY, -M, M, R2-1, R1+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Back to white for future draw operations
|
||||||
|
G.setColor(1,1,1);
|
||||||
|
|
||||||
|
// While the buffer remains full-screen, we may trim out the
|
||||||
|
// bottom of the image so we can shift the whole thing down for
|
||||||
|
// widgets.
|
||||||
|
const img = {width:GW,height:GH-TM,buffer:G.buffer};
|
||||||
|
return img;
|
||||||
|
};
|
||||||
|
|
||||||
|
let hours, minutes, seconds, date;
|
||||||
|
|
||||||
|
// Schedule event for calling at the start of the next second
|
||||||
|
const inOneSecond = (cb) => {
|
||||||
|
let now = new Date();
|
||||||
|
clearTimeout();
|
||||||
|
setTimeout(cb, 1000 - now.getMilliseconds());
|
||||||
|
};
|
||||||
|
|
||||||
|
// Schedule event for calling at the start of the next minute
|
||||||
|
const inOneMinute = (cb) => {
|
||||||
|
let now = new Date();
|
||||||
|
clearTimeout();
|
||||||
|
setTimeout(cb, 60000 - (now.getSeconds() * 1000 + now.getMilliseconds()));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Draw a fat hour/minute hand
|
||||||
|
const drawHand = (G, a, w2, r1, r2) =>
|
||||||
|
G.fillRotRect(Math.sin(a), Math.cos(a), CX, CY, -w2, w2, r1, r2);
|
||||||
|
|
||||||
|
// Redraw function
|
||||||
|
const drawAll = (force) => {
|
||||||
|
let now = new Date();
|
||||||
|
|
||||||
|
if (!faceImg) force = true;
|
||||||
|
|
||||||
|
let face_changed = force;
|
||||||
|
let date_changed = false;
|
||||||
|
|
||||||
|
tmp = hours;
|
||||||
|
hours = now.getHours();
|
||||||
|
if (tmp !== hours)
|
||||||
|
face_changed = true;
|
||||||
|
|
||||||
|
tmp = minutes;
|
||||||
|
minutes = now.getMinutes();
|
||||||
|
if (tmp !== minutes)
|
||||||
|
face_changed = true;
|
||||||
|
|
||||||
|
// If the face has been updated and/or needs a redraw,
|
||||||
|
// face_changed is true.
|
||||||
|
|
||||||
|
let time_changed = face_changed;
|
||||||
|
|
||||||
|
// If the screen needs an update, regardless of whether the face
|
||||||
|
// needs a redraw, time_changed is true.
|
||||||
|
|
||||||
|
if (with_seconds) {
|
||||||
|
// If we're going by second, we always need an update.
|
||||||
|
seconds = now.getSeconds();
|
||||||
|
time_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (with_digital_date) {
|
||||||
|
// See if the date has changed. If it has, then we need a
|
||||||
|
// full-blown redraw of the screen and the face, plus text.
|
||||||
|
tmp = date;
|
||||||
|
date = now.getDate();
|
||||||
|
if (tmp !== date) {
|
||||||
|
date_changed = true;
|
||||||
|
face_changed = true; // Should have changed anyway with hour/minute rollover
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (face_changed) {
|
||||||
|
// Redraw the face and hands onto the buffer G1.
|
||||||
|
faceImg = drawFace(G1);
|
||||||
|
drawHand(G1, Math.PI*hours/6, HW2, RC1, HR);
|
||||||
|
drawHand(G1, Math.PI*minutes/30, MW2, RC1, MR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Has the time updated? If so, we'll need to draw something.
|
||||||
|
if (time_changed) {
|
||||||
|
|
||||||
|
// Are we adding text?
|
||||||
|
if (with_digital_date || with_digital_time) {
|
||||||
|
|
||||||
|
// Construct the date/time text to add above the face
|
||||||
|
let d = now.toString();
|
||||||
|
let da = d.toString().split(" ");
|
||||||
|
let txt;
|
||||||
|
|
||||||
|
if (with_digital_time) {
|
||||||
|
txt = da[4].substr(0, 5);
|
||||||
|
if (with_digital_date)
|
||||||
|
G1.drawStringDH(txt+',', 24, 0, 'L', GW);
|
||||||
|
else
|
||||||
|
G1.drawStringDH(txt, 0, 0, 'C', GW);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (with_digital_date) {
|
||||||
|
let txt = [da[0], da[1], da[2]].join(" ");
|
||||||
|
if (with_digital_time)
|
||||||
|
G1.drawStringDH(txt, -24, 0, 'R', GW);
|
||||||
|
else
|
||||||
|
G1.drawStringDH(txt, 0, 0, 'C', GW);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the hub
|
// If the time has updated, we need to _at least_ draw the
|
||||||
G.fillCircle(CX, CY, RC1);
|
// image to the screen.
|
||||||
|
g.setColor(1,1,1);
|
||||||
// Black
|
g.drawImage({width:GW,
|
||||||
G.setColor(0,0,0);
|
height:GH-TM,
|
||||||
|
buffer:G1.buffer}, 0, TM);
|
||||||
// Clear the centre of the hub
|
|
||||||
G.fillCircle(CX, CY, RC2);
|
|
||||||
|
|
||||||
// Draw the gap in the hour marks
|
|
||||||
for (let h=1; h<=12; h++) {
|
|
||||||
G.fillRotRect(ss[h], cs[h], CX, CY, -M, M, R2-1, R1+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Back to white for future draw operations
|
|
||||||
G.setColor(1,1,1);
|
|
||||||
|
|
||||||
// While the buffer remains full-screen, we may trim out the
|
|
||||||
// bottom of the image so we can shift the whole thing down for
|
|
||||||
// widgets.
|
|
||||||
const img = {width:GW,height:GH-TM,buffer:G.buffer};
|
|
||||||
return img;
|
|
||||||
};
|
|
||||||
|
|
||||||
let hours, minutes, seconds, date;
|
|
||||||
|
|
||||||
// Schedule event for calling at the start of the next second
|
|
||||||
const inOneSecond = (cb) => {
|
|
||||||
let now = new Date();
|
|
||||||
clearTimeout();
|
|
||||||
setTimeout(cb, 1000 - now.getMilliseconds());
|
|
||||||
};
|
|
||||||
|
|
||||||
// Schedule event for calling at the start of the next minute
|
|
||||||
const inOneMinute = (cb) => {
|
|
||||||
let now = new Date();
|
|
||||||
clearTimeout();
|
|
||||||
setTimeout(cb, 60000 - (now.getSeconds() * 1000 + now.getMilliseconds()));
|
|
||||||
};
|
|
||||||
|
|
||||||
// Draw a fat hour/minute hand
|
|
||||||
const drawHand = (G, a, w2, r1, r2) =>
|
|
||||||
G.fillRotRect(Math.sin(a), Math.cos(a), CX, CY, -w2, w2, r1, r2);
|
|
||||||
|
|
||||||
// Redraw function
|
|
||||||
const drawAll = (force) => {
|
|
||||||
let now = new Date();
|
|
||||||
|
|
||||||
if (!faceImg) force = true;
|
|
||||||
|
|
||||||
let face_changed = force;
|
|
||||||
let date_changed = false;
|
|
||||||
|
|
||||||
tmp = hours;
|
|
||||||
hours = now.getHours();
|
|
||||||
if (tmp !== hours)
|
|
||||||
face_changed = true;
|
|
||||||
|
|
||||||
tmp = minutes;
|
|
||||||
minutes = now.getMinutes();
|
|
||||||
if (tmp !== minutes)
|
|
||||||
face_changed = true;
|
|
||||||
|
|
||||||
// If the face has been updated and/or needs a redraw,
|
|
||||||
// face_changed is true.
|
|
||||||
|
|
||||||
let time_changed = face_changed;
|
|
||||||
|
|
||||||
// If the screen needs an update, regardless of whether the face
|
|
||||||
// needs a redraw, time_changed is true.
|
|
||||||
|
|
||||||
|
// and possibly add the second hand
|
||||||
if (with_seconds) {
|
if (with_seconds) {
|
||||||
// If we're going by second, we always need an update.
|
let a = 2.0 * Math.PI * seconds / 60.0;
|
||||||
seconds = now.getSeconds();
|
g.drawRotLine(Math.sin(a), Math.cos(a), CX, CY+TM, RC1, R1);
|
||||||
time_changed = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (with_digital_date) {
|
// And draw widgets if we're in that mode
|
||||||
// See if the date has changed. If it has, then we need a
|
if (with_widgets)
|
||||||
// full-blown redraw of the screen and the face, plus text.
|
Bangle.drawWidgets();
|
||||||
tmp = date;
|
}
|
||||||
date = now.getDate();
|
|
||||||
if (tmp !== date) {
|
|
||||||
date_changed = true;
|
|
||||||
face_changed = true; // Should have changed anyway with hour/minute rollover
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (face_changed) {
|
// Schedule to repeat this. A `setTimeout(1000)` isn't good
|
||||||
// Redraw the face and hands onto the buffer G1.
|
// enough, as all the above might've taken some milliseconds and
|
||||||
faceImg = drawFace(G1);
|
// we don't want to drift.
|
||||||
drawHand(G1, Math.PI*hours/6, HW2, RC1, HR);
|
if (with_seconds)
|
||||||
drawHand(G1, Math.PI*minutes/30, MW2, RC1, MR);
|
inOneSecond(drawAll);
|
||||||
}
|
else
|
||||||
|
inOneMinute(drawAll);
|
||||||
|
};
|
||||||
|
|
||||||
// Has the time updated? If so, we'll need to draw something.
|
const setButtons = () => {
|
||||||
if (time_changed) {
|
// Show launcher when button pressed
|
||||||
|
Bangle.setUI("clockupdown", btn=> {
|
||||||
|
if (btn==0) changeSeconds();
|
||||||
|
if (btn==1) { ++mode; setMode(); drawAll(true); }
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Are we adding text?
|
// Load display parameters based on `mode`
|
||||||
if (with_digital_date || with_digital_time) {
|
const setMode = () => {
|
||||||
|
// Normalize mode to 0 <= mode <= 5
|
||||||
|
mode = (6+mode) % 6;
|
||||||
|
|
||||||
// Construct the date/time text to add above the face
|
// [R1, R2, RC1, RC2, HW2, MW3, HR, MR, M, HSCALE] =
|
||||||
let d = now.toString();
|
const scales = [
|
||||||
let da = d.toString().split(" ");
|
[120, 84, 17, 12.4, 4.6, 2.2, 8, 2, 1, h => (3.0 + Math.ceil(h/1.5)) ],
|
||||||
let txt;
|
[102, 70, 14.6, 10.7, 3.88, 1.8, 8, 2, 1, h => (2.4 + Math.ceil(h/1.6)) ],
|
||||||
|
];
|
||||||
|
|
||||||
if (with_digital_time) {
|
if (mode < 3) {
|
||||||
txt = da[4].substr(0, 5);
|
// Face without time/date text. Might have widgets though.
|
||||||
if (with_digital_date)
|
with_digital_time = with_digital_date = false;
|
||||||
G1.drawStringDH(txt+',', 24, 0, 'L', GW);
|
with_widgets = (mode == 1);
|
||||||
else
|
}
|
||||||
G1.drawStringDH(txt, 0, 0, 'C', GW);
|
else {
|
||||||
}
|
// Face with time/date text, but no widgets
|
||||||
|
with_digital_time = (mode-2)&1;
|
||||||
|
with_digital_date = (mode-2)&2;
|
||||||
|
with_widgets = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (with_digital_date) {
|
// Destructure the array to the global display parameters
|
||||||
let txt = [da[0], da[1], da[2]].join(" ");
|
let arr = scales[mode > 0 ? 1 : 0];
|
||||||
if (with_digital_time)
|
R1 = arr[0];
|
||||||
G1.drawStringDH(txt, -24, 0, 'R', GW);
|
R2 = arr[1];
|
||||||
else
|
RC1 = arr[2];
|
||||||
G1.drawStringDH(txt, 0, 0, 'C', GW);
|
RC2 = arr[3];
|
||||||
}
|
HW2 = arr[4];
|
||||||
}
|
MW2 = arr[5];
|
||||||
|
HR = R2 - arr[6];
|
||||||
|
MR = R1 - arr[7];
|
||||||
|
M = arr[8];
|
||||||
|
HSCALE = arr[9];
|
||||||
|
TM = with_widgets ? 36 : 0;
|
||||||
|
|
||||||
// If the time has updated, we need to _at least_ draw the
|
CX = GW/2;
|
||||||
// image to the screen.
|
CY = R1;
|
||||||
g.setColor(1,1,1);
|
|
||||||
g.drawImage({width:GW,
|
|
||||||
height:GH-TM,
|
|
||||||
buffer:G1.buffer}, 0, TM);
|
|
||||||
|
|
||||||
// and possibly add the second hand
|
// If we're in the small-face + text regime, we're going to buffer
|
||||||
if (with_seconds) {
|
// the full screen but draw the clock face further down to give
|
||||||
let a = 2.0 * Math.PI * seconds / 60.0;
|
// space for the text.
|
||||||
g.drawRotLine(Math.sin(a), Math.cos(a), CX, CY+TM, RC1, R1);
|
//
|
||||||
}
|
// Compare with modes 0 (full-screen) and 1 (with_widgets==true)
|
||||||
|
// where the face is drawn at the top of the buffer, but drawn
|
||||||
|
// lower down the screen (so CY doesn't move)
|
||||||
|
if (mode > 1) {
|
||||||
|
CY += 36;
|
||||||
|
}
|
||||||
|
|
||||||
// And draw widgets if we're in that mode
|
// We only don't bother redrawing the face from modes 2 to 5, as
|
||||||
if (with_widgets)
|
// they're the same.
|
||||||
Bangle.drawWidgets();
|
if (!faceImg || mode<3) {
|
||||||
}
|
faceImg = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
// Schedule to repeat this. A `setTimeout(1000)` isn't good
|
// Store the settings for next time
|
||||||
// enough, as all the above might've taken some milliseconds and
|
|
||||||
// we don't want to drift.
|
|
||||||
if (with_seconds)
|
|
||||||
inOneSecond(drawAll);
|
|
||||||
else
|
|
||||||
inOneMinute(drawAll);
|
|
||||||
};
|
|
||||||
|
|
||||||
const setButtons = () => {
|
|
||||||
const opts = { repeat: true, edge:'rising', debounce:30};
|
|
||||||
|
|
||||||
// BTN1: enable/disable second hand
|
|
||||||
setWatch(changeSeconds, BTN1, opts);
|
|
||||||
|
|
||||||
// BTN2: return to launcher
|
|
||||||
setWatch(Bangle.showLauncher, BTN2, { repeat:false, edge:'falling' });
|
|
||||||
|
|
||||||
// BTN3: change display mode
|
|
||||||
setWatch(function () { ++mode; setMode(); drawAll(true); }, BTN3, opts);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Load display parameters based on `mode`
|
|
||||||
const setMode = () => {
|
|
||||||
// Normalize mode to 0 <= mode <= 5
|
|
||||||
mode = (6+mode) % 6;
|
|
||||||
|
|
||||||
// [R1, R2, RC1, RC2, HW2, MW3, HR, MR, M, HSCALE] =
|
|
||||||
const scales = [
|
|
||||||
[120, 84, 17, 12.4, 4.6, 2.2, 8, 2, 1, h => (3.0 + Math.ceil(h/1.5)) ],
|
|
||||||
[102, 70, 14.6, 10.7, 3.88, 1.8, 8, 2, 1, h => (2.4 + Math.ceil(h/1.6)) ],
|
|
||||||
];
|
|
||||||
|
|
||||||
if (mode < 3) {
|
|
||||||
// Face without time/date text. Might have widgets though.
|
|
||||||
with_digital_time = with_digital_date = false;
|
|
||||||
with_widgets = (mode == 1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Face with time/date text, but no widgets
|
|
||||||
with_digital_time = (mode-2)&1;
|
|
||||||
with_digital_date = (mode-2)&2;
|
|
||||||
with_widgets = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destructure the array to the global display parameters
|
|
||||||
let arr = scales[mode > 0 ? 1 : 0];
|
|
||||||
R1 = arr[0];
|
|
||||||
R2 = arr[1];
|
|
||||||
RC1 = arr[2];
|
|
||||||
RC2 = arr[3];
|
|
||||||
HW2 = arr[4];
|
|
||||||
MW2 = arr[5];
|
|
||||||
HR = R2 - arr[6];
|
|
||||||
MR = R1 - arr[7];
|
|
||||||
M = arr[8];
|
|
||||||
HSCALE = arr[9];
|
|
||||||
TM = with_widgets ? 36 : 0;
|
|
||||||
|
|
||||||
CX = GW/2;
|
|
||||||
CY = R1;
|
|
||||||
|
|
||||||
// If we're in the small-face + text regime, we're going to buffer
|
|
||||||
// the full screen but draw the clock face further down to give
|
|
||||||
// space for the text.
|
|
||||||
//
|
|
||||||
// Compare with modes 0 (full-screen) and 1 (with_widgets==true)
|
|
||||||
// where the face is drawn at the top of the buffer, but drawn
|
|
||||||
// lower down the screen (so CY doesn't move)
|
|
||||||
if (mode > 1) {
|
|
||||||
CY += 36;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We only don't bother redrawing the face from modes 2 to 5, as
|
|
||||||
// they're the same.
|
|
||||||
if (!faceImg || mode<3) {
|
|
||||||
faceImg = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store the settings for next time
|
|
||||||
try {
|
|
||||||
storage.writeJSON(filename, [mode,with_seconds]);
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear the screen: we need to make sure all parts are cleaned off.
|
|
||||||
g.clear();
|
|
||||||
};
|
|
||||||
|
|
||||||
const changeSeconds = () => {
|
|
||||||
with_seconds = !with_seconds;
|
|
||||||
drawAll(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
Bangle.loadWidgets();
|
|
||||||
|
|
||||||
// Restore mode
|
|
||||||
try {
|
try {
|
||||||
conf = storage.readJSON(filename);
|
storage.writeJSON(filename, [mode,with_seconds]);
|
||||||
mode = conf[0];
|
|
||||||
with_seconds = conf[1];
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
mode = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setButtons();
|
// Clear the screen: we need to make sure all parts are cleaned off.
|
||||||
setMode();
|
g.clear();
|
||||||
drawAll();
|
};
|
||||||
|
|
||||||
Bangle.on('lcdPower', (on) => {
|
const changeSeconds = () => {
|
||||||
if (on) {
|
with_seconds = !with_seconds;
|
||||||
Bangle.loadWidgets();
|
drawAll(true);
|
||||||
Bangle.drawWidgets();
|
};
|
||||||
drawAll();
|
|
||||||
} else {
|
|
||||||
clearTimeout();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
})(g);
|
Bangle.loadWidgets();
|
||||||
|
|
||||||
|
// Restore mode
|
||||||
|
try {
|
||||||
|
conf = storage.readJSON(filename);
|
||||||
|
mode = conf[0];
|
||||||
|
with_seconds = conf[1];
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
mode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
setButtons();
|
||||||
|
setMode();
|
||||||
|
drawAll();
|
||||||
|
|
||||||
|
Bangle.on('lcdPower', (on) => {
|
||||||
|
if (on) {
|
||||||
|
Bangle.loadWidgets();
|
||||||
|
Bangle.drawWidgets();
|
||||||
|
drawAll();
|
||||||
|
} else {
|
||||||
|
clearTimeout();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
0.02: Modified for use with new bootloader and firmware
|
0.02: Modified for use with new bootloader and firmware
|
||||||
0.03: Shrinked size to avoid cut-off edges on the physical device. BTN3: show date. BTN1: show time in decimal.
|
0.03: Shrinked size to avoid cut-off edges on the physical device. BTN3: show date. BTN1: show time in decimal.
|
||||||
|
0.04: Update to use Bangle.setUI instead of setWatch
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ time_digit = [];
|
||||||
function drawBerlinClock() {
|
function drawBerlinClock() {
|
||||||
g.clear();
|
g.clear();
|
||||||
var now = new Date();
|
var now = new Date();
|
||||||
|
|
||||||
// show date below the clock
|
// show date below the clock
|
||||||
if (show_date) {
|
if (show_date) {
|
||||||
var yr = now.getFullYear();
|
var yr = now.getFullYear();
|
||||||
|
|
@ -28,7 +28,7 @@ function drawBerlinClock() {
|
||||||
g.setFontAlign(-1,-1);
|
g.setFontAlign(-1,-1);
|
||||||
g.drawString(dateString, ( g.getWidth() - strWidth ) / 2, height + offset + 4);
|
g.drawString(dateString, ( g.getWidth() - strWidth ) / 2, height + offset + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
rowlights[0] = Math.floor(now.getHours() / 5);
|
rowlights[0] = Math.floor(now.getHours() / 5);
|
||||||
rowlights[1] = now.getHours() % 5;
|
rowlights[1] = now.getHours() % 5;
|
||||||
rowlights[2] = Math.floor(now.getMinutes() / 5);
|
rowlights[2] = Math.floor(now.getMinutes() / 5);
|
||||||
|
|
@ -62,7 +62,7 @@ function drawBerlinClock() {
|
||||||
} else {
|
} else {
|
||||||
g.setColor(1, 0, 0);
|
g.setColor(1, 0, 0);
|
||||||
}
|
}
|
||||||
g.fillRect(x1 + 2, y1 + 2, x2 - 2, y2 - 2);
|
g.fillRect(x1 + 2, y1 + 2, x2 - 2, y2 - 2);
|
||||||
}
|
}
|
||||||
if (row == 3 && show_time) {
|
if (row == 3 && show_time) {
|
||||||
g.setColor(1,1,1);
|
g.setColor(1,1,1);
|
||||||
|
|
@ -100,9 +100,11 @@ g.clear();
|
||||||
Bangle.loadWidgets();
|
Bangle.loadWidgets();
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
drawBerlinClock();
|
drawBerlinClock();
|
||||||
// Toggle date display, when BTN3 is pressed
|
if (BTN3) {
|
||||||
setWatch(toggleTime,BTN1, { repeat : true, edge: "falling"});
|
// Toggle date display, when BTN3 is pressed
|
||||||
// Toggle date display, when BTN3 is pressed
|
setWatch(toggleTime,BTN1, { repeat : true, edge: "falling"});
|
||||||
setWatch(toggleDate,BTN3, { repeat : true, edge: "falling"});
|
// Toggle date display, when BTN3 is pressed
|
||||||
// Show launcher when middle button pressed
|
setWatch(toggleDate,BTN3, { repeat : true, edge: "falling"});
|
||||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
}
|
||||||
|
// Show launcher when button pressed
|
||||||
|
Bangle.setUI("clock");
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
0.01: New App!
|
0.01: New App!
|
||||||
0.02: Fixed bug where screen didn't clear so incorrect time displayed.
|
0.02: Fixed bug where screen didn't clear so incorrect time displayed.
|
||||||
|
0.03: Update to use Bangle.setUI instead of setWatch
|
||||||
|
|
|
||||||
|
|
@ -23,17 +23,17 @@ function drawTime(d) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateHourArray(hours){
|
function updateHourArray(hours){
|
||||||
|
|
||||||
var j;
|
var j;
|
||||||
for(j=0;j<hourLED.length;j++){
|
for(j=0;j<hourLED.length;j++){
|
||||||
prevHour[j] = hourLED[j];
|
prevHour[j] = hourLED[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
var i;
|
var i;
|
||||||
for(i = 0;i < hourLED.length;i++){
|
for(i = 0;i < hourLED.length;i++){
|
||||||
hourLED[i]=0;
|
hourLED[i]=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hours > 15){
|
if(hours > 15){
|
||||||
hourLED[0] = 1;
|
hourLED[0] = 1;
|
||||||
hours = hours - 16;
|
hours = hours - 16;
|
||||||
|
|
@ -53,9 +53,9 @@ function updateHourArray(hours){
|
||||||
if(hours > 0){
|
if(hours > 0){
|
||||||
hourLED[4] = 1;
|
hourLED[4] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return hourLED;
|
return hourLED;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateMinuteArray(minutes){
|
function updateMinuteArray(minutes){
|
||||||
|
|
@ -63,12 +63,12 @@ function updateMinuteArray(minutes){
|
||||||
for(j=0;j<minuteLED.length;j++){
|
for(j=0;j<minuteLED.length;j++){
|
||||||
prevMinute[j] = minuteLED[j];
|
prevMinute[j] = minuteLED[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
var i;
|
var i;
|
||||||
for(i = 0;i < minuteLED.length;i++){
|
for(i = 0;i < minuteLED.length;i++){
|
||||||
minuteLED[i]=0;
|
minuteLED[i]=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(minutes > 31){
|
if(minutes > 31){
|
||||||
minuteLED[0] = 1;
|
minuteLED[0] = 1;
|
||||||
minutes = minutes - 32;
|
minutes = minutes - 32;
|
||||||
|
|
@ -92,20 +92,20 @@ function updateMinuteArray(minutes){
|
||||||
if(minutes > 0){
|
if(minutes > 0){
|
||||||
minuteLED[5] = 1;
|
minuteLED[5] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return minuteLED;
|
return minuteLED;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function draw(){
|
function draw(){
|
||||||
|
|
||||||
// work out how to display the current time
|
// work out how to display the current time
|
||||||
var d = new Date();
|
var d = new Date();
|
||||||
var h = d.getHours(), m = d.getMinutes();
|
var h = d.getHours(), m = d.getMinutes();
|
||||||
|
|
||||||
updateHourArray(h);
|
updateHourArray(h);
|
||||||
updateMinuteArray(m);
|
updateMinuteArray(m);
|
||||||
|
|
||||||
var i;
|
var i;
|
||||||
//Draw hour circles
|
//Draw hour circles
|
||||||
for(i=0; i<hourLED.length; i++){
|
for(i=0; i<hourLED.length; i++){
|
||||||
|
|
@ -118,10 +118,10 @@ function draw(){
|
||||||
g.fillCircle(24+i*48,50,10);
|
g.fillCircle(24+i*48,50,10);
|
||||||
g.setColor(colour);
|
g.setColor(colour);
|
||||||
g.drawCircle(24+i*48,50,10);
|
g.drawCircle(24+i*48,50,10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i=0; i<minuteLED.length; i++){
|
for(i=0; i<minuteLED.length; i++){
|
||||||
if(prevMinute[i] == minuteLED[i]){
|
if(prevMinute[i] == minuteLED[i]){
|
||||||
if(minuteLED[i] == 1){
|
if(minuteLED[i] == 1){
|
||||||
|
|
@ -132,21 +132,21 @@ function draw(){
|
||||||
g.fillCircle(20+i*40,100,10);
|
g.fillCircle(20+i*40,100,10);
|
||||||
g.setColor(colour);
|
g.setColor(colour);
|
||||||
g.drawCircle(20+i*40,100,10);
|
g.drawCircle(20+i*40,100,10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw the date, in a normal font
|
// draw the date, in a normal font
|
||||||
g.setFont("6x8");
|
g.setFont("6x8");
|
||||||
g.setFontAlign(0,1); // align center bottom
|
g.setFontAlign(0,1); // align center bottom
|
||||||
// pad the date - this clears the background if the date were to change length
|
// pad the date - this clears the background if the date were to change length
|
||||||
var dateStr = " "+require("locale").date(d)+" ";
|
var dateStr = " "+require("locale").date(d)+" ";
|
||||||
g.drawString(dateStr, g.getWidth()/2, 130, true /*clear background*/);
|
g.drawString(dateStr, g.getWidth()/2, 130, true /*clear background*/);
|
||||||
|
|
||||||
if(displayTime){
|
if(displayTime){
|
||||||
drawTime(d);
|
drawTime(d);
|
||||||
}else{
|
}else{
|
||||||
g.clearRect(0,240,240,130);
|
g.clearRect(0,240,240,130);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -167,12 +167,12 @@ Bangle.on('lcdPower',on=>{
|
||||||
// Load widgets
|
// Load widgets
|
||||||
Bangle.loadWidgets();
|
Bangle.loadWidgets();
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
// Show launcher when middle button pressed
|
// Show launcher when button pressed
|
||||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
Bangle.setUI("clockupdown", btn=>{
|
||||||
setWatch(function() {
|
if (btn!=1) return;
|
||||||
if(displayTime == 0){
|
if(displayTime == 0){
|
||||||
displayTime = 1;
|
displayTime = 1;
|
||||||
} else{
|
} else{
|
||||||
displayTime = 0;
|
displayTime = 0;
|
||||||
}
|
}
|
||||||
}, BTN, {edge:"rising", debounce:50, repeat:true});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
0.01: New game! BTN4- Hit card, BTN5- Stand
|
0.01: New game! BTN4- Hit card, BTN5- Stand
|
||||||
|
0.02: ignore buttons on pauses
|
||||||
|
|
@ -18,6 +18,7 @@ const Diamonds = { width : 48, height : 48, bpp : 4,
|
||||||
var deck = [];
|
var deck = [];
|
||||||
var player = {Hand:[]};
|
var player = {Hand:[]};
|
||||||
var computer = {Hand:[]};
|
var computer = {Hand:[]};
|
||||||
|
var ctx = {ready:true};
|
||||||
|
|
||||||
function createDeck() {
|
function createDeck() {
|
||||||
var suits = ["Spades", "Hearts", "Diamonds", "Clubs"];
|
var suits = ["Spades", "Hearts", "Diamonds", "Clubs"];
|
||||||
|
|
@ -44,6 +45,7 @@ function shuffle(a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function EndGameMessdage(msg){
|
function EndGameMessdage(msg){
|
||||||
|
ctx.ready = false;
|
||||||
g.drawString(msg, 155, 200);
|
g.drawString(msg, 155, 200);
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
startGame();
|
startGame();
|
||||||
|
|
@ -52,6 +54,7 @@ function EndGameMessdage(msg){
|
||||||
}
|
}
|
||||||
|
|
||||||
function hitMe() {
|
function hitMe() {
|
||||||
|
if (!ctx.ready) return;
|
||||||
player.Hand.push(deck.pop());
|
player.Hand.push(deck.pop());
|
||||||
renderOnScreen(1);
|
renderOnScreen(1);
|
||||||
var playerWeight = calcWeight(player.Hand, 0);
|
var playerWeight = calcWeight(player.Hand, 0);
|
||||||
|
|
@ -97,6 +100,8 @@ function calcWeight(hand, hideCard) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function stand(){
|
function stand(){
|
||||||
|
if (!ctx.ready) return;
|
||||||
|
ctx.ready = false;
|
||||||
function sleepFor( sleepDuration ){
|
function sleepFor( sleepDuration ){
|
||||||
console.log("Sleeping...");
|
console.log("Sleeping...");
|
||||||
var now = new Date().getTime();
|
var now = new Date().getTime();
|
||||||
|
|
@ -156,6 +161,7 @@ function renderOnScreen(HideCard) {
|
||||||
function dealHands() {
|
function dealHands() {
|
||||||
player.Hand= [];
|
player.Hand= [];
|
||||||
computer.Hand= [];
|
computer.Hand= [];
|
||||||
|
ctx.ready = false;
|
||||||
|
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
player.Hand.push(deck.pop());
|
player.Hand.push(deck.pop());
|
||||||
|
|
@ -175,6 +181,7 @@ function dealHands() {
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
computer.Hand.push(deck.pop());
|
computer.Hand.push(deck.pop());
|
||||||
renderOnScreen(1);
|
renderOnScreen(1);
|
||||||
|
ctx.ready = true;
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,3 +4,4 @@
|
||||||
0.03: Modified for use with new bootloader and firmware
|
0.03: Modified for use with new bootloader and firmware
|
||||||
0.04: Modified to account for changes in the behavior of Graphics.fillPoly
|
0.04: Modified to account for changes in the behavior of Graphics.fillPoly
|
||||||
0.05: Slight increase to draw speed after LCD on
|
0.05: Slight increase to draw speed after LCD on
|
||||||
|
0.06: Update to use Bangle.setUI instead of setWatch, allow themes and different size screens
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
const buf = Graphics.createArrayBuffer(144,200,1,{msb:true});
|
let big = g.getHeight() > 200;
|
||||||
|
const buf = Graphics.createArrayBuffer(big ? 144 : 120, big ? 180 : 150,1,{msb:true});
|
||||||
|
// TODO: convert these to Polys -> much faster and cleaner!
|
||||||
const NUMBERS = [
|
const NUMBERS = [
|
||||||
[1,1,1,1,3,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1],//0
|
[1,1,1,1,3,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1],//0
|
||||||
[0,1,1,1,3,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1],//1
|
[0,1,1,1,3,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1],//1
|
||||||
|
|
@ -14,8 +16,10 @@ const NUMBERS = [
|
||||||
let intervalRef = null;
|
let intervalRef = null;
|
||||||
let digits = [-1,-1,-1,-1,-1,-1];
|
let digits = [-1,-1,-1,-1,-1,-1];
|
||||||
function flip() {
|
function flip() {
|
||||||
g.setColor(1,1,1);
|
g.reset();
|
||||||
g.drawImage({width:buf.getWidth(),height:buf.getHeight(),buffer:buf.buffer},55,26);
|
g.drawImage({width:buf.getWidth(),height:buf.getHeight(),buffer:buf.buffer},
|
||||||
|
(g.getWidth() - buf.getWidth())/2,
|
||||||
|
26 + (g.getHeight() - (buf.getHeight()+24))/2);
|
||||||
}
|
}
|
||||||
function drawPixel(ox,oy,x,y,r,p) {
|
function drawPixel(ox,oy,x,y,r,p) {
|
||||||
let x1 = ox+x*(r*2);
|
let x1 = ox+x*(r*2);
|
||||||
|
|
@ -53,26 +57,31 @@ function redraw() {
|
||||||
|
|
||||||
let newDigits = [Math.floor(hours/10),hours%10,Math.floor(mins/10),mins%10,Math.floor(secs/10),secs%10];
|
let newDigits = [Math.floor(hours/10),hours%10,Math.floor(mins/10),mins%10,Math.floor(secs/10),secs%10];
|
||||||
|
|
||||||
|
let s = big?6:5; // size of main digits
|
||||||
|
let y2 = big?72:55;
|
||||||
|
let y3 = big?144:110;
|
||||||
|
|
||||||
|
|
||||||
for (var p = 0;p<25;p++) {
|
for (var p = 0;p<25;p++) {
|
||||||
var px = p%5;
|
var px = p%5;
|
||||||
var py = Math.floor(p/5);
|
var py = Math.floor(p/5);
|
||||||
if (digits[0] === -1 || NUMBERS[newDigits[0]][p] !== NUMBERS[digits[0]][p] ) {
|
if (digits[0] === -1 || NUMBERS[newDigits[0]][p] !== NUMBERS[digits[0]][p] ) {
|
||||||
drawPixel(0,20,px,py,6,NUMBERS[newDigits[0]][p]);
|
drawPixel(0,0,px,py,s,NUMBERS[newDigits[0]][p]);
|
||||||
}
|
}
|
||||||
if (digits[1] === -1 || NUMBERS[newDigits[1]][p] !== NUMBERS[digits[1]][p] ) {
|
if (digits[1] === -1 || NUMBERS[newDigits[1]][p] !== NUMBERS[digits[1]][p] ) {
|
||||||
drawPixel(78,20,px,py,6,NUMBERS[newDigits[1]][p]);
|
drawPixel(13*s,0,px,py,s,NUMBERS[newDigits[1]][p]);
|
||||||
}
|
}
|
||||||
if (digits[2] === -1 || NUMBERS[newDigits[2]][p] !== NUMBERS[digits[2]][p] ) {
|
if (digits[2] === -1 || NUMBERS[newDigits[2]][p] !== NUMBERS[digits[2]][p] ) {
|
||||||
drawPixel(0,92,px,py,6,NUMBERS[newDigits[2]][p]);
|
drawPixel(0,y2,px,py,s,NUMBERS[newDigits[2]][p]);
|
||||||
}
|
}
|
||||||
if (digits[3] === -1 || NUMBERS[newDigits[3]][p] !== NUMBERS[digits[3]][p] ) {
|
if (digits[3] === -1 || NUMBERS[newDigits[3]][p] !== NUMBERS[digits[3]][p] ) {
|
||||||
drawPixel(78,92,px,py,6,NUMBERS[newDigits[3]][p]);
|
drawPixel(13*s,y2,px,py,s,NUMBERS[newDigits[3]][p]);
|
||||||
}
|
}
|
||||||
if (digits[4] === -1 || NUMBERS[newDigits[4]][p] !== NUMBERS[digits[4]][p] ) {
|
if (digits[4] === -1 || NUMBERS[newDigits[4]][p] !== NUMBERS[digits[4]][p] ) {
|
||||||
drawPixel(69,164,px,py,3,NUMBERS[newDigits[4]][p]);
|
drawPixel(17*s - 3*12,y3,px,py,3,NUMBERS[newDigits[4]][p]);
|
||||||
}
|
}
|
||||||
if (digits[5] === -1 || NUMBERS[newDigits[5]][p] !== NUMBERS[digits[5]][p] ) {
|
if (digits[5] === -1 || NUMBERS[newDigits[5]][p] !== NUMBERS[digits[5]][p] ) {
|
||||||
drawPixel(108,164,px,py,3,NUMBERS[newDigits[5]][p]);
|
drawPixel(17*s,y3,px,py,3,NUMBERS[newDigits[5]][p]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
digits = newDigits;
|
digits = newDigits;
|
||||||
|
|
@ -99,5 +108,5 @@ Bangle.on('lcdPower',function(on) {
|
||||||
clearTimers();
|
clearTimers();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Show launcher when middle button pressed
|
// Show launcher when button pressed
|
||||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
Bangle.setUI("clock");
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
0.02: Modified for use with new bootloader and firmware
|
0.02: Modified for use with new bootloader and firmware
|
||||||
0.03: Tweak for more efficient rendering, and firmware 2v06
|
0.03: Tweak for more efficient rendering, and firmware 2v06
|
||||||
|
0.04: Work with themes, smaller screens
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,9 @@ var minute_hand = {
|
||||||
//g.fillRect(0,24,239,239); // Apps area
|
//g.fillRect(0,24,239,239); // Apps area
|
||||||
let intervalRef = null;
|
let intervalRef = null;
|
||||||
const p180 = Math.PI/180;
|
const p180 = Math.PI/180;
|
||||||
const clock_center = {x:Math.floor((240-1)/2), y:24+Math.floor((239-24)/2)};
|
const clock_center = {x:Math.floor((g.getWidth()-1)/2), y:24+Math.floor((g.getHeight()-25)/2)};
|
||||||
// ={ x: 119, y: 131 }
|
// ={ x: 119, y: 131 }
|
||||||
const radius = Math.floor((239-24+1)/2); // =108
|
const radius = Math.floor((g.getWidth()-24+1)/2); // =108
|
||||||
|
|
||||||
let tick0 = Graphics.createArrayBuffer(30,8,1,{msb:true});
|
let tick0 = Graphics.createArrayBuffer(30,8,1,{msb:true});
|
||||||
tick0.fillRect(0,0,tick0.getWidth()-1, tick0.getHeight()-1);
|
tick0.fillRect(0,0,tick0.getWidth()-1, tick0.getHeight()-1);
|
||||||
|
|
@ -60,18 +60,15 @@ function hour_angle(date){
|
||||||
function draw_clock(){
|
function draw_clock(){
|
||||||
//console.log("draw_clock");
|
//console.log("draw_clock");
|
||||||
let date = new Date();
|
let date = new Date();
|
||||||
//g.clear();
|
g.reset();
|
||||||
g.setBgColor(0,0,0);
|
g.clearRect(0,24,239,239); // clear app area
|
||||||
g.setColor(0,0,0);
|
|
||||||
g.fillRect(0,24,239,239); // clear app area
|
|
||||||
g.setColor(1,1,1);
|
|
||||||
|
|
||||||
// draw cross lines for testing
|
// draw cross lines for testing
|
||||||
// g.setColor(1,0,0);
|
// g.setColor(1,0,0);
|
||||||
// g.drawLine(clock_center.x - radius, clock_center.y, clock_center.x + radius, clock_center.y);
|
// g.drawLine(clock_center.x - radius, clock_center.y, clock_center.x + radius, clock_center.y);
|
||||||
// g.drawLine(clock_center.x, clock_center.y - radius, clock_center.x, clock_center.y + radius);
|
// g.drawLine(clock_center.x, clock_center.y - radius, clock_center.x, clock_center.y + radius);
|
||||||
|
|
||||||
g.setColor(1,1,1);
|
g.setColor(g.theme.fg);
|
||||||
let ticks = [0, 90, 180, 270];
|
let ticks = [0, 90, 180, 270];
|
||||||
ticks.forEach((item)=>{
|
ticks.forEach((item)=>{
|
||||||
let agl = item+180;
|
let agl = item+180;
|
||||||
|
|
@ -87,13 +84,13 @@ function draw_clock(){
|
||||||
let minute_agl = minute_angle(date);
|
let minute_agl = minute_angle(date);
|
||||||
g.drawImage(hour_hand, hour_pos_x(hour_agl), hour_pos_y(hour_agl), {rotate:hour_agl*p180}); //
|
g.drawImage(hour_hand, hour_pos_x(hour_agl), hour_pos_y(hour_agl), {rotate:hour_agl*p180}); //
|
||||||
g.drawImage(minute_hand, minute_pos_x(minute_agl), minute_pos_y(minute_agl), {rotate:minute_agl*p180}); //
|
g.drawImage(minute_hand, minute_pos_x(minute_agl), minute_pos_y(minute_agl), {rotate:minute_agl*p180}); //
|
||||||
g.setColor(1,1,1);
|
g.setColor(g.theme.fg);
|
||||||
g.fillCircle(clock_center.x, clock_center.y, 6);
|
g.fillCircle(clock_center.x, clock_center.y, 6);
|
||||||
g.setColor(0,0,0);
|
g.setColor(g.theme.bg);
|
||||||
g.fillCircle(clock_center.x, clock_center.y, 3);
|
g.fillCircle(clock_center.x, clock_center.y, 3);
|
||||||
|
|
||||||
// draw minute ticks. Takes long time to draw!
|
// draw minute ticks. Takes long time to draw!
|
||||||
g.setColor(1,1,1);
|
g.setColor(g.theme.fg);
|
||||||
for (var i=0; i<60; i++){
|
for (var i=0; i<60; i++){
|
||||||
let agl = i*6+180;
|
let agl = i*6+180;
|
||||||
g.drawImage(tick1.asImage(), rotate_around_x(big_wheel_x(i*6), agl, tick1), rotate_around_y(big_wheel_y(i*6), agl, tick1), {rotate:agl*p180});
|
g.drawImage(tick1.asImage(), rotate_around_x(big_wheel_x(i*6), agl, tick1), rotate_around_y(big_wheel_y(i*6), agl, tick1), {rotate:agl*p180});
|
||||||
|
|
@ -141,5 +138,5 @@ g.clear();
|
||||||
Bangle.loadWidgets();
|
Bangle.loadWidgets();
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
startTimers();
|
startTimers();
|
||||||
// Show launcher when middle button pressed
|
// Show launcher when button pressed
|
||||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
Bangle.setUI("clock");
|
||||||
|
|
|
||||||
|
|
@ -24,3 +24,6 @@
|
||||||
0.23: Move to a precalculated .boot0 file which should speed up load time
|
0.23: Move to a precalculated .boot0 file which should speed up load time
|
||||||
0.24: Add Bangle.setUI polyfill
|
0.24: Add Bangle.setUI polyfill
|
||||||
0.25: Fix error in 'no clock app' message
|
0.25: Fix error in 'no clock app' message
|
||||||
|
0.26: Remove buzz in setUI polyfill (#750)
|
||||||
|
0.27: Update polyfill for most recent changes
|
||||||
|
0.28: Fix double clock load after settings are changed
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ recalculates, but this avoids us doing a whole bunch of reconfiguration most
|
||||||
of the time. */
|
of the time. */
|
||||||
E.showMessage("Updating boot0...");
|
E.showMessage("Updating boot0...");
|
||||||
var s = require('Storage').readJSON('setting.json',1)||{};
|
var s = require('Storage').readJSON('setting.json',1)||{};
|
||||||
|
var isB2 = process.env.HWVERSION; // Is Bangle.js 2
|
||||||
var boot = "";
|
var boot = "";
|
||||||
var CRC = E.CRC32(require('Storage').read('setting.json'))+E.CRC32(require('Storage').list(/\.boot\.js/));
|
var CRC = E.CRC32(require('Storage').read('setting.json'))+E.CRC32(require('Storage').list(/\.boot\.js/));
|
||||||
boot += `if (E.CRC32(require('Storage').read('setting.json'))+E.CRC32(require('Storage').list(/\.boot\.js/))!=${CRC}) { eval(require('Storage').read('bootupdate.js'));} else {\n`;
|
boot += `if (E.CRC32(require('Storage').read('setting.json'))+E.CRC32(require('Storage').list(/\.boot\.js/))!=${CRC}) { eval(require('Storage').read('bootupdate.js'));} else {\n`;
|
||||||
|
|
@ -81,9 +82,9 @@ if (s.passkey!==undefined && s.passkey.length==6) boot+=`NRF.setSecurity({passke
|
||||||
if (s.whitelist) boot+=`NRF.on('connect', function(addr) { if (!(require('Storage').readJSON('setting.json',1)||{}).whitelist.includes(addr)) NRF.disconnect(); });\n`;
|
if (s.whitelist) boot+=`NRF.on('connect', function(addr) { if (!(require('Storage').readJSON('setting.json',1)||{}).whitelist.includes(addr)) NRF.disconnect(); });\n`;
|
||||||
// Pre-2v10 firmwares without a theme/setUI
|
// Pre-2v10 firmwares without a theme/setUI
|
||||||
if (!g.theme) {
|
if (!g.theme) {
|
||||||
boot += `g.theme={fg:-1,bg:0,fg2:-1,bg2:7,fgH:-1,bgH:0x02F7};\n`;
|
boot += `g.theme={fg:-1,bg:0,fg2:-1,bg2:7,fgH:-1,bgH:0x02F7,dark:true};\n`;
|
||||||
}
|
}
|
||||||
if (!Bangle.setUI) {
|
if (!Bangle.setUI) { // assume this is just for F18 - Q3 should already have it
|
||||||
boot += `Bangle.setUI=function(mode, cb) {
|
boot += `Bangle.setUI=function(mode, cb) {
|
||||||
if (Bangle.btnWatches) {
|
if (Bangle.btnWatches) {
|
||||||
Bangle.btnWatches.forEach(clearWatch);
|
Bangle.btnWatches.forEach(clearWatch);
|
||||||
|
|
@ -97,26 +98,35 @@ if (Bangle.touchandler) {
|
||||||
Bangle.removeListener("touch", Bangle.touchHandler);
|
Bangle.removeListener("touch", Bangle.touchHandler);
|
||||||
delete Bangle.touchHandler;
|
delete Bangle.touchHandler;
|
||||||
}
|
}
|
||||||
function b() {
|
|
||||||
try{Bangle.buzz(20);}catch(e){}
|
|
||||||
}
|
|
||||||
if (!mode) return;
|
if (!mode) return;
|
||||||
else if (mode=="updown") {
|
else if (mode=="updown") {
|
||||||
Bangle.btnWatches = [
|
Bangle.btnWatches = [
|
||||||
setWatch(function() { b();cb(-1); }, BTN1, {repeat:1}),
|
setWatch(function() { cb(-1); }, BTN1, {repeat:1}),
|
||||||
setWatch(function() { b();cb(1); }, BTN3, {repeat:1}),
|
setWatch(function() { cb(1); }, BTN3, {repeat:1}),
|
||||||
setWatch(function() { b();cb(); }, BTN2, {repeat:1})
|
setWatch(function() { cb(); }, BTN2, {repeat:1})
|
||||||
];
|
];
|
||||||
} else if (mode=="leftright") {
|
} else if (mode=="leftright") {
|
||||||
Bangle.btnWatches = [
|
Bangle.btnWatches = [
|
||||||
setWatch(function() { b();cb(-1); }, BTN1, {repeat:1}),
|
setWatch(function() { cb(-1); }, BTN1, {repeat:1}),
|
||||||
setWatch(function() { b();cb(1); }, BTN3, {repeat:1}),
|
setWatch(function() { cb(1); }, BTN3, {repeat:1}),
|
||||||
setWatch(function() { b();cb(); }, BTN2, {repeat:1})
|
setWatch(function() { cb(); }, BTN2, {repeat:1})
|
||||||
];
|
];
|
||||||
Bangle.swipeHandler = d => {b();cb(d);};
|
Bangle.swipeHandler = d => {cb(d);};
|
||||||
Bangle.on("swipe", Bangle.swipeHandler);
|
Bangle.on("swipe", Bangle.swipeHandler);
|
||||||
Bangle.touchHandler = d => {b();cb();};
|
Bangle.touchHandler = d => {cb();};
|
||||||
Bangle.on("touch", Bangle.touchHandler);
|
Bangle.on("touch", Bangle.touchHandler);
|
||||||
|
} else if (mode=="clock") {
|
||||||
|
Bangle.CLOCK=1;
|
||||||
|
Bangle.btnWatches = [
|
||||||
|
setWatch(Bangle.showLauncher, BTN2, {repeat:1,edge:"falling"})
|
||||||
|
];
|
||||||
|
} else if (mode=="clockupdown") {
|
||||||
|
Bangle.CLOCK=1;
|
||||||
|
Bangle.btnWatches = [
|
||||||
|
setWatch(function() { cb(-1); }, BTN1, {repeat:1}),
|
||||||
|
setWatch(function() { cb(1); }, BTN3, {repeat:1}),
|
||||||
|
setWatch(Bangle.showLauncher, BTN2, {repeat:1,edge:"falling"})
|
||||||
|
];
|
||||||
} else
|
} else
|
||||||
throw new Error("Unknown UI mode");
|
throw new Error("Unknown UI mode");
|
||||||
};\n`;
|
};\n`;
|
||||||
|
|
@ -126,8 +136,9 @@ require('Storage').list(/\.boot\.js/).forEach(bootFile=>{
|
||||||
boot += "//"+bootFile+"\n"+require('Storage').read(bootFile)+"\n";
|
boot += "//"+bootFile+"\n"+require('Storage').read(bootFile)+"\n";
|
||||||
});
|
});
|
||||||
boot += "}\n";// initial 'if'
|
boot += "}\n";// initial 'if'
|
||||||
var s = require('Storage').write('.boot0',boot);
|
require('Storage').write('.boot0',boot);
|
||||||
delete boot;
|
delete boot;
|
||||||
E.showMessage("Reloading...");
|
E.showMessage("Reloading...");
|
||||||
eval(require('Storage').read('.boot0'));
|
eval(require('Storage').read('.boot0'));
|
||||||
eval(require('Storage').read('.bootcde'));
|
// .bootcde should be run automatically after if required, since
|
||||||
|
// we normally get called automatically from '.boot0'
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
|
|
@ -1 +1,2 @@
|
||||||
0.01: Basic calendar
|
0.01: Basic calendar
|
||||||
|
0.02: Make Bangle 2 compatible
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
const maxX = 240;
|
const maxX = g.getWidth();
|
||||||
const maxY = 240;
|
const maxY = g.getHeight();
|
||||||
|
const fontSize = g.getWidth()>200?2:1;
|
||||||
const rowN = 7;
|
const rowN = 7;
|
||||||
const colN = 7;
|
const colN = 7;
|
||||||
const headerH = maxY / 7;
|
const headerH = maxY / 7;
|
||||||
|
|
@ -50,7 +51,7 @@ function drawCalendar(date) {
|
||||||
11: "December"
|
11: "December"
|
||||||
};
|
};
|
||||||
g.setFontAlign(0, 0);
|
g.setFontAlign(0, 0);
|
||||||
g.setFont("6x8", 2);
|
g.setFont("6x8", fontSize);
|
||||||
g.setColor(white);
|
g.setColor(white);
|
||||||
g.drawString(`${monthMap[month]} ${year}`, maxX / 2, headerH / 2);
|
g.drawString(`${monthMap[month]} ${year}`, maxX / 2, headerH / 2);
|
||||||
g.drawPoly([10, headerH / 2, 20, 10, 20, headerH - 10], true);
|
g.drawPoly([10, headerH / 2, 20, 10, 20, headerH - 10], true);
|
||||||
|
|
@ -59,7 +60,7 @@ function drawCalendar(date) {
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
g.setFont("6x8", 2);
|
g.setFont("6x8", fontSize);
|
||||||
const dowLbls = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
|
const dowLbls = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
|
||||||
dowLbls.forEach((lbl, i) => {
|
dowLbls.forEach((lbl, i) => {
|
||||||
g.drawString(lbl, i * colW + colW / 2, headerH + rowH / 2);
|
g.drawString(lbl, i * colW + colW / 2, headerH + rowH / 2);
|
||||||
|
|
@ -135,26 +136,21 @@ const today = {
|
||||||
};
|
};
|
||||||
drawCalendar(date);
|
drawCalendar(date);
|
||||||
clearWatch();
|
clearWatch();
|
||||||
setWatch(
|
Bangle.on("touch",area=>{
|
||||||
() => {
|
const month = date.getMonth();
|
||||||
const month = date.getMonth();
|
let prevMonth;
|
||||||
const prevMonth = month > 0 ? month - 1 : 11;
|
if (area==1) {
|
||||||
|
let prevMonth = month > 0 ? month - 1 : 11;
|
||||||
if (prevMonth === 11) date.setFullYear(date.getFullYear() - 1);
|
if (prevMonth === 11) date.setFullYear(date.getFullYear() - 1);
|
||||||
date.setMonth(prevMonth);
|
date.setMonth(prevMonth);
|
||||||
drawCalendar(date);
|
} else {
|
||||||
},
|
let prevMonth = month < 11 ? month + 1 : 0;
|
||||||
BTN4,
|
|
||||||
{ repeat: true }
|
|
||||||
);
|
|
||||||
setWatch(
|
|
||||||
() => {
|
|
||||||
const month = date.getMonth();
|
|
||||||
const prevMonth = month < 11 ? month + 1 : 0;
|
|
||||||
if (prevMonth === 0) date.setFullYear(date.getFullYear() + 1);
|
if (prevMonth === 0) date.setFullYear(date.getFullYear() + 1);
|
||||||
date.setMonth(month + 1);
|
date.setMonth(month + 1);
|
||||||
drawCalendar(date);
|
}
|
||||||
},
|
drawCalendar(date);
|
||||||
BTN5,
|
});
|
||||||
{ repeat: true }
|
|
||||||
);
|
// Show launcher when button pressed
|
||||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
Bangle.setUI("clock"); // TODO: ideally don't set 'clock' mode
|
||||||
|
// No space for widgets!
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
0.07: Submitted to App Loader
|
0.07: Submitted to App Loader
|
||||||
0.08: Fixes issue where face would redraw on wake leading to all memory being used and watch crashing.
|
0.08: Fixes issue where face would redraw on wake leading to all memory being used and watch crashing.
|
||||||
0.09: Add BTN1 status line with ID,Fw ver, mem %, battery %
|
0.09: Add BTN1 status line with ID,Fw ver, mem %, battery %
|
||||||
0.10: Icon fixed for transparency
|
0.10: Icon fixed for transparency
|
||||||
0.11: added Heart Rate Monitor status and ability to turn on/off
|
0.11: added Heart Rate Monitor status and ability to turn on/off
|
||||||
0.12: added support for different locales
|
0.12: added support for different locales
|
||||||
|
0.13: Use setUI, work with smaller screens and themes
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
var fontsize = 3;
|
var fontsize = g.getWidth()>200 ? 3 : 2;
|
||||||
|
var fontheight = 10*fontsize;
|
||||||
var locale = require("locale");
|
var locale = require("locale");
|
||||||
var marginTop = 40;
|
var marginTop = 40;
|
||||||
var flag = false;
|
var flag = false;
|
||||||
|
|
@ -39,22 +40,23 @@ function updateTime(){
|
||||||
updateRest(now);
|
updateRest(now);
|
||||||
}
|
}
|
||||||
function writeLineStart(line){
|
function writeLineStart(line){
|
||||||
g.drawString(">",4,marginTop+line*30);
|
g.drawString(">",4,marginTop+line*fontheight);
|
||||||
}
|
}
|
||||||
function writeLine(str,line){
|
function writeLine(str,line){
|
||||||
|
var y = marginTop+line*fontheight;
|
||||||
g.setFont("6x8",fontsize);
|
g.setFont("6x8",fontsize);
|
||||||
//g.setColor(0,1,0);
|
//g.setColor(0,1,0);
|
||||||
g.setColor(0,0x07E0,0);
|
g.setColor("#0f0");
|
||||||
g.setFontAlign(-1,-1);
|
g.setFontAlign(-1,-1);
|
||||||
g.clearRect(0,marginTop+line*30,((str.length+1)*20),marginTop+25+line*30);
|
g.clearRect(0,y,((str.length+1)*20),y+fontheight-1);
|
||||||
writeLineStart(line);
|
writeLineStart(line);
|
||||||
g.drawString(str,25,marginTop+line*30);
|
g.drawString(str,25,y);
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawInfo(line) {
|
function drawInfo(line) {
|
||||||
let val;
|
let val;
|
||||||
let str = "";
|
let str = "";
|
||||||
let col = 0x07E0; // green
|
let col = "#0f0"; // green
|
||||||
|
|
||||||
//console.log("drawInfo(), infoMode=" + infoMode + " funcMode=" + functionMode);
|
//console.log("drawInfo(), infoMode=" + infoMode + " funcMode=" + functionMode);
|
||||||
|
|
||||||
|
|
@ -62,15 +64,15 @@ function drawInfo(line) {
|
||||||
case NONE_FN_MODE:
|
case NONE_FN_MODE:
|
||||||
break;
|
break;
|
||||||
case HRT_FN_MODE:
|
case HRT_FN_MODE:
|
||||||
col = 0x07FF; // cyan
|
col = "#0ff"; // cyan
|
||||||
str = "HRM: " + (hrtOn ? "ON" : "OFF");
|
str = "HRM: " + (hrtOn ? "ON" : "OFF");
|
||||||
drawModeLine(line,str,col);
|
drawModeLine(line,str,col);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(infoMode) {
|
switch(infoMode) {
|
||||||
case NONE_MODE:
|
case NONE_MODE:
|
||||||
col = 0x0000;
|
col = "#fff";
|
||||||
str = "";
|
str = "";
|
||||||
break;
|
break;
|
||||||
case HRT_MODE:
|
case HRT_MODE:
|
||||||
|
|
@ -100,10 +102,11 @@ function drawInfo(line) {
|
||||||
|
|
||||||
function drawModeLine(line, str, col) {
|
function drawModeLine(line, str, col) {
|
||||||
g.setColor(col);
|
g.setColor(col);
|
||||||
g.fillRect(0, marginTop-3+line*30, 239, marginTop+25+line*30);
|
var y = marginTop+line*fontheight;
|
||||||
g.setColor(0,0,0);
|
g.fillRect(0, y, 239, y+fontheight-1);
|
||||||
|
g.setColor(0);
|
||||||
g.setFontAlign(0, -1);
|
g.setFontAlign(0, -1);
|
||||||
g.drawString(str, g.getWidth()/2, marginTop+line*30);
|
g.drawString(str, g.getWidth()/2, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeInfoMode() {
|
function changeInfoMode() {
|
||||||
|
|
@ -160,7 +163,7 @@ function changeFunctionMode() {
|
||||||
functionMode = NONE_FN_MODE;
|
functionMode = NONE_FN_MODE;
|
||||||
}
|
}
|
||||||
//console.log(functionMode);
|
//console.log(functionMode);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function stepsWidget() {
|
function stepsWidget() {
|
||||||
|
|
@ -185,10 +188,12 @@ Bangle.loadWidgets();
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
drawAll();
|
drawAll();
|
||||||
Bangle.on('lcdPower',function(on) {
|
Bangle.on('lcdPower',function(on) {
|
||||||
if (on)
|
if (on) drawAll();
|
||||||
drawAll();
|
|
||||||
});
|
});
|
||||||
var click = setInterval(updateTime, 1000);
|
var click = setInterval(updateTime, 1000);
|
||||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
// Show launcher when button pressed
|
||||||
setWatch(() => { changeInfoMode(); drawAll(); }, BTN1, {repeat: true});
|
Bangle.setUI("clockupdown", btn=>{
|
||||||
setWatch(() => { changeFunctionMode(); drawAll(); }, BTN3, {repeat: true});
|
if (btn==0) changeInfoMode();
|
||||||
|
if (btn==1) changeFunctionMode();
|
||||||
|
drawAll();
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
0.02: Modified for use with new bootloader and firmware
|
0.02: Modified for use with new bootloader and firmware
|
||||||
0.03: Added 'reset' so we don't get the font color from widgets
|
0.03: Added 'reset' so we don't get the font color from widgets
|
||||||
0.04: Changed name from clck3x2 to clock2x3
|
0.04: Changed name from clck3x2 to clock2x3
|
||||||
|
0.05: Use setUI, work with smaller screens and themes
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
|
|
||||||
|
const big = g.getWidth()>200;
|
||||||
const ox=10; // x offset
|
const ox=10; // x offset
|
||||||
const oy=80;
|
const oy=big ? 80 : 70;
|
||||||
const pw=20; // pixel width
|
const pw=big ? 20 : 14; // pixel width
|
||||||
const ps=5; // pixel spacing
|
const ps=big ? 5 : 3; // pixel spacing
|
||||||
const ds=10; // digit spacing
|
const ds=big ? 10 : 8; // digit spacing
|
||||||
const ms=20; // middle space
|
const ms=20; // middle space
|
||||||
|
|
||||||
const x00=ox; // digit 0, pixel 0, x position
|
const x00=ox; // digit 0, pixel 0, x position
|
||||||
|
|
@ -90,7 +92,7 @@ Bangle.on('lcdPower', function(on){
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Show launcher when button pressed
|
||||||
|
Bangle.setUI("clock");
|
||||||
Bangle.loadWidgets();
|
Bangle.loadWidgets();
|
||||||
drawTime();
|
drawTime();
|
||||||
// Show launcher when middle button pressed
|
|
||||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
0.02: Modified for use with new bootloader and firmware
|
0.02: Modified for use with new bootloader and firmware
|
||||||
|
0.03: Changed setWatch to Bangle.setUI
|
||||||
|
|
|
||||||
|
|
@ -46,26 +46,25 @@ function drawSegment (align, base, str) {
|
||||||
point = base + (maxSegmentWidth / 2) -
|
point = base + (maxSegmentWidth / 2) -
|
||||||
(g.stringWidth(str) / 2);
|
(g.stringWidth(str) / 2);
|
||||||
}
|
}
|
||||||
g.setColor(1, 1, 1);
|
g.setColor(g.theme.fg);
|
||||||
g.drawString(str, point, middleY - 4, false);
|
g.drawString(str, point, middleY - 4, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawDots (center) {
|
function drawDots (center) {
|
||||||
g.setColor(0xFD20);
|
g.setColor("#FA0");
|
||||||
g.fillCircle(center, middleY + 10, 2);
|
g.fillCircle(center, middleY + 10, 2);
|
||||||
g.fillCircle(center, middleY + 40, 2);
|
g.fillCircle(center, middleY + 40, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawLines () {
|
function drawLines () {
|
||||||
g.setColor(0.5, 0.5, 0.5);
|
g.setColor("#777");
|
||||||
g.drawLine(middleX - lineLength, lineY1, middleX + lineLength, lineY1);
|
g.drawLine(middleX - lineLength, lineY1, middleX + lineLength, lineY1);
|
||||||
g.drawLine(middleX - lineLength, lineY2, middleX + lineLength, lineY2);
|
g.drawLine(middleX - lineLength, lineY2, middleX + lineLength, lineY2);
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawDate (str) {
|
function drawDate (str) {
|
||||||
let maxSegmentWidth = 236;
|
let maxSegmentWidth = 236;
|
||||||
g.setColor(0.5, 0.5, 0.5);
|
g.setColor("#777");
|
||||||
g.setColor(0.5, 0.5, 0.5);
|
|
||||||
g.drawString(str, (maxSegmentWidth) - (g.stringWidth(str)), middleY - 22,
|
g.drawString(str, (maxSegmentWidth) - (g.stringWidth(str)), middleY - 22,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
@ -149,6 +148,9 @@ function start () {
|
||||||
}
|
}
|
||||||
|
|
||||||
start();
|
start();
|
||||||
|
// Show launcher when middle button pressed
|
||||||
|
Bangle.setUI("clock");
|
||||||
|
|
||||||
Bangle.loadWidgets();
|
Bangle.loadWidgets();
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
Bangle.on('lcdPower', function (on) {
|
Bangle.on('lcdPower', function (on) {
|
||||||
|
|
@ -158,6 +160,3 @@ Bangle.on('lcdPower', function (on) {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Show launcher when middle button pressed
|
|
||||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,4 @@
|
||||||
0.07: add days in current month (md) and days since new moon (l)
|
0.07: add days in current month (md) and days since new moon (l)
|
||||||
0.08: update icon
|
0.08: update icon
|
||||||
0.09: Use localised month and day of the week from locale
|
0.09: Use localised month and day of the week from locale
|
||||||
|
0.10: Changed setWatch to Bangle.setUI and allow small screen
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,18 @@
|
||||||
var locale = require("locale");
|
var locale = require("locale");
|
||||||
/* jshint esversion: 6 */
|
/* jshint esversion: 6 */
|
||||||
const timeFontSize = 4;
|
const big = g.getWidth()>200;
|
||||||
const dateFontSize = 3;
|
const timeFontSize = big?4:3;
|
||||||
const smallFontSize = 2;
|
const dateFontSize = big?3:2;
|
||||||
|
const smallFontSize = big?2:1;
|
||||||
const font = "6x8";
|
const font = "6x8";
|
||||||
|
|
||||||
const xyCenter = g.getWidth() / 2;
|
const xyCenter = g.getWidth() / 2;
|
||||||
const yposTime = 50;
|
const yposTime = 50;
|
||||||
const yposDate = 85;
|
const yposDate = big?85:75;
|
||||||
const yposTst = 115;
|
const yposTst = big?115:95;
|
||||||
const yposDml = 170;
|
const yposDml = big?170:130;
|
||||||
const yposDayMonth = 195;
|
const yposDayMonth = big?195:140;
|
||||||
const yposGMT = 220;
|
const yposGMT = big?220:150;
|
||||||
|
|
||||||
// Check settings for what type our clock should be
|
// Check settings for what type our clock should be
|
||||||
var is12Hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"];
|
var is12Hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"];
|
||||||
|
|
@ -99,6 +100,8 @@ Bangle.on('lcdPower', function(on) {
|
||||||
|
|
||||||
// clean app screen
|
// clean app screen
|
||||||
g.clear();
|
g.clear();
|
||||||
|
// Show launcher when button pressed
|
||||||
|
Bangle.setUI("clock");
|
||||||
Bangle.loadWidgets();
|
Bangle.loadWidgets();
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
|
|
||||||
|
|
@ -107,6 +110,3 @@ setInterval(drawSimpleClock, 100);
|
||||||
|
|
||||||
// draw now
|
// draw now
|
||||||
drawSimpleClock();
|
drawSimpleClock();
|
||||||
|
|
||||||
// Show launcher when middle button pressed
|
|
||||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
0.01: New App!
|
||||||
|
0.02: Adjust for different screen types and themes
|
||||||
|
|
@ -1,29 +1,21 @@
|
||||||
|
g.setBgColor(0).clear();
|
||||||
|
|
||||||
//g.clear();
|
var img = require("heatshrink").decompress(atob("plB4X/ln7A4OGmMs5dVAANa1WlAoQADBI9W1QAByoJNtWv4f61ISEtWrBI2q4EAgeqCQgJHq2sLoU6IYdaBIg5CrWAn2q2EDF4dq4EO1W8gQcCtUD1fP9cA9QSC1cA9f/9XADgWohxBBh2whQvBq2gAwMAh+wlQSB1k7IIXogYvBrXAlYJC9k6DYOw9gIChXA9JBC0AJCncOytWwAtBAAMDF4RBDAAMOgWVrXDwDjD9kKy2gIIcAgXD0taDYgvCRIJBDF4OA0trhwIDJgK2B4BKDAAXptcLA4kC4HrD4IJE8HptE4BAhfBLAJBEgEslISGL4JOBBAoSB1ksBIs6/70DBIgSHh+q+AIFnASIABASU0EgCR0IhWgEp4SBHCBxJLzusXowAIaBISLhYSO8EptcOCR2w9NagXACJkDwGlrXDwASMgXDCQOA2ASMh0C0tW2HgCRkLh2Vq2glASMlEKytV1iFN9k6qtVtEOORcD2EpCQNqOwJwL4GpCQNa4GgCRUKgelCQJyBlgSKnBwBCQWgnZdLOAQAB1BfKLoMqCIVVtYHBXZPA9ISDL4PsCRE7LoZfDnRKJLoYAC1kOTI8CDoIREJgMA1gSGFwJKEJgaGH9hKFTIaGGPQKVEAAeogbTFhXASogADtXAlYSE9cDeYRMG2A5EG4MOJQxMC1g5EG4M6JQ4AB1Q5E9ED1QRIHIatBG5Y5EVoM6G5Y5DnXDCwJvIHIsD32AG5Y5C1aUBgHqG5atDLwI3MHIReCG5hgD4aUKHI2+G5xgC1RcNAAdpBJA"))
|
||||||
|
|
||||||
var img = {
|
|
||||||
width : 100, height : 100, bpp : 8,
|
|
||||||
transparent : 254,
|
|
||||||
buffer : require("heatshrink").decompress(atob("/wA/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4AglYAGE/44gHz4nnHKtPumez3C4WezFzp49ZLAgoCE4WeugnaHStPG4QAHzw9DE/Y6VHJQ9YMJwnEMk46CF4lzfglPug9WCAWYDQl0E4tzN4gLCMVC5Cp+YGoOezxBCubKHExxUEuiFCEoInECAhkjMQuYLArCFGwLLEHpjsGMIRpEfAsrMkwhBFAQ6BHJA9EKApDBHpAJBQYhPBE5iZBzAsDMb4gBEwg6MJhBkIYorgBPQiMMUAhkeHgkrug7ObI5qBHwhiGZYomOEojGeJQVzTx5kOMQ6JREAR3CDIJkcHobwEMiw+CAAYJEMSYWCAgRjcDgI4CYyiiDXopiFBooAWRwJkaHwjGVKwdzH4rADuhiXZAaICMbbtGHy2YBQ+YRDCiEMbidCULBkDLIwIIdqbmCp5jZPwIfDAYQAXXwNPzwACIQLQIACt0ZDIZBTwRFBHjWeHoSJCETlPc4ZjdAYYA7L4Jj/Mf5jCEYQDDAHhEEMbzH+McBfCMf4ADzxjep+YL/1PMb10MYQDCAHd0MYV0MbdzEYoA7UYdPMTBkCc4hj9leeAYRjbL4aIDAHN0UwRjeL4WYZHlPzBnCMbZkBQojtCAG6gEp5ibZARfCdwjG3ugDBzzGcMYTIEFAQA1ujGFMbjIFeAgA0HobGeZA9PAgYAyG4jGfZAyPBzBizf4LGjMggtCFAJpDAFw0FMURjCeAd0AgYAup90AgZjjMgWYFYZkwGImYMUhkDeYdPuZituZiDzximMYUrFwj6DAFF0TAg6CMcpkCSYpkqMQtPMVBkDuZktMQtzMVRkDLwZkoMQoFBMVZkJp5ijX4JizMhFPMkQjBMWpkHIAKjEADTrGMWZkDuY8DuZkdMQKKEMWpkDUIxFEACocGdoJi1MhCqBAwgATLYLkEMXJkDIY4GEAB+ep9PC4aDBMXRkJukruhiRCgxi+MglzJAtPMR7cGNIJi+MglPJYhSBzBhLzB0FzwWBMX5lGMghVGAAtzld0bwph/MhNzWYzKGNwR2Euhi/MhhTHA4ZrHA4Rh/Mp10YIlzA4JoCBQjE/ZTK8BA45i/MqtzX4jE/Mj0rYQjECBYZP/MrFPMoWep5h/ZT90ujE/MsZh/MsZB/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/ACg"))
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
function hr(){
|
function hr(){
|
||||||
|
Bangle.buzz(100,0.1).then(()=>{
|
||||||
Bangle.buzz(100,0.1).then(()=>{
|
g.clear();
|
||||||
g.clear();
|
return new Promise(resolve=>setTimeout(resolve,250)); // wait 250ms
|
||||||
return new Promise(resolve=>setTimeout(resolve,250)); // wait 250ms
|
}).then(()=>{
|
||||||
}).then(()=>{
|
return Bangle.buzz(150);
|
||||||
return Bangle.buzz(150);
|
}).then(()=>{
|
||||||
}).then(()=>{
|
g.drawImage(img, g.getWidth()/2 - 76, g.getHeight()/2 - 65, {scale:2});
|
||||||
g.drawImage(img, 25, 40, {scale:2});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
setInterval(hr, 2000);
|
setInterval(hr, 2000);
|
||||||
|
|
||||||
g.flip();
|
g.flip();
|
||||||
|
|
||||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
// TODO - not clock but we still want a press to show launcher when button pressed
|
||||||
|
Bangle.setUI("clock");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
0.01: App created
|
0.01: App created
|
||||||
0.02: Persist state to storage to enable stopwatch to continue in the background
|
0.02: Persist state to storage to enable stopwatch to continue in the background
|
||||||
|
0.03: Modified to use setUI, theme and different screens
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,16 @@ const EMPTY_LAP = '--:--:---';
|
||||||
const EMPTY_H = '00:00:000';
|
const EMPTY_H = '00:00:000';
|
||||||
const MAX_LAPS = 6;
|
const MAX_LAPS = 6;
|
||||||
const XY_CENTER = g.getWidth() / 2;
|
const XY_CENTER = g.getWidth() / 2;
|
||||||
|
const big = g.getWidth()>200;
|
||||||
const Y_CHRONO = 40;
|
const Y_CHRONO = 40;
|
||||||
const Y_HEADER = 80;
|
const Y_HEADER = big?80:60;
|
||||||
const Y_LAPS = 125;
|
const Y_LAPS = big?125:90;
|
||||||
const Y_BTN3 = 225;
|
const H_LAPS = big?15:8;
|
||||||
|
const Y_BTN3 = big?225:165;
|
||||||
const FONT = '6x8';
|
const FONT = '6x8';
|
||||||
const CHRONO = '/* C H R O N O */';
|
const CHRONO = '/* C H R O N O */';
|
||||||
|
|
||||||
|
|
||||||
var reset = false;
|
var reset = false;
|
||||||
var currentLap = '';
|
var currentLap = '';
|
||||||
var chronoInterval;
|
var chronoInterval;
|
||||||
|
|
@ -22,11 +25,11 @@ var state = require("Storage").readJSON("devstopwatch.state.json",1) || {
|
||||||
laps: [EMPTY_LAP, EMPTY_LAP, EMPTY_LAP, EMPTY_LAP, EMPTY_LAP, EMPTY_LAP, EMPTY_LAP],
|
laps: [EMPTY_LAP, EMPTY_LAP, EMPTY_LAP, EMPTY_LAP, EMPTY_LAP, EMPTY_LAP, EMPTY_LAP],
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set laps.
|
// Show launcher when button pressed
|
||||||
setWatch(() => {
|
Bangle.setUI("clockupdown", btn=>{
|
||||||
|
if (btn==0) {
|
||||||
reset = false;
|
reset = false;
|
||||||
|
|
||||||
if (state.started) {
|
if (state.started) {
|
||||||
changeLap();
|
changeLap();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -34,13 +37,9 @@ setWatch(() => {
|
||||||
chronoInterval = setInterval(chronometer, 10);
|
chronoInterval = setInterval(chronometer, 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, BTN1, { repeat: true, edge: 'rising' });
|
}
|
||||||
|
if (btn==1) resetChrono();
|
||||||
// Reset chronometre.
|
});
|
||||||
setWatch(() => { resetChrono(); }, BTN3, { repeat: true, edge: 'rising' });
|
|
||||||
|
|
||||||
// Show launcher when middle button pressed.
|
|
||||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: 'falling' });
|
|
||||||
|
|
||||||
function resetChrono() {
|
function resetChrono() {
|
||||||
state.laps = [EMPTY_H, EMPTY_H, EMPTY_LAP, EMPTY_LAP, EMPTY_LAP, EMPTY_LAP, EMPTY_LAP];
|
state.laps = [EMPTY_H, EMPTY_H, EMPTY_LAP, EMPTY_LAP, EMPTY_LAP, EMPTY_LAP, EMPTY_LAP];
|
||||||
|
|
@ -106,33 +105,33 @@ function printChrono() {
|
||||||
|
|
||||||
var print = '';
|
var print = '';
|
||||||
|
|
||||||
g.setFont(FONT, 2);
|
g.setFont(FONT, big?2:1);
|
||||||
print = CHRONO;
|
print = CHRONO;
|
||||||
g.drawString(print, XY_CENTER, Y_CHRONO, true);
|
g.drawString(print, XY_CENTER, Y_CHRONO, true);
|
||||||
|
|
||||||
g.setColor(0, 220, 0);
|
g.setColor("#0e0");
|
||||||
g.setFont(FONT, 3);
|
g.setFont(FONT, big?3:2);
|
||||||
print = ` T ${state.laps[0]}\n`;
|
print = ` T ${state.laps[0]}\n`;
|
||||||
print += ` C ${state.laps[1]}\n`;
|
print += ` C ${state.laps[1]}\n`;
|
||||||
g.drawString(print, XY_CENTER, Y_HEADER, true);
|
g.drawString(print, XY_CENTER, Y_HEADER, true);
|
||||||
|
|
||||||
g.setColor(255, 255, 255);
|
g.setColor(g.theme.fg);
|
||||||
g.setFont(FONT, 2);
|
g.setFont(FONT, big?2:1);
|
||||||
|
|
||||||
for (var i = 2; i < MAX_LAPS + 1; i++) {
|
for (var i = 2; i < MAX_LAPS + 1; i++) {
|
||||||
|
|
||||||
g.setColor(255, 255, 255);
|
g.setColor(g.theme.fg);
|
||||||
let suffix = ' ';
|
let suffix = ' ';
|
||||||
if (state.currentLapIndex === i) {
|
if (state.currentLapIndex === i) {
|
||||||
let suffix = '*';
|
let suffix = '*';
|
||||||
g.setColor(255, 200, 0);
|
g.setColor("#f70");
|
||||||
}
|
}
|
||||||
|
|
||||||
const lapLine = `L${i - 1} ${state.laps[i]} ${suffix}\n`;
|
const lapLine = `L${i - 1} ${state.laps[i]} ${suffix}\n`;
|
||||||
g.drawString(lapLine, XY_CENTER, Y_LAPS + (15 * (i - 1)), true);
|
g.drawString(lapLine, XY_CENTER, Y_LAPS + (H_LAPS * (i - 1)), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
g.setColor(255, 255, 255);
|
g.setColor(g.theme.fg);
|
||||||
g.setFont(FONT, 1);
|
g.setFont(FONT, 1);
|
||||||
print = 'Press 3 to reset';
|
print = 'Press 3 to reset';
|
||||||
g.drawString(print, XY_CENTER, Y_BTN3, true);
|
g.drawString(print, XY_CENTER, Y_BTN3, true);
|
||||||
|
|
@ -166,7 +165,7 @@ E.on('kill', function(){
|
||||||
});
|
});
|
||||||
|
|
||||||
if(state.started){
|
if(state.started){
|
||||||
chronoInterval = setInterval(chronometer, 10);
|
chronoInterval = setInterval(chronometer, 10);
|
||||||
} else {
|
} else {
|
||||||
resetChrono();
|
resetChrono();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
0.01: App Made!
|
0.01: App Made!
|
||||||
|
0.02: Changed setWatch to Bangle.setUI, code tidy
|
||||||
|
|
|
||||||
|
|
@ -1,141 +1,50 @@
|
||||||
//load fonts
|
//load fonts
|
||||||
require("Font7x11Numeric7Seg").add(Graphics);
|
require("Font7x11Numeric7Seg").add(Graphics);
|
||||||
require("FontHaxorNarrow7x17").add(Graphics);
|
require("FontHaxorNarrow7x17").add(Graphics);
|
||||||
//screen position
|
//screen position
|
||||||
const X = 170;
|
const X = 170;
|
||||||
const Y = 140;
|
const Y = 140;
|
||||||
|
|
||||||
function draw() {
|
function draw() {
|
||||||
// Date Variables
|
// Date Variables
|
||||||
var date = new Date();
|
var date = new Date();
|
||||||
var h = date.getHours();
|
var h = date.getHours();
|
||||||
var m = date.getMinutes();
|
var m = date.getMinutes();
|
||||||
var day = date.getDay();
|
var day = require("locale").dow(date);
|
||||||
var month = date.getMonth();
|
var month = require("locale").month(date,1);
|
||||||
var dateNum = date.getDate();
|
var dateNum = date.getDate();
|
||||||
var year = date.getFullYear();
|
var year = date.getFullYear();
|
||||||
var half = "AM";
|
var half = "AM";
|
||||||
var time = (" " + h).substr(-2) + ":" + ("0" + m).substr(-2);
|
var time = (" " + h).substr(-2) + ":" + ("0" + m).substr(-2);
|
||||||
|
|
||||||
//convert day into string
|
|
||||||
switch (day) {
|
|
||||||
case 0:
|
|
||||||
day = "Sunday";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
day = "Monday";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
day = "Tuesday";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
day = "Wednesday";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
day = "Thursday";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 5:
|
|
||||||
day = "Friday";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 6:
|
|
||||||
day = "Saturday";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
day = "ERROR";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//convert month into String
|
|
||||||
switch(month) {
|
|
||||||
case 0:
|
|
||||||
month = "Jan";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
month = "Feb";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
month = "Mar";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
month = "Apr";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
month = "May";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 5:
|
|
||||||
month = "Jun";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 6:
|
|
||||||
month = "Jul";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 7:
|
|
||||||
month = "Aug";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 8:
|
|
||||||
month = "Sep";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 9:
|
|
||||||
month = "Oct";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 10:
|
|
||||||
month = "Nov";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 11:
|
|
||||||
month = "Dec";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
month = "ERROR";
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (h > 12) {
|
if (h > 12) {
|
||||||
half = "PM";
|
half = "PM";
|
||||||
h = h - 12;
|
h = h - 12;
|
||||||
}
|
}
|
||||||
//reset graphics
|
//reset graphics
|
||||||
g.reset();
|
g.reset();
|
||||||
//draw the time
|
//draw the time
|
||||||
g.setFont("7x11Numeric7Seg", 5);
|
g.setFont("7x11Numeric7Seg", 5);
|
||||||
g.setFontAlign(1,1);
|
g.setFontAlign(1,1);
|
||||||
g.drawString(time, X, Y, true /*clear background*/);
|
g.drawString(time, X, Y, true /*clear background*/);
|
||||||
g.setFont("7x11Numeric7Seg", 3);
|
g.setFont("7x11Numeric7Seg", 3);
|
||||||
g.drawString(("0"+date.getSeconds()).substr(-2), X+50, Y, true /*clear background*/);
|
g.drawString(("0"+date.getSeconds()).substr(-2), X+50, Y, true /*clear background*/);
|
||||||
g.setFontAlign(0,1);
|
g.setFontAlign(0,1);
|
||||||
g.setFont("HaxorNarrow7x17", 2);
|
g.setFont("HaxorNarrow7x17", 2);
|
||||||
g.drawString(half, X+30, Y-35, true);
|
g.drawString(half, X+30, Y-35, true);
|
||||||
g.setFont("HaxorNarrow7x17", 3);
|
g.setFont("HaxorNarrow7x17", 3);
|
||||||
g.drawString(day, X-60, Y+53, true);
|
g.drawString(day, X-60, Y+53, true);
|
||||||
g.drawString(month, X-100, Y+95, true);
|
g.drawString(month, X-100, Y+95, true);
|
||||||
g.drawString(dateNum, X-40, Y+95, true);
|
g.drawString(dateNum, X-40, Y+95, true);
|
||||||
g.drawString(year, X-90, Y-55, true);
|
g.drawString(year, X-90, Y-55, true);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//clear screen at startup
|
//clear screen at startup
|
||||||
g.clear();
|
g.clear();
|
||||||
//draw immediatly
|
//draw immediatly
|
||||||
draw();
|
draw();
|
||||||
|
|
||||||
var secondInterval = setInterval(draw, 1000);
|
var secondInterval = setInterval(draw, 1000);
|
||||||
// Stop updates when LCD is off, restart when on
|
// Stop updates when LCD is off, restart when on
|
||||||
|
|
@ -148,7 +57,7 @@ Bangle.on('lcdPower',on=>{
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Show launcher when button pressed
|
||||||
|
Bangle.setUI("clock");
|
||||||
Bangle.loadWidgets();
|
Bangle.loadWidgets();
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
|
|
||||||
setWatch(Bangle.showLauncher, BTN2, {repeat : false, edge: "falling"});
|
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
0.01: Based on the Analog Clock app, minimal dot
|
0.01: Based on the Analog Clock app, minimal dot
|
||||||
0.02: Remove hardcoded hour buzz (you can install widchime if you miss it)
|
0.02: Remove hardcoded hour buzz (you can install widchime if you miss it)
|
||||||
|
0.03: Use setUI, adjust for themes and different size screens
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,22 @@
|
||||||
let g;
|
const big = g.getWidth()>200;
|
||||||
let Bangle;
|
|
||||||
|
|
||||||
const locale = require('locale');
|
const locale = require('locale');
|
||||||
const p = Math.PI / 2;
|
const p = Math.PI / 2;
|
||||||
const pRad = Math.PI / 180;
|
const pRad = Math.PI / 180;
|
||||||
const faceWidth = 100; // watch face radius
|
|
||||||
let timer = null;
|
let timer = null;
|
||||||
let currentDate = new Date();
|
let currentDate = new Date();
|
||||||
let hourRadius = 60;
|
const faceWidth = big?100:65; // watch face radius
|
||||||
let minRadius = 80;
|
let hourRadius = big?60:40;
|
||||||
const centerPx = g.getWidth() / 2;
|
let minRadius = big?80:55;
|
||||||
|
const centerX = g.getWidth() / 2;
|
||||||
|
const centerY = 24 + (g.getHeight()-24) / 2;
|
||||||
|
let colSecA = g.theme.dark ? "#00A" : "#58F"; // before the second
|
||||||
|
let colSecB = g.theme.dark ? "#58F" : "#00A"; // after the second
|
||||||
|
let colSec1 = g.theme.dark ? "#F83" : "#000"; // ON the second
|
||||||
|
|
||||||
const seconds = (angle) => {
|
const seconds = (angle) => {
|
||||||
const a = angle * pRad;
|
const a = angle * pRad;
|
||||||
const x = centerPx + Math.sin(a) * faceWidth;
|
const x = centerX + Math.sin(a) * faceWidth;
|
||||||
const y = centerPx - Math.cos(a) * faceWidth;
|
const y = centerY - Math.cos(a) * faceWidth;
|
||||||
|
|
||||||
// if 15 degrees, make hour marker larger
|
// if 15 degrees, make hour marker larger
|
||||||
const radius = (angle % 15) ? 2 : 4;
|
const radius = (angle % 15) ? 2 : 4;
|
||||||
|
|
@ -23,15 +25,15 @@ const seconds = (angle) => {
|
||||||
|
|
||||||
const hourDot = (angle,radius) => {
|
const hourDot = (angle,radius) => {
|
||||||
const a = angle * pRad;
|
const a = angle * pRad;
|
||||||
const x = centerPx + Math.sin(a) * hourRadius;
|
const x = centerX + Math.sin(a) * hourRadius;
|
||||||
const y = centerPx - Math.cos(a) * hourRadius;
|
const y = centerY - Math.cos(a) * hourRadius;
|
||||||
g.fillCircle(x, y, radius);
|
g.fillCircle(x, y, radius);
|
||||||
};
|
};
|
||||||
|
|
||||||
const minDot = (angle,radius) => {
|
const minDot = (angle,radius) => {
|
||||||
const a = angle * pRad;
|
const a = angle * pRad;
|
||||||
const x = centerPx + Math.sin(a) * minRadius;
|
const x = centerX + Math.sin(a) * minRadius;
|
||||||
const y = centerPx - Math.cos(a) * minRadius;
|
const y = centerY - Math.cos(a) * minRadius;
|
||||||
g.fillCircle(x, y, radius);
|
g.fillCircle(x, y, radius);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -45,54 +47,49 @@ const drawAll = () => {
|
||||||
// draw all secs
|
// draw all secs
|
||||||
|
|
||||||
for (let i = 0; i < 60; i++) {
|
for (let i = 0; i < 60; i++) {
|
||||||
if (i > currentSec) {
|
g.setColor((i > currentSec) ? colSecA : colSecB);
|
||||||
g.setColor(0, 0, 0.6);
|
|
||||||
} else {
|
|
||||||
g.setColor(0.3, 0.3, 1);
|
|
||||||
}
|
|
||||||
seconds((360 * i) / 60);
|
seconds((360 * i) / 60);
|
||||||
}
|
}
|
||||||
onSecond();
|
onSecond();
|
||||||
};
|
};
|
||||||
|
|
||||||
const resetSeconds = () => {
|
const resetSeconds = () => {
|
||||||
g.setColor(0, 0, 0.6);
|
g.setColor(colSecA);
|
||||||
for (let i = 0; i < 60; i++) {
|
for (let i = 0; i < 60; i++) {
|
||||||
seconds((360 * i) / 60);
|
seconds((360 * i) / 60);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const drawMin = () => {
|
const drawMin = () => {
|
||||||
g.setColor(0.5, 0.5, 0.5);
|
g.setColor("#777");
|
||||||
for (let i = 0; i < 60; i++) {
|
for (let i = 0; i < 60; i++) {
|
||||||
minDot((360 * i) / 60,1);
|
minDot((360 * i) / 60,1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const drawHour = () => {
|
const drawHour = () => {
|
||||||
g.setColor(0.5, 0.5, 0.5);
|
g.setColor("#777");
|
||||||
for (let i = 0; i < 12; i++) {
|
for (let i = 0; i < 12; i++) {
|
||||||
hourDot((360 * 5 * i) / 60,1);
|
hourDot((360 * 5 * i) / 60,1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSecond = () => {
|
const onSecond = () => {
|
||||||
g.setColor(0.3, 0.3, 1);
|
g.setColor(colSecB);
|
||||||
seconds((360 * currentDate.getSeconds()) / 60);
|
seconds((360 * currentDate.getSeconds()) / 60);
|
||||||
if (currentDate.getSeconds() === 59) {
|
if (currentDate.getSeconds() === 59) {
|
||||||
resetSeconds();
|
resetSeconds();
|
||||||
onMinute();
|
onMinute();
|
||||||
}
|
}
|
||||||
g.setColor(1, 0.7, 0.2);
|
g.setColor(colSec1);
|
||||||
currentDate = new Date();
|
currentDate = new Date();
|
||||||
seconds((360 * currentDate.getSeconds()) / 60);
|
seconds((360 * currentDate.getSeconds()) / 60);
|
||||||
g.setColor(1, 1, 1);
|
g.setColor(g.theme.fg);
|
||||||
};
|
};
|
||||||
|
|
||||||
const drawDate = () => {
|
const drawDate = () => {
|
||||||
g.reset();
|
g.reset();
|
||||||
g.setColor(1, 1, 1);
|
g.setFont('6x8', big?2:1);
|
||||||
g.setFont('6x8', 2);
|
|
||||||
|
|
||||||
const dayString = locale.dow(currentDate, true);
|
const dayString = locale.dow(currentDate, true);
|
||||||
// pad left date
|
// pad left date
|
||||||
|
|
@ -101,7 +98,7 @@ const drawDate = () => {
|
||||||
// console.log(`${dayString}|${dateString}`);
|
// console.log(`${dayString}|${dateString}`);
|
||||||
// center date
|
// center date
|
||||||
const l = (g.getWidth() - g.stringWidth(dateDisplay)) / 2;
|
const l = (g.getWidth() - g.stringWidth(dateDisplay)) / 2;
|
||||||
const t = centerPx - 6 ;
|
const t = centerY - 6 ;
|
||||||
g.drawString(dateDisplay, l, t);
|
g.drawString(dateDisplay, l, t);
|
||||||
// console.log(l, t);
|
// console.log(l, t);
|
||||||
};
|
};
|
||||||
|
|
@ -111,7 +108,7 @@ const onMinute = () => {
|
||||||
resetSeconds();
|
resetSeconds();
|
||||||
}
|
}
|
||||||
// clear existing hands
|
// clear existing hands
|
||||||
g.setColor(0, 0, 0);
|
g.setColor(g.theme.bg);
|
||||||
hourDot((360 * currentDate.getHours()) / 12,4);
|
hourDot((360 * currentDate.getHours()) / 12,4);
|
||||||
minDot((360 * currentDate.getMinutes()) / 60,3);
|
minDot((360 * currentDate.getMinutes()) / 60,3);
|
||||||
|
|
||||||
|
|
@ -125,7 +122,7 @@ const onMinute = () => {
|
||||||
g.setColor(1, 0, 0);
|
g.setColor(1, 0, 0);
|
||||||
// Hour
|
// Hour
|
||||||
hourDot((360 * currentDate.getHours()) / 12,4);
|
hourDot((360 * currentDate.getHours()) / 12,4);
|
||||||
g.setColor(1, 0.9, 0.9);
|
g.setColor(g.theme.fg2);
|
||||||
// Minute
|
// Minute
|
||||||
minDot((360 * currentDate.getMinutes()) / 60,3);
|
minDot((360 * currentDate.getMinutes()) / 60,3);
|
||||||
drawDate();
|
drawDate();
|
||||||
|
|
@ -152,8 +149,8 @@ g.clear();
|
||||||
resetSeconds();
|
resetSeconds();
|
||||||
startTimers();
|
startTimers();
|
||||||
drawAll();
|
drawAll();
|
||||||
|
// Show launcher when button pressed
|
||||||
|
Bangle.setUI("clock");
|
||||||
|
|
||||||
Bangle.loadWidgets();
|
Bangle.loadWidgets();
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
|
|
||||||
// Show launcher when middle button pressed
|
|
||||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 9.8 KiB |
|
|
@ -1 +1,4 @@
|
||||||
0.01: New App!
|
0.01: New App!
|
||||||
|
0.02: added emulator capability and display of widgets
|
||||||
|
0.03: bug of advancing time fixed; doztime now correct within ca. 1 second
|
||||||
|
0.04: changed time colour from slightly off white to pure white
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,11 @@ const g_height_t = 48; // height of time region
|
||||||
const A1 = [30,30,30,30,31,31,31,31,31,31,30,30];
|
const A1 = [30,30,30,30,31,31,31,31,31,31,30,30];
|
||||||
const B1 = [30,30,30,30,30,31,31,31,31,31,30,30];
|
const B1 = [30,30,30,30,30,31,31,31,31,31,30,30];
|
||||||
const B2 = [30,30,30,30,31,31,31,31,31,30,30,30];
|
const B2 = [30,30,30,30,31,31,31,31,31,30,30,30];
|
||||||
const timeColour = "#f2f2f2";
|
const timeColour = "#ffffff";
|
||||||
const dateColours = ["#ff0000","#ffa500","#ffff00","#00b800","#0000ff","#ff00ff","#ff0080"];
|
const dateColours = ["#ff0000","#ffa500","#ffff00","#00b800","#0000ff","#ff00ff","#ff0080"];
|
||||||
const calen10 = {"size":32,"pt0":[32-g_x_off,16],"step":[20,0],"dx":-4.5,"dy":-4.5}; // positioning for usual calendar line
|
const calen10 = {"size":32,"pt0":[32-g_x_off,16],"step":[20,0],"dx":-4.5,"dy":-4.5}; // positioning for usual calendar line
|
||||||
const calen7 = {"size":32,"pt0":[62-g_x_off,16],"step":[20,0],"dx":-4.5,"dy":-4.5}; // positioning for S-day calendar line
|
const calen7 = {"size":32,"pt0":[62-g_x_off,16],"step":[20,0],"dx":-4.5,"dy":-4.5}; // positioning for S-day calendar line
|
||||||
const time5 = {"size":48,"pt0":[64-g_x_off,24],"step":[30,0],"dx":-6.5,"dy":-6.5}; // positioning for lull time line; was 64
|
const time5 = {"size":48,"pt0":[64-g_x_off,24],"step":[30,0],"dx":-6.5,"dy":-6.5}; // positioning for lull time line
|
||||||
const time6 = {"size":48,"pt0":[48-g_x_off,24],"step":[30,0],"dx":-6.5,"dy":-6.5}; // positioning for twinkling time line
|
const time6 = {"size":48,"pt0":[48-g_x_off,24],"step":[30,0],"dx":-6.5,"dy":-6.5}; // positioning for twinkling time line
|
||||||
const baseYear = 11584;
|
const baseYear = 11584;
|
||||||
const baseDate = Date(2020,11,21); // month values run from 0 to 11
|
const baseDate = Date(2020,11,21); // month values run from 0 to 11
|
||||||
|
|
@ -30,8 +30,11 @@ let lastX = 999999999;
|
||||||
let res = {};
|
let res = {};
|
||||||
//var last_time_log = 0;
|
//var last_time_log = 0;
|
||||||
|
|
||||||
|
var drawtime_timeout;
|
||||||
|
|
||||||
// Date and time graphics buffers
|
// Date and time graphics buffers
|
||||||
var dateColour = "#ffffff"; // override later
|
var dateColour = "#ffffff"; // override later
|
||||||
|
var timeColour2 = timeColour;
|
||||||
var g_d = Graphics.createArrayBuffer(g_width,g_height_d,1,{'msb':true});
|
var g_d = Graphics.createArrayBuffer(g_width,g_height_d,1,{'msb':true});
|
||||||
var g_t = Graphics.createArrayBuffer(g_width,g_height_t,1,{'msb':true});
|
var g_t = Graphics.createArrayBuffer(g_width,g_height_t,1,{'msb':true});
|
||||||
// Set screen mode and function to write graphics buffers
|
// Set screen mode and function to write graphics buffers
|
||||||
|
|
@ -46,7 +49,7 @@ g.flip = function()
|
||||||
height:g_height_d,
|
height:g_height_d,
|
||||||
buffer:g_d.buffer
|
buffer:g_d.buffer
|
||||||
}, g_x_off, g_y_off + g_y_off_d);
|
}, g_x_off, g_y_off + g_y_off_d);
|
||||||
g.setColor(timeColour);
|
g.setColor(timeColour2);
|
||||||
g.drawImage(
|
g.drawImage(
|
||||||
{
|
{
|
||||||
width:g_width,
|
width:g_width,
|
||||||
|
|
@ -118,7 +121,7 @@ function formatDate(res,dateFormat){
|
||||||
return(yyyy+"-"+m+"-"+w+"-"+d);
|
return(yyyy+"-"+m+"-"+w+"-"+d);
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeDozTime(text,def,colour){
|
function writeDozTime(text,def){
|
||||||
let pts = def.pts;
|
let pts = def.pts;
|
||||||
let x=def.pt0[0];
|
let x=def.pt0[0];
|
||||||
let y=def.pt0[1];
|
let y=def.pt0[1];
|
||||||
|
|
@ -133,6 +136,7 @@ function writeDozTime(text,def,colour){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function writeDozDate(text,def,colour){
|
function writeDozDate(text,def,colour){
|
||||||
|
|
||||||
dateColour = colour;
|
dateColour = colour;
|
||||||
let pts = def.pts;
|
let pts = def.pts;
|
||||||
let x=def.pt0[0];
|
let x=def.pt0[0];
|
||||||
|
|
@ -177,10 +181,10 @@ function drawTime()
|
||||||
{
|
{
|
||||||
// Write to background buffers, then display on screen
|
// Write to background buffers, then display on screen
|
||||||
writeDozDate(date,calenDef,res.colour);
|
writeDozDate(date,calenDef,res.colour);
|
||||||
writeDozTime(time,timeDef,timeColour);
|
writeDozTime(time,timeDef);
|
||||||
g.flip();
|
g.flip();
|
||||||
// Ready next interval
|
// Ready next interval
|
||||||
setTimeout(drawTime,wait);
|
drawtime_timeout = setTimeout(drawTime,wait);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -196,22 +200,14 @@ function modeTime()
|
||||||
timeActiveUntil = new Date();
|
timeActiveUntil = new Date();
|
||||||
timeActiveUntil.setDate(timeActiveUntil.getDate());
|
timeActiveUntil.setDate(timeActiveUntil.getDate());
|
||||||
timeActiveUntil.setSeconds(timeActiveUntil.getSeconds()+15);
|
timeActiveUntil.setSeconds(timeActiveUntil.getSeconds()+15);
|
||||||
//Bangle.setLCDPower(true);
|
if (typeof drawtime_timeout !== 'undefined')
|
||||||
clearTimeout();
|
{
|
||||||
|
clearTimeout(drawtime_timeout);
|
||||||
|
}
|
||||||
drawTime();
|
drawTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
Bangle.loadWidgets();
|
Bangle.loadWidgets();
|
||||||
|
Bangle.drawWidgets();
|
||||||
// Time-logging function
|
|
||||||
/*function logTime(label)
|
|
||||||
{
|
|
||||||
var d = new Date();
|
|
||||||
var t = d.getTime();
|
|
||||||
var diff_test = t - last_time_log;
|
|
||||||
last_time_log = t;
|
|
||||||
console.log(label + " at time: " + t + ", since last: " + diff_test);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Functions for weather mode - TODO
|
// Functions for weather mode - TODO
|
||||||
function drawWeather() {}
|
function drawWeather() {}
|
||||||
|
|
@ -222,4 +218,20 @@ Bangle.on('twist', function() {
|
||||||
modeTime();
|
modeTime();
|
||||||
});
|
});
|
||||||
|
|
||||||
Bangle.drawWidgets();
|
// Time fix with GPS
|
||||||
|
function fixTime() {
|
||||||
|
Bangle.on("GPS",function cb(g) {
|
||||||
|
Bangle.setGPSPower(0,"time");
|
||||||
|
Bangle.removeListener("GPS",cb);
|
||||||
|
if (!g.time || (g.time.getFullYear()<2000) ||
|
||||||
|
(g.time.getFullYear()>2200)) {
|
||||||
|
} else {
|
||||||
|
// We have a GPS time. Set time
|
||||||
|
setTime(g.time.getTime()/1000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Bangle.setGPSPower(1,"time");
|
||||||
|
setTimeout(fixTime, 10*60*1000); // every 10 minutes
|
||||||
|
}
|
||||||
|
// Start time fixing with GPS on next 10 minute interval
|
||||||
|
setTimeout(fixTime, ((60-(new Date()).getMinutes()) % 10) * 60 * 1000);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
0.01: Initial version
|
0.01: Initial version
|
||||||
0.02: Multiple pages
|
0.02: Multiple pages
|
||||||
0.03: cycle thru pages
|
0.03: cycle thru pages
|
||||||
|
0.04: reset to clock after 2 mins of inactivity
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,20 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
function wdog(handle,timeout){
|
||||||
|
if(handle !== undefined){
|
||||||
|
wdog.handle = handle;
|
||||||
|
wdog.timeout = timeout;
|
||||||
|
}
|
||||||
|
if(wdog.timer){
|
||||||
|
clearTimeout(wdog.timer)
|
||||||
|
}
|
||||||
|
wdog.timer = setTimeout(wdog.handle,wdog.timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset after two minutes of inactivity
|
||||||
|
wdog(load,120000)
|
||||||
|
|
||||||
var s = require("Storage");
|
var s = require("Storage");
|
||||||
var apps = s.list(/\.info$/).map(app=>{var a=s.readJSON(app,1);return a&&{name:a.name,type:a.type,icon:a.icon,sortorder:a.sortorder,src:a.src};}).filter(app=>app && (app.type=="app" || app.type=="clock" || !app.type));
|
var apps = s.list(/\.info$/).map(app=>{var a=s.readJSON(app,1);return a&&{name:a.name,type:a.type,icon:a.icon,sortorder:a.sortorder,src:a.src};}).filter(app=>app && (app.type=="app" || app.type=="clock" || !app.type));
|
||||||
apps.sort((a,b)=>{
|
apps.sort((a,b)=>{
|
||||||
|
|
@ -42,6 +56,7 @@ function drawPage(p){
|
||||||
}
|
}
|
||||||
|
|
||||||
Bangle.on("swipe",(dir)=>{
|
Bangle.on("swipe",(dir)=>{
|
||||||
|
wdog()
|
||||||
selected = 0;
|
selected = 0;
|
||||||
oldselected=-1;
|
oldselected=-1;
|
||||||
if (dir<0){
|
if (dir<0){
|
||||||
|
|
@ -54,6 +69,7 @@ Bangle.on("swipe",(dir)=>{
|
||||||
});
|
});
|
||||||
|
|
||||||
function nextapp(d){
|
function nextapp(d){
|
||||||
|
wdog();
|
||||||
oldselected = selected;
|
oldselected = selected;
|
||||||
selected+=d;
|
selected+=d;
|
||||||
selected = selected<0?5:selected>5?0:selected;
|
selected = selected<0?5:selected>5?0:selected;
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
0.01: First published version of app
|
0.01: First published version of app
|
||||||
|
0.02: Move to Bangle.setUI to launcher support
|
||||||
|
|
|
||||||
|
|
@ -1,206 +1,203 @@
|
||||||
{
|
var minutes;
|
||||||
var minutes;
|
var seconds;
|
||||||
var seconds;
|
var hours;
|
||||||
var hours;
|
var date;
|
||||||
var date;
|
var first = true;
|
||||||
var first = true;
|
var locale = require('locale');
|
||||||
var locale = require('locale');
|
var _12hour = (require("Storage").readJSON("setting.json", 1) || {})["12hour"] || false;
|
||||||
var _12hour = (require("Storage").readJSON("setting.json", 1) || {})["12hour"] || false;
|
|
||||||
|
|
||||||
//HR variables
|
//HR variables
|
||||||
var id = 0;
|
var id = 0;
|
||||||
var grow = true;
|
var grow = true;
|
||||||
var size=10;
|
var size=10;
|
||||||
|
|
||||||
//Screen dimensions
|
//Screen dimensions
|
||||||
const screen = {
|
const screen = {
|
||||||
width: g.getWidth(),
|
width: g.getWidth(),
|
||||||
height: g.getWidth(),
|
height: g.getWidth(),
|
||||||
middle: g.getWidth() / 2,
|
middle: g.getWidth() / 2,
|
||||||
center: g.getHeight() / 2,
|
center: g.getHeight() / 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Ssettings
|
// Ssettings
|
||||||
const settings = {
|
const settings = {
|
||||||
time: {
|
time: {
|
||||||
color: '#dddddd',
|
color: '#dddddd',
|
||||||
font: 'Vector',
|
font: 'Vector',
|
||||||
size: 100,
|
size: 100,
|
||||||
middle: screen.middle,
|
middle: screen.middle,
|
||||||
center: screen.center,
|
center: screen.center,
|
||||||
},
|
},
|
||||||
date: {
|
date: {
|
||||||
color: '#dddddd',
|
color: '#dddddd',
|
||||||
font: 'Vector',
|
font: 'Vector',
|
||||||
size: 15,
|
size: 15,
|
||||||
middle: screen.height-17, // at bottom of screen
|
middle: screen.height-17, // at bottom of screen
|
||||||
center: screen.center,
|
center: screen.center,
|
||||||
},
|
},
|
||||||
circle: {
|
circle: {
|
||||||
colormin: '#ffffff',
|
colormin: '#ffffff',
|
||||||
colorsec: '#ffffff',
|
colorsec: '#ffffff',
|
||||||
width: 10,
|
width: 10,
|
||||||
middle: screen.middle,
|
middle: screen.middle,
|
||||||
center: screen.center,
|
center: screen.center,
|
||||||
height: screen.height
|
height: screen.height
|
||||||
},
|
},
|
||||||
hr: {
|
hr: {
|
||||||
color: '#333333',
|
color: '#333333',
|
||||||
size: 20,
|
size: 20,
|
||||||
x: screen.center,
|
x: screen.center,
|
||||||
y: screen.middle + 65
|
y: screen.middle + 65
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const dateStr = function (date) {
|
const dateStr = function (date) {
|
||||||
return locale.date(new Date(), 1);
|
return locale.date(new Date(), 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getFormated = function(val) {
|
const getFormated = function(val) {
|
||||||
if (val<10) {
|
if (val<10) {
|
||||||
val='0'+val;
|
val='0'+val;
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
};
|
};
|
||||||
|
|
||||||
const drawMin = function (sections, color) {
|
const drawMin = function (sections, color) {
|
||||||
|
|
||||||
g.setFontAlign(0, 0, 0);
|
|
||||||
g.setColor('#000000');
|
|
||||||
g.setFont(settings.time.font, settings.time.size/2);
|
|
||||||
g.drawString(getFormated(sections-1), settings.time.center+50, settings.time.middle);
|
|
||||||
g.setColor(settings.time.color);
|
|
||||||
g.setFont(settings.time.font, settings.time.size/2);
|
|
||||||
g.drawString(getFormated(sections), settings.time.center+50, settings.time.middle);
|
|
||||||
};
|
|
||||||
|
|
||||||
const drawSec = function (sections, color) {
|
g.setFontAlign(0, 0, 0);
|
||||||
g.setFontAlign(0, 0, 0);
|
g.setColor('#000000');
|
||||||
g.setColor('#000000');
|
g.setFont(settings.time.font, settings.time.size/2);
|
||||||
g.setFont(settings.time.font, settings.time.size/4);
|
g.drawString(getFormated(sections-1), settings.time.center+50, settings.time.middle);
|
||||||
g.drawString(getFormated(sections-1), settings.time.center+100, settings.time.middle);
|
g.setColor(settings.time.color);
|
||||||
g.setColor(settings.time.color);
|
g.setFont(settings.time.font, settings.time.size/2);
|
||||||
g.setFont(settings.time.font, settings.time.size/4);
|
g.drawString(getFormated(sections), settings.time.center+50, settings.time.middle);
|
||||||
g.drawString(getFormated(sections), settings.time.center+100, settings.time.middle);
|
};
|
||||||
};
|
|
||||||
|
|
||||||
const drawClock = function () {
|
const drawSec = function (sections, color) {
|
||||||
|
g.setFontAlign(0, 0, 0);
|
||||||
|
g.setColor('#000000');
|
||||||
|
g.setFont(settings.time.font, settings.time.size/4);
|
||||||
|
g.drawString(getFormated(sections-1), settings.time.center+100, settings.time.middle);
|
||||||
|
g.setColor(settings.time.color);
|
||||||
|
g.setFont(settings.time.font, settings.time.size/4);
|
||||||
|
g.drawString(getFormated(sections), settings.time.center+100, settings.time.middle);
|
||||||
|
};
|
||||||
|
|
||||||
currentTime = new Date();
|
const drawClock = function () {
|
||||||
|
|
||||||
//Get date as a string
|
currentTime = new Date();
|
||||||
date = dateStr(currentTime);
|
|
||||||
|
|
||||||
if(seconds==59) {
|
|
||||||
g.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update minutes when needed
|
//Get date as a string
|
||||||
if (minutes != currentTime.getMinutes()) {
|
date = dateStr(currentTime);
|
||||||
minutes = currentTime.getMinutes();
|
|
||||||
drawMin(minutes, settings.circle.colormin);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Update seconds when needed
|
if(seconds==59) {
|
||||||
if (seconds != currentTime.getSeconds()) {
|
g.clear();
|
||||||
seconds = currentTime.getSeconds();
|
}
|
||||||
drawSec(seconds, settings.circle.colorsec);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Write the time as configured in the settings
|
// Update minutes when needed
|
||||||
hours = currentTime.getHours();
|
if (minutes != currentTime.getMinutes()) {
|
||||||
if (_12hour && hours > 13) {
|
minutes = currentTime.getMinutes();
|
||||||
hours = hours - 12;
|
drawMin(minutes, settings.circle.colormin);
|
||||||
}
|
}
|
||||||
|
|
||||||
var meridian;
|
//Update seconds when needed
|
||||||
|
if (seconds != currentTime.getSeconds()) {
|
||||||
|
seconds = currentTime.getSeconds();
|
||||||
|
drawSec(seconds, settings.circle.colorsec);
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof locale.meridian === "function") {
|
//Write the time as configured in the settings
|
||||||
meridian = locale.meridian(new Date());
|
hours = currentTime.getHours();
|
||||||
} else {
|
if (_12hour && hours > 13) {
|
||||||
meridian = "";
|
hours = hours - 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
var timestr;
|
var meridian;
|
||||||
|
|
||||||
if (meridian.length > 0 && _12hour) {
|
if (typeof locale.meridian === "function") {
|
||||||
timestr = hours + " " + meridian;
|
meridian = locale.meridian(new Date());
|
||||||
} else {
|
} else {
|
||||||
timestr = hours;
|
meridian = "";
|
||||||
}
|
}
|
||||||
g.setFontAlign(0, 0, 0);
|
|
||||||
g.setColor(settings.time.color);
|
|
||||||
g.setFont(settings.time.font, settings.time.size);
|
|
||||||
g.drawString(timestr, settings.time.center-40, settings.time.middle);
|
|
||||||
|
|
||||||
//Write the date as configured in the settings
|
var timestr;
|
||||||
g.setColor(settings.date.color);
|
|
||||||
g.setFont(settings.date.font, settings.date.size);
|
|
||||||
g.drawString(date, settings.date.center, settings.date.middle);
|
|
||||||
};
|
|
||||||
|
|
||||||
//setInterval for HR visualisation
|
if (meridian.length > 0 && _12hour) {
|
||||||
const newBeats = function (hr) {
|
timestr = hours + " " + meridian;
|
||||||
if (id != 0) {
|
} else {
|
||||||
changeInterval(id, 6e3 / hr.bpm);
|
timestr = hours;
|
||||||
} else {
|
}
|
||||||
id = setInterval(drawHR, 6e3 / hr.bpm);
|
g.setFontAlign(0, 0, 0);
|
||||||
}
|
g.setColor(settings.time.color);
|
||||||
};
|
g.setFont(settings.time.font, settings.time.size);
|
||||||
|
g.drawString(timestr, settings.time.center-40, settings.time.middle);
|
||||||
|
|
||||||
//visualize HR with circles pulsating
|
//Write the date as configured in the settings
|
||||||
const drawHR = function () {
|
g.setColor(settings.date.color);
|
||||||
if (grow && size < settings.hr.size) {
|
g.setFont(settings.date.font, settings.date.size);
|
||||||
size++;
|
g.drawString(date, settings.date.center, settings.date.middle);
|
||||||
}
|
};
|
||||||
|
|
||||||
if (!grow && size > 3) {
|
//setInterval for HR visualisation
|
||||||
size--;
|
const newBeats = function (hr) {
|
||||||
}
|
if (id != 0) {
|
||||||
|
changeInterval(id, 6e3 / hr.bpm);
|
||||||
|
} else {
|
||||||
|
id = setInterval(drawHR, 6e3 / hr.bpm);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (size == settings.hr.size || size == 3) {
|
//visualize HR with circles pulsating
|
||||||
grow = !grow;
|
const drawHR = function () {
|
||||||
}
|
if (grow && size < settings.hr.size) {
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
|
||||||
if (grow) {
|
if (!grow && size > 3) {
|
||||||
color = settings.hr.color;
|
size--;
|
||||||
g.setColor(color);
|
}
|
||||||
g.fillCircle(settings.hr.x, settings.hr.y, size);
|
|
||||||
} else {
|
|
||||||
color = "#000000";
|
|
||||||
g.setColor(color);
|
|
||||||
g.drawCircle(settings.hr.x, settings.hr.y, size);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// clean app screen
|
if (size == settings.hr.size || size == 3) {
|
||||||
g.clear();
|
grow = !grow;
|
||||||
Bangle.loadWidgets();
|
}
|
||||||
Bangle.drawWidgets();
|
|
||||||
|
|
||||||
//manage when things should be enabled and not
|
if (grow) {
|
||||||
Bangle.on('lcdPower', function (on) {
|
color = settings.hr.color;
|
||||||
if (on) {
|
g.setColor(color);
|
||||||
Bangle.setHRMPower(1);
|
g.fillCircle(settings.hr.x, settings.hr.y, size);
|
||||||
} else {
|
} else {
|
||||||
Bangle.setHRMPower(0);
|
color = "#000000";
|
||||||
}
|
g.setColor(color);
|
||||||
});
|
g.drawCircle(settings.hr.x, settings.hr.y, size);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// refesh every second
|
// clean app screen
|
||||||
setInterval(drawClock, 1E3);
|
g.clear();
|
||||||
|
Bangle.loadWidgets();
|
||||||
|
Bangle.drawWidgets();
|
||||||
|
|
||||||
//start HR monitor and update frequency of update
|
//manage when things should be enabled and not
|
||||||
Bangle.setHRMPower(1);
|
Bangle.on('lcdPower', function (on) {
|
||||||
Bangle.on('HRM', function (d) {
|
if (on) {
|
||||||
newBeats(d);
|
Bangle.setHRMPower(1);
|
||||||
});
|
} else {
|
||||||
|
Bangle.setHRMPower(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// draw now
|
// refesh every second
|
||||||
drawClock();
|
setInterval(drawClock, 1E3);
|
||||||
|
|
||||||
// Show launcher when middle button pressed
|
//start HR monitor and update frequency of update
|
||||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
Bangle.setHRMPower(1);
|
||||||
|
Bangle.on('HRM', function (d) {
|
||||||
|
newBeats(d);
|
||||||
|
});
|
||||||
|
|
||||||
}
|
// draw now
|
||||||
|
drawClock();
|
||||||
|
|
||||||
|
// Show launcher when button pressed
|
||||||
|
Bangle.setUI("clock");
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,5 @@
|
||||||
0.03: Add support for data files
|
0.03: Add support for data files
|
||||||
0.04: Add functionality to sort apps manually or alphabetically ascending/descending.
|
0.04: Add functionality to sort apps manually or alphabetically ascending/descending.
|
||||||
0.05: Tweaks to help with memory usage
|
0.05: Tweaks to help with memory usage
|
||||||
0.06: Reduce memory usage
|
0.06: Reduce memory usage
|
||||||
|
0.07: Allow negative numbers when manual-sorting
|
||||||
|
|
@ -180,7 +180,7 @@ function showSortAppsManually() {
|
||||||
appList.reduce((menu, app) => {
|
appList.reduce((menu, app) => {
|
||||||
menu[app.name] = {
|
menu[app.name] = {
|
||||||
value: app.sortorder || 0,
|
value: app.sortorder || 0,
|
||||||
min: 0,
|
min: -appList.length,
|
||||||
max: appList.length,
|
max: appList.length,
|
||||||
step: 1,
|
step: 1,
|
||||||
onchange: val => setSortorder(app, val)
|
onchange: val => setSortorder(app, val)
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
0.01: First released version
|
0.01: First released version
|
||||||
|
0.02: Changed setWatch to Bangle.setUI
|
||||||
|
|
|
||||||
|
|
@ -243,5 +243,5 @@ startTimers();
|
||||||
Bangle.loadWidgets();
|
Bangle.loadWidgets();
|
||||||
drawAll();
|
drawAll();
|
||||||
|
|
||||||
// Show launcher when middle button pressed
|
// Show launcher when button pressed
|
||||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
Bangle.setUI("clock");
|
||||||
|
|
|
||||||
|
|
@ -22,3 +22,4 @@
|
||||||
0.20: Reduce memory usage
|
0.20: Reduce memory usage
|
||||||
0.21: Fix HRM setting
|
0.21: Fix HRM setting
|
||||||
0.22: Respect Quiet Mode
|
0.22: Respect Quiet Mode
|
||||||
|
0.23: Allow notification dismiss to remove from phone too
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
(() => {
|
(() => {
|
||||||
|
// Current shown notification, saved for dismissing.
|
||||||
|
var currentNot = null;
|
||||||
|
|
||||||
// Music handling
|
// Music handling
|
||||||
const state = {
|
const state = {
|
||||||
music: "stop",
|
music: "stop",
|
||||||
|
|
@ -151,16 +154,23 @@
|
||||||
global.GB = (event) => {
|
global.GB = (event) => {
|
||||||
switch (event.t) {
|
switch (event.t) {
|
||||||
case "notify":
|
case "notify":
|
||||||
case "notify-":
|
currentNot = prettifyNotificationEvent(event);
|
||||||
if (event.t === "notify") {
|
currentNot.onHide = function() {
|
||||||
require("notify").show(prettifyNotificationEvent(event));
|
// when notification hidden, remove from phone
|
||||||
if (!(require('Storage').readJSON('setting.json',1)||{}).quiet) {
|
gbSend({ t:"notify", n:"DISMISS", id:currentNot.id });
|
||||||
Bangle.buzz();
|
};
|
||||||
}
|
require("notify").show(currentNot);
|
||||||
} else { // notify-
|
if (!(require('Storage').readJSON('setting.json',1)||{}).quiet) {
|
||||||
require("notify").hide(event);
|
Bangle.buzz();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "notify-":
|
||||||
|
currentNot.t = "notify";
|
||||||
|
currentNot.n = "DISMISS";
|
||||||
|
gbSend(currentNot);
|
||||||
|
currentNot = null;
|
||||||
|
require("notify").hide(event);
|
||||||
|
break;
|
||||||
case "musicinfo":
|
case "musicinfo":
|
||||||
state.musicInfo = event;
|
state.musicInfo = event;
|
||||||
updateMusic({on: false});
|
updateMusic({on: false});
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
0.01: New App!
|
0.01: New App!
|
||||||
0.02: BTN2->launcher, use smaller text to allow "20:00" to fit on screen
|
0.02: BTN2->launcher, use smaller text to allow "20:00" to fit on screen
|
||||||
|
0.03: Changed setWatch to Bangle.setUI
|
||||||
|
|
|
||||||
|
|
@ -148,4 +148,5 @@ Bangle.drawWidgets();
|
||||||
iterate();
|
iterate();
|
||||||
animInterval = setInterval(iterate, 50);
|
animInterval = setInterval(iterate, 50);
|
||||||
|
|
||||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
// Show launcher when button pressed
|
||||||
|
Bangle.setUI("clock");
|
||||||
|
|
|
||||||
|
|
@ -21,3 +21,6 @@
|
||||||
0.17: Disable recording if storage is full (fix #574)
|
0.17: Disable recording if storage is full (fix #574)
|
||||||
0.18: Period counter now uses GPS time rather than counting packets (allows use with GPS Setup)
|
0.18: Period counter now uses GPS time rather than counting packets (allows use with GPS Setup)
|
||||||
0.19: Fix memory usage issues inside track viewer app
|
0.19: Fix memory usage issues inside track viewer app
|
||||||
|
0.20: Add documentation to explain time needed for getting a time fix
|
||||||
|
0.21: Fix issue where a period of 1s recorded every 2s, 5s every 6s, and so on
|
||||||
|
0.22: Ensure Bangle.setGPSPower uses 'gpsrec' as a tag
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
# GPS Recorder
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
This app allows you to record a GPS track. It can run in background. The data can later be exported as KML or GPX files via the BangleJS app store.
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
When you turn on recording, a widget badge that looks like a satellite will appear immediately at the top of the screen. However, the recording does not begin immediately. It usually takes several minutes for the watch to get a [GPS fix](https://en.wikipedia.org/wiki/Time_to_first_fix). You will notice a blinking question mark at the lower left of the badge indicating currently getting a fix. The badge will change when a GPS fix is achieved and that is when the app actually starts writing data to the log file. You can [upload assistant files](https://banglejs.com/apps/#assisted%20gps%20update) to speed up the time spent on getting a GPS fix.
|
||||||
|
|
||||||
|
|
@ -95,6 +95,7 @@ function getTrackList() {
|
||||||
Util.showModal("Loading Tracks...");
|
Util.showModal("Loading Tracks...");
|
||||||
domTracks.innerHTML = "";
|
domTracks.innerHTML = "";
|
||||||
Puck.write(`\x10(function() {
|
Puck.write(`\x10(function() {
|
||||||
|
Bluetooth.println("");
|
||||||
for (var n=0;n<36;n++) {
|
for (var n=0;n<36;n++) {
|
||||||
var f = require("Storage").open(".gpsrc"+n.toString(36),"r");
|
var f = require("Storage").open(".gpsrc"+n.toString(36),"r");
|
||||||
var l = f.readLine();
|
var l = f.readLine();
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
var period = 1000000;
|
var period = 1000000;
|
||||||
if (lastFixTime!==undefined)
|
if (lastFixTime!==undefined)
|
||||||
period = fix.time.getTime() - lastFixTime;
|
period = fix.time.getTime() - lastFixTime;
|
||||||
if (period > settings.period*1000) {
|
if (period+500 > settings.period*1000) { // round up
|
||||||
lastFixTime = fix.time.getTime();
|
lastFixTime = fix.time.getTime();
|
||||||
try {
|
try {
|
||||||
if (gpsTrack) gpsTrack.write([
|
if (gpsTrack) gpsTrack.write([
|
||||||
|
|
@ -69,7 +69,7 @@
|
||||||
gpsTrack = undefined;
|
gpsTrack = undefined;
|
||||||
}
|
}
|
||||||
if (gOn != gpsOn) {
|
if (gOn != gpsOn) {
|
||||||
Bangle.setGPSPower(gOn);
|
Bangle.setGPSPower(gOn,"gpsrec");
|
||||||
gpsOn = gOn;
|
gpsOn = gOn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
A configurable, low power GPS widget that runs in the background.
|
A configurable, low power GPS widget that runs in the background.
|
||||||
|
|
||||||
|
NOTE: This app has been superceded by [gpssetup](https://github.com/espruino/BangleApps/blob/master/apps/gpssetup/README.md)
|
||||||
|
|
||||||
|
|
||||||
## Goals
|
## Goals
|
||||||
|
|
||||||
To develop a low power GPS widget that runs in the background and to
|
To develop a low power GPS widget that runs in the background and to
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
0.01: base code
|
||||||
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Hi-Contrast Clock
|
||||||
|
|
||||||
|
A High-contrast, black-on-white or white-on-black clock displaying huge pixel digits. It is purposed for being both elegant and readable in high luminosity environments. The goal is to keep the clock as simple and efficient as possible.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
* BTN 1 switches between the two modes : black-on-white or white-on-black
|
||||||
|
* That's it!
|
||||||
|
|
||||||
|
## Issues and Requests
|
||||||
|
|
||||||
|
If you have issues, feel free to contact me at https://github.com/peeweek/
|
||||||
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
E.toArrayBuffer(atob("MDAB////////////////////////////////////////////////////////////////////////////////4AABgAAH4AABgAAH///5n//n///5n//n4AABn//n4AABn//n5///n//n5///n//n4AABgAAH4AABgAAH/////////////////////////015urF//3d+vZt//1V5uNV/////////////////5//5gAAH5//5gAAH5//5n//n5//5n//n4AABgAAH4AABgAAH///5n//n///5n//n///5gAAH///5gAAH////////////////////////////////////////////////////////////////////////////////"))
|
||||||
|
After Width: | Height: | Size: 368 B |
|
|
@ -0,0 +1,210 @@
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
// Numbers Rect order (left, top, right, bottom)
|
||||||
|
// Each number defines a set of rects to draw
|
||||||
|
|
||||||
|
const numbers =
|
||||||
|
[
|
||||||
|
[// Zero
|
||||||
|
[0, 0, 1, 0.2],
|
||||||
|
[0, 0.8, 1, 1],
|
||||||
|
[0, 0, 0.1, 1],
|
||||||
|
[0.9, 0, 1, 1]
|
||||||
|
],
|
||||||
|
[// One
|
||||||
|
[0.7, 0, 1, 0.2],
|
||||||
|
[0.9, 0, 1, 1]
|
||||||
|
],
|
||||||
|
[// Two
|
||||||
|
[0, 0, 1, 0.2],
|
||||||
|
[0, 0.4, 1, 0.6],
|
||||||
|
[0, 0.8, 1, 1],
|
||||||
|
[0, 0.4, 0.1, 1],
|
||||||
|
[0.9, 0, 1, 0.6]
|
||||||
|
],
|
||||||
|
[// Three
|
||||||
|
[0, 0, 1, 0.2],
|
||||||
|
[0.5, 0.4, 1, 0.6],
|
||||||
|
[0, 0.8, 1, 1],
|
||||||
|
[0.9, 0, 1, 1]
|
||||||
|
],
|
||||||
|
[// Four
|
||||||
|
[0, 0.4, 1, 0.6],
|
||||||
|
[0, 0, 0.1, 0.6],
|
||||||
|
[0.9, 0, 1, 1]
|
||||||
|
],
|
||||||
|
[// Five
|
||||||
|
[0, 0, 1, 0.2],
|
||||||
|
[0, 0.4, 1, 0.6],
|
||||||
|
[0, 0.8, 1, 1],
|
||||||
|
[0, 0, 0.1, 0.6],
|
||||||
|
[0.9, 0.4, 1, 1]
|
||||||
|
],
|
||||||
|
[// Six
|
||||||
|
[0, 0, 1, 0.2],
|
||||||
|
[0, 0.4, 1, 0.6],
|
||||||
|
[0, 0.8, 1, 1],
|
||||||
|
[0, 0, 0.1, 1.0],
|
||||||
|
[0.9, 0.4, 1, 1]
|
||||||
|
],
|
||||||
|
[// Seven
|
||||||
|
[0.0, 0, 1, 0.2],
|
||||||
|
[0.9, 0, 1, 1]
|
||||||
|
],
|
||||||
|
[// Eight
|
||||||
|
[0, 0, 1, 0.2],
|
||||||
|
[0, 0.4, 1, 0.6],
|
||||||
|
[0, 0.8, 1, 1],
|
||||||
|
[0, 0, 0.1, 1],
|
||||||
|
[0.9, 0, 1, 1]
|
||||||
|
],
|
||||||
|
[// Nine
|
||||||
|
[0, 0, 1, 0.2],
|
||||||
|
[0, 0.4, 1, 0.6],
|
||||||
|
[0, 0.8, 1, 1],
|
||||||
|
[0, 0, 0.1, 0.6],
|
||||||
|
[0.9, 0, 1, 1]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
const months = [ "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" ];
|
||||||
|
|
||||||
|
const interval = 1000; // in ms
|
||||||
|
const top = 32;
|
||||||
|
|
||||||
|
let ampm = (require("Storage").readJSON("setting.json",1)||{})["12hour"];
|
||||||
|
|
||||||
|
let bg = 255;
|
||||||
|
let fg = 0;
|
||||||
|
|
||||||
|
let mins = -1;
|
||||||
|
let hour = -1;
|
||||||
|
let day = -1;
|
||||||
|
|
||||||
|
function redraw() {
|
||||||
|
mins = -1;
|
||||||
|
hour = -1;
|
||||||
|
day = -1;
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
function refresh() {
|
||||||
|
g.setColor(bg,bg,bg);
|
||||||
|
g.fillRect(0,45,240,210);
|
||||||
|
Bangle.drawWidgets();
|
||||||
|
updateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTime()
|
||||||
|
{
|
||||||
|
let now = new Date();
|
||||||
|
let m = now.getMinutes();
|
||||||
|
let h = now.getHours();
|
||||||
|
let mo = now.getMonth();
|
||||||
|
let y = now.getFullYear();
|
||||||
|
let d = now.getDate();
|
||||||
|
|
||||||
|
if(h != hour)
|
||||||
|
{
|
||||||
|
hour = h;
|
||||||
|
g.setColor(bg,bg,bg);
|
||||||
|
g.fillRect(0,60,240,110);
|
||||||
|
g.setColor(fg,fg,fg);
|
||||||
|
if(ampm)
|
||||||
|
h = h%12;
|
||||||
|
drawDigits(60, h);
|
||||||
|
}
|
||||||
|
if(m != mins)
|
||||||
|
{
|
||||||
|
mins = m;
|
||||||
|
g.setColor(bg,bg,bg);
|
||||||
|
g.fillRect(0,145,240,195);
|
||||||
|
g.setColor(fg,fg,fg);
|
||||||
|
drawDigits(145, mins);
|
||||||
|
}
|
||||||
|
if(d != day)
|
||||||
|
{
|
||||||
|
day = d;
|
||||||
|
g.setFont("6x8", 2);
|
||||||
|
g.setFontAlign(0, -1, 0);
|
||||||
|
g.drawString(fmtDate(d,mo,y,hour), 120, 120);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawDigits(x, value)
|
||||||
|
{
|
||||||
|
if(!Bangle.isLCDOn()) // No need to draw when LCD Off
|
||||||
|
return;
|
||||||
|
|
||||||
|
drawChar(Math.floor(value/10), 15, x, 115, x+50);
|
||||||
|
if(value%10 == 1)
|
||||||
|
drawChar(value%10, 55, x, 155, x+50);
|
||||||
|
else
|
||||||
|
drawChar(value%10, 125, x, 225, x+50);
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawChar(i, xMin, yMin, xMax, yMax)
|
||||||
|
{
|
||||||
|
numbers[i].forEach(rect => {
|
||||||
|
r = place(rect, xMin, yMin, xMax, yMax);
|
||||||
|
g.setColor(fg,fg,fg);
|
||||||
|
g.fillRect(r[0], r[1], r[2], r[3]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function place(array, xMin, yMin, xMax, yMax)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
lerp(xMin,xMax,array[0]),
|
||||||
|
lerp(yMin,yMax,array[1]),
|
||||||
|
lerp(xMin,xMax,array[2]),
|
||||||
|
lerp(yMin,yMax,array[3])
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function lerp(a,b,t)
|
||||||
|
{
|
||||||
|
return a + t*(b-a);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fmtDate(day,month,year,hour)
|
||||||
|
{
|
||||||
|
if(ampm)
|
||||||
|
{
|
||||||
|
let ap = "(AM)";
|
||||||
|
if(hour == 0 || hour > 12)
|
||||||
|
ap = "(PM)";
|
||||||
|
return months[month] + " " + day + " " + year + " "+ ap;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return months[month] + ". " + day + " " + year;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handles Flipping colors, then refreshes the UI
|
||||||
|
function flipColors()
|
||||||
|
{
|
||||||
|
let t = bg;
|
||||||
|
bg = fg;
|
||||||
|
fg = t;
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// MAIN FUNCTION()
|
||||||
|
//
|
||||||
|
|
||||||
|
// Initialize
|
||||||
|
g.clear();
|
||||||
|
Bangle.loadWidgets();
|
||||||
|
redraw();
|
||||||
|
|
||||||
|
// Define Refresh Interval
|
||||||
|
setInterval(updateTime, interval);
|
||||||
|
|
||||||
|
// Handle Button Press
|
||||||
|
setWatch(flipColors, BTN1, true);
|
||||||
|
setWatch(Bangle.showLauncher, BTN2, false);
|
||||||
|
|
||||||
|
// Handle redraw on LCD on / fullscreen notifications dismissed
|
||||||
|
Bangle.on('lcdPower', (on) => { if(on) redraw(); });
|
||||||
|
|
@ -2,3 +2,4 @@
|
||||||
0.02: Use HRM data and calculations from Bangle.js (don't access hardware directly)
|
0.02: Use HRM data and calculations from Bangle.js (don't access hardware directly)
|
||||||
0.03: Fix timing issues, and use 1/2 scale to keep graph on screen
|
0.03: Fix timing issues, and use 1/2 scale to keep graph on screen
|
||||||
0.04: Update for new firmwares that have a 'HRM-raw' event
|
0.04: Update for new firmwares that have a 'HRM-raw' event
|
||||||
|
0.05: Tweaks for 'HRM-raw' handling
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ Bangle.setLCDTimeout(0);
|
||||||
Bangle.setHRMPower(1);
|
Bangle.setHRMPower(1);
|
||||||
var hrmInfo, hrmOffset = 0;
|
var hrmInfo, hrmOffset = 0;
|
||||||
var hrmInterval;
|
var hrmInterval;
|
||||||
|
var btm = g.getHeight()-1;
|
||||||
|
|
||||||
function onHRM(h) {
|
function onHRM(h) {
|
||||||
if (counter!==undefined) {
|
if (counter!==undefined) {
|
||||||
// the first time we're called remove
|
// the first time we're called remove
|
||||||
|
|
@ -26,7 +28,7 @@ function onHRM(h) {
|
||||||
|
|
||||||
var px = g.getWidth()/2;
|
var px = g.getWidth()/2;
|
||||||
g.setFontAlign(0,0);
|
g.setFontAlign(0,0);
|
||||||
g.clearRect(0,24,239,90);
|
g.clearRect(0,24,239,80);
|
||||||
g.setFont("6x8").drawString("Confidence "+hrmInfo.confidence+"%", px, 75);
|
g.setFont("6x8").drawString("Confidence "+hrmInfo.confidence+"%", px, 75);
|
||||||
var str = hrmInfo.bpm;
|
var str = hrmInfo.bpm;
|
||||||
g.setFontVector(40).drawString(str,px,45);
|
g.setFontVector(40).drawString(str,px,45);
|
||||||
|
|
@ -38,17 +40,21 @@ Bangle.on('HRM', onHRM);
|
||||||
/* On newer (2v10) firmwares we can subscribe to get
|
/* On newer (2v10) firmwares we can subscribe to get
|
||||||
HRM events as they happen */
|
HRM events as they happen */
|
||||||
Bangle.on('HRM-raw', function(v) {
|
Bangle.on('HRM-raw', function(v) {
|
||||||
var a = v.raw;
|
|
||||||
hrmOffset++;
|
hrmOffset++;
|
||||||
if (hrmOffset>g.getWidth()) {
|
if (hrmOffset>g.getWidth()) {
|
||||||
hrmOffset=0;
|
hrmOffset=0;
|
||||||
g.clearRect(0,90,239,239);
|
g.clearRect(0,80,239,239);
|
||||||
g.moveTo(-100,0);
|
g.moveTo(-100,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
y = E.clip(170 - (v.raw*2),100,230);
|
y = E.clip(btm-v.filt/4,btm-10,btm);
|
||||||
g.setColor(1,1,1);
|
g.setColor(1,0,0).fillRect(hrmOffset,btm, hrmOffset, y);
|
||||||
g.lineTo(hrmOffset, y);
|
y = E.clip(170 - (v.raw/2),80,btm);
|
||||||
|
g.setColor(g.theme.fg).lineTo(hrmOffset, y);
|
||||||
|
if (counter !==undefined) {
|
||||||
|
counter = undefined;
|
||||||
|
g.clear();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// It takes 5 secs for us to get the first HRM event
|
// It takes 5 secs for us to get the first HRM event
|
||||||
|
|
@ -80,7 +86,6 @@ function readHRM() {
|
||||||
var a = hrmInfo.raw[hrmOffset];
|
var a = hrmInfo.raw[hrmOffset];
|
||||||
hrmOffset++;
|
hrmOffset++;
|
||||||
y = E.clip(170 - (a*2),100,230);
|
y = E.clip(170 - (a*2),100,230);
|
||||||
g.setColor(1,1,1);
|
g.setColor(g.theme.fg).lineTo(hrmOffset, y);
|
||||||
g.lineTo(hrmOffset, y);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,5 @@
|
||||||
Scaling for background images <240px wide
|
Scaling for background images <240px wide
|
||||||
0.05: Fix memory/interval leak when LCD turns on
|
0.05: Fix memory/interval leak when LCD turns on
|
||||||
0.06: Support 12 hour time
|
0.06: Support 12 hour time
|
||||||
0.07: Don't cut off wide date formats
|
0.07: Don't cut off wide date formats
|
||||||
|
0.08: Use Bangle.setUI for button/launcher handling
|
||||||
|
|
|
||||||
|
|
@ -84,5 +84,5 @@ Bangle.on('lcdPower',on=>{
|
||||||
draw();
|
draw();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Show launcher when middle button pressed
|
// Show launcher when button pressed
|
||||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
Bangle.setUI("clock");
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
0.01: New App!
|
0.01: New App!
|
||||||
0.02: Stopped watchface from flashing every interval
|
0.02: Stopped watchface from flashing every interval
|
||||||
|
0.03: Move to Bangle.setUI to launcher support
|
||||||
|
|
|
||||||
|
|
@ -47,10 +47,9 @@ const activeColorNight = 0xF800 /*red*/ ;
|
||||||
const activeColorDay = 0xFFFF /* white */;
|
const activeColorDay = 0xFFFF /* white */;
|
||||||
|
|
||||||
var hidxPrev;
|
var hidxPrev;
|
||||||
|
var showDigitalTime = false;
|
||||||
|
|
||||||
function drawWordClock() {
|
function drawWordClock() {
|
||||||
|
|
||||||
|
|
||||||
// get time
|
// get time
|
||||||
var t = new Date();
|
var t = new Date();
|
||||||
var h = t.getHours();
|
var h = t.getHours();
|
||||||
|
|
@ -141,7 +140,7 @@ function drawWordClock() {
|
||||||
|
|
||||||
// Display digital time while button 1 is pressed
|
// Display digital time while button 1 is pressed
|
||||||
g.clearRect(0, 215, 240, 240);
|
g.clearRect(0, 215, 240, 240);
|
||||||
if (BTN1.read()){
|
if (showDigitalTime){
|
||||||
g.setColor(activeColor);
|
g.setColor(activeColor);
|
||||||
g.drawString(time, 120, 215);
|
g.drawString(time, 120, 215);
|
||||||
}
|
}
|
||||||
|
|
@ -158,8 +157,20 @@ Bangle.drawWidgets();
|
||||||
setInterval(drawWordClock, 1E4);
|
setInterval(drawWordClock, 1E4);
|
||||||
drawWordClock();
|
drawWordClock();
|
||||||
|
|
||||||
// Show digital time while top button is pressed
|
// Show digital time while top button is pressed (if we have physical buttons)
|
||||||
setWatch(drawWordClock, BTN1, {repeat:true,edge:"both"});
|
if (global.BTN3) setWatch(function() {
|
||||||
|
showDigitalTime = BTN1.read();
|
||||||
|
drawWordClock();
|
||||||
|
}, BTN1, {repeat:true,edge:"both"});
|
||||||
|
|
||||||
// Show launcher when middle button pressed
|
// If LCD pressed (on Bangle.js 2) draw digital time
|
||||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
Bangle.on('drag',e=>{
|
||||||
|
var pressed = e.b!=0;
|
||||||
|
if (pressed!=showDigitalTime) {
|
||||||
|
showDigitalTime = pressed;
|
||||||
|
drawWordClock();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Show launcher when button pressed
|
||||||
|
Bangle.setUI("clock");
|
||||||
|
|
|
||||||