feat: Enhance surface setup chooser with compact mode and cancel functionality
This commit is contained in:
@@ -6,7 +6,15 @@ Phase 19 is in progress on the local branch `feature/phase-19-scenery`. This is
|
||||
|
||||
The integrated feature lets children choose a Sky, place and edit inert Scenery artwork and wall panels, paint Ground finishes, use editable starter scenes, and save/reopen the result. Scenery artwork can be placed Far, Near, or On the floor and resized independently. The Prop Editor has a stickman-relative size guide and reversible size presets for authoring art at a useful scale. Missing artwork remains visible and repairable.
|
||||
|
||||
Recent reported editor issues were addressed during Phase 19 iteration, including scene loading, grid snapping/placement previews, starter-scene thumbnails, artwork cursor alignment, wall-panel erasing and tile rendering, and scenery size/depth controls. Treat those fixes as needing a focused regression pass on the next machine; the user has not completed overall Phase 19 testing. The selected-artwork depth inspector was the latest specifically approved piece.
|
||||
Recent reported editor issues were addressed during Phase 19 iteration, including scene loading, grid snapping/placement previews, starter-scene thumbnails, artwork cursor alignment, wall-panel erasing and tile rendering, scenery size/depth controls, and the scenery chooser's surface-setup flow. Treat those fixes as needing a focused regression pass on the next machine; the user has not completed overall Phase 19 testing. The selected-artwork depth inspector was the latest specifically approved piece.
|
||||
|
||||
### Latest bug fix: surface setup chooser visibility (2026-10-19)
|
||||
|
||||
The Paint/Brick/Wood wall setup and Carpet background-ground setup previously put the Draw action after the color controls, where it could fall below the visible part of the dialog. In setup mode, the chooser now moves its action row (Cancel + Draw) above the scrollable setup content, compacts the setup layout, limits the popup to the usable screen area, and re-centers after size changes. Look choices and color controls remain scrollable. Outside clicks are blocked from reaching the Stage, and an unexpected popup hide restores the chooser instead of cancelling setup.
|
||||
|
||||
The latest focused Godot GUI run of `tests/test_phase19_surface_followup.gd` passed after this change. Its capture showed the Draw action visible for wall and background-ground setup. The test also passed its placement, color, erase, and outside-click scenarios. Captures and logs are in `/private/tmp` on the current Mac and are not repository artifacts.
|
||||
|
||||
The chooser fix is currently uncommitted in `scripts/shared/ui/asset_selector.gd`, `scripts/shared/stage_ui/stage_surface_color_controls.gd`, and `scripts/editors/stage/stage_asset_browser.gd`, with related assertions in `tests/test_phase19_surface_followup.gd`. Include these changes and this handoff update in the commit before pushing the branch for the other computer.
|
||||
|
||||
Stage-wide Undo/Redo is deliberately out of scope and recorded as technical debt for a separate phase. No new scene save workflow was requested; the current ordinary scene and Prop save flows remain authoritative.
|
||||
|
||||
|
||||
@@ -47,7 +47,8 @@ func build_ui(ui_layer: CanvasLayer, ui_font: Font, emoji_font: Font, sandbox_th
|
||||
selector_dim = ColorRect.new()
|
||||
selector_dim.name = "SelectorDim"
|
||||
selector_dim.color = Color(0.0, 0.0, 0.0, SELECTOR_DIM_ALPHA)
|
||||
selector_dim.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
# Keep clicks outside the modal from reaching the Stage canvas beneath it.
|
||||
selector_dim.mouse_filter = Control.MOUSE_FILTER_STOP
|
||||
selector_dim.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||||
selector_dim.visible = false
|
||||
ui_layer.add_child(selector_dim)
|
||||
@@ -55,7 +56,7 @@ func build_ui(ui_layer: CanvasLayer, ui_font: Font, emoji_font: Font, sandbox_th
|
||||
selector = ASSET_SELECTOR_SCENE.instantiate() as AssetSelector
|
||||
selector.item_selected.connect(func(entry: Dictionary) -> void: asset_selected_requested.emit(entry))
|
||||
selector.cancelled.connect(_on_selector_cancelled)
|
||||
selector.popup_hide.connect(_on_selector_cancelled)
|
||||
selector.popup_hide.connect(_on_selector_popup_hide)
|
||||
selector.browse_requested.connect(show_browse_dialog)
|
||||
selector.refresh_requested.connect(func() -> void: refresh_requested.emit())
|
||||
selector.make_artwork_requested.connect(func() -> void: make_artwork_requested.emit())
|
||||
@@ -281,6 +282,19 @@ func _on_selector_cancelled() -> void:
|
||||
selector_cancel_requested.emit()
|
||||
|
||||
|
||||
func _on_selector_popup_hide() -> void:
|
||||
if not selector_open:
|
||||
return
|
||||
# PopupPanel can hide itself when it loses focus. Keep the chooser alive so an
|
||||
# outside click cannot silently cancel the user's scenery setup.
|
||||
call_deferred("_restore_selector_after_unexpected_hide")
|
||||
|
||||
|
||||
func _restore_selector_after_unexpected_hide() -> void:
|
||||
if selector_open and selector != null and not selector.visible:
|
||||
selector.popup_centered()
|
||||
|
||||
|
||||
func get_selector() -> AssetSelector:
|
||||
return selector
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -344,8 +344,45 @@ func _test_selector_setup_routes(controller: StageSceneryController) -> void:
|
||||
_capture_gui_screen("phase19_wall_setup.png")
|
||||
var setup: Control = selector.find_child("SurfaceSetupView", true, false) as Control
|
||||
var draw: Button = selector.find_child("DrawSurfaceButton", true, false) as Button
|
||||
var cancel_setup: Button = selector.find_child("CancelSurfaceSetupButton", true, false) as Button
|
||||
var chooser_colors: StageSurfaceColorControls = selector.find_child("SurfaceColorControls", true, false) as StageSurfaceColorControls
|
||||
_expect(setup != null and setup.visible and draw != null, "Wall panel setup shows a reachable preview and Draw action")
|
||||
_expect(draw != null and draw.get_parent() == selector.find_child("Footer", true, false), "Wall panel Draw action stays fixed in the chooser footer")
|
||||
_expect(cancel_setup != null and cancel_setup.visible and cancel_setup.get_parent() == selector.find_child("Footer", true, false), "Wall panel setup keeps an explicit Cancel action in the chooser footer")
|
||||
_expect(browser.selector_dim != null and browser.selector_dim.mouse_filter == Control.MOUSE_FILTER_STOP, "Clicks outside the scenery chooser are blocked from the Stage canvas")
|
||||
if gui_render:
|
||||
selector.hide()
|
||||
await process_frame
|
||||
await process_frame
|
||||
_expect(browser.selector_open and selector.visible, "Unexpected popup dismissal restores the chooser without cancelling setup")
|
||||
if not gui_render:
|
||||
browser.selector_open = true
|
||||
if cancel_setup != null:
|
||||
cancel_setup.pressed.emit()
|
||||
_expect(not browser.selector_open and String(controller.get_active_tool()).is_empty(), "Cancel exits the scenery chooser without starting placement")
|
||||
if gui_render:
|
||||
_stage.call("_open_selector", "scenery")
|
||||
await process_frame
|
||||
await process_frame
|
||||
await create_timer(0.2).timeout
|
||||
else:
|
||||
browser.selector_open = true
|
||||
browser.set_selector_kind("scenery")
|
||||
selector.kind = "scenery"
|
||||
var reopened_entries: Array[Dictionary] = browser.scan_entries("scenery")
|
||||
reopened_entries.append_array(browser.call("_scenery_background_entries") as Array[Dictionary])
|
||||
selector.set_entries(reopened_entries)
|
||||
wall_card = _find_card(selector.find_child("GridContainer", true, false) as GridContainer, "wall_panel_setup")
|
||||
_expect(wall_card != null, "Cancel returns to a fresh scenery gallery")
|
||||
if wall_card != null:
|
||||
selector.call("_on_cell_pressed", wall_card.payload())
|
||||
if gui_render:
|
||||
await process_frame
|
||||
await process_frame
|
||||
setup = selector.find_child("SurfaceSetupView", true, false) as Control
|
||||
draw = selector.find_child("DrawSurfaceButton", true, false) as Button
|
||||
chooser_colors = selector.find_child("SurfaceColorControls", true, false) as StageSurfaceColorControls
|
||||
_expect(setup != null and setup.visible and draw != null and draw.visible, "Wall setup reopens after Cancel with Draw available")
|
||||
var wall_looks: StagePanelChoiceGroup = selector.get_meta("wall_look_group") as StagePanelChoiceGroup
|
||||
if wall_looks != null:
|
||||
wall_looks.choice_selected.emit(&"finish_wall_wood")
|
||||
|
||||
Reference in New Issue
Block a user