## 整数元组列表编辑器（@tool）— 每行 N 个 SpinBox + 🗑 删行，底部 ➕ 加行。
## 用于 Core edges（from/to）、balance aether_thresholds（波次/碎片）等可变长小整数元组列表。
## 数据模型：Array[Array]（行数组）；调用方负责与自身 JSON 结构互转。
@tool
extends VBoxContainer

var _cols: Array = []            # [{label,min,max,step,int,default}]
var _rows_box: VBoxContainer
var _add_label: String = "➕ 加行"

func setup(col_specs: Array, add_label: String = "➕ 加行") -> void:
	_cols = col_specs
	_add_label = add_label
	_rows_box = VBoxContainer.new()
	add_child(_rows_box)
	var add_btn := Button.new()
	add_btn.text = _add_label
	add_btn.pressed.connect(_on_add)
	add_child(add_btn)

func set_values(rows: Array) -> void:
	if _rows_box == null:
		return
	for c in _rows_box.get_children():
		_rows_box.remove_child(c)
		c.free()
	for r in rows:
		_add_row(r)

func get_values() -> Array:
	var out: Array = []
	if _rows_box == null:
		return out
	for h in _rows_box.get_children():
		var row: Array = []
		var ci := 0
		for ch in h.get_children():
			if ch is SpinBox:
				var v: float = (ch as SpinBox).value
				var is_int: bool = bool(_cols[ci].get("int", true)) if ci < _cols.size() else true
				row.append(int(v) if is_int else v)
				ci += 1
		out.append(row)
	return out

func _on_add() -> void:
	_add_row([])

func _add_row(vals: Array) -> void:
	var h := HBoxContainer.new()
	for i in _cols.size():
		var c: Dictionary = _cols[i]
		var lbl := String(c.get("label", ""))
		if lbl != "":
			var l := Label.new(); l.text = lbl
			h.add_child(l)
		var sp := SpinBox.new()
		sp.min_value = c.get("min", 0)
		sp.max_value = c.get("max", 100000)
		sp.step = c.get("step", 1)
		sp.value = float(vals[i]) if i < vals.size() else float(c.get("default", c.get("min", 0)))
		sp.size_flags_horizontal = Control.SIZE_EXPAND_FILL
		h.add_child(sp)
	var del := Button.new()
	del.text = "🗑"
	del.pressed.connect(func(): _rows_box.remove_child(h); h.queue_free())
	h.add_child(del)
	_rows_box.add_child(h)
