Add interface sound feedback
This commit is contained in:
+29
-33
@@ -6,8 +6,8 @@ const AUTH_REGISTER_URL := "https://pauth.ranaze.com/api/Auth/register"
|
||||
|
||||
var main: Control
|
||||
var auth_panel: PanelContainer
|
||||
var login_tab: Button
|
||||
var register_tab: Button
|
||||
var auth_prompt_label: Label
|
||||
var switch_mode_button: Button
|
||||
var login_fields: VBoxContainer
|
||||
var register_fields: VBoxContainer
|
||||
var username_input: LineEdit
|
||||
@@ -54,30 +54,11 @@ func _ready() -> void:
|
||||
Style.set_label(title, 34, Style.TEXT)
|
||||
content.add_child(title)
|
||||
|
||||
var subtitle := Label.new()
|
||||
subtitle.text = "Sign in or create an account to start studying."
|
||||
subtitle.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
subtitle.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
Style.set_label(subtitle, 16, Style.MUTED)
|
||||
content.add_child(subtitle)
|
||||
|
||||
var tabs := HBoxContainer.new()
|
||||
tabs.add_theme_constant_override("separation", 8)
|
||||
content.add_child(tabs)
|
||||
|
||||
login_tab = Button.new()
|
||||
login_tab.text = "Log In"
|
||||
login_tab.custom_minimum_size = Vector2(0, 44)
|
||||
login_tab.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
login_tab.pressed.connect(func(): _set_auth_mode("login"))
|
||||
tabs.add_child(login_tab)
|
||||
|
||||
register_tab = Button.new()
|
||||
register_tab.text = "Create Account"
|
||||
register_tab.custom_minimum_size = Vector2(0, 44)
|
||||
register_tab.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
register_tab.pressed.connect(func(): _set_auth_mode("register"))
|
||||
tabs.add_child(register_tab)
|
||||
auth_prompt_label = Label.new()
|
||||
auth_prompt_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
auth_prompt_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
Style.set_label(auth_prompt_label, 16, Style.MUTED)
|
||||
content.add_child(auth_prompt_label)
|
||||
|
||||
login_fields = VBoxContainer.new()
|
||||
login_fields.add_theme_constant_override("separation", 10)
|
||||
@@ -122,6 +103,16 @@ func _ready() -> void:
|
||||
Style.set_label(error_label, 15, Style.RED)
|
||||
content.add_child(error_label)
|
||||
|
||||
var switch_spacer := Control.new()
|
||||
switch_spacer.custom_minimum_size = Vector2(0, 8)
|
||||
content.add_child(switch_spacer)
|
||||
|
||||
switch_mode_button = Button.new()
|
||||
switch_mode_button.custom_minimum_size = Vector2(0, 46)
|
||||
Style.style_chip(switch_mode_button, Style.CYAN)
|
||||
switch_mode_button.pressed.connect(_toggle_auth_mode)
|
||||
content.add_child(switch_mode_button)
|
||||
|
||||
var spacer_bottom := Control.new()
|
||||
spacer_bottom.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
add_child(spacer_bottom)
|
||||
@@ -165,18 +156,22 @@ func _set_auth_mode(next_mode: String) -> void:
|
||||
return
|
||||
login_fields.visible = auth_mode == "login"
|
||||
register_fields.visible = auth_mode == "register"
|
||||
auth_panel.custom_minimum_size.y = 470 if auth_mode == "login" else 650
|
||||
auth_panel.custom_minimum_size.y = 535 if auth_mode == "login" else 650
|
||||
if auth_mode == "login":
|
||||
Style.style_primary_button(login_tab)
|
||||
Style.style_chip(register_tab, Style.CYAN)
|
||||
auth_prompt_label.text = "Log in to continue studying."
|
||||
switch_mode_button.text = "Create new account"
|
||||
username_input.grab_focus()
|
||||
else:
|
||||
Style.style_chip(login_tab, Style.CYAN)
|
||||
Style.style_primary_button(register_tab)
|
||||
auth_prompt_label.text = "Create your account"
|
||||
switch_mode_button.text = "Already have an account? Log in"
|
||||
registration_username_input.grab_focus()
|
||||
_clear_messages()
|
||||
|
||||
|
||||
func _toggle_auth_mode() -> void:
|
||||
_set_auth_mode("register" if auth_mode == "login" else "login")
|
||||
|
||||
|
||||
func _on_login_pressed() -> void:
|
||||
_send_login(username_input.text.strip_edges(), password_input.text, false)
|
||||
|
||||
@@ -236,6 +231,7 @@ func _on_login_request_completed(result: int, response_code: int, _headers: Pack
|
||||
String(response.get("exp", ""))
|
||||
)
|
||||
QuestionBankService.load_questions_from_api()
|
||||
UISoundService.play_sound("correct")
|
||||
password_input.text = ""
|
||||
registration_password_input.text = ""
|
||||
registration_confirm_input.text = ""
|
||||
@@ -309,8 +305,7 @@ func _set_busy(is_busy: bool) -> void:
|
||||
return
|
||||
login_button.disabled = is_busy
|
||||
register_button.disabled = is_busy
|
||||
login_tab.disabled = is_busy
|
||||
register_tab.disabled = is_busy
|
||||
switch_mode_button.disabled = is_busy
|
||||
username_input.editable = not is_busy
|
||||
password_input.editable = not is_busy
|
||||
registration_username_input.editable = not is_busy
|
||||
@@ -344,5 +339,6 @@ func _clear_messages() -> void:
|
||||
|
||||
|
||||
func _show_error(message: String) -> void:
|
||||
UISoundService.play_sound("error")
|
||||
success_label.text = ""
|
||||
error_label.text = message
|
||||
|
||||
@@ -8,6 +8,7 @@ var header_panel: PanelContainer
|
||||
var user_label: Label
|
||||
var app_menu: PanelContainer
|
||||
var menu_exit_button: Button
|
||||
var sound_toggle: CheckButton
|
||||
var current_screen_name := ""
|
||||
|
||||
func _ready() -> void:
|
||||
@@ -195,9 +196,18 @@ func _build_app_menu() -> void:
|
||||
resume.text = "Resume"
|
||||
resume.custom_minimum_size = Vector2(0, 48)
|
||||
Style.style_primary_button(resume)
|
||||
UISoundService.set_button_sound(resume, "close")
|
||||
resume.pressed.connect(_close_app_menu)
|
||||
content.add_child(resume)
|
||||
|
||||
sound_toggle = CheckButton.new()
|
||||
sound_toggle.text = "UI Sounds"
|
||||
sound_toggle.button_pressed = UISoundService.are_sounds_enabled()
|
||||
sound_toggle.custom_minimum_size = Vector2(0, 44)
|
||||
UISoundService.set_button_sound(sound_toggle, "none")
|
||||
sound_toggle.toggled.connect(UISoundService.set_sounds_enabled)
|
||||
content.add_child(sound_toggle)
|
||||
|
||||
var profile := Button.new()
|
||||
profile.text = "Profile"
|
||||
profile.custom_minimum_size = Vector2(0, 48)
|
||||
@@ -208,6 +218,7 @@ func _build_app_menu() -> void:
|
||||
menu_exit_button = Button.new()
|
||||
menu_exit_button.text = "Exit Run"
|
||||
menu_exit_button.custom_minimum_size = Vector2(0, 48)
|
||||
UISoundService.set_button_sound(menu_exit_button, "back")
|
||||
menu_exit_button.pressed.connect(_exit_run)
|
||||
content.add_child(menu_exit_button)
|
||||
|
||||
@@ -215,6 +226,7 @@ func _build_app_menu() -> void:
|
||||
logout.text = "Log Out"
|
||||
logout.custom_minimum_size = Vector2(0, 48)
|
||||
Style.style_chip(logout, Style.RED)
|
||||
UISoundService.set_button_sound(logout, "back")
|
||||
logout.pressed.connect(_logout)
|
||||
content.add_child(logout)
|
||||
|
||||
@@ -223,8 +235,10 @@ func _toggle_app_menu() -> void:
|
||||
if app_menu == null:
|
||||
return
|
||||
if app_menu.visible:
|
||||
UISoundService.play_sound("close")
|
||||
_close_app_menu()
|
||||
else:
|
||||
UISoundService.play_sound("open")
|
||||
app_menu.visible = true
|
||||
app_menu.size = app_menu.custom_minimum_size
|
||||
app_menu.position = (get_viewport_rect().size - app_menu.size) * 0.5
|
||||
|
||||
@@ -2,7 +2,7 @@ extends VBoxContainer
|
||||
|
||||
const Style := preload("res://scripts/ui/ui_style.gd")
|
||||
const FEEDBACK_FADE_SECONDS := 0.45
|
||||
const CORRECT_ADVANCE_DELAY_SECONDS := 0.6
|
||||
const CORRECT_ADVANCE_DELAY_SECONDS := 1.25
|
||||
const TEXT_SCALE_MIN := 0.85
|
||||
const TEXT_SCALE_MAX := 1.35
|
||||
const TEXT_SCALE_STEP := 0.1
|
||||
@@ -108,6 +108,7 @@ func _ready() -> void:
|
||||
text_smaller_button.tooltip_text = "Decrease text size"
|
||||
text_smaller_button.custom_minimum_size = Vector2(44, 44)
|
||||
Style.style_chip(text_smaller_button, Style.CYAN)
|
||||
UISoundService.set_button_sound(text_smaller_button, "toggle")
|
||||
text_smaller_button.pressed.connect(func(): _adjust_question_text_scale(-TEXT_SCALE_STEP))
|
||||
question_toolbar.add_child(text_smaller_button)
|
||||
|
||||
@@ -116,6 +117,7 @@ func _ready() -> void:
|
||||
text_larger_button.tooltip_text = "Increase text size"
|
||||
text_larger_button.custom_minimum_size = Vector2(44, 44)
|
||||
Style.style_chip(text_larger_button, Style.CYAN)
|
||||
UISoundService.set_button_sound(text_larger_button, "toggle")
|
||||
text_larger_button.pressed.connect(func(): _adjust_question_text_scale(TEXT_SCALE_STEP))
|
||||
question_toolbar.add_child(text_larger_button)
|
||||
|
||||
@@ -124,6 +126,7 @@ func _ready() -> void:
|
||||
labs_button.icon = _make_labs_icon()
|
||||
labs_button.custom_minimum_size = Vector2(44, 44)
|
||||
Style.style_chip(labs_button, Style.LIME)
|
||||
UISoundService.set_button_sound(labs_button, "open")
|
||||
labs_button.pressed.connect(_show_labs_modal)
|
||||
question_toolbar.add_child(labs_button)
|
||||
|
||||
@@ -132,6 +135,7 @@ func _ready() -> void:
|
||||
clear_highlight_button.icon = _make_clear_highlights_icon()
|
||||
clear_highlight_button.custom_minimum_size = Vector2(44, 44)
|
||||
Style.style_chip(clear_highlight_button, Style.CYAN)
|
||||
UISoundService.set_button_sound(clear_highlight_button, "eliminate")
|
||||
clear_highlight_button.pressed.connect(_clear_current_highlights)
|
||||
question_toolbar.add_child(clear_highlight_button)
|
||||
|
||||
@@ -141,6 +145,7 @@ func _ready() -> void:
|
||||
flag_button.icon = _make_flag_icon()
|
||||
flag_button.custom_minimum_size = Vector2(44, 44)
|
||||
Style.style_chip(flag_button, Style.AMBER)
|
||||
UISoundService.set_button_sound(flag_button, "toggle")
|
||||
flag_button.toggled.connect(func(value: bool):
|
||||
flagged = value
|
||||
_refresh_toolbar_state()
|
||||
@@ -217,6 +222,7 @@ func _ready() -> void:
|
||||
button.custom_minimum_size = Vector2(0, 64)
|
||||
button.alignment = HORIZONTAL_ALIGNMENT_LEFT
|
||||
Style.style_answer_button(button)
|
||||
UISoundService.set_button_sound(button, "select")
|
||||
_set_scaled_button_font(button, 17)
|
||||
button.pressed.connect(func(i := index): _select_choice(i))
|
||||
button.gui_input.connect(func(event: InputEvent, i := index): _choice_gui_input(event, i))
|
||||
@@ -288,6 +294,7 @@ func _ready() -> void:
|
||||
skip_button.text = "Skip"
|
||||
skip_button.custom_minimum_size = Vector2(120, 48)
|
||||
Style.style_chip(skip_button, Style.AMBER)
|
||||
UISoundService.set_button_sound(skip_button, "back")
|
||||
skip_button.pressed.connect(_skip_current_question)
|
||||
actions.add_child(skip_button)
|
||||
|
||||
@@ -535,6 +542,7 @@ func _choice_gui_input(event: InputEvent, index: int) -> void:
|
||||
eliminated.erase(choice_id)
|
||||
else:
|
||||
eliminated.append(choice_id)
|
||||
UISoundService.play_sound("eliminate")
|
||||
_set_choice_button_text(index, choice)
|
||||
_apply_saved_choice_state()
|
||||
|
||||
@@ -549,6 +557,7 @@ func _toggle_eliminate_selected() -> void:
|
||||
eliminated.erase(selected_choice)
|
||||
else:
|
||||
eliminated.append(selected_choice)
|
||||
UISoundService.play_sound("eliminate")
|
||||
_set_choice_button_text(index, choices[index])
|
||||
_apply_saved_choice_state()
|
||||
|
||||
@@ -663,6 +672,7 @@ func _lock_wrong_choice(choice_id: String) -> void:
|
||||
|
||||
|
||||
func _trigger_wrong_feedback() -> void:
|
||||
UISoundService.play_sound("error")
|
||||
shake_time = 0.28
|
||||
shake_origin = position
|
||||
green_fog_time = 0.0
|
||||
@@ -672,6 +682,7 @@ func _trigger_wrong_feedback() -> void:
|
||||
|
||||
|
||||
func _trigger_correct_feedback() -> void:
|
||||
UISoundService.play_sound("correct")
|
||||
pending_correct_advance = true
|
||||
correct_advance_delay = CORRECT_ADVANCE_DELAY_SECONDS
|
||||
red_fog_time = 0.0
|
||||
@@ -1010,6 +1021,7 @@ func _build_labs_modal() -> void:
|
||||
close_button.tooltip_text = "Close lab results"
|
||||
close_button.custom_minimum_size = Vector2(42, 38)
|
||||
Style.style_chip(close_button, Style.RED)
|
||||
UISoundService.set_button_sound(close_button, "close")
|
||||
close_button.pressed.connect(_hide_labs_modal)
|
||||
header.add_child(close_button)
|
||||
|
||||
@@ -1331,6 +1343,7 @@ func _build_followup_panel(index: int, choice_id: String) -> void:
|
||||
option_button.alignment = HORIZONTAL_ALIGNMENT_LEFT
|
||||
option_button.custom_minimum_size = Vector2(0, 32)
|
||||
Style.style_chip(option_button, Style.CYAN)
|
||||
UISoundService.set_button_sound(option_button, "select")
|
||||
_set_scaled_button_font(option_button, 15)
|
||||
option_button.set_meta("option_id", str(option.get("id", "")))
|
||||
option_button.pressed.connect(func(option_id := str(option.get("id", "")), selected_button := option_button, followup_data := followup):
|
||||
@@ -1459,6 +1472,7 @@ func _build_collapsed_followup(index: int, state: Dictionary) -> void:
|
||||
summary.alignment = HORIZONTAL_ALIGNMENT_LEFT
|
||||
summary.custom_minimum_size = Vector2(0, 40)
|
||||
Style.style_chip(summary, Style.AMBER)
|
||||
UISoundService.set_button_sound(summary, "open")
|
||||
_set_scaled_button_font(summary, 15)
|
||||
summary.gui_input.connect(func(_event: InputEvent): _mark_review_input_handled())
|
||||
summary.pressed.connect(func(choice_id := str(state.get("choice_id", ""))): _toggle_followup_state(choice_id))
|
||||
@@ -1472,6 +1486,7 @@ func _build_readonly_followup(index: int, state: Dictionary) -> void:
|
||||
summary.alignment = HORIZONTAL_ALIGNMENT_LEFT
|
||||
summary.custom_minimum_size = Vector2(0, 36)
|
||||
Style.style_chip(summary, Style.AMBER)
|
||||
UISoundService.set_button_sound(summary, "close")
|
||||
_set_scaled_button_font(summary, 15)
|
||||
summary.gui_input.connect(func(_event: InputEvent): _mark_review_input_handled())
|
||||
summary.pressed.connect(func(choice_id := str(state.get("choice_id", ""))): _toggle_followup_state(choice_id))
|
||||
|
||||
@@ -88,6 +88,7 @@ func _build_mode_view() -> void:
|
||||
back_button.alignment = HORIZONTAL_ALIGNMENT_LEFT
|
||||
back_button.custom_minimum_size = Vector2(150, 42)
|
||||
Style.style_chip(back_button, Style.CYAN)
|
||||
UISoundService.set_button_sound(back_button, "back")
|
||||
back_button.pressed.connect(func(): _show_stage("exam"))
|
||||
mode_view.add_child(back_button)
|
||||
|
||||
@@ -237,6 +238,7 @@ func _start_question_bank() -> void:
|
||||
if not visible or current_stage != "step3" or not QuestionBankService.has_questions():
|
||||
return
|
||||
if BlockSessionService.start_core_run():
|
||||
UISoundService.play_sound("question")
|
||||
main.show_screen("player")
|
||||
else:
|
||||
bank_error_label.text = BlockSessionService.core_status_message
|
||||
|
||||
Reference in New Issue
Block a user