|interface Efl.Gfx.Arrangement @beta |├ (P) content_align |├ (P) content_padding
Description
Details
Status | Assigned | Task | ||
---|---|---|---|---|
Resolved | bu5hm4n | T8096 efl.ui.collection | ||
Resolved | None | T7870 efl.ui.grid | ||
Resolved | None | T7881 efl.ui.list | ||
Resolved | None | T7859 efl.ui.box | ||
Resolved | None | T7899 efl.ui.table | ||
Resolved | None | T7864 efl.gfx.arrangement |
I do not understand how content_align is supposed to work. When playing with Efl.Ui.Box I see no difference between setting it or the align hint on the box. Any help?
From what I read, that should align the box itself inside its allocated space. Isn't that what Efl.Gfx.Hint.hint_align does?
Right now I don't see the point in having content_align inside Efl.Gfx.Arrangement :/
No, it's a little different. For example, suppose there isn't enough space allocated to the box on the canvas. Using this API, you can specify which part of the box is visible. The alt+tab/winlist component in enlightenment uses the API for this purpose.
Wow, that's an unexpected turn. So alignment works both when there's room to spare and when there's not enough room to fit a widget. Got it.
But still, can't this alignment (when there's not enough room) be controlled through Efl.Gfx.Hint.hint_align instead of Efl.Gfx.Arrangement.content_align?
content_align is used in efl_ui_container_layout.c:126 // pack align is used if "no item has a weight" and _efl_ui_container_layout_init is called by _efl_ui_box_custom_layout in efl_ui_box_layout.c.
Efl.Gfx.Hint.align is box widget align that used by parent container(box).
When box is vertical mode, x-axis content_align is ignored. x-axis content_align is controlled by children's x-axis hint_align.
Example code is here.
/* * gcc -o efl_ui_box_example efl_ui_box_example.c `pkg-config --cflags --libs elementary` */ #define EFL_BETA_API_SUPPORT 1 #define EFL_UI_WIDGET_PROTECTED #include <Efl_Ui.h> #include <Elementary.h> EAPI_MAIN void efl_main(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED) { Eo *win, *box[4], *bg[4]; int i; win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(), efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_BASIC), efl_text_set(efl_added, "Efl.Ui.Box example"), efl_ui_win_autodel_set(efl_added, EINA_TRUE) ); for (i = 0; i < 4; i++) { box[i] = efl_add(EFL_UI_BOX_CLASS, win); efl_gfx_hint_fill_set(box[i], EINA_FALSE, EINA_FALSE); efl_gfx_hint_weight_set(box[i], 0.0, 0.0); } efl_content_set(win, box[0]); // set size_min efl_gfx_hint_size_min_set(box[0], EINA_SIZE2D(400 , 400)); efl_gfx_hint_size_min_set(box[1], EINA_SIZE2D(150 , 150)); efl_gfx_hint_size_min_set(box[2], EINA_SIZE2D(150 , 150)); efl_gfx_hint_size_min_set(box[3], EINA_SIZE2D(50 , 50)); // set color efl_gfx_color_set(efl_part(box[0], "background"), 255, 255, 255, 255); efl_gfx_color_set(efl_part(box[1], "background"), 0, 255, 0, 255); efl_gfx_color_set(efl_part(box[2], "background"), 0, 0, 255, 255); efl_gfx_color_set(efl_part(box[3], "background"), 0, 255, 255, 255); // pack box efl_pack(box[0], box[1]); efl_pack(box[0], box[2]); efl_pack(box[1], box[3]); // set direction and align /* box[0] have box[1] and box[2]. only y-axis content_align will work. x-axis align is responsible for children's hint_align. */ efl_ui_layout_orientation_set(box[0], EFL_UI_LAYOUT_ORIENTATION_VERTICAL); // it is default value. efl_gfx_arrangement_content_align_set(box[0], 0.2/*it is ignored because orientation is VERTICAL*/, 0.7); efl_gfx_hint_align_set(box[1], 0.7, 0.0/*it is ignored because there is no space(0-weight)*/); efl_gfx_hint_align_set(box[2], 0.2, 0.2/*it is ignored because there is no space(0-weight)*/); // efl_gfx_hint_weight_set(box[2], 1.0, 1.0); y-axis hint_align of box[2] will work with this code. /* box[1] have box[3]. only x-axis content_align will work. y-axis align is responsible for children's hint_align. */ efl_ui_layout_orientation_set(box[1], EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL); efl_gfx_arrangement_content_align_set(box[1], 0.2, 0.7/*ignored*/); efl_gfx_hint_align_set(box[3], 0.7/*ignored*/, 0.9); efl_gfx_entity_size_set(win, EINA_SIZE2D(400, 400)); } EFL_MAIN()
Result
@YOhoho Thank you very much for this very detailed explanation. Now I understand how it works.
This looks very complicated, but I guess finding a simpler mechanism would require some time.
This definitely needs a tutorial, and it is not going to be pretty.
This is a bit hard to describe, but I think the existing API is fine. The issue, however, is the name. The properties are named content_* but the namespace is Arrangement; this seems strange?
Maybe we want something like Efl.Gfx.Content_Layout? Needs brainstorming.
We already spent some time looking for a name to describe "a collection of things uniformly spaced inside another thing"... and this was the best we came up with.
Maybe a second round (and fresh eyes) help.
My issue is solely with the reuse of content here since we have a whole Efl.Content namespace which this does not appear to directly be related to in its own namespace, yet does seem to have some relation to in function.
Big problem (imo):
this interface has content_padding:
values { pad_horiz: double; [[Horizontal padding]] pad_vert: double; [[Vertical padding]] scalable: bool; [[$true if scalable, $false otherwise]] }
efl.gfx.hint has hint_margin, which is identical in terms of functionality, but it has:
values { l: int; [[Integer to specify left padding.]] r: int; [[Integer to specify right padding.]] t: int; [[Integer to specify top padding.]] b: int; [[Integer to specify bottom padding.]] }
These property names should be the same and they should have the same values.
Hmmm... yeah, that's pretty inconsistent.
So we should rename content_padding to content_margin and move it from two doubles to 4 ints?
It wasn't clear anyway what those two doubles meant.. fractional pixels?
Alright, after sleeping on this again, I think we can actually ignore that: these mechanisms function fundamentally differently. margin is applied to an object always. content_padding appears to be the same on the surface, but really this is a uniform size that's applied to all sub-objects of a container; it wouldn't make much sense to have an inset-style property for this, you're only trying to set the space between the content objects.
This needs some clarifying in docs to explain it a little more clearly at the conceptual level I think.
What would you add to the docs for content_padding?
[[This property determines the space between a container's content items. It is different than the @Efl.Gfx.Hint.hint_margin property in that it is applied to each content item within the container instead of a single item. The calculation for these two properties is cumulative. See also @Efl.Gfx.Hint.hint_margin. ]]
I'm not sure? I just feel like if I put myself in the mind of a clueless new developer then there's some nuance missing in that explanation.
Hahaha, OK, I found what is missing. The fricking units. Is it pixels? Why is it a double, then?
This would also need diagrams, for sure.
And there's an Elementary positioning tutorial pending.
I can neither confirm nor deny this, but I can say that all existing implementations and usages of this property are currently using pixels.
I have no idea of scalable value and double type history. The first commit is 57e64ee65b6ae35107f40ca155e2fb318a0082f6.
I think it is better to use int type (or Eina.Size2D) without scalable for consistency.
I spoke with @jpeg and he seemed to think that there were cases where users would want to enable/disable scaling of padding between items? This is just his opinion from when he wrote it, however.
We should clarify what behavior we need/want here. I think at minimum we can change double, though I am not sure if we want Eina.Size2D since this is not technically a size, it is a border...
We also need to determine whether we want the values to scale or not, or if there is a need to have this configurable on a per-object basis.
@YOhoho If you want to change this property to just be 2x uint params (and remove scalable) I think that would help. I started working on it a little last week, but I'm currently trying to resolve theme API stuff. P324 has the wip patch, though it's not much...
marking content_padding beta for now since we haven't gotten a definite idea about the needs/uses for this
I'm still not sold on this name. I haven't gotten definite feedback that this is required immediately either, so I think this can stay beta.
Alright, so we've now got content_padding that has 2x uint params (thanks @YOhoho!).
The only thing that I'm still not keen on is the name. I'm wondering if maybe changing the properties from content_ prefixing to something else might solve this for me, but at the same time "arrangement" is super long for an API namespace...
If there is no better alternative names for "content_" prefix and "arrangement",
I think we can go with current definitions.
How do you think about this ?
This has been stopped for more than a month and we didn't come up with a better name.
Plus, the only person against "arrangement" is Mike who won't be available for another month...
So yes, I also think we should use the current names.
Ok ~ If there would be no more feedback in a day ~ I'll move this task to "stabilized".
I was hoping we'd get a better name, but we haven't, so I don't see a reason to keep holding out on one.