BangleApps icon indicating copy to clipboard operation
BangleApps copied to clipboard

Clock Info -> extra data on the clock face

Open gfwilliams opened this issue 2 years ago • 15 comments

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 area clk 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 at this.w and this.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

gfwilliams avatar Nov 04 '22 09:11 gfwilliams

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

gfwilliams avatar Nov 04 '22 09:11 gfwilliams

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 avatar Nov 04 '22 11:11 gfwilliams

@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 avatar Nov 04 '22 14:11 gfwilliams

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

thyttan avatar Nov 04 '22 18:11 thyttan

should something be appended to the Clock Faces guide?

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

gfwilliams avatar Nov 05 '22 11:11 gfwilliams

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?

peerdavid avatar Nov 10 '22 14:11 peerdavid

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.

gfwilliams avatar Nov 10 '22 14:11 gfwilliams

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

peerdavid avatar Nov 10 '22 14:11 peerdavid

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

gfwilliams avatar Nov 23 '22 10:11 gfwilliams

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 avatar Dec 11 '22 11:12 hughbarney

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.

hughbarney avatar Dec 11 '22 11:12 hughbarney

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

gfwilliams avatar Dec 12 '22 09:12 gfwilliams

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.

thyttan avatar Jun 03 '23 18:06 thyttan

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?

gfwilliams avatar Jun 05 '23 08:06 gfwilliams

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.

thyttan avatar Jun 05 '23 22:06 thyttan

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

gfwilliams avatar Oct 14 '24 08:10 gfwilliams