Sort the scripts and scenes into folders
main/ holds the main window and top bar, quiz/ the quiz and its parts, player/ the music player, popups/ every popup and what they share, data/ the songs, players, playlist and settings, server/ the MusicServer client, common/ the list row and GameLog, and themes/ the themes and style boxes.
This commit is contained in:
1 parent
a0428e3475
commit
d77b72159d
115 files changed
+94
-84
No files matched your search
@@ -0,0 +1,61 @@
|
||||
[gd_scene format=3 uid="uid://cp54idaudb8dp"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://b7bh0of7olbcb" path="res://popups/about_popup.gd" id="1_about_script"]
|
||||
[ext_resource type="Theme" path="res://themes/popup_theme.tres" id="popup_theme"]
|
||||
|
||||
[node name="AboutPopup" type="Control" unique_id=1626010355 node_paths=PackedStringArray("panel")]
|
||||
theme = ExtResource("popup_theme")
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_about_script")
|
||||
panel = NodePath("AboutPanel")
|
||||
|
||||
[node name="AboutPanel" type="Panel" parent="." unique_id=1907299275]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_right = 600.0
|
||||
offset_bottom = 640.0
|
||||
|
||||
[node name="TitleLabel" type="Label" parent="AboutPanel" unique_id=200295721]
|
||||
layout_mode = 0
|
||||
offset_right = 600.0
|
||||
offset_bottom = 50.0
|
||||
text = "About"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="AboutPanel" unique_id=417677913]
|
||||
layout_mode = 0
|
||||
offset_left = 20.0
|
||||
offset_top = 50.0
|
||||
offset_right = 580.0
|
||||
offset_bottom = 630.0
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="ContentVBox" type="VBoxContainer" parent="AboutPanel/ScrollContainer" unique_id=1746337912]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="VersionLabel" type="Label" parent="AboutPanel/ScrollContainer/ContentVBox" unique_id=352884126]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="DescriptionLabel" type="Label" parent="AboutPanel/ScrollContainer/ContentVBox" unique_id=543094263]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Try your video game music knowledge with this VGM randomizer, invite your friends and see who is the best."
|
||||
horizontal_alignment = 1
|
||||
autowrap_mode = 2
|
||||
|
||||
[node name="WhatsNewLabel" type="Label" parent="AboutPanel/ScrollContainer/ContentVBox" unique_id=1363040291]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
autowrap_mode = 2
|
||||
@@ -0,0 +1,45 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://c7ecjj2af6usf"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://i35b3scbpwpu" path="res://popups/character_card.gd" id="1_pjt0s"]
|
||||
[ext_resource type="Texture2D" uid="uid://cv3hdd6bsruau" path="res://icon.svg" id="2_pjt0s"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_pjt0s"]
|
||||
bg_color = Color(0.302, 0.302, 0.302, 1)
|
||||
|
||||
[node name="CharacterCard" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
script = ExtResource("1_pjt0s")
|
||||
|
||||
[node name="Panel" type="Panel" parent="."]
|
||||
layout_mode = 0
|
||||
offset_right = 240.0
|
||||
offset_bottom = 145.0
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_pjt0s")
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="Panel"]
|
||||
layout_mode = 0
|
||||
offset_right = 240.0
|
||||
offset_bottom = 145.0
|
||||
theme_override_constants/margin_left = 15
|
||||
theme_override_constants/margin_top = 10
|
||||
theme_override_constants/margin_right = 15
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="Panel/MarginContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="CharacterTextureRect" type="TextureRect" parent="Panel/MarginContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(200, 100)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
texture = ExtResource("2_pjt0s")
|
||||
expand_mode = 3
|
||||
stretch_mode = 5
|
||||
|
||||
[node name="CharacterName" type="Label" parent="Panel/MarginContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "Aloy"
|
||||
horizontal_alignment = 1
|
||||
@@ -0,0 +1,59 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://cdy4kvemwaiom"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cvffg87wr6r3y" path="res://popups/character_select_popup.gd" id="1_h4tdp"]
|
||||
[ext_resource type="Theme" path="res://themes/popup_theme.tres" id="popup_theme"]
|
||||
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_p4iny"]
|
||||
font_size = 25
|
||||
|
||||
[node name="CharacterSelectPopup" type="Control" node_paths=PackedStringArray("panel")]
|
||||
theme = ExtResource("popup_theme")
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
script = ExtResource("1_h4tdp")
|
||||
panel = NodePath("CharacterPanel")
|
||||
|
||||
[node name="CharacterPanel" type="Panel" parent="."]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_right = 1290.0
|
||||
offset_bottom = 665.0
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="CharacterPanel"]
|
||||
layout_mode = 0
|
||||
offset_right = 1290.0
|
||||
offset_bottom = 659.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="TitleLabel" type="Label" parent="CharacterPanel/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 0
|
||||
text = "Character Select"
|
||||
label_settings = SubResource("LabelSettings_p4iny")
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="CharacterPanel/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 20
|
||||
theme_override_constants/margin_top = 10
|
||||
theme_override_constants/margin_right = 20
|
||||
theme_override_constants/margin_bottom = 10
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="CharacterPanel/VBoxContainer/MarginContainer"]
|
||||
custom_minimum_size = Vector2(0, 600)
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="CharacterGridContainer" type="GridContainer" parent="CharacterPanel/VBoxContainer/MarginContainer/ScrollContainer"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(1150, 600)
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/h_separation = 10
|
||||
theme_override_constants/v_separation = 10
|
||||
columns = 5
|
||||
|
||||
[node name="CloseTimer" type="Timer" parent="CharacterPanel"]
|
||||
unique_name_in_owner = true
|
||||
@@ -0,0 +1,47 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://bijh5h5yrivm3"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cw41y87l64qo7" path="res://popups/log_popup.gd" id="1_q72ua"]
|
||||
[ext_resource type="Theme" path="res://themes/popup_theme.tres" id="popup_theme"]
|
||||
|
||||
[node name="LogPopup" type="Control" node_paths=PackedStringArray("panel")]
|
||||
theme = ExtResource("popup_theme")
|
||||
custom_minimum_size = Vector2(700, 700)
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_q72ua")
|
||||
panel = NodePath("LogPanel")
|
||||
|
||||
[node name="LogPanel" type="Panel" parent="."]
|
||||
unique_name_in_owner = true
|
||||
visibility_layer = 513
|
||||
custom_minimum_size = Vector2(700, 700)
|
||||
layout_mode = 0
|
||||
offset_right = 700.0
|
||||
offset_bottom = 700.0
|
||||
|
||||
[node name="TitleLabel" type="Label" parent="LogPanel"]
|
||||
layout_mode = 0
|
||||
offset_top = 8.0
|
||||
offset_right = 700.0
|
||||
offset_bottom = 48.0
|
||||
theme_override_font_sizes/font_size = 25
|
||||
text = "Log"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="LogScrollContainer" type="ScrollContainer" parent="LogPanel"]
|
||||
layout_mode = 0
|
||||
offset_left = 20.0
|
||||
offset_top = 56.0
|
||||
offset_right = 680.0
|
||||
offset_bottom = 684.0
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="LogVBoxContainer" type="VBoxContainer" parent="LogPanel/LogScrollContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/separation = 1
|
||||
@@ -0,0 +1,56 @@
|
||||
[gd_scene format=3 uid="uid://btupbowehiyyu"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bsa6xg5xos6h7" path="res://popups/qr_popup.gd" id="1_qr_script"]
|
||||
[ext_resource type="Script" uid="uid://dynulhnyq5hpq" path="res://addons/kenyoni/qr_code/qr_code_rect.gd" id="2_jpsxt"]
|
||||
[ext_resource type="Theme" path="res://themes/popup_theme.tres" id="popup_theme"]
|
||||
|
||||
[node name="QRPopup" type="Control" unique_id=1996957585 node_paths=PackedStringArray("panel")]
|
||||
theme = ExtResource("popup_theme")
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_qr_script")
|
||||
panel = NodePath("QRPanel")
|
||||
|
||||
[node name="QRPanel" type="Panel" parent="." unique_id=1021365843]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_right = 450.0
|
||||
offset_bottom = 520.0
|
||||
|
||||
[node name="QRCodeRect" type="TextureRect" parent="QRPanel" unique_id=1054378438]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_left = 20.0
|
||||
offset_top = 20.0
|
||||
offset_right = 430.0
|
||||
offset_bottom = 430.0
|
||||
script = ExtResource("2_jpsxt")
|
||||
auto_update = true
|
||||
mode = 4
|
||||
error_correction = 3
|
||||
use_eci = true
|
||||
eci_value = 26
|
||||
data = ""
|
||||
auto_version = true
|
||||
auto_mask_pattern = true
|
||||
light_module_color = Color(1, 1, 1, 1)
|
||||
dark_module_color = Color(0, 0, 0, 1)
|
||||
auto_module_size = false
|
||||
module_size = 8
|
||||
quiet_zone_size = 4
|
||||
metadata/_custom_type_script = "uid://dynulhnyq5hpq"
|
||||
|
||||
[node name="URLLabel" type="Label" parent="QRPanel" unique_id=230761497]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_left = 20.0
|
||||
offset_top = 450.0
|
||||
offset_right = 430.0
|
||||
offset_bottom = 490.0
|
||||
text = "URL"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
@@ -0,0 +1,53 @@
|
||||
[gd_scene format=3 uid="uid://bxydgil1yifps"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bg5yo08638600" path="res://popups/search_popup.gd" id="1_m7bij"]
|
||||
[ext_resource type="Theme" path="res://themes/popup_theme.tres" id="popup_theme"]
|
||||
|
||||
[node name="SearchPopup" type="Control" unique_id=616238617 node_paths=PackedStringArray("panel")]
|
||||
theme = ExtResource("popup_theme")
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_m7bij")
|
||||
panel = NodePath("SearchPanel")
|
||||
|
||||
[node name="SearchPanel" type="Panel" parent="." unique_id=1262945994]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_right = 1152.0
|
||||
offset_bottom = 640.0
|
||||
|
||||
[node name="ClearButton" type="Button" parent="." unique_id=1549439398]
|
||||
layout_mode = 0
|
||||
offset_left = 936.0
|
||||
offset_top = 16.0
|
||||
offset_right = 1027.0
|
||||
offset_bottom = 56.0
|
||||
scale = Vector2(2, 2)
|
||||
focus_mode = 0
|
||||
action_mode = 0
|
||||
text = "Clear"
|
||||
|
||||
[node name="Searchbar" type="TextEdit" parent="." unique_id=2112669372]
|
||||
layout_mode = 0
|
||||
offset_left = 32.0
|
||||
offset_top = 16.0
|
||||
offset_right = 468.0
|
||||
offset_bottom = 56.0
|
||||
scale = Vector2(2, 2)
|
||||
placeholder_text = "Search"
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="." unique_id=213733486]
|
||||
layout_mode = 0
|
||||
offset_top = 128.0
|
||||
offset_right = 576.0
|
||||
offset_bottom = 384.0
|
||||
scale = Vector2(2, 2)
|
||||
|
||||
[node name="SearchResults" type="VBoxContainer" parent="ScrollContainer" unique_id=1567403144]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
@@ -0,0 +1,259 @@
|
||||
[gd_scene format=3 uid="uid://dldpeo5y3l5hq"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://dukqyjoduf1af" path="res://popups/settings_popup.gd" id="1_bt55j"]
|
||||
[ext_resource type="Theme" path="res://themes/popup_theme.tres" id="popup_theme"]
|
||||
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_3xrlm"]
|
||||
font_size = 25
|
||||
|
||||
[node name="SettingsPopup" type="Control" unique_id=1298840328 node_paths=PackedStringArray("panel")]
|
||||
theme = ExtResource("popup_theme")
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_bt55j")
|
||||
panel = NodePath("SettingsPanel")
|
||||
|
||||
[node name="SettingsPanel" type="Panel" parent="." unique_id=45537159]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_right = 500.0
|
||||
offset_bottom = 640.0
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="SettingsPanel" unique_id=1325795358]
|
||||
layout_mode = 0
|
||||
offset_left = 20.0
|
||||
offset_top = 8.0
|
||||
offset_right = 480.0
|
||||
offset_bottom = 632.0
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="SettingsPanel/ScrollContainer" unique_id=1796635163]
|
||||
clip_contents = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="Label" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=1111531402]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 0
|
||||
text = "Settings"
|
||||
label_settings = SubResource("LabelSettings_3xrlm")
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="StopAfterCurrentCheckButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=508305575]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
button_pressed = true
|
||||
action_mode = 0
|
||||
text = "Stop after current"
|
||||
|
||||
[node name="HideNextTrackCheckButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=1568244599]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
button_pressed = true
|
||||
action_mode = 0
|
||||
text = "Hide next track"
|
||||
|
||||
[node name="AddToDatabaseCheckButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=1673750542]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
action_mode = 0
|
||||
text = "Turn on played to database"
|
||||
|
||||
[node name="LowPlayedCheckButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=1672657048]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
action_mode = 0
|
||||
text = "Use low played mode"
|
||||
|
||||
[node name="HideBeginningCheckButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=1370617867]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
action_mode = 0
|
||||
text = "Hide beginning of songs"
|
||||
|
||||
[node name="HideForSecondsHBoxContainer" type="HBoxContainer" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=1368485120]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
|
||||
[node name="HideForSecondsTitle" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/HideForSecondsHBoxContainer" unique_id=1822369383]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Hide Start Seconds: "
|
||||
|
||||
[node name="HideForSecondsLabel" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/HideForSecondsHBoxContainer" unique_id=1580108945]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(48, 0)
|
||||
layout_mode = 2
|
||||
text = "5.0"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="LowerHideForSecondsButton" type="Button" parent="SettingsPanel/ScrollContainer/VBoxContainer/HideForSecondsHBoxContainer" unique_id=180643442]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(30, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
focus_mode = 0
|
||||
action_mode = 0
|
||||
text = "-1"
|
||||
|
||||
[node name="IncreaseHideForSecondsButton" type="Button" parent="SettingsPanel/ScrollContainer/VBoxContainer/HideForSecondsHBoxContainer" unique_id=340681770]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(30, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
focus_mode = 0
|
||||
action_mode = 0
|
||||
text = "+1"
|
||||
|
||||
[node name="HideLengthCheckButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=67806372]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
action_mode = 0
|
||||
text = "Hide length of songs"
|
||||
|
||||
[node name="HideTicksCheckButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=706322752]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
action_mode = 0
|
||||
text = "Hide ticks in playbar"
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=2140610992]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label2" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/HBoxContainer" unique_id=1892907487]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Winning Score: "
|
||||
|
||||
[node name="ScoreLabel" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/HBoxContainer" unique_id=444542662]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(48, 0)
|
||||
layout_mode = 2
|
||||
text = "20"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="LowerButton" type="Button" parent="SettingsPanel/ScrollContainer/VBoxContainer/HBoxContainer" unique_id=614806355]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(30, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
focus_mode = 0
|
||||
action_mode = 0
|
||||
text = "-1"
|
||||
|
||||
[node name="IncreaseButton" type="Button" parent="SettingsPanel/ScrollContainer/VBoxContainer/HBoxContainer" unique_id=1837169457]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(30, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
focus_mode = 0
|
||||
action_mode = 0
|
||||
text = "+1"
|
||||
|
||||
[node name="CacheHBoxContainer" type="HBoxContainer" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=658210492]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="CacheTitleLabel" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/CacheHBoxContainer" unique_id=365012193]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Predownload songs: "
|
||||
|
||||
[node name="CacheLabel" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/CacheHBoxContainer" unique_id=1558370172]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(48, 0)
|
||||
layout_mode = 2
|
||||
text = "1"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="LowerCacheButton" type="Button" parent="SettingsPanel/ScrollContainer/VBoxContainer/CacheHBoxContainer" unique_id=1990385038]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(30, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
focus_mode = 0
|
||||
action_mode = 0
|
||||
text = "-1"
|
||||
|
||||
[node name="IncreaseCacheButton" type="Button" parent="SettingsPanel/ScrollContainer/VBoxContainer/CacheHBoxContainer" unique_id=1806295533]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(30, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
focus_mode = 0
|
||||
action_mode = 0
|
||||
text = "+1"
|
||||
|
||||
[node name="InspirationHBoxContainer" type="HBoxContainer" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=1686756540]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="InspirationListSpeedTitle" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/InspirationHBoxContainer" unique_id=1397861506]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Inspiration List Speed: "
|
||||
|
||||
[node name="InspirationListSpeedLabel" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/InspirationHBoxContainer" unique_id=867387668]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(48, 0)
|
||||
layout_mode = 2
|
||||
text = "1"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="LowerInspirationSpeedButton" type="Button" parent="SettingsPanel/ScrollContainer/VBoxContainer/InspirationHBoxContainer" unique_id=845209534]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(30, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
focus_mode = 0
|
||||
action_mode = 0
|
||||
text = "-1"
|
||||
|
||||
[node name="IncreaseInspirationSpeedButton" type="Button" parent="SettingsPanel/ScrollContainer/VBoxContainer/InspirationHBoxContainer" unique_id=1122701153]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(30, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
focus_mode = 0
|
||||
action_mode = 0
|
||||
text = "+1"
|
||||
|
||||
[node name="SelectServerButton" type="OptionButton" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=434350694]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
selected = 0
|
||||
item_count = 5
|
||||
popup/item_0/text = "https://music.sanplex.xyz"
|
||||
popup/item_0/id = 1
|
||||
popup/item_1/text = "https://tmusic.sanplex.xyz"
|
||||
popup/item_1/id = 2
|
||||
popup/item_2/text = "https://rmusic.sanplex.xyz"
|
||||
popup/item_2/id = 3
|
||||
popup/item_3/text = "https://old-music.sanplex.xyz"
|
||||
popup/item_3/id = 4
|
||||
popup/item_4/text = "http://localhost:8080"
|
||||
popup/item_4/id = 5
|
||||
|
||||
[node name="FullscreenButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=400304684]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Fullscreen"
|
||||
|
||||
[node name="QuickSyncButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=49497448]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
button_pressed = true
|
||||
action_mode = 0
|
||||
text = "Quick sync"
|
||||
|
||||
[node name="LocalButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=905844805]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
disabled = true
|
||||
text = "Local"
|
||||
@@ -0,0 +1,50 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://bd1by80q1v27e"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://rolypd0cqd6h" path="res://popups/shortcuts_popup.gd" id="1_12pxi"]
|
||||
[ext_resource type="Theme" path="res://themes/popup_theme.tres" id="popup_theme"]
|
||||
|
||||
[node name="ShortcutsPopup" type="Control" node_paths=PackedStringArray("panel")]
|
||||
theme = ExtResource("popup_theme")
|
||||
custom_minimum_size = Vector2(700, 700)
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_12pxi")
|
||||
panel = NodePath("ShortcutsPanel")
|
||||
|
||||
[node name="ShortcutsPanel" type="Panel" parent="."]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(700, 700)
|
||||
layout_mode = 0
|
||||
offset_right = 40.0
|
||||
offset_bottom = 40.0
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="ShortcutsPanel"]
|
||||
custom_minimum_size = Vector2(700, 700)
|
||||
layout_mode = 0
|
||||
offset_right = 40.0
|
||||
offset_bottom = 40.0
|
||||
|
||||
[node name="shortcutsVBox" type="VBoxContainer" parent="ShortcutsPanel/ScrollContainer"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(700, 700)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="ShortcutsPanel/ScrollContainer/shortcutsVBox"]
|
||||
layout_mode = 2
|
||||
alignment = 1
|
||||
|
||||
[node name="Label" type="Label" parent="ShortcutsPanel/ScrollContainer/shortcutsVBox/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "testar"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="Label2" type="Label" parent="ShortcutsPanel/ScrollContainer/shortcutsVBox/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "testera 2"
|
||||
horizontal_alignment = 1
|
||||
@@ -0,0 +1,168 @@
|
||||
[gd_scene format=3 uid="uid://dpdem7pdxweb5"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://c3ejukwth512a" path="res://popups/sync_popup.gd" id="1_8ba47"]
|
||||
[ext_resource type="Theme" path="res://themes/popup_theme.tres" id="popup_theme"]
|
||||
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_anbfi"]
|
||||
font_size = 25
|
||||
|
||||
[node name="SyncPopup" type="Control" unique_id=1302914356 node_paths=PackedStringArray("panel")]
|
||||
theme = ExtResource("popup_theme")
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_8ba47")
|
||||
panel = NodePath("SyncPanel")
|
||||
|
||||
[node name="SyncPanel" type="Panel" parent="." unique_id=1714634204]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_right = 1500.0
|
||||
offset_bottom = 640.0
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="SyncPanel" unique_id=1289116349]
|
||||
layout_mode = 0
|
||||
offset_left = 20.0
|
||||
offset_top = 8.0
|
||||
offset_right = 1480.0
|
||||
offset_bottom = 632.0
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="SyncVBoxContainer" type="VBoxContainer" parent="SyncPanel/ScrollContainer" unique_id=1594735567]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/separation = 12
|
||||
|
||||
[node name="SyncTitleLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer" unique_id=2125198054]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 0
|
||||
text = "Sync"
|
||||
label_settings = SubResource("LabelSettings_anbfi")
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="SyncTime" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer" unique_id=1344333200]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "Sync time: "
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="NoChangesLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer" unique_id=1059308183]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 0
|
||||
text = "No changes since last sync"
|
||||
label_settings = SubResource("LabelSettings_anbfi")
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="ProgressHBoxContainer" type="HBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer" unique_id=196414805]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SyncProgressBar" type="ProgressBar" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/ProgressHBoxContainer" unique_id=719135231]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(1300, 0)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
step = 1.0
|
||||
rounded = true
|
||||
|
||||
[node name="SyncHBoxContainer" type="HBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer" unique_id=1156646398]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/separation = 16
|
||||
|
||||
[node name="SoundtracksAddedVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=897546696]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="SoundtracksAddedLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/SoundtracksAddedVBox" unique_id=535797768]
|
||||
layout_mode = 2
|
||||
text = "SoundtracksAdded"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="SoundtracksAddedSeparator" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=853642947]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SoundtracksReAddedVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=995736806]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="SoundtracksReAddedLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/SoundtracksReAddedVBox" unique_id=1142636525]
|
||||
layout_mode = 2
|
||||
text = "SoundtracksReAdded"
|
||||
|
||||
[node name="SoundtracksReAddedSeparator" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=1872445446]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SoundtracksChangedTitleVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=294212033]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="SoundtracksChangedTitleLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/SoundtracksChangedTitleVBox" unique_id=696960827]
|
||||
layout_mode = 2
|
||||
text = "SoundtracksChangedTitle"
|
||||
|
||||
[node name="SoundtracksChangedTitleSeparator" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=1730403036]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SoundtracksChangedContentVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=1470922281]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="SoundtracksChangedContentLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/SoundtracksChangedContentVBox" unique_id=1209639099]
|
||||
layout_mode = 2
|
||||
text = "SoundtracksChangedContent"
|
||||
|
||||
[node name="SoundtracksChangedContentSeparator" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=626592535]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SoundtracksRemovedVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=1174594338]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="SoundtracksRemovedLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/SoundtracksRemovedVBox" unique_id=877713862]
|
||||
layout_mode = 2
|
||||
text = "SoundtracksRemoved"
|
||||
|
||||
[node name="SoundtracksRemovedSeparator" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=839653516]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
|
||||
[node name="CaughtErrorsVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer" unique_id=63733711]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="CaughtErrorsLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/CaughtErrorsVBox" unique_id=1784389644]
|
||||
layout_mode = 2
|
||||
text = "CatchedErrors"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="RestartSyncButton" type="Button" parent="SyncPanel/ScrollContainer/SyncVBoxContainer" unique_id=372442237]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
custom_minimum_size = Vector2(200, 80)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
text = "Restart Sync"
|
||||
|
||||
[node name="SyncTimer" type="Timer" parent="." unique_id=1955169547]
|
||||
unique_name_in_owner = true
|
||||
@@ -0,0 +1,56 @@
|
||||
[gd_scene format=3 uid="uid://cxlsmxnrp0agh"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://dxpb22xbwf3t1" path="res://popups/winner_popup.gd" id="1_winner_script"]
|
||||
[ext_resource type="Texture2D" uid="uid://r4as0nmtoa7p" path="res://noCharacter.png" id="2_no_character"]
|
||||
[ext_resource type="Theme" path="res://themes/popup_theme.tres" id="popup_theme"]
|
||||
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_hr75l"]
|
||||
font_size = 35
|
||||
|
||||
[node name="WinnerPopup" type="Control" unique_id=1111111111 node_paths=PackedStringArray("panel")]
|
||||
theme = ExtResource("popup_theme")
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_winner_script")
|
||||
panel = NodePath("WinnerPanel")
|
||||
|
||||
[node name="WinnerPanel" type="Panel" parent="." unique_id=89212869]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_right = 500.0
|
||||
offset_bottom = 600.0
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="WinnerPanel" unique_id=471159349]
|
||||
layout_mode = 0
|
||||
offset_top = 25.0
|
||||
offset_right = 500.0
|
||||
offset_bottom = 282.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
alignment = 1
|
||||
|
||||
[node name="WinnerPicture" type="TextureRect" parent="WinnerPanel/VBoxContainer" unique_id=1543774067]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(480, 200)
|
||||
layout_mode = 2
|
||||
texture = ExtResource("2_no_character")
|
||||
expand_mode = 3
|
||||
stretch_mode = 5
|
||||
|
||||
[node name="WinnerLabel" type="Label" parent="WinnerPanel/VBoxContainer" unique_id=1437597286]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "Winner!"
|
||||
label_settings = SubResource("LabelSettings_hr75l")
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 2
|
||||
|
||||
[node name="PlayersList" type="VBoxContainer" parent="WinnerPanel/VBoxContainer" unique_id=471159350]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
@@ -0,0 +1,59 @@
|
||||
class_name AboutPopup
|
||||
extends BasePopup
|
||||
## Shows the game version and what is new in each version.
|
||||
|
||||
## What is new in each version, newest first.
|
||||
const WHATS_NEW: Dictionary = {
|
||||
"1.9.0": "Made improvements to the Search window
|
||||
Made small changes to the inspiration list scrolling
|
||||
Made small changes to the player list
|
||||
Changed the term game to soundtrack
|
||||
#28: Made changes to the sync window
|
||||
#34: Fixed bug in Character Select when clicking or scrolling",
|
||||
"1.8.5": "#9: New winner screen with positions of all players
|
||||
#32: New setting for how long to hide the beginning
|
||||
#33: Fixed bug with hiding beginning when song restarts",
|
||||
"1.8.0": "#14: Updated About page
|
||||
#15: Create new keymap page
|
||||
#20: The winner song can now be stopped
|
||||
#24: The speed of the inspiration list can now be changed
|
||||
#29: New settings to hide time left and things like that
|
||||
#31: Added a QR page",
|
||||
"1.7.0": "#22: Now block add player if player name is empty
|
||||
#23: Add a log for when points are given to players
|
||||
#25: Fixed some graphical stuff
|
||||
#26: Changed so the same character can be on a song multiple times
|
||||
#27: Turning off statistics after win",
|
||||
"1.6.1": "#17: Removed Debug text in release
|
||||
#18: Fixed bug with new character select screen",
|
||||
"1.6.0": "#1: Fixed bug with inspiration list not reloading after sync
|
||||
#2: New dialog for sync
|
||||
#4: Now downloads characters from the server
|
||||
#5: New character select screen
|
||||
#6: Now show progress during sync
|
||||
#7: Blocking all requests to the server during sync
|
||||
#8: Added functionality to cache more than one song",
|
||||
"1.5.0": "Made big changes to players and the song list and how the local song list works",
|
||||
"0.9.0-Beta": "Fixed settings and updated the player view",
|
||||
"0.8.0-Beta": "Fixed reset buttons and some other small things",
|
||||
"0.7.8-Beta": "Added shortcuts. Added dialog for winner. Started cleaning code.",
|
||||
"0.7.5-Beta": "Added settings menu, most things don't do anything yet",
|
||||
"0.7-Beta": "Can now hop between songs"
|
||||
}
|
||||
|
||||
@onready var about_panel: Panel = %AboutPanel
|
||||
@onready var version_label: Label = %VersionLabel
|
||||
@onready var whats_new_label: Label = %WhatsNewLabel
|
||||
|
||||
|
||||
func open() -> void:
|
||||
super()
|
||||
version_label.text = Settings.version
|
||||
|
||||
# Build changelog text with version headers
|
||||
var changelog_text: String = ""
|
||||
for version: String in WHATS_NEW.keys():
|
||||
changelog_text += "\n" + version + "\n"
|
||||
changelog_text += WHATS_NEW[version] + "\n"
|
||||
|
||||
whats_new_label.text = changelog_text
|
||||
@@ -0,0 +1 @@
|
||||
uid://b7bh0of7olbcb
|
||||
@@ -0,0 +1,38 @@
|
||||
class_name BasePopup
|
||||
extends Control
|
||||
## A window shown on top of the main window, such as Settings or About.
|
||||
##
|
||||
## Clicking outside [member panel] closes it. Popups that need to prepare or clean up
|
||||
## override [method open] or [method close] and call [code]super()[/code].
|
||||
|
||||
## The visible part of the popup. Clicks outside it close the popup.
|
||||
|
||||
@export var panel: Control
|
||||
|
||||
|
||||
## Shows the popup.
|
||||
func open() -> void:
|
||||
visible = true
|
||||
|
||||
|
||||
## Hides the popup.
|
||||
func close() -> void:
|
||||
visible = false
|
||||
|
||||
|
||||
## Opens the popup if it is closed and closes it if it is open.
|
||||
func toggle() -> void:
|
||||
if visible:
|
||||
close()
|
||||
else:
|
||||
open()
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if !visible || !(event is InputEventMouseButton) || !event.pressed:
|
||||
return
|
||||
var click: InputEventMouseButton = panel.make_input_local(event)
|
||||
if !Rect2(Vector2.ZERO, panel.size).has_point(click.position):
|
||||
close()
|
||||
# The click only closes the popup; it must not also press what is behind it
|
||||
get_viewport().set_input_as_handled()
|
||||
@@ -0,0 +1 @@
|
||||
uid://dwd4dcbujpv6p
|
||||
@@ -0,0 +1,48 @@
|
||||
class_name CharacterCard
|
||||
extends Control
|
||||
## One character in the character select popup: its picture and name. Clicking it picks
|
||||
## the character.
|
||||
|
||||
## Emitted with the character's picture when the card is clicked.
|
||||
|
||||
signal new_character_selected(img_texture: ImageTexture)
|
||||
|
||||
@onready var panel: Panel = $Panel
|
||||
@onready var character_image: TextureRect = %CharacterTextureRect
|
||||
@onready var character_name_label: Label = %CharacterName
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if visible && Settings.character_select_open:
|
||||
if event is InputEventMouseButton && event.is_pressed() \
|
||||
&& event.get_button_index() == MOUSE_BUTTON_LEFT:
|
||||
var local_event: InputEvent = make_input_local(event)
|
||||
if Rect2(Vector2(0, 0), panel.size).has_point(local_event.position):
|
||||
GameLog.debug(character_name_label.text)
|
||||
new_character_selected.emit(character_image.texture)
|
||||
|
||||
|
||||
## Shows [param character_name] and fetches its picture from the server.
|
||||
func set_character_name(character_name: String) -> void:
|
||||
panel.size = Vector2(240, 145)
|
||||
character_name_label.text = character_name.split(".")[0]
|
||||
character_name_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
var image_fetched: Callable = func image_fetched(image: PackedByteArray) -> void:
|
||||
var img: Image = Image.new()
|
||||
var err: Error = img.load_png_from_buffer(image)
|
||||
if err != OK:
|
||||
GameLog.debug("Character image is not a PNG, trying JPG: ", error_string(err))
|
||||
var err2: Error = img.load_jpg_from_buffer(image)
|
||||
if err2 != OK:
|
||||
GameLog.warning("Could not load the image for ", character_name, ": ",
|
||||
error_string(err2))
|
||||
var new_image: ImageTexture = ImageTexture.new()
|
||||
new_image.set_image(img)
|
||||
character_image.custom_minimum_size = Vector2(200, 100)
|
||||
character_image.size = Vector2(200, 100)
|
||||
character_image.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
|
||||
character_image.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
character_image.expand_mode = TextureRect.EXPAND_FIT_WIDTH_PROPORTIONAL
|
||||
character_image.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||
character_image.texture = new_image
|
||||
MusicServerClient.fetch_character_image(character_name, image_fetched)
|
||||
@@ -0,0 +1 @@
|
||||
uid://i35b3scbpwpu
|
||||
@@ -0,0 +1,65 @@
|
||||
class_name CharacterSelectPopup
|
||||
extends BasePopup
|
||||
|
||||
## Emitted with the picture of the character that was picked.
|
||||
signal character_selected(texture: ImageTexture)
|
||||
|
||||
var can_select_character: bool = false
|
||||
var character: PackedScene = preload("res://popups/CharacterCard.tscn")
|
||||
|
||||
@onready var character_panel: Panel = %CharacterPanel
|
||||
@onready var title_label: Label = %TitleLabel
|
||||
@onready var character_grid: GridContainer = %CharacterGridContainer
|
||||
@onready var close_timer: Timer = %CloseTimer
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
close_timer.timeout.connect(_on_close_timeout)
|
||||
|
||||
|
||||
func _on_close_timeout() -> void:
|
||||
GameLog.debug("_on_close_timeout!")
|
||||
Settings.character_select_open = false
|
||||
close_timer.stop()
|
||||
|
||||
|
||||
func load_characters() -> void:
|
||||
GameLog.debug("load_characters")
|
||||
var fetch_character_list: Callable = func fetch_character_list(list: Variant) -> void:
|
||||
GameLog.debug("fetch_character_list")
|
||||
Settings.delete_children(character_grid)
|
||||
if typeof(list) == TYPE_ARRAY:
|
||||
for character_name: String in list:
|
||||
GameLog.debug("character_name ", character_name)
|
||||
var character_box: CharacterCard = character.instantiate()
|
||||
character_grid.add_child(character_box)
|
||||
character_box.custom_minimum_size = Vector2(235, 145)
|
||||
character_box.size = Vector2(235, 145)
|
||||
character_box.set_character_name(character_name)
|
||||
character_box.new_character_selected.connect(_on_character_selected)
|
||||
MusicServerClient.fetch_character_list(fetch_character_list)
|
||||
|
||||
|
||||
func show_grid(player_name: String) -> void:
|
||||
GameLog.debug("show_grid")
|
||||
title_label.text = "Select character for " + player_name
|
||||
close_timer.stop()
|
||||
open()
|
||||
can_select_character = true
|
||||
Settings.character_select_open = true
|
||||
|
||||
|
||||
func close() -> void:
|
||||
super()
|
||||
Settings.character_select_open = false
|
||||
|
||||
|
||||
func _on_character_selected(texture: ImageTexture) -> void:
|
||||
GameLog.debug("_on_character_selected")
|
||||
# Not close(): character_select_open stays true until close_timer fires, so the click
|
||||
# that picked the character does not also select a song behind it
|
||||
visible = false
|
||||
if can_select_character:
|
||||
character_selected.emit(texture)
|
||||
close_timer.start()
|
||||
can_select_character = false
|
||||
@@ -0,0 +1 @@
|
||||
uid://cvffg87wr6r3y
|
||||
@@ -0,0 +1,28 @@
|
||||
class_name LogPopup
|
||||
extends BasePopup
|
||||
## The game log: a row with the time for each thing that happens in the quiz, such as a
|
||||
## player getting a point. Opened with Alt+L.
|
||||
|
||||
var log_rows: Array
|
||||
|
||||
@onready var log_panel: Panel = %LogPanel
|
||||
@onready var log_box: VBoxContainer = %LogVBoxContainer
|
||||
|
||||
|
||||
func add_log_row(text: String) -> void:
|
||||
var log_row: String = get_time() + text
|
||||
log_rows.append(log_row)
|
||||
log_box.add_child(make_log_label(log_row))
|
||||
|
||||
|
||||
func make_log_label(row: String) -> Label:
|
||||
var log_label: Label = Label.new()
|
||||
log_label.add_theme_font_size_override("font_size", 20)
|
||||
log_label.text = row
|
||||
log_label.autowrap_mode = TextServer.AUTOWRAP_WORD
|
||||
return log_label
|
||||
|
||||
|
||||
func get_time() -> String:
|
||||
var time: Dictionary = Time.get_time_dict_from_system()
|
||||
return "%02d:%02d:%02d " % [time.hour, time.minute, time.second]
|
||||
@@ -0,0 +1 @@
|
||||
uid://cw41y87l64qo7
|
||||
@@ -0,0 +1,31 @@
|
||||
class_name PopupBackdrop
|
||||
extends ColorRect
|
||||
## Dims everything behind an open popup and keeps clicks from reaching the buttons
|
||||
## under it.
|
||||
##
|
||||
## The backdrop sits above the rest of its parent and below the popups it belongs to.
|
||||
## Popups close themselves when clicked outside, and the backdrop keeps that click from
|
||||
## reaching the buttons behind them.
|
||||
|
||||
var _popups: Array[BasePopup] = []
|
||||
|
||||
|
||||
## Adds a backdrop to [param parent] and moves [param popups] above it. The backdrop
|
||||
## shows while any of them is open.
|
||||
static func add_to(parent: Control, popups: Array[BasePopup]) -> PopupBackdrop:
|
||||
var backdrop: PopupBackdrop = PopupBackdrop.new()
|
||||
backdrop.name = "PopupBackdrop"
|
||||
backdrop.color = Color(0, 0, 0, 0.55)
|
||||
backdrop.mouse_filter = Control.MOUSE_FILTER_STOP
|
||||
backdrop._popups = popups
|
||||
parent.add_child(backdrop)
|
||||
backdrop.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||||
for popup: BasePopup in popups:
|
||||
parent.move_child(popup, -1)
|
||||
popup.visibility_changed.connect(backdrop._update)
|
||||
backdrop._update()
|
||||
return backdrop
|
||||
|
||||
|
||||
func _update() -> void:
|
||||
visible = _popups.any(func(popup: BasePopup) -> bool: return popup.visible)
|
||||
@@ -0,0 +1 @@
|
||||
uid://swjhekc8beob
|
||||
@@ -0,0 +1,29 @@
|
||||
class_name QRPopup
|
||||
extends BasePopup
|
||||
## Shows a QR code with the address of the search page on the MusicServer, so players
|
||||
## can search for soundtracks on their phones.
|
||||
|
||||
@onready var qr_panel: Panel = $QRPanel
|
||||
@onready var qr_code_rect: QRCodeRect = %QRCodeRect
|
||||
@onready var url_label: Label = %URLLabel
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
qr_code_rect.light_module_color = Color.WHITE
|
||||
qr_code_rect.dark_module_color = Color.BLACK
|
||||
qr_code_rect.quiet_zone_size = 4
|
||||
|
||||
# Generate QR code for the search URL
|
||||
var url: String = Settings.default_path + "/search"
|
||||
qr_code_rect.data = url
|
||||
url_label.text = qr_code_rect.data
|
||||
GameLog.debug("QR code generated for: ", url)
|
||||
|
||||
|
||||
func open() -> void:
|
||||
super()
|
||||
# Regenerate QR code in case settings changed
|
||||
var url: String = Settings.default_path + "/search"
|
||||
qr_code_rect.data = url
|
||||
url_label.text = qr_code_rect.data
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://bsa6xg5xos6h7
|
||||
@@ -0,0 +1,196 @@
|
||||
class_name SearchPopup
|
||||
extends BasePopup
|
||||
## Searches every soundtrack on the server as you type. Matches ignore case, spaces and
|
||||
## special characters, and also find the letters in order with others in between.
|
||||
|
||||
var soundtracks: Array = []
|
||||
|
||||
## Each soundtrack as a Dictionary with its original, lowercase and cleaned name.
|
||||
var precomputed_soundtracks: Array = []
|
||||
|
||||
## Compiled patterns for the letters-in-order search, by cleaned search term.
|
||||
var regex_cache: Dictionary = {}
|
||||
|
||||
var label_pool: Array[Label] = []
|
||||
|
||||
@onready var search_list: VBoxContainer = %SearchResults
|
||||
@onready var search_panel: Panel = %SearchPanel
|
||||
@onready var clear_button: Button = $ClearButton
|
||||
@onready var search_bar: TextEdit = $Searchbar
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
clear_button.pressed.connect(clear)
|
||||
search_bar.grab_focus()
|
||||
search_bar.text_changed.connect(search)
|
||||
visibility_changed.connect(focus)
|
||||
|
||||
|
||||
func focus() -> void:
|
||||
if visible:
|
||||
search_bar.grab_focus()
|
||||
clear()
|
||||
|
||||
|
||||
func close() -> void:
|
||||
clear()
|
||||
super()
|
||||
|
||||
|
||||
func search() -> void:
|
||||
GameLog.debug(search_bar.text)
|
||||
var search_text: String = search_bar.text
|
||||
|
||||
if search_text == "":
|
||||
show_all_soundtracks()
|
||||
return
|
||||
|
||||
perform_search(search_text)
|
||||
|
||||
|
||||
func show_all_soundtracks() -> void:
|
||||
# Hide all visible labels and add to pool
|
||||
for child: Label in search_list.get_children():
|
||||
if child.visible:
|
||||
child.visible = false
|
||||
label_pool.append(child)
|
||||
|
||||
# Show all soundtracks in order
|
||||
for soundtrack: String in soundtracks:
|
||||
add_soundtrack_reuse(soundtrack)
|
||||
|
||||
|
||||
func perform_search(search_text: String) -> void:
|
||||
# Hide all visible labels and add to pool
|
||||
for child: Label in search_list.get_children():
|
||||
if child.visible:
|
||||
child.visible = false
|
||||
label_pool.append(child)
|
||||
|
||||
for soundtrack: String in find_matches(search_text):
|
||||
add_soundtrack_reuse(soundtrack)
|
||||
|
||||
|
||||
## Returns the soundtracks matching [param search_text], best matches first: plain
|
||||
## case-insensitive matches, then matches ignoring spaces and special characters,
|
||||
## then matches with the letters in order but not next to each other.
|
||||
func find_matches(search_text: String) -> Array[String]:
|
||||
var seen: Dictionary = {}
|
||||
var search_text_lower: String = search_text.to_lower()
|
||||
var clean_search_text: String = clean_term(search_text)
|
||||
|
||||
var matches: Array[String] = []
|
||||
|
||||
# Pass 1: Exact case-insensitive contains match on lowercase versions
|
||||
for i: int in range(precomputed_soundtracks.size()):
|
||||
var st_data: Dictionary = precomputed_soundtracks[i]
|
||||
if st_data["lowercase"].contains(search_text_lower):
|
||||
if not st_data["original"] in seen:
|
||||
seen[st_data["original"]] = true
|
||||
matches.append(st_data["original"])
|
||||
|
||||
# Pass 2: Contains match on cleaned terms
|
||||
for i: int in range(precomputed_soundtracks.size()):
|
||||
var st_data: Dictionary = precomputed_soundtracks[i]
|
||||
if st_data["cleaned"].contains(clean_search_text):
|
||||
if not st_data["original"] in seen:
|
||||
seen[st_data["original"]] = true
|
||||
matches.append(st_data["original"])
|
||||
|
||||
# Pass 3: Regex match on cleaned terms
|
||||
var regex: RegEx = compile_regex_cached(clean_search_text)
|
||||
for i: int in range(precomputed_soundtracks.size()):
|
||||
var st_data: Dictionary = precomputed_soundtracks[i]
|
||||
if regex.search(st_data["cleaned"]):
|
||||
if not st_data["original"] in seen:
|
||||
seen[st_data["original"]] = true
|
||||
matches.append(st_data["original"])
|
||||
|
||||
return matches
|
||||
|
||||
|
||||
## Cleans a term by removing spaces and replacing special characters.
|
||||
## Matches MusicServer's clean_term() function.
|
||||
func clean_term(term: String) -> String:
|
||||
return term.replace(" ", "").replace("é", "e").replace("+", "plus").replace("&", "and") \
|
||||
.replace("'n", "and").to_lower()
|
||||
|
||||
|
||||
## Compiles the letters-in-order pattern for [param search_term], once per term.
|
||||
func compile_regex_cached(search_term: String) -> RegEx:
|
||||
if not search_term in regex_cache:
|
||||
var regex: RegEx = RegEx.new()
|
||||
var regex_text: String = ".*"
|
||||
for letter: String in search_term:
|
||||
# Escape regex metacharacters so searches like "Q*bert" or "(Remix)" work
|
||||
if "\\^$.|?*+()[]{}".contains(letter):
|
||||
regex_text += "\\"
|
||||
regex_text += letter + ".*"
|
||||
regex.compile(regex_text)
|
||||
regex_cache[search_term] = regex
|
||||
return regex_cache[search_term]
|
||||
|
||||
|
||||
func add_soundtrack(soundtrack: String) -> void:
|
||||
# Backward compatibility - delegates to reuse version
|
||||
add_soundtrack_reuse(soundtrack)
|
||||
|
||||
|
||||
## Shows [param soundtrack], reusing a hidden label from the pool when there is one.
|
||||
func add_soundtrack_reuse(soundtrack: String) -> void:
|
||||
var label: Label
|
||||
if label_pool.size() > 0:
|
||||
label = label_pool.pop_front()
|
||||
label.text = soundtrack
|
||||
label.visible = true
|
||||
# Move to end to maintain display order
|
||||
search_list.move_child(label, search_list.get_child_count() - 1)
|
||||
else:
|
||||
label = Label.new()
|
||||
label.text = soundtrack
|
||||
label.autowrap_mode = TextServer.AUTOWRAP_WORD
|
||||
search_list.add_child(label)
|
||||
label.visible = true
|
||||
|
||||
|
||||
func check_if_soundtrack_exists(soundtrack: String) -> bool:
|
||||
var soundtrack_exists: bool = false
|
||||
for child: Label in search_list.get_children():
|
||||
if child.text == soundtrack and child.visible:
|
||||
soundtrack_exists = true
|
||||
return soundtrack_exists
|
||||
|
||||
|
||||
func get_list_of_soundtracks() -> void:
|
||||
GameLog.debug("get_list_of_soundtracks")
|
||||
var handle_soundtracks: Callable = func handle_soundtracks(array: Variant) -> void:
|
||||
if typeof(array) == TYPE_ARRAY:
|
||||
# Reuse existing labels: hide all and add to pool
|
||||
for child: Label in search_list.get_children():
|
||||
child.visible = false
|
||||
label_pool.append(child)
|
||||
set_soundtracks(array)
|
||||
for soundtrack: String in soundtracks:
|
||||
add_soundtrack_reuse(soundtrack)
|
||||
else:
|
||||
GameLog.warning("Unexpected data")
|
||||
MusicServerClient.fetch_all_soundtracks_ordered(handle_soundtracks)
|
||||
|
||||
|
||||
## Replaces the searchable soundtracks and precomputes their search forms.
|
||||
func set_soundtracks(list: Array) -> void:
|
||||
soundtracks = []
|
||||
precomputed_soundtracks = []
|
||||
soundtracks.append_array(list)
|
||||
for soundtrack: String in soundtracks:
|
||||
precomputed_soundtracks.append({
|
||||
"original": soundtrack,
|
||||
"lowercase": soundtrack.to_lower(),
|
||||
"cleaned": clean_term(soundtrack)
|
||||
})
|
||||
|
||||
|
||||
func clear() -> void:
|
||||
search_bar.text = ""
|
||||
show_all_soundtracks()
|
||||
search_bar.grab_focus()
|
||||
@@ -0,0 +1 @@
|
||||
uid://bg5yo08638600
|
||||
@@ -0,0 +1,208 @@
|
||||
class_name SettingsPopup
|
||||
extends BasePopup
|
||||
## The settings: how songs are shown and played, the winning score, the song cache,
|
||||
## which MusicServer to use and fullscreen.
|
||||
|
||||
## Emitted when another MusicServer is picked.
|
||||
signal server_changed
|
||||
|
||||
@onready var settings_panel: Panel = %SettingsPanel
|
||||
@onready var stop_after_current_button: CheckButton = %StopAfterCurrentCheckButton
|
||||
@onready var hide_next_track_button: CheckButton = %HideNextTrackCheckButton
|
||||
@onready var add_to_database_button: CheckButton = %AddToDatabaseCheckButton
|
||||
@onready var low_played_button: CheckButton = %LowPlayedCheckButton
|
||||
@onready var hide_beginning_button: CheckButton = %HideBeginningCheckButton
|
||||
@onready var hide_length_button: CheckButton = %HideLengthCheckButton
|
||||
@onready var hide_ticks_button: CheckButton = %HideTicksCheckButton
|
||||
@onready var score_label: Label = %ScoreLabel
|
||||
@onready var lower_winning_score_button: Button = %LowerButton
|
||||
@onready var increase_winning_score_button: Button = %IncreaseButton
|
||||
@onready var cache_label: Label = %CacheLabel
|
||||
@onready var lower_cache_button: Button = %LowerCacheButton
|
||||
@onready var increase_cache_button: Button = %IncreaseCacheButton
|
||||
@onready var inspiration_speed_label: Label = %InspirationListSpeedLabel
|
||||
@onready var lower_inspiration_speed_button: Button = %LowerInspirationSpeedButton
|
||||
@onready var increase_inspiration_speed_button: Button = %IncreaseInspirationSpeedButton
|
||||
@onready var hide_for_seconds_label: Label = %HideForSecondsLabel
|
||||
@onready var lower_hide_for_seconds_button: Button = %LowerHideForSecondsButton
|
||||
@onready var increase_hide_for_seconds_button: Button = %IncreaseHideForSecondsButton
|
||||
@onready var select_server_button: OptionButton = %SelectServerButton
|
||||
@onready var fullscreen_button: CheckButton = %FullscreenButton
|
||||
@onready var local_button: CheckButton = %LocalButton
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
fullscreen_button.button_pressed = Settings.fullscreen
|
||||
select_server_button.selected = Settings.selected_server
|
||||
|
||||
stop_after_current_button.pressed.connect(stop_after_current)
|
||||
hide_next_track_button.pressed.connect(hide_next_track)
|
||||
add_to_database_button.pressed.connect(add_to_database)
|
||||
low_played_button.pressed.connect(low_played)
|
||||
hide_beginning_button.pressed.connect(hide_beginning)
|
||||
hide_length_button.pressed.connect(hide_length)
|
||||
hide_ticks_button.pressed.connect(hide_ticks)
|
||||
lower_winning_score_button.pressed.connect(lower_winning_score)
|
||||
increase_winning_score_button.pressed.connect(increase_winning_score)
|
||||
lower_cache_button.pressed.connect(lower_cache)
|
||||
increase_cache_button.pressed.connect(increase_cache)
|
||||
lower_inspiration_speed_button.pressed.connect(lower_inspiration_speed)
|
||||
increase_inspiration_speed_button.pressed.connect(increase_inspiration_speed)
|
||||
lower_hide_for_seconds_button.pressed.connect(lower_hide_for_seconds)
|
||||
increase_hide_for_seconds_button.pressed.connect(increase_hide_for_seconds)
|
||||
fullscreen_button.pressed.connect(fullscreen)
|
||||
local_button.pressed.connect(local_play)
|
||||
|
||||
stop_after_current_button.button_pressed = Settings.stop_after_current
|
||||
hide_next_track_button.button_pressed = Settings.hide_next_track
|
||||
add_to_database_button.button_pressed = Settings.add_to_stats
|
||||
low_played_button.button_pressed = Settings.use_low_played_mode
|
||||
hide_beginning_button.button_pressed = Settings.hide_beginning
|
||||
hide_length_button.button_pressed = Settings.hide_length
|
||||
hide_ticks_button.button_pressed = Settings.hide_ticks
|
||||
score_label.text = str(Settings.winning_score)
|
||||
cache_label.text = str(Playlist.number_of_tracks_to_preload)
|
||||
inspiration_speed_label.text = str(Settings.inspiration_list_speed)
|
||||
hide_for_seconds_label.text = str(Settings.hide_for_seconds)
|
||||
fullscreen_button.button_pressed = Settings.fullscreen
|
||||
update_hide_for_seconds_enabled()
|
||||
select_server_button.select(Settings.selected_server)
|
||||
select_server_button.item_selected.connect(select_server)
|
||||
visibility_changed.connect(_on_visibility_changed)
|
||||
# Alt+Enter switches fullscreen from the main window, which resizes the window
|
||||
get_window().size_changed.connect(_update_fullscreen_button)
|
||||
|
||||
|
||||
# Settings can change outside this popup, e.g. winning turns statistics off
|
||||
func _on_visibility_changed() -> void:
|
||||
if visible:
|
||||
add_to_database_button.button_pressed = Settings.add_to_stats
|
||||
_update_fullscreen_button()
|
||||
|
||||
|
||||
func _update_fullscreen_button() -> void:
|
||||
fullscreen_button.set_pressed_no_signal(Settings.fullscreen)
|
||||
|
||||
|
||||
func fullscreen() -> void:
|
||||
Settings.fullscreen = !Settings.fullscreen
|
||||
if Settings.fullscreen:
|
||||
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
|
||||
if !Settings.fullscreen:
|
||||
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
|
||||
|
||||
|
||||
func local_play() -> void:
|
||||
Settings.play_local = !Settings.play_local
|
||||
|
||||
|
||||
func stop_after_current() -> void:
|
||||
Settings.stop_after_current = !Settings.stop_after_current
|
||||
|
||||
|
||||
func hide_next_track() -> void:
|
||||
Settings.hide_next_track = !Settings.hide_next_track
|
||||
|
||||
|
||||
func add_to_database() -> void:
|
||||
Settings.add_to_stats = !Settings.add_to_stats
|
||||
|
||||
|
||||
func low_played() -> void:
|
||||
Settings.use_low_played_mode = !Settings.use_low_played_mode
|
||||
|
||||
|
||||
func hide_beginning() -> void:
|
||||
Settings.hide_beginning = !Settings.hide_beginning
|
||||
update_hide_for_seconds_enabled()
|
||||
|
||||
|
||||
func update_hide_for_seconds_enabled() -> void:
|
||||
var enabled: bool = Settings.hide_beginning
|
||||
%HideForSecondsHBoxContainer.visible = enabled
|
||||
|
||||
|
||||
func hide_length() -> void:
|
||||
Settings.hide_length = !Settings.hide_length
|
||||
|
||||
|
||||
func hide_ticks() -> void:
|
||||
Settings.hide_ticks = !Settings.hide_ticks
|
||||
|
||||
|
||||
func lower_winning_score() -> void:
|
||||
Settings.winning_score = max(Settings.winning_score - 1, 1)
|
||||
score_label.text = str(Settings.winning_score)
|
||||
|
||||
|
||||
func increase_winning_score() -> void:
|
||||
Settings.winning_score += 1
|
||||
score_label.text = str(Settings.winning_score)
|
||||
|
||||
|
||||
func set_winning_score(new_score: int) -> void:
|
||||
Settings.winning_score = new_score
|
||||
score_label.text = str(Settings.winning_score)
|
||||
|
||||
|
||||
func lower_cache() -> void:
|
||||
Playlist.number_of_tracks_to_preload -= 1
|
||||
if Playlist.number_of_tracks_to_preload < 1:
|
||||
Playlist.number_of_tracks_to_preload = 1
|
||||
cache_label.text = str(Playlist.number_of_tracks_to_preload)
|
||||
|
||||
|
||||
func increase_cache() -> void:
|
||||
Playlist.number_of_tracks_to_preload += 1
|
||||
cache_label.text = str(Playlist.number_of_tracks_to_preload)
|
||||
|
||||
|
||||
func lower_inspiration_speed() -> void:
|
||||
Settings.inspiration_list_speed -= 1
|
||||
if Settings.inspiration_list_speed < 1:
|
||||
Settings.inspiration_list_speed = 1
|
||||
inspiration_speed_label.text = str(Settings.inspiration_list_speed)
|
||||
|
||||
|
||||
func increase_inspiration_speed() -> void:
|
||||
Settings.inspiration_list_speed += 1
|
||||
inspiration_speed_label.text = str(Settings.inspiration_list_speed )
|
||||
|
||||
|
||||
func lower_hide_for_seconds() -> void:
|
||||
Settings.hide_for_seconds -= 1.0
|
||||
if Settings.hide_for_seconds < 0:
|
||||
Settings.hide_for_seconds = 0
|
||||
hide_for_seconds_label.text = str(Settings.hide_for_seconds)
|
||||
|
||||
|
||||
func increase_hide_for_seconds() -> void:
|
||||
Settings.hide_for_seconds += 1.0
|
||||
if Settings.hide_for_seconds > 10.0:
|
||||
Settings.hide_for_seconds = 10.0
|
||||
hide_for_seconds_label.text = str(Settings.hide_for_seconds)
|
||||
|
||||
|
||||
func select_server(new_server: int) -> void:
|
||||
GameLog.debug("select_server")
|
||||
Settings.default_path = select_server_button.get_item_text(new_server)
|
||||
Settings.selected_server = new_server
|
||||
GameLog.debug("Settings.default_path: " + Settings.default_path)
|
||||
GameLog.debug("Settings.selected_server: " + str(Settings.selected_server))
|
||||
GameLog.debug("new_server: " + str(new_server))
|
||||
GameLog.debug("select_server_button.get_item_text(new_server): ",
|
||||
select_server_button.get_item_text(new_server))
|
||||
server_changed.emit()
|
||||
|
||||
|
||||
func set_selected_server(new_server: int) -> void:
|
||||
GameLog.debug("set_selected_server")
|
||||
select_server_button.select(new_server)
|
||||
Settings.default_path = select_server_button.get_item_text(new_server)
|
||||
Settings.selected_server = new_server
|
||||
GameLog.debug("Settings.default_path: " + Settings.default_path)
|
||||
GameLog.debug("Settings.selected_server: " + str(Settings.selected_server))
|
||||
GameLog.debug("new_server: " + str(new_server))
|
||||
GameLog.debug("select_server_button.get_item_text(new_server): ",
|
||||
select_server_button.get_item_text(new_server))
|
||||
server_changed.emit()
|
||||
@@ -0,0 +1 @@
|
||||
uid://dukqyjoduf1af
|
||||
@@ -0,0 +1,70 @@
|
||||
class_name ShortcutsPopup
|
||||
extends BasePopup
|
||||
## Lists the keyboard shortcuts. Opened with Alt+K or the Shortcuts button.
|
||||
|
||||
var shortcuts_dic: Dictionary = {
|
||||
"Alt + S": "Search",
|
||||
"Alt + A": "Add Players",
|
||||
"Alt + Z": "Reset",
|
||||
"Alt + X": "Play/Pause",
|
||||
"Alt + C": "Next Song",
|
||||
"Alt + V": "Show Answer",
|
||||
"Alt + L": "Show Debug Log",
|
||||
"Alt + K": "Show shortcuts",
|
||||
"Alt + Enter": "Fullscreen",
|
||||
"Alt + UP": "Volume up",
|
||||
"Alt + DOWN": "Volume down",
|
||||
"Alt + LEFT": "Jump back in song",
|
||||
"Alt + Ctrl + LEFT": "Restart song",
|
||||
"Alt + RIGHT": "Jump forward in song",
|
||||
"Alt + 1 - 9": "Give player point",
|
||||
"Alt + Ctrl + 1 - 9": "Take point from player",
|
||||
}
|
||||
|
||||
@onready var shortcuts_vbox: VBoxContainer = %shortcutsVBox
|
||||
@onready var shortcuts_panel: Panel = %ShortcutsPanel
|
||||
|
||||
|
||||
#Color(0.18, 0.18, 0.18)
|
||||
#Color(0.302, 0.302, 0.302)
|
||||
#Color(0.259, 0.259, 0.259)
|
||||
func _ready() -> void:
|
||||
shortcuts_dic.sort()
|
||||
Settings.delete_children(shortcuts_vbox)
|
||||
|
||||
var title: Label = Label.new()
|
||||
title.add_theme_font_size_override("font_size", 20)
|
||||
title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
title.text = "Shortcuts"
|
||||
shortcuts_vbox.add_child(title)
|
||||
|
||||
var count: int = 0
|
||||
for shortcut: String in shortcuts_dic.keys():
|
||||
var panel: PanelContainer = PanelContainer.new()
|
||||
var hbox: HBoxContainer = HBoxContainer.new()
|
||||
hbox.alignment = BoxContainer.ALIGNMENT_CENTER
|
||||
|
||||
var label: Label = Label.new()
|
||||
label.add_theme_font_size_override("font_size", 20)
|
||||
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
label.text = shortcut
|
||||
label.autowrap_mode = TextServer.AUTOWRAP_WORD
|
||||
label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
|
||||
var label2: Label = Label.new()
|
||||
label2.add_theme_font_size_override("font_size", 20)
|
||||
label2.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
label2.text = shortcuts_dic[shortcut]
|
||||
label2.autowrap_mode = TextServer.AUTOWRAP_WORD
|
||||
label2.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
|
||||
if count % 2 == 0:
|
||||
var new_stylebox_normal: Resource = panel.get_theme_stylebox("panel").duplicate()
|
||||
new_stylebox_normal.bg_color = Color(0.18, 0.18, 0.18)
|
||||
panel.add_theme_stylebox_override("panel", new_stylebox_normal)
|
||||
|
||||
hbox.add_child(label)
|
||||
hbox.add_child(label2)
|
||||
panel.add_child(hbox)
|
||||
shortcuts_vbox.add_child(panel)
|
||||
count += 1
|
||||
@@ -0,0 +1 @@
|
||||
uid://rolypd0cqd6h
|
||||
@@ -0,0 +1,227 @@
|
||||
class_name SyncPopup
|
||||
extends BasePopup
|
||||
## Asks the server to sync its soundtracks with the music folder, shows the progress,
|
||||
## and then lists what was added, changed or removed.
|
||||
|
||||
## Emitted when the server has started syncing.
|
||||
|
||||
signal sync_started
|
||||
## Emitted when the sync is done and its result is shown.
|
||||
signal sync_finished
|
||||
|
||||
var changes: bool = false
|
||||
var has_synced: bool = false
|
||||
|
||||
@onready var sync_panel: Panel = %SyncPanel
|
||||
@onready var sync_title_label: Label = %SyncTitleLabel
|
||||
@onready var no_changes_label: Label = %NoChangesLabel
|
||||
@onready var progress_hbox: HBoxContainer = %ProgressHBoxContainer
|
||||
@onready var sync_hbox: HBoxContainer = %SyncHBoxContainer
|
||||
@onready var sync_progress_bar: ProgressBar = %SyncProgressBar
|
||||
@onready var soundtracks_added_vbox: VBoxContainer = %SoundtracksAddedVBox
|
||||
@onready var soundtracks_added_separator: VSeparator = %SoundtracksAddedSeparator
|
||||
@onready var soundtracks_readded_vbox: VBoxContainer = %SoundtracksReAddedVBox
|
||||
@onready var soundtracks_readded_separator: VSeparator = %SoundtracksReAddedSeparator
|
||||
@onready var soundtracks_changed_title_vbox: VBoxContainer = %SoundtracksChangedTitleVBox
|
||||
@onready var soundtracks_changed_title_separator: VSeparator = %SoundtracksChangedTitleSeparator
|
||||
@onready var soundtracks_changed_content_vbox: VBoxContainer = %SoundtracksChangedContentVBox
|
||||
@onready var soundtracks_changed_content_separator: VSeparator = %SoundtracksChangedContentSeparator
|
||||
@onready var soundtracks_removed_vbox: VBoxContainer = %SoundtracksRemovedVBox
|
||||
@onready var soundtracks_removed_separator: VSeparator = %SoundtracksRemovedSeparator
|
||||
@onready var caught_errors_vbox: VBoxContainer = %CaughtErrorsVBox
|
||||
@onready var sync_time: Label = %SyncTime
|
||||
@onready var sync_timer: Timer = %SyncTimer
|
||||
@onready var restart_sync_button: Button = %RestartSyncButton
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
sync_timer.timeout.connect(_on_sync_timeout)
|
||||
restart_sync_button.pressed.connect(start_sync)
|
||||
restart_sync_button.visible = false
|
||||
|
||||
|
||||
## Lists [param data] under [param header_text] in [param vbox] and returns true, or hides
|
||||
## the column and its separator when there is nothing to list.
|
||||
func show_section_if_has_data(data: Variant, vbox: VBoxContainer, separator: VSeparator,
|
||||
header_text: String) -> bool:
|
||||
if data != null && data.size() > 0:
|
||||
vbox.visible = true
|
||||
make_list(data, vbox, header_text)
|
||||
return true
|
||||
else:
|
||||
vbox.visible = false
|
||||
separator.visible = false
|
||||
return false
|
||||
|
||||
|
||||
func start_sync() -> void:
|
||||
GameLog.debug("start_sync")
|
||||
visible = true
|
||||
if has_synced:
|
||||
# Already synced, just show the results
|
||||
show_sync_result()
|
||||
return
|
||||
var sync_request_sent: Callable = func sync_request_sent() -> void:
|
||||
sync_timer.start(0.75)
|
||||
Settings.currently_syncing = true
|
||||
sync_started.emit()
|
||||
show_sync_progress()
|
||||
if !Settings.currently_syncing:
|
||||
MusicServerClient.start_sync(sync_request_sent)
|
||||
|
||||
|
||||
func _on_sync_timeout() -> void:
|
||||
GameLog.debug("_on_sync_timeout!")
|
||||
var get_progress: Callable = func get_progress(data_received: Dictionary) -> void:
|
||||
GameLog.debug("get_progress")
|
||||
GameLog.debug("data_received: ", data_received)
|
||||
if data_received != null:
|
||||
if data_received.has("progress"):
|
||||
sync_progress_bar.value = int(data_received.progress)
|
||||
sync_time.text = data_received.time_spent if data_received.has("time_spent") else ""
|
||||
else:
|
||||
on_sync_finished(data_received)
|
||||
MusicServerClient.fetch_sync_progress(get_progress)
|
||||
|
||||
|
||||
func on_sync_finished(data_received: Dictionary) -> void:
|
||||
has_synced = true
|
||||
reset_sync_result()
|
||||
|
||||
if show_section_if_has_data(data_received.soundtracks_added, soundtracks_added_vbox,
|
||||
soundtracks_added_separator, "Added"):
|
||||
changes = true
|
||||
|
||||
if show_section_if_has_data(data_received.soundtracks_re_added, soundtracks_readded_vbox,
|
||||
soundtracks_readded_separator, "Re-added"):
|
||||
changes = true
|
||||
|
||||
var changed_titles: Variant = data_received.soundtracks_changed_title
|
||||
if changed_titles != null && changed_titles.size() > 0:
|
||||
changes = true
|
||||
Settings.delete_children(soundtracks_changed_title_vbox)
|
||||
make_header_label(soundtracks_changed_title_vbox, "Changed Title")
|
||||
var row: int = 0
|
||||
for old_soundtrack_title: String in changed_titles:
|
||||
var new_soundtrack_title: String = changed_titles[old_soundtrack_title]
|
||||
soundtracks_changed_title_vbox.add_child(make_soundtrack_row(
|
||||
old_soundtrack_title + "\nchanged title to\n" + new_soundtrack_title, row))
|
||||
row += 1
|
||||
soundtracks_changed_title_vbox.visible = true
|
||||
|
||||
if show_section_if_has_data(data_received.soundtracks_changed_content,
|
||||
soundtracks_changed_content_vbox, soundtracks_changed_content_separator,
|
||||
"Changed Content"):
|
||||
changes = true
|
||||
|
||||
if show_section_if_has_data(data_received.soundtracks_removed, soundtracks_removed_vbox,
|
||||
soundtracks_removed_separator, "Removed"):
|
||||
changes = true
|
||||
|
||||
# The server's name for the errors it caught
|
||||
if data_received.catched_errors != null && data_received.catched_errors.size() > 0:
|
||||
caught_errors_vbox.visible = true
|
||||
make_list(data_received.catched_errors, caught_errors_vbox, "Errors")
|
||||
|
||||
# Separators go only between visible columns, not after the last one
|
||||
var visible_sections: Array = []
|
||||
if soundtracks_added_vbox.visible:
|
||||
visible_sections.append("added")
|
||||
if soundtracks_readded_vbox.visible:
|
||||
visible_sections.append("readded")
|
||||
if soundtracks_changed_title_vbox.visible:
|
||||
visible_sections.append("changed_title")
|
||||
if soundtracks_changed_content_vbox.visible:
|
||||
visible_sections.append("changed_content")
|
||||
if soundtracks_removed_vbox.visible:
|
||||
visible_sections.append("removed")
|
||||
|
||||
# Show section separators only if there's a visible section after them
|
||||
for i: int in range(visible_sections.size()):
|
||||
var section: String = visible_sections[i]
|
||||
var separator_map: Dictionary = {
|
||||
"added": soundtracks_added_separator,
|
||||
"readded": soundtracks_readded_separator,
|
||||
"changed_title": soundtracks_changed_title_separator,
|
||||
"changed_content": soundtracks_changed_content_separator,
|
||||
"removed": soundtracks_removed_separator
|
||||
}
|
||||
# Show this section's separator only if there's a next section
|
||||
if i < visible_sections.size() - 1:
|
||||
separator_map[section].visible = true
|
||||
else:
|
||||
separator_map[section].visible = false
|
||||
|
||||
if !changes:
|
||||
no_changes_label.visible = true
|
||||
sync_time.text = "Total time: " + data_received.total_time \
|
||||
if data_received.has("total_time") else ""
|
||||
Settings.currently_syncing = false
|
||||
sync_timer.stop()
|
||||
GameLog.debug("sync finished")
|
||||
show_sync_result()
|
||||
restart_sync_button.visible = true
|
||||
sync_finished.emit()
|
||||
|
||||
|
||||
func list_visible(vbox: VBoxContainer, separator: VSeparator) -> void:
|
||||
vbox.visible = true
|
||||
separator.visible = true
|
||||
|
||||
|
||||
func make_header_label(vbox: VBoxContainer, text: String) -> void:
|
||||
var label: Label = Label.new()
|
||||
label.add_theme_font_size_override("font_size", 20)
|
||||
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
label.add_theme_color_override("font_color", Color(1, 0.5, 0))
|
||||
label.text = text
|
||||
vbox.add_child(label)
|
||||
|
||||
|
||||
# Items alternate between white and orange text as well as background shade
|
||||
func make_soundtrack_row(text: String, row: int) -> ListRow:
|
||||
var list_row: ListRow = ListRow.create(text, row, 18, HORIZONTAL_ALIGNMENT_CENTER)
|
||||
if row % 2 != 0:
|
||||
list_row.label.add_theme_color_override("font_color", Color(1, 0.5, 0))
|
||||
return list_row
|
||||
|
||||
|
||||
func reset_sync_result() -> void:
|
||||
sync_progress_bar.value = 0
|
||||
sync_time.text = ""
|
||||
changes = false
|
||||
no_changes_label.visible = false
|
||||
soundtracks_added_vbox.visible = false
|
||||
soundtracks_added_separator.visible = false
|
||||
soundtracks_readded_vbox.visible = false
|
||||
soundtracks_readded_separator.visible = false
|
||||
soundtracks_changed_title_vbox.visible = false
|
||||
soundtracks_changed_title_separator.visible = false
|
||||
soundtracks_changed_content_vbox.visible = false
|
||||
soundtracks_changed_content_separator.visible = false
|
||||
soundtracks_removed_vbox.visible = false
|
||||
soundtracks_removed_separator.visible = false
|
||||
caught_errors_vbox.visible = false
|
||||
|
||||
|
||||
func make_list(list: Array, vbox: VBoxContainer, text: String) -> void:
|
||||
Settings.delete_children(vbox)
|
||||
make_header_label(vbox, text)
|
||||
for row: int in list.size():
|
||||
vbox.add_child(make_soundtrack_row(list[row], row))
|
||||
|
||||
|
||||
func show_sync_result() -> void:
|
||||
sync_title_label.text = "Sync Result"
|
||||
progress_hbox.visible = false
|
||||
sync_hbox.visible = true
|
||||
restart_sync_button.visible = true
|
||||
|
||||
|
||||
func show_sync_progress() -> void:
|
||||
sync_title_label.text = "Sync in Progress"
|
||||
progress_hbox.visible = true
|
||||
no_changes_label.visible = false
|
||||
sync_hbox.visible = false
|
||||
caught_errors_vbox.visible = false
|
||||
restart_sync_button.visible = false
|
||||
@@ -0,0 +1 @@
|
||||
uid://c3ejukwth512a
|
||||
@@ -0,0 +1,50 @@
|
||||
class_name WinnerPopup
|
||||
extends BasePopup
|
||||
## Shows who won, with their character, and where the other players placed.
|
||||
|
||||
@onready var winner_panel: Panel = %WinnerPanel
|
||||
@onready var winner_picture: TextureRect = %WinnerPicture
|
||||
@onready var winner_label: Label = %WinnerLabel
|
||||
@onready var players_list: VBoxContainer = %PlayersList
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
visible = false
|
||||
|
||||
|
||||
func show_winner(winner: PlayerObject) -> void:
|
||||
visible = true
|
||||
# Set winner info
|
||||
winner_label.text = winner.player_name + " won with " + str(winner.player_score) + \
|
||||
" points!!"
|
||||
winner_picture.texture = winner.character
|
||||
# The "no character" placeholder is pixel art, which blurs when scaled up smoothly
|
||||
if winner.character.resource_path == PlayerObject.NO_CHARACTER_PATH:
|
||||
winner_picture.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
|
||||
else:
|
||||
winner_picture.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR
|
||||
winner_picture.custom_minimum_size = Vector2(480, 200)
|
||||
winner_picture.expand_mode = TextureRect.EXPAND_FIT_WIDTH_PROPORTIONAL
|
||||
winner_picture.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||
|
||||
# Clear previous player list entries
|
||||
for child: Node in players_list.get_children():
|
||||
child.queue_free()
|
||||
|
||||
# Sort players by score (descending) and add to list
|
||||
var sorted_players: Array = Settings.player_array.duplicate()
|
||||
sorted_players.sort_custom(
|
||||
func(a: PlayerObject, b: PlayerObject) -> bool:
|
||||
return a.player_score > b.player_score
|
||||
)
|
||||
|
||||
var placing: int = 2
|
||||
for player: PlayerObject in sorted_players:
|
||||
if player == winner:
|
||||
continue # Skip the winner, already shown above
|
||||
var label: Label = Label.new()
|
||||
label.text = str(placing) + ". " + player.player_name + " - " + \
|
||||
str(player.player_score) + " points"
|
||||
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
players_list.add_child(label)
|
||||
placing += 1
|
||||
@@ -0,0 +1 @@
|
||||
uid://dxpb22xbwf3t1
|
||||
Reference in new issue
Block a user