Fix shield icon rendering, move slot machine to a movable panel
The shield icon's dark/mushy rendering was caused by disabled mipmaps on all 6 slot-machine icon textures (inherited from the flat lucide icon convention, wrong for these gradient-heavy assets) - at small display sizes this caused aliasing that hit the shield's fine detail (RZ lettering, metallic bevels) hardest since the other icons are bolder/simpler shapes. Enabling mipmaps/generate on all 6 fixes it; confirmed by rendering the actual in-game presentation size before and after, not just eyeballing the source file. Also converts the slot machine from a full standalone screen (sidebar nav entry, main.gd-managed) into a movable/draggable floating panel opened from the question-player toolbar, mirroring the existing calculator panel exactly: same top_level+custom title-bar-drag+ viewport-clamp mechanics, same open/close/toggle API, instantiated once alongside the calculator and closed on session hide. Shrunk the cabinet and restacked the rewards list below it (was beside it) to fit a toolbox-sized floating panel instead of a full page, wrapped in a ScrollContainer for any overflow. Removed the sidebar entry and screens[] registration from main.gd and the now-dead routing case from navigation_routes.gd.
This commit is contained in:
@@ -23,7 +23,7 @@ compress/rdo_quality_loss=0.0
|
|||||||
compress/hdr_compression=1
|
compress/hdr_compression=1
|
||||||
compress/normal_map=0
|
compress/normal_map=0
|
||||||
compress/channel_pack=0
|
compress/channel_pack=0
|
||||||
mipmaps/generate=false
|
mipmaps/generate=true
|
||||||
mipmaps/limit=-1
|
mipmaps/limit=-1
|
||||||
roughness/mode=0
|
roughness/mode=0
|
||||||
roughness/src_normal=""
|
roughness/src_normal=""
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ compress/rdo_quality_loss=0.0
|
|||||||
compress/hdr_compression=1
|
compress/hdr_compression=1
|
||||||
compress/normal_map=0
|
compress/normal_map=0
|
||||||
compress/channel_pack=0
|
compress/channel_pack=0
|
||||||
mipmaps/generate=false
|
mipmaps/generate=true
|
||||||
mipmaps/limit=-1
|
mipmaps/limit=-1
|
||||||
roughness/mode=0
|
roughness/mode=0
|
||||||
roughness/src_normal=""
|
roughness/src_normal=""
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ compress/rdo_quality_loss=0.0
|
|||||||
compress/hdr_compression=1
|
compress/hdr_compression=1
|
||||||
compress/normal_map=0
|
compress/normal_map=0
|
||||||
compress/channel_pack=0
|
compress/channel_pack=0
|
||||||
mipmaps/generate=false
|
mipmaps/generate=true
|
||||||
mipmaps/limit=-1
|
mipmaps/limit=-1
|
||||||
roughness/mode=0
|
roughness/mode=0
|
||||||
roughness/src_normal=""
|
roughness/src_normal=""
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ compress/rdo_quality_loss=0.0
|
|||||||
compress/hdr_compression=1
|
compress/hdr_compression=1
|
||||||
compress/normal_map=0
|
compress/normal_map=0
|
||||||
compress/channel_pack=0
|
compress/channel_pack=0
|
||||||
mipmaps/generate=false
|
mipmaps/generate=true
|
||||||
mipmaps/limit=-1
|
mipmaps/limit=-1
|
||||||
roughness/mode=0
|
roughness/mode=0
|
||||||
roughness/src_normal=""
|
roughness/src_normal=""
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ compress/rdo_quality_loss=0.0
|
|||||||
compress/hdr_compression=1
|
compress/hdr_compression=1
|
||||||
compress/normal_map=0
|
compress/normal_map=0
|
||||||
compress/channel_pack=0
|
compress/channel_pack=0
|
||||||
mipmaps/generate=false
|
mipmaps/generate=true
|
||||||
mipmaps/limit=-1
|
mipmaps/limit=-1
|
||||||
roughness/mode=0
|
roughness/mode=0
|
||||||
roughness/src_normal=""
|
roughness/src_normal=""
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ compress/rdo_quality_loss=0.0
|
|||||||
compress/hdr_compression=1
|
compress/hdr_compression=1
|
||||||
compress/normal_map=0
|
compress/normal_map=0
|
||||||
compress/channel_pack=0
|
compress/channel_pack=0
|
||||||
mipmaps/generate=false
|
mipmaps/generate=true
|
||||||
mipmaps/limit=-1
|
mipmaps/limit=-1
|
||||||
roughness/mode=0
|
roughness/mode=0
|
||||||
roughness/src_normal=""
|
roughness/src_normal=""
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ compress/rdo_quality_loss=0.0
|
|||||||
compress/hdr_compression=1
|
compress/hdr_compression=1
|
||||||
compress/normal_map=0
|
compress/normal_map=0
|
||||||
compress/channel_pack=0
|
compress/channel_pack=0
|
||||||
mipmaps/generate=false
|
mipmaps/generate=true
|
||||||
mipmaps/limit=-1
|
mipmaps/limit=-1
|
||||||
roughness/mode=0
|
roughness/mode=0
|
||||||
roughness/src_normal=""
|
roughness/src_normal=""
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ compress/rdo_quality_loss=0.0
|
|||||||
compress/hdr_compression=1
|
compress/hdr_compression=1
|
||||||
compress/normal_map=0
|
compress/normal_map=0
|
||||||
compress/channel_pack=0
|
compress/channel_pack=0
|
||||||
mipmaps/generate=false
|
mipmaps/generate=true
|
||||||
mipmaps/limit=-1
|
mipmaps/limit=-1
|
||||||
roughness/mode=0
|
roughness/mode=0
|
||||||
roughness/src_normal=""
|
roughness/src_normal=""
|
||||||
|
|||||||
@@ -361,11 +361,6 @@ func _build_ui() -> void:
|
|||||||
rz_store.main = self
|
rz_store.main = self
|
||||||
screens_container.add_child(rz_store)
|
screens_container.add_child(rz_store)
|
||||||
screens["rz_store"] = rz_store
|
screens["rz_store"] = rz_store
|
||||||
var slot_machine := preload("res://scripts/ui/rz_slot_machine_screen.gd").new()
|
|
||||||
slot_machine.name = "RzSlotMachine"
|
|
||||||
slot_machine.main = self
|
|
||||||
screens_container.add_child(slot_machine)
|
|
||||||
screens["slot_machine"] = slot_machine
|
|
||||||
|
|
||||||
feedback_dialog = preload("res://scripts/ui/app_feedback_dialog.gd").new()
|
feedback_dialog = preload("res://scripts/ui/app_feedback_dialog.gd").new()
|
||||||
feedback_dialog.name = "AppFeedbackDialog"
|
feedback_dialog.name = "AppFeedbackDialog"
|
||||||
@@ -445,7 +440,6 @@ func _populate_navigation(container: VBoxContainer, include_brand: bool) -> void
|
|||||||
_add_nav_button(container, "donations", "Support RanaZe", "heart-pulse", true)
|
_add_nav_button(container, "donations", "Support RanaZe", "heart-pulse", true)
|
||||||
_add_nav_button(container, "performance", "Profile", "user-round", true)
|
_add_nav_button(container, "performance", "Profile", "user-round", true)
|
||||||
_add_nav_button(container, "rz_store", "RZ Shop", "star", true)
|
_add_nav_button(container, "rz_store", "RZ Shop", "star", true)
|
||||||
_add_nav_button(container, "slot_machine", "Slot Machine", "gem", true)
|
|
||||||
_add_nav_button(container, "settings", "Settings", "settings", true)
|
_add_nav_button(container, "settings", "Settings", "settings", true)
|
||||||
_add_nav_button(container, "logout", "Log out", "log-out", true)
|
_add_nav_button(container, "logout", "Log out", "log-out", true)
|
||||||
|
|
||||||
@@ -490,7 +484,6 @@ func _on_navigation_pressed(key: String) -> void:
|
|||||||
"bookmarks": show_screen("bookmarks")
|
"bookmarks": show_screen("bookmarks")
|
||||||
"donations": show_screen("donations")
|
"donations": show_screen("donations")
|
||||||
"rz_store": show_screen("rz_store")
|
"rz_store": show_screen("rz_store")
|
||||||
"slot_machine": show_screen("slot_machine")
|
|
||||||
"logout": _logout()
|
"logout": _logout()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,4 @@ static func key_for_screen(screen_name: String, payload: Variant = null) -> Stri
|
|||||||
key = "donations"
|
key = "donations"
|
||||||
elif screen_name == "rz_store":
|
elif screen_name == "rz_store":
|
||||||
key = "rz_store"
|
key = "rz_store"
|
||||||
elif screen_name == "slot_machine":
|
|
||||||
key = "slot_machine"
|
|
||||||
return key
|
return key
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ const Style := preload("res://scripts/ui/ui_style.gd")
|
|||||||
const Brand := preload("res://scripts/ui/medmind_style.gd")
|
const Brand := preload("res://scripts/ui/medmind_style.gd")
|
||||||
const FlashcardPrefillDialog := preload("res://scripts/ui/flashcard_prefill_dialog.gd")
|
const FlashcardPrefillDialog := preload("res://scripts/ui/flashcard_prefill_dialog.gd")
|
||||||
const CalculatorPanel := preload("res://scripts/ui/calculator_panel.gd")
|
const CalculatorPanel := preload("res://scripts/ui/calculator_panel.gd")
|
||||||
|
const SlotMachinePanel := preload("res://scripts/ui/rz_slot_machine_screen.gd")
|
||||||
const CreditsBadge := preload("res://scripts/ui/credits_badge.gd")
|
const CreditsBadge := preload("res://scripts/ui/credits_badge.gd")
|
||||||
const CLEAR_HIGHLIGHT_DARK_ICON := preload("res://assets/icons/medmind/clear-highlight-dark.svg")
|
const CLEAR_HIGHLIGHT_DARK_ICON := preload("res://assets/icons/medmind/clear-highlight-dark.svg")
|
||||||
const CLEAR_HIGHLIGHT_LIGHT_ICON := preload("res://assets/icons/medmind/clear-highlight-light.svg")
|
const CLEAR_HIGHLIGHT_LIGHT_ICON := preload("res://assets/icons/medmind/clear-highlight-light.svg")
|
||||||
@@ -94,6 +95,7 @@ var text_smaller_button: Button
|
|||||||
var text_larger_button: Button
|
var text_larger_button: Button
|
||||||
var labs_button: Button
|
var labs_button: Button
|
||||||
var calculator_button: Button
|
var calculator_button: Button
|
||||||
|
var slot_machine_button: Button
|
||||||
var exit_button: Button
|
var exit_button: Button
|
||||||
var clear_highlight_button: Button
|
var clear_highlight_button: Button
|
||||||
var flag_button: Button
|
var flag_button: Button
|
||||||
@@ -127,6 +129,7 @@ var labs_overlay: Control
|
|||||||
var labs_panel: PanelContainer
|
var labs_panel: PanelContainer
|
||||||
var labs_content: VBoxContainer
|
var labs_content: VBoxContainer
|
||||||
var calculator_panel
|
var calculator_panel
|
||||||
|
var slot_machine_panel
|
||||||
var report_overlay: Control
|
var report_overlay: Control
|
||||||
var report_panel: PanelContainer
|
var report_panel: PanelContainer
|
||||||
var report_form_content: VBoxContainer
|
var report_form_content: VBoxContainer
|
||||||
@@ -347,6 +350,18 @@ func _ready() -> void:
|
|||||||
UISoundService.set_button_sound(calculator_button, "open")
|
UISoundService.set_button_sound(calculator_button, "open")
|
||||||
calculator_button.pressed.connect(_toggle_calculator)
|
calculator_button.pressed.connect(_toggle_calculator)
|
||||||
|
|
||||||
|
slot_machine_button = Button.new()
|
||||||
|
slot_machine_button.name = "SlotMachineButton"
|
||||||
|
slot_machine_button.tooltip_text = "Open RZ Slot Machine"
|
||||||
|
slot_machine_button.icon = preload("res://assets/icons/lucide/gem.svg")
|
||||||
|
slot_machine_button.custom_minimum_size = Vector2(44, 44)
|
||||||
|
slot_machine_button.add_theme_constant_override("icon_max_width", 22)
|
||||||
|
slot_machine_button.alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||||
|
slot_machine_button.icon_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||||
|
slot_machine_button.focus_mode = Control.FOCUS_NONE
|
||||||
|
UISoundService.set_button_sound(slot_machine_button, "open")
|
||||||
|
slot_machine_button.pressed.connect(_toggle_slot_machine)
|
||||||
|
|
||||||
labs_button = Button.new()
|
labs_button = Button.new()
|
||||||
labs_button.tooltip_text = "Review lab results"
|
labs_button.tooltip_text = "Review lab results"
|
||||||
labs_button.custom_minimum_size = Vector2(44, 44)
|
labs_button.custom_minimum_size = Vector2(44, 44)
|
||||||
@@ -432,6 +447,7 @@ func _ready() -> void:
|
|||||||
question_toolbar.add_child(text_smaller_button)
|
question_toolbar.add_child(text_smaller_button)
|
||||||
question_toolbar.add_child(text_larger_button)
|
question_toolbar.add_child(text_larger_button)
|
||||||
question_toolbar.add_child(calculator_button)
|
question_toolbar.add_child(calculator_button)
|
||||||
|
question_toolbar.add_child(slot_machine_button)
|
||||||
question_toolbar.add_child(labs_button)
|
question_toolbar.add_child(labs_button)
|
||||||
question_toolbar.add_child(clear_highlight_button)
|
question_toolbar.add_child(clear_highlight_button)
|
||||||
question_toolbar.add_child(flag_button)
|
question_toolbar.add_child(flag_button)
|
||||||
@@ -725,6 +741,9 @@ func _ready() -> void:
|
|||||||
_build_labs_modal()
|
_build_labs_modal()
|
||||||
calculator_panel = CalculatorPanel.new()
|
calculator_panel = CalculatorPanel.new()
|
||||||
add_child(calculator_panel)
|
add_child(calculator_panel)
|
||||||
|
slot_machine_panel = SlotMachinePanel.new()
|
||||||
|
slot_machine_panel.main = main
|
||||||
|
add_child(slot_machine_panel)
|
||||||
_build_report_modal()
|
_build_report_modal()
|
||||||
_build_media_viewer()
|
_build_media_viewer()
|
||||||
resized.connect(_fit_modal_panels)
|
resized.connect(_fit_modal_panels)
|
||||||
@@ -810,10 +829,10 @@ func _refresh_responsive_layout() -> void:
|
|||||||
header_toolbar_host.reparent(target_parent)
|
header_toolbar_host.reparent(target_parent)
|
||||||
header_toolbar_host.size_flags_horizontal = Control.SIZE_EXPAND_FILL if compact else Control.SIZE_SHRINK_END
|
header_toolbar_host.size_flags_horizontal = Control.SIZE_EXPAND_FILL if compact else Control.SIZE_SHRINK_END
|
||||||
question_toolbar.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
question_toolbar.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
# 12 bare 44px icon buttons + the wider 92px Feedback button + the ~194px
|
# 13 bare 44px icon buttons + the wider 92px Feedback button + the ~194px
|
||||||
# rank/ELO + points badge, with 8px gaps between all 14 - anything less
|
# rank/ELO + points badge, with 8px gaps between all 15 - anything less
|
||||||
# than this wraps onto a second row.
|
# than this wraps onto a second row.
|
||||||
header_toolbar_host.custom_minimum_size.x = 0.0 if compact else 960.0
|
header_toolbar_host.custom_minimum_size.x = 0.0 if compact else 1020.0
|
||||||
if size.x < 560.0:
|
if size.x < 560.0:
|
||||||
nav_palette.columns = 5
|
nav_palette.columns = 5
|
||||||
else:
|
else:
|
||||||
@@ -1069,7 +1088,7 @@ func _apply_question_theme() -> void:
|
|||||||
var navigator_heading := navigator_popup.find_child("NavigatorHeading", true, false) as Label
|
var navigator_heading := navigator_popup.find_child("NavigatorHeading", true, false) as Label
|
||||||
if navigator_heading != null:
|
if navigator_heading != null:
|
||||||
navigator_heading.add_theme_color_override("font_color", Brand.text_color(dark))
|
navigator_heading.add_theme_color_override("font_color", Brand.text_color(dark))
|
||||||
for control in [exit_button, text_smaller_button, text_larger_button, calculator_button, bookmark_button, notes_button, flashcard_button, app_feedback_button]:
|
for control in [exit_button, text_smaller_button, text_larger_button, calculator_button, slot_machine_button, bookmark_button, notes_button, flashcard_button, app_feedback_button]:
|
||||||
if control == null:
|
if control == null:
|
||||||
continue
|
continue
|
||||||
var active: bool = control == bookmark_button and BookmarkService.is_bookmarked(str(BlockSessionService.get_current_question().get("id", "")))
|
var active: bool = control == bookmark_button and BookmarkService.is_bookmarked(str(BlockSessionService.get_current_question().get("id", "")))
|
||||||
@@ -1085,6 +1104,8 @@ func _apply_question_theme() -> void:
|
|||||||
_style_theme_toggle_button(dark)
|
_style_theme_toggle_button(dark)
|
||||||
if calculator_panel != null:
|
if calculator_panel != null:
|
||||||
calculator_panel.refresh_theme_controls()
|
calculator_panel.refresh_theme_controls()
|
||||||
|
if slot_machine_panel != null:
|
||||||
|
slot_machine_panel.refresh_theme_controls()
|
||||||
if credits_badge != null:
|
if credits_badge != null:
|
||||||
credits_badge.refresh_theme_controls()
|
credits_badge.refresh_theme_controls()
|
||||||
if skip_button != null:
|
if skip_button != null:
|
||||||
@@ -1135,6 +1156,8 @@ func on_hide() -> void:
|
|||||||
if calculator_panel != null:
|
if calculator_panel != null:
|
||||||
calculator_panel.close_panel()
|
calculator_panel.close_panel()
|
||||||
calculator_panel.reset_calculation()
|
calculator_panel.reset_calculation()
|
||||||
|
if slot_machine_panel != null:
|
||||||
|
slot_machine_panel.close_panel()
|
||||||
|
|
||||||
|
|
||||||
func _save_simulation_current_response() -> void:
|
func _save_simulation_current_response() -> void:
|
||||||
@@ -2365,6 +2388,8 @@ func _refresh_toolbar_state() -> void:
|
|||||||
bookmark_button.tooltip_text = ("Saved; waiting to sync" if bookmark_pending else "Remove bookmark") if bookmark_value else ("Removal waiting to sync" if bookmark_pending else "Save question")
|
bookmark_button.tooltip_text = ("Saved; waiting to sync" if bookmark_pending else "Remove bookmark") if bookmark_value else ("Removal waiting to sync" if bookmark_pending else "Save question")
|
||||||
if calculator_button != null:
|
if calculator_button != null:
|
||||||
calculator_button.visible = true
|
calculator_button.visible = true
|
||||||
|
if slot_machine_button != null:
|
||||||
|
slot_machine_button.visible = true
|
||||||
_apply_question_theme()
|
_apply_question_theme()
|
||||||
|
|
||||||
|
|
||||||
@@ -2373,6 +2398,11 @@ func _toggle_calculator() -> void:
|
|||||||
calculator_panel.toggle_panel()
|
calculator_panel.toggle_panel()
|
||||||
|
|
||||||
|
|
||||||
|
func _toggle_slot_machine() -> void:
|
||||||
|
if slot_machine_panel != null:
|
||||||
|
slot_machine_panel.toggle_panel()
|
||||||
|
|
||||||
|
|
||||||
func _toggle_bookmark_current_question() -> void:
|
func _toggle_bookmark_current_question() -> void:
|
||||||
var question := BlockSessionService.get_current_question()
|
var question := BlockSessionService.get_current_question()
|
||||||
if not question.is_empty():
|
if not question.is_empty():
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
extends VBoxContainer
|
extends PanelContainer
|
||||||
|
|
||||||
const Brand := preload("res://scripts/ui/medmind_style.gd")
|
const Brand := preload("res://scripts/ui/medmind_style.gd")
|
||||||
const STAR_ICON := preload("res://assets/icons/lucide/star.svg")
|
const STAR_ICON := preload("res://assets/icons/lucide/star.svg")
|
||||||
@@ -23,9 +23,15 @@ const REWARD_ICONS := {
|
|||||||
"nice": {"texture": SLOT_COIN_STACK, "modulate": false},
|
"nice": {"texture": SLOT_COIN_STACK, "modulate": false},
|
||||||
"good_luck": {"texture": SLOT_COIN, "modulate": false, "tint": true},
|
"good_luck": {"texture": SLOT_COIN, "modulate": false, "tint": true},
|
||||||
}
|
}
|
||||||
|
const MACHINE_SIZE := 380.0
|
||||||
|
const CELL := 44.0
|
||||||
|
|
||||||
var main: Control
|
var main: Control
|
||||||
|
|
||||||
|
var drag_active := false
|
||||||
|
var drag_offset := Vector2.ZERO
|
||||||
|
var has_been_positioned := false
|
||||||
|
|
||||||
var subtitle_label: Label
|
var subtitle_label: Label
|
||||||
var machine_root: Control
|
var machine_root: Control
|
||||||
var lever_button: TextureButton
|
var lever_button: TextureButton
|
||||||
@@ -49,67 +55,129 @@ var _spinning := false
|
|||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
name = "RzSlotMachinePanel"
|
||||||
size_flags_vertical = Control.SIZE_EXPAND_FILL
|
visible = false
|
||||||
add_theme_constant_override("separation", 18)
|
top_level = true
|
||||||
|
mouse_filter = Control.MOUSE_FILTER_STOP
|
||||||
|
custom_minimum_size = Vector2(460, 680)
|
||||||
|
size = custom_minimum_size
|
||||||
|
|
||||||
_build_header()
|
_build_ui()
|
||||||
|
|
||||||
var body := HBoxContainer.new()
|
if not get_viewport().size_changed.is_connected(_on_viewport_size_changed):
|
||||||
body.add_theme_constant_override("separation", 18)
|
get_viewport().size_changed.connect(_on_viewport_size_changed)
|
||||||
body.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
_on_viewport_size_changed()
|
||||||
add_child(body)
|
|
||||||
|
|
||||||
var left_column := VBoxContainer.new()
|
|
||||||
left_column.add_theme_constant_override("separation", 16)
|
|
||||||
left_column.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
|
||||||
body.add_child(left_column)
|
|
||||||
|
|
||||||
_build_machine(left_column)
|
|
||||||
_build_controls(left_column)
|
|
||||||
_build_rewards_panel(body)
|
|
||||||
|
|
||||||
status_label = Label.new()
|
|
||||||
status_label.add_theme_font_override("font", Brand.font)
|
|
||||||
status_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
|
||||||
add_child(status_label)
|
|
||||||
|
|
||||||
_build_footer()
|
|
||||||
|
|
||||||
CreditsService.credits_changed.connect(_refresh_spin_button)
|
CreditsService.credits_changed.connect(_refresh_spin_button)
|
||||||
CreditsService.spin_config_loaded.connect(_refresh_rewards)
|
CreditsService.spin_config_loaded.connect(_refresh_rewards)
|
||||||
UIThemeService.theme_changed.connect(func(_dark: bool): _refresh_theme_controls())
|
UIThemeService.theme_changed.connect(func(_dark: bool): refresh_theme_controls())
|
||||||
|
refresh_theme_controls()
|
||||||
_refresh_rewards()
|
_refresh_rewards()
|
||||||
_refresh_spin_button()
|
_refresh_spin_button()
|
||||||
|
|
||||||
|
|
||||||
func on_show(_payload: Variant = null) -> void:
|
func open_panel() -> void:
|
||||||
|
visible = true
|
||||||
|
move_to_front()
|
||||||
|
if not has_been_positioned:
|
||||||
|
var viewport_size := get_viewport_rect().size
|
||||||
|
position = Vector2(maxf(12.0, viewport_size.x - size.x - 24.0), 72.0)
|
||||||
|
has_been_positioned = true
|
||||||
|
_clamp_to_viewport()
|
||||||
CreditsService.refresh()
|
CreditsService.refresh()
|
||||||
CreditsService.fetch_spin_config()
|
CreditsService.fetch_spin_config()
|
||||||
_refresh_rewards()
|
_refresh_rewards()
|
||||||
_refresh_spin_button()
|
_refresh_spin_button()
|
||||||
|
|
||||||
|
|
||||||
func _build_header() -> void:
|
func close_panel() -> void:
|
||||||
var title := Label.new()
|
visible = false
|
||||||
title.text = "RZ Coin Slot Machine"
|
drag_active = false
|
||||||
title.add_theme_font_override("font", Brand.font)
|
|
||||||
title.add_theme_font_size_override("font_size", 30)
|
|
||||||
add_child(title)
|
func toggle_panel() -> void:
|
||||||
|
if visible:
|
||||||
|
close_panel()
|
||||||
|
else:
|
||||||
|
open_panel()
|
||||||
|
|
||||||
|
|
||||||
|
func _build_ui() -> void:
|
||||||
|
var margin := MarginContainer.new()
|
||||||
|
margin.add_theme_constant_override("margin_left", 12)
|
||||||
|
margin.add_theme_constant_override("margin_right", 12)
|
||||||
|
margin.add_theme_constant_override("margin_top", 12)
|
||||||
|
margin.add_theme_constant_override("margin_bottom", 14)
|
||||||
|
add_child(margin)
|
||||||
|
|
||||||
|
var content := VBoxContainer.new()
|
||||||
|
content.add_theme_constant_override("separation", 10)
|
||||||
|
margin.add_child(content)
|
||||||
|
|
||||||
|
_build_title_bar(content)
|
||||||
|
|
||||||
|
var scroll := ScrollContainer.new()
|
||||||
|
scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||||
|
scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
|
||||||
|
content.add_child(scroll)
|
||||||
|
|
||||||
|
var scroll_content := VBoxContainer.new()
|
||||||
|
scroll_content.add_theme_constant_override("separation", 14)
|
||||||
|
scroll_content.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
scroll.add_child(scroll_content)
|
||||||
|
|
||||||
subtitle_label = Label.new()
|
subtitle_label = Label.new()
|
||||||
subtitle_label.text = "Test your luck and win exciting rewards!"
|
subtitle_label.text = "Test your luck and win exciting rewards!"
|
||||||
subtitle_label.add_theme_font_override("font", Brand.font)
|
subtitle_label.add_theme_font_override("font", Brand.font)
|
||||||
subtitle_label.add_theme_font_size_override("font_size", 14)
|
subtitle_label.add_theme_font_size_override("font_size", 13)
|
||||||
subtitle_label.add_theme_color_override("font_color", Brand.muted_color(UIThemeService.is_dark_mode()))
|
subtitle_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||||
add_child(subtitle_label)
|
scroll_content.add_child(subtitle_label)
|
||||||
|
|
||||||
|
_build_machine(scroll_content)
|
||||||
|
_build_controls(scroll_content)
|
||||||
|
_build_rewards_section(scroll_content)
|
||||||
|
_build_footer(scroll_content)
|
||||||
|
|
||||||
|
status_label = Label.new()
|
||||||
|
status_label.add_theme_font_override("font", Brand.font)
|
||||||
|
status_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||||
|
status_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||||
|
scroll_content.add_child(status_label)
|
||||||
|
|
||||||
|
|
||||||
|
func _build_title_bar(content: VBoxContainer) -> void:
|
||||||
|
var title_bar := HBoxContainer.new()
|
||||||
|
title_bar.name = "SlotMachineTitleBar"
|
||||||
|
title_bar.mouse_filter = Control.MOUSE_FILTER_STOP
|
||||||
|
title_bar.custom_minimum_size.y = 34
|
||||||
|
title_bar.gui_input.connect(_on_title_bar_gui_input)
|
||||||
|
content.add_child(title_bar)
|
||||||
|
|
||||||
|
var title := Label.new()
|
||||||
|
title.text = "RZ Slot Machine"
|
||||||
|
title.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
title.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||||
|
title.add_theme_font_override("font", Brand.font)
|
||||||
|
title.add_theme_font_size_override("font_size", 18)
|
||||||
|
title_bar.add_child(title)
|
||||||
|
|
||||||
|
var close := Button.new()
|
||||||
|
close.name = "SlotMachineClose"
|
||||||
|
close.text = "×"
|
||||||
|
close.tooltip_text = "Close slot machine"
|
||||||
|
close.custom_minimum_size = Vector2(36, 32)
|
||||||
|
close.focus_mode = Control.FOCUS_NONE
|
||||||
|
close.pressed.connect(close_panel)
|
||||||
|
title_bar.add_child(close)
|
||||||
|
|
||||||
|
|
||||||
func _build_machine(parent: Control) -> void:
|
func _build_machine(parent: Control) -> void:
|
||||||
|
var center := CenterContainer.new()
|
||||||
|
parent.add_child(center)
|
||||||
|
|
||||||
machine_root = Control.new()
|
machine_root = Control.new()
|
||||||
machine_root.custom_minimum_size = Vector2(560, 560)
|
machine_root.custom_minimum_size = Vector2(MACHINE_SIZE, MACHINE_SIZE)
|
||||||
machine_root.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
|
center.add_child(machine_root)
|
||||||
machine_root.size_flags_vertical = Control.SIZE_SHRINK_BEGIN
|
|
||||||
parent.add_child(machine_root)
|
|
||||||
|
|
||||||
var frame := TextureRect.new()
|
var frame := TextureRect.new()
|
||||||
frame.texture = CABINET_FRAME
|
frame.texture = CABINET_FRAME
|
||||||
@@ -127,20 +195,19 @@ func _build_machine(parent: Control) -> void:
|
|||||||
window.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
window.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||||
machine_root.add_child(window)
|
machine_root.add_child(window)
|
||||||
|
|
||||||
var center := CenterContainer.new()
|
var reel_center := CenterContainer.new()
|
||||||
center.set_anchors_preset(Control.PRESET_FULL_RECT)
|
reel_center.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||||
window.add_child(center)
|
window.add_child(reel_center)
|
||||||
|
|
||||||
var reels_grid := HBoxContainer.new()
|
var reels_grid := HBoxContainer.new()
|
||||||
reels_grid.add_theme_constant_override("separation", 16)
|
reels_grid.add_theme_constant_override("separation", 10)
|
||||||
center.add_child(reels_grid)
|
reel_center.add_child(reels_grid)
|
||||||
|
|
||||||
var cell := 66.0
|
|
||||||
reel_states.clear()
|
reel_states.clear()
|
||||||
for _column_index in range(3):
|
for _column_index in range(3):
|
||||||
var clip := Control.new()
|
var clip := Control.new()
|
||||||
clip.clip_contents = true
|
clip.clip_contents = true
|
||||||
clip.custom_minimum_size = Vector2(cell, cell * 3)
|
clip.custom_minimum_size = Vector2(CELL, CELL * 3)
|
||||||
reels_grid.add_child(clip)
|
reels_grid.add_child(clip)
|
||||||
|
|
||||||
var strip := VBoxContainer.new()
|
var strip := VBoxContainer.new()
|
||||||
@@ -151,7 +218,7 @@ func _build_machine(parent: Control) -> void:
|
|||||||
for _row_index in range(4):
|
for _row_index in range(4):
|
||||||
var icon := TextureRect.new()
|
var icon := TextureRect.new()
|
||||||
icon.texture = REEL_SYMBOLS[randi() % REEL_SYMBOLS.size()]
|
icon.texture = REEL_SYMBOLS[randi() % REEL_SYMBOLS.size()]
|
||||||
icon.custom_minimum_size = Vector2(cell, cell)
|
icon.custom_minimum_size = Vector2(CELL, CELL)
|
||||||
icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
||||||
icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||||
strip.add_child(icon)
|
strip.add_child(icon)
|
||||||
@@ -160,8 +227,8 @@ func _build_machine(parent: Control) -> void:
|
|||||||
reel_states.append({
|
reel_states.append({
|
||||||
"strip": strip,
|
"strip": strip,
|
||||||
"icons": icons,
|
"icons": icons,
|
||||||
"step": cell,
|
"step": CELL,
|
||||||
"speed": 620.0,
|
"speed": 420.0,
|
||||||
"spinning": false,
|
"spinning": false,
|
||||||
"stop_requested": false,
|
"stop_requested": false,
|
||||||
"target_texture": null,
|
"target_texture": null,
|
||||||
@@ -199,22 +266,22 @@ func _build_controls(parent: Control) -> void:
|
|||||||
win_up_to_label = Label.new()
|
win_up_to_label = Label.new()
|
||||||
win_up_to_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
win_up_to_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||||
win_up_to_label.add_theme_font_override("font", Brand.font)
|
win_up_to_label.add_theme_font_override("font", Brand.font)
|
||||||
win_up_to_label.add_theme_font_size_override("font_size", 15)
|
win_up_to_label.add_theme_font_size_override("font_size", 14)
|
||||||
win_up_to_label.add_theme_color_override("font_color", Brand.text_color(dark))
|
win_up_to_label.add_theme_color_override("font_color", Brand.text_color(dark))
|
||||||
win_margin.add_child(win_up_to_label)
|
win_margin.add_child(win_up_to_label)
|
||||||
|
|
||||||
var controls_row := HBoxContainer.new()
|
var controls_row := HBoxContainer.new()
|
||||||
controls_row.add_theme_constant_override("separation", 12)
|
controls_row.add_theme_constant_override("separation", 10)
|
||||||
parent.add_child(controls_row)
|
parent.add_child(controls_row)
|
||||||
|
|
||||||
cost_card = PanelContainer.new()
|
cost_card = PanelContainer.new()
|
||||||
cost_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
|
cost_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
|
||||||
controls_row.add_child(cost_card)
|
controls_row.add_child(cost_card)
|
||||||
var cost_margin := MarginContainer.new()
|
var cost_margin := MarginContainer.new()
|
||||||
cost_margin.add_theme_constant_override("margin_left", 14)
|
cost_margin.add_theme_constant_override("margin_left", 10)
|
||||||
cost_margin.add_theme_constant_override("margin_right", 14)
|
cost_margin.add_theme_constant_override("margin_right", 10)
|
||||||
cost_margin.add_theme_constant_override("margin_top", 8)
|
cost_margin.add_theme_constant_override("margin_top", 6)
|
||||||
cost_margin.add_theme_constant_override("margin_bottom", 8)
|
cost_margin.add_theme_constant_override("margin_bottom", 6)
|
||||||
cost_card.add_child(cost_margin)
|
cost_card.add_child(cost_margin)
|
||||||
var cost_box := VBoxContainer.new()
|
var cost_box := VBoxContainer.new()
|
||||||
cost_box.add_theme_constant_override("separation", 0)
|
cost_box.add_theme_constant_override("separation", 0)
|
||||||
@@ -222,22 +289,22 @@ func _build_controls(parent: Control) -> void:
|
|||||||
var cost_caption := Label.new()
|
var cost_caption := Label.new()
|
||||||
cost_caption.text = "Cost per spin"
|
cost_caption.text = "Cost per spin"
|
||||||
cost_caption.add_theme_font_override("font", Brand.font)
|
cost_caption.add_theme_font_override("font", Brand.font)
|
||||||
cost_caption.add_theme_font_size_override("font_size", 11)
|
cost_caption.add_theme_font_size_override("font_size", 10)
|
||||||
cost_caption.add_theme_color_override("font_color", Brand.muted_color(dark))
|
cost_caption.add_theme_color_override("font_color", Brand.muted_color(dark))
|
||||||
cost_box.add_child(cost_caption)
|
cost_box.add_child(cost_caption)
|
||||||
cost_value_label = Label.new()
|
cost_value_label = Label.new()
|
||||||
cost_value_label.add_theme_font_override("font", Brand.font)
|
cost_value_label.add_theme_font_override("font", Brand.font)
|
||||||
cost_value_label.add_theme_font_size_override("font_size", 15)
|
cost_value_label.add_theme_font_size_override("font_size", 14)
|
||||||
cost_value_label.add_theme_color_override("font_color", Brand.text_color(dark))
|
cost_value_label.add_theme_color_override("font_color", Brand.text_color(dark))
|
||||||
cost_box.add_child(cost_value_label)
|
cost_box.add_child(cost_value_label)
|
||||||
|
|
||||||
spin_button = Button.new()
|
spin_button = Button.new()
|
||||||
spin_button.text = "Spin"
|
spin_button.text = "Spin"
|
||||||
spin_button.custom_minimum_size = Vector2(140, 58)
|
spin_button.custom_minimum_size = Vector2(110, 52)
|
||||||
spin_button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
spin_button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
spin_button.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
spin_button.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||||
spin_button.add_theme_font_override("font", Brand.font)
|
spin_button.add_theme_font_override("font", Brand.font)
|
||||||
spin_button.add_theme_font_size_override("font_size", 17)
|
spin_button.add_theme_font_size_override("font_size", 16)
|
||||||
_style_spin_button()
|
_style_spin_button()
|
||||||
spin_button.pressed.connect(_on_spin_pressed)
|
spin_button.pressed.connect(_on_spin_pressed)
|
||||||
controls_row.add_child(spin_button)
|
controls_row.add_child(spin_button)
|
||||||
@@ -246,10 +313,10 @@ func _build_controls(parent: Control) -> void:
|
|||||||
auto_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
|
auto_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
|
||||||
controls_row.add_child(auto_card)
|
controls_row.add_child(auto_card)
|
||||||
var auto_margin := MarginContainer.new()
|
var auto_margin := MarginContainer.new()
|
||||||
auto_margin.add_theme_constant_override("margin_left", 14)
|
auto_margin.add_theme_constant_override("margin_left", 10)
|
||||||
auto_margin.add_theme_constant_override("margin_right", 14)
|
auto_margin.add_theme_constant_override("margin_right", 10)
|
||||||
auto_margin.add_theme_constant_override("margin_top", 8)
|
auto_margin.add_theme_constant_override("margin_top", 6)
|
||||||
auto_margin.add_theme_constant_override("margin_bottom", 8)
|
auto_margin.add_theme_constant_override("margin_bottom", 6)
|
||||||
auto_card.add_child(auto_margin)
|
auto_card.add_child(auto_margin)
|
||||||
var auto_box := VBoxContainer.new()
|
var auto_box := VBoxContainer.new()
|
||||||
auto_box.add_theme_constant_override("separation", 0)
|
auto_box.add_theme_constant_override("separation", 0)
|
||||||
@@ -261,31 +328,30 @@ func _build_controls(parent: Control) -> void:
|
|||||||
var auto_caption := Label.new()
|
var auto_caption := Label.new()
|
||||||
auto_caption.text = "10 spins"
|
auto_caption.text = "10 spins"
|
||||||
auto_caption.add_theme_font_override("font", Brand.font)
|
auto_caption.add_theme_font_override("font", Brand.font)
|
||||||
auto_caption.add_theme_font_size_override("font_size", 11)
|
auto_caption.add_theme_font_size_override("font_size", 10)
|
||||||
auto_caption.add_theme_color_override("font_color", Brand.muted_color(dark))
|
auto_caption.add_theme_color_override("font_color", Brand.muted_color(dark))
|
||||||
auto_box.add_child(auto_caption)
|
auto_box.add_child(auto_caption)
|
||||||
|
|
||||||
var info_label := Label.new()
|
var info_label := Label.new()
|
||||||
info_label.text = "All rewards are instant and sent to your account."
|
info_label.text = "All rewards are instant and sent to your account."
|
||||||
info_label.add_theme_font_override("font", Brand.font)
|
info_label.add_theme_font_override("font", Brand.font)
|
||||||
info_label.add_theme_font_size_override("font_size", 11)
|
info_label.add_theme_font_size_override("font_size", 10)
|
||||||
info_label.add_theme_color_override("font_color", Brand.muted_color(dark))
|
info_label.add_theme_color_override("font_color", Brand.muted_color(dark))
|
||||||
info_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
info_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||||
parent.add_child(info_label)
|
parent.add_child(info_label)
|
||||||
|
|
||||||
|
|
||||||
func _build_rewards_panel(parent: Control) -> void:
|
func _build_rewards_section(parent: Control) -> void:
|
||||||
var dark := UIThemeService.is_dark_mode()
|
var dark := UIThemeService.is_dark_mode()
|
||||||
var panel := PanelContainer.new()
|
var panel := PanelContainer.new()
|
||||||
panel.custom_minimum_size = Vector2(280, 0)
|
|
||||||
panel.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
|
panel.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
|
||||||
parent.add_child(panel)
|
parent.add_child(panel)
|
||||||
|
|
||||||
var margin := MarginContainer.new()
|
var margin := MarginContainer.new()
|
||||||
margin.add_theme_constant_override("margin_left", 16)
|
margin.add_theme_constant_override("margin_left", 14)
|
||||||
margin.add_theme_constant_override("margin_right", 16)
|
margin.add_theme_constant_override("margin_right", 14)
|
||||||
margin.add_theme_constant_override("margin_top", 14)
|
margin.add_theme_constant_override("margin_top", 12)
|
||||||
margin.add_theme_constant_override("margin_bottom", 14)
|
margin.add_theme_constant_override("margin_bottom", 12)
|
||||||
panel.add_child(margin)
|
panel.add_child(margin)
|
||||||
|
|
||||||
var column := VBoxContainer.new()
|
var column := VBoxContainer.new()
|
||||||
@@ -295,39 +361,39 @@ func _build_rewards_panel(parent: Control) -> void:
|
|||||||
var heading := Label.new()
|
var heading := Label.new()
|
||||||
heading.text = "Possible Rewards"
|
heading.text = "Possible Rewards"
|
||||||
heading.add_theme_font_override("font", Brand.font)
|
heading.add_theme_font_override("font", Brand.font)
|
||||||
heading.add_theme_font_size_override("font_size", 16)
|
heading.add_theme_font_size_override("font_size", 15)
|
||||||
heading.add_theme_color_override("font_color", Brand.text_color(dark))
|
heading.add_theme_color_override("font_color", Brand.text_color(dark))
|
||||||
column.add_child(heading)
|
column.add_child(heading)
|
||||||
|
|
||||||
rewards_list = VBoxContainer.new()
|
rewards_list = VBoxContainer.new()
|
||||||
rewards_list.add_theme_constant_override("separation", 10)
|
rewards_list.add_theme_constant_override("separation", 8)
|
||||||
column.add_child(rewards_list)
|
column.add_child(rewards_list)
|
||||||
|
|
||||||
|
|
||||||
func _build_footer() -> void:
|
func _build_footer(parent: Control) -> void:
|
||||||
var dark := UIThemeService.is_dark_mode()
|
var dark := UIThemeService.is_dark_mode()
|
||||||
footer_card = PanelContainer.new()
|
footer_card = PanelContainer.new()
|
||||||
footer_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
|
footer_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
|
||||||
add_child(footer_card)
|
parent.add_child(footer_card)
|
||||||
|
|
||||||
var margin := MarginContainer.new()
|
var margin := MarginContainer.new()
|
||||||
margin.add_theme_constant_override("margin_left", 16)
|
margin.add_theme_constant_override("margin_left", 14)
|
||||||
margin.add_theme_constant_override("margin_right", 16)
|
margin.add_theme_constant_override("margin_right", 14)
|
||||||
margin.add_theme_constant_override("margin_top", 12)
|
margin.add_theme_constant_override("margin_top", 10)
|
||||||
margin.add_theme_constant_override("margin_bottom", 12)
|
margin.add_theme_constant_override("margin_bottom", 10)
|
||||||
footer_card.add_child(margin)
|
footer_card.add_child(margin)
|
||||||
|
|
||||||
var row := HBoxContainer.new()
|
var row := HBoxContainer.new()
|
||||||
row.add_theme_constant_override("separation", 14)
|
row.add_theme_constant_override("separation", 12)
|
||||||
margin.add_child(row)
|
margin.add_child(row)
|
||||||
|
|
||||||
footer_icon_panel = PanelContainer.new()
|
footer_icon_panel = PanelContainer.new()
|
||||||
footer_icon_panel.custom_minimum_size = Vector2(36, 36)
|
footer_icon_panel.custom_minimum_size = Vector2(32, 32)
|
||||||
footer_icon_panel.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
footer_icon_panel.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||||
footer_icon_panel.add_theme_stylebox_override("panel", Brand.icon_circle_box(dark, Brand.ROYAL_BLUE, 18))
|
footer_icon_panel.add_theme_stylebox_override("panel", Brand.icon_circle_box(dark, Brand.ROYAL_BLUE, 16))
|
||||||
footer_icon = TextureRect.new()
|
footer_icon = TextureRect.new()
|
||||||
footer_icon.texture = STAR_ICON
|
footer_icon.texture = STAR_ICON
|
||||||
footer_icon.custom_minimum_size = Vector2(18, 18)
|
footer_icon.custom_minimum_size = Vector2(16, 16)
|
||||||
footer_icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
footer_icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
||||||
footer_icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
footer_icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||||
footer_icon.modulate = Brand.ROYAL_BLUE
|
footer_icon.modulate = Brand.ROYAL_BLUE
|
||||||
@@ -341,21 +407,22 @@ func _build_footer() -> void:
|
|||||||
footer_heading = Label.new()
|
footer_heading = Label.new()
|
||||||
footer_heading.text = "How it works"
|
footer_heading.text = "How it works"
|
||||||
footer_heading.add_theme_font_override("font", Brand.font)
|
footer_heading.add_theme_font_override("font", Brand.font)
|
||||||
footer_heading.add_theme_font_size_override("font_size", 15)
|
footer_heading.add_theme_font_size_override("font_size", 14)
|
||||||
footer_heading.add_theme_color_override("font_color", Brand.text_color(dark))
|
footer_heading.add_theme_color_override("font_color", Brand.text_color(dark))
|
||||||
copy.add_child(footer_heading)
|
copy.add_child(footer_heading)
|
||||||
footer_description = Label.new()
|
footer_description = Label.new()
|
||||||
footer_description.text = "Spend RZ Coins to spin the slot machine. Win coins, boosts, tokens, and more!"
|
footer_description.text = "Spend RZ Coins to spin the slot machine. Win coins, boosts, tokens, and more!"
|
||||||
footer_description.add_theme_font_override("font", Brand.font)
|
footer_description.add_theme_font_override("font", Brand.font)
|
||||||
footer_description.add_theme_font_size_override("font_size", 12)
|
footer_description.add_theme_font_size_override("font_size", 11)
|
||||||
footer_description.add_theme_color_override("font_color", Brand.muted_color(dark))
|
footer_description.add_theme_color_override("font_color", Brand.muted_color(dark))
|
||||||
footer_description.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
footer_description.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||||
copy.add_child(footer_description)
|
copy.add_child(footer_description)
|
||||||
row.add_child(copy)
|
row.add_child(copy)
|
||||||
|
|
||||||
|
|
||||||
func _refresh_theme_controls() -> void:
|
func refresh_theme_controls() -> void:
|
||||||
var dark := UIThemeService.is_dark_mode()
|
var dark := UIThemeService.is_dark_mode()
|
||||||
|
add_theme_stylebox_override("panel", Brand.content_card_box(dark, true, Brand.ROYAL_BLUE))
|
||||||
subtitle_label.add_theme_color_override("font_color", Brand.muted_color(dark))
|
subtitle_label.add_theme_color_override("font_color", Brand.muted_color(dark))
|
||||||
win_up_to_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
|
win_up_to_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
|
||||||
win_up_to_label.add_theme_color_override("font_color", Brand.text_color(dark))
|
win_up_to_label.add_theme_color_override("font_color", Brand.text_color(dark))
|
||||||
@@ -363,7 +430,7 @@ func _refresh_theme_controls() -> void:
|
|||||||
cost_value_label.add_theme_color_override("font_color", Brand.text_color(dark))
|
cost_value_label.add_theme_color_override("font_color", Brand.text_color(dark))
|
||||||
auto_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
|
auto_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
|
||||||
footer_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
|
footer_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
|
||||||
footer_icon_panel.add_theme_stylebox_override("panel", Brand.icon_circle_box(dark, Brand.ROYAL_BLUE, 18))
|
footer_icon_panel.add_theme_stylebox_override("panel", Brand.icon_circle_box(dark, Brand.ROYAL_BLUE, 16))
|
||||||
footer_heading.add_theme_color_override("font_color", Brand.text_color(dark))
|
footer_heading.add_theme_color_override("font_color", Brand.text_color(dark))
|
||||||
footer_description.add_theme_color_override("font_color", Brand.muted_color(dark))
|
footer_description.add_theme_color_override("font_color", Brand.muted_color(dark))
|
||||||
_refresh_rewards()
|
_refresh_rewards()
|
||||||
@@ -382,6 +449,8 @@ func _reward_color(key: String) -> Color:
|
|||||||
|
|
||||||
|
|
||||||
func _refresh_rewards() -> void:
|
func _refresh_rewards() -> void:
|
||||||
|
if cost_value_label == null:
|
||||||
|
return
|
||||||
var dark := UIThemeService.is_dark_mode()
|
var dark := UIThemeService.is_dark_mode()
|
||||||
cost_value_label.text = "%d RZ Coins" % CreditsService.spin_cost
|
cost_value_label.text = "%d RZ Coins" % CreditsService.spin_cost
|
||||||
|
|
||||||
@@ -408,13 +477,13 @@ func _build_reward_row(dark: bool, reward: Dictionary) -> HBoxContainer:
|
|||||||
row.add_theme_constant_override("separation", 10)
|
row.add_theme_constant_override("separation", 10)
|
||||||
|
|
||||||
var icon_panel := PanelContainer.new()
|
var icon_panel := PanelContainer.new()
|
||||||
icon_panel.custom_minimum_size = Vector2(36, 36)
|
icon_panel.custom_minimum_size = Vector2(34, 34)
|
||||||
icon_panel.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
icon_panel.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||||
icon_panel.add_theme_stylebox_override("panel", Brand.icon_circle_box(dark, accent, 18))
|
icon_panel.add_theme_stylebox_override("panel", Brand.icon_circle_box(dark, accent, 17))
|
||||||
var icon := TextureRect.new()
|
var icon := TextureRect.new()
|
||||||
var spec: Dictionary = REWARD_ICONS.get(key, {"texture": SLOT_COIN, "modulate": false})
|
var spec: Dictionary = REWARD_ICONS.get(key, {"texture": SLOT_COIN, "modulate": false})
|
||||||
icon.texture = spec.get("texture")
|
icon.texture = spec.get("texture")
|
||||||
icon.custom_minimum_size = Vector2(22, 22)
|
icon.custom_minimum_size = Vector2(20, 20)
|
||||||
icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
||||||
icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||||
if spec.get("modulate", false):
|
if spec.get("modulate", false):
|
||||||
@@ -431,13 +500,13 @@ func _build_reward_row(dark: bool, reward: Dictionary) -> HBoxContainer:
|
|||||||
var label := Label.new()
|
var label := Label.new()
|
||||||
label.text = str(reward.get("label", ""))
|
label.text = str(reward.get("label", ""))
|
||||||
label.add_theme_font_override("font", Brand.font)
|
label.add_theme_font_override("font", Brand.font)
|
||||||
label.add_theme_font_size_override("font_size", 13)
|
label.add_theme_font_size_override("font_size", 12)
|
||||||
label.add_theme_color_override("font_color", Brand.text_color(dark))
|
label.add_theme_color_override("font_color", Brand.text_color(dark))
|
||||||
copy.add_child(label)
|
copy.add_child(label)
|
||||||
var description := Label.new()
|
var description := Label.new()
|
||||||
description.text = str(reward.get("description", ""))
|
description.text = str(reward.get("description", ""))
|
||||||
description.add_theme_font_override("font", Brand.font)
|
description.add_theme_font_override("font", Brand.font)
|
||||||
description.add_theme_font_size_override("font_size", 11)
|
description.add_theme_font_size_override("font_size", 10)
|
||||||
description.add_theme_color_override("font_color", Brand.muted_color(dark))
|
description.add_theme_color_override("font_color", Brand.muted_color(dark))
|
||||||
copy.add_child(description)
|
copy.add_child(description)
|
||||||
row.add_child(copy)
|
row.add_child(copy)
|
||||||
@@ -445,7 +514,7 @@ func _build_reward_row(dark: bool, reward: Dictionary) -> HBoxContainer:
|
|||||||
var percent_label := Label.new()
|
var percent_label := Label.new()
|
||||||
percent_label.text = "%s%%" % _format_percent(float(reward.get("probability", 0.0)) * 100.0)
|
percent_label.text = "%s%%" % _format_percent(float(reward.get("probability", 0.0)) * 100.0)
|
||||||
percent_label.add_theme_font_override("font", Brand.font)
|
percent_label.add_theme_font_override("font", Brand.font)
|
||||||
percent_label.add_theme_font_size_override("font_size", 13)
|
percent_label.add_theme_font_size_override("font_size", 12)
|
||||||
percent_label.add_theme_color_override("font_color", accent)
|
percent_label.add_theme_color_override("font_color", accent)
|
||||||
row.add_child(percent_label)
|
row.add_child(percent_label)
|
||||||
|
|
||||||
@@ -453,6 +522,8 @@ func _build_reward_row(dark: bool, reward: Dictionary) -> HBoxContainer:
|
|||||||
|
|
||||||
|
|
||||||
func _refresh_spin_button() -> void:
|
func _refresh_spin_button() -> void:
|
||||||
|
if spin_button == null:
|
||||||
|
return
|
||||||
var disabled := _spinning or CreditsService.credits < CreditsService.spin_cost
|
var disabled := _spinning or CreditsService.credits < CreditsService.spin_cost
|
||||||
spin_button.disabled = disabled
|
spin_button.disabled = disabled
|
||||||
lever_button.disabled = disabled
|
lever_button.disabled = disabled
|
||||||
@@ -648,6 +719,46 @@ func _style_spin_button() -> void:
|
|||||||
spin_button.add_theme_color_override("font_disabled_color", Color(Brand.DARK_TEXT, 0.7))
|
spin_button.add_theme_color_override("font_disabled_color", Color(Brand.DARK_TEXT, 0.7))
|
||||||
|
|
||||||
|
|
||||||
|
func _on_title_bar_gui_input(event: InputEvent) -> void:
|
||||||
|
var touch_event := event as InputEventScreenTouch
|
||||||
|
if touch_event != null:
|
||||||
|
drag_active = touch_event.pressed
|
||||||
|
if drag_active:
|
||||||
|
drag_offset = touch_event.position
|
||||||
|
get_viewport().set_input_as_handled()
|
||||||
|
return
|
||||||
|
var touch_drag := event as InputEventScreenDrag
|
||||||
|
if touch_drag != null and drag_active:
|
||||||
|
global_position += touch_drag.relative
|
||||||
|
_clamp_to_viewport()
|
||||||
|
get_viewport().set_input_as_handled()
|
||||||
|
return
|
||||||
|
var mouse_event := event as InputEventMouseButton
|
||||||
|
if mouse_event != null and mouse_event.button_index == MOUSE_BUTTON_LEFT:
|
||||||
|
drag_active = mouse_event.pressed
|
||||||
|
if drag_active:
|
||||||
|
drag_offset = mouse_event.global_position - global_position
|
||||||
|
get_viewport().set_input_as_handled()
|
||||||
|
return
|
||||||
|
var motion := event as InputEventMouseMotion
|
||||||
|
if motion != null and drag_active:
|
||||||
|
global_position = motion.global_position - drag_offset
|
||||||
|
_clamp_to_viewport()
|
||||||
|
get_viewport().set_input_as_handled()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_viewport_size_changed() -> void:
|
||||||
|
_clamp_to_viewport()
|
||||||
|
|
||||||
|
|
||||||
|
func _clamp_to_viewport() -> void:
|
||||||
|
if not is_inside_tree():
|
||||||
|
return
|
||||||
|
var viewport_size := get_viewport_rect().size
|
||||||
|
position.x = clampf(position.x, 12.0, maxf(12.0, viewport_size.x - size.x - 12.0))
|
||||||
|
position.y = clampf(position.y, 12.0, maxf(12.0, viewport_size.y - size.y - 12.0))
|
||||||
|
|
||||||
|
|
||||||
func _format_thousands(value: int) -> String:
|
func _format_thousands(value: int) -> String:
|
||||||
var digits := str(absi(value))
|
var digits := str(absi(value))
|
||||||
var grouped := ""
|
var grouped := ""
|
||||||
|
|||||||
Reference in New Issue
Block a user