BangleApps
BangleApps copied to clipboard
Clock Info -> extra data on the clock face
I'm seeing quite a few clocks now that provide extra data on the watch face - like steps or weather. Often there may even be an existing clock that is then cloned to make it show that extra data - and then the clock's code is duplicated, as well as the code to show the data.
It'd be nice to:
- make the process of adding extra data to clock faces easier and more flexible
- reduce the code duplication
The idea of widgets was to display this kind of data, but right now they're relegated to a small 24px strip at the top and bottom of the screen.
We also have clock_info now which is a really neat system that allows a clock to display information that can be scrolled through (and added to with plugins): https://github.com/espruino/BangleApps/blob/master/modules/clock_info.js
I'm open to ideas here - just thinking aloud really, but:
- We have
tl,tr,bl,br
widget areas - we could have a new widget areaclk
or something, and then a library that allowed those widgets to be displayed wherever made sense on the clock face. Widgets would then need to look atthis.w
andthis.h
to figure out how much space they had available.- Downside is clock widgets would get loaded (and then ignored) when there wasn't a clock showing
- Maybe we have another library like
clock_info
that handles non-interactive clock widgets? -
Or maybe these clocks should just use clock_info? It seems in many cases being able to swipe through different info would actually be a big improvement
- but then what if >1 type of info was to be displayed? Maybe we could allow a tap to select which one swipes on the screen would affect
- currently clock_info leaves user-interaction up to the app, but this could be part of the library too
... also if using clock_info it should probably remember what setting it was scrolled to last time the clock was shown
Ok, just added something... So as an example:
var clockInfoMenu = require("clock_info").addInteractive(require("clock_info").load(), (itm, info) => {
var x = 20, y = 20, w=80, h=48;
g.reset().clearRect(x,y,x+w-1,y+h-1);
g.drawRect(x,y,x+w-1,y+h-1); // debug - just to show where we are
g.drawImage(info.img, x+w/2-12,y+4);
g.setFont("6x8:2").setFontAlign(0,0).drawString(info.text, x+w/2,y+36);
});
// then when clock 'unloads':
clockInfoMenu.remove();
delete clockInfoMenu;
So this should be really easy to add to clock faces now...
@peerdavid any thoughts on this? How does this fit with what you're doing with clock_info at the moment?
I think we should probably do with .focus/.unfocus
methods exported, so clocks could potentially have two of these and then allow them to be tapped on to select them.
... and maybe it should store the currently shown options in a settings file
@gfwilliams When clock_info and these things crystallize a bit, should something be appended to the Clock Faces guide? If I get to learning it first I could maybe contribute to that later.
should something be appended to the Clock Faces guide?
Yes, absolutely! And it might be worth mentioning the clock module too
Hi @gfwilliams,
sry forgot to answer :/ Honestly, I'm not sure if I understood it correctly, but the addInteractive
function allows me to dynamically add clock infos somewhere in my clocks when those are selected?
It basically abstracts the user interaction away, so you call it and then all you have to worry about is drawing the information. Swiping on the watch screen then cycles through all the info.
... having said that it doesn't handle calling item.run
but I reckon that would be pretty easy.
I need to actually add it to some clock faces now, but it's just a few lines to do now.
Ohhh yea thats pretty cool, thank you! I will later on update my clocks :D
There is now an app which adds sunrise/sunset to this, if someone wants to see how to add their own clockinfo-only app: https://github.com/espruino/BangleApps/tree/master/apps/clkinfosunrise
Also tapping on an info item will call the run
method if it exists, and it is now possible to have more than one clock_info on screen at once:
let clockInfoDraw = (itm, info, options) => {
g.reset().setBgColor(options.bg).setColor(options.fg).clearRect(options.x, options.y, options.x+options.w-2, options.y+options.h-1);
if (options.focus) g.drawRect(options.x, options.y, options.x+options.w-2, options.y+options.h-1)
var midx = options.x+options.w/2;
g.drawImage(info.img, midx-12,options.y);
g.setFont("6x15").setFontAlign(0,-1).drawString(info.text, midx,options.y+26);
};
let clockInfoItems = require("clock_info").load();
let clockInfoMenu = require("clock_info").addInteractive(clockInfoItems, { x:126, y:24, w:50, h:40, draw : clockInfoDraw, bg : g.theme.bg, fg : g.theme.fg });
let clockInfoMenu2 = require("clock_info").addInteractive(clockInfoItems, { x:0, y:120, w:50, h:40, draw : clockInfoDraw, bg : bgColor, fg : g.theme.bg});
You can then tap to focus, and swipes change the focused item - which is also remembered next time you load the clock.
I'll update slopeclockpp
to use it in a minute
I think clock_info's are the future. I'm very grateful for the work thats been done here. I have already replaced my Pastel Clock with Lato. And the great thing is that it will benefit from all the future clock_info's that become available.
Would be good to have a firmware Clock_info and a Bluetooth ID clock_info. I might get to write one of the other soon. The FW one would be my first pick.
I can see that calendar_info now exists. Would ideally like a configurable date format clock_info.
And a day of the week info (Full day or Abbreviated day. Also would be better to use Camelcase for the Day element then the developer can call touppercase() or tolowercase() on the string. For example return 'Thursday' or 'Thu' and let the developer decide to call touppercase() to get THURSDAY or THU. I personally prefer to display Thursday, it just looks less 1970s that way.
It would also be great to have a GPS clock info that would to show lat / lon and OS Grid reference. Eastings and Northings are pretty useless (IMHO), OS grid reference is much more useful when you have an OS map in your hand.
However I think this comes back to my preference for the developer to be able to pull out device information through a system call, rather than having to setup and manage event handlers which means the developer has to work out of the GPS is already on or not, and there are other complexities like making sure you dont create a 2nd event handler and that you correctly clear down the event handler. BangleJS has moved to the system call approach with Bangle.getHealthStatus("day").steps
and the equivalent for Heart rate. It would be much nicer if you could do Bangle.getGPSFix()
and you either got back an empty object or the last fix. The only thing the user would have to do then is deliberately switch the GPS on through the Settings or Recorder Apps. As the power drain on the GPS gives you 6hrs before you run out of battery the power/fix status of the GPS needs to be visible through a widget like 'GPS Widget' at all times (you dont want the situation where you switch the GPS on and then forget about it).
If I had more time I would have another crack at the lower power option for the GPS.
Great! I think for clocks, clock_info is definitely the way forward
Would be good to have a ....
Well I'm always open to merging PRs :) I see you did the firmware widget already.
OS grid reference is a great one - because it's basically UK only it really doesn't make a great deal of sense to add it inside a clock app, but as an add-on it's perfect. Not sure if you saw but I already had some example code for other Espruino devices which would be easy to use: http://www.espruino.com/Pocket+Walking+GPS
the developer has to work out of the GPS is already on or not
I do listen sometimes :)
http://www.espruino.com/Reference#l_Bangle_getGPSFix http://www.espruino.com/Reference#l_Bangle_isGPSOn
I've thought up some configurations for clock info's that could be implemented. If I know myself I will probably not get to doing it - but if I do I'll leave a comment here.
- [ ] When a clock face app sets up clock infos make it possible to lock to one specific clock info. This way if there is some info that should always be visible it wont be hidden by accident. If the user want to change this I imagine it being done from the clock face apps settings page.
- [ ] As an addition to the suggestion above, make it possible for a clock info section to be unable to be focused. Doing this has the added benefit of not hindering other input listeners if that's not wanted.
- [ ] Add setting, both to clock face apps settings (for individual configuration) and clock info settings page (for general configuration), making clock info section always return to a specific clock info entry when the Bangle is locked/LCD times out.
I'll probably add more ideas here.
I like the third one - resetting to a specific entry on lock. I guess we'd need to do a bit of work to allow clockinfo settings to be per-clockface.
In terms of the others, I'm not a massive fan of deliberately restricting things... Have you actually really had a big issue where you accidentally selected a clockinfo and changed it?
I like the third one - resetting to a specific entry on lock. I guess we'd need to do a bit of work to allow clockinfo settings to be per-clockface.
And since some clockfaces implement multiple clock info sections - have clockinfo settings PER CLOCKINFO SECTION in a clockface 😂 - maybe take one step at a time here whenever someone gets to maybe implementing this.
Have you actually really had a big issue where you accidentally selected a clockinfo and changed it?
No, not really.
I thought it could be a way to make it easy to create clock faces with complications in some more classical sense. Where they often aren't as interactive.
I think it's fine to close this now - we have clockinfos and a lot of stuff uses them, so I think we're good