MP3 Player UI

This commit is contained in:
Rob Kelly 2025-06-26 23:34:01 -06:00
parent fce4d1f7fd
commit db467e10c9
22 changed files with 634 additions and 70 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -16,12 +16,12 @@ Rendering=null
antialiasing=1
generate_mipmaps=true
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false
multichannel_signed_distance_field=true
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
hinting=1
hinting=0
subpixel_positioning=4
keep_rounding_remainders=true
oversampling=0.0

Binary file not shown.

View File

@ -0,0 +1,35 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://dass4iqsje7pl"
path="res://.godot/imported/Silkscreen-Sharp.ttf-dcb5c83ebb8ea0d97782b63dc405147a.fontdata"
[deps]
source_file="res://assets/fonts/Silkscreen/Silkscreen-Sharp.ttf"
dest_files=["res://.godot/imported/Silkscreen-Sharp.ttf-dcb5c83ebb8ea0d97782b63dc405147a.fontdata"]
[params]
Rendering=null
antialiasing=0
generate_mipmaps=true
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
hinting=0
subpixel_positioning=4
keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}

BIN
assets/ui/hud/tools/mp3_player_screen_mask.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cithtj8fu8pco"
path="res://.godot/imported/mp3_player_screen_mask.png-4d17c6b0038ffdb0f03053b122a1f827.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/ui/hud/tools/mp3_player_screen_mask.png"
dest_files=["res://.godot/imported/mp3_player_screen_mask.png-4d17c6b0038ffdb0f03053b122a1f827.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=23 format=3 uid="uid://bov4ok76woyc"]
[gd_scene load_steps=22 format=3 uid="uid://bov4ok76woyc"]
[ext_resource type="PackedScene" uid="uid://crydi5cjgfwe5" path="res://levels/ghost_ship/ghost_ship_level.tscn" id="1_aj2m7"]
[ext_resource type="Environment" uid="uid://bkvij3ljl5ox3" path="res://levels/ghost_ship/environment_3.tres" id="1_h081y"]
@ -7,7 +7,6 @@
[ext_resource type="PackedScene" uid="uid://d1kacn4b60ucy" path="res://src/ui/post_processing.tscn" id="3_o7mxe"]
[ext_resource type="AudioStream" uid="uid://dx4d8a3mgpws" path="res://assets/sfx/ambient/drone_loop.wav" id="5_ejh2c"]
[ext_resource type="Script" uid="uid://441gcyrbv0jd" path="res://levels/ghost_ship/ambient_drone.gd" id="5_jiowi"]
[ext_resource type="Script" uid="uid://btwfewn35d0hm" path="res://src/items/item.gd" id="6_4mbcm"]
[ext_resource type="PackedScene" uid="uid://dd21uy6yfgg51" path="res://src/effects/creaker/creaker.tscn" id="7_vdioa"]
[ext_resource type="AudioStream" uid="uid://cqh31d5my7fst" path="res://assets/sfx/ambient/metal_creak1.wav" id="8_ihj8k"]
[ext_resource type="AudioStream" uid="uid://cfvdtl1n42bis" path="res://assets/sfx/ambient/metal_creak2.wav" id="9_d2iql"]
@ -60,20 +59,6 @@ environment = ExtResource("1_h081y")
transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 1, 0)
[node name="Player" parent="PlayerSpawn" instance=ExtResource("2_0ef5p")]
godmode = false
dead = false
movement_enabled = true
activity_enabled = true
look_enabled = true
run_speed = 80.0
sprint_speed = 160.0
sneak_speed = 40.0
focus_speed = 25.0
air_speed_factor = 0.1
jump_force = 4.0
ground_friction = 0.3
air_friction = 0.03
inventory = Dictionary[ExtResource("6_4mbcm"), int]({})
[node name="PlayerShipArea" type="Area3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0)

View File

@ -1,9 +1,8 @@
[gd_scene load_steps=32 format=4 uid="uid://b8rv6dg4tgaeb"]
[gd_scene load_steps=31 format=4 uid="uid://b8rv6dg4tgaeb"]
[ext_resource type="Script" uid="uid://bvua1l2hb3an6" path="res://levels/mechanic_test/mechanic_test.gd" id="1_iyuyb"]
[ext_resource type="PackedScene" uid="uid://bwe2jdmvinhqd" path="res://src/player/player.tscn" id="2_qjnj2"]
[ext_resource type="PackedScene" uid="uid://b6eg8t04rkh0c" path="res://src/props/wall_switch/wall_switch.tscn" id="3_awnx0"]
[ext_resource type="Script" uid="uid://btwfewn35d0hm" path="res://src/items/item.gd" id="3_qjnj2"]
[ext_resource type="PackedScene" uid="uid://c2omlx4ptrc01" path="res://src/world/gunk_body/gunk_body.tscn" id="4_cgmn0"]
[ext_resource type="Texture2D" uid="uid://8cm835h4gxwe" path="res://assets/debug_mask.png" id="5_aix42"]
[ext_resource type="Shader" uid="uid://ckxc0ngd37rtk" path="res://src/shaders/gunk.gdshader" id="6_6frcc"]
@ -104,7 +103,7 @@ seamless = true
seamless_blend_skirt = 0.5
noise = ExtResource("7_7cbja")
[sub_resource type="ShaderMaterial" id="ShaderMaterial_awnx0"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_iyuyb"]
resource_local_to_scene = true
render_priority = 0
shader = ExtResource("6_6frcc")
@ -139,20 +138,6 @@ pretty_name = "Mechanics Test Sandbox"
[node name="Player" parent="." instance=ExtResource("2_qjnj2")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.65, 0)
godmode = false
dead = false
movement_enabled = true
activity_enabled = true
look_enabled = true
run_speed = 80.0
sprint_speed = 160.0
sneak_speed = 40.0
focus_speed = 25.0
air_speed_factor = 0.1
jump_force = 4.0
ground_friction = 0.3
air_friction = 0.03
inventory = Dictionary[ExtResource("3_qjnj2"), int]({})
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
transform = Transform3D(0.866025, -0.156955, -0.474726, 0.5, 0.271854, 0.82225, 0, -0.949453, 0.31391, 0, 0, 0)
@ -255,7 +240,7 @@ skeleton = NodePath("GunkHallBody")
[node name="GunkHallBody" parent="GunkHall" instance=ExtResource("4_cgmn0")]
unique_name_in_owner = true
initial_mask = ExtResource("5_aix42")
source_gunk_material = SubResource("ShaderMaterial_awnx0")
source_gunk_material = SubResource("ShaderMaterial_iyuyb")
[node name="CollisionShape3D" type="CollisionShape3D" parent="GunkHall/GunkHallBody"]
shape = SubResource("ConcavePolygonShape3D_qjnj2")

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=41 format=3 uid="uid://dc4tts6342cuj"]
[gd_scene load_steps=40 format=3 uid="uid://dc4tts6342cuj"]
[ext_resource type="Script" uid="uid://dmbdkydqnbyqv" path="res://levels/prop_test/prop_test.gd" id="1_ibd1t"]
[ext_resource type="PackedScene" uid="uid://bwe2jdmvinhqd" path="res://src/player/player.tscn" id="1_ml0ka"]
@ -31,7 +31,6 @@
[ext_resource type="Texture2D" uid="uid://gbvtbiurxrop" path="res://assets/props/vending_machine/vending_machine_R.png" id="27_8a67w"]
[ext_resource type="Script" uid="uid://deg5xd87cy8rg" path="res://src/props/interactive.gd" id="28_ibd1t"]
[ext_resource type="PackedScene" uid="uid://d1kacn4b60ucy" path="res://src/ui/post_processing.tscn" id="30_qnhar"]
[ext_resource type="Script" uid="uid://btwfewn35d0hm" path="res://src/items/item.gd" id="32_8a67w"]
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_tm4v6"]
@ -407,20 +406,6 @@ visible = false
[node name="Player" parent="." instance=ExtResource("1_ml0ka")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
godmode = false
dead = false
movement_enabled = true
activity_enabled = true
look_enabled = true
run_speed = 80.0
sprint_speed = 160.0
sneak_speed = 40.0
focus_speed = 25.0
air_speed_factor = 0.1
jump_force = 4.0
ground_friction = 0.3
air_friction = 0.03
inventory = Dictionary[ExtResource("32_8a67w"), int]({})
[connection signal="animation_finished" from="Props/Bulkhead" to="Props/SwitchPodium/OpenSwitch" method="enable"]
[connection signal="activated" from="Props/SwitchPodium/OpenSwitch" to="Props/Bulkhead" method="toggle"]

View File

@ -0,0 +1,61 @@
class_name MP3Controller extends Control
## UI controller for the MP3 player
signal pause
signal resume
signal select_track(track_index: int)
var selecting := true
@onready var play_label: Label = %PlayLabel
@onready var pause_label: Label = %PauseLabel
@onready var retro_selector_list: RetroSelectorList = %RetroSelectorList
@onready var transition_player: AnimationPlayer = %TransitionPlayer
func set_paused(paused: bool) -> void:
play_label.visible = not paused
pause_label.visible = paused
if paused:
pause.emit()
else:
resume.emit()
func is_paused() -> bool:
return pause_label.visible
## One of two input buttons to the device
func select() -> void:
if transition_player.is_playing():
return
if selecting:
# If we're in track selection, play the selected track
selecting = false
transition_player.play("to_player")
else:
# If we're in player mode, toggle pause/play
set_paused(not is_paused())
func _emit_select_track() -> void:
select_track.emit(retro_selector_list.selection_idx)
set_paused(false)
## The other input button to the device
func cancel() -> void:
if transition_player.is_playing():
return
if selecting:
# If we're in track selection, advance selection to the next track
retro_selector_list.selection_idx += 1
else:
# If we're in player mode, pause playback and go to track selection
set_paused(true)
selecting = true
transition_player.play("to_selector")

View File

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

View File

@ -0,0 +1,237 @@
[gd_scene load_steps=8 format=3 uid="uid://dsaumps2w2p26"]
[ext_resource type="Theme" uid="uid://drq4sbm3i6uxt" path="res://src/equipment/mp3_player/player_ui_theme.tres" id="1_bwydb"]
[ext_resource type="Script" uid="uid://cbu05jn6it4p5" path="res://src/equipment/mp3_player/mp3_controller.gd" id="2_f300k"]
[ext_resource type="PackedScene" uid="uid://t11xpl4mtgvf" path="res://src/equipment/mp3_player/retro_selector_list.tscn" id="3_n8ehr"]
[sub_resource type="Animation" id="Animation_0xevb"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("RetroSelectorList:expanded")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [true]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("RetroSelectorList:position")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(0, 0)]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("NowPlaying:position")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(-70, 0)]
}
[sub_resource type="Animation" id="Animation_ywxng"]
resource_name = "to_player"
length = 0.7
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("RetroSelectorList:expanded")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("RetroSelectorList:position")
tracks/1/interp = 2
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0.333333, 0.566667),
"transitions": PackedFloat32Array(0.618, 1),
"update": 0,
"values": [Vector2(0, 0), Vector2(0, 64)]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("NowPlaying:position")
tracks/2/interp = 2
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0.29, 0.7),
"transitions": PackedFloat32Array(0.618, 1),
"update": 0,
"values": [Vector2(-70, 0), Vector2(0, 0)]
}
tracks/3/type = "method"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath(".")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0.333333),
"transitions": PackedFloat32Array(1),
"values": [{
"args": [],
"method": &"_emit_select_track"
}]
}
[sub_resource type="Animation" id="Animation_ryx3y"]
resource_name = "to_selector"
length = 0.5667
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("RetroSelectorList:expanded")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.533333),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [false, true]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("NowPlaying:position")
tracks/1/interp = 2
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 0.5667),
"transitions": PackedFloat32Array(1.618, 1),
"update": 0,
"values": [Vector2(0, 0), Vector2(-70, 0)]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("RetroSelectorList:position")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0.233333, 0.5667),
"transitions": PackedFloat32Array(1.618, 1),
"update": 0,
"values": [Vector2(0, 64), Vector2(0, 0)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_0xevb"]
_data = {
&"RESET": SubResource("Animation_0xevb"),
&"to_player": SubResource("Animation_ywxng"),
&"to_selector": SubResource("Animation_ryx3y")
}
[node name="MP3Controller" type="Control"]
texture_filter = 1
custom_minimum_size = Vector2(70, 76)
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_right = -1850.0
offset_bottom = -1004.0
grow_horizontal = 2
grow_vertical = 2
theme = ExtResource("1_bwydb")
script = ExtResource("2_f300k")
[node name="Background" type="ColorRect" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0.619608, 0.678431, 0.705882, 1)
[node name="NowPlaying" type="MarginContainer" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = -70.0
offset_right = -70.0
grow_horizontal = 2
grow_vertical = 2
theme_override_constants/margin_left = 2
theme_override_constants/margin_top = 2
theme_override_constants/margin_right = 2
theme_override_constants/margin_bottom = 2
[node name="NowPlaying" type="RichTextLabel" parent="NowPlaying"]
layout_mode = 2
bbcode_enabled = true
text = "[center][wave amp=20]now playing[/wave][/center]"
[node name="PlayPause" type="Control" parent="NowPlaying"]
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
[node name="PlayLabel" type="Label" parent="NowPlaying/PlayPause"]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -6.0
offset_top = -8.0
offset_right = 6.0
offset_bottom = 8.0
grow_horizontal = 2
grow_vertical = 2
theme_type_variation = &"IconLabel"
text = ""
[node name="PauseLabel" type="Label" parent="NowPlaying/PlayPause"]
unique_name_in_owner = true
visible = false
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -5.0
offset_top = -8.0
offset_right = 5.0
offset_bottom = 8.0
grow_horizontal = 2
grow_vertical = 2
theme_type_variation = &"IconLabel"
text = ""
[node name="RetroSelectorList" parent="." instance=ExtResource("3_n8ehr")]
unique_name_in_owner = true
offset_bottom = 11.0
[node name="TransitionPlayer" type="AnimationPlayer" parent="."]
unique_name_in_owner = true
libraries = {
&"": SubResource("AnimationLibrary_0xevb")
}

View File

@ -1,6 +1,18 @@
extends Tool
## Pump up the jamz!
@onready var mp3_controller: MP3Controller = %MP3Controller
func unlocked() -> bool:
return World.instance.manager.mp3_player_unlocked
func fire() -> void:
if not firing:
firing = true
mp3_controller.select()
func switch_mode() -> void:
mp3_controller.cancel()

View File

@ -4,10 +4,8 @@
[ext_resource type="Script" uid="uid://b274q7uvn0cvp" path="res://src/ui/rumbler_3d.gd" id="2_o7o6r"]
[ext_resource type="Texture2D" uid="uid://0wbowky48ign" path="res://assets/ui/hud/tools/mp3_player.png" id="3_de88k"]
[ext_resource type="Script" uid="uid://dj2x7x5qkbym1" path="res://src/ui/canvas_projector.gd" id="3_eysps"]
[ext_resource type="FontFile" uid="uid://oq8ue2qrfijg" path="res://assets/fonts/Silkscreen/Silkscreen-Regular.ttf" id="5_rb5mc"]
[sub_resource type="FontVariation" id="FontVariation_6lbfp"]
base_font = ExtResource("5_rb5mc")
[ext_resource type="Texture2D" uid="uid://cithtj8fu8pco" path="res://assets/ui/hud/tools/mp3_player_screen_mask.png" id="5_6lbfp"]
[ext_resource type="PackedScene" uid="uid://dsaumps2w2p26" path="res://src/equipment/mp3_player/mp3_controller.tscn" id="7_05qxf"]
[node name="MP3Player" type="Node3D"]
script = ExtResource("1_hjo3m")
@ -38,6 +36,7 @@ grow_horizontal = 2
grow_vertical = 2
[node name="DeviceTexture" type="TextureRect" parent="HUDTool/Rumbler/Position/HUDElement"]
texture_filter = 1
layout_mode = 0
offset_left = -290.0
offset_top = -231.0
@ -46,21 +45,40 @@ offset_bottom = 25.0
scale = Vector2(5, 5)
texture = ExtResource("3_de88k")
[node name="RichTextLabel" type="RichTextLabel" parent="HUDTool/Rumbler/Position/HUDElement"]
texture_filter = 4
[node name="DeviceScreenMask" type="TextureRect" parent="HUDTool/Rumbler/Position/HUDElement"]
clip_children = 1
texture_filter = 1
layout_mode = 0
offset_left = -96.0
offset_top = -170.0
offset_right = 155.0
offset_bottom = 109.0
rotation = 0.15708
theme_override_colors/default_color = Color(0, 0, 0, 1)
theme_override_fonts/normal_font = SubResource("FontVariation_6lbfp")
theme_override_font_sizes/normal_font_size = 30
bbcode_enabled = true
text = "[wave amp=50]hey kid i'm a computer[/wave]
offset_left = -290.0
offset_top = -231.0
offset_right = -162.0
offset_bottom = 25.0
scale = Vector2(5, 5)
texture = ExtResource("5_6lbfp")
[node name="SubViewportContainer" type="SubViewportContainer" parent="HUDTool/Rumbler/Position/HUDElement/DeviceScreenMask"]
texture_filter = 1
custom_minimum_size = Vector2(90, 90)
layout_mode = 0
offset_left = 21.2
offset_top = 9.4
offset_right = 111.2
offset_bottom = 99.4
scale = Vector2(0.825, 0.825)
[node name="SubViewport" type="SubViewport" parent="HUDTool/Rumbler/Position/HUDElement/DeviceScreenMask/SubViewportContainer"]
transparent_bg = true
handle_input_locally = false
size = Vector2i(90, 90)
render_target_update_mode = 4
stop all the downloadin
"
[node name="ScreenTransform" type="Marker2D" parent="HUDTool/Rumbler/Position/HUDElement/DeviceScreenMask/SubViewportContainer/SubViewport"]
texture_filter = 1
position = Vector2(17.939, -1)
rotation = 0.139626
skew = 0.0331613
[node name="MP3Controller" parent="HUDTool/Rumbler/Position/HUDElement/DeviceScreenMask/SubViewportContainer/SubViewport/ScreenTransform" instance=ExtResource("7_05qxf")]
unique_name_in_owner = true
offset_right = 70.0
offset_bottom = 76.0

View File

@ -0,0 +1,13 @@
[gd_resource type="Theme" load_steps=3 format=3 uid="uid://drq4sbm3i6uxt"]
[ext_resource type="FontFile" uid="uid://qadtckvw0t3l" path="res://assets/fonts/fontawesome-free-6.7.2-desktop/otfs/Font Awesome 6 Free-Solid-900.otf" id="1_umb73"]
[ext_resource type="FontFile" uid="uid://dass4iqsje7pl" path="res://assets/fonts/Silkscreen/Silkscreen-Sharp.ttf" id="2_umb73"]
[resource]
default_font = ExtResource("2_umb73")
default_font_size = 8
IconLabel/base_type = &"Label"
IconLabel/font_sizes/font_size = 27
IconLabel/fonts/font = ExtResource("1_umb73")
Label/colors/font_color = Color(0.333333, 0.403922, 0.439216, 1)
RichTextLabel/colors/default_color = Color(0.333333, 0.403922, 0.439216, 1)

View File

@ -0,0 +1,120 @@
@tool
class_name RetroSelectorList extends Control
const DEFAULT_HEIGHT := 76.0
const LINE_HEIGHT_PX := 11
const LINE_HEIGHT_OFFSET := 1
const SELECTION_SMOOTHING := 8.0
const BLINK_INTERVAL := 0.2
@export var options: Array[String] = []
@export var selection_idx := 0:
set(value):
selection_idx = wrapi(value, 0, options.size())
@export var expanded := true:
set(value):
if value != expanded:
if value:
expand()
else:
select_and_contract()
expanded = value
@export var tween_scale := 0.24
@export var debug_update_list: bool:
set(value):
if value:
_build_list()
var _active_tween: Tween
@onready var screen_bounds_container: Control = %ScreenBoundsContainer
@onready var title_list: VBoxContainer = %TitleList
@onready var selection_mask: ColorRect = %SelectionMask
func _ready() -> void:
_build_list()
func _build_list() -> void:
# Remove any existing items
for c: Node in title_list.get_children():
c.queue_free()
for item: String in options:
var item_label := Label.new()
item_label.text = item
item_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
title_list.add_child(item_label)
selection_idx = selection_idx % options.size()
func _new_tween() -> Tween:
if _active_tween and _active_tween.is_valid():
_active_tween.kill()
_active_tween = create_tween()
return _active_tween
func expand() -> Tween:
var tween := _new_tween()
tween.set_parallel(true)
(
tween
. tween_property(self, "size:y", DEFAULT_HEIGHT, tween_scale)
. set_trans(Tween.TRANS_CUBIC)
. set_ease(Tween.EASE_OUT)
)
(
tween
. tween_property(screen_bounds_container, "position:y", 0, tween_scale * 1.1)
. set_trans(Tween.TRANS_CUBIC)
. set_ease(Tween.EASE_OUT)
)
_active_tween = tween
selection_mask.show()
return tween
func select_and_contract() -> Tween:
var contract_subtween := contract()
var tween := create_tween()
_active_tween = tween
for i: int in range(3):
tween.tween_callback(selection_mask.hide)
tween.tween_interval(BLINK_INTERVAL * tween_scale)
tween.tween_callback(selection_mask.show)
tween.tween_interval(BLINK_INTERVAL * tween_scale)
tween.tween_subtween(contract_subtween)
return tween
func contract() -> Tween:
var tween := _new_tween()
tween.set_parallel(true)
(
tween
. tween_property(
screen_bounds_container, "position:y", -selection_mask.position.y, tween_scale * 1.1
)
. set_trans(Tween.TRANS_CUBIC)
. set_ease(Tween.EASE_OUT)
)
(
tween
. tween_property(self, "size:y", LINE_HEIGHT_PX, tween_scale)
. set_trans(Tween.TRANS_CUBIC)
. set_ease(Tween.EASE_OUT)
)
return tween
func _process(delta: float) -> void:
var target_position := selection_idx * LINE_HEIGHT_PX + LINE_HEIGHT_OFFSET
selection_mask.position.y = lerpf(
selection_mask.position.y, target_position, 1 - exp(-SELECTION_SMOOTHING * delta)
)

View File

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

View File

@ -0,0 +1,57 @@
[gd_scene load_steps=5 format=3 uid="uid://t11xpl4mtgvf"]
[ext_resource type="Script" uid="uid://qt6hnlakpqob" path="res://src/equipment/mp3_player/retro_selector_list.gd" id="1_kvinm"]
[ext_resource type="Theme" uid="uid://drq4sbm3i6uxt" path="res://src/equipment/mp3_player/player_ui_theme.tres" id="2_4rnpc"]
[ext_resource type="Shader" uid="uid://b6c7d34uvtssk" path="res://src/shaders/canvas_invert.gdshader" id="3_4rnpc"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_4rnpc"]
shader = ExtResource("3_4rnpc")
shader_parameter/fg_color = Color(0.333333, 0.403922, 0.439216, 1)
shader_parameter/bg_color = Color(0.619608, 0.678431, 0.705882, 1)
shader_parameter/threshold = 0.5
[node name="RetroSelectorList" type="Control"]
texture_filter = 1
clip_contents = true
layout_mode = 3
anchors_preset = 0
offset_right = 70.0
offset_bottom = 76.0
theme = ExtResource("2_4rnpc")
script = ExtResource("1_kvinm")
options = Array[String](["thing1", "thing2", "uhh", "thing4"])
[node name="ScreenBoundsContainer" type="Control" parent="."]
unique_name_in_owner = true
custom_minimum_size = Vector2(70, 76)
anchors_preset = 0
offset_right = 70.0
offset_bottom = 76.0
[node name="Background" type="ColorRect" parent="ScreenBoundsContainer"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0.619608, 0.678431, 0.705882, 1)
[node name="TitleList" type="VBoxContainer" parent="ScreenBoundsContainer"]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_constants/separation = 0
[node name="SelectionMask" type="ColorRect" parent="ScreenBoundsContainer"]
unique_name_in_owner = true
material = SubResource("ShaderMaterial_4rnpc")
custom_minimum_size = Vector2(70, 11)
layout_mode = 0
offset_top = 1.00001
offset_right = 70.0
offset_bottom = 12.0

View File

@ -0,0 +1,16 @@
shader_type canvas_item;
uniform sampler2D screen_tex: hint_screen_texture, repeat_disable, filter_nearest;
uniform vec3 fg_color: source_color = vec3(0.0);
uniform vec3 bg_color: source_color = vec3(1.0);
uniform float threshold = 0.5;
void fragment() {
vec4 color = texture(screen_tex, SCREEN_UV);
if (color.r < threshold) {
COLOR = vec4(bg_color, 1.0);
} else {
COLOR = vec4(fg_color, 1.0);
}
}

View File

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