pull/783/head
adrian w kirk 2021-08-04 00:10:33 +01:00
commit 581e2773d7
84 changed files with 1822 additions and 707 deletions

124
apps.json
View File

@ -4,7 +4,7 @@
"tags": "tool,system,b2",
"type":"bootloader",
"icon": "bootloader.png",
"version":"0.27",
"version":"0.28",
"description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings",
"storage": [
{"name":".boot0","url":"boot0.js"},
@ -94,7 +94,7 @@
"name": "Notifications (default)",
"shortName":"Notifications",
"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",
"tags": "widget",
"type": "notify",
@ -107,7 +107,7 @@
"name": "Fullscreen Notifications",
"shortName":"Notifications",
"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.",
"tags": "widget",
"type": "notify",
@ -153,7 +153,7 @@
{ "id": "gbridge",
"name": "Gadgetbridge",
"icon": "app.png",
"version":"0.22",
"version":"0.23",
"description": "The default notification handler for Gadgetbridge notifications from Android",
"tags": "tool,system,android,widget",
"readme": "README.md",
@ -171,7 +171,7 @@
{ "id": "mclock",
"name": "Morphing Clock",
"icon": "clock-morphing.png",
"version":"0.06",
"version":"0.07",
"description": "7 segment clock that morphs between minutes and hours",
"tags": "clock",
"type":"clock",
@ -258,7 +258,7 @@
{ "id": "slidingtext",
"name": "Sliding Clock",
"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",
"tags": "clock",
"type":"clock",
@ -323,7 +323,7 @@
"name": "Image background clock",
"shortName":"Image Clock",
"icon": "app.png",
"version":"0.07",
"version":"0.08",
"description": "A clock with an image as a background",
"tags": "clock",
"type" : "clock",
@ -339,7 +339,7 @@
{ "id": "impwclock",
"name": "Imprecise Word Clock",
"icon": "clock-impword.png",
"version":"0.02",
"version":"0.03",
"description": "Imprecise word clock for vacations, weekends, and those who never need accurate time.",
"tags": "clock",
"type":"clock",
@ -560,7 +560,7 @@
{ "id": "files",
"name": "App Manager",
"icon": "files.png",
"version":"0.06",
"version":"0.07",
"description": "Show currently installed apps, free space, and allow their deletion from the watch",
"tags": "tool,system,files",
"storage": [
@ -710,7 +710,7 @@
{ "id": "hrm",
"name": "Heart Rate Monitor",
"icon": "heartrate.png",
"version":"0.04",
"version":"0.05",
"description": "Measure your heart rate and see live sensor data",
"tags": "health",
"storage": [
@ -892,7 +892,7 @@
{ "id": "sclock",
"name": "Simple Clock",
"icon": "clock-simple.png",
"version":"0.05",
"version":"0.06",
"description": "A Simple Digital Clock",
"tags": "clock,b2",
"type":"clock",
@ -931,7 +931,7 @@
{ "id": "svclock",
"name": "Simple V-Clock",
"icon": "vclock-simple.png",
"version":"0.01",
"version":"0.02",
"description": "Modification of Simple Clock 0.04 to use Vectorfont",
"tags": "clock",
"type":"clock",
@ -1057,7 +1057,7 @@
{ "id": "miclock",
"name": "Mixed Clock",
"icon": "clock-mixed.png",
"version":"0.04",
"version":"0.05",
"description": "A mix of analog and digital Clock",
"tags": "clock",
"type":"clock",
@ -1271,6 +1271,19 @@
{"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",
"name": "Workout HRM",
"icon": "app.png",
@ -1490,7 +1503,7 @@
{ "id": "minionclk",
"name": "Minion clock",
"icon": "minionclk.png",
"version": "0.04",
"version": "0.05",
"description": "Minion themed clock.",
"tags": "clock,minion",
"type": "clock",
@ -1773,7 +1786,7 @@
"name": "Black Jack game",
"shortName":"Black Jack game",
"icon": "blackjack.png",
"version":"0.01",
"version":"0.02",
"description": "Simple implementation of card game Black Jack",
"tags": "game",
"allow_emulator":true,
@ -1799,7 +1812,7 @@
"name": "SWL Clock / Short Wave Listner Clock",
"shortName": "SWL Clock",
"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",
"tags": "tool,clock",
"type":"clock",
@ -1815,7 +1828,7 @@
"name": "Round clock with seconds, minutes and date",
"shortName": "Round Clock",
"icon": "app.png",
"version": "0.05",
"version": "0.06",
"description": "Designed round clock with ticks for minutes and seconds and heart rate indication",
"tags": "clock",
"type": "clock",
@ -1829,7 +1842,7 @@
"name": "fclock",
"shortName": "F Clock",
"icon": "app.png",
"version": "0.01",
"version": "0.02",
"description": "Simple design of a digital clock",
"tags": "clock",
"type": "clock",
@ -1931,7 +1944,7 @@
"id": "largeclock",
"name": "Large Clock",
"icon": "largeclock.png",
"version": "0.07",
"version": "0.08",
"description": "A readable and informational digital watch, with date, seconds and moon phase",
"readme": "README.md",
"tags": "clock",
@ -2124,6 +2137,20 @@
{ "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",
"name": "BLE Customisable Controller with Joystick",
"shortName": "BLE Controller",
@ -2610,7 +2637,7 @@
"name": "NCR Clock",
"shortName":"NCR Clock",
"icon": "app.png",
"version":"0.01",
"version":"0.02",
"description": "NodeConf Remote clock",
"tags": "clock",
"type": "clock",
@ -2623,7 +2650,7 @@
"name": "ISO Compliant Clock Face",
"shortName":"ISO Clock",
"icon": "isoclock.png",
"version":"0.01",
"version":"0.02",
"description": "Tweaked fork of digiclock for ISO date and time",
"tags": "clock",
"type" : "clock",
@ -2694,7 +2721,7 @@
{ "id": "dtlaunch",
"name": "Desktop Launcher",
"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.",
"readme": "README.md",
"tags": "tool,system,launcher",
@ -2781,7 +2808,7 @@
{ "id": "lazyclock",
"name": "Lazy Clock",
"icon": "lazyclock.png",
"version":"0.02",
"version":"0.03",
"readme": "README.md",
"description": "Tells the time, roughly",
"tags": "clock",
@ -2821,13 +2848,13 @@
"name": "Game of Life Clock",
"shortName":"Conway's Clock",
"icon": "app.png",
"version":"0.05",
"version":"0.06",
"description": "Modification and clockification of Conway's Game of Life",
"tags": "clock",
"type" : "clock",
"readme": "README.md",
"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}
]
},
@ -2883,7 +2910,7 @@
"name": "Morph Clock+",
"shortName":"Morph Clock+",
"icon": "mclockplus.png",
"version":"1.0",
"version":"0.02",
"description": "Morphing Clock with more readable seconds and date and additional stopwatch",
"tags": "clock",
"type": "clock",
@ -3113,7 +3140,7 @@
{ "id": "simplest",
"name": "Simplest Clock",
"icon": "simplest.png",
"version":"0.01",
"version":"0.02",
"description": "The simplest working clock, acts as a tutorial piece",
"tags": "clock",
"type":"clock",
@ -3199,6 +3226,21 @@
{"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",
"name": "Quiet Mode Schedule",
"shortName":"Quiet Mode",
@ -3276,7 +3318,7 @@
"name":"Dozenal Time",
"shortName":"Dozenal Time",
"icon":"app.png",
"version":"0.01",
"version":"0.04",
"description":"A dozenal Holocene calendar and dozenal diurnal clock",
"tags":"clock",
"type":"clock",
@ -3332,7 +3374,7 @@
{ "id": "mysticclock",
"name": "Mystic Clock",
"icon": "mystic-clock.png",
"version":"1.00",
"version":"1.01",
"description": "A retro-inspired watchface featuring time, date, and an interactive data display line.",
"tags": "clock",
"type":"clock",
@ -3343,5 +3385,29 @@
{"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}
]
}
]

View File

@ -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).

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -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>

BIN
apps/banglebridge/watch.img Normal file

Binary file not shown.

302
apps/banglebridge/widget.js Normal file
View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -1 +1,2 @@
0.01: New game! BTN4- Hit card, BTN5- Stand
0.02: ignore buttons on pauses

View File

@ -18,6 +18,7 @@ const Diamonds = { width : 48, height : 48, bpp : 4,
var deck = [];
var player = {Hand:[]};
var computer = {Hand:[]};
var ctx = {ready:true};
function createDeck() {
var suits = ["Spades", "Hearts", "Diamonds", "Clubs"];
@ -44,6 +45,7 @@ function shuffle(a) {
}
function EndGameMessdage(msg){
ctx.ready = false;
g.drawString(msg, 155, 200);
setTimeout(function(){
startGame();
@ -52,6 +54,7 @@ function EndGameMessdage(msg){
}
function hitMe() {
if (!ctx.ready) return;
player.Hand.push(deck.pop());
renderOnScreen(1);
var playerWeight = calcWeight(player.Hand, 0);
@ -97,6 +100,8 @@ function calcWeight(hand, hideCard) {
}
function stand(){
if (!ctx.ready) return;
ctx.ready = false;
function sleepFor( sleepDuration ){
console.log("Sleeping...");
var now = new Date().getTime();
@ -156,6 +161,7 @@ function renderOnScreen(HideCard) {
function dealHands() {
player.Hand= [];
computer.Hand= [];
ctx.ready = false;
setTimeout(function(){
player.Hand.push(deck.pop());
@ -175,6 +181,7 @@ function dealHands() {
setTimeout(function(){
computer.Hand.push(deck.pop());
renderOnScreen(1);
ctx.ready = true;
}, 2000);
}

View File

@ -26,3 +26,4 @@
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

View File

@ -136,8 +136,9 @@ require('Storage').list(/\.boot\.js/).forEach(bootFile=>{
boot += "//"+bootFile+"\n"+require('Storage').read(bootFile)+"\n";
});
boot += "}\n";// initial 'if'
var s = require('Storage').write('.boot0',boot);
require('Storage').write('.boot0',boot);
delete boot;
E.showMessage("Reloading...");
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'

View File

@ -1 +1,4 @@
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

View File

@ -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 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 timeColour = "#f2f2f2";
const timeColour = "#ffffff";
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 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 baseYear = 11584;
const baseDate = Date(2020,11,21); // month values run from 0 to 11
@ -30,8 +30,11 @@ let lastX = 999999999;
let res = {};
//var last_time_log = 0;
var drawtime_timeout;
// Date and time graphics buffers
var dateColour = "#ffffff"; // override later
var timeColour2 = timeColour;
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});
// Set screen mode and function to write graphics buffers
@ -46,7 +49,7 @@ g.flip = function()
height:g_height_d,
buffer:g_d.buffer
}, g_x_off, g_y_off + g_y_off_d);
g.setColor(timeColour);
g.setColor(timeColour2);
g.drawImage(
{
width:g_width,
@ -118,7 +121,7 @@ function formatDate(res,dateFormat){
return(yyyy+"-"+m+"-"+w+"-"+d);
}
function writeDozTime(text,def,colour){
function writeDozTime(text,def){
let pts = def.pts;
let x=def.pt0[0];
let y=def.pt0[1];
@ -133,6 +136,7 @@ function writeDozTime(text,def,colour){
}
}
function writeDozDate(text,def,colour){
dateColour = colour;
let pts = def.pts;
let x=def.pt0[0];
@ -177,10 +181,10 @@ function drawTime()
{
// Write to background buffers, then display on screen
writeDozDate(date,calenDef,res.colour);
writeDozTime(time,timeDef,timeColour);
writeDozTime(time,timeDef);
g.flip();
// Ready next interval
setTimeout(drawTime,wait);
drawtime_timeout = setTimeout(drawTime,wait);
}
else
{
@ -196,22 +200,14 @@ function modeTime()
timeActiveUntil = new Date();
timeActiveUntil.setDate(timeActiveUntil.getDate());
timeActiveUntil.setSeconds(timeActiveUntil.getSeconds()+15);
//Bangle.setLCDPower(true);
clearTimeout();
if (typeof drawtime_timeout !== 'undefined')
{
clearTimeout(drawtime_timeout);
}
drawTime();
}
Bangle.loadWidgets();
// 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);
}*/
Bangle.drawWidgets();
// Functions for weather mode - TODO
function drawWeather() {}
@ -222,4 +218,20 @@ Bangle.on('twist', function() {
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);

View File

@ -1,4 +1,4 @@
0.01: Initial version
0.02: Multiple pages
0.03: cycle thru pages
0.04: reset to clock after 2 mins of inactivity

View File

@ -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 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)=>{
@ -42,6 +56,7 @@ function drawPage(p){
}
Bangle.on("swipe",(dir)=>{
wdog()
selected = 0;
oldselected=-1;
if (dir<0){
@ -54,6 +69,7 @@ Bangle.on("swipe",(dir)=>{
});
function nextapp(d){
wdog();
oldselected = selected;
selected+=d;
selected = selected<0?5:selected>5?0:selected;

View File

@ -1 +1,2 @@
0.01: First published version of app
0.02: Move to Bangle.setUI to launcher support

View File

@ -1,4 +1,3 @@
{
var minutes;
var seconds;
var hours;
@ -200,7 +199,5 @@
// draw now
drawClock();
// Show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
}
// Show launcher when button pressed
Bangle.setUI("clock");

View File

@ -3,3 +3,4 @@
0.04: Add functionality to sort apps manually or alphabetically ascending/descending.
0.05: Tweaks to help with memory usage
0.06: Reduce memory usage
0.07: Allow negative numbers when manual-sorting

View File

@ -180,7 +180,7 @@ function showSortAppsManually() {
appList.reduce((menu, app) => {
menu[app.name] = {
value: app.sortorder || 0,
min: 0,
min: -appList.length,
max: appList.length,
step: 1,
onchange: val => setSortorder(app, val)

View File

@ -22,3 +22,4 @@
0.20: Reduce memory usage
0.21: Fix HRM setting
0.22: Respect Quiet Mode
0.23: Allow notification dismiss to remove from phone too

View File

@ -155,6 +155,10 @@
switch (event.t) {
case "notify":
currentNot = prettifyNotificationEvent(event);
currentNot.onHide = function() {
// when notification hidden, remove from phone
gbSend({ t:"notify", n:"DISMISS", id:currentNot.id });
};
require("notify").show(currentNot);
if (!(require('Storage').readJSON('setting.json',1)||{}).quiet) {
Bangle.buzz();

2
apps/hcclock/ChangeLog Normal file
View File

@ -0,0 +1,2 @@
0.01: base code

13
apps/hcclock/README.md Normal file
View File

@ -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/

View File

@ -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////////////////////////////////////////////////////////////////////////////////"))

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 B

210
apps/hcclock/hcclock.app.js Normal file
View File

@ -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(); });

View File

@ -2,3 +2,4 @@
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.04: Update for new firmwares that have a 'HRM-raw' event
0.05: Tweaks for 'HRM-raw' handling

View File

@ -3,6 +3,8 @@ Bangle.setLCDTimeout(0);
Bangle.setHRMPower(1);
var hrmInfo, hrmOffset = 0;
var hrmInterval;
var btm = g.getHeight()-1;
function onHRM(h) {
if (counter!==undefined) {
// the first time we're called remove
@ -26,7 +28,7 @@ function onHRM(h) {
var px = g.getWidth()/2;
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);
var str = hrmInfo.bpm;
g.setFontVector(40).drawString(str,px,45);
@ -38,17 +40,21 @@ Bangle.on('HRM', onHRM);
/* On newer (2v10) firmwares we can subscribe to get
HRM events as they happen */
Bangle.on('HRM-raw', function(v) {
var a = v.raw;
hrmOffset++;
if (hrmOffset>g.getWidth()) {
hrmOffset=0;
g.clearRect(0,90,239,239);
g.clearRect(0,80,239,239);
g.moveTo(-100,0);
}
y = E.clip(170 - (v.raw*2),100,230);
g.setColor(1,1,1);
g.lineTo(hrmOffset, y);
y = E.clip(btm-v.filt/4,btm-10,btm);
g.setColor(1,0,0).fillRect(hrmOffset,btm, 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
@ -80,7 +86,6 @@ function readHRM() {
var a = hrmInfo.raw[hrmOffset];
hrmOffset++;
y = E.clip(170 - (a*2),100,230);
g.setColor(1,1,1);
g.lineTo(hrmOffset, y);
g.setColor(g.theme.fg).lineTo(hrmOffset, y);
}
}

View File

@ -6,3 +6,4 @@
0.05: Fix memory/interval leak when LCD turns on
0.06: Support 12 hour time
0.07: Don't cut off wide date formats
0.08: Use Bangle.setUI for button/launcher handling

View File

@ -84,5 +84,5 @@ Bangle.on('lcdPower',on=>{
draw();
}
});
// Show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
// Show launcher when button pressed
Bangle.setUI("clock");

View File

@ -1,2 +1,3 @@
0.01: New App!
0.02: Stopped watchface from flashing every interval
0.03: Move to Bangle.setUI to launcher support

View File

@ -47,10 +47,9 @@ const activeColorNight = 0xF800 /*red*/ ;
const activeColorDay = 0xFFFF /* white */;
var hidxPrev;
var showDigitalTime = false;
function drawWordClock() {
// get time
var t = new Date();
var h = t.getHours();
@ -141,7 +140,7 @@ function drawWordClock() {
// Display digital time while button 1 is pressed
g.clearRect(0, 215, 240, 240);
if (BTN1.read()){
if (showDigitalTime){
g.setColor(activeColor);
g.drawString(time, 120, 215);
}
@ -158,8 +157,20 @@ Bangle.drawWidgets();
setInterval(drawWordClock, 1E4);
drawWordClock();
// Show digital time while top button is pressed
setWatch(drawWordClock, BTN1, {repeat:true,edge:"both"});
// Show digital time while top button is pressed (if we have physical buttons)
if (global.BTN3) setWatch(function() {
showDigitalTime = BTN1.read();
drawWordClock();
}, BTN1, {repeat:true,edge:"both"});
// Show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
// If LCD pressed (on Bangle.js 2) draw digital time
Bangle.on('drag',e=>{
var pressed = e.b!=0;
if (pressed!=showDigitalTime) {
showDigitalTime = pressed;
drawWordClock();
}
});
// Show launcher when button pressed
Bangle.setUI("clock");

View File

@ -1 +1,2 @@
0.01: Created app based on digiclock with some small tweaks.
0.02: Swap to Bangle.setUI for launcher/buttons

View File

@ -92,4 +92,5 @@ Bangle.on('lcdPower',on=>{
Bangle.loadWidgets();
Bangle.drawWidgets();
setWatch(Bangle.showLauncher, BTN2, {repeat : false, edge: "falling"});
// Show launcher when button pressed
Bangle.setUI("clock");

1
apps/jbm8b_IT/ChangeLog Normal file
View File

@ -0,0 +1 @@
0.01: Cloning Magic 8 Ball and make it speak italian

View File

@ -0,0 +1 @@
require("heatshrink").decompress(atob("mEwhBC/AGMrq2B1gAEwNWlYthq2s64AKGYIydFpoAEGLUrFqIADqxcXFqhiDFymBFy7GCF1owTRjCSVlYudeiGsF7/XlaNqSKBeP1mBwJxQMBReO1gaEleBMDBLN1hAC1hhBAoIwNCwQAGlZINqxvFGAIXOSBAXQN4hPBC5yQIVBxfBCAgvQSBC+NFAYRDMwJHOF654DqxkBYooALF6+sbIhkEF8Z3CRIWBR6AvXFAzvQF6wnIYQJgNd5AWNdoLoGBBAvPO5pfYH4IvUUwS/GVBzXBYCpHCq2s1mBDwKOWDwRgNPAwVVMCRLCwIABCZ6OJJSAATLxZgRACJeLAAMrFz9WFxiRgRpoADwIub1guQGDmsXhqSfRiL0G1jqkMRYxRwKLUGK2sFryVEq2B1gAEwNWFkIA/AH4A/AH4AQ"))

79
apps/jbm8b_IT/app.js Normal file
View File

@ -0,0 +1,79 @@
const affirmative = [
'È certo.',
'È decisamente\ncosì.',
'Senza alcun\ndubbio.',
'Sì,\nsenza dubbio.',
'Ci puoi\ncontare.',
'Da quanto\nvedo,\nsì.',
'Molto\nprobabilmente.',
'Le prospettive\nsono buone.',
'Sì.',
'I segni\nindicano\ndi sì.'
];
const nonCommittal = [
'È difficile\ndirlo,\nprova di nuovo.',
'Rifai la domanda\npiù tardi.',
'Meglio non\nrisponderti\nadesso.',
'Non posso\npredirlo ora.',
'Concentrati e\nrifai la\ndomanda.'
];
const negative = [
'Non ci\ncontare.',
'La mia\nrisposta\nè no.',
'Le mie\nfonti dicono\ndi no.',
'Le prospettive\nnon sono\nbuone.',
'È molto\ndubbio.'
];
const title = 'Magic 8 Ball';
const answers = [affirmative, nonCommittal, negative];
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
function predict() {
// affirmative, negative or non-committal
let max = answers.length;
const a = Math.floor(getRandomArbitrary(0, max));
// sets max compared to answer category
max = answers[a].length;
const b = Math.floor(getRandomArbitrary(0, max));
// get the answer
const response = answers[a][b];
return response;
}
function draw(msg) {
// console.log(msg);
g.clear();
E.showMessage(msg, title);
}
function reply(button) {
const theButton = (typeof button === 'undefined' || isNaN(button)) ? 1 : button;
const timer = Math.floor(getRandomArbitrary(0, theButton) * 1000);
// Thinking...
draw('...');
setTimeout('draw(predict());', timer);
}
function ask() {
draw('Ponimi una\ndomanda\nSì/No e\ntocca lo\nschermo');
}
g.clear();
Bangle.loadWidgets();
Bangle.drawWidgets();
ask();
// Event Handlers
Bangle.on('touch', (button) => reply(button));
setWatch(ask, BTN1, { repeat: true, edge: "falling" });
setWatch(reply, BTN3, { repeat: true, edge: "falling" });
// Back to launcher
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });

BIN
apps/jbm8b_IT/app.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -5,3 +5,4 @@
0.05: Add support for 12 hour time
0.06: Allow to disable BTN1 and BTN3 buttons
0.07: Don't clear all intervals during initialisation
0.08: Use Bangle.setUI for button/launcher handling

View File

@ -179,9 +179,9 @@ Bangle.on("lcdPower", function(on) {
Bangle.setLCDMode();
// Show launcher when middle button pressed
clearWatch();
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
// Show launcher when button pressed
Bangle.setUI("clock");
if (BTN1app) setWatch(
function() {
load(BTN1app);

View File

@ -36,6 +36,7 @@ function drawMenu() {
}
g.clear();
drawMenu();
g.flip(); // force an update now to make this snappier
Bangle.on('drag',e=>{
var dy = e.dy;
if (menuScroll - dy < 0)

View File

@ -1,2 +1,3 @@
0.01: Launch app
0.02: Fix bug with the elusive one o'clock monster; Only change template when going over boundaries; Re-jig wording options
0.03: Use Bangle.setUI for launcher/buttons

View File

@ -221,22 +221,13 @@ function addEvents() {
}
});
setWatch(switchMode, BTN1, {
repeat: true,
edge: "falling"
});
setWatch(Bangle.showLauncher, BTN2, {
repeat: false,
edge: "falling"
});
setWatch(() => {
// Show launcher when button pressed
Bangle.setUI("clockupdown", btn=>{
if (btn<0) switchMode();
if (btn>0) {
currentFormatter = null;
refreshTime();
}, BTN3, {
repeat: true,
edge: "falling"
}
});
}

View File

@ -3,3 +3,4 @@
0.03: Ah yes. Some people prefer the 12 hour system 2021-01-14
0.04: Fixed a bug, doesn't run while display's on now 2021-01-18
0.05: Fixed a bug, doesn't count the time it was asleep when calculating the update time 2021-01-19
0.06: Use Bangle.set UI, change to unminified upload to ensure this works ok on Bangle.js

View File

@ -1,4 +1,4 @@
Bangle.setLCDTimeout(30);
// Name as .min.js so we don't try and pretokenise (which stops Bangle.js running this somehow)
const is12Hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"];
@ -435,9 +435,11 @@ function showMinAgain(){
}
function setButtons(){
setWatch(showMinAgain, BTN1, {repeat:true,edge:"falling"});
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
setWatch(regen, BTN3, {repeat:true,edge:"falling"});
// Show launcher when button pressed
Bangle.setUI("clockupdown", btn=>{
if (btn<0) showMinAgain();
if (btn>0) regen();
});
}
let wentToSleepAt;

View File

@ -4,3 +4,4 @@
0.05: Add "ram" keyword to allow 2v06 Espruino builds to cache function that needs to be fast
Fix issue where first digit could get stuck going from "2x:xx" to " x:xx" (fix #365)
0.06: Support 12 hour time
0.07: Use Bangle.setUI for button/launcher handling

View File

@ -216,5 +216,5 @@ Bangle.drawWidgets();
timeInterval = setInterval(showTime, 1000);
showTime();
// Show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
// Show launcher when button pressed
Bangle.setUI("clock");

View File

@ -1 +1,2 @@
1.0: Created app
0.01: Created app
0.02: Use Bangle.setUI for button/launcher handling

View File

@ -310,8 +310,8 @@ Bangle.drawWidgets();
timeInterval = setInterval(showTime, 1000);
showTime();
// Show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
// Show launcher when button pressed
Bangle.setUI("clock");
// Start stopwatch when BTN3 is pressed
setWatch(() => {swInterval=setInterval(stopWatch, 1000);stopWatch();}, BTN3, {repeat:false,edge:"falling"});

View File

@ -1,3 +1,4 @@
0.02: Modified for use with new bootloader and firmware
0.03: Localization
0.04: move jshint to the top
0.05: Use Bangle.setUI for button/launcher handling

View File

@ -83,5 +83,5 @@ Bangle.drawWidgets();
setInterval(drawMixedClock, 5E3);
drawMixedClock();
// Show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
// Show launcher when button pressed
Bangle.setUI("clock");

View File

@ -2,3 +2,4 @@
0.02: Improved date readability, fixed drawing of widgets
0.03: Fixed rendering for Espruino v2.06
0.04: Fixed overlapped rendering of dates
0.05: Use Bangle.setUI for button/launcher handling

View File

@ -81,4 +81,5 @@ Bangle.on('lcdPower', (on) => {
Bangle.loadWidgets();
startDrawing();
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: 'falling' });
// Show launcher when button pressed
Bangle.setUI("clock");

View File

@ -1 +1,2 @@
1.00: First published version.
1.01: Use Bangle.setUI for Launcher/buttons

View File

@ -200,16 +200,9 @@ if (Bangle.isLCDOn()) {
drawAll(); // draw immediately
}
// show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
// rotate through info when the buttons are pressed
setWatch(() => {
nextInfo();
// Show launcher when button pressed
Bangle.setUI("clockupdown", btn=>{
if (btn<0) prevInfo();
if (btn>0) nextInfo();
drawAll();
}, BTN3, { repeat: true });
setWatch(() => {
prevInfo();
drawAll();
}, BTN1, { repeat: true });
});

View File

@ -1 +1,2 @@
0.01: A copy of the analogimgclk to work for NodeConf Remote
0.02: Use Bangle.setUI for button/launcher handling

View File

@ -125,5 +125,5 @@ Bangle.loadWidgets();
Bangle.drawWidgets();
drawHands(true);
// Show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
// Show launcher when button pressed
Bangle.setUI("clock");

View File

@ -5,3 +5,4 @@
0.06: Support background color
0.07: Auto-calculate height, and pad text down even when there's no title (so it stays on-screen)
0.08: Don't turn on screen during Quiet Mode
0.09: Add onHide callback

View File

@ -1,5 +1,6 @@
let pos = 0;
let id = null;
let hideCallback = undefined;
/**
* Fit text into area, trying to insert newlines between words
@ -44,6 +45,7 @@ function fitWords(text,rows,width) {
render : function(y) // function callback to render
bgColor : int/string // optional background color (default black)
titleBgColor : int/string // optional background color for title (default black)
onHide : function() // callback when notification is hidden
}
*/
/*
@ -141,7 +143,9 @@ exports.show = function(options) {
if (pos > -size) setTimeout(anim, 15);
}
anim();
Bangle.on("touch", exports.dismiss_and_hide);
Bangle.on("touch", exports.hide);
if (options.onHide)
hideCallback = options.onHide;
};
/**
@ -152,6 +156,8 @@ exports.show = function(options) {
exports.hide = function(options) {
options = options||{};
if ("id" in options && options.id!==id) return;
if (hideCallback) hideCallback({id:id});
hideCallback = undefined;
id = null;
Bangle.removeListener("touch", exports.hide);
function anim() {
@ -162,20 +168,3 @@ exports.hide = function(options) {
}
anim();
};
/**
Calls exports.hide(), but if Gadgetbridge is installed, dismiss through it
instead (which will call call exports.hide() itself).
*/
exports.dismiss_and_hide = function(options) {
options = options||{};
if (typeof(options) == "number") {
options = {};
}
if ("GB" in global) {
options["t"] = "notify-";
GB(options);
} else {
exports.hide(options);
}
};

View File

@ -6,3 +6,4 @@
0.06: Adjust position of notification src text and notifications without title
0.07: Support background color
0.08: Don't turn on screen during Quiet Mode
0.09: Add onHide callback

View File

@ -1,5 +1,6 @@
let oldg;
let id = null;
let hideCallback = null;
/**
* See notify/notify.js
@ -40,6 +41,7 @@ function fitWords(text,rows,width) {
render : function(y) // function callback to render
bgColor : int/string // optional background color (default black)
titleBgColor : int/string // optional background color for title (default black)
onHide : function() // callback when notification is hidden
}
*/
exports.show = function(options) {
@ -65,7 +67,6 @@ exports.show = function(options) {
if (options.title && options.src) {
g.setColor(-1).setFontAlign(1, 1, 0).setFont("6x8", 2);
// above drawing area, but we are fullscreen
print(options.src.substring(0, 10), w-23, y-4);
g.drawString(options.src.substring(0, 10), w-16, y-4);
}
y += 30;h -= 30;
@ -94,6 +95,8 @@ exports.show = function(options) {
Bangle.setLCDPower(1); // light up
}
Bangle.on("touch", exports.hide);
if (options.onHide)
hideCallback = options.onHide;
// Create a fake graphics to hide draw attempts
oldg = g;
g = Graphics.createArrayBuffer(8,8,1);
@ -108,6 +111,8 @@ exports.show = function(options) {
exports.hide = function(options) {
options = options||{};
if ("id" in options && options.id!==id) return;
if (hideCallback) hideCallback({id:id});
hideCallback = undefined;
id = null;
if (oldg) {
g=oldg;

View File

@ -3,3 +3,5 @@
0.03: Added HR indication to clock
0.04: Update font size and alignment
0.05: Changes which circle show minutes and seconds
0.06: Avoid function wrapper, use setUI for launcher
Clock face smaller so no longer breaks widgets

View File

@ -1,4 +1,3 @@
{
var minutes;
var seconds;
var hours;
@ -20,7 +19,7 @@
center: g.getHeight() / 2,
};
// Ssettings
// Settings
const settings = {
time: {
color: '#D6ED17',
@ -42,7 +41,7 @@
width: 10,
middle: screen.middle,
center: screen.center,
height: screen.height
height: screen.height-24
},
hr: {
color: '#333333',
@ -67,10 +66,10 @@
const drawMinArc = function (sections, color) {
g.setColor(color);
rad = (settings.circle.height / 2) - 40;
r1 = getArcXY(settings.circle.middle, settings.circle.center, rad, sections * (360 / 60) - 90);
var rad = (settings.circle.height / 2) - 40;
var r1 = getArcXY(settings.circle.middle, settings.circle.center, rad, sections * (360 / 60) - 90);
//g.setPixel(r[0],r[1]);
r2 = getArcXY(settings.circle.middle, settings.circle.center, rad - settings.circle.width, sections * (360 / 60) - 90);
var r2 = getArcXY(settings.circle.middle, settings.circle.center, rad - settings.circle.width, sections * (360 / 60) - 90);
//g.setPixel(r[0],r[1]);
g.drawLine(r1[0], r1[1], r2[0], r2[1]);
g.setColor('#333333');
@ -79,10 +78,10 @@
const drawSecArc = function (sections, color) {
g.setColor(color);
rad = (settings.circle.height / 2) - 20;
r1 = getArcXY(settings.circle.middle, settings.circle.center, rad, sections * (360 / 60) - 90);
var rad = (settings.circle.height / 2) - 20;
var r1 = getArcXY(settings.circle.middle, settings.circle.center, rad, sections * (360 / 60) - 90);
//g.setPixel(r[0],r[1]);
r2 = getArcXY(settings.circle.middle, settings.circle.center, rad - settings.circle.width, sections * (360 / 60) - 90);
var r2 = getArcXY(settings.circle.middle, settings.circle.center, rad - settings.circle.width, sections * (360 / 60) - 90);
//g.setPixel(r[0],r[1]);
g.drawLine(r1[0], r1[1], r2[0], r2[1]);
g.setColor('#333333');
@ -90,7 +89,7 @@
};
const drawClock = function () {
g.reset();
currentTime = new Date();
//Set to initial time when started
@ -223,7 +222,5 @@
// draw now
drawClock();
// Show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
}
// Show launcher when button pressed
Bangle.setUI("clock");

1
apps/rtorch/ChangeLog Normal file
View File

@ -0,0 +1 @@
0.01: Cloning torch and making it red :D

1
apps/rtorch/app-icon.js Normal file
View File

@ -0,0 +1 @@
require("heatshrink").decompress(atob("mEw4UA///oP4gH+t9TCQ1VAAYLpgILunoLK/4LJgf/6oLIh//+oLK/oLIhapBBZEqBYIwDBYu/GAgLE1WvGAgLF1YwEBQcC1WqGAgLGGAgLDhQLBGAdQBYwwCBQgLDGASlFlQLC3/8BYoIBGAXwBQkCFgILC4AuFBYeAFw2v/wLBBQqNCBYOgBQp1B1/qCw5dDFoxdEBQwuBAAOoBQykCHI4uXgZPBFxEP/QuJn5/CFw7DBLpILB9QuHEYP//QuHHYP//wuHKYL0HGAoLJn/8BZMP+ALJgfABRA="))

22
apps/rtorch/app.js Normal file
View File

@ -0,0 +1,22 @@
Bangle.setLCDPower(1);
Bangle.setLCDTimeout(0);
g.reset();
c = 1;
function setColor(delta){
c+=delta;
c = Math.max(c,0);
c = Math.min(c,2);
if (c<1){
g.setColor(c,0,0);
}else{
g.setColor(1,c-1,c-1);
}
g.fillRect(0,0,g.getWidth(),g.getHeight());
}
setColor(0)
// BTN1 light up toward white
// BTN3 light down to red
// BTN2 to reset
setWatch(()=>setColor(0.1), BTN1, { repeat:true, edge:"rising", debounce: 50 });
setWatch(()=>load(), BTN2);
setWatch(()=>setColor(-0.1), BTN3, { repeat:true, edge:"rising", debounce: 50 });

BIN
apps/rtorch/app.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

26
apps/rtorch/widget.js Normal file
View File

@ -0,0 +1,26 @@
(function() {
var clickTimes = [];
var clickPattern = "";
var TAPS = 4; // number of taps
var PERIOD = 1; // seconds
// we don't actually create/draw a widget here at all...
Bangle.on("lcdPower",function(on) {
// First click (that turns LCD on) isn't given to
// setWatch, so handle it here
if (!on) return;
clickTimes=[getTime()];
clickPattern="x";
});
function tap(e,c) {
clickPattern = clickPattern.substr(-3)+c;
while (clickTimes.length>=TAPS) clickTimes.shift();
clickTimes.push(e.time);
var clickPeriod = e.time-clickTimes[0];
if (clickPeriod<PERIOD && clickPattern.match(/.131/)) {
load("rtorch.app.js");
}
}
setWatch(function(e) { tap(e,"1"); }, BTN1, {repeat:true, edge:"rising"});
setWatch(function(e) { tap(e,"3"); }, BTN3, {repeat:true, edge:"rising"});
})();

View File

@ -2,3 +2,4 @@
0.03: Actually make into 24h clock since there's a 12h variant
0.04: Make this clock do 12h and 24h
0.05: setUI, screen size changes
0.06: Use Bangle.setUI for button/launcher handling

View File

@ -69,6 +69,8 @@ Bangle.on('lcdPower', function(on) {
// clean app screen
g.clear();
// Show launcher when button pressed
Bangle.setUI("clock");
Bangle.loadWidgets();
Bangle.drawWidgets();
@ -77,6 +79,3 @@ setInterval(drawSimpleClock, 15E3);
// draw now
drawSimpleClock();
// Show launcher when button pressed
Bangle.setUI("clock");

2
apps/simplest/ChangeLog Normal file
View File

@ -0,0 +1,2 @@
0.01: Modified for use with new bootloader and firmware
0.02: Use Bangle.setUI for button/launcher handling

View File

@ -21,4 +21,5 @@ Bangle.loadWidgets();
Bangle.drawWidgets();
setInterval(draw, 15000); // refresh every 15s
draw();
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
// Show launcher when button pressed
Bangle.setUI("clock");

View File

@ -3,3 +3,4 @@
0.03: Added Spanish Language
0.04: Added German Language
0.05: BUGFIX: pedometer widget interfered with the clock Font Alignment
0.06: Use Bangle.setUI for button/launcher handling

View File

@ -635,8 +635,8 @@ Bangle.loadWidgets();
Bangle.drawWidgets();
startTimers();
// Show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2,{repeat:false,edge:"falling"});
// Show launcher when button pressed
Bangle.setUI("clock");
// Handle button 1 being pressed

View File

@ -1 +1,2 @@
0.01: Modification of SimpleClock 0.04 to use Vectorfont
0.02: Use Bangle.setUI for button/launcher handling

View File

@ -80,5 +80,5 @@ setInterval(drawSimpleClock, 15E3);
// draw now
drawSimpleClock();
// Show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
// Show launcher when button pressed
Bangle.setUI("clock");

View File

@ -1 +1,2 @@
0.01: New App!
0.02: Fix text alignment, move to setUI

View File

@ -17,8 +17,7 @@ function drawTime(){
var utc = getUTCTime(d);
var beats = Math.floor((((utc[0] + 1) % 24) + utc[1] / 60 + utc[2] / 3600) * 1000 / 24);
function drawStation(){
g.setFont("Vector",10);
g.reset().setFont("Vector",10).setFontAlign(0,0);
g.setColor("#ffffff");
switch (utc[0]) {
case 0:
@ -118,25 +117,19 @@ function drawTime(){
g.drawString("17h00-18h00 R.F.I.\n13740 15300 17850\n17h00-18h00 R.F.I.\n7205 9790",xyCenter,30);
break;
}
}
drawStation();
// Local time
g.setFont("6x8",1);
g.setColor("#cccccc");
g.setFont("6x8",1).setColor("#cccccc");
g.drawString("Loc",10,85);
g.setFont("7x11Numeric7Seg",4);
g.setColor("#ffffff");
g.setFont("7x11Numeric7Seg",4).setColor("#ffffff");
g.drawString(`${hours}:${minutes}:${seconds}`, xyCenter, 115, true);
// UTC time
g.setFont("6x8",1);
g.setColor("#cccccc");
g.setFont("6x8",1).setColor("#cccccc");
g.drawString("UTC",10,155);
g.setFont("7x11Numeric7Seg",4);
g.setColor("#ff0000");
g.setFont("7x11Numeric7Seg",4).setColor("#ff0000");
g.drawString(utc[0]+`:${minutes}:${seconds}`, xyCenter, 185,true);
// footer date
@ -147,6 +140,7 @@ function drawTime(){
}
function setGpsTime(){
print("set GPS time");
Bangle.setGPSPower(1);
Bangle.on('GPS',function(fix) {
if (fix.fix) {
@ -157,7 +151,7 @@ function setGpsTime(){
start();
} else {
stop();
g.setFont("Vector",10);
g.reset().setFont("Vector",10).setFontAlign(0,0);
g.setColor("#cccccc");
g.clearRect(0,25,240,80);
g.drawString("Mise à l'heure\npar satellites\nen cours...",xyCenter,40);
@ -166,14 +160,13 @@ function setGpsTime(){
}
function setButtons(){
// BTN 1
setWatch(() => {
// Show launcher when button pressed
Bangle.setUI("clockupdown", btn=>{
if (btn!=-1) return;
// if up pressed, turn GPS on and wait for new time
setGpsTime();
Bangle.beep(500, 4000);
}, BTN1, {edge:"rising", repeat:true});
// BTN 2
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
});
}
var intervalRef = null;

1
apps/thermom/ChangeLog Normal file
View File

@ -0,0 +1 @@
0.02: New App!

View File

@ -0,0 +1 @@
require("heatshrink").decompress(atob("mEwwhC/AH4AChGIxGAC6eIAQgARFgUIC9ReCAYJgSC7BHDF6gUBC6ovWI/5Hga/6P/ABsCkABDC/4XxkQXDkQuSAQwXPDQkAC6BBCkQDDC6MCmczFoIXQCQQXBDgQXP2EA2YXBncAhYXR3YXB3YXRCQWznYcCC6ICBAYYXPhYrBApAwPFyQqCIoYuRLwZgDAH4A/"))

28
apps/thermomF/app.js Normal file
View File

@ -0,0 +1,28 @@
function onTemperature(p) {
g.reset(1).clearRect(0,24,g.getWidth(),g.getHeight());
g.setFont("6x8",2).setFontAlign(0,0);
var x = g.getWidth()/2;
var y = g.getHeight()/2 + 10;
g.drawString("Temperature", x, y - 45);
g.setFontVector(70).setFontAlign(0,0);
g.drawString(p.temperature.toFixed(1), x, y);
}
function drawTemperature() {
if (Bangle.getPressure) {
Bangle.getPressure().then(onTemperature);
} else {
onTemperature({
temperature : E.getTemperature() * (9/5) + 32
});
}
}
setInterval(function() {
drawTemperature();
}, 20000);
drawTemperature();
E.showMessage("Loading...");
Bangle.loadWidgets();
Bangle.drawWidgets();

BIN
apps/thermomF/thermf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -30,6 +30,42 @@ global.Const = {
SINGLE_APP_ONLY : false,
};
function atob(input) {
// Copied from https://github.com/strophe/strophejs/blob/e06d027/src/polyfills.js#L149
// This code was written by Tyler Akins and has been placed in the
// public domain. It would be nice if you left this header intact.
// Base64 code from Tyler Akins -- http://rumkin.com
var keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
var output = [];
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
do {
enc1 = keyStr.indexOf(input.charAt(i++));
enc2 = keyStr.indexOf(input.charAt(i++));
enc3 = keyStr.indexOf(input.charAt(i++));
enc4 = keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output.push(chr1);
if (enc3 !== 64) {
output.push(chr2);
}
if (enc4 !== 64) {
output.push(chr3);
}
} while (i < input.length);
return new Uint8Array(output);
}
var AppInfo = require(ROOTDIR+"/core/js/appinfo.js");
var appjson = JSON.parse(fs.readFileSync(APPJSON).toString());
var appfiles = [];
@ -50,6 +86,28 @@ function fileGetter(url) {
return Promise.resolve(fs.readFileSync(url).toString("binary"));
}
// If file should be evaluated, try and do it...
function evaluateFile(file) {
var hsStart = 'require("heatshrink").decompress(atob("';
var hsEnd = '"))';
if (file.content.startsWith(hsStart) && file.content.endsWith(hsEnd)) {
var heatshrink = require(ROOTDIR+"/core/lib/heatshrink.js");
var b64 = file.content.slice(hsStart.length, -hsEnd.length);
var decompressed = heatshrink.decompress(atob(b64));
file.content = "";
for (var i=0;i<decompressed.length;i++)
file.content += String.fromCharCode(decompressed[i]);
return;
}
// if JSON just pass through. We could try and minify.
if (file.name.endsWith(".json")) {
return;
}
// else... uh-oh
console.log(file);
throw new Error("Unable to evaluate "+file.name);
}
Promise.all(APPS.map(appid => {
var app = appjson.find(app=>app.id==appid);
if (app===undefined) throw new Error(`App ${appid} not found`);
@ -63,6 +121,8 @@ Promise.all(APPS.map(appid => {
// work out what goes in storage
var storageContent = "";
appfiles.forEach((file) => {
//console.log(file);
if (file.evaluate) evaluateFile(file);
var fileLength = file.content.length;
console.log(file.name+" -> "+fileLength+"b");
// set up header

232
modules/Layout.js Normal file
View File

@ -0,0 +1,232 @@
if (!g.theme) {
g.theme = {
fg:-1,bg:0,fgH:-1,bgH:"#008"
};
}
function Layout(layout, buttons) {
this._l = this.l = layout;
this.b = buttons;
// Do we have physical buttons?
this.physBtn = process.env.HWVERSION!=2;
this.yOffset = Object.keys(global.WIDGETS).length ? 24 : 0;
if (buttons) {
var btnHeight = Math.floor((g.getHeight()-this.yOffset) / buttons.length);
if (this.physBtn) {
if (Bangle.btnWatch) Bangle.btnWatch.forEach(clearWatch);
Bangle.btnWatch = [];
if (buttons[0]) Bangle.btnWatch.push(setWatch(pressHandler.bind(this,0), BTN1, {repeat:true,edge:-1}));
if (buttons[1]) Bangle.btnWatch.push(setWatch(pressHandler.bind(this,1), BTN2, {repeat:true,edge:-1}));
if (buttons[2]) Bangle.btnWatch.push(setWatch(pressHandler.bind(this,2), BTN3, {repeat:true,edge:-1}));
this._l.width = g.getWidth()-8; // text width
this._l = {type:"h", content: [
this._l,
{type:"v", content: buttons.map(b=>(b.type="txt",b.font="6x8",b.height=btnHeight,b.r=1,b))}
]};
} else { // no physical buttons, use touchscreen
this._l.width = g.getWidth()-20; // button width
this._l = {type:"h", content: [
this._l,
{type:"v", content: buttons.map(b=>(b.type="btn",b.height=btnHeight,b.width=32,b.r=1,b))}
]};
Bangle.touchHandler = (_,e) => touchHandler(this._l,e);
Bangle.on('touch',Bangle.touchHandler);
}
}
}
Layout.prototype.remove = function (l) {
if (Bangle.btnWatch) {
Bangle.btnWatch.forEach(clearWatch);
delete Bangle.btnWatch;
}
if (Bangle.touchHandler) {
Bangle.removeListener("touch",Bangle.touchHandler);
delete Bangle.touchHandler;
}
};
// Handler for button watch events
function pressHandler(btn,e) {
if (e.time-e.lastTime > 0.75 && this.b[btn].cbl)
this.b[btn].cbl(e);
else
if (this.b[btn].cb) this.b[btn].cb(e);
}
// Handler for touch events
function touchHandler(l,e) {
if (l.type=="btn" && l.cb && e.x>=l.x && e.y>=l.y && e.x<=l.x+l.w && e.y<=l.y+l.h)
l.cb(e);
if (l.content) l.content.forEach(n => touchHandler(n,e));
}
function updateMin(l) {
switch (l.type) {
case "txt": {
if (l.font.endsWith("%"))
l.font = "Vector"+Math.round(g.getHeight()*l.font.slice(0,-1)/100);
g.setFont(l.font);
l._h = g.getFontHeight();
l._w = g.stringWidth(l.label);
break;
}
case "btn": {
l._h = 24;
l._w = 14 + l.label.length*8;
break;
}
case "img": {
var im = E.toString(l.src());
l._h = im.charCodeAt(0);
l._w = im.charCodeAt(1);
break;
}
case "custom": {
// size should already be set up in width/height
l._w = 0;
l._h = 0;
break;
}
case "h": {
l.content.forEach(updateMin);
l._h = l.content.reduce((a,b)=>Math.max(a,b._h+(b.pad<<1)),0);
l._w = l.content.reduce((a,b)=>a+b._w+(b.pad<<1),0);
l.fill |= l.content.some(c=>c.fill);
break;
}
case "v": {
l.content.forEach(updateMin);
l._h = l.content.reduce((a,b)=>a+b._h+(b.pad<<1),0);
l._w = l.content.reduce((a,b)=>Math.max(a,b._w+(b.pad<<1)),0);
l.fill |= l.content.some(c=>c.fill);
break;
}
default: throw "Unknown item type "+l.type;
}
if (l.r&1) { // rotation
var t = l._w;l._w=l._h;l._h=t;
}
l._w = Math.max(l._w, 0|l.width);
l._h = Math.max(l._h, 0|l.height);
}
function render(l) {
if (!l) l = this.l;
g.reset();
if (l.col) g.setColor(l.col);
switch (l.type) {
case "txt":
g.setFont(l.font).setFontAlign(0,0,l.r).drawString(l.label, l.x+(l.w>>1), l.y+(l.h>>1));
break;
case "btn":
var poly = [
l.x,l.y+4,
l.x+4,l.y,
l.x+l.w-5,l.y,
l.x+l.w-1,l.y+4,
l.x+l.w-1,l.y+l.h-5,
l.x+l.w-5,l.y+l.h-1,
l.x+4,l.y+l.h-1,
l.x,l.y+l.h-5,
l.x,l.y+4
];
g.setColor(g.theme.bgH).fillPoly(poly).setColor(l.selected ? g.theme.fgH : g.theme.fg).drawPoly(poly).setFont("4x6",2).setFontAlign(0,0,l.r).drawString(l.label,l.x+l.w/2,l.y+l.h/2);
break;
case "img":
g.drawImage(l.src(), l.x, l.y);
break;
case "custom":
l.render(l);
break;
}
if (l.content) l.content.forEach(render);
}
Layout.prototype.render = function (l) {
if (!l) l = this._l;
render(l);
};
Layout.prototype.layout = function (l) {
// l = current layout element
// exw,exh = extra width/height available
var fill = l.content.reduce((a,l)=>a+(0|l.fill),0);
switch (l.type) {
case "h": {
let x = l.x + (l.w-l._w)/2;
if (fill) { x = l.x; }
l.content.forEach(c => {
c.w = c._w + (c.fill?(l.w-l._w)/fill:0);
c.h = c.fill ? l.h : c._h;
c.x = x;
c.y = l.y + (1+(0|c.valign))*(l.h-c.h)/2;
x += c.w;
if (c.pad) {
x += c.pad*2;
c.x += c.pad;
c.y += c.pad;
}
if (c.content) {
this.layout(c);
}
});
break;
}
case "v": {
let y = l.y + (l.h-l._h)/2;
if (fill) { y = l.y; }
l.content.forEach(c => {
c.w = c.fill ? l.w : c._w;
c.h = c._h + (c.fill?(l.h-l._h)/fill:0);
c.x = l.x + (1+(0|c.halign))*(l.w-c.w)/2;
c.y = y;
y += c.h;
if (c.pad) {
y += c.pad*2;
c.x += c.pad;
c.y += c.pad;
}
if (c.content) this.layout(c);
});
break;
}
}
};
Layout.prototype.debug = function(l,c) {
if (!l) l = this._l;
c=c||1;
g.setColor(c&1,c&2,c&4).drawRect(l.x+c-1, l.y+c-1, l.x+l.w-c, l.y+l.h-c);
c++;
if (l.content) l.content.forEach(n => this.debug(n,c));
};
Layout.prototype.update = function() {
var l = this._l;
var w = g.getWidth();
var y = this.yOffset;
var h = g.getHeight()-y;
// update sizes
updateMin(l);
// center
if (l.fill) {
l.w = w;
l.h = h;
l.x = 0;
l.y = y;
} else {
l.w = l._w;
l.h = l._h;
l.x = (w-l.w)/2;
l.y = y+(h-l.h)/2;
}
// layout children
this.layout(l);
};
Layout.prototype.clear = function(l) {
if (!l) l = this._l;
g.reset().clearRect(l.x,l.y,l.x+l.w-1,l.y+l.h-1);
};
exports = Layout;