Repository: godot
Issue: ItemList has clipped items, unwanted extra spacing and inconsistent handling of mouse clicks depending on spacing parameters
Labels: bug,topic:input,topic:gui

### Tested versions

- Reproducible in 4.3 dev [4e990cd7e5]
- Reproducible in 4.2.1 stable
- Found the issue in 3.0 branch too

### System information

Godot v4.2.1.stable - Ubuntu 22.04.3 LTS 22.04 - X11 - Vulkan (Mobile) - integrated Intel(R) Iris(R) Plus Graphics (ICL GT2) () - Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz (8 Threads)

### Issue description

Depending on the constants set to adjust items spacing on the ItemList control, there are quirks in the rendering and pointer event handling that cause:

- Inconsistency between the area used to detect mouse events on each item, and the draw area of the selection rectangle.
- Unwanted extra spacing at the bottom, or the first/last item hover/selection graphic being clipped off
- Actual spacing is double the value set in pixels on the corresponding property

I have played a bit, had a look in the source code and attempted to describe how it works. Those are quite a bunch of issues grouped together, for the reason that the root cause is the item positioning algorithm. Below is how it looks when the vertical spacing is set to 10px.

![image](https://github.com/godotengine/godot/assets/26961646/278d7bd1-74cd-4e70-8cba-945dfbc37470)

**Mouse events inconsistency**

The mouse detection area for each item is smaller than the perceived selection rectangle. If horizontal (for multiple columns) or vertical spacing is more than zero, all items appear to be touching each other, due to the way the selection / hover rectangle is rendered, but there is a gap between items where clicks do not have any effects. (also reported on #88095)

From the drawing above, the green (B) rectangle on each item is the mouse events target.
The blue (C) rectangle is where the selection/hover background is drawn on the corresponding item.

**Measurement inconsistency**

In the above example, vertical spacing is set to 10px, but the result is 20px more vertical space in comparison to when the same spacing is set to 0. The algorithm ends up adding twice the desired spacing.

**Extra spacing at the bottom**

![image](https://github.com/godotengine/godot/assets/26961646/a59f2b06-9a65-4407-af82-b478041bdcb7)

In this example, the more vertical spacing between items, the larger the gap at the bottom of the list when fully scrolled at the end. Only applies to single-columns lists with scrolling. No issue if vertical spacing is zero.

The extra spacing appears to be half the vertical spacing value, and behaves like being the vertical spacing value regarding mouse events.

**Cut-off selection rectangle at the top of single-column list**

![image](https://github.com/godotengine/godot/assets/26961646/bd67a005-7a31-4897-a24b-bf65925c862c)

The first item has its selection rectangle cut-off. It is even more visible with larger values for vertical spacing. No cutoff occurs if spacing is 0. This is due to a compensation by the algorithm to attempt having some visual consistency with the baseline of the first row text.

**Cut-off selection rectangle on all sides of multiple column lists**

![image](https://github.com/godotengine/godot/assets/26961646/6e27f759-f91c-43f1-aa4c-2868213128f1)

![image](https://github.com/godotengine/godot/assets/26961646/3366095f-d6da-4c7a-bf8d-f145d6ae65f6)

The cutoff effect of the selection rectangle is visible at both the top and bottom of the list when set to multiple columns with icons. Note that the rounding of the corner is missing to notice the cutoff.
Leftmost example has no spacing.

**Icon margin setting causes text to appear outside the item rectangle**

![image](https://github.com/godotengine/godot/assets/26961646/bed09e7c-bd47-4eff-902a-71035f9e58cf)

![image](https://github.com/godotengine/godot/assets/26961646/7f0ec76b-d340-43a0-892c-eac7409d1255)

On the second screenshot, we can see how the previous row text is hidden by the selection. Also notice that the text is clipped beyond the last row.
Leftmost example has no spacing.

**Refactoring proposal**

Due to the presence of multiple issues related by the positioning algorithm, I have a proposal to reimplement the rendering of those items and solve all those bugs at once. I have a nearly working prototype. Needs some discussion as it may cause some little breaking changes.

https://github.com/godotengine/godot-proposals/issues/9076

### Steps to reproduce

Open the reproduction project and run the scene. You can play with the window size; layout is anchored to it.

Select items in the different lists to view the issues with spacing and some cut-off elements.

### Minimal reproduction project (MRP)

[itemlist-issue.zip](https://github.com/godotengine/godot/files/14233922/itemlist-issue.zip)