Merge remote-tracking branch 'upstream/master'
157
apps.json
|
|
@ -1,10 +1,10 @@
|
|||
[
|
||||
{ "id": "boot",
|
||||
"name": "Bootloader",
|
||||
"tags": "tool,system",
|
||||
"tags": "tool,system,b2",
|
||||
"type":"bootloader",
|
||||
"icon": "bootloader.png",
|
||||
"version":"0.26",
|
||||
"version":"0.27",
|
||||
"description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings",
|
||||
"storage": [
|
||||
{"name":".boot0","url":"boot0.js"},
|
||||
|
|
@ -44,7 +44,7 @@
|
|||
"icon": "app.png",
|
||||
"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.",
|
||||
"tags": "tool,system,launcher",
|
||||
"tags": "tool,system,launcher,b2",
|
||||
"type":"launch",
|
||||
"storage": [
|
||||
{"name":"launch.app.js","url":"app.js"}
|
||||
|
|
@ -56,7 +56,7 @@
|
|||
"icon": "app.png",
|
||||
"version":"0.08",
|
||||
"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,
|
||||
"storage": [
|
||||
{"name":"about.app.js","url":"app.js"},
|
||||
|
|
@ -68,7 +68,7 @@
|
|||
"icon": "locale.png",
|
||||
"version":"0.09",
|
||||
"description": "Translations for different countries",
|
||||
"tags": "tool,system,locale,translate",
|
||||
"tags": "tool,system,locale,translate,b2",
|
||||
"type": "locale",
|
||||
"custom":"locale.html",
|
||||
"readme": "README.md",
|
||||
|
|
@ -174,7 +174,7 @@
|
|||
"icon": "settings.png",
|
||||
"version":"0.26",
|
||||
"description": "A menu for setting up Bangle.js",
|
||||
"tags": "tool,system",
|
||||
"tags": "tool,system,b2",
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{"name":"setting.app.js","url":"settings.js"},
|
||||
|
|
@ -191,7 +191,7 @@
|
|||
"icon": "app.png",
|
||||
"version":"0.11",
|
||||
"description": "Set and respond to alarms",
|
||||
"tags": "tool,alarm,widget",
|
||||
"tags": "tool,alarm,widget,b2",
|
||||
"storage": [
|
||||
{"name":"alarm.app.js","url":"app.js"},
|
||||
{"name":"alarm.boot.js","url":"boot.js"},
|
||||
|
|
@ -206,9 +206,9 @@
|
|||
{ "id": "wclock",
|
||||
"name": "Word Clock",
|
||||
"icon": "clock-word.png",
|
||||
"version":"0.02",
|
||||
"version":"0.03",
|
||||
"description": "Display Time as Text",
|
||||
"tags": "clock",
|
||||
"tags": "clock,b2",
|
||||
"type":"clock",
|
||||
"allow_emulator":true,
|
||||
"storage": [
|
||||
|
|
@ -312,9 +312,9 @@
|
|||
{ "id": "aclock",
|
||||
"name": "Analog Clock",
|
||||
"icon": "clock-analog.png",
|
||||
"version": "0.14",
|
||||
"version": "0.15",
|
||||
"description": "An Analog Clock",
|
||||
"tags": "clock",
|
||||
"tags": "clock,b2",
|
||||
"type":"clock",
|
||||
"allow_emulator":true,
|
||||
"storage": [
|
||||
|
|
@ -325,9 +325,9 @@
|
|||
{ "id": "clock2x3",
|
||||
"name": "2x3 Pixel Clock",
|
||||
"icon": "clock2x3.png",
|
||||
"version":"0.04",
|
||||
"version":"0.05",
|
||||
"description": "This is a simple clock using minimalist 2x3 pixel numerical digits",
|
||||
"tags": "clock",
|
||||
"tags": "clock,b2",
|
||||
"type": "clock",
|
||||
"allow_emulator":true,
|
||||
"storage": [
|
||||
|
|
@ -338,9 +338,9 @@
|
|||
{ "id": "geissclk",
|
||||
"name": "Geiss Clock",
|
||||
"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",
|
||||
"tags": "clock",
|
||||
"tags": "clock,nob2",
|
||||
"type":"clock",
|
||||
"storage": [
|
||||
{"name":"geissclk.app.js","url":"clock.js"},
|
||||
|
|
@ -457,10 +457,11 @@
|
|||
{ "id": "gpsrec",
|
||||
"name": "GPS Recorder",
|
||||
"icon": "app.png",
|
||||
"version":"0.19",
|
||||
"version":"0.21",
|
||||
"interface": "interface.html",
|
||||
"description": "Application that allows you to record a GPS track. Can run in background",
|
||||
"tags": "tool,outdoors,gps,widget",
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{"name":"gpsrec.app.js","url":"app.js"},
|
||||
{"name":"gpsrec.img","url":"app-icon.js","evaluate":true},
|
||||
|
|
@ -530,7 +531,7 @@
|
|||
{ "id": "weather",
|
||||
"name": "Weather",
|
||||
"icon": "icon.png",
|
||||
"version":"0.03",
|
||||
"version":"0.05",
|
||||
"description": "Show Gadgetbridge weather report",
|
||||
"readme": "readme.md",
|
||||
"tags": "widget,outdoors",
|
||||
|
|
@ -575,9 +576,9 @@
|
|||
{ "id": "widbat",
|
||||
"name": "Battery Level Widget",
|
||||
"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",
|
||||
"tags": "widget,battery",
|
||||
"tags": "widget,battery,b2",
|
||||
"type":"widget",
|
||||
"storage": [
|
||||
{"name":"widbat.wid.js","url":"widget.js"}
|
||||
|
|
@ -586,9 +587,9 @@
|
|||
{ "id": "widlock",
|
||||
"name": "Lock Widget",
|
||||
"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",
|
||||
"tags": "widget,lock",
|
||||
"tags": "widget,lock,b2",
|
||||
"type":"widget",
|
||||
"storage": [
|
||||
{"name":"widlock.wid.js","url":"widget.js"}
|
||||
|
|
@ -631,9 +632,9 @@
|
|||
{ "id": "widbt",
|
||||
"name": "Bluetooth Widget",
|
||||
"icon": "widget.png",
|
||||
"version":"0.04",
|
||||
"version":"0.05",
|
||||
"description": "Show the current Bluetooth connection status in the top right of the clock",
|
||||
"tags": "widget,bluetooth",
|
||||
"tags": "widget,bluetooth,b2",
|
||||
"type":"widget",
|
||||
"storage": [
|
||||
{"name":"widbt.wid.js","url":"widget.js"}
|
||||
|
|
@ -851,9 +852,9 @@
|
|||
{ "id": "sclock",
|
||||
"name": "Simple Clock",
|
||||
"icon": "clock-simple.png",
|
||||
"version":"0.04",
|
||||
"version":"0.05",
|
||||
"description": "A Simple Digital Clock",
|
||||
"tags": "clock",
|
||||
"tags": "clock,b2",
|
||||
"type":"clock",
|
||||
"allow_emulator":true,
|
||||
"storage": [
|
||||
|
|
@ -864,9 +865,9 @@
|
|||
{ "id": "s7clk",
|
||||
"name": "Simple 7 segment Clock",
|
||||
"icon": "icon.png",
|
||||
"version":"0.02",
|
||||
"version":"0.03",
|
||||
"description": "A simple 7 segment Clock with date",
|
||||
"tags": "clock",
|
||||
"tags": "clock,b2",
|
||||
"type":"clock",
|
||||
"allow_emulator":true,
|
||||
"storage": [
|
||||
|
|
@ -877,7 +878,7 @@
|
|||
{ "id": "vibrclock",
|
||||
"name": "Vibrate Clock",
|
||||
"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.",
|
||||
"tags": "clock",
|
||||
"type":"clock",
|
||||
|
|
@ -903,9 +904,9 @@
|
|||
{ "id": "dclock",
|
||||
"name": "Dev Clock",
|
||||
"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)",
|
||||
"tags": "clock",
|
||||
"tags": "clock,b2",
|
||||
"type":"clock",
|
||||
"allow_emulator":true,
|
||||
"storage": [
|
||||
|
|
@ -1029,7 +1030,7 @@
|
|||
{ "id": "bclock",
|
||||
"name": "Binary Clock",
|
||||
"icon": "clock-binary.png",
|
||||
"version":"0.02",
|
||||
"version":"0.03",
|
||||
"description": "A simple binary clock watch face",
|
||||
"tags": "clock",
|
||||
"type":"clock",
|
||||
|
|
@ -1105,9 +1106,9 @@
|
|||
"name": "Large Digit Blob Clock",
|
||||
"shortName" : "Blob Clock",
|
||||
"icon": "clock-blob.png",
|
||||
"version":"0.05",
|
||||
"version":"0.06",
|
||||
"description": "A clock with big digits",
|
||||
"tags": "clock",
|
||||
"tags": "clock,b2",
|
||||
"type":"clock",
|
||||
"allow_emulator":true,
|
||||
"storage": [
|
||||
|
|
@ -1118,9 +1119,9 @@
|
|||
{ "id": "boldclk",
|
||||
"name": "Bold Clock",
|
||||
"icon": "bold_clock.png",
|
||||
"version":"0.03",
|
||||
"version":"0.04",
|
||||
"description": "Simple, readable and practical clock",
|
||||
"tags": "clock",
|
||||
"tags": "clock,b2",
|
||||
"type":"clock",
|
||||
"allow_emulator":true,
|
||||
"storage": [
|
||||
|
|
@ -1131,7 +1132,7 @@
|
|||
{ "id": "widclk",
|
||||
"name": "Digital clock widget",
|
||||
"icon": "widget.png",
|
||||
"version":"0.04",
|
||||
"version":"0.05",
|
||||
"description": "A simple digital clock widget",
|
||||
"tags": "widget,clock",
|
||||
"type":"widget",
|
||||
|
|
@ -1142,9 +1143,9 @@
|
|||
{ "id": "widpedom",
|
||||
"name": "Pedometer widget",
|
||||
"icon": "widget.png",
|
||||
"version":"0.13",
|
||||
"version":"0.14",
|
||||
"description": "Daily pedometer widget",
|
||||
"tags": "widget",
|
||||
"tags": "widget,b2",
|
||||
"type":"widget",
|
||||
"storage": [
|
||||
{"name":"widpedom.wid.js","url":"widget.js"},
|
||||
|
|
@ -1154,7 +1155,7 @@
|
|||
{ "id": "berlinc",
|
||||
"name": "Berlin Clock",
|
||||
"icon": "berlin-clock.png",
|
||||
"version":"0.03",
|
||||
"version":"0.04",
|
||||
"description": "Berlin Clock (see https://en.wikipedia.org/wiki/Mengenlehreuhr)",
|
||||
"tags": "clock",
|
||||
"type":"clock",
|
||||
|
|
@ -1167,9 +1168,9 @@
|
|||
{ "id": "ctrclk",
|
||||
"name": "Centerclock",
|
||||
"icon": "app.png",
|
||||
"version":"0.02",
|
||||
"version":"0.03",
|
||||
"description": "Watch-centered digital 24h clock with date in dd.mm.yyyy format.",
|
||||
"tags": "clock",
|
||||
"tags": "clock,nob2",
|
||||
"type":"clock",
|
||||
"allow_emulator":true,
|
||||
"storage": [
|
||||
|
|
@ -1207,9 +1208,9 @@
|
|||
"id": "pipboy",
|
||||
"name": "Pipboy",
|
||||
"icon": "app.png",
|
||||
"version": "0.03",
|
||||
"version": "0.04",
|
||||
"description": "Pipboy themed clock",
|
||||
"tags": "clock",
|
||||
"tags": "clock,nob2",
|
||||
"type":"clock",
|
||||
"allow_emulator":true,
|
||||
"storage": [
|
||||
|
|
@ -1288,9 +1289,9 @@
|
|||
"name": "Commandline-Clock",
|
||||
"shortName":"CLI-Clock",
|
||||
"icon": "app.png",
|
||||
"version":"0.12",
|
||||
"version":"0.13",
|
||||
"description": "Simple CLI-Styled Clock",
|
||||
"tags": "clock,cli,command,bash,shell",
|
||||
"tags": "clock,cli,command,bash,shell,b2",
|
||||
"type":"clock",
|
||||
"allow_emulator":true,
|
||||
"storage": [
|
||||
|
|
@ -1312,10 +1313,11 @@
|
|||
{ "id": "barclock",
|
||||
"name": "Bar Clock",
|
||||
"icon": "clock-bar.png",
|
||||
"version":"0.05",
|
||||
"version":"0.07",
|
||||
"description": "A simple digital clock showing seconds as a bar",
|
||||
"tags": "clock",
|
||||
"type":"clock",
|
||||
"readme": "README.md",
|
||||
"allow_emulator":true,
|
||||
"storage": [
|
||||
{"name":"barclock.app.js","url":"clock-bar.js"},
|
||||
|
|
@ -1325,9 +1327,9 @@
|
|||
{ "id": "dotclock",
|
||||
"name": "Dot Clock",
|
||||
"icon": "clock-dot.png",
|
||||
"version":"0.02",
|
||||
"version":"0.03",
|
||||
"description": "A Minimal Dot Analog Clock",
|
||||
"tags": "clock",
|
||||
"tags": "clock,b2",
|
||||
"type":"clock",
|
||||
"allow_emulator":true,
|
||||
"storage": [
|
||||
|
|
@ -1462,9 +1464,9 @@
|
|||
"name": "OpenStreetMap",
|
||||
"shortName":"OpenStMap",
|
||||
"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",
|
||||
"tags": "outdoors,gps",
|
||||
"tags": "outdoors,gps,b2",
|
||||
"custom": "custom.html",
|
||||
"storage": [
|
||||
{"name":"openstmap","url":"openstmap.js"},
|
||||
|
|
@ -1529,9 +1531,9 @@
|
|||
"name": "Dev Stopwatch",
|
||||
"shortName":"Dev Stopwatch",
|
||||
"icon": "app.png",
|
||||
"version":"0.02",
|
||||
"version":"0.03",
|
||||
"description": "Stopwatch with 5 laps supported (cyclically replaced)",
|
||||
"tags": "stopwatch, chrono, timer, chronometer",
|
||||
"tags": "stopwatch,chrono,timer,chronometer,b2",
|
||||
"allow_emulator":true,
|
||||
"storage": [
|
||||
{"name":"devstopwatch.app.js","url":"app.js"},
|
||||
|
|
@ -1570,7 +1572,7 @@
|
|||
"name": "Numerals Clock",
|
||||
"shortName": "Numerals Clock",
|
||||
"icon": "numerals.png",
|
||||
"version":"0.08",
|
||||
"version":"0.09",
|
||||
"description": "A simple big numerals clock",
|
||||
"tags": "numerals,clock",
|
||||
"type":"clock",
|
||||
|
|
@ -1856,9 +1858,9 @@
|
|||
{ "id": "calendar",
|
||||
"name": "Calendar",
|
||||
"icon": "calendar.png",
|
||||
"version": "0.01",
|
||||
"version": "0.02",
|
||||
"description": "Simple calendar",
|
||||
"tags": "calendar",
|
||||
"tags": "calendar,b2",
|
||||
"readme": "README.md",
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
|
|
@ -1984,7 +1986,7 @@
|
|||
"id": "beebclock",
|
||||
"name": "Beeb Clock",
|
||||
"icon": "beebclock.png",
|
||||
"version":"0.03",
|
||||
"version":"0.04",
|
||||
"description": "Clock face that may be coincidentally familiar to BBC viewers",
|
||||
"tags": "clock",
|
||||
"type": "clock",
|
||||
|
|
@ -2028,9 +2030,9 @@
|
|||
"name": "Time Traveller's Chronometer",
|
||||
"shortName": "Time Travel Clock",
|
||||
"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.",
|
||||
"tags": "clock",
|
||||
"tags": "clock,b2",
|
||||
"readme": "README.md",
|
||||
"type": "clock",
|
||||
"allow_emulator":true,
|
||||
|
|
@ -2112,7 +2114,7 @@
|
|||
"name": "Binary Clock",
|
||||
"shortName":"Binary Clock",
|
||||
"icon": "app.png",
|
||||
"version":"0.02",
|
||||
"version":"0.03",
|
||||
"description": "A binary clock with hours and minutes. BTN1 toggles a digital clock.",
|
||||
"tags": "clock,binary",
|
||||
"type": "clock",
|
||||
|
|
@ -2139,9 +2141,9 @@
|
|||
"name": "Animated Clock",
|
||||
"shortName":"Anim Clock",
|
||||
"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",
|
||||
"tags": "clock,animated",
|
||||
"tags": "clock,animated,nob2",
|
||||
"type": "clock",
|
||||
"storage": [
|
||||
{"name":"animclk.app.js","url":"app.js"},
|
||||
|
|
@ -2155,9 +2157,9 @@
|
|||
"name": "Analog Clock (Image background)",
|
||||
"shortName":"Analog Clock",
|
||||
"icon": "app.png",
|
||||
"version":"0.02",
|
||||
"version":"0.03",
|
||||
"description": "An analog clock with an image background",
|
||||
"tags": "clock",
|
||||
"tags": "clock,nob2",
|
||||
"type": "clock",
|
||||
"storage": [
|
||||
{"name":"analogimgclk.app.js","url":"app.js"},
|
||||
|
|
@ -2475,7 +2477,7 @@
|
|||
"name": "World Clock - 4 time zones",
|
||||
"shortName":"World Clock",
|
||||
"icon": "app.png",
|
||||
"version":"0.03",
|
||||
"version":"0.04",
|
||||
"description": "Current time zone plus up to four others",
|
||||
"tags": "clock",
|
||||
"type" : "clock",
|
||||
|
|
@ -2493,9 +2495,9 @@
|
|||
"name": "Digital Clock Face",
|
||||
"shortName":"Digi Clock",
|
||||
"icon": "digiclock.png",
|
||||
"version":"0.01",
|
||||
"version":"0.02",
|
||||
"description": "A simple digital clock with the time, day, month, and year",
|
||||
"tags": "clock",
|
||||
"tags": "clock,nob2",
|
||||
"type" : "clock",
|
||||
"storage": [
|
||||
{"name":"digiclock.app.js","url":"digiclock.js"},
|
||||
|
|
@ -2753,7 +2755,7 @@
|
|||
{ "id": "astral",
|
||||
"name": "Astral Clock",
|
||||
"icon": "app-icon.png",
|
||||
"version":"0.02",
|
||||
"version":"0.03",
|
||||
"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.",
|
||||
"tags": "clock",
|
||||
|
|
@ -2812,7 +2814,7 @@
|
|||
"name": "De-Stress",
|
||||
"shortName":"De-Stress",
|
||||
"icon": "app.png",
|
||||
"version":"0.01",
|
||||
"version":"0.02",
|
||||
"description": "Simple haptic heartbeat",
|
||||
"storage": [
|
||||
{"name":"de-stress.app.js","url":"app.js"},
|
||||
|
|
@ -3049,7 +3051,7 @@
|
|||
"version":"0.01",
|
||||
"description": "Displays RGB565 and RGB888 colors, its name and code in screen.",
|
||||
"readme": "README.md",
|
||||
"tags": "Color, input,buttons,touch,UI",
|
||||
"tags": "Color,input,buttons,touch,UI,nob2",
|
||||
"storage": [
|
||||
{"name":"color_catalog.app.js","url":"app.js"},
|
||||
{"name":"color_catalog.img","url":"app-icon.js","evaluate":true}
|
||||
|
|
@ -3212,7 +3214,6 @@
|
|||
"readme": "README.md",
|
||||
"description": "An Omnitrix Showpiece",
|
||||
"tags": "game",
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{"name":"omnitrix.app.js","url":"omnitrix.app.js"},
|
||||
{"name":"omnitrix.img","url":"omnitrix.icon.js","evaluate":true}
|
||||
|
|
@ -3222,7 +3223,7 @@
|
|||
"name": "Bat Clock",
|
||||
"shortName":"Bat Clock",
|
||||
"icon": "bat-clock.png",
|
||||
"version":"0.01",
|
||||
"version":"0.02",
|
||||
"description": "Morphing Clock, with an awesome \"The Dark Knight\" themed logo.",
|
||||
"tags": "clock",
|
||||
"type": "clock",
|
||||
|
|
@ -3262,10 +3263,22 @@
|
|||
{"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.0",
|
||||
"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",
|
||||
|
|
|
|||
|
|
@ -9,3 +9,4 @@
|
|||
0.12: Fix regression after 0.11
|
||||
0.13: Fix broken date padding (fix #376)
|
||||
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 p = Math.PI / 2;
|
||||
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;
|
||||
let timer = null;
|
||||
let currentDate = new Date();
|
||||
const centerX = g.getWidth() / 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 a = angle * pRad;
|
||||
|
|
@ -46,40 +49,35 @@ const drawAll = () => {
|
|||
// draw all secs
|
||||
|
||||
for (let i = 0; i < 60; i++) {
|
||||
if (i > currentSec) {
|
||||
g.setColor(0, 0, 0.6);
|
||||
} else {
|
||||
g.setColor(0.3, 0.3, 1);
|
||||
}
|
||||
g.setColor((i > currentSec) ? colSecA : colSecB);
|
||||
seconds((360 * i) / 60);
|
||||
}
|
||||
onSecond();
|
||||
|
||||
};
|
||||
|
||||
const resetSeconds = () => {
|
||||
g.setColor(0, 0, 0.6);
|
||||
g.setColor(colSecA);
|
||||
for (let i = 0; i < 60; i++) {
|
||||
seconds((360 * i) / 60);
|
||||
}
|
||||
};
|
||||
|
||||
const onSecond = () => {
|
||||
g.setColor(0.3, 0.3, 1);
|
||||
g.setColor(colSecB);
|
||||
seconds((360 * currentDate.getSeconds()) / 60);
|
||||
if (currentDate.getSeconds() === 59) {
|
||||
resetSeconds();
|
||||
onMinute();
|
||||
}
|
||||
g.setColor(1, 0.7, 0.2);
|
||||
g.setColor(colSec1);
|
||||
currentDate = new Date();
|
||||
seconds((360 * currentDate.getSeconds()) / 60);
|
||||
g.setColor(1, 1, 1);
|
||||
g.setColor(g.theme.fg);
|
||||
};
|
||||
|
||||
const drawDate = () => {
|
||||
g.reset();
|
||||
g.setColor(1, 0, 0);
|
||||
g.setColor("#f00");
|
||||
g.setFont('6x8', 2);
|
||||
|
||||
const dayString = locale.dow(currentDate, true);
|
||||
|
|
@ -89,7 +87,7 @@ const drawDate = () => {
|
|||
// console.log(`${dayString}|${dateString}`);
|
||||
// center date
|
||||
const l = (g.getWidth() - g.stringWidth(dateDisplay)) / 2;
|
||||
const t = centerY + 37;
|
||||
const t = centerY + faceWidth*0.37;
|
||||
g.drawString(dateDisplay, l, t, true);
|
||||
// console.log(l, t);
|
||||
};
|
||||
|
|
@ -99,7 +97,7 @@ const onMinute = () => {
|
|||
resetSeconds();
|
||||
}
|
||||
// clear existing hands
|
||||
g.setColor(0, 0, 0);
|
||||
g.setColor(g.theme.bg);
|
||||
// Hour
|
||||
hand((360 * (currentDate.getHours() + currentDate.getMinutes() / 60)) / 12, -8, faceWidth - 35);
|
||||
// Minute
|
||||
|
|
@ -107,10 +105,10 @@ const onMinute = () => {
|
|||
|
||||
// get new date, then draw new hands
|
||||
currentDate = new Date();
|
||||
g.setColor(1, 0.9, 0.9);
|
||||
g.setColor(g.theme.fg);
|
||||
// Hour
|
||||
hand((360 * (currentDate.getHours() + currentDate.getMinutes() / 60)) / 12, -8, faceWidth - 35);
|
||||
g.setColor(1, 1, 0.9);
|
||||
g.setColor(g.theme.fg);
|
||||
// Minute
|
||||
hand((360 * currentDate.getMinutes()) / 60, -8, faceWidth - 10);
|
||||
drawDate();
|
||||
|
|
@ -137,8 +135,9 @@ g.clear();
|
|||
resetSeconds();
|
||||
startTimers();
|
||||
drawAll();
|
||||
|
||||
// Show launcher when button pressed
|
||||
Bangle.setUI("clock");
|
||||
|
||||
Bangle.loadWidgets();
|
||||
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.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");
|
||||
}
|
||||
|
||||
// Show launcher when middle button pressed
|
||||
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.02: Fix bug if image clock wasn't installed
|
||||
0.03: Update to use setUI
|
||||
|
|
|
|||
|
|
@ -102,5 +102,5 @@ if (g.drawImages) {
|
|||
} else {
|
||||
E.showMessage("Please update\nBangle.js firmware\nto use this clock","animclk");
|
||||
}
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
||||
// Show launcher when button pressed
|
||||
Bangle.setUI("clock");
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
0.01: Create astral clock app
|
||||
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.
|
||||
// Use lon = 0 to get the Greenwich MST.
|
||||
// "mean_sidereal_time" returns the Mean Sidereal Time in units of degrees.
|
||||
// Use lon = 0 to get the Greenwich MST.
|
||||
// East longitudes are positive; West longitudes are negative
|
||||
//
|
||||
// returns: time in degrees
|
||||
|
|
@ -523,7 +523,7 @@ function mean_sidereal_time(lon) {
|
|||
var c = Math.floor(365.25 * year);
|
||||
var da = Math.floor(30.6001 * (month + 1));
|
||||
|
||||
// days since J2000.0
|
||||
// days since J2000.0
|
||||
var jd = b + c + da - 730550.5 + day
|
||||
+ (hour + mins / 60.0 + secs / 3600.0) / 24.0;
|
||||
|
||||
|
|
@ -796,10 +796,11 @@ Bangle.on('lcdPower', on => {
|
|||
Bangle.setCompassPower(1);
|
||||
Bangle.setGPSPower(1);
|
||||
|
||||
// Buttons
|
||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
||||
// Show launcher when button pressed
|
||||
Bangle.setClockMode();
|
||||
|
||||
setWatch(function () {
|
||||
Bangle.setUI("clockupdown", btn => {
|
||||
if (btn==0) {
|
||||
if (!processing) {
|
||||
if (!modeswitch) {
|
||||
modeswitch = true;
|
||||
|
|
@ -809,12 +810,11 @@ setWatch(function () {
|
|||
else
|
||||
modeswitch = false;
|
||||
}
|
||||
}, BTN3, { repeat: true });
|
||||
|
||||
setWatch(function () {
|
||||
} else {
|
||||
if (!processing)
|
||||
ready_to_compute = true;
|
||||
}, BTN1, { repeat: true });
|
||||
}
|
||||
});
|
||||
|
||||
setWatch(function () {
|
||||
if (!astral_settings.astral_default) {
|
||||
|
|
|
|||
|
|
@ -2,4 +2,6 @@
|
|||
0.02: Apply locale, 12-hour setting
|
||||
0.03: Fix dates drawing over each other at midnight
|
||||
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
|
||||
**/
|
||||
{
|
||||
// Check settings for what type our clock should be
|
||||
const is12Hour = (require('Storage').readJSON('setting.json', 1) || {})['12hour']
|
||||
let locale = require('locale')
|
||||
{ // add some more info to locale
|
||||
let date = new Date()
|
||||
date.setFullYear(1111)
|
||||
date.setMonth(1, 3) // februari: months are zero-indexed
|
||||
const localized = locale.date(date, true)
|
||||
locale.dayFirst = /3.*2/.test(localized)
|
||||
|
||||
locale.hasMeridian = false
|
||||
if(typeof locale.meridian === 'function') { // function does not exists if languages app is not installed
|
||||
locale.hasMeridian = (locale.meridian(date) !== '')
|
||||
}
|
||||
|
||||
}
|
||||
const screen = {
|
||||
width: g.getWidth(),
|
||||
height: g.getWidth(),
|
||||
middle: g.getWidth() / 2,
|
||||
center: g.getHeight() / 2,
|
||||
// Check settings for what type our clock should be
|
||||
const is12Hour = (require('Storage').readJSON('setting.json', 1) || {})['12hour']
|
||||
let locale = require('locale')
|
||||
{ // add some more info to locale
|
||||
let date = new Date()
|
||||
date.setFullYear(1111)
|
||||
date.setMonth(1, 3) // februari: months are zero-indexed
|
||||
const localized = locale.date(date, true)
|
||||
locale.dayFirst = /3.*2/.test(localized)
|
||||
|
||||
locale.hasMeridian = false
|
||||
if(typeof locale.meridian === 'function') { // function does not exists if languages app is not installed
|
||||
locale.hasMeridian = (locale.meridian(date) !== '')
|
||||
}
|
||||
|
||||
// hardcoded "settings"
|
||||
const settings = {
|
||||
time: {
|
||||
}
|
||||
const screen = {
|
||||
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,
|
||||
font: '6x8',
|
||||
size: (is12Hour && locale.hasMeridian) ? 6 : 8,
|
||||
middle: screen.middle,
|
||||
center: screen.center,
|
||||
ampm: {
|
||||
color: -1,
|
||||
font: '6x8',
|
||||
size: 2,
|
||||
},
|
||||
size: 2,
|
||||
},
|
||||
date: {
|
||||
color: -1,
|
||||
font: 'Vector',
|
||||
size: 20,
|
||||
middle: screen.height - 20, // at bottom of screen
|
||||
center: screen.center,
|
||||
},
|
||||
bar: {
|
||||
color: -1,
|
||||
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()
|
||||
},
|
||||
date: {
|
||||
color: -1,
|
||||
font: 'Vector',
|
||||
size: 20,
|
||||
middle: screen.height - 20, // at bottom of screen
|
||||
center: screen.center,
|
||||
},
|
||||
bar: {
|
||||
color: -1,
|
||||
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, 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.02: Update to use Bangle.setUI instead of setWatch
|
||||
|
|
|
|||
|
|
@ -256,8 +256,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");
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
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();
|
||||
setInterval(() => { drawClock(); }, 1000);
|
||||
drawClock();
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
||||
// Show launcher when button pressed
|
||||
Bangle.setUI("clock");
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
0.01: Initial commit. Not very efficient, and widgets not working for some reason.
|
||||
0.02: Fixes; widget support
|
||||
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) {
|
||||
// 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;
|
||||
// R1, R2: Outer and inner radii of hour marks
|
||||
// RC1, RC2: Outer and inner radii of hub
|
||||
// CX, CY: Centre location, relative to buffer (not screen, necessarily)
|
||||
// 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;
|
||||
|
||||
// R1, R2: Outer and inner radii of hour marks
|
||||
// RC1, RC2: Outer and inner radii of hub
|
||||
// CX, CY: Centre location, relative to buffer (not screen, necessarily)
|
||||
// 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
|
||||
const GW = g.getWidth();
|
||||
const GH = g.getHeight();
|
||||
|
||||
// Screen size
|
||||
const GW = g.getWidth();
|
||||
const GH = g.getHeight();
|
||||
// Top margin: the gap taken from the top of the buffer, except when
|
||||
// in mode 0 (full screen)
|
||||
let TM;
|
||||
|
||||
// Top margin: the gap taken from the top of the buffer, except when
|
||||
// in mode 0 (full screen)
|
||||
let TM;
|
||||
// Buffer image. undefined means it needs regenerating
|
||||
let faceImg;
|
||||
|
||||
// Buffer image. undefined means it needs regenerating
|
||||
let faceImg;
|
||||
// with_seconds flag determines whether the face is updated every
|
||||
// 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
|
||||
// second or every minute, and to draw the hand or not.
|
||||
let with_seconds = true;
|
||||
// Display flags, determined from `mode` by setMode()
|
||||
let with_widgets = false;
|
||||
let with_digital_time = true;
|
||||
let with_digital_date = true;
|
||||
|
||||
// Display flags, determined from `mode` by setMode()
|
||||
let with_widgets = false;
|
||||
let with_digital_time = true;
|
||||
let with_digital_date = true;
|
||||
// Create offscreen buffer for the once-per-minute face draw
|
||||
const G1 = Graphics.createArrayBuffer(g.getWidth(), g.getHeight(), 1, {msb:true});
|
||||
|
||||
// Create offscreen buffer for the once-per-minute face draw
|
||||
const G1 = Graphics.createArrayBuffer(g.getWidth(), g.getHeight(), 1, {msb:true});
|
||||
// Precalculate sin/cos for the hour marks. Might be premature
|
||||
// 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
|
||||
// optimisation, but might as well.
|
||||
let ss = [], cs = [];
|
||||
// Draw the face with hour and minute hand. Ideally, we'd separate
|
||||
// the face from the hands and double-buffer, but memory is limited,
|
||||
// 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++) {
|
||||
const a = Math.PI * h / 6;
|
||||
ss[h] = Math.sin(a);
|
||||
cs[h] = Math.cos(a);
|
||||
hs[h] = HSCALE(h);
|
||||
G.fillRotRect(ss[h], cs[h], CX, CY, -hs[h], hs[h], R2, R1);
|
||||
|
||||
}
|
||||
|
||||
// Draw the face with hour and minute hand. Ideally, we'd separate
|
||||
// the face from the hands and double-buffer, but memory is limited,
|
||||
// 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 = [];
|
||||
// Draw the hub
|
||||
G.fillCircle(CX, CY, RC1);
|
||||
|
||||
// Wipe the image and start with white
|
||||
G.clear();
|
||||
G.setColor(1,1,1);
|
||||
// Black
|
||||
G.setColor(0,0,0);
|
||||
|
||||
// Draw the hour marks.
|
||||
for (let h=1; h<=12; h++) {
|
||||
hs[h] = HSCALE(h);
|
||||
G.fillRotRect(ss[h], cs[h], CX, CY, -hs[h], hs[h], R2, R1);
|
||||
// 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.
|
||||
|
||||
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
|
||||
G.fillCircle(CX, CY, RC1);
|
||||
|
||||
// Black
|
||||
G.setColor(0,0,0);
|
||||
|
||||
// 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.
|
||||
// If the time has updated, we need to _at least_ draw the
|
||||
// image to the screen.
|
||||
g.setColor(1,1,1);
|
||||
g.drawImage({width:GW,
|
||||
height:GH-TM,
|
||||
buffer:G1.buffer}, 0, TM);
|
||||
|
||||
// and possibly add the second hand
|
||||
if (with_seconds) {
|
||||
// If we're going by second, we always need an update.
|
||||
seconds = now.getSeconds();
|
||||
time_changed = true;
|
||||
let a = 2.0 * Math.PI * seconds / 60.0;
|
||||
g.drawRotLine(Math.sin(a), Math.cos(a), CX, CY+TM, RC1, R1);
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
// And draw widgets if we're in that mode
|
||||
if (with_widgets)
|
||||
Bangle.drawWidgets();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
// Schedule to repeat this. A `setTimeout(1000)` isn't good
|
||||
// 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);
|
||||
};
|
||||
|
||||
// Has the time updated? If so, we'll need to draw something.
|
||||
if (time_changed) {
|
||||
const setButtons = () => {
|
||||
// Show launcher when button pressed
|
||||
Bangle.setUI("clockupdown", btn=> {
|
||||
if (btn==0) changeSeconds();
|
||||
if (btn==1) { ++mode; setMode(); drawAll(true); }
|
||||
});
|
||||
};
|
||||
|
||||
// Are we adding text?
|
||||
if (with_digital_date || with_digital_time) {
|
||||
// Load display parameters based on `mode`
|
||||
const setMode = () => {
|
||||
// Normalize mode to 0 <= mode <= 5
|
||||
mode = (6+mode) % 6;
|
||||
|
||||
// Construct the date/time text to add above the face
|
||||
let d = now.toString();
|
||||
let da = d.toString().split(" ");
|
||||
let txt;
|
||||
// [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 (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 (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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
|
||||
// If the time has updated, we need to _at least_ draw the
|
||||
// image to the screen.
|
||||
g.setColor(1,1,1);
|
||||
g.drawImage({width:GW,
|
||||
height:GH-TM,
|
||||
buffer:G1.buffer}, 0, TM);
|
||||
CX = GW/2;
|
||||
CY = R1;
|
||||
|
||||
// and possibly add the second hand
|
||||
if (with_seconds) {
|
||||
let a = 2.0 * Math.PI * seconds / 60.0;
|
||||
g.drawRotLine(Math.sin(a), Math.cos(a), CX, CY+TM, RC1, 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;
|
||||
}
|
||||
|
||||
// And draw widgets if we're in that mode
|
||||
if (with_widgets)
|
||||
Bangle.drawWidgets();
|
||||
}
|
||||
// We only don't bother redrawing the face from modes 2 to 5, as
|
||||
// they're the same.
|
||||
if (!faceImg || mode<3) {
|
||||
faceImg = undefined;
|
||||
}
|
||||
|
||||
// Schedule to repeat this. A `setTimeout(1000)` isn't good
|
||||
// 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
|
||||
// Store the settings for next time
|
||||
try {
|
||||
conf = storage.readJSON(filename);
|
||||
mode = conf[0];
|
||||
with_seconds = conf[1];
|
||||
storage.writeJSON(filename, [mode,with_seconds]);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
mode = 1;
|
||||
}
|
||||
|
||||
setButtons();
|
||||
setMode();
|
||||
drawAll();
|
||||
// Clear the screen: we need to make sure all parts are cleaned off.
|
||||
g.clear();
|
||||
};
|
||||
|
||||
Bangle.on('lcdPower', (on) => {
|
||||
if (on) {
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
drawAll();
|
||||
} else {
|
||||
clearTimeout();
|
||||
}
|
||||
});
|
||||
const changeSeconds = () => {
|
||||
with_seconds = !with_seconds;
|
||||
drawAll(true);
|
||||
};
|
||||
|
||||
})(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.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() {
|
||||
g.clear();
|
||||
var now = new Date();
|
||||
|
||||
|
||||
// show date below the clock
|
||||
if (show_date) {
|
||||
var yr = now.getFullYear();
|
||||
|
|
@ -28,7 +28,7 @@ function drawBerlinClock() {
|
|||
g.setFontAlign(-1,-1);
|
||||
g.drawString(dateString, ( g.getWidth() - strWidth ) / 2, height + offset + 4);
|
||||
}
|
||||
|
||||
|
||||
rowlights[0] = Math.floor(now.getHours() / 5);
|
||||
rowlights[1] = now.getHours() % 5;
|
||||
rowlights[2] = Math.floor(now.getMinutes() / 5);
|
||||
|
|
@ -62,7 +62,7 @@ function drawBerlinClock() {
|
|||
} else {
|
||||
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) {
|
||||
g.setColor(1,1,1);
|
||||
|
|
@ -100,9 +100,11 @@ g.clear();
|
|||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
drawBerlinClock();
|
||||
// Toggle date display, when BTN3 is pressed
|
||||
setWatch(toggleTime,BTN1, { repeat : true, edge: "falling"});
|
||||
// Toggle date display, when BTN3 is pressed
|
||||
setWatch(toggleDate,BTN3, { repeat : true, edge: "falling"});
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
||||
if (BTN3) {
|
||||
// Toggle date display, when BTN3 is pressed
|
||||
setWatch(toggleTime,BTN1, { repeat : true, edge: "falling"});
|
||||
// Toggle date display, when BTN3 is pressed
|
||||
setWatch(toggleDate,BTN3, { repeat : true, edge: "falling"});
|
||||
}
|
||||
// Show launcher when button pressed
|
||||
Bangle.setUI("clock");
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
0.01: New App!
|
||||
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){
|
||||
|
||||
|
||||
var j;
|
||||
for(j=0;j<hourLED.length;j++){
|
||||
prevHour[j] = hourLED[j];
|
||||
}
|
||||
|
||||
|
||||
var i;
|
||||
for(i = 0;i < hourLED.length;i++){
|
||||
hourLED[i]=0;
|
||||
hourLED[i]=0;
|
||||
}
|
||||
|
||||
|
||||
if(hours > 15){
|
||||
hourLED[0] = 1;
|
||||
hours = hours - 16;
|
||||
|
|
@ -53,9 +53,9 @@ function updateHourArray(hours){
|
|||
if(hours > 0){
|
||||
hourLED[4] = 1;
|
||||
}
|
||||
|
||||
|
||||
return hourLED;
|
||||
|
||||
|
||||
}
|
||||
|
||||
function updateMinuteArray(minutes){
|
||||
|
|
@ -63,12 +63,12 @@ function updateMinuteArray(minutes){
|
|||
for(j=0;j<minuteLED.length;j++){
|
||||
prevMinute[j] = minuteLED[j];
|
||||
}
|
||||
|
||||
|
||||
var i;
|
||||
for(i = 0;i < minuteLED.length;i++){
|
||||
minuteLED[i]=0;
|
||||
minuteLED[i]=0;
|
||||
}
|
||||
|
||||
|
||||
if(minutes > 31){
|
||||
minuteLED[0] = 1;
|
||||
minutes = minutes - 32;
|
||||
|
|
@ -92,20 +92,20 @@ function updateMinuteArray(minutes){
|
|||
if(minutes > 0){
|
||||
minuteLED[5] = 1;
|
||||
}
|
||||
|
||||
|
||||
return minuteLED;
|
||||
|
||||
|
||||
}
|
||||
|
||||
function draw(){
|
||||
|
||||
|
||||
// work out how to display the current time
|
||||
var d = new Date();
|
||||
var h = d.getHours(), m = d.getMinutes();
|
||||
|
||||
|
||||
updateHourArray(h);
|
||||
updateMinuteArray(m);
|
||||
|
||||
|
||||
var i;
|
||||
//Draw hour circles
|
||||
for(i=0; i<hourLED.length; i++){
|
||||
|
|
@ -118,10 +118,10 @@ function draw(){
|
|||
g.fillCircle(24+i*48,50,10);
|
||||
g.setColor(colour);
|
||||
g.drawCircle(24+i*48,50,10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for(i=0; i<minuteLED.length; i++){
|
||||
if(prevMinute[i] == minuteLED[i]){
|
||||
if(minuteLED[i] == 1){
|
||||
|
|
@ -132,21 +132,21 @@ function draw(){
|
|||
g.fillCircle(20+i*40,100,10);
|
||||
g.setColor(colour);
|
||||
g.drawCircle(20+i*40,100,10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// draw the date, in a normal font
|
||||
g.setFont("6x8");
|
||||
g.setFontAlign(0,1); // align center bottom
|
||||
// pad the date - this clears the background if the date were to change length
|
||||
var dateStr = " "+require("locale").date(d)+" ";
|
||||
g.drawString(dateStr, g.getWidth()/2, 130, true /*clear background*/);
|
||||
|
||||
|
||||
if(displayTime){
|
||||
drawTime(d);
|
||||
}else{
|
||||
g.clearRect(0,240,240,130);
|
||||
g.clearRect(0,240,240,130);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -167,12 +167,12 @@ Bangle.on('lcdPower',on=>{
|
|||
// Load widgets
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
||||
setWatch(function() {
|
||||
// Show launcher when button pressed
|
||||
Bangle.setUI("clockupdown", btn=>{
|
||||
if (btn!=1) return;
|
||||
if(displayTime == 0){
|
||||
displayTime = 1;
|
||||
} else{
|
||||
displayTime = 0;
|
||||
displayTime = 0;
|
||||
}
|
||||
}, BTN, {edge:"rising", debounce:50, repeat:true});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -4,3 +4,4 @@
|
|||
0.03: Modified for use with new bootloader and firmware
|
||||
0.04: Modified to account for changes in the behavior of Graphics.fillPoly
|
||||
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 = [
|
||||
[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
|
||||
|
|
@ -14,8 +16,10 @@ const NUMBERS = [
|
|||
let intervalRef = null;
|
||||
let digits = [-1,-1,-1,-1,-1,-1];
|
||||
function flip() {
|
||||
g.setColor(1,1,1);
|
||||
g.drawImage({width:buf.getWidth(),height:buf.getHeight(),buffer:buf.buffer},55,26);
|
||||
g.reset();
|
||||
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) {
|
||||
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 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++) {
|
||||
var px = p%5;
|
||||
var py = Math.floor(p/5);
|
||||
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] ) {
|
||||
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] ) {
|
||||
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] ) {
|
||||
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] ) {
|
||||
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] ) {
|
||||
drawPixel(108,164,px,py,3,NUMBERS[newDigits[5]][p]);
|
||||
drawPixel(17*s,y3,px,py,3,NUMBERS[newDigits[5]][p]);
|
||||
}
|
||||
}
|
||||
digits = newDigits;
|
||||
|
|
@ -99,5 +108,5 @@ Bangle.on('lcdPower',function(on) {
|
|||
clearTimers();
|
||||
}
|
||||
});
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
||||
// Show launcher when button pressed
|
||||
Bangle.setUI("clock");
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
0.02: Modified for use with new bootloader and firmware
|
||||
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
|
||||
let intervalRef = null;
|
||||
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 }
|
||||
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});
|
||||
tick0.fillRect(0,0,tick0.getWidth()-1, tick0.getHeight()-1);
|
||||
|
|
@ -60,18 +60,15 @@ function hour_angle(date){
|
|||
function draw_clock(){
|
||||
//console.log("draw_clock");
|
||||
let date = new Date();
|
||||
//g.clear();
|
||||
g.setBgColor(0,0,0);
|
||||
g.setColor(0,0,0);
|
||||
g.fillRect(0,24,239,239); // clear app area
|
||||
g.setColor(1,1,1);
|
||||
g.reset();
|
||||
g.clearRect(0,24,239,239); // clear app area
|
||||
|
||||
// draw cross lines for testing
|
||||
// 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, 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];
|
||||
ticks.forEach((item)=>{
|
||||
let agl = item+180;
|
||||
|
|
@ -87,13 +84,13 @@ function draw_clock(){
|
|||
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(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.setColor(0,0,0);
|
||||
g.setColor(g.theme.bg);
|
||||
g.fillCircle(clock_center.x, clock_center.y, 3);
|
||||
|
||||
// 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++){
|
||||
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});
|
||||
|
|
@ -141,5 +138,5 @@ g.clear();
|
|||
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");
|
||||
|
|
|
|||
|
|
@ -25,3 +25,4 @@
|
|||
0.24: Add Bangle.setUI polyfill
|
||||
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
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ recalculates, but this avoids us doing a whole bunch of reconfiguration most
|
|||
of the time. */
|
||||
E.showMessage("Updating boot0...");
|
||||
var s = require('Storage').readJSON('setting.json',1)||{};
|
||||
var isB2 = process.env.HWVERSION; // Is Bangle.js 2
|
||||
var boot = "";
|
||||
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`;
|
||||
|
|
@ -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`;
|
||||
// Pre-2v10 firmwares without a theme/setUI
|
||||
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) {
|
||||
if (Bangle.btnWatches) {
|
||||
Bangle.btnWatches.forEach(clearWatch);
|
||||
|
|
@ -114,6 +115,18 @@ else if (mode=="updown") {
|
|||
Bangle.on("swipe", Bangle.swipeHandler);
|
||||
Bangle.touchHandler = d => {cb();};
|
||||
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
|
||||
throw new Error("Unknown UI mode");
|
||||
};\n`;
|
||||
|
|
|
|||
|
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.02: Make Bangle 2 compatible
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
const maxX = 240;
|
||||
const maxY = 240;
|
||||
const maxX = g.getWidth();
|
||||
const maxY = g.getHeight();
|
||||
const fontSize = g.getWidth()>200?2:1;
|
||||
const rowN = 7;
|
||||
const colN = 7;
|
||||
const headerH = maxY / 7;
|
||||
|
|
@ -50,7 +51,7 @@ function drawCalendar(date) {
|
|||
11: "December"
|
||||
};
|
||||
g.setFontAlign(0, 0);
|
||||
g.setFont("6x8", 2);
|
||||
g.setFont("6x8", fontSize);
|
||||
g.setColor(white);
|
||||
g.drawString(`${monthMap[month]} ${year}`, maxX / 2, headerH / 2);
|
||||
g.drawPoly([10, headerH / 2, 20, 10, 20, headerH - 10], true);
|
||||
|
|
@ -59,7 +60,7 @@ function drawCalendar(date) {
|
|||
true
|
||||
);
|
||||
|
||||
g.setFont("6x8", 2);
|
||||
g.setFont("6x8", fontSize);
|
||||
const dowLbls = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
|
||||
dowLbls.forEach((lbl, i) => {
|
||||
g.drawString(lbl, i * colW + colW / 2, headerH + rowH / 2);
|
||||
|
|
@ -135,26 +136,21 @@ const today = {
|
|||
};
|
||||
drawCalendar(date);
|
||||
clearWatch();
|
||||
setWatch(
|
||||
() => {
|
||||
const month = date.getMonth();
|
||||
const prevMonth = month > 0 ? month - 1 : 11;
|
||||
Bangle.on("touch",area=>{
|
||||
const month = date.getMonth();
|
||||
let prevMonth;
|
||||
if (area==1) {
|
||||
let prevMonth = month > 0 ? month - 1 : 11;
|
||||
if (prevMonth === 11) date.setFullYear(date.getFullYear() - 1);
|
||||
date.setMonth(prevMonth);
|
||||
drawCalendar(date);
|
||||
},
|
||||
BTN4,
|
||||
{ repeat: true }
|
||||
);
|
||||
setWatch(
|
||||
() => {
|
||||
const month = date.getMonth();
|
||||
const prevMonth = month < 11 ? month + 1 : 0;
|
||||
} else {
|
||||
let prevMonth = month < 11 ? month + 1 : 0;
|
||||
if (prevMonth === 0) date.setFullYear(date.getFullYear() + 1);
|
||||
date.setMonth(month + 1);
|
||||
drawCalendar(date);
|
||||
},
|
||||
BTN5,
|
||||
{ repeat: true }
|
||||
);
|
||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
||||
}
|
||||
drawCalendar(date);
|
||||
});
|
||||
|
||||
// Show launcher when button pressed
|
||||
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.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.10: Icon fixed for transparency
|
||||
0.11: added Heart Rate Monitor status and ability to turn on/off
|
||||
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 marginTop = 40;
|
||||
var flag = false;
|
||||
|
|
@ -39,22 +40,23 @@ function updateTime(){
|
|||
updateRest(now);
|
||||
}
|
||||
function writeLineStart(line){
|
||||
g.drawString(">",4,marginTop+line*30);
|
||||
g.drawString(">",4,marginTop+line*fontheight);
|
||||
}
|
||||
function writeLine(str,line){
|
||||
var y = marginTop+line*fontheight;
|
||||
g.setFont("6x8",fontsize);
|
||||
//g.setColor(0,1,0);
|
||||
g.setColor(0,0x07E0,0);
|
||||
g.setColor("#0f0");
|
||||
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);
|
||||
g.drawString(str,25,marginTop+line*30);
|
||||
}
|
||||
g.drawString(str,25,y);
|
||||
}
|
||||
|
||||
function drawInfo(line) {
|
||||
let val;
|
||||
let str = "";
|
||||
let col = 0x07E0; // green
|
||||
let col = "#0f0"; // green
|
||||
|
||||
//console.log("drawInfo(), infoMode=" + infoMode + " funcMode=" + functionMode);
|
||||
|
||||
|
|
@ -62,15 +64,15 @@ function drawInfo(line) {
|
|||
case NONE_FN_MODE:
|
||||
break;
|
||||
case HRT_FN_MODE:
|
||||
col = 0x07FF; // cyan
|
||||
col = "#0ff"; // cyan
|
||||
str = "HRM: " + (hrtOn ? "ON" : "OFF");
|
||||
drawModeLine(line,str,col);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
switch(infoMode) {
|
||||
case NONE_MODE:
|
||||
col = 0x0000;
|
||||
col = "#fff";
|
||||
str = "";
|
||||
break;
|
||||
case HRT_MODE:
|
||||
|
|
@ -100,10 +102,11 @@ function drawInfo(line) {
|
|||
|
||||
function drawModeLine(line, str, col) {
|
||||
g.setColor(col);
|
||||
g.fillRect(0, marginTop-3+line*30, 239, marginTop+25+line*30);
|
||||
g.setColor(0,0,0);
|
||||
var y = marginTop+line*fontheight;
|
||||
g.fillRect(0, y, 239, y+fontheight-1);
|
||||
g.setColor(0);
|
||||
g.setFontAlign(0, -1);
|
||||
g.drawString(str, g.getWidth()/2, marginTop+line*30);
|
||||
g.drawString(str, g.getWidth()/2, y);
|
||||
}
|
||||
|
||||
function changeInfoMode() {
|
||||
|
|
@ -160,7 +163,7 @@ function changeFunctionMode() {
|
|||
functionMode = NONE_FN_MODE;
|
||||
}
|
||||
//console.log(functionMode);
|
||||
|
||||
|
||||
}
|
||||
|
||||
function stepsWidget() {
|
||||
|
|
@ -185,10 +188,12 @@ Bangle.loadWidgets();
|
|||
Bangle.drawWidgets();
|
||||
drawAll();
|
||||
Bangle.on('lcdPower',function(on) {
|
||||
if (on)
|
||||
drawAll();
|
||||
if (on) drawAll();
|
||||
});
|
||||
var click = setInterval(updateTime, 1000);
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
||||
setWatch(() => { changeInfoMode(); drawAll(); }, BTN1, {repeat: true});
|
||||
setWatch(() => { changeFunctionMode(); drawAll(); }, BTN3, {repeat: true});
|
||||
// Show launcher when button pressed
|
||||
Bangle.setUI("clockupdown", btn=>{
|
||||
if (btn==0) changeInfoMode();
|
||||
if (btn==1) changeFunctionMode();
|
||||
drawAll();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
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.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 oy=80;
|
||||
const pw=20; // pixel width
|
||||
const ps=5; // pixel spacing
|
||||
const ds=10; // digit spacing
|
||||
const oy=big ? 80 : 70;
|
||||
const pw=big ? 20 : 14; // pixel width
|
||||
const ps=big ? 5 : 3; // pixel spacing
|
||||
const ds=big ? 10 : 8; // digit spacing
|
||||
const ms=20; // middle space
|
||||
|
||||
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();
|
||||
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.03: Changed setWatch to Bangle.setUI
|
||||
|
|
|
|||
|
|
@ -46,26 +46,25 @@ function drawSegment (align, base, str) {
|
|||
point = base + (maxSegmentWidth / 2) -
|
||||
(g.stringWidth(str) / 2);
|
||||
}
|
||||
g.setColor(1, 1, 1);
|
||||
g.setColor(g.theme.fg);
|
||||
g.drawString(str, point, middleY - 4, false);
|
||||
}
|
||||
|
||||
function drawDots (center) {
|
||||
g.setColor(0xFD20);
|
||||
g.setColor("#FA0");
|
||||
g.fillCircle(center, middleY + 10, 2);
|
||||
g.fillCircle(center, middleY + 40, 2);
|
||||
}
|
||||
|
||||
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, lineY2, middleX + lineLength, lineY2);
|
||||
}
|
||||
|
||||
function drawDate (str) {
|
||||
let maxSegmentWidth = 236;
|
||||
g.setColor(0.5, 0.5, 0.5);
|
||||
g.setColor(0.5, 0.5, 0.5);
|
||||
g.setColor("#777");
|
||||
g.drawString(str, (maxSegmentWidth) - (g.stringWidth(str)), middleY - 22,
|
||||
false);
|
||||
}
|
||||
|
|
@ -149,6 +148,9 @@ function start () {
|
|||
}
|
||||
|
||||
start();
|
||||
// Show launcher when middle button pressed
|
||||
Bangle.setUI("clock");
|
||||
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
Bangle.on('lcdPower', function (on) {
|
||||
|
|
@ -158,6 +160,3 @@ Bangle.on('lcdPower', function (on) {
|
|||
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.08: update icon
|
||||
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");
|
||||
/* jshint esversion: 6 */
|
||||
const timeFontSize = 4;
|
||||
const dateFontSize = 3;
|
||||
const smallFontSize = 2;
|
||||
const big = g.getWidth()>200;
|
||||
const timeFontSize = big?4:3;
|
||||
const dateFontSize = big?3:2;
|
||||
const smallFontSize = big?2:1;
|
||||
const font = "6x8";
|
||||
|
||||
const xyCenter = g.getWidth() / 2;
|
||||
const yposTime = 50;
|
||||
const yposDate = 85;
|
||||
const yposTst = 115;
|
||||
const yposDml = 170;
|
||||
const yposDayMonth = 195;
|
||||
const yposGMT = 220;
|
||||
const yposDate = big?85:75;
|
||||
const yposTst = big?115:95;
|
||||
const yposDml = big?170:130;
|
||||
const yposDayMonth = big?195:140;
|
||||
const yposGMT = big?220:150;
|
||||
|
||||
// Check settings for what type our clock should be
|
||||
var is12Hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"];
|
||||
|
|
@ -99,6 +100,8 @@ Bangle.on('lcdPower', function(on) {
|
|||
|
||||
// clean app screen
|
||||
g.clear();
|
||||
// Show launcher when button pressed
|
||||
Bangle.setUI("clock");
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
|
||||
|
|
@ -107,6 +110,3 @@ setInterval(drawSimpleClock, 100);
|
|||
|
||||
// draw now
|
||||
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 = {
|
||||
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"))
|
||||
};
|
||||
var img = require("heatshrink").decompress(atob("plB4X/ln7A4OGmMs5dVAANa1WlAoQADBI9W1QAByoJNtWv4f61ISEtWrBI2q4EAgeqCQgJHq2sLoU6IYdaBIg5CrWAn2q2EDF4dq4EO1W8gQcCtUD1fP9cA9QSC1cA9f/9XADgWohxBBh2whQvBq2gAwMAh+wlQSB1k7IIXogYvBrXAlYJC9k6DYOw9gIChXA9JBC0AJCncOytWwAtBAAMDF4RBDAAMOgWVrXDwDjD9kKy2gIIcAgXD0taDYgvCRIJBDF4OA0trhwIDJgK2B4BKDAAXptcLA4kC4HrD4IJE8HptE4BAhfBLAJBEgEslISGL4JOBBAoSB1ksBIs6/70DBIgSHh+q+AIFnASIABASU0EgCR0IhWgEp4SBHCBxJLzusXowAIaBISLhYSO8EptcOCR2w9NagXACJkDwGlrXDwASMgXDCQOA2ASMh0C0tW2HgCRkLh2Vq2glASMlEKytV1iFN9k6qtVtEOORcD2EpCQNqOwJwL4GpCQNa4GgCRUKgelCQJyBlgSKnBwBCQWgnZdLOAQAB1BfKLoMqCIVVtYHBXZPA9ISDL4PsCRE7LoZfDnRKJLoYAC1kOTI8CDoIREJgMA1gSGFwJKEJgaGH9hKFTIaGGPQKVEAAeogbTFhXASogADtXAlYSE9cDeYRMG2A5EG4MOJQxMC1g5EG4M6JQ4AB1Q5E9ED1QRIHIatBG5Y5EVoM6G5Y5DnXDCwJvIHIsD32AG5Y5C1aUBgHqG5atDLwI3MHIReCG5hgD4aUKHI2+G5xgC1RcNAAdpBJA"))
|
||||
|
||||
|
||||
function hr(){
|
||||
|
||||
Bangle.buzz(100,0.1).then(()=>{
|
||||
g.clear();
|
||||
return new Promise(resolve=>setTimeout(resolve,250)); // wait 250ms
|
||||
}).then(()=>{
|
||||
return Bangle.buzz(150);
|
||||
}).then(()=>{
|
||||
g.drawImage(img, 25, 40, {scale:2});
|
||||
});
|
||||
|
||||
Bangle.buzz(100,0.1).then(()=>{
|
||||
g.clear();
|
||||
return new Promise(resolve=>setTimeout(resolve,250)); // wait 250ms
|
||||
}).then(()=>{
|
||||
return Bangle.buzz(150);
|
||||
}).then(()=>{
|
||||
g.drawImage(img, g.getWidth()/2 - 76, g.getHeight()/2 - 65, {scale:2});
|
||||
});
|
||||
}
|
||||
setInterval(hr, 2000);
|
||||
|
||||
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.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 MAX_LAPS = 6;
|
||||
const XY_CENTER = g.getWidth() / 2;
|
||||
const big = g.getWidth()>200;
|
||||
const Y_CHRONO = 40;
|
||||
const Y_HEADER = 80;
|
||||
const Y_LAPS = 125;
|
||||
const Y_BTN3 = 225;
|
||||
const Y_HEADER = big?80:60;
|
||||
const Y_LAPS = big?125:90;
|
||||
const H_LAPS = big?15:8;
|
||||
const Y_BTN3 = big?225:165;
|
||||
const FONT = '6x8';
|
||||
const CHRONO = '/* C H R O N O */';
|
||||
|
||||
|
||||
var reset = false;
|
||||
var currentLap = '';
|
||||
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],
|
||||
};
|
||||
|
||||
// Set laps.
|
||||
setWatch(() => {
|
||||
|
||||
// Show launcher when button pressed
|
||||
Bangle.setUI("clockupdown", btn=>{
|
||||
if (btn==0) {
|
||||
reset = false;
|
||||
|
||||
|
||||
if (state.started) {
|
||||
changeLap();
|
||||
} else {
|
||||
|
|
@ -34,13 +37,9 @@ setWatch(() => {
|
|||
chronoInterval = setInterval(chronometer, 10);
|
||||
}
|
||||
}
|
||||
}, BTN1, { repeat: true, edge: 'rising' });
|
||||
|
||||
// Reset chronometre.
|
||||
setWatch(() => { resetChrono(); }, BTN3, { repeat: true, edge: 'rising' });
|
||||
|
||||
// Show launcher when middle button pressed.
|
||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: 'falling' });
|
||||
}
|
||||
if (btn==1) resetChrono();
|
||||
});
|
||||
|
||||
function resetChrono() {
|
||||
state.laps = [EMPTY_H, EMPTY_H, EMPTY_LAP, EMPTY_LAP, EMPTY_LAP, EMPTY_LAP, EMPTY_LAP];
|
||||
|
|
@ -106,33 +105,33 @@ function printChrono() {
|
|||
|
||||
var print = '';
|
||||
|
||||
g.setFont(FONT, 2);
|
||||
g.setFont(FONT, big?2:1);
|
||||
print = CHRONO;
|
||||
g.drawString(print, XY_CENTER, Y_CHRONO, true);
|
||||
|
||||
g.setColor(0, 220, 0);
|
||||
g.setFont(FONT, 3);
|
||||
g.setColor("#0e0");
|
||||
g.setFont(FONT, big?3:2);
|
||||
print = ` T ${state.laps[0]}\n`;
|
||||
print += ` C ${state.laps[1]}\n`;
|
||||
g.drawString(print, XY_CENTER, Y_HEADER, true);
|
||||
|
||||
g.setColor(255, 255, 255);
|
||||
g.setFont(FONT, 2);
|
||||
g.setColor(g.theme.fg);
|
||||
g.setFont(FONT, big?2:1);
|
||||
|
||||
for (var i = 2; i < MAX_LAPS + 1; i++) {
|
||||
|
||||
g.setColor(255, 255, 255);
|
||||
g.setColor(g.theme.fg);
|
||||
let suffix = ' ';
|
||||
if (state.currentLapIndex === i) {
|
||||
let suffix = '*';
|
||||
g.setColor(255, 200, 0);
|
||||
g.setColor("#f70");
|
||||
}
|
||||
|
||||
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);
|
||||
print = 'Press 3 to reset';
|
||||
g.drawString(print, XY_CENTER, Y_BTN3, true);
|
||||
|
|
@ -166,7 +165,7 @@ E.on('kill', function(){
|
|||
});
|
||||
|
||||
if(state.started){
|
||||
chronoInterval = setInterval(chronometer, 10);
|
||||
chronoInterval = setInterval(chronometer, 10);
|
||||
} else {
|
||||
resetChrono();
|
||||
resetChrono();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
0.01: App Made!
|
||||
0.02: Changed setWatch to Bangle.setUI, code tidy
|
||||
|
|
|
|||
|
|
@ -1,141 +1,50 @@
|
|||
//load fonts
|
||||
require("Font7x11Numeric7Seg").add(Graphics);
|
||||
require("FontHaxorNarrow7x17").add(Graphics);
|
||||
require("FontHaxorNarrow7x17").add(Graphics);
|
||||
//screen position
|
||||
const X = 170;
|
||||
const Y = 140;
|
||||
const X = 170;
|
||||
const Y = 140;
|
||||
|
||||
function draw() {
|
||||
// Date Variables
|
||||
var date = new Date();
|
||||
var h = date.getHours();
|
||||
var m = date.getMinutes();
|
||||
var day = date.getDay();
|
||||
var month = date.getMonth();
|
||||
var dateNum = date.getDate();
|
||||
var year = date.getFullYear();
|
||||
var half = "AM";
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
var date = new Date();
|
||||
var h = date.getHours();
|
||||
var m = date.getMinutes();
|
||||
var day = require("locale").dow(date);
|
||||
var month = require("locale").month(date,1);
|
||||
var dateNum = date.getDate();
|
||||
var year = date.getFullYear();
|
||||
var half = "AM";
|
||||
var time = (" " + h).substr(-2) + ":" + ("0" + m).substr(-2);
|
||||
|
||||
if (h > 12) {
|
||||
half = "PM";
|
||||
h = h - 12;
|
||||
half = "PM";
|
||||
h = h - 12;
|
||||
}
|
||||
//reset graphics
|
||||
g.reset();
|
||||
g.reset();
|
||||
//draw the time
|
||||
g.setFont("7x11Numeric7Seg", 5);
|
||||
g.setFontAlign(1,1);
|
||||
g.drawString(time, X, Y, true /*clear background*/);
|
||||
g.setFont("7x11Numeric7Seg", 3);
|
||||
g.drawString(("0"+date.getSeconds()).substr(-2), X+50, Y, true /*clear background*/);
|
||||
g.setFont("7x11Numeric7Seg", 3);
|
||||
g.drawString(("0"+date.getSeconds()).substr(-2), X+50, Y, true /*clear background*/);
|
||||
g.setFontAlign(0,1);
|
||||
g.setFont("HaxorNarrow7x17", 2);
|
||||
g.drawString(half, X+30, Y-35, true);
|
||||
g.setFont("HaxorNarrow7x17", 3);
|
||||
g.drawString(day, X-60, Y+53, true);
|
||||
g.drawString(month, X-100, Y+95, true);
|
||||
g.drawString(dateNum, X-40, Y+95, true);
|
||||
g.drawString(year, X-90, Y-55, true);
|
||||
|
||||
|
||||
g.drawString(month, X-100, Y+95, true);
|
||||
g.drawString(dateNum, X-40, Y+95, true);
|
||||
g.drawString(year, X-90, Y-55, true);
|
||||
|
||||
|
||||
}
|
||||
|
||||
//clear screen at startup
|
||||
g.clear();
|
||||
g.clear();
|
||||
//draw immediatly
|
||||
draw();
|
||||
draw();
|
||||
|
||||
var secondInterval = setInterval(draw, 1000);
|
||||
// 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.drawWidgets();
|
||||
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat : false, edge: "falling"});
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
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.03: Use setUI, adjust for themes and different size screens
|
||||
|
|
|
|||
|
|
@ -1,20 +1,22 @@
|
|||
let g;
|
||||
let Bangle;
|
||||
|
||||
const big = g.getWidth()>200;
|
||||
const locale = require('locale');
|
||||
const p = Math.PI / 2;
|
||||
const pRad = Math.PI / 180;
|
||||
const faceWidth = 100; // watch face radius
|
||||
let timer = null;
|
||||
let currentDate = new Date();
|
||||
let hourRadius = 60;
|
||||
let minRadius = 80;
|
||||
const centerPx = g.getWidth() / 2;
|
||||
const faceWidth = big?100:65; // watch face radius
|
||||
let hourRadius = big?60:40;
|
||||
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 a = angle * pRad;
|
||||
const x = centerPx + Math.sin(a) * faceWidth;
|
||||
const y = centerPx - Math.cos(a) * faceWidth;
|
||||
const x = centerX + Math.sin(a) * faceWidth;
|
||||
const y = centerY - Math.cos(a) * faceWidth;
|
||||
|
||||
// if 15 degrees, make hour marker larger
|
||||
const radius = (angle % 15) ? 2 : 4;
|
||||
|
|
@ -23,15 +25,15 @@ const seconds = (angle) => {
|
|||
|
||||
const hourDot = (angle,radius) => {
|
||||
const a = angle * pRad;
|
||||
const x = centerPx + Math.sin(a) * hourRadius;
|
||||
const y = centerPx - Math.cos(a) * hourRadius;
|
||||
const x = centerX + Math.sin(a) * hourRadius;
|
||||
const y = centerY - Math.cos(a) * hourRadius;
|
||||
g.fillCircle(x, y, radius);
|
||||
};
|
||||
|
||||
const minDot = (angle,radius) => {
|
||||
const a = angle * pRad;
|
||||
const x = centerPx + Math.sin(a) * minRadius;
|
||||
const y = centerPx - Math.cos(a) * minRadius;
|
||||
const x = centerX + Math.sin(a) * minRadius;
|
||||
const y = centerY - Math.cos(a) * minRadius;
|
||||
g.fillCircle(x, y, radius);
|
||||
};
|
||||
|
||||
|
|
@ -45,54 +47,49 @@ const drawAll = () => {
|
|||
// draw all secs
|
||||
|
||||
for (let i = 0; i < 60; i++) {
|
||||
if (i > currentSec) {
|
||||
g.setColor(0, 0, 0.6);
|
||||
} else {
|
||||
g.setColor(0.3, 0.3, 1);
|
||||
}
|
||||
g.setColor((i > currentSec) ? colSecA : colSecB);
|
||||
seconds((360 * i) / 60);
|
||||
}
|
||||
onSecond();
|
||||
};
|
||||
|
||||
const resetSeconds = () => {
|
||||
g.setColor(0, 0, 0.6);
|
||||
g.setColor(colSecA);
|
||||
for (let i = 0; i < 60; i++) {
|
||||
seconds((360 * i) / 60);
|
||||
}
|
||||
};
|
||||
|
||||
const drawMin = () => {
|
||||
g.setColor(0.5, 0.5, 0.5);
|
||||
g.setColor("#777");
|
||||
for (let i = 0; i < 60; i++) {
|
||||
minDot((360 * i) / 60,1);
|
||||
}
|
||||
};
|
||||
|
||||
const drawHour = () => {
|
||||
g.setColor(0.5, 0.5, 0.5);
|
||||
g.setColor("#777");
|
||||
for (let i = 0; i < 12; i++) {
|
||||
hourDot((360 * 5 * i) / 60,1);
|
||||
}
|
||||
};
|
||||
|
||||
const onSecond = () => {
|
||||
g.setColor(0.3, 0.3, 1);
|
||||
g.setColor(colSecB);
|
||||
seconds((360 * currentDate.getSeconds()) / 60);
|
||||
if (currentDate.getSeconds() === 59) {
|
||||
resetSeconds();
|
||||
onMinute();
|
||||
}
|
||||
g.setColor(1, 0.7, 0.2);
|
||||
g.setColor(colSec1);
|
||||
currentDate = new Date();
|
||||
seconds((360 * currentDate.getSeconds()) / 60);
|
||||
g.setColor(1, 1, 1);
|
||||
g.setColor(g.theme.fg);
|
||||
};
|
||||
|
||||
const drawDate = () => {
|
||||
g.reset();
|
||||
g.setColor(1, 1, 1);
|
||||
g.setFont('6x8', 2);
|
||||
g.setFont('6x8', big?2:1);
|
||||
|
||||
const dayString = locale.dow(currentDate, true);
|
||||
// pad left date
|
||||
|
|
@ -101,7 +98,7 @@ const drawDate = () => {
|
|||
// console.log(`${dayString}|${dateString}`);
|
||||
// center date
|
||||
const l = (g.getWidth() - g.stringWidth(dateDisplay)) / 2;
|
||||
const t = centerPx - 6 ;
|
||||
const t = centerY - 6 ;
|
||||
g.drawString(dateDisplay, l, t);
|
||||
// console.log(l, t);
|
||||
};
|
||||
|
|
@ -111,7 +108,7 @@ const onMinute = () => {
|
|||
resetSeconds();
|
||||
}
|
||||
// clear existing hands
|
||||
g.setColor(0, 0, 0);
|
||||
g.setColor(g.theme.bg);
|
||||
hourDot((360 * currentDate.getHours()) / 12,4);
|
||||
minDot((360 * currentDate.getMinutes()) / 60,3);
|
||||
|
||||
|
|
@ -125,7 +122,7 @@ const onMinute = () => {
|
|||
g.setColor(1, 0, 0);
|
||||
// Hour
|
||||
hourDot((360 * currentDate.getHours()) / 12,4);
|
||||
g.setColor(1, 0.9, 0.9);
|
||||
g.setColor(g.theme.fg2);
|
||||
// Minute
|
||||
minDot((360 * currentDate.getMinutes()) / 60,3);
|
||||
drawDate();
|
||||
|
|
@ -152,8 +149,8 @@ g.clear();
|
|||
resetSeconds();
|
||||
startTimers();
|
||||
drawAll();
|
||||
// Show launcher when button pressed
|
||||
Bangle.setUI("clock");
|
||||
|
||||
Bangle.loadWidgets();
|
||||
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,2 @@
|
|||
0.01: First released version
|
||||
0.02: Changed setWatch to Bangle.setUI
|
||||
|
|
|
|||
|
|
@ -243,5 +243,5 @@ startTimers();
|
|||
Bangle.loadWidgets();
|
||||
drawAll();
|
||||
|
||||
// Show launcher when middle button pressed
|
||||
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.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();
|
||||
animInterval = setInterval(iterate, 50);
|
||||
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
||||
// Show launcher when button pressed
|
||||
Bangle.setUI("clock");
|
||||
|
|
|
|||
|
|
@ -21,3 +21,5 @@
|
|||
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.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,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.
|
||||
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
var period = 1000000;
|
||||
if (lastFixTime!==undefined)
|
||||
period = fix.time.getTime() - lastFixTime;
|
||||
if (period > settings.period*1000) {
|
||||
if (period+500 > settings.period*1000) { // round up
|
||||
lastFixTime = fix.time.getTime();
|
||||
try {
|
||||
if (gpsTrack) gpsTrack.write([
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 707 B After Width: | Height: | Size: 707 B |
|
Before Width: | Height: | Size: 707 B After Width: | Height: | Size: 707 B |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
|
|
@ -11,11 +11,9 @@ function animate(seq,period) {
|
|||
// Fade in to FG color with angled lines
|
||||
function fade(col, callback) {
|
||||
var n = 0;
|
||||
function f() {
|
||||
function f() {"ram"
|
||||
g.setColor(col);
|
||||
for (var i=n;i<240;i+=10) {
|
||||
g.drawLine(i,0,0,i).drawLine(i,240,240,i);
|
||||
}
|
||||
for (var i=n;i<240;i+=10) g.drawLine(i,0,0,i).drawLine(i,240,240,i);
|
||||
g.flip();
|
||||
n++;
|
||||
if (n<10) setTimeout(f,0);
|
||||
|
|
@ -25,19 +23,22 @@ function fade(col, callback) {
|
|||
}
|
||||
|
||||
|
||||
var scenes = [
|
||||
function() {
|
||||
var SCENE_COUNT=11;
|
||||
function getScene(n) {
|
||||
if (n==0) return function() {
|
||||
console.log("Start app");
|
||||
g.clear(1);
|
||||
eval(require("Storage").read("mywelcome.custom.js"));
|
||||
},function() {
|
||||
}
|
||||
if (n==1) return function() {
|
||||
g.clear(1);
|
||||
g.setFont("4x6",2);
|
||||
var n=0;
|
||||
var l = Bangle.getLogo();
|
||||
var i = setInterval(function() {
|
||||
n+=0.04;
|
||||
g.setColor(n,n,n);
|
||||
g.drawImage(Bangle.getLogo(),(240-222)/2,(240-100)/2);
|
||||
g.drawImage(l,(240-222)/2,(240-100)/2);
|
||||
if (n>=1) {
|
||||
clearInterval(i);
|
||||
setTimeout(()=>g.drawString("Open",34,144), 500);
|
||||
|
|
@ -45,7 +46,8 @@ var scenes = [
|
|||
setTimeout(()=>g.drawString("Smart Watch",34,168), 1500);
|
||||
}
|
||||
},50);
|
||||
},function() {
|
||||
};
|
||||
if (n==2) return function() {
|
||||
var img = require("heatshrink").decompress(atob("ptRxH+qYAfvl70mj5gAC0ekvd8FkAAdz3HJAYAH4+eJXWkJJYAF0hK2vfNJaIAB5t7S3fN5/V6wAD6vOTg9SumXy2W3QAB3eXul2JdnO63XAApPEVYvAJQIACJoRQDzBLoJQ3W5/NIwr4GJohMFAAROgJYvVJQiPGABZNN3bsdvYyESwnWJSIAC3RNM3V1JjZAES4nVJSYAB4xMNJrbkE56WD5xLVdB5NbFofNJbgABJh26qREPrFXrlbAAWjFgfWJgRLaTQhMLy5KNJINhsJLDrYrD5xLC6pLa5nGTR7oLq9bJQJMKTAXWJbbnR3RLJSoRMHv4pC5rkec6SaIrBLGw2r2XW1epcoqYeJiOXJYziEsOH2RBBw7lF56Yg5nGc6FScZOGJQPX2TmDFIfVTEBMSc4hLEw5KB6+rsJMH63X6pMf5hMQzBLCq5LD1ZLEJhTlfJiWXTA2GJYpMIcwPNc2O6TAuGRIPX1igDJg/PJmyYDcgXWwxMH1ApC53XcsHAJiVYcg2HJYZME0YpC5vWJkhLNJgLlDTAeFJhF/FQfVJkG6JiGXcomyJgOrJYhMErYqD53NJj7lRzBMDcoeGJhzoBJb3GJiN1qZBCJgWyJYpNF1LigAAXAJiNSJgzlGJgt/JkZLRy9TJgeHJhznFcuSZGw5MHJomjcuhLBqdcJiSaiTChMV1CYxy5LCqdXIAWy6+rJhCalTCN2JgdYH4WHJiGpTF7kDc43W2RMJTUZLQzBLFc4mr6+GJh2jTFmXJYyaEwuyc5Sag4xLZTQmG2WFJhxNaJYZMLJZSaEJoOHTR9/Ja+6JbdTqRNETRRNF1JLV4BLcAANYI5ToK1BLYJhWYJZwABq5NoJZ91JaAABdAZNS0ZLey9SJaRNYv5KM426JZmXuxKUJrKcL0lTzBLKzBKYJrVXvfGSol7EYWXJI27zF1JLQADq5NUrgYB4wAEEIV0comXI7wAFrCcPJgYWBTIIAETIN2JYmWuhMkdSdYCgOeJgueqRLFyzhfTi9bq4TC45MF49TuuXJlpONcogAC0hKB0gHDvZMEqRMpAANSq9crlbJAYADqwRDxGk0mIA4eCTQOeveXJdYAHqxNFdAeIAAQGCrOI0oHEAGVXTRJMGvgGCwRM7TAZMHwQGCvhM1rBMERIhMGAwdZJmtSqVTwNcwJEDJg19cvIADa4d9JhANDJnSLHJgrl6AAhFFAwpZDegjn7vhMGcvwABrJAFJgjl/TQpBBI4jl/AAN8TQhHDcv4ADcJBMDvpM+IYaeDAAhL+qd9SgycEJn7iEAA18Jf7nEcv4AIrJLIcv6aMcv4ADvhMHrJJ/AAbl/c6ZM/AAt9cv7nSIv7nLcv4AHrLl/TRpJBvgnjA=="));
|
||||
g.reset();
|
||||
g.setBgColor("#6633ff");
|
||||
|
|
@ -76,7 +78,8 @@ var scenes = [
|
|||
},20);
|
||||
},3500);
|
||||
|
||||
},function() {
|
||||
};
|
||||
if (n==3) return function() {
|
||||
g.reset();
|
||||
g.setBgColor("#ffa800");g.clear();
|
||||
g.setFont("6x8",2);
|
||||
|
|
@ -91,8 +94,8 @@ var scenes = [
|
|||
()=>g.drawString("2",200,120),
|
||||
()=>g.drawString("3",200,200)
|
||||
],200);
|
||||
},
|
||||
function() {
|
||||
};
|
||||
if (n==4) return function() {
|
||||
g.reset();
|
||||
g.setBgColor("#00a8ff");g.clear();
|
||||
g.setFontAlign(0,0);
|
||||
|
|
@ -101,8 +104,8 @@ var scenes = [
|
|||
g.setFontAlign(-1,-1);
|
||||
g.setFont("6x8",2);
|
||||
g.drawString("Move up\nin menus\n\nTurn Bangle.js on\nif it was off", 20,40);
|
||||
},
|
||||
function() {
|
||||
};
|
||||
if (n==5) return function() {
|
||||
g.reset();
|
||||
g.setBgColor("#00a8ff");g.clear();
|
||||
g.setFontAlign(0,0);
|
||||
|
|
@ -111,8 +114,8 @@ var scenes = [
|
|||
g.setFontAlign(-1,-1);
|
||||
g.setFont("6x8",2);
|
||||
g.drawString("Select menu\nitem\n\nLaunch app\nwhen watch\nis showing", 20,70);
|
||||
},
|
||||
function() {
|
||||
};
|
||||
if (n==6) return function() {
|
||||
g.reset();
|
||||
g.setBgColor("#00a8ff");g.clear();
|
||||
g.setFontAlign(0,0);
|
||||
|
|
@ -121,8 +124,8 @@ var scenes = [
|
|||
g.setFontAlign(-1,-1);
|
||||
g.setFont("6x8",2);
|
||||
g.drawString("Move down\nin menus\n\nLong press\nto exit app\nand go back\nto clock", 20,100);
|
||||
},
|
||||
function() {
|
||||
};
|
||||
if (n==7) return function() {
|
||||
g.reset();
|
||||
g.setBgColor("#ff3300");g.clear();
|
||||
g.setFontAlign(0,0);
|
||||
|
|
@ -132,8 +135,8 @@ var scenes = [
|
|||
g.setFontAlign(-1,-1);
|
||||
g.setFont("6x8",2);
|
||||
g.drawString("If Bangle.js\never stops,\nhold buttons\n1 and 2 for\naround six\nseconds.\n\n\n\nBangle.js will\nthen reboot.", 20,20);
|
||||
},
|
||||
function() {
|
||||
};
|
||||
if (n==8) return function() {
|
||||
g.reset();
|
||||
g.setBgColor("#00a8ff");g.clear();
|
||||
g.setFont("6x8",2);
|
||||
|
|
@ -150,8 +153,8 @@ var scenes = [
|
|||
g.drawString("work too. Try now",x,y+=h);
|
||||
g.drawString("to change page.",x,y+=h);}
|
||||
],300);
|
||||
},
|
||||
function() {
|
||||
};
|
||||
if (n==9) return function() {
|
||||
g.reset();
|
||||
g.setBgColor("#339900");g.clear();
|
||||
g.setFont("6x8",2);
|
||||
|
|
@ -168,8 +171,8 @@ var scenes = [
|
|||
g.drawString("with a Bluetooth",x,y+=h);
|
||||
g.drawString("capable device",x,y+=h);},
|
||||
],400);
|
||||
},
|
||||
function() {
|
||||
};
|
||||
if (n==10) return function() {
|
||||
g.reset();
|
||||
g.setBgColor("#990066");g.clear();
|
||||
g.setFont("6x8",2);
|
||||
|
|
@ -182,6 +185,7 @@ var scenes = [
|
|||
g.drawString("banglejs.com",x,y+=h);
|
||||
|
||||
var rx = 0, ry = 0;
|
||||
E.defrag(); // rearrange memory to ensure we have space
|
||||
var h = Graphics.createArrayBuffer(96,96,1,{msb:true});
|
||||
// draw a cube
|
||||
function draw() {
|
||||
|
|
@ -230,8 +234,8 @@ var scenes = [
|
|||
}
|
||||
|
||||
setInterval(draw,50);
|
||||
},
|
||||
function() {
|
||||
};
|
||||
if (n==11) return function() {
|
||||
g.reset();
|
||||
g.setBgColor("#660099");g.clear();
|
||||
g.setFontAlign(0,0);
|
||||
|
|
@ -248,20 +252,18 @@ var scenes = [
|
|||
g.drawString("Bangle.js",x,y+=h);}
|
||||
],400);
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
var sceneNumber = 0;
|
||||
|
||||
function move(dir) {
|
||||
if (dir>0 && sceneNumber+1 == scenes.length) return; // at the end
|
||||
sceneNumber = (sceneNumber+dir)%scenes.length;
|
||||
if (dir>0 && sceneNumber+1 == SCENE_COUNT) return; // at the end
|
||||
sceneNumber = (sceneNumber+dir)%SCENE_COUNT;
|
||||
if (sceneNumber<0) sceneNumber=0;
|
||||
clearInterval();
|
||||
Bangle.setLCDMode();
|
||||
g.clear();
|
||||
scenes[sceneNumber]();
|
||||
getScene(sceneNumber)();
|
||||
if (sceneNumber>2) {
|
||||
var l = scenes.length;
|
||||
var l = SCENE_COUNT;
|
||||
for (var i=0;i<l-2;i++) {
|
||||
var x = 120+(i-(l-2)/2)*12;
|
||||
if (i<sceneNumber-1) {
|
||||
|
|
@ -275,7 +277,7 @@ function move(dir) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (sceneNumber < scenes.length-1)
|
||||
if (sceneNumber < SCENE_COUNT-1)
|
||||
setTimeout(function() {
|
||||
move(1);
|
||||
}, (sceneNumber==0) ? 20000 : 5000);
|
||||
|
|
|
|||
|
|
@ -6,3 +6,4 @@
|
|||
0.06: Improve rendering of Numeral 1, fix issue with alarms not showing up
|
||||
0.07: Add date on touch and some improvements (see settings and readme)
|
||||
0.08: Add new draw styles, tidy up draw functionality
|
||||
0.09: Tweak for faster rendering
|
||||
|
|
|
|||
|
|
@ -22,16 +22,17 @@ var _12hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"]||fal
|
|||
var _hCol = ["#ff5555","#ffff00","#FF9901","#2F00FF"];
|
||||
var _mCol = ["#55ff55","#ffffff","#00EFEF","#FFBF00"];
|
||||
var _rCol = 0;
|
||||
var scale = g.getWidth()/240;
|
||||
var interval = 0;
|
||||
const REFRESH_RATE = 10E3;
|
||||
var drawFuncs = {
|
||||
fill : function(poly,isHole){
|
||||
if (isHole) g.setColor(0);
|
||||
if (isHole) g.setColor(g.theme.bg);
|
||||
g.fillPoly(poly,true);
|
||||
},
|
||||
framefill : function(poly,isHole){
|
||||
var c = g.getColor();
|
||||
g.setColor(isHole ? 0 : ((c&0b1111011111011110)>>1)); // 16 bit half bright
|
||||
g.setColor(isHole ? g.theme.bg : ((c&0b1111011111011110)>>1)); // 16 bit half bright
|
||||
g.fillPoly(poly,true);
|
||||
g.setColor(c);
|
||||
g.drawPoly(poly,true);
|
||||
|
|
@ -48,7 +49,8 @@ var drawFuncs = {
|
|||
};
|
||||
|
||||
function translate(tx, ty, p){
|
||||
return p.map((x, i)=> x+((i&1)?ty:tx));
|
||||
//return p.map((x, i)=> x+((i&1)?ty:tx));
|
||||
return g.transformVertices(p, {x:tx,y:ty,scale:scale});
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -57,15 +59,14 @@ if (!settings) {
|
|||
settings = {
|
||||
color:0,
|
||||
drawMode:"fill",
|
||||
menuButton:24,
|
||||
showDate:0
|
||||
};
|
||||
}
|
||||
|
||||
function drawNum(num,col,x,y,func,funcName){
|
||||
g.setColor(col);
|
||||
let tx = x*100+25;
|
||||
let ty = y*104+32;
|
||||
let tx = (x*100+25) * scale;
|
||||
let ty = (y*104+32) * scale;
|
||||
for (let i=0;i<numerals[num].length;i++){
|
||||
g.setColor(col);
|
||||
func(translate(tx,ty,numerals[num][i]), i>0);
|
||||
|
|
@ -98,9 +99,9 @@ function setUpdateInt(set){
|
|||
if (set) interval=setInterval(draw, REFRESH_RATE);
|
||||
}
|
||||
|
||||
Bangle.setLCDMode();
|
||||
g.reset().clear();
|
||||
setWatch(Bangle.showLauncher, settings.menuButton, {repeat:false,edge:"falling"});
|
||||
g.clear(1);
|
||||
// Show launcher when button pressed
|
||||
Bangle.setUI("clock");
|
||||
if (settings.color>0) _rCol=settings.color-1;
|
||||
setUpdateInt(1);
|
||||
draw();
|
||||
|
|
|
|||
|
|
@ -6,14 +6,12 @@
|
|||
numeralsSettings = {
|
||||
color:0,
|
||||
drawMode:"fill",
|
||||
menuButton:22,
|
||||
showDate:0
|
||||
};
|
||||
updateSettings();
|
||||
}
|
||||
let numeralsSettings = storage.readJSON('numerals.json',1);
|
||||
if (!numeralsSettings) resetSettings();
|
||||
if (numeralsSettings.menuButton===undefined) numeralsSettings.menuButton=22;
|
||||
let dm = ["fill","frame","framefill","thickframe"];
|
||||
let col = ["rnd","r/g","y/w","o/c","b/y"];
|
||||
let btn = [[24,"BTN1"],[22,"BTN2"],[23,"BTN3"],[11,"BTN4"],[16,"BTN5"]];
|
||||
|
|
@ -31,12 +29,6 @@
|
|||
format: v=>dm[v],
|
||||
onchange: v=> { numeralsSettings.drawMode=dm[v]; updateSettings();}
|
||||
},
|
||||
"Menu button": {
|
||||
value: btn.findIndex(e=>e[0]==numeralsSettings.menuButton),
|
||||
min:0,max:btn.length-1,
|
||||
format: v=>btn[v][1],
|
||||
onchange: v=> { numeralsSettings.menuButton=btn[v][0]; updateSettings();}
|
||||
},
|
||||
"Date on touch": {
|
||||
value: 0|numeralsSettings.showDate,
|
||||
min:0,max:1,
|
||||
|
|
|
|||
|
|
@ -3,3 +3,6 @@
|
|||
0.03: Show widgets (mainly so we can use the GPS recorder widget)
|
||||
0.04: Move map rendering to a module (fix #396)
|
||||
0.05: Show currently active gpsrec GPS trace (fix #395)
|
||||
0.06: Add support for scrolling, option for 3 bit maps
|
||||
0.07: Move to 96px tiles - less files (64 -> 25) and speed up rendering
|
||||
0.08: Update for drag event refactor
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ Bangle.on('GPS',function(f) {
|
|||
g.drawString(txt,120,y1 + 4);
|
||||
drawMarker();
|
||||
});
|
||||
Bangle.setGPSPower(1);
|
||||
Bangle.setGPSPower(1, "app");
|
||||
|
||||
if (HASWIDGETS) {
|
||||
Bangle.loadWidgets();
|
||||
|
|
@ -49,9 +49,25 @@ if (HASWIDGETS) {
|
|||
|
||||
redraw();
|
||||
|
||||
setWatch(function() {
|
||||
function recenter() {
|
||||
if (!fix.fix) return;
|
||||
m.lat = fix.lat;
|
||||
m.lon = fix.lon;
|
||||
redraw();
|
||||
}, BTN2, {repeat:true});
|
||||
}
|
||||
|
||||
setWatch(recenter, global.BTN2?BTN2:BTN1, {repeat:true});
|
||||
|
||||
var hasScrolled = false;
|
||||
Bangle.on('drag',e=>{
|
||||
if (e.b) {
|
||||
g.setClipRect(0,y1,g.getWidth()-1,y2);
|
||||
g.scroll(e.dx,e.dy);
|
||||
m.scroll(e.dx,e.dy);
|
||||
g.setClipRect(0,0,g.getWidth()-1,g.getHeight()-1);
|
||||
hasScrolled = true;
|
||||
} else if (hasScrolled) {
|
||||
hasScrolled = false;
|
||||
redraw();
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
<div id="map">
|
||||
</div>
|
||||
<div id="controls">
|
||||
<div style="display:inline-block;text-align:center;vertical-align: top;"> <input type="checkbox" id="3bit"></input><br/><span>3 bit</span></div>
|
||||
<button id="getmap" class="btn btn-primary">Get Map</button><br/>
|
||||
<canvas id="maptiles" style="display:none"></canvas>
|
||||
<div id="uploadbuttons" style="display:none"><button id="upload" class="btn btn-primary">Upload</button>
|
||||
|
|
@ -55,9 +56,10 @@ TODO:
|
|||
* What is faster? Storing as a compressed image and decompressing, or storing decompressed?
|
||||
|
||||
*/
|
||||
var TILESIZE = 64;
|
||||
var OSMTILESIZE = 256;
|
||||
var OSMSUBTILES = OSMTILESIZE / TILESIZE;
|
||||
var TILESIZE = 96; // Size of our tiles
|
||||
var OSMTILESIZE = 256; // Size of openstreetmap tiles
|
||||
var MAPSIZE = TILESIZE*5; ///< 480 - Size of map we download
|
||||
var OSMTILECOUNT = 3; // how many tiles do we download in each direction (Math.floor(MAPSIZE / OSMTILESIZE)+1)
|
||||
/* Can see possible tiles on http://leaflet-extras.github.io/leaflet-providers/preview/
|
||||
However some don't allow cross-origin use */
|
||||
var TILELAYER = 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png'; // simple, high contrast
|
||||
|
|
@ -74,7 +76,17 @@ TODO:
|
|||
tileLayer.addTo(map);
|
||||
|
||||
function tilesLoaded(ctx, width, height) {
|
||||
var options = { compression:true, mode:"web", output:"string"};
|
||||
var options = {
|
||||
compression:false, output:"raw",
|
||||
mode:"web"
|
||||
};
|
||||
if (document.getElementById("3bit").checked) {
|
||||
options = {
|
||||
compression:false, output:"raw",
|
||||
mode:"3bit", brightness:-64,
|
||||
};
|
||||
}
|
||||
console.log("Compression options", options);
|
||||
var w = Math.round(width / TILESIZE);
|
||||
var h = Math.round(height / TILESIZE);
|
||||
var tiles = [];
|
||||
|
|
@ -92,8 +104,7 @@ TODO:
|
|||
imgstr = imgstr.slice(compress.length,-1);*/
|
||||
tiles.push({
|
||||
name:"openstmap-"+x+"-"+y+".img",
|
||||
content:imgstr,
|
||||
evaluate:true
|
||||
content:imgstr
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -114,10 +125,10 @@ TODO:
|
|||
var canvas = document.getElementById("maptiles");
|
||||
canvas.style.display="";
|
||||
var ctx = canvas.getContext('2d');
|
||||
canvas.width = OSMTILESIZE*2;
|
||||
canvas.height = OSMTILESIZE*2;
|
||||
for (var i = 0; i < 3; i++) {
|
||||
for (var j = 0; j < 3; j++) {
|
||||
canvas.width = MAPSIZE;
|
||||
canvas.height = MAPSIZE;
|
||||
for (var i = 0; i < OSMTILECOUNT; i++) {
|
||||
for (var j = 0; j < OSMTILECOUNT; j++) {
|
||||
(function(i,j){
|
||||
var coords = new L.Point(center.x+i-1, center.y+j-1);
|
||||
coords.z = zoom;
|
||||
|
|
|
|||
|
|
@ -45,15 +45,12 @@ exports.draw = function() {
|
|||
for (var y=oy,tty=ty;y<g.getHeight();y+=map.tilesize,tty++) {
|
||||
var img = s.read("openstmap-"+ttx+"-"+tty+".img");
|
||||
if (img) g.drawImage(img,x,y);
|
||||
else {
|
||||
g.clearRect(x,y,x+map.tilesize-1,y+map.tilesize-1);
|
||||
g.drawLine(x,y,x+map.tilesize-1,y+map.tilesize-1);
|
||||
g.drawLine(x,y+map.tilesize-1,x+map.tilesize-1,y);
|
||||
}
|
||||
else g.clearRect(x,y,x+map.tilesize-1,y+map.tilesize-1).drawLine(x,y,x+map.tilesize-1,y+map.tilesize-1).drawLine(x,y+map.tilesize-1,x+map.tilesize-1,y);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/// Convert lat/lon to pixels on the screen
|
||||
exports.latLonToXY = function(lat, lon) {
|
||||
var p = Bangle.project({lat:m.lat,lon:m.lon});
|
||||
var q = Bangle.project({lat:lat, lon:lon});
|
||||
|
|
@ -64,3 +61,11 @@ exports.latLonToXY = function(lat, lon) {
|
|||
y : cy - (q.y-p.y)*4096/map.scale
|
||||
};
|
||||
};
|
||||
|
||||
/// Given an amount to scroll in pixels on the screen, adjust the lat/lon of the map to match
|
||||
exports.scroll = function(x,y) {
|
||||
var a = Bangle.project({lat:this.lat,lon:this.lon});
|
||||
var b = Bangle.project({lat:this.lat+1,lon:this.lon+1});
|
||||
this.lon += x * this.map.scale / ((a.x-b.x) * 4096);
|
||||
this.lat -= y * this.map.scale / ((a.y-b.y) * 4096);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
0.01: New Watch!
|
||||
0.02: Changed colors for better readability and added current date
|
||||
0.03: Added Info to HP (day in year) and LEVEL (day of week / progress bar show day progress)
|
||||
0.04: Using setUI, portable colors
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
const bigFont = 4;
|
||||
const smallFont = 2;
|
||||
const tinyFont = 1;
|
||||
const green = 0x0661;
|
||||
const darkGreen = 0x0461;
|
||||
const darkerGreen = 0x0261;
|
||||
const green = "#0d1";
|
||||
const darkGreen = "#091";
|
||||
const darkerGreen = "#051";
|
||||
const pip = require("heatshrink").decompress(atob("klQyAlihNhgNhNP5FC0MjokboUJ8JC64ABBgNAjdDifiikhjfjjekjcDgOhImMKoUbscTsUbwUT4QBC8UMkMMgUT8MLwcBS8/hiNiIo2DhkBgkhhfhHoMT0MT0RLBjYJCCIMTocBUoIAiiIvBgcKsMSG4KLChY1CjckgUhgOAhJDBocL4RTBAYMT0ZJliS9BwUDQIchgWAhXCgVAgUghWhiXihWBgUAhdjhYTBkEB8ELkUTgcA8BHfgNAZ4MT8UTwcCJIOjikjihVB8QDBAIcToUSRYNDkdjjWDgOhjdjhVBI8EAgVBiXhQ4MTkcb4ZPCTILLBAYPBjZDBAIUL8QBBd4KRBWIMboZHfiPCOIMKsK5BR4XChkBAIUChkiheibYMT0RPBBoJZBgWgiRfD0RHfhMhhPhjcjhcBiQrBwSHBRocLRINCgUAhWBR4SZBsatCI4IRBsRHfAAMKkJBBhYBCgfBgZDBAYQFC0Q3BicCgehgbRBscKoMCkBlBjXiI8IxBifDgVAidDhfiIoMLkMUgUb4USQ4MiAoLlDiejgVhI4L3BjUjIr8BIILPBwUBwEa8YzBhQ/BoTLBjejgOgiTVEhkChdhiXCI4MB4MA8BHgsAxBjkDP4MjskTgZ3BTIMMkMb8cKLINCS4KPEcIMChWiK4LVhgJ5EAIJJBOoKTBbIQLB4I9BA4QJDCoOigZLBocJ8JHiwELGoPAgfghdCBIJ7BH4mhAYXAAYMDAIQNE0UKwJHioETwZ/C8cT0cS4UDgCBC4UTHIKjCiaNChfiB4SVDoUA4BJhicjhVgjeEjfDifiikCiZPBwUS4MB4ES0Ub4UUgMMgJDBAYJTBiXjIsIABiPiaIK5BgWggXhhXhgQJB4Mi8kakRJBHoJHDLIViiWCWYJHjhNBhWCHoMK0MbgkbkkTgYHBKYMTgUC4DVCcYUbscB8BDjAArFBOoKLCoECgADBaoMToUTsMLwML0MLBIUJ4JFpAAK3BidDhfiQIXCQIIBBRIcEgJFC0UKoJFrbYnBjeDibHBAIUMgIFC8QBC4UKsEA8EZ4cRJd0BwDPC8Y/BI4IBBR4IHBheijXkgOBjcCjcDVoJHriUiiWigVhiY3BS4PBI4JLCwcKkUK0UMgULwSrBiPBRtEhidDQII3BgMgPoMKgRRBhVhgPAiWBieCiehhQBBoKpBJYJFjiPihPhhdChfBieiGIMKwEKkI5BJIMTsUL4UL4afBgUgidjBIMbscJsBFfhOhjdDicigUAhWBYYMT8MT4QBHcIMCwIVBU4TnCMIMbgarBaLkgIoML8UT8Q1BiViYYI/DikCAoRXCgOAiWCCoIbBAIRHBEIPjBoJHbiR7D8UMgQ9BIoMKbIIJCAIMLkMSoSjCIYUMgIBECYIFCKYL/BIq8KgMTwRtBXIcL0UKsELRIIJBBYUCwEK4UL4UD4MDCoPgCIITEEIYJBgUBsLTUsMTka1DAIS3B0UCoETQYIvCT4MKoLXBH4QXCAYIBDEInhSIIZCsTTUsQZBNIXigkBGIVjgUhZIQ7DTIIPBoSHESoRDFAIYlBT4MToUBkCNQsETsRFBgaFBAoPhEIUiR4WiB4QxBwK+BhYTCZojPDAIYJCgfgAoRjBkKNQ0UTZoLVBgMKOYPihiLBoYhBToQJBXocALYbTEEIJHFE4IJCUYQFBkUA8CNMPoOCGIIBCoLPC4aPCsTNCBoIvD4MCkC/BHYrZEAoKTGdIQDB0UJ4KNMsR9CDYeCgR9BwZ9CsQHBGYhHB4RHGJIT1CNoTdGMIQnC0MSwSNKgEbobBBYYQXCgQrBkYpCJ4T9BI4sKkELoQzEMoKtB0BhBQYKnCT4Z5EjdCHoIAHTYIbBZYIBBDIWihWBhWhhYBBI4UDsJPCDIOhI4TjBD4PBAIJ9C8SdCkQdBBYIbCEoITDwUJ0JHHhTLBe4xPBhUigVBA4TNBoIhBA4KjC8RZBhcCDoKvDC4cTgUCkMbwgPDXoIfDikCiWBIw3ggOAidjI4ZFBiXCBoWgS4JHEoRZDBYMK4MKB4Q1BI4YDC4USsUKAoOjF4TrCAIcbkSNGoQZCeoODFYMboZRBB4LvBicjjeDCoMLoSBER4PhhWCV4StDJ4UbscSkQhBiXjjZJCLIsTsUBsBHDGoWChVhgUBhVBiPiLAnAhPgB4MJNoLJCQoJHBichTYWjAIJXBKIMCsMKkLHBjWDhOhOYJHFLocB8A0BhNhLYMLwJTBjUjiPChNBIwYFBjXjiXhiVha4RLB4ADBDYMCkEB4ABCLoQZBCoL9BjcjfoILBDIMD8AhCAISBBGoMR0USDIIbCEoMS0ZlBI4cBIINjhkCNIXiOIZzCZoODc4IBBSYQJBCYUT4cTgcA0DLBieCBYTXCAoMSwZHCwSJBV4JJBN4MST4Mga4ngY4MLoMbGYJrDW4QtC4RLBAIRDBE4INB0UKOYNggEhgFgiWiCYQPB8BPBhUCYoTRBokCwEbskJ4KzBhUia4j/B4cCsC3CgKlBAIXCKIQvCIIIvBjcidoJvCkMa8UBgMAdYPBjahCjbPB8MKGYQ3BjUDgPhjcEhUhiWhV4MJwTXCsDDCBYMCiVjhUBTIL7BKIIBBgVAhQ3B4BDCOoPjDoa5CB4MAhWCGYI3BEoMjkkSoQ3CoMSkZJBgPgNYITBhIPDoELwUDV4PBidjidDiXihXChWBF4IxCSYMCidihehhfAgfADIL7Ba4JBCwMCDYInBoTZCoDJDiNikXkiQpBoUZ8YNDM4MLsUD8EEgAvBGYI3CHIgNBAIYVBC4cL4T3BEYKZBjdjNYIBBCYYjBWII5DAAMJ0MawbjDAAnAjcje4MLSIPiGIJrBegMTOIPhB4IFEAIITBBYUCgMSAIKDBgKLC0ULsJFBWoMJ4I7GABgXBFYMMgIBBJILNBXYMT0JDBHoTpCLYQDD4USW4gnCI4NhhSzBkMSwcBR4wANhViI4aRDV4MKKYRDBBogBEJ4RdCf4sTgUTIYJpBoMRwRFTcocTsR7E0UCkELgQHCAJo5CI4lgI4MCoMasZPBADHgbIIxEwUCgELkQHC0BDHgYDB0IBBgPhNosa4cBkEA4BGZbIUiieiYYWjgPgTIwBKieCRIIjDZoMR4ZDbWYmAidCI41jA4RJBAI6nBBoNiV4I/fABMSwUb4RHDjejikCAJphBI9cBoETGINigUAhbfBapkL4UK4UJ4MKDAIAohOgjXjgUgheBhfAgY9B0IBBAoIHCAIOihVCiXCiXDI9JJCwMCgKPCI4YBIieCgPhicjjWEI9YABhUhY4I9C8JDEAoIBCdYJHCLwJGtI4NCikDikCAIsMAIUT8RDBCYMbwapBR+iRFRoeihVhhWhdYMS0RHtgUhgY1B0EDAIPAAoQDB4MToUCgELgMDA4MiR+sDR4Q9BBIUhgPgieCgYDBoRHwaYoBD8DPDa4IJBhkAiXjI91BifihkCifhAoMUgUMgMb4cKgMSsQNBhkhJ4JHugKNCIoIBCA4cbocBsEJ4MT0RVBgUBI9sJHoOhaIQDB4EDBIUSsITDjWjkcjgMgI9sB4BHEAIPgSoVihOhLYkBiNCItpHC0CLDAYMDI4OijXjHt5HKwET4cL8UTAIPjiciTYMI8BH4gES4ULkcS8USkUJ8AJBiTPwAA8KsUKsMCoECsMK0MTgUTsZH1hPhhdChaNB4MT0RBC4cKTINCgMgImGghPihdigfBgeggfAhehhXBgHAZ+qLCwULAYPCiaNBoTbBgNAIuoABiOiiQBB0LJBhUhgKLBAEgA=="));
|
||||
|
||||
function isLeapYear(year)
|
||||
|
|
@ -37,16 +37,16 @@ function bottomLine() {
|
|||
var yy = today.getFullYear();
|
||||
var day = today.getDay(); //day of week as number
|
||||
var h = today.getHours();
|
||||
|
||||
|
||||
var startDate = new Date(yy, 0, 0);
|
||||
var oneDay = 1000 * 60 * 60 * 24;
|
||||
var daysInYear = 0;
|
||||
var diff = today - startDate;
|
||||
var currDayInYear = Math.floor(diff / oneDay);
|
||||
|
||||
|
||||
if (isLeapYear(yy)) daysInYear = 366;
|
||||
else daysInYear = 365;
|
||||
|
||||
|
||||
g.setFont("6x8", tinyFont);
|
||||
|
||||
//first line
|
||||
|
|
@ -55,7 +55,7 @@ function bottomLine() {
|
|||
g.fillRect(105, 175, 160, 185);//STIM
|
||||
g.fillRect(166, 175, 239, 185); // RADAWAY
|
||||
g.setColor(green);
|
||||
|
||||
|
||||
g.drawString("DATE", 20, 177);
|
||||
g.drawString("STIM (3)", 135, 177);
|
||||
g.drawString("RADAWAY (8)", 205, 177);
|
||||
|
|
@ -84,7 +84,7 @@ function drawClock() {
|
|||
var mm = t.getMonth()+1; //month is zero-based
|
||||
var yy = t.getFullYear();
|
||||
var time = ("0" + h).substr(-2) + ":" + ("0" + m).substr(-2);
|
||||
|
||||
|
||||
//create date string
|
||||
if (dd.toString().length < 2) dd = '0' + dd;
|
||||
if (mm.toString().length < 2) mm = '0' + mm;
|
||||
|
|
@ -114,9 +114,9 @@ Bangle.on('lcdPower', function(on) {
|
|||
});
|
||||
|
||||
g.clear();
|
||||
// Show launcher when button pressed
|
||||
Bangle.setUI("clock");
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
setInterval(drawClock, 1E4);
|
||||
drawAll();
|
||||
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
|
|
@ -1,2 +1,3 @@
|
|||
0.01: New App!
|
||||
0.02: Tweaks for Q3 watch
|
||||
0.03: setUI
|
||||
|
|
|
|||
|
|
@ -34,8 +34,7 @@ Bangle.on('lcdPower', function(on) {
|
|||
g.clear();
|
||||
var secondInterval = setInterval(draw, 1000);
|
||||
draw();
|
||||
// Show launcher when button pressed
|
||||
Bangle.setUI("clock");
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
0.02: Modified for use with new bootloader and firmware
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
/* jshint esversion: 6 */
|
||||
const timeFontSize = 6;
|
||||
const dateFontSize = 3;
|
||||
const big = g.getWidth()>200;
|
||||
const timeFontSize = big?6:5;
|
||||
const dateFontSize = big?3:2;
|
||||
const gmtFontSize = 2;
|
||||
const font = "6x8";
|
||||
|
||||
const xyCenter = g.getWidth() / 2;
|
||||
const yposTime = 75;
|
||||
const yposDate = 130;
|
||||
const yposYear = 175;
|
||||
const yposGMT = 220;
|
||||
const yposTime = xyCenter*0.6;
|
||||
const yposDate = xyCenter*1.1;
|
||||
const yposYear = xyCenter*1.4;
|
||||
const yposGMT = xyCenter*1.9;
|
||||
|
||||
// Check settings for what type our clock should be
|
||||
var is12Hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"];
|
||||
|
|
@ -77,5 +78,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");
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 590 B After Width: | Height: | Size: 590 B |
|
Before Width: | Height: | Size: 237 B After Width: | Height: | Size: 237 B |
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwwYurgP/8AROh///gROv///+ACOtJkARhI/5H/I98SpMkwMkCZgRUGqJH/I/5HeyQRByAQMggRCyQRMBwIRCoARcgIREpAR/CMiPjYqTpRgECCIIQNADo="))
|
||||
|
|
@ -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()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setInterval(function() {
|
||||
drawTemperature();
|
||||
}, 20000);
|
||||
drawTemperature();
|
||||
E.showMessage("Loading...");
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
|
After Width: | Height: | Size: 567 B |
|
|
@ -1,2 +1,3 @@
|
|||
0.01: First commit
|
||||
0.02: Made Date more visible
|
||||
0.03: setUI and support for different screens
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@ require("Font7x11Numeric7Seg").add(Graphics);
|
|||
// Check settings for what type our clock should be
|
||||
var is12Hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"];
|
||||
// position on screen
|
||||
const X = 160, Y = 140;
|
||||
|
||||
const big = g.getWidth()>200;
|
||||
const X = big?160:135, Y = big?140:100;
|
||||
|
||||
function draw() {
|
||||
// work out how to display the current time
|
||||
var d = new Date();
|
||||
|
|
@ -25,13 +26,13 @@ function draw() {
|
|||
g.setFont("7x11Numeric7Seg",2);
|
||||
g.drawString(("0"+d.getSeconds()).substr(-2), X+35, Y, true /*clear background*/);
|
||||
// draw the date, in a normal font
|
||||
g.setFont("6x8", 3);
|
||||
g.setFont("6x8", big?3:2);
|
||||
g.setFontAlign(0,1); // align center bottom
|
||||
// pad the date - this clears the background if the date were to change length
|
||||
var dateStr = " "+require("locale").date(d)+" ";
|
||||
g.drawString(dateStr, g.getWidth()/2, Y+35, true /*clear background*/);
|
||||
}
|
||||
|
||||
|
||||
// Clear the screen once, at startup
|
||||
g.clear();
|
||||
// draw immediately at first
|
||||
|
|
@ -46,12 +47,15 @@ Bangle.on('lcdPower',on=>{
|
|||
draw(); // draw immediately
|
||||
}
|
||||
});
|
||||
|
||||
// Show launcher when button pressed
|
||||
Bangle.setUI("clockupdown", btn=>{
|
||||
if (btn==0) vibrateTime();
|
||||
});
|
||||
// Load widgets
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
||||
|
||||
|
||||
// ====================================== Vibration
|
||||
// vibrate 0..9
|
||||
function vibrateDigit(num) {
|
||||
|
|
@ -74,24 +78,21 @@ function vibrateNumber(num) {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var vibrateBusy;
|
||||
function vibrateTime() {
|
||||
if (vibrateBusy) return;
|
||||
vibrateBusy = true;
|
||||
|
||||
|
||||
var d = new Date();
|
||||
var hours = d.getHours(), minutes = d.getMinutes();
|
||||
if (is12Hour) {
|
||||
if (hours == 0) hours = 12;
|
||||
else if (hours>12) hours -= 12;
|
||||
}
|
||||
|
||||
|
||||
vibrateNumber(hours.toString()).
|
||||
then(() => new Promise(resolve=>setTimeout(resolve,500))).
|
||||
then(() => vibrateNumber(minutes.toString())).
|
||||
then(() => vibrateBusy=false);
|
||||
}
|
||||
|
||||
// when BTN1 pressed, vibrate
|
||||
setWatch(vibrateTime, BTN1, {repeat:true,edge:"rising"});
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
0.02: Modified for use with new bootloader and firmware
|
||||
0.03: setUI and support for different screens
|
||||
|
|
|
|||