How to use the Bangle.js Layout library #3001
Replies: 31 comments
-
Posted at 2021-09-02 by rigrig This looks pretty neat, hopefully I'll have some time to play with it this weekend. Would it be bloaty to add something like this (untested):
(or even add it to Just because I expect otherwise the |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-09-02 by @fanoush Looks nice and useful. Is there also color attribute? Or one could separate layouts per color and do g.setColor between. EDIT: oh yes, there is col,bgCol documented in https://raw.githubusercontent.com/espruino/BangleApps/master/modules/Layout.js However now I see there is lot of "Bangle." calls inside so it is not so universal and reusable for other devices. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-09-02 by @gfwilliams
I think it could be a good one to add, yes. It's could also provide some extra logic in there as sometimes new text might change the width of the field which could move other things.
It's only to handle the touchscreen so they could always be put inside If you're wondering about it for other smartwatches I'd definitely say you should try including edit: I should also add that I'd like to make the layout/rendering for this really fast, so when we get something that works well for what we need it for I may well build it into the firmware - and then it could make sense to use it because it'll actually be faster that issuing draw calls from JS. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-09-05 by rigrig Gave it a spin, and it works pretty nice. Definitely a huge improvement over fiddling with pixels by hand. One minor annoyance I ran into: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-09-13 by NebbishHacker I haven't looked too deeply at the new layout library yet, but maybe this will serve as some inspiration... A while back I was experimenting with a layout library of my own. I never quite got it to the point where I was happy releasing it to the world, but it did have some interesting features. Most notably:
Usage looked like this:
(Each If anyone would like to see it in action, they can try it here: https://www.espruino.com/ide/?gist=bde5d085b2723a87e93f55411c03983a |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-09-13 by @allObjects @nebbishhacker, tried to run your Web-linked code in the emulator and get:
What do I miss here? (See no reason why it should not run in the emulator.) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-09-13 by @MaBecker It does on my site and look's very nice. Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-09-13 by NebbishHacker The problem was my use of a particularly long immediately invoked function expression - it only worked for me because I had enabled "Pretokenise code before upload" in the web ide settings. I've tweaked it so it should work now regardless. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-09-14 by @allObjects @nebbishhacker, Ic, thank you. I faced a similar issue with my http://www.espruino.com/ui supporting touch screen and soft keyboard (for screenshots see: http://forum.espruino.com/conversations/292990/) when defining a layout. For the framework code I could have only limited modules 'inline'. Placing the layout in a function instead of in immediate execution helped in my case, since the definitions were simpler than your module inline code. (The ui does though a bit more than rendering... and, of course, it was a larger display with much more items on it and the layout is position and size-wise custom/hard coded to the device). I like the lazy part very much! Modified line # 227 to
to showcase nicely the gracious handling of different long - too long - line(s)... see attached screen shots ;) Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-09-14 by @gfwilliams Nice - I like the idea of the lazy rendering too (with the CRC to check for changes). Although it looks like you don't use it in that example? While it's super easy for the user, I wonder if it'd just make things too slow to try and handle it automatically? I wonder if there's anything that we could pull across? I think the row/col layout and 'flex' areas are pretty similar to what Layout does with @rigrig the changing values is something so common we definitely need a nice, fast, easy way of handling it. Just thinking here but I guess there are two main solutions:
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-09-14 by rigrig
I guess that sounds ideal, but what if changing some text means the item changes size, so adjacent (non-modified) elements would have to move?
That might be a bit tricky with Vector fonts, as it depends on the actual characters.
Or maybe make Another wishlist item: specify
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-09-14 by NebbishHacker
My example does use lazy rendering! Each time
The hashing is pretty fast, since it just delegates to E.toJS and E.CRC32, and the rest of the logic honestly isn't too complicated. I'd say it's at least worth investigating. The Vector Clock app I just submitted also uses very similar lazy rendering logic, without all the layout stuff.
Correct me if I'm wrong, but it sounds like my 'flex' system is a bit more powerful? I'm guessing that only one element can be set to |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-09-14 by HughB
This will still require the developer to keep a prevVal to compare against. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-09-15 by NebbishHacker Since there appears to be some interest in lazy rendering, I've created pull request implementing it in the Layout library. Just pass the third argument
Demo here: https://www.espruino.com/ide/?gist=cc5f26ad897ecaa531b698781d47964a# Edit: I see my demo has the same issue as before. If it gives you any errors enable "Pretokenise code before upload" in the web ide settings. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-09-15 by @gfwilliams
Yes, that would be a pain, however I imagine for the vast majority of apps you probably don't want things to start moving around on the screen when text changes? It's almost a benefit if stuff stays in the same place unless it is explicitly updated.
Yes, this does make a lot of sense. I was avoiding it because I assumed it would be a slow iterative thing, but @nebbishhacker has a really neat trick there to do it quick. It does make me wonder whether if no font is specified, it almost makes sense to choose the font automatically? Like use Vector for >20px, and then 6x8:2, 6x8, 4x6 depending on the width available? I guess you don't want the font changing each time but if the font selection were done during 'update' it wouldn't be a huge problem.
No, you can have more than one in layout. The way it's implemented it'd be trivial to make
Sorry, I didn't notice that! I just saw the UI 'tree' being recreated each call and assumed it wasn't :) Thanks for the PR - I'm a bit busy at the moment but I'll try and have a proper play with it at some point. I'll post some comments on the PR itself though |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-09-16 by @gfwilliams Just merged your changes! I've got some tweaks to enable fillx/y with ints which I'll get in too. But yes, I think ideally the layout library needs to handle both cases, but I hope in a lot of apps things will stay in the same place most of the time. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-10-13 by coylen Just a quick question on lazy rendering, if I update a layout txt with the exact same text, will this cause a screen update on a render pass? Just need to know whether I need to check elsewhere in the code if the data has changed before updating screen or if I can just set screen with all current data and have the lazy renderer decide what work actually needs done? |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-10-13 by NebbishHacker
As long as the contents of the layout element are identical the lazy renderer should be able to avoid re-rendering it.
That's the idea :) One caveat is that the lazy rendering algorithm itself has a small performance cost, so while it can help a great deal with reducing flicking on the Bangle 1, it's not always that much faster than a full re-render. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-10-15 by coylen I have been looking into the layout library and to meet my aspirations I would like to add an option to have an imagebutton. I am happy to do the work and submit a pull request, but as this could be done in a number of ways I thought it would be a good idea to float the idea and perhaps get a consensus on how it is best implemented. In my mind I can see three options:
I would be interested in any views/ preferences on how this should be implemented? |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-10-15 by @gfwilliams Hi! That sounds like a great idea - it's something I've been considering too. I'd say option 2: If you could issue a PR that'd be awesome. Main reason for choosing Option 2 is the idea is to extend Layout such that on Bangle.js 1 you can use the up/down buttons to cycle through the selected buttons and then use the middle button to select (allowing even touch-based apps to be used with the original Bangle). It'll be a lot easier to do that if there's only one 'btn' type). |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-10-15 by NebbishHacker An even more general approach would be to allow |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-10-15 by coylen @nebbishhacker in effect an equivalent of "v" or "h" but with a touch callback and possibly an outline round the whole thing. I guess the implementation would have "btn" contain a single layout object which could be a "v" or "h" to allow stacking. Certainly more flexible, but makes the simplest used case of a button with just a label more complicated to implement. @gfwilliams how does this sound to you? |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-10-15 by @gfwilliams Well, in new Espruino firmwares (cutting edge, or 2v11 when released) you can actually put a binary image inside a text string like this, and alignment and newlines are handled correctly. There's a new 'stringMetrics' too which gives you width/height of a string (even including inline images) and I'll move the layout over to using that soon. So in a way, you can actually do the 'simple' option right now - just set the label to the "\0" plus the image. If you want text under, do However probably one big use case is going to be toggle buttons - so press once and the image changes to 'on', again for 'off', so probably something that allows you to change the image easily is better. So yeah, maybe we just look for a You can still do the 'quick' image icon, or can do it properly |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-10-16 by @allObjects ..."\o"... I know where that leads to: quite elaborate figuring what the context / object is - to properly deal with the variations of the options information. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-10-20 by @gfwilliams Just a note that the tutorial is now live: http://www.espruino.com/Bangle.js+Layout Additions/tweaks welcome |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-10-20 by @allObjects I like the partial and lazy update of a layout... what bothers me a bit is calling a value a label... I understand that it is historical, and atomic- with no composite display object, such as ro/rw field as in html - everything can be looked at as a label, the label of a field and the value of a field. Since I cannot see any absolute placements, I assume the partial update walks the complete layout to determine where the update has to happen. Regarding fonts: I understand that with vector fonts the font size is in percents of screen size and allows use in both bangles. What a bout the (much faster) WxH fonts? I assume the W and H are absolute. Is there a solution path for layouts using such fonts? The Bangle 1 / 2 ration is 1.363636., or 0.73333. Could something be baked in to the layout for these fonts that tells for which bangle the layout is originally specified, like dots per (square) screen? Line height (and positions) - vertical (horizontal?) on horizontal display could then still be calculated and a font mapping could figure what font to use. To handle font (as well as colors) I would always go for a palette. Handling the mapping of elements in a palette is always easier than do it for every layout element (label) definition. What are the thoughts for selecting a font (and color) from a palette in a layout element? |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-10-20 by @gfwilliams
Yes, these are all scaled explicitly. I have been wondering about an 'auto' font size... So basically don't specify a font and then Layout just uses a font that fits into the available space. Seems like a good plan, but it requires two passes, since you might lay out once to find out how much width you have, but then choose a bigger font which uses up more height and needs another layout
We now have themes in |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-10-24 by avanc Is it possible to scroll text horizontally if the text exceeds the available width? |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-10-24 by @allObjects everything can be made... BUT: Something has to hold on to the graphics buffer of the full with, or you would have to calculate for every output, beginning with what pixel you have to send the graphics to the device... and you would end up with 'snailing display'. With double buffer and messing with the buffer size in the memory and the view port size of the actual display... that works. I'm not sure current setup would allow you to define a different buffer size than the display and to offset the view port from the buffer (for double buffering, and it would cost you a lot of memory... 176x176x3/8 = 11.6 Kbytes for a matching buffer, and way much more for a buffer that would accommodate longer lines...). If you can go on a single fixed width font and matching grid, you could make scroll work with redrawing always 'everything' without double buffering. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-10-25 by @gfwilliams Right now I'm not sure it makes sense to add things like animation to layout, but it'd be pretty easy to add it yourself. There's the 'custom' object type - so you can just provide your own renderer. If you call For the grocery list, does something like |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-09-02 by @gfwilliams
Hi! With the new Bangle.js 2 coming along the screen sizes/numbers of buttons are different, and it's meant that most apps are going to need a bit of fiddling to work correctly. Rather than having two versions of the same app (or lots of 'if' statements) I thought it'd be good to have a layout library that places everything on the screen in the right place.
THE TUTORIAL IS NOW ONLINE:
http://www.espruino.com/Bangle.js+Layout
Beta Was this translation helpful? Give feedback.
All reactions