Add synchronized Fishnet jobs and laptop UI
This commit is contained in:
parent
46df74361a
commit
26fbd41132
39 changed files with 3257 additions and 188 deletions
|
|
@ -4,6 +4,7 @@ extends Control
|
|||
const CHECK_DEBOUNCE_SECONDS: float = 0.4
|
||||
|
||||
var _service: NetworkProfileService
|
||||
var _experience: PlayerExperience
|
||||
var _draft_name: String = ""
|
||||
var _draft_appearance: Dictionary = {}
|
||||
var _persisted_name: String = ""
|
||||
|
|
@ -25,6 +26,9 @@ var _confirmation_label: Label
|
|||
var _confirmation_confirm: Button
|
||||
var _confirmation_action: String = ""
|
||||
var _debounce: Timer
|
||||
var _experience_level: Label
|
||||
var _experience_progress: ProgressBar
|
||||
var _experience_value: Label
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
|
|
@ -37,12 +41,24 @@ func _ready() -> void:
|
|||
add_child(_debounce)
|
||||
|
||||
|
||||
func setup(service: NetworkProfileService) -> void:
|
||||
func setup(
|
||||
service: NetworkProfileService,
|
||||
experience: PlayerExperience,
|
||||
) -> void:
|
||||
_service = service
|
||||
_experience = experience
|
||||
if not _service.conflict_result.is_connected(_on_conflict_result):
|
||||
_service.conflict_result.connect(_on_conflict_result)
|
||||
_service.apply_finished.connect(_on_apply_finished)
|
||||
if (
|
||||
_experience != null
|
||||
and not _experience.experience_changed.is_connected(
|
||||
_on_experience_changed
|
||||
)
|
||||
):
|
||||
_experience.experience_changed.connect(_on_experience_changed)
|
||||
_load_persisted()
|
||||
_refresh_experience()
|
||||
var identity_value := find_child("IdentityFingerprint", true, false) as Label
|
||||
if identity_value != null:
|
||||
var fingerprint := _service.get_identity_fingerprint()
|
||||
|
|
@ -108,134 +124,200 @@ func has_modal_confirmation() -> bool:
|
|||
|
||||
|
||||
func _build_ui() -> void:
|
||||
var paper := PanelContainer.new()
|
||||
paper.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
paper.offset_left = 64.0
|
||||
paper.offset_top = 28.0
|
||||
paper.offset_right = -64.0
|
||||
paper.offset_bottom = -28.0
|
||||
paper.add_theme_stylebox_override(
|
||||
"panel", UtilityPageStyle.panel_style()
|
||||
)
|
||||
add_child(paper)
|
||||
UtilityPageStyle.apply_page(self)
|
||||
|
||||
var margin := MarginContainer.new()
|
||||
for side: String in ["left", "right", "top", "bottom"]:
|
||||
margin.add_theme_constant_override("margin_%s" % side, 18)
|
||||
paper.add_child(margin)
|
||||
var margin: MarginContainer = UtilityPageStyle.build_laptop_screen(self)
|
||||
var layout := VBoxContainer.new()
|
||||
layout.add_theme_constant_override("separation", 5)
|
||||
layout.add_theme_constant_override("separation", 8)
|
||||
margin.add_child(layout)
|
||||
|
||||
var heading := Label.new()
|
||||
heading.text = "Player Profile"
|
||||
heading.add_theme_font_size_override("font_size", 25)
|
||||
heading.add_theme_color_override(
|
||||
"font_color", UtilityPageStyle.OCEAN_TEXT_PRIMARY
|
||||
)
|
||||
layout.add_child(heading)
|
||||
|
||||
var name_row := HBoxContainer.new()
|
||||
name_row.add_theme_constant_override("separation", 10)
|
||||
layout.add_child(name_row)
|
||||
var name_stack := VBoxContainer.new()
|
||||
name_stack.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
name_row.add_child(name_stack)
|
||||
var account_row := HBoxContainer.new()
|
||||
account_row.add_theme_constant_override("separation", 14)
|
||||
layout.add_child(account_row)
|
||||
var account_stack := VBoxContainer.new()
|
||||
account_stack.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
account_stack.add_theme_constant_override("separation", 2)
|
||||
account_row.add_child(account_stack)
|
||||
var name_line := HBoxContainer.new()
|
||||
name_line.add_theme_constant_override("separation", 10)
|
||||
account_stack.add_child(name_line)
|
||||
var name_label := Label.new()
|
||||
name_label.text = "player name"
|
||||
name_label.custom_minimum_size.x = 98.0
|
||||
name_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
name_label.add_theme_color_override(
|
||||
"font_color", UtilityPageStyle.OCEAN_TEXT_PRIMARY
|
||||
)
|
||||
name_stack.add_child(name_label)
|
||||
name_line.add_child(name_label)
|
||||
_name_edit = LineEdit.new()
|
||||
_name_edit.max_length = NetworkProtocol.MAX_DISPLAY_NAME_LENGTH
|
||||
_name_edit.placeholder_text = "Player"
|
||||
_name_edit.custom_minimum_size = Vector2(300, 40)
|
||||
_name_edit.custom_minimum_size = Vector2(280, 34)
|
||||
UtilityPageStyle.apply_ocean_line_edit(_name_edit)
|
||||
_name_edit.add_theme_stylebox_override(
|
||||
"normal", UtilityPageStyle.ocean_button_style(
|
||||
UtilityPageStyle.OCEAN_PANEL_MID
|
||||
)
|
||||
)
|
||||
_name_edit.text_changed.connect(_on_name_changed)
|
||||
name_stack.add_child(_name_edit)
|
||||
name_line.add_child(_name_edit)
|
||||
var helper := Label.new()
|
||||
helper.text = "Shown to other players in multiplayer."
|
||||
helper.add_theme_font_size_override("font_size", 12)
|
||||
helper.add_theme_color_override(
|
||||
"font_color", UtilityPageStyle.OCEAN_TEXT_SECONDARY
|
||||
)
|
||||
name_stack.add_child(helper)
|
||||
_apply_button = Button.new()
|
||||
_apply_button.text = "apply"
|
||||
_apply_button.custom_minimum_size = Vector2(92, 40)
|
||||
UtilityPageStyle.apply_ocean_button(_apply_button)
|
||||
_apply_button.pressed.connect(_apply)
|
||||
name_row.add_child(_apply_button)
|
||||
_revert_button = Button.new()
|
||||
_revert_button.text = "revert"
|
||||
_revert_button.custom_minimum_size = Vector2(88, 40)
|
||||
UtilityPageStyle.apply_ocean_button(_revert_button)
|
||||
_revert_button.pressed.connect(_revert)
|
||||
name_row.add_child(_revert_button)
|
||||
var defaults_button := Button.new()
|
||||
defaults_button.text = "defaults"
|
||||
defaults_button.custom_minimum_size = Vector2(88, 40)
|
||||
UtilityPageStyle.apply_ocean_button(defaults_button)
|
||||
defaults_button.pressed.connect(_show_confirmation.bind("defaults"))
|
||||
name_row.add_child(defaults_button)
|
||||
|
||||
account_stack.add_child(helper)
|
||||
_name_status = Label.new()
|
||||
_name_status.add_theme_font_size_override("font_size", 12)
|
||||
_name_status.add_theme_color_override(
|
||||
"font_color", UtilityPageStyle.OCEAN_TEXT_SECONDARY
|
||||
)
|
||||
layout.add_child(_name_status)
|
||||
account_stack.add_child(_name_status)
|
||||
_suggestions = HBoxContainer.new()
|
||||
_suggestions.add_theme_constant_override("separation", 8)
|
||||
layout.add_child(_suggestions)
|
||||
_suggestions.add_theme_constant_override("separation", 6)
|
||||
account_stack.add_child(_suggestions)
|
||||
|
||||
var identity_value := Label.new()
|
||||
identity_value.name = "IdentityFingerprint"
|
||||
identity_value.text = "Identity • Stored on this device"
|
||||
identity_value.text = "identity • stored on this device"
|
||||
identity_value.tooltip_text = (
|
||||
"This identity helps other players recognize you between sessions."
|
||||
)
|
||||
identity_value.add_theme_font_size_override("font_size", 12)
|
||||
identity_value.add_theme_color_override(
|
||||
"font_color", UtilityPageStyle.OCEAN_TEXT_SECONDARY
|
||||
)
|
||||
layout.add_child(identity_value)
|
||||
account_stack.add_child(identity_value)
|
||||
|
||||
var experience_row := HBoxContainer.new()
|
||||
experience_row.add_theme_constant_override("separation", 9)
|
||||
account_stack.add_child(experience_row)
|
||||
_experience_level = Label.new()
|
||||
_experience_level.custom_minimum_size.x = 64.0
|
||||
_experience_level.add_theme_font_size_override("font_size", 14)
|
||||
_experience_level.add_theme_color_override(
|
||||
"font_color", UtilityPageStyle.OCEAN_TEXT_PRIMARY
|
||||
)
|
||||
experience_row.add_child(_experience_level)
|
||||
_experience_progress = ProgressBar.new()
|
||||
_experience_progress.custom_minimum_size = Vector2(210.0, 14.0)
|
||||
_experience_progress.max_value = 1.0
|
||||
_experience_progress.show_percentage = false
|
||||
_experience_progress.add_theme_stylebox_override(
|
||||
"background", UtilityPageStyle.rounded_style(
|
||||
UtilityPageStyle.OCEAN_PANEL_MID, 7
|
||||
)
|
||||
)
|
||||
_experience_progress.add_theme_stylebox_override(
|
||||
"fill", UtilityPageStyle.rounded_style(
|
||||
UtilityPageStyle.OCEAN_SELECTED, 7
|
||||
)
|
||||
)
|
||||
experience_row.add_child(_experience_progress)
|
||||
_experience_value = Label.new()
|
||||
_experience_value.add_theme_font_size_override("font_size", 14)
|
||||
_experience_value.add_theme_color_override(
|
||||
"font_color", UtilityPageStyle.OCEAN_TEXT_SECONDARY
|
||||
)
|
||||
experience_row.add_child(_experience_value)
|
||||
|
||||
var actions := HBoxContainer.new()
|
||||
actions.alignment = BoxContainer.ALIGNMENT_END
|
||||
actions.size_flags_vertical = Control.SIZE_SHRINK_BEGIN
|
||||
actions.add_theme_constant_override("separation", 7)
|
||||
account_row.add_child(actions)
|
||||
_apply_button = Button.new()
|
||||
_apply_button.text = "apply"
|
||||
_apply_button.custom_minimum_size.x = 72.0
|
||||
UtilityPageStyle.apply_compact_ocean_button(_apply_button)
|
||||
_apply_button.pressed.connect(_apply)
|
||||
actions.add_child(_apply_button)
|
||||
_revert_button = Button.new()
|
||||
_revert_button.text = "revert"
|
||||
_revert_button.custom_minimum_size.x = 76.0
|
||||
UtilityPageStyle.apply_compact_ocean_button(_revert_button)
|
||||
_revert_button.pressed.connect(_revert)
|
||||
actions.add_child(_revert_button)
|
||||
var defaults_button := Button.new()
|
||||
defaults_button.text = "defaults"
|
||||
defaults_button.custom_minimum_size.x = 82.0
|
||||
UtilityPageStyle.apply_compact_ocean_button(defaults_button)
|
||||
defaults_button.pressed.connect(_show_confirmation.bind("defaults"))
|
||||
actions.add_child(defaults_button)
|
||||
|
||||
var body_panel := PanelContainer.new()
|
||||
body_panel.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
body_panel.add_theme_stylebox_override(
|
||||
"panel", UtilityPageStyle.row_style(false)
|
||||
)
|
||||
layout.add_child(body_panel)
|
||||
var body_margin := MarginContainer.new()
|
||||
body_margin.add_theme_constant_override("margin_left", 14)
|
||||
body_margin.add_theme_constant_override("margin_top", 10)
|
||||
body_margin.add_theme_constant_override("margin_right", 14)
|
||||
body_margin.add_theme_constant_override("margin_bottom", 10)
|
||||
body_panel.add_child(body_margin)
|
||||
var body := HBoxContainer.new()
|
||||
body.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
body.add_theme_constant_override("separation", 12)
|
||||
layout.add_child(body)
|
||||
body.alignment = BoxContainer.ALIGNMENT_BEGIN
|
||||
body.add_theme_constant_override("separation", 16)
|
||||
body_margin.add_child(body)
|
||||
_category_list = VBoxContainer.new()
|
||||
_category_list.custom_minimum_size = Vector2(140, 0)
|
||||
_category_list.custom_minimum_size = Vector2(120, 0)
|
||||
_category_list.add_theme_constant_override("separation", 5)
|
||||
body.add_child(_category_list)
|
||||
_option_list = VBoxContainer.new()
|
||||
_option_list.custom_minimum_size = Vector2(190, 0)
|
||||
_option_list.custom_minimum_size = Vector2(170, 0)
|
||||
_option_list.add_theme_constant_override("separation", 5)
|
||||
body.add_child(_option_list)
|
||||
var body_spacer := Control.new()
|
||||
body_spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
body.add_child(body_spacer)
|
||||
var preview_stack := VBoxContainer.new()
|
||||
preview_stack.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
preview_stack.custom_minimum_size.x = 180.0
|
||||
preview_stack.alignment = BoxContainer.ALIGNMENT_CENTER
|
||||
preview_stack.add_theme_constant_override("separation", 7)
|
||||
body.add_child(preview_stack)
|
||||
var preview_frame := PanelContainer.new()
|
||||
preview_frame.custom_minimum_size = Vector2(180.0, 220.0)
|
||||
preview_frame.add_theme_stylebox_override(
|
||||
"panel", UtilityPageStyle.rounded_style(
|
||||
UtilityPageStyle.OCEAN_FIELD, 18
|
||||
)
|
||||
)
|
||||
preview_stack.add_child(preview_frame)
|
||||
_preview = preload("res://ui/profile_preview.tscn").instantiate()
|
||||
preview_stack.add_child(_preview)
|
||||
var preview_actions := HBoxContainer.new()
|
||||
_preview.custom_minimum_size = Vector2(180.0, 220.0)
|
||||
preview_frame.add_child(_preview)
|
||||
var preview_actions := VBoxContainer.new()
|
||||
preview_actions.alignment = BoxContainer.ALIGNMENT_CENTER
|
||||
preview_actions.add_theme_constant_override("separation", 10)
|
||||
preview_actions.add_theme_constant_override("separation", 4)
|
||||
preview_stack.add_child(preview_actions)
|
||||
var preview_note := Label.new()
|
||||
preview_note.text = "Current player • drag or use left / right"
|
||||
preview_note.text = "drag or use left / right"
|
||||
preview_note.custom_minimum_size.x = 180.0
|
||||
preview_note.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
preview_note.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
preview_note.add_theme_font_size_override("font_size", 12)
|
||||
preview_note.add_theme_color_override(
|
||||
"font_color", UtilityPageStyle.OCEAN_TEXT_SECONDARY
|
||||
)
|
||||
preview_actions.add_child(preview_note)
|
||||
var reset_view := Button.new()
|
||||
reset_view.text = "reset view"
|
||||
reset_view.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
|
||||
reset_view.pressed.connect(_preview.reset_view)
|
||||
UtilityPageStyle.apply_ocean_button(reset_view)
|
||||
UtilityPageStyle.apply_compact_ocean_button(reset_view)
|
||||
preview_actions.add_child(reset_view)
|
||||
|
||||
_discard_confirmation = PanelContainer.new()
|
||||
_discard_confirmation.visible = false
|
||||
_discard_confirmation.set_anchors_and_offsets_preset(Control.PRESET_CENTER)
|
||||
_discard_confirmation.custom_minimum_size = Vector2(430, 190)
|
||||
_discard_confirmation.add_theme_stylebox_override(
|
||||
"panel", UtilityPageStyle.rounded_style(
|
||||
UtilityPageStyle.OCEAN_PANEL_MID, 14
|
||||
)
|
||||
)
|
||||
add_child(_discard_confirmation)
|
||||
var confirm_stack := VBoxContainer.new()
|
||||
confirm_stack.alignment = BoxContainer.ALIGNMENT_CENTER
|
||||
|
|
@ -249,6 +331,7 @@ func _build_ui() -> void:
|
|||
confirm_stack.add_child(confirm_buttons)
|
||||
_confirmation_confirm = Button.new()
|
||||
_confirmation_confirm.pressed.connect(_confirm_pending_action)
|
||||
UtilityPageStyle.apply_ocean_button(_confirmation_confirm)
|
||||
confirm_buttons.add_child(_confirmation_confirm)
|
||||
var keep := Button.new()
|
||||
keep.name = "KeepEditing"
|
||||
|
|
@ -258,6 +341,7 @@ func _build_ui() -> void:
|
|||
_discard_confirmation.visible = false
|
||||
_name_edit.grab_focus()
|
||||
)
|
||||
UtilityPageStyle.apply_ocean_button(keep)
|
||||
confirm_buttons.add_child(keep)
|
||||
|
||||
_build_categories()
|
||||
|
|
@ -270,10 +354,10 @@ func _build_categories() -> void:
|
|||
var button := Button.new()
|
||||
button.text = CharacterCustomizationCatalog.category_label(category_id)
|
||||
button.toggle_mode = true
|
||||
button.custom_minimum_size = Vector2(0, 34)
|
||||
button.custom_minimum_size.x = 120.0
|
||||
button.button_pressed = category_id == _category_id
|
||||
button.pressed.connect(_select_category.bind(category_id))
|
||||
UtilityPageStyle.apply_ocean_button(button)
|
||||
UtilityPageStyle.apply_compact_ocean_button(button)
|
||||
_category_list.add_child(button)
|
||||
_refresh_options()
|
||||
|
||||
|
|
@ -294,7 +378,7 @@ func _refresh_options() -> void:
|
|||
child.queue_free()
|
||||
var title := Label.new()
|
||||
title.text = CharacterCustomizationCatalog.category_label(_category_id)
|
||||
title.add_theme_font_size_override("font_size", 22)
|
||||
title.add_theme_font_size_override("font_size", 18)
|
||||
title.add_theme_color_override(
|
||||
"font_color", UtilityPageStyle.OCEAN_TEXT_PRIMARY
|
||||
)
|
||||
|
|
@ -311,10 +395,10 @@ func _refresh_options() -> void:
|
|||
var button := Button.new()
|
||||
button.text = str(option["label"])
|
||||
button.toggle_mode = true
|
||||
button.custom_minimum_size = Vector2(0, 34)
|
||||
button.custom_minimum_size.x = 170.0
|
||||
button.button_pressed = _draft_appearance.get(_category_id) == option_id
|
||||
button.pressed.connect(_select_option.bind(_category_id, option_id))
|
||||
UtilityPageStyle.apply_ocean_button(button)
|
||||
UtilityPageStyle.apply_compact_ocean_button(button)
|
||||
_option_list.add_child(button)
|
||||
|
||||
|
||||
|
|
@ -358,6 +442,7 @@ func _on_conflict_result(
|
|||
var button := Button.new()
|
||||
button.text = suggestion
|
||||
button.pressed.connect(_use_suggestion.bind(suggestion))
|
||||
UtilityPageStyle.apply_compact_ocean_button(button)
|
||||
_suggestions.add_child(button)
|
||||
var anyway := Button.new()
|
||||
anyway.text = "use anyway"
|
||||
|
|
@ -365,9 +450,33 @@ func _on_conflict_result(
|
|||
_allow_duplicate = true
|
||||
_name_status.text = "Duplicate name allowed for this apply."
|
||||
)
|
||||
UtilityPageStyle.apply_compact_ocean_button(anyway)
|
||||
_suggestions.add_child(anyway)
|
||||
|
||||
|
||||
func _on_experience_changed(_total_experience: int, _level: int) -> void:
|
||||
_refresh_experience()
|
||||
|
||||
|
||||
func _refresh_experience() -> void:
|
||||
if _experience_level == null:
|
||||
return
|
||||
if _experience == null:
|
||||
_experience_level.text = "level 1"
|
||||
_experience_progress.value = 0.0
|
||||
_experience_value.text = "0 / 100 xp"
|
||||
return
|
||||
var level: int = _experience.get_level()
|
||||
var current: int = _experience.get_experience_in_level()
|
||||
var required: int = _experience.get_experience_for_next_level()
|
||||
_experience_level.text = "level %d" % level
|
||||
_experience_progress.value = _experience.get_level_progress()
|
||||
_experience_value.text = "%d / %d xp" % [current, required]
|
||||
_experience_value.tooltip_text = "%d total xp" % (
|
||||
_experience.get_total_experience()
|
||||
)
|
||||
|
||||
|
||||
func _use_suggestion(value: String) -> void:
|
||||
_name_edit.text = value
|
||||
_draft_name = value
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue