Panel adaptable

Seis tarjetas en una rejilla que pasa de tres columnas a dos cuando la viewport se estrecha.

El editor de arriba está ejecutando este proyecto. Cambia una línea y se recarga.

Clases de Godot usadas

GridContainerPanelContainerMarginContainer

El código

scripts/main.gd
extends Node

const NARROW: float = 900.0

var grid: GridContainer
var size_label: Label


func _ready() -> void:
	var background: ColorRect = ColorRect.new()
	background.color = Color('#12141a')
	add_child(background)
	background.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)

	var margin: MarginContainer = MarginContainer.new()

	for side in ['margin_left', 'margin_right', 'margin_top', 'margin_bottom']:
		margin.add_theme_constant_override(side, 32)

	add_child(margin)
	margin.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)

	var column: VBoxContainer = VBoxContainer.new()
	column.add_theme_constant_override('separation', 18)
	margin.add_child(column)

	var header: HBoxContainer = HBoxContainer.new()
	column.add_child(header)

	var title: Label = Label.new()
	title.text = 'Dashboard'
	title.add_theme_font_size_override('font_size', 28)
	title.size_flags_horizontal = Control.SIZE_EXPAND_FILL
	header.add_child(title)

	size_label = Label.new()
	size_label.add_theme_color_override('font_color', Color('#999999'))
	header.add_child(size_label)

	grid = GridContainer.new()
	grid.columns = 3
	grid.add_theme_constant_override('h_separation', 18)
	grid.add_theme_constant_override('v_separation', 18)
	grid.size_flags_vertical = Control.SIZE_EXPAND_FILL
	column.add_child(grid)

	for entry in [
		{title = 'sessions', value = '1,284', color = '#8da5f3'},
		{title = 'projects', value = '312', color = '#8eef97'},
		{title = 'shaders', value = '87', color = '#fc7f7f'},
		{title = 'errors', value = '4', color = '#f3d48d'},
		{title = 'uptime', value = '99.9%', color = '#8da5f3'},
		{title = 'builds', value = '46', color = '#8eef97'},
	]:
		grid.add_child(_card(entry))

	get_viewport().size_changed.connect(_reflow)
	_reflow()

	print('one grid, two column counts, the switch is a single property')


func _reflow() -> void:
	var size: Vector2 = get_viewport().get_visible_rect().size

	grid.columns = 3 if size.x >= NARROW else 2
	size_label.text = '%d x %d, %d columns' % [int(size.x), int(size.y), grid.columns]


func _card(entry: Dictionary) -> Control:
	var style: StyleBoxFlat = StyleBoxFlat.new()
	style.bg_color = Color('#1c1b1b')
	style.set_corner_radius_all(14)
	style.set_content_margin_all(20)

	var panel: PanelContainer = PanelContainer.new()
	panel.size_flags_horizontal = Control.SIZE_EXPAND_FILL
	panel.size_flags_vertical = Control.SIZE_EXPAND_FILL
	panel.add_theme_stylebox_override('panel', style)

	var column: VBoxContainer = VBoxContainer.new()
	panel.add_child(column)

	var caption: Label = Label.new()
	caption.text = entry.title
	caption.add_theme_color_override('font_color', Color('#999999'))
	column.add_child(caption)

	var value: Label = Label.new()
	value.text = entry.value
	value.add_theme_font_size_override('font_size', 34)
	value.add_theme_color_override('font_color', Color(entry.color))
	column.add_child(value)

	return panel

Más ejemplos de Interfaz