feat: Enhance surface setup chooser with compact mode and cancel functionality
This commit is contained in:
@@ -18,6 +18,13 @@ var _recent_empty_label: Label
|
||||
var _recent_swatches: ColorSwatchSelector
|
||||
var _preset_swatches: ColorSwatchSelector
|
||||
var _more_button: Button
|
||||
var _compact_mode: bool = false
|
||||
|
||||
|
||||
func set_compact_mode(enabled: bool) -> void:
|
||||
_compact_mode = enabled
|
||||
if _built:
|
||||
_apply_compact_layout()
|
||||
|
||||
|
||||
func configure(selected: Color, recents: Array[Color], presets: Array[Color], stage_theme: SandboxTheme) -> void:
|
||||
@@ -53,14 +60,16 @@ func focus_custom_button() -> void:
|
||||
|
||||
func _build() -> void:
|
||||
_built = true
|
||||
add_theme_constant_override("separation", _integer("stage_surface_colors.section_gap", 8, 0, 28))
|
||||
_apply_compact_layout()
|
||||
var current_heading: Label = _make_heading("Color")
|
||||
add_child(current_heading)
|
||||
var current_row := HBoxContainer.new()
|
||||
current_row.add_theme_constant_override("separation", _integer("stage_surface_colors.section_gap", 8, 0, 28))
|
||||
current_row.add_theme_constant_override("separation", _compact_gap())
|
||||
add_child(current_row)
|
||||
_current_chip = Button.new()
|
||||
var swatch_size: float = float(_integer("stage_surface_colors.swatch_size", 48, 44, 96))
|
||||
if _compact_mode:
|
||||
swatch_size = minf(swatch_size, 44.0)
|
||||
_current_chip.custom_minimum_size = Vector2(swatch_size, swatch_size)
|
||||
_current_chip.focus_mode = Control.FOCUS_NONE
|
||||
_current_chip.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
@@ -84,7 +93,8 @@ func _build() -> void:
|
||||
add_child(_preset_swatches)
|
||||
_more_button = Button.new()
|
||||
_more_button.text = "More colors…"
|
||||
_more_button.custom_minimum_size.y = float(_integer("stage_panels.action.min_target_size", 48, 44, 96))
|
||||
var action_height: float = float(_integer("stage_panels.action.min_target_size", 48, 44, 96))
|
||||
_more_button.custom_minimum_size.y = minf(action_height, 44.0) if _compact_mode else action_height
|
||||
_more_button.focus_mode = Control.FOCUS_ALL
|
||||
_more_button.pressed.connect(func() -> void: custom_color_requested.emit())
|
||||
add_child(_more_button)
|
||||
@@ -132,13 +142,26 @@ func _on_swatch_selected(color: Color) -> void:
|
||||
func _make_heading(text_value: String) -> Label:
|
||||
var heading := Label.new()
|
||||
heading.text = text_value
|
||||
heading.add_theme_font_size_override("font_size", _integer("stage_panels.type.section_size", 20, 12, 40))
|
||||
var heading_size: int = _integer("stage_panels.type.section_size", 20, 12, 40)
|
||||
if _compact_mode:
|
||||
heading_size = mini(heading_size, 18)
|
||||
heading.add_theme_font_size_override("font_size", heading_size)
|
||||
heading.add_theme_color_override("font_color", _color("stage_panels.type.text_color", Color("#F5F7FA")))
|
||||
if _stage_theme != null and _stage_theme.font() != null:
|
||||
heading.add_theme_font_override("font", _stage_theme.font())
|
||||
return heading
|
||||
|
||||
|
||||
func _apply_compact_layout() -> void:
|
||||
var section_gap: int = _integer("stage_surface_colors.section_gap", 8, 0, 28)
|
||||
add_theme_constant_override("separation", mini(section_gap, 4) if _compact_mode else section_gap)
|
||||
|
||||
|
||||
func _compact_gap() -> int:
|
||||
var section_gap: int = _integer("stage_surface_colors.section_gap", 8, 0, 28)
|
||||
return mini(section_gap, 4) if _compact_mode else section_gap
|
||||
|
||||
|
||||
func _integer(path: String, fallback: int, minimum: int, maximum: int) -> int:
|
||||
return fallback if _stage_theme == null else _stage_theme.integer(path, fallback, minimum, maximum)
|
||||
|
||||
|
||||
@@ -56,6 +56,8 @@ var _setup_color_chosen: bool = false
|
||||
var _setup_preview: StageSurfacePreview
|
||||
var _setup_color_controls: StageSurfaceColorControls
|
||||
var _setup_color_dialog: StageSurfaceColorDialog
|
||||
var _setup_cancel_button: Button
|
||||
var _setup_draw_button: Button
|
||||
|
||||
@onready var _title_label: Label = %TitleLabel
|
||||
@onready var _grid: GridContainer = %GridContainer
|
||||
@@ -101,7 +103,6 @@ func _on_root_size_changed() -> void:
|
||||
if visible:
|
||||
_update_popup_layout()
|
||||
_rebuild()
|
||||
popup_centered()
|
||||
|
||||
|
||||
func open(p_kind: String, entries: Array[Dictionary], current_sky_id: String = "") -> void:
|
||||
@@ -198,7 +199,7 @@ func _build_surface_setup_view() -> void:
|
||||
_setup_view = VBoxContainer.new()
|
||||
_setup_view.name = "SurfaceSetupView"
|
||||
_setup_view.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
_setup_view.add_theme_constant_override("separation", _theme_integer("popups.asset_selector.setup_gap", 10, 0, 32))
|
||||
_setup_view.add_theme_constant_override("separation", mini(_theme_integer("popups.asset_selector.setup_gap", 10, 0, 32), 6))
|
||||
_setup_view.visible = false
|
||||
_content_stack.add_child(_setup_view)
|
||||
var heading_row := HBoxContainer.new()
|
||||
@@ -226,6 +227,7 @@ func _build_surface_setup_view() -> void:
|
||||
wall_choices.add_choice(&"finish_wall_brick", "Brick", _make_look_cue(&"wall", &"finish_wall_brick"))
|
||||
wall_choices.add_choice(&"finish_wall_wood", "Wood", _make_look_cue(&"wall", &"finish_wall_wood"))
|
||||
wall_choices.choice_selected.connect(_on_setup_look_choice)
|
||||
_compact_look_choices(wall_choices)
|
||||
_setup_view.add_child(wall_choices)
|
||||
var ground_choices: StagePanelChoiceGroup = STAGE_PANEL_CHOICE_GROUP.new() as StagePanelChoiceGroup
|
||||
ground_choices.name = "BackgroundGroundLookChoices"
|
||||
@@ -233,12 +235,14 @@ func _build_surface_setup_view() -> void:
|
||||
ground_choices.add_choice(&"finish_background_concrete", "Concrete", _make_look_cue(&"background_ground", &"finish_background_concrete"))
|
||||
ground_choices.add_choice(&"finish_background_carpet", "Carpet", _make_look_cue(&"background_ground", &"finish_background_carpet"))
|
||||
ground_choices.choice_selected.connect(_on_setup_look_choice)
|
||||
_compact_look_choices(ground_choices)
|
||||
_setup_view.add_child(ground_choices)
|
||||
set_meta("wall_look_group", wall_choices)
|
||||
set_meta("ground_look_group", ground_choices)
|
||||
var preview_frame := PanelContainer.new()
|
||||
preview_frame.name = "SurfacePreviewFrame"
|
||||
var preview_size: Vector2 = _theme_vector2("popups.asset_selector.surface_preview_size", Vector2(420.0, 132.0))
|
||||
preview_size.y = minf(preview_size.y, 96.0)
|
||||
preview_frame.custom_minimum_size.y = preview_size.y + 10.0
|
||||
preview_frame.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
_setup_preview = SURFACE_PREVIEW.new() as StageSurfacePreview
|
||||
@@ -248,6 +252,7 @@ func _build_surface_setup_view() -> void:
|
||||
_setup_view.add_child(preview_frame)
|
||||
_setup_color_controls = SURFACE_COLOR_CONTROLS.new() as StageSurfaceColorControls
|
||||
_setup_color_controls.name = "SurfaceColorControls"
|
||||
_setup_color_controls.set_compact_mode(true)
|
||||
_setup_color_controls.color_selected.connect(_on_setup_color_selected)
|
||||
_setup_color_controls.custom_color_requested.connect(_open_setup_color_dialog)
|
||||
_setup_view.add_child(_setup_color_controls)
|
||||
@@ -256,25 +261,35 @@ func _build_surface_setup_view() -> void:
|
||||
helper.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
helper.add_theme_color_override("font_color", _theme_color("global.muted_text_color", Color("#AAB2C0")))
|
||||
_setup_view.add_child(helper)
|
||||
var draw_button := Button.new()
|
||||
draw_button.name = "DrawSurfaceButton"
|
||||
draw_button.custom_minimum_size.y = float(_theme_integer("stage_panels.choice.minimum_height", 56, 44, 112))
|
||||
draw_button.focus_mode = Control.FOCUS_ALL
|
||||
draw_button.pressed.connect(_draw_selected_surface)
|
||||
_setup_view.add_child(draw_button)
|
||||
_setup_cancel_button = Button.new()
|
||||
_setup_cancel_button.name = "CancelSurfaceSetupButton"
|
||||
_setup_cancel_button.text = "Cancel"
|
||||
_setup_cancel_button.custom_minimum_size = Vector2(104.0, float(_theme_integer("stage_panels.action.min_target_size", 48, 44, 96)))
|
||||
_setup_cancel_button.focus_mode = Control.FOCUS_ALL
|
||||
_setup_cancel_button.pressed.connect(_cancel_surface_setup)
|
||||
_footer.add_child(_setup_cancel_button)
|
||||
_setup_draw_button = Button.new()
|
||||
_setup_draw_button.name = "DrawSurfaceButton"
|
||||
_setup_draw_button.custom_minimum_size = Vector2(220.0, float(_theme_integer("stage_panels.choice.minimum_height", 56, 44, 112)))
|
||||
_setup_draw_button.focus_mode = Control.FOCUS_ALL
|
||||
_setup_draw_button.pressed.connect(_draw_selected_surface)
|
||||
_footer.add_child(_setup_draw_button)
|
||||
set_meta("setup_heading", heading)
|
||||
set_meta("setup_helper", helper)
|
||||
set_meta("setup_draw_button", draw_button)
|
||||
_apply_font_to(back_button)
|
||||
_apply_font_to(heading)
|
||||
_apply_font_to(look_heading)
|
||||
_apply_font_to(helper)
|
||||
_apply_font_to(draw_button)
|
||||
_apply_font_to(_setup_cancel_button)
|
||||
_apply_font_to(_setup_draw_button)
|
||||
if _sandbox_theme != null:
|
||||
draw_button.add_theme_stylebox_override("normal", _sandbox_theme.stylebox("stage_panels.action"))
|
||||
draw_button.add_theme_stylebox_override("hover", _sandbox_theme.stylebox("stage_panels.action"))
|
||||
draw_button.add_theme_color_override("font_color", _theme_color("stage_panels.type.text_color", Color("#F5F7FA")))
|
||||
draw_button.add_theme_font_size_override("font_size", _theme_integer("stage_panels.type.body_size", 20, 14, 40))
|
||||
_setup_cancel_button.add_theme_stylebox_override("normal", _sandbox_theme.stylebox("stage_panels.choice"))
|
||||
_setup_cancel_button.add_theme_stylebox_override("hover", _sandbox_theme.stylebox("stage_panels.choice"))
|
||||
_setup_cancel_button.add_theme_font_size_override("font_size", _theme_integer("stage_panels.type.body_size", 20, 14, 40))
|
||||
_setup_draw_button.add_theme_stylebox_override("normal", _sandbox_theme.stylebox("stage_panels.action"))
|
||||
_setup_draw_button.add_theme_stylebox_override("hover", _sandbox_theme.stylebox("stage_panels.action"))
|
||||
_setup_draw_button.add_theme_color_override("font_color", _theme_color("stage_panels.type.text_color", Color("#F5F7FA")))
|
||||
_setup_draw_button.add_theme_font_size_override("font_size", _theme_integer("stage_panels.type.body_size", 20, 14, 40))
|
||||
for choice: StagePanelChoiceGroup in [wall_choices, ground_choices]:
|
||||
choice.apply_theme(_sandbox_theme as SandboxTheme)
|
||||
_apply_font_to(choice)
|
||||
@@ -282,11 +297,21 @@ func _build_surface_setup_view() -> void:
|
||||
|
||||
func _make_look_cue(kind: StringName, finish: StringName) -> Control:
|
||||
var preview: StageSurfacePreview = SURFACE_PREVIEW.new() as StageSurfacePreview
|
||||
preview.custom_minimum_size = _theme_vector2("popups.asset_selector.look_cue_size", Vector2(80.0, 42.0))
|
||||
var cue_size: Vector2 = _theme_vector2("popups.asset_selector.look_cue_size", Vector2(80.0, 42.0))
|
||||
cue_size.x = minf(cue_size.x, 68.0)
|
||||
cue_size.y = minf(cue_size.y, 34.0)
|
||||
preview.custom_minimum_size = cue_size
|
||||
preview.configure(kind, finish, SURFACE_RENDERER.default_tint(finish))
|
||||
return preview
|
||||
|
||||
|
||||
func _compact_look_choices(group: StagePanelChoiceGroup) -> void:
|
||||
for child: Node in group.get_children():
|
||||
if child is Button:
|
||||
var button := child as Button
|
||||
button.custom_minimum_size.y = minf(button.custom_minimum_size.y, 50.0)
|
||||
|
||||
|
||||
func _open_surface_setup(kind: StringName) -> void:
|
||||
_setup_kind = kind
|
||||
_setup_color_chosen = false
|
||||
@@ -301,7 +326,7 @@ func _open_surface_setup(kind: StringName) -> void:
|
||||
ground_choices.select_no_signal(_setup_finish)
|
||||
(get_meta("setup_heading") as Label).text = "Wall panel" if kind == &"wall" else "Background ground"
|
||||
(get_meta("setup_helper") as Label).text = "Looks like a wall · Stickmen can pass through." if kind == &"wall" else "Decorative only · Stickmen don’t walk here."
|
||||
(get_meta("setup_draw_button") as Button).text = "Draw wall panel" if kind == &"wall" else "Draw background ground"
|
||||
_setup_draw_button.text = "Draw wall panel" if kind == &"wall" else "Draw background ground"
|
||||
_setup_color_controls.visible = _supports_setup_color()
|
||||
_setup_color_controls.configure(_setup_color, _surface_color_history, _preset_surface_colors(), _sandbox_theme as SandboxTheme)
|
||||
_update_setup_preview()
|
||||
@@ -400,6 +425,12 @@ func _draw_selected_surface() -> void:
|
||||
var background_kind: String = "wall" if _setup_kind == &"wall" else "background_ground"
|
||||
item_selected.emit({"background_kind": background_kind, "finish_id": String(_setup_finish), "color": _setup_color})
|
||||
|
||||
|
||||
func _cancel_surface_setup() -> void:
|
||||
_setup_kind = &""
|
||||
_setup_view.visible = false
|
||||
cancelled.emit()
|
||||
|
||||
var _cell_min_size: Vector2 = CELL_MIN_SIZE
|
||||
var _thumbnail_size: Vector2 = THUMB_SIZE
|
||||
|
||||
@@ -500,9 +531,15 @@ func _usable_screen_size() -> Vector2:
|
||||
|
||||
|
||||
func _update_popup_layout() -> void:
|
||||
var in_setup: bool = not _setup_kind.is_empty()
|
||||
_position_footer(in_setup)
|
||||
_setup_cancel_button.visible = in_setup
|
||||
_setup_draw_button.visible = in_setup
|
||||
_edit_scenery_button.visible = kind == "scenery" and not in_setup
|
||||
_footer.alignment = BoxContainer.ALIGNMENT_END if in_setup else BoxContainer.ALIGNMENT_CENTER
|
||||
var available: Vector2 = _usable_screen_size()
|
||||
var max_width: float = maxf(1.0, minf(available.x * 0.94, available.x - POPUP_SAFE_SCREEN_MARGIN))
|
||||
var max_height: float = maxf(1.0, minf(available.y * 0.90, available.y - POPUP_SAFE_SCREEN_MARGIN))
|
||||
var max_height: float = maxf(1.0, minf(available.y * 0.86, available.y - POPUP_SAFE_SCREEN_MARGIN * 2.0))
|
||||
var preferred_width: float = CELL_MIN_SIZE.x * COLUMNS + GRID_H_SEPARATION * (COLUMNS - 1) + POPUP_SIDE_PADDING
|
||||
var popup_width: float = minf(preferred_width, max_width)
|
||||
var grid_width: float = maxf(1.0, popup_width - POPUP_SIDE_PADDING)
|
||||
@@ -534,6 +571,8 @@ func _update_popup_layout() -> void:
|
||||
fixed_height += float(visible_sections - 1) * 8.0
|
||||
var popup_height: float = minf(fixed_height + body_height, max_height)
|
||||
size = Vector2i(maxi(1, roundi(popup_width)), maxi(1, roundi(popup_height)))
|
||||
if visible:
|
||||
popup_centered()
|
||||
|
||||
|
||||
func _rebuild() -> void:
|
||||
@@ -543,7 +582,11 @@ func _rebuild() -> void:
|
||||
_cell_texrects.clear()
|
||||
var filtered: Array[Dictionary] = _filtered_entries()
|
||||
var in_setup: bool = not _setup_kind.is_empty()
|
||||
_position_footer(in_setup)
|
||||
_setup_view.visible = in_setup
|
||||
_setup_cancel_button.visible = in_setup
|
||||
_setup_draw_button.visible = in_setup
|
||||
_edit_scenery_button.visible = kind == "scenery" and not in_setup
|
||||
_empty_label.visible = filtered.is_empty() and not in_setup
|
||||
_grid.visible = not filtered.is_empty() and not in_setup
|
||||
_grid_scroll.visible = not filtered.is_empty() or in_setup
|
||||
@@ -570,6 +613,15 @@ func _rebuild() -> void:
|
||||
_grid.add_child(_build_cell(filtered[i]))
|
||||
|
||||
|
||||
func _position_footer(in_setup: bool) -> void:
|
||||
var parent := _footer.get_parent() as VBoxContainer
|
||||
if parent == null:
|
||||
return
|
||||
var target_index: int = _tabs.get_index() + 1 if in_setup else parent.get_child_count() - 1
|
||||
if _footer.get_index() != target_index:
|
||||
parent.move_child(_footer, target_index)
|
||||
|
||||
|
||||
func _build_cell(entry: Dictionary) -> Control:
|
||||
var key := _entry_key(entry)
|
||||
var cell: Variant = ASSET_CARD.new()
|
||||
|
||||
Reference in New Issue
Block a user