Merge branch 'espruino:master' into master
commit
1a33dff88a
|
|
@ -56,4 +56,6 @@
|
||||||
0.50: Allow setting of screen rotation
|
0.50: Allow setting of screen rotation
|
||||||
Remove support for 2v11 and earlier firmware
|
Remove support for 2v11 and earlier firmware
|
||||||
0.51: Remove patches for 2v10 firmware (BEEPSET and setUI)
|
0.51: Remove patches for 2v10 firmware (BEEPSET and setUI)
|
||||||
Add patch to ensure that compass heading is corrected
|
Add patch to ensure that compass heading is corrected on pre-2v15.68 firmware
|
||||||
|
Ensure clock is only fast-loaded if it doesn't contain widgets
|
||||||
|
0.52: Ensure heading patch for pre-2v15.68 firmware applies to getCompass
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
// This runs after a 'fresh' boot
|
// This runs after a 'fresh' boot
|
||||||
var s = require("Storage").readJSON("setting.json",1)||{};
|
var s = require("Storage").readJSON("setting.json",1)||{};
|
||||||
|
/* If were being called from JS code in order to load the clock quickly (eg from a launcher)
|
||||||
|
and the clock in question doesn't have widgets, force a normal 'load' as this will then
|
||||||
|
reset everything and remove the widgets. */
|
||||||
|
if (global.__FILE__ && !s.clockHasWidgets) {load();throw "Clock has no widgets, can't fast load";}
|
||||||
|
// Otherwise continue to try and load the clock
|
||||||
var _clkApp = require("Storage").read(s.clock);
|
var _clkApp = require("Storage").read(s.clock);
|
||||||
if (!_clkApp) {
|
if (!_clkApp) {
|
||||||
_clkApp = require("Storage").list(/\.info$/)
|
_clkApp = require("Storage").list(/\.info$/)
|
||||||
|
|
@ -13,7 +18,8 @@ if (!_clkApp) {
|
||||||
.sort((a, b) => a.sortorder - b.sortorder)[0];
|
.sort((a, b) => a.sortorder - b.sortorder)[0];
|
||||||
if (_clkApp){
|
if (_clkApp){
|
||||||
s.clock = _clkApp.src;
|
s.clock = _clkApp.src;
|
||||||
_clkApp = require("Storage").read(_clkApp.src);
|
_clkApp = require("Storage").read(_clkApp.src);
|
||||||
|
s.clockHasWidgets = _clkApp.includes("Bangle.loadWidgets");
|
||||||
require("Storage").writeJSON("setting.json", s);
|
require("Storage").writeJSON("setting.json", s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,8 @@ if (s.rotate) boot+=`g.setRotation(${s.rotate&3},${s.rotate>>2});\n` // screen r
|
||||||
// ================================================== FIXING OLDER FIRMWARES
|
// ================================================== FIXING OLDER FIRMWARES
|
||||||
// 2v15.68 and before had compass heading inverted.
|
// 2v15.68 and before had compass heading inverted.
|
||||||
if (process.version.replace("v","")<215.68)
|
if (process.version.replace("v","")<215.68)
|
||||||
boot += `Bangle.on('mag',e=>{if(!isNaN(e.heading)) e.heading=360-e.heading;});`;
|
boot += `Bangle.on('mag',e=>{if(!isNaN(e.heading))e.heading=360-e.heading;});
|
||||||
|
Bangle.getCompass=(c=>(()=>{e=c();if(!isNaN(e.heading))e.heading=360-e.heading;return e;}))(Bangle.getCompass);`;
|
||||||
|
|
||||||
// ================================================== BOOT.JS
|
// ================================================== BOOT.JS
|
||||||
// Append *.boot.js files
|
// Append *.boot.js files
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"id": "boot",
|
"id": "boot",
|
||||||
"name": "Bootloader",
|
"name": "Bootloader",
|
||||||
"version": "0.51",
|
"version": "0.52",
|
||||||
"description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings",
|
"description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings",
|
||||||
"icon": "bootloader.png",
|
"icon": "bootloader.png",
|
||||||
"type": "bootloader",
|
"type": "bootloader",
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,4 @@
|
||||||
0.07: Read app icons on demand
|
0.07: Read app icons on demand
|
||||||
Add swipe-to-exit
|
Add swipe-to-exit
|
||||||
0.08: Only use fast loading for switching to clock to prevent problems in full screen apps
|
0.08: Only use fast loading for switching to clock to prevent problems in full screen apps
|
||||||
|
0.09: Remove fast load option since clocks containing Bangle.loadWidgets are now always normally loaded
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,3 @@ This launcher shows 9 apps per screen, making it much faster to navigate versus
|
||||||
## Technical note
|
## Technical note
|
||||||
|
|
||||||
The app uses `E.showScroller`'s code in the app but not the function itself because `E.showScroller` doesn't report the position of a press to the select function.
|
The app uses `E.showScroller`'s code in the app but not the function itself because `E.showScroller` doesn't report the position of a press to the select function.
|
||||||
|
|
||||||
### Fastload option
|
|
||||||
|
|
||||||
Fastload clears up the memory used by the launcher and directly evals the code of the clock to load.
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
const s = require("Storage");
|
const s = require("Storage");
|
||||||
const settings = s.readJSON("launch.json", true) || { showClocks: true, fullscreen: false,direct:false,swipeExit:false,oneClickExit:false,fastload:false };
|
const settings = s.readJSON("launch.json", true) || { showClocks: true, fullscreen: false,direct:false,swipeExit:false,oneClickExit:false};
|
||||||
if (!settings.fullscreen) {
|
if (!settings.fullscreen) {
|
||||||
Bangle.loadWidgets();
|
Bangle.loadWidgets();
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
|
|
@ -180,24 +180,20 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
const returnToClock = function() {
|
const returnToClock = function() {
|
||||||
if (settings.fastload == true){
|
Bangle.setUI();
|
||||||
Bangle.setUI();
|
delete launchCache;
|
||||||
delete launchCache;
|
delete launchHash;
|
||||||
delete launchHash;
|
delete drawItemAuto;
|
||||||
delete drawItemAuto;
|
delete drawText;
|
||||||
delete drawText;
|
delete selectItem;
|
||||||
delete selectItem;
|
delete onDrag;
|
||||||
delete onDrag;
|
delete drawItems;
|
||||||
delete drawItems;
|
delete drawItem;
|
||||||
delete drawItem;
|
delete returnToClock;
|
||||||
delete returnToClock;
|
delete idxToY;
|
||||||
delete idxToY;
|
delete YtoIdx;
|
||||||
delete YtoIdx;
|
delete settings;
|
||||||
delete settings;
|
setTimeout(eval, 0, s.read(".bootcde"));
|
||||||
setTimeout(eval, 0, s.read(".bootcde"));
|
|
||||||
} else {
|
|
||||||
load();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"id": "iconlaunch",
|
"id": "iconlaunch",
|
||||||
"name": "Icon Launcher",
|
"name": "Icon Launcher",
|
||||||
"shortName" : "Icon launcher",
|
"shortName" : "Icon launcher",
|
||||||
"version": "0.08",
|
"version": "0.09",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"description": "A launcher inspired by smartphones, with an icon-only scrollable menu.",
|
"description": "A launcher inspired by smartphones, with an icon-only scrollable menu.",
|
||||||
"tags": "tool,system,launcher",
|
"tags": "tool,system,launcher",
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,7 @@
|
||||||
fullscreen: false,
|
fullscreen: false,
|
||||||
direct: false,
|
direct: false,
|
||||||
oneClickExit: false,
|
oneClickExit: false,
|
||||||
swipeExit: false,
|
swipeExit: false
|
||||||
fastload: false
|
|
||||||
}, require("Storage").readJSON("launch.json", true) || {});
|
}, require("Storage").readJSON("launch.json", true) || {});
|
||||||
|
|
||||||
let fonts = g.getFonts();
|
let fonts = g.getFonts();
|
||||||
|
|
@ -36,10 +35,6 @@
|
||||||
/*LANG*/"Swipe exit": {
|
/*LANG*/"Swipe exit": {
|
||||||
value: settings.swipeExit == true,
|
value: settings.swipeExit == true,
|
||||||
onchange: m => { save("swipeExit", m) }
|
onchange: m => { save("swipeExit", m) }
|
||||||
},
|
|
||||||
/*LANG*/"Fastload": {
|
|
||||||
value: settings.fastload == true,
|
|
||||||
onchange: (m) => { save("fastload", m) }
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
E.showMenu(appMenu);
|
E.showMenu(appMenu);
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ E.showScroller({
|
||||||
});
|
});
|
||||||
g.flip(); // force a render before widgets have finished drawing
|
g.flip(); // force a render before widgets have finished drawing
|
||||||
|
|
||||||
function returnToClock() {
|
let returnToClock = function() {
|
||||||
// unload everything manually
|
// unload everything manually
|
||||||
// ... or we could just call `load();` but it will be slower
|
// ... or we could just call `load();` but it will be slower
|
||||||
Bangle.setUI(); // remove scroller's handling
|
Bangle.setUI(); // remove scroller's handling
|
||||||
|
|
@ -85,7 +85,7 @@ if (process.env.HWVERSION==2) {
|
||||||
// 10s of inactivity goes back to clock
|
// 10s of inactivity goes back to clock
|
||||||
Bangle.setLocked(false); // unlock initially
|
Bangle.setLocked(false); // unlock initially
|
||||||
let lockTimeout;
|
let lockTimeout;
|
||||||
function lockHandler(locked) {
|
let lockHandler = function(locked) {
|
||||||
if (lockTimeout) clearTimeout(lockTimeout);
|
if (lockTimeout) clearTimeout(lockTimeout);
|
||||||
lockTimeout = undefined;
|
lockTimeout = undefined;
|
||||||
if (locked)
|
if (locked)
|
||||||
|
|
|
||||||
|
|
@ -57,4 +57,4 @@
|
||||||
0.50: Add Bangle.js 2 touchscreen calibration - for 2v16 or 2v15 cutting edge builds
|
0.50: Add Bangle.js 2 touchscreen calibration - for 2v16 or 2v15 cutting edge builds
|
||||||
0.51: Add setting for configuring a launcher
|
0.51: Add setting for configuring a launcher
|
||||||
0.52: Add option for left-handed users
|
0.52: Add option for left-handed users
|
||||||
|
0.53: Ensure that when clock is set, clockHasWidgets is set correctly too
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"id": "setting",
|
"id": "setting",
|
||||||
"name": "Settings",
|
"name": "Settings",
|
||||||
"version": "0.52",
|
"version": "0.53",
|
||||||
"description": "A menu for setting up Bangle.js",
|
"description": "A menu for setting up Bangle.js",
|
||||||
"icon": "settings.png",
|
"icon": "settings.png",
|
||||||
"tags": "tool,system",
|
"tags": "tool,system",
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ function resetSettings() {
|
||||||
timezone: 0, // Set the timezone for the device
|
timezone: 0, // Set the timezone for the device
|
||||||
HID: false, // BLE HID mode, off by default
|
HID: false, // BLE HID mode, off by default
|
||||||
clock: null, // a string for the default clock's name
|
clock: null, // a string for the default clock's name
|
||||||
|
// clockHasWidgets: false, // Does the clock in 'clock' contain the string 'Bangle.loadWidgets'
|
||||||
"12hour" : false, // 12 or 24 hour clock?
|
"12hour" : false, // 12 or 24 hour clock?
|
||||||
firstDayOfWeek: 0, // 0 -> Sunday (default), 1 -> Monday
|
firstDayOfWeek: 0, // 0 -> Sunday (default), 1 -> Monday
|
||||||
brightness: 1, // LCD brightness from 0 to 1
|
brightness: 1, // LCD brightness from 0 to 1
|
||||||
|
|
@ -674,11 +675,10 @@ function showClockMenu() {
|
||||||
label = "* " + label;
|
label = "* " + label;
|
||||||
}
|
}
|
||||||
clockMenu[label] = () => {
|
clockMenu[label] = () => {
|
||||||
if (settings.clock !== app.src) {
|
settings.clock = app.src;
|
||||||
settings.clock = app.src;
|
settings.clockHasWidgets = require("Storage").read(app.src).includes("Bangle.loadWidgets");
|
||||||
updateSettings();
|
updateSettings();
|
||||||
showMainMenu();
|
showMainMenu();
|
||||||
}
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
if (clockApps.length === 0) {
|
if (clockApps.length === 0) {
|
||||||
|
|
@ -703,11 +703,9 @@ function showLauncherMenu() {
|
||||||
label = "* " + label;
|
label = "* " + label;
|
||||||
}
|
}
|
||||||
launcherMenu[label] = () => {
|
launcherMenu[label] = () => {
|
||||||
if (settings.launcher !== app.src) {
|
settings.launcher = app.src;
|
||||||
settings.launcher = app.src;
|
updateSettings();
|
||||||
updateSettings();
|
showMainMenu();
|
||||||
showMainMenu();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
if (launcherApps.length === 0) {
|
if (launcherApps.length === 0) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
0.01: New App!
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
require("heatshrink").decompress(atob("mEw4X/AAMfBIWSyhL/ACkD1cAlWq1WABYk6BYnABQcO1QLa3//FwgLEHIoABlQLO3WsBZHqHYwLGEooLF0ALHnW/BZMDDII8DmoLDAAILDmtVBZHV+oLEmEA1Ws6vAgNVh5EB+Eq/2lq4cCqqPBIYMqytVoALCioLD6tVBYMDqALEr4KBqotBqkAgsP/9VvkMhoLBhoLCKwQrCIoQLCBQITBM4QPB+ALBFYYLBhpHDBY0BIoILFuEPBYNcBY1XP4fAmgLENIYDBI4JGCNIlXqp3CCof/F4UPIIILEI4wtEIQVwAYIzCO4oLCSgIXFqpfCIwjTBCQXAEQgA/AAoA="))
|
||||||
|
|
@ -0,0 +1,117 @@
|
||||||
|
Graphics.prototype.setFontPaytoneOne = function(scale) {
|
||||||
|
// Actual height 81 (91 - 11)
|
||||||
|
this.setFontCustom(
|
||||||
|
E.toString(require('heatshrink').decompress(atob('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'))),
|
||||||
|
46,
|
||||||
|
atob("ITZOMzs7SDxHNUdGIQ=="),
|
||||||
|
113+(scale<<8)+(1<<16)
|
||||||
|
);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
{ // must be inside our own scope here so that when we are unloaded everything disappears
|
||||||
|
// we also define functions using 'let fn = function() {..}' for the same reason. function decls are global
|
||||||
|
let drawTimeout;
|
||||||
|
|
||||||
|
let g2 = Graphics.createArrayBuffer(g.getWidth(),90,1,{msb:true});
|
||||||
|
let g2img = {
|
||||||
|
width:g2.getWidth(), height:g2.getHeight(), bpp:1,
|
||||||
|
buffer:g2.buffer, transparent:0
|
||||||
|
};
|
||||||
|
const slope = 20;
|
||||||
|
const offsy = 20; // offset of numbers from middle
|
||||||
|
const fontBorder = 4; // offset from left/right
|
||||||
|
const slopeBorder = 10, slopeBorderUpper = 4; // fudge-factor to move minutes down from slope
|
||||||
|
let R,x,y; // middle of the clock face
|
||||||
|
let dateStr = "";
|
||||||
|
let bgColors = g.theme.dark ? ["#ff0","#0ff","#f0f"] : ["#f00","#0f0","#00f"];
|
||||||
|
let bgColor = bgColors[(Math.random()*bgColors.length)|0];
|
||||||
|
|
||||||
|
|
||||||
|
// Draw the hour, and the minute into an offscreen buffer
|
||||||
|
let draw = function() {
|
||||||
|
R = Bangle.appRect;
|
||||||
|
x = R.w / 2;
|
||||||
|
y = R.y + R.h / 2 - 12; // 12 = room for date
|
||||||
|
var date = new Date();
|
||||||
|
var hourStr = date.getHours();
|
||||||
|
var minStr = date.getMinutes().toString().padStart(2,0);
|
||||||
|
dateStr = require("locale").dow(date, 1).toUpperCase()+ " "+
|
||||||
|
require("locale").date(date, 0).toUpperCase();
|
||||||
|
|
||||||
|
// Draw hour
|
||||||
|
g.reset().clearRect(R); // clear whole background (w/o widgets)
|
||||||
|
g.setFontAlign(-1, 0).setFont("PaytoneOne");
|
||||||
|
g.drawString(hourStr, fontBorder, y-offsy);
|
||||||
|
// add slope in background color
|
||||||
|
g.setColor(g.theme.bg).fillPoly([0,y+slope-slopeBorderUpper, R.w,y-slope-slopeBorderUpper,
|
||||||
|
R.w,y-slope, 0,y+slope]);
|
||||||
|
// Draw minute to offscreen buffer
|
||||||
|
g2.setColor(0).fillRect(0,0,g2.getWidth(),g2.getHeight()).setFontAlign(1, 0).setFont("PaytoneOne");
|
||||||
|
g2.setColor(1).drawString(minStr, g2.getWidth()-fontBorder, g2.getHeight()/2);
|
||||||
|
g2.setColor(0).fillPoly([0,0, g2.getWidth(),0, 0,slope*2]);
|
||||||
|
// start the animation *in*
|
||||||
|
animate(true);
|
||||||
|
|
||||||
|
// queue next draw
|
||||||
|
if (drawTimeout) clearTimeout(drawTimeout);
|
||||||
|
drawTimeout = setTimeout(function() {
|
||||||
|
drawTimeout = undefined;
|
||||||
|
animate(false, function() {
|
||||||
|
draw();
|
||||||
|
});
|
||||||
|
}, 60000 - (Date.now() % 60000));
|
||||||
|
};
|
||||||
|
|
||||||
|
let isAnimIn = true;
|
||||||
|
let animInterval;
|
||||||
|
// Draw *just* the minute image
|
||||||
|
let drawMinute = function() {
|
||||||
|
var yo = slopeBorder + offsy + y - 2*slope*minuteX/R.w;
|
||||||
|
// draw over the slanty bit
|
||||||
|
g.setColor(bgColor).fillPoly([0,y+slope, R.w,y-slope, R.w,R.h+R.y, 0,R.h+R.y]);
|
||||||
|
// draw the minutes
|
||||||
|
g.setColor(g.theme.bg).drawImage(g2img, x+minuteX-(g2.getWidth()/2), yo-(g2.getHeight()/2));
|
||||||
|
};
|
||||||
|
let animate = function(isIn, callback) {
|
||||||
|
if (animInterval) clearInterval(animInterval);
|
||||||
|
isAnimIn = isIn;
|
||||||
|
minuteX = isAnimIn ? -g2.getWidth() : 0;
|
||||||
|
drawMinute();
|
||||||
|
animInterval = setInterval(function() {
|
||||||
|
minuteX += 8;
|
||||||
|
let stop = false;
|
||||||
|
if (isAnimIn && minuteX>=0) {
|
||||||
|
minuteX=0;
|
||||||
|
stop = true;
|
||||||
|
} else if (!isAnimIn && minuteX>=R.w)
|
||||||
|
stop = true;
|
||||||
|
drawMinute();
|
||||||
|
if (stop) {
|
||||||
|
clearInterval(animInterval);
|
||||||
|
animInterval=undefined;
|
||||||
|
if (callback) callback();
|
||||||
|
if (isAnimIn) {
|
||||||
|
// draw the date
|
||||||
|
g.setColor(g.theme.bg).setFontAlign(0, 0).setFont("6x15").drawString(dateStr, R.x + R.w/2, R.y+R.h-9);}
|
||||||
|
}
|
||||||
|
}, 20);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Show launcher when middle button pressed
|
||||||
|
Bangle.setUI({
|
||||||
|
mode : "clock",
|
||||||
|
remove : function() {
|
||||||
|
// Called to unload all of the clock app
|
||||||
|
if (animInterval) clearInterval(animInterval);
|
||||||
|
animInterval = undefined;
|
||||||
|
if (drawTimeout) clearTimeout(drawTimeout);
|
||||||
|
drawTimeout = undefined;
|
||||||
|
delete Graphics.prototype.setFontPaytoneOne;
|
||||||
|
}});
|
||||||
|
// Load widgets
|
||||||
|
Bangle.loadWidgets();
|
||||||
|
draw();
|
||||||
|
setTimeout(Bangle.drawWidgets,0);
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
|
|
@ -0,0 +1,14 @@
|
||||||
|
{ "id": "slopeclock",
|
||||||
|
"name": "Slope Clock",
|
||||||
|
"version":"0.01",
|
||||||
|
"description": "A clock where hours and minutes are divided by a sloping line. When the minute changes, the numbers slide off the screen",
|
||||||
|
"icon": "app.png",
|
||||||
|
"screenshots": [{"url":"screenshot.png"}],
|
||||||
|
"type": "clock",
|
||||||
|
"tags": "clock",
|
||||||
|
"supports" : ["BANGLEJS2"],
|
||||||
|
"storage": [
|
||||||
|
{"name":"slopeclock.app.js","url":"app.js"},
|
||||||
|
{"name":"slopeclock.img","url":"app-icon.js","evaluate":true}
|
||||||
|
]
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
Loading…
Reference in New Issue