espruino / BangleApps

Bangle.js App Loader (and Apps)
https://banglejs.com/apps
MIT License
478 stars 1.14k forks source link

Clock Info -> extra data on the clock face #2226

Open gfwilliams opened 1 year ago

gfwilliams commented 1 year ago

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:

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:

gfwilliams commented 1 year ago

... also if using clock_info it should probably remember what setting it was scrolled to last time the clock was shown

gfwilliams commented 1 year ago

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

gfwilliams commented 1 year ago

@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

thyttan commented 1 year ago

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

gfwilliams commented 1 year ago

should something be appended to the Clock Faces guide?

Yes, absolutely! And it might be worth mentioning the clock module too

peerdavid commented 1 year ago

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?

gfwilliams commented 1 year ago

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.

peerdavid commented 1 year ago

Ohhh yea thats pretty cool, thank you! I will later on update my clocks :D

gfwilliams commented 1 year ago

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

hughbarney commented 1 year ago

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.

hughbarney commented 1 year ago

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.

gfwilliams commented 1 year ago

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

thyttan commented 1 year ago

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.

I'll probably add more ideas here.

gfwilliams commented 1 year ago

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?

thyttan commented 1 year ago

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.