Improve fullscreen menus on 4:3 displays

This commit is contained in:
Alexander Sellite 2026-08-19 06:53:55 -04:00
parent 805885a9f1
commit c6b897718c
9 changed files with 281 additions and 19 deletions

View file

@ -6,6 +6,9 @@ const ControllerFocusNavigationType = preload(
const UIReferencePresentationType = preload(
"res://ui/ui_reference_presentation.gd"
)
const FullscreenMenuPresentationType = preload(
"res://ui/fullscreen_menu_presentation.gd"
)
func _initialize() -> void:
@ -234,10 +237,21 @@ func _validate_settings_navigation_contract() -> void:
func _validate_four_by_three_centering() -> void:
var stage_position: Vector2 = (
UIReferencePresentationType.get_stage_position(Vector2(640.0, 480.0))
var display_size := Vector2(640.0, 480.0)
var stage_position: Vector2 = UIReferencePresentationType.get_stage_position(
display_size
)
assert(stage_position.is_equal_approx(Vector2(0.0, 120.0)))
assert(FullscreenMenuPresentationType.uses_compact_profile(display_size))
assert(is_equal_approx(
FullscreenMenuPresentationType.get_profile_scale(display_size),
4.0 / 3.0,
))
assert(FullscreenMenuPresentationType.get_profile_position(
display_size
).is_equal_approx(Vector2(-640.0 / 3.0, -120.0)))
assert(FullscreenMenuPresentationType.get_source_rect(display_size)
== Rect2(160.0, 0.0, 960.0, 720.0))
func _validate_low_end_profile_contract() -> void:

View file

@ -81,6 +81,22 @@ func _validate_page() -> void:
page.setup(collection, inventory, CatalogResource)
page.activate()
await process_frame
var outer_margin := page.get("_outer_margin") as MarginContainer
var book := page.get("_book") as Control
assert(outer_margin != null)
assert(book != null)
page.set_compact_presentation(true)
await process_frame
assert(outer_margin.get_theme_constant("margin_left") == 160)
assert(outer_margin.get_theme_constant("margin_right") == 160)
assert(outer_margin.get_theme_constant("margin_bottom") == 106)
assert(is_equal_approx(book.offset_top, 65.0))
page.set_compact_presentation(false)
await process_frame
assert(outer_margin.get_theme_constant("margin_left") == 52)
assert(outer_margin.get_theme_constant("margin_right") == 52)
assert(outer_margin.get_theme_constant("margin_bottom") == 18)
assert(is_equal_approx(book.offset_top, 50.0))
assert(
page.get("_category") == LogbookCatalog.Category.FRESH_WATER
)
@ -289,6 +305,25 @@ func _validate_page() -> void:
var facts_detail := detail_buttons[1] as Button
var quality_detail := detail_buttons[2] as Button
var stats_detail := detail_buttons[3] as Button
assert(
quality_detail.custom_minimum_size
== LogbookPage.DETAIL_QUALITY_SECTION_SIZE
)
assert(
stats_detail.custom_minimum_size
== LogbookPage.DETAIL_STATS_SECTION_SIZE
)
assert(
quality_detail.size_flags_horizontal
== Control.SIZE_SHRINK_CENTER
)
assert(
stats_detail.size_flags_horizontal
== Control.SIZE_SHRINK_CENTER
)
assert(
stats_detail.size_flags_vertical & Control.SIZE_EXPAND == 0
)
assert(
portrait_detail.get_node(portrait_detail.focus_neighbor_right)
== facts_detail

View file

@ -6,6 +6,9 @@ const UIPixelationPresenterType = preload(
const UIReferencePresentationType = preload(
"res://ui/ui_reference_presentation.gd"
)
const FullscreenMenuPresentationType = preload(
"res://ui/fullscreen_menu_presentation.gd"
)
const GameUIScene := preload("res://ui/game_ui.tscn")
const TARGET_SIZES: Array[Vector2i] = [
Vector2i(1280, 720),
@ -40,6 +43,9 @@ func _run() -> void:
var player_menu := game_ui.get_node(
"UIRoot/CanonicalStage/PlayerMenu"
) as PlayerMenu
var player_menu_profile_stage := player_menu.get_node(
"ResponsivePlayerMenuStage"
) as Control
var hotbar := game_ui.get_node(
"UIRoot/CanonicalStage/Hotbar"
) as HotbarUI
@ -51,6 +57,15 @@ func _run() -> void:
var title_content_stage := title_screen.get_node(
"ResponsiveTitleStage"
) as Control
var title_profile_root := title_screen.get_node(
"ResponsiveTitleStage/TitlePresentationScaleRoot"
) as Control
var pause_menu := game_ui.get_node(
"UIRoot/CanonicalStage/PauseMenu"
) as PauseMenu
var pause_profile_stage := pause_menu.get_node(
"ResponsivePauseStage"
) as Control
var decorative_fish_layer := title_screen.get_node(
"DecorativeFishLayer"
) as Control
@ -94,6 +109,12 @@ func _run() -> void:
var expected_stage_offset: Vector2 = UIReferencePresentationType.get_offset(
display_size
)
var expected_profile_scale: float = (
FullscreenMenuPresentationType.get_profile_scale(display_size)
)
var expected_profile_position: Vector2 = (
FullscreenMenuPresentationType.get_profile_position(display_size)
)
assert(presenter.position.is_equal_approx(Vector2.ZERO))
assert(ui_root.position.is_equal_approx(Vector2.ZERO))
var expected_visible_size: Vector2 = (
@ -112,6 +133,12 @@ func _run() -> void:
assert(player_menu.size.is_equal_approx(
UIReferencePresentationType.REFERENCE_SIZE
))
assert(player_menu_profile_stage.scale.is_equal_approx(
Vector2.ONE * expected_profile_scale
))
assert(player_menu_profile_stage.position.is_equal_approx(
expected_profile_position
))
assert(hotbar.position.is_equal_approx(Vector2(
0.0,
canonical_stage.position.y,
@ -126,6 +153,18 @@ func _run() -> void:
assert(title_content_stage.position.is_equal_approx(
canonical_stage.position
))
assert(title_profile_root.scale.is_equal_approx(
Vector2.ONE * expected_profile_scale
))
assert(title_profile_root.position.is_equal_approx(
expected_profile_position
))
assert(pause_profile_stage.scale.is_equal_approx(
Vector2.ONE * expected_profile_scale
))
assert(pause_profile_stage.position.is_equal_approx(
expected_profile_position
))
assert(decorative_fish_layer.size.is_equal_approx(
expected_visible_size
))
@ -153,6 +192,34 @@ func _run() -> void:
assert((
canonical_stage.position * effective_scale
).distance_to(expected_stage_offset) <= 0.01)
var profile_source_rect: Rect2 = (
FullscreenMenuPresentationType.get_source_rect(display_size)
)
var profile_screen_start: Vector2 = expected_stage_offset + (
expected_profile_position
+ profile_source_rect.position * expected_profile_scale
) * expected_scale
var profile_screen_size: Vector2 = (
profile_source_rect.size
* expected_profile_scale
* expected_scale
)
var compact_target_scale: float = minf(
display_size.x / profile_source_rect.size.x,
display_size.y / profile_source_rect.size.y,
)
var expected_profile_screen_size: Vector2 = (
profile_source_rect.size * compact_target_scale
)
var expected_profile_screen_start: Vector2 = (
display_size - expected_profile_screen_size
) * 0.5
assert(profile_screen_start.distance_to(
expected_profile_screen_start
) <= 0.01)
assert(profile_screen_size.distance_to(
expected_profile_screen_size
) <= 0.01)
var expected_render_height: int = mini(
roundi(UIReferencePresentationType.REFERENCE_SIZE.y * expected_scale),
PlayerSettings.get_ui_render_height(