New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rework layouts #1615
Comments
A related topic is automatic size setting. In CSS it's handled with Now LVGL doesn't store the set width and height just modifies the coordinates. So if the coordinates change again this information is lost. It's important because if I'm thinking about making possible to set width/height in the percentage of the parent. If it's reasonable shall we set it dynamically? (save the percentage and apply again if the parent's size changes)
What do you think? |
Could you provide use-cases you need to support? I guess, it's the grid with single row and multiple cells? Sometime this can be done via macros, without flexbox at all. If you support combinaion of (parent:position:relaive + child:position:absolute). In general, full flexbox & grid seems too much for lvgl. But i can not say right now how much to cut. Full set of desired use cases needed.
That's ugly thing, and impossible for height a all. I know 2 use cases:
(1) without flexbox may be horrible. (2) is specific, i don't think needed for lvgl.
Those are needed, but only if real display size changes and may become too big (~ if you resize browser window).
I agree. It's always good idea to remember where LVGL is effective. I'd say "where QT can not be used". This can give ideas about used hardware. Also, you have "free" additional abstraction layer, not available in CSS - macros. Consider try to create a set of macros to calculate coords. For example, instead of width in % you could calculate absolute coords of each column. |
Sure there are many examples where sizing to the content comes in handy:
Using flexbox only (no grid) seems suitable but I also don't know now which options to drop yet.
If there is a parent with a fixed height you can create a child with 50% parent height.
Do you mean to use e.g.
|
Nobody use flexbox for that. That's an ordinary https://getbootstrap.com/ - please investigate docs, there are lot of examples.
If there is parent with fixed height, i can create child with fixed height :). You described feature, but not use case. Where is this needed in real world?
Everything required should be used as param. |
It seemed it was a reflection to "Maybe instead of display: block/inline display: flex is enough with support to flex-basis:auto, height:auto, width:auto." That's why I described use cases for
True, but if the parent height changes you need to change children's height manually. Or if the styles change the size has to be updated too.
Yes, I know, width set/get uses the content area without padding and margin. It's quite counterintuitive to me. If there are some padding and margin it's really difficult to create two 50-50% columns next to each other. |
I believe this is what |
Oh really, I forgot that. Once supporting one, supporting the other too shouldn't be too complicated. |
It might be more efficient and take less time to only support |
That's very primitive and inaccurate explanation. Only to show those modes can not replace each other.
This splits to 2 cases:
Yes, box-sizing is outdated and not needed. |
I think the gist is to find out something smart for this. Here is my view to have something concrete to discuss. I don't say it's perfect as it is so please tell your opinion. Element sizeUse:
The set Set element positionI think
Similarly to MarginTo allow flushing element to the right/bottom use Layout.Every element has flex-box enabled by deafult with
Not obvious to store it as style or object property. IMO we should make a property related to styles if
E.g. padding, colors, border width, etc are typical style properties. Size, position, list of options, label text, min-max range, current value, etc are typical object properties. Following this, I think the layout is rather an object property because probably the developer wants to set it on a per-object basis. E.g. "I want this layout on this box and other here".
There are some discussions about "Why there is no The usual answer is that it doesn't work with margin collapse. (I'm not sure we need margin collapse in LVGL though) |
Layout It's not inherited so there's no functional difference between making it an object property or a style property. I'd say it's up to you.
Can you give a specific example? I'm pretty sure with flexbox you can use margins without problems. |
I don't understand discussion point. What is the goal?
I think product development is not right place to demonstrate acrobatics skills :). It's not rational to spend time for implementing all features. Rational is to implement minimal set, allowing well known programming patterns. |
Tell if you agree or disagree with this direction. :)
Yes, it works well and easily in flexbox but not in "manual placement". If you set We can say to use layout for this case though. So I don't insist on |
I would agree in advance with direction to implement subset of CSS without deviation (except some defaults like
Just don't do so :). If someone design sibbling for embed, it would be not clever to hardcode outer margins. There is no magical way to combine anything ugly into something perfect. |
Okay, according to this my summary above is not that bad. |
Do you have an idea what's going on here?https://codepen.io/kisvegabor/pen/XWXGaMO But if I set one child's height manually to 100px the siblings in the same row will have 115px calculated height. |
I guess, it calculates every line height first, then expand proportionally. Without that special cell, initial state is:
=> 100 each. But
=> ... That's only my quick-guess. Should be verified in w3c specs. |
It may be related to cross-axis alignment as well ( |
@puzrin That makes sens, thank you! @embeddedt I've already learned that but didn't understand how it stretches. |
Note, flexbox is cool thing, but not mandatory in many cases. If it increase code size significantly, consider option to disable it. For many simple interfaces |
True, it should be optional. With |
I believe grid layouts might be a better option than flex box for embedded devices. Grid allows not only the dynamic resizing but also dynamic rearranging of the layout components. This comes in handy when turning your device and switching from a horizontal to vertical layout. You may want certain parts of your UI to change the location altogether instead of changing their size or just wrapping to the next line. You could for instance have the menu stretch across the top in horizontal mode or go down the side in vertical mode. I see it being very useful for a dashboard app where you might have many small components that are not the same height as your menu. This is a great talk demonstrating how useful grid layouts are. |
@excitedbox When I've checked it I found it a little bit complicated to implement due to the flexible references of areas and naming of rows/columns. However, if implement only a carefully chosen subset it might work. I used this poster to see the summary of features This my initial view about the required, not sure, and not required features: Required
Not sure
Not required
What do you think? |
Convenient thing, but if not supported, can be done via duplicaed blocks and visibility switch. Not a big deal. @kisvegabor i'd suggest to postpone everything if it's not breaking / blocking. Sorry, have no practice with grids. |
I think the goal is to avoid duplication. Finally, everything can be done without layouts if user calculates the position of the objects himself. BTW, the "grid" can work very well with |
No. From my point of view, that's not a problem at all. My goal is to not rewrie app everytime when lvgl inroduces next bunch of breaking changes.
Such generic statement can not be used for any conclusion. If you need decision about feature value, estimate list of use cases and their weighs. For example, there are lot of cases for flexbox, and it can not be emulated well via more simple styles. Grid is not so critical, IMO, and will be not a breaking change if postponed. |
This is not necessarily representative of an embedded app, but in all the web projects I've worked on thus far, I've never used CSS grid. I've only used flexbox and the classic block layout. |
To see the advantages/disadvantages lets see an example UI: The right (light) UI can be created with one large grid without any transparent wrapper elements. On the left UI the list elements with an image and 3 labels are interesting. They are also a single grid. With flexbox both cases would require a lot of wrapper I was missing one thing from grid: the ability to automatically wrap elements as flexbox does. But it turned out it is supported like this: https://codepen.io/Weldebob/pen/WjMLav What do you think? |
can != should. Usually each component of web-page should be self-sufficient (including inner layout & css). Or you will have problems with modificaions. Of cause, nobody can prohibit you create monolytic solutions, but that's not good argument for consideration. As i said, i see no reasons to discuss technical aspects of grid. I'll be ok both with and without grid (i don't decline to use it). The only critical thing for me is to include to v8.x all big breaking things. Text nodes and RGBA in styles still have floating satus - seems more significant (in scope of api stability). |
Good point.
In case of embedded design, I see higher value in saving some containers (100-150 byte each) than loosing a little on flexibility. Anyway, if flexibility is preferred you are free to create more containers for local layouts.
Actually that's the gist. Adding flexbox now and grid beside it later (or vice-versa) is certainly a wrong direction. LVGL is too small to have 2 very similar and large features in it. So we have to choose one to live with for a (hopefully) long time. I'm getting closer to choose grid because (in our case) it knows what flexbox knows and more. But we don't have to decide now. Let some days for remarks to come. |
To be honest, i don't beleive in arguments about savings in phase of architecture design. From my experience - if you have good modular architecture, it can be optimized later effectively. Premature optimizations cause tight-coupling of data/code, and become a problem very soon. For example, if memory problem is with long list - you can provide explicit custom solution for list.
I have a bit different view. Flexbox is minimal (mandatory) requirement to express "everything". Grid is really nice, but not mandatory, if flexbox available. In scope of "restriced human resources", priorities are shifted from "what can be done" to "what can't be avoided".
I can not estimate cost of grid implementation, because it's not trivial thing (much more complicated than flexbox). But if you are sure - i'm ok to use grid instead of flexbox. It's your time, and if you have fun with grid implementation - no problem. At first glance, if you will be able to implement full-featured grid - it will possible cut it to "flexbox mode" to save flash [if needed]. |
One more checkpoint. It was no mentioned in this topic, but |
However, I faced a problem when mouse cursor caused overflow (i.e. made scrollbars appear) when it was in the bottom-most position and its bottom part was out of the screen. So some setting is required to "let objects live their own life" regarding causing overflow at least. I don't know which HTML property can be used for this yet. I was thinking a lot about grid. I found it very useful to create fixed flat layouts (like the music player I shown above. It's a clear advantage over flexbox. However, explicitly placing some objects and let others flow automatically is quite complicated to handle. So I came up with a simplification. Do not mix "fix grid" and "dynamic grid". The idea is if In the other case, Something like It misses one thing which can be done with flexbox: "flow" elements with different sizes with wrapping. It would be no like a grid after all. However, I can't imagine any use cases from the embedded UI world where it would be required. What do you think about this approach? |
screen =
I don't suggest to drop screens immediately. But in he same time, i don't understand the problem. Top-level parent (virtual or real) should always exist. It's size will be equal to display size. If you don't plan to display object on 2 displays simultaniously - i see no collisions.
My question is, can we do it more close to HTML/CSS, without enforsed top screen layer (user can do it by hand, if needed).
AFAIK, cursor is not is not part of DOM an not part of layout. This should be considered separate (and that's about draw, not layout). In html there are no way to "let objects live their own life" exactly. But this can be done with I did not dived into grid spec, can't comment. The only note - it looks "too much" for sticky header/footer. You tend to invent complicated monolytic silver bullet instead of independent/optional things. Miracles not exist, i've checked :) |
I have been a web dev for close to 20 years at this point so I have lived through everything from the Tables, Divs, Floats and Layers to the modern flexbox and grid layouts. Grid layouts really are the best option available for dynamic layouts. Flexbox is great if all your components have the same dimensions but everything is arranged in either rows or columns so as soon as you have 1 tall element next to 2 short elements you need to use a container. Grid layout splits your view port into a grid and elements are aligned by arranging them on that grid. I think it might even be easier to implement than flexbox because you only define a starting grid and ending grid space for each item on that grid which should be easy to calculate. If you divide the screen in the number of grid spaces you could align elements by specifying which grid they should start in and allow them to overflow the edges in either vertical or horizontal direction as if they were on another layer. This gives them as much space as they need or you define a starting grid AND ending grid space to limit how big the item is. Then you specify break points to switch to another layout. So for instance Draw Button starting in grid 1 if the screen is horizontal or draw it starting in grid 5 if it is vertical. This could be done just by adding a single rule for each item based on horizontal or vertical orientation. There would also be the possibility for other rules such as how much space there is for the element to consume using the remaining fraction of the screen This link will show you how simple it is to define grid layouts and the flexibility they allow. Since you already have pixel positioning for elements you just need to transform grid square values into the pixel values based on the height and width of the spaces. I was thinking the current layout style definitions should be made to be more like CSS by allowing the use of shorter keywords instead of a long rule name as it is right now (lv_style_set_radius would become radius for instance) this could be done with very basic parsing rules since there would be so little variance unlike in web design where HTML, CSS, JS etc. all co exist. This would make it quicker and easier to define styles and also allow quicker changing of styles. This would even make it easier to build additional tools such as a style generator for a wysiwyg editor down the road. |
Grid is like using pixel positioning with reduced number of pixels. So overflow spills onto the next grid space if there is no end row or column defined. This is also what makes masonry layouts possible. By drawing the grid on it's own layer you can draw the grid to be smaller than an element and one element can cover 4x4 grid spaces while another only covers 2x2 spaces with 2 2x1 elements below it. For flex box you would need 2 containers (4x4 and 4x2) and another 2 containers (2x2 and 2x2) stacked on top of each other in the right one and another 2 containers for the 2 small elements. So the grid layout would eliminate 2 out of 6 containers. Cursor does not belong to the grid and the only time you really need to worry about overflow with a grid is if a drop down or something that pops up goes off the screen in which case the best option is to start drawing at the screen edge - the width/height of the drop down or pop up. In our case the grid is not really drawn or even used beyond as a divisor to make positioning easier. It is used to calculate a pixel value and set rules for how the pixel value should change based on dimensions or orientation. In reality the number of containers etc doesn't matter for Lvgl as long as you use pixel positioning instead of implementing a full DOM. You just need to calculate the pixel position for where to draw a widget. With a grid layout system that becomes very easy since if the screen is 600x400 and you divide it into a 12x8 grid each space is 50 pixels so an element starting in grid 1,4 would have a starting position of 400px horizontal and 0px vertical while 4,4 is 400 horizontal and 200 vertical. It is just row or column -1 times the grid space dimensions. So an element would have a start and end coordinate that gets multiplied by the space dimensions and to calculate the size of the element you subtract the difference of the start and end position in pixels. |
To summarize my 2 posts. https://css-tricks.com/wp-content/uploads/2018/11/dddgrid-template-areas.svg I propose:
example:
These are just to show what it could look like and property values are not meant to be exact Benefits are that everything is in 1 place, simple to configure, easy to learn, easy to update, flexible, less typing and fewer style rules to remember. It should only require minimal amounts of code to implement a parser and integrate into the current system. Positions are easy to calculate as long as screen dimensions are known. |
@excitedbox You may be interested in https://github.com/embeddedt/lv_css. I'm planning to extend it with layout support once the spec gets finalized. |
Wow that is exactly what I had in mind 💯 :D |
The next thing I need to add to it is support for object type selectors, as opposed to just classes. That will enable people to quickly and easily create custom themes. I'm not planning to support the combined versions of properties (e.g. Once that's done, all that's left to do is make a proper CLI for it and add a watch mode so it can be integrated with any build system. |
@embeddedt Do you have plans to generate Micropython code as well? |
@embeddedt
I was also thinking about compile-time calculation in some form but found these problems:
In this comment, I summarized my view about "fix" and "dynamic" grid. According to this what you described is the "fix grid". However, we also need to layout an unknown number of elements. |
I was planning to mention it once it was more polished. It was initially a quick experiment but I think it'll be a pretty useful tool. I decided to link to it now because of @excitedbox's comment.
I can add that as well; it should only require changing the output syntax. |
Have you seen this library? It is a pretty cool demo of a resizing stacking box layout. I haven't looked at how it is done but thought maybe you would be interested for inspiration. |
This is something I would like to try out,after flexbox implementation is complete. For javascript binding jerryscript can be used as it supports a variety of embedded OS. But first of all a lightweight HTML parser will be required . Any suggestions regarding this? @embeddedt Any other aspect I am missing out?(Asking you since you are also a web developer -saw from your github profile) |
@excitedbox had previously mentioned this library in a forum post. I haven't experimented with it but it does have an HTML parser. Maybe that would be useful. |
I needed a lightweight webview which could write to framebuffer. Netsurf exactly fits my requirement and so I have abandoned my above plan. |
I think all were discussed related to the new layouts so I close this issue. Thank you very much for sharing your ideas. |
Maybe you can take some inspiration from Yoga, the layout engine used by React Native: https://yogalayout.com/ |
@nickdima As a matter of fact, we did end up implementing flexbox as one of our layout options. |
Continue from #1539
As it was discussed in the mentioned issue, it'd be great if the layouts would be supported by
lv_obj
directly a work similarly to flexbox in CSS.Let's discuss the issues and related ideas here.
The text was updated successfully, but these errors were encountered: