godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.08k stars 69 forks source link

(DRAFT) Refactor ItemList item layout algorithm to solve multiple rendering quirks #9076

Open davthedev opened 5 months ago

davthedev commented 5 months ago

Describe the project you are working on

A GUI for a game that uses lists to access a database of contents. Also stumbled upon bugs that happen in the editor related to the ItemList control.

Describe the problem or limitation you are having in your project

There are various bugs I noticed with ItemList. Among those:

Quirks

See this bug for a detail of the problems and visual explanations.

Limitations of customizability, related to my project

I have started working on a solution to fix those problems all at once. As I progressed on it, I realized that it involves more than just fixing the bugs, may cause a breaking change in the API because it introduces new properties. This is why I make an actual proposal to open up the discussion.

There are quite a lot of ideas. Feel free to mention if it would be better to split this up.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

The ItemList control renders its items, calculates sizes for each one and computes the total length of scrollable area using a set algorithm. By adjusting this algorithm, the issues listed in the mentioned bug report are solved all at once.

Some new theme properties are added to control the new aspects after refactoring.

In addition, while there is a refactoring taking place and some breaking changes are introduced, there are proposed new properties related to the customization I would like to achieve. The idea is to minimize the number of disruptions in project codebases.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

The layout algorithm is replaced by a new one, more aligned with how it is done in other GUI frameworks and HTML/CSS. I took inspiration from the Android ListView at least for the single-column version.

image

The concept can be extrapolated to the multiple columns / grid rendering as well.

Evolution of theme attributes to fix the layout

Horizontal spacing and vertical spacing are repurposed to govern the actual spacing i.e. gap between items. The gap is not sensitive to any mouse events and the selector is not drawn on top of it.

New padding values are introduced. Those govern the amount of pixels the items have of extra space on each side - totaling of four properties (left, right, top, bottom). Optionally, can consider the content offset of the StyleBox used to render the rectangle of the item in its current state. For now, there is no consideration of the StyleBox content offset.

The introduction of a separate padding from the spacing is necessary because the current algorithm does something in-between: it considers the current separation value to be what would be the padding in my solution and doubles it, and draws the separator over the item (aligned at the bottom) instead of between two adjacent items.

New theme attributes for extra customization

(Draft in progress, pictures will come soon)

A new StyleBox for the separator, and a separator size value. The current separator color attribute is removed. Can be emulated by passing a StyleBoxRect / StyleBoxLine and setting the separator size to 1px.

New values for separator overlap, in case we want to allow a slight overlap of the separator graphic with the area of neighboring items. Would be two values (top and bottom), positive values increase the separator thickness towards the next/previous item and negative ones shrink it.

A new StyleBox to render the "idle" items and draw those in individual boxes. Not mandatory, would default to a StyleBoxEmpty to keep the current aspect (relates to #8881)

The "icon on left/icon on top" attribute is expanded to support right and bottom.

A new attribute is added to set text alignment (left / center / right).

If this enhancement will not be used often, can it be worked around with a few lines of script?

Requires implementation of a pseudo-ItemList by hand in projects using a scroll container, can be less optimized when there are a lot of items as it instantiates as many children nodes whereas the ItemList only draws the items on the canvas. And does not solve related issues to it as it is used in the Godot editor itself.

Is there a reason why this should be core and not an add-on in the asset library?

ItemList is a core widget, and it affects the editor

Shadowblitz16 commented 2 months ago

Any UI improvements are good in my book.

Calinou commented 2 months ago

@Shadowblitz16 Please don't bump issues without contributing significant new information. Use the :+1: reaction button on the first post instead.