2024-04-23 23:11:18 +03:00
|
|
|
@tool
|
|
|
|
extends Container3D
|
|
|
|
class_name FlexContainer3D
|
|
|
|
|
|
|
|
enum Justification {
|
|
|
|
START,
|
|
|
|
CENTER,
|
|
|
|
END,
|
|
|
|
SPACE_BETWEEN,
|
|
|
|
SPACE_AROUND,
|
|
|
|
SPACE_EVENLY,
|
|
|
|
}
|
|
|
|
|
|
|
|
@export var justification: Justification = Justification.START:
|
|
|
|
set(value):
|
|
|
|
justification = value
|
|
|
|
_update()
|
|
|
|
@export var vertical: bool = false:
|
|
|
|
set(value):
|
|
|
|
vertical = value
|
|
|
|
_update()
|
|
|
|
@export var gap: float = 0.0:
|
|
|
|
set(value):
|
|
|
|
gap = value
|
|
|
|
_update()
|
|
|
|
|
|
|
|
func _ready():
|
|
|
|
_update()
|
|
|
|
|
|
|
|
func _update():
|
|
|
|
var width = size.y if vertical else size.x
|
2024-04-25 14:19:12 +03:00
|
|
|
var children_size := Vector2(0, 0)
|
2024-04-23 23:11:18 +03:00
|
|
|
var child_count = 0
|
|
|
|
|
|
|
|
for child in get_children():
|
|
|
|
if child is Container3D == false:
|
|
|
|
continue
|
|
|
|
|
|
|
|
if vertical:
|
2024-04-25 14:19:12 +03:00
|
|
|
children_size.x = max(child.size.x, children_size.x)
|
|
|
|
children_size.y += child.size.y + gap
|
2024-04-23 23:11:18 +03:00
|
|
|
else:
|
2024-04-25 14:19:12 +03:00
|
|
|
children_size.x += child.size.x + gap
|
|
|
|
children_size.y = max(child.size.y, children_size.y)
|
2024-04-23 23:11:18 +03:00
|
|
|
|
|
|
|
child_count += 1
|
|
|
|
|
|
|
|
if child_count == 0:
|
|
|
|
return
|
|
|
|
|
2024-04-25 14:19:12 +03:00
|
|
|
var children_scale = Vector2(size.x, size.y) / children_size
|
|
|
|
children_size.clamp(Vector2(0, 0), Vector2(size.x, size.y))
|
2024-04-23 23:11:18 +03:00
|
|
|
|
2024-04-25 14:19:12 +03:00
|
|
|
children_scale = children_scale.clamp(Vector2(0.001, 0.001), Vector2(1, 1))
|
2024-04-23 23:11:18 +03:00
|
|
|
|
|
|
|
var offset = 0.0
|
|
|
|
|
2024-04-25 14:19:12 +03:00
|
|
|
var children_width = children_size.y if vertical else children_size.x
|
|
|
|
|
2024-04-23 23:11:18 +03:00
|
|
|
match justification:
|
|
|
|
Justification.START:
|
|
|
|
offset = 0.0
|
|
|
|
Justification.CENTER:
|
2024-04-25 14:19:12 +03:00
|
|
|
offset = (width - children_width) / 2.0
|
2024-04-23 23:11:18 +03:00
|
|
|
Justification.END:
|
2024-04-25 14:19:12 +03:00
|
|
|
offset = width - children_width
|
2024-04-23 23:11:18 +03:00
|
|
|
Justification.SPACE_BETWEEN:
|
|
|
|
offset = 0.0
|
|
|
|
Justification.SPACE_AROUND:
|
2024-04-25 14:19:12 +03:00
|
|
|
offset = (width - children_width) / child_count / 2.0
|
2024-04-23 23:11:18 +03:00
|
|
|
Justification.SPACE_EVENLY:
|
2024-04-25 14:19:12 +03:00
|
|
|
offset = (width - children_width) / (child_count + 1)
|
2024-04-23 23:11:18 +03:00
|
|
|
|
|
|
|
for child in get_children():
|
|
|
|
if child is Container3D == false:
|
|
|
|
continue
|
|
|
|
|
2024-04-25 14:19:12 +03:00
|
|
|
child.scale = Vector3(children_scale.x, children_scale.y, 1)
|
2024-04-23 23:11:18 +03:00
|
|
|
|
|
|
|
if vertical:
|
2024-04-25 14:19:12 +03:00
|
|
|
var child_width = child.size.y * children_scale.y
|
|
|
|
|
|
|
|
child.position = Vector3(0, -offset - child_width / 2.0, 0)
|
|
|
|
offset += child.size.y * children_scale.y
|
2024-04-23 23:11:18 +03:00
|
|
|
else:
|
2024-04-25 14:19:12 +03:00
|
|
|
var child_width = child.size.x * children_scale.x
|
|
|
|
|
|
|
|
child.position = Vector3(offset + child_width / 2.0, 0, 0)
|
|
|
|
offset += child.size.x * children_scale.x
|
2024-04-23 23:11:18 +03:00
|
|
|
|
|
|
|
match justification:
|
|
|
|
Justification.START, Justification.CENTER, Justification.END:
|
|
|
|
offset += gap
|
|
|
|
Justification.SPACE_BETWEEN:
|
2024-04-25 14:19:12 +03:00
|
|
|
offset += (width - children_width) / (child_count - 1)
|
2024-04-23 23:11:18 +03:00
|
|
|
Justification.SPACE_AROUND:
|
2024-04-25 14:19:12 +03:00
|
|
|
offset += (width - children_width) / child_count
|
2024-04-23 23:11:18 +03:00
|
|
|
Justification.SPACE_EVENLY:
|
2024-04-25 14:19:12 +03:00
|
|
|
offset += (width - children_width) / (child_count + 1)
|
2024-04-23 23:11:18 +03:00
|
|
|
|