Checkpoint Player Menu bubble redesign

This commit is contained in:
Alexander Sellite 2026-07-28 16:29:02 -04:00
parent 7a435ca7b8
commit bcffe2013d
14 changed files with 1062 additions and 152 deletions

View file

@ -0,0 +1,49 @@
class_name BubbleContentShell
extends PanelContainer
@export var profile: BubbleMenuProfile
@export_range(0.0, 96.0, 1.0) var content_margin: float = 24.0
@export_range(0, 512, 1) var corner_radius: int = 72
@export_range(0, 12, 1) var border_width: int = 3
var _background_visible: bool = true
func _ready() -> void:
apply_profile()
func apply_profile() -> void:
if profile == null:
return
var style := StyleBoxFlat.new()
style.bg_color = profile.normal_fill
style.border_color = profile.normal_border
style.border_width_left = border_width
style.border_width_top = border_width
style.border_width_right = border_width
style.border_width_bottom = border_width
style.corner_radius_top_left = corner_radius
style.corner_radius_top_right = corner_radius
style.corner_radius_bottom_right = corner_radius
style.corner_radius_bottom_left = corner_radius
style.content_margin_left = content_margin
style.content_margin_top = content_margin
style.content_margin_right = content_margin
style.content_margin_bottom = content_margin
add_theme_stylebox_override("panel", style)
func set_background_visible(background_visible: bool) -> void:
_background_visible = background_visible
if not is_node_ready() or profile == null:
return
if _background_visible:
apply_profile()
return
var transparent_style := StyleBoxEmpty.new()
transparent_style.content_margin_left = content_margin
transparent_style.content_margin_top = content_margin
transparent_style.content_margin_right = content_margin
transparent_style.content_margin_bottom = content_margin
add_theme_stylebox_override("panel", transparent_style)

View file

@ -0,0 +1 @@
uid://bsplayercontentshell

View file

@ -0,0 +1,8 @@
[gd_scene load_steps=3 format=3]
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_content_shell.gd" id="1_shell"]
[ext_resource type="Resource" path="res://ui/components/bubble_menu/bubble_menu_profile.tres" id="2_profile"]
[node name="BubbleContentShell" type="PanelContainer"]
script = ExtResource("1_shell")
profile = ExtResource("2_profile")

View file

@ -0,0 +1,21 @@
class_name BubbleInformationPanel
extends PanelContainer
@export var profile: BubbleMenuProfile
@export_range(0.0, 96.0, 1.0) var content_margin: float = 20.0
@export_range(0, 512, 1) var corner_radius: int = 96
func _ready() -> void:
if profile == null:
return
var style: StyleBoxFlat = profile.make_normal_style()
style.corner_radius_top_left = corner_radius
style.corner_radius_top_right = corner_radius
style.corner_radius_bottom_left = corner_radius
style.corner_radius_bottom_right = corner_radius
style.content_margin_left = content_margin
style.content_margin_top = content_margin
style.content_margin_right = content_margin
style.content_margin_bottom = content_margin
add_theme_stylebox_override("panel", style)

View file

@ -0,0 +1 @@
uid://bubbleinformationpanel

View file

@ -0,0 +1,9 @@
[gd_scene load_steps=3 format=3]
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_information_panel.gd" id="1_panel"]
[ext_resource type="Resource" path="res://ui/components/bubble_menu/bubble_menu_profile.tres" id="2_profile"]
[node name="BubbleInformationPanel" type="PanelContainer"]
mouse_filter = 1
script = ExtResource("1_panel")
profile = ExtResource("2_profile")

View file

@ -0,0 +1,125 @@
class_name BubbleInventoryCell
extends Button
@export var profile: BubbleMenuProfile
@onready var _icon: TextureRect = %Icon
@onready var _primary_label: Label = %PrimaryLabel
@onready var _secondary_label: Label = %SecondaryLabel
@onready var _favorite_marker: Label = %FavoriteMarker
@onready var _selected_marker: Label = %SelectedMarker
var _selected: bool = false
var _focused_item: bool = false
var _compact: bool = false
var _icon_texture: Texture2D
var _primary_text: String = ""
var _secondary_text: String = ""
var _favorite: bool = false
func _ready() -> void:
focus_entered.connect(_refresh_style)
focus_exited.connect(_refresh_style)
_apply_compact_layout()
_apply_content()
_refresh_style()
func configure(
icon_texture: Texture2D,
primary_text: String,
secondary_text: String,
) -> void:
_icon_texture = icon_texture
_primary_text = primary_text
_secondary_text = secondary_text
if is_node_ready():
_apply_content()
func set_item_state(
selected: bool,
focused_item: bool,
favorite: bool,
) -> void:
_selected = selected
_focused_item = focused_item
_favorite = favorite
if is_node_ready():
_apply_content()
_refresh_style()
func set_compact(compact: bool) -> void:
_compact = compact
if not is_node_ready():
custom_minimum_size = (
Vector2(104.0, 98.0)
if compact
else Vector2(144.0, 136.0)
)
return
_apply_compact_layout()
func _apply_compact_layout() -> void:
custom_minimum_size = (
Vector2(104.0, 98.0)
if _compact
else Vector2(144.0, 136.0)
)
_icon.custom_minimum_size = (
Vector2(72.0, 44.0)
if _compact
else Vector2(104.0, 68.0)
)
_primary_label.add_theme_font_size_override(
"font_size",
15 if _compact else 18,
)
_secondary_label.add_theme_font_size_override(
"font_size",
13 if _compact else 15,
)
func _apply_content() -> void:
_icon.texture = _icon_texture
_primary_label.text = _primary_text
_secondary_label.text = _secondary_text
_selected_marker.visible = _selected
_favorite_marker.visible = _favorite
func _has_point(point: Vector2) -> bool:
var radius: Vector2 = size * 0.5
if radius.x <= 0.0 or radius.y <= 0.0:
return false
var normalized: Vector2 = (point - radius) / radius
return normalized.length_squared() <= 1.0
func _refresh_style() -> void:
if profile == null:
return
var normal_style: StyleBoxFlat = profile.make_normal_style()
var border_width: int = (
profile.emphasized_border_width
if _selected or _focused_item or has_focus()
else profile.normal_border_width
)
normal_style.border_width_left = border_width
normal_style.border_width_top = border_width
normal_style.border_width_right = border_width
normal_style.border_width_bottom = border_width
if _selected:
normal_style.bg_color = profile.pressed_fill
if _focused_item:
normal_style.border_color = profile.text_color
add_theme_stylebox_override("normal", normal_style)
add_theme_stylebox_override("hover", profile.make_hover_style())
add_theme_stylebox_override("focus", normal_style)
add_theme_stylebox_override("pressed", profile.make_pressed_style())
add_theme_stylebox_override("disabled", profile.make_disabled_style())
add_theme_color_override("font_color", profile.text_color)

View file

@ -0,0 +1 @@
uid://bubbleinventorycell

View file

@ -0,0 +1,78 @@
[gd_scene load_steps=3 format=3]
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_inventory_cell.gd" id="1_cell"]
[ext_resource type="Resource" path="res://ui/components/bubble_menu/bubble_menu_profile.tres" id="2_profile"]
[node name="BubbleInventoryCell" type="Button"]
custom_minimum_size = Vector2(144, 136)
toggle_mode = true
script = ExtResource("1_cell")
profile = ExtResource("2_profile")
[node name="Content" type="VBoxContainer" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 17.0
offset_top = 14.0
offset_right = -17.0
offset_bottom = -14.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
theme_override_constants/separation = 2
[node name="Icon" type="TextureRect" parent="Content"]
unique_name_in_owner = true
custom_minimum_size = Vector2(104, 68)
layout_mode = 2
size_flags_vertical = 3
mouse_filter = 2
texture_filter = 1
expand_mode = 1
stretch_mode = 5
[node name="PrimaryLabel" type="Label" parent="Content"]
unique_name_in_owner = true
layout_mode = 2
mouse_filter = 2
theme_override_font_sizes/font_size = 18
horizontal_alignment = 1
text_overrun_behavior = 3
[node name="SecondaryLabel" type="Label" parent="Content"]
unique_name_in_owner = true
layout_mode = 2
mouse_filter = 2
theme_override_colors/font_color = Color(0.16, 0.25, 0.29, 0.78)
theme_override_font_sizes/font_size = 15
horizontal_alignment = 1
[node name="FavoriteMarker" type="Label" parent="."]
unique_name_in_owner = true
visible = false
layout_mode = 0
offset_left = 102.0
offset_top = 12.0
offset_right = 132.0
offset_bottom = 42.0
mouse_filter = 2
theme_override_colors/font_color = Color(1, 0.82, 0.4, 1)
theme_override_font_sizes/font_size = 23
text = "★"
horizontal_alignment = 1
[node name="SelectedMarker" type="Label" parent="."]
unique_name_in_owner = true
visible = false
layout_mode = 0
offset_left = 14.0
offset_top = 10.0
offset_right = 42.0
offset_bottom = 38.0
mouse_filter = 2
theme_override_colors/font_color = Color(0.035, 0.145, 0.22, 1)
theme_override_font_sizes/font_size = 22
text = "✓"
horizontal_alignment = 1

View file

@ -0,0 +1,18 @@
class_name BubbleStatusBubble
extends PanelContainer
@export var profile: BubbleMenuProfile
@onready var _heading: Label = %Heading
@onready var _value: Label = %Value
func _ready() -> void:
mouse_filter = Control.MOUSE_FILTER_IGNORE
if profile != null:
add_theme_stylebox_override("panel", profile.make_normal_style())
func set_content(heading: String, value: String) -> void:
_heading.text = heading
_value.text = value

View file

@ -0,0 +1 @@
uid://bubblestatusbubble

View file

@ -0,0 +1,32 @@
[gd_scene load_steps=3 format=3]
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_status_bubble.gd" id="1_status"]
[ext_resource type="Resource" path="res://ui/components/bubble_menu/bubble_menu_profile.tres" id="2_profile"]
[node name="BubbleStatusBubble" type="PanelContainer"]
custom_minimum_size = Vector2(128, 88)
mouse_filter = 2
script = ExtResource("1_status")
profile = ExtResource("2_profile")
[node name="Labels" type="VBoxContainer" parent="."]
layout_mode = 2
mouse_filter = 2
theme_override_constants/separation = 0
alignment = 1
[node name="Heading" type="Label" parent="Labels"]
unique_name_in_owner = true
layout_mode = 2
mouse_filter = 2
theme_override_font_sizes/font_size = 15
text = "status"
horizontal_alignment = 1
[node name="Value" type="Label" parent="Labels"]
unique_name_in_owner = true
layout_mode = 2
mouse_filter = 2
theme_override_font_sizes/font_size = 21
text = "0"
horizontal_alignment = 1