Improve art tools and UI docking
This commit is contained in:
parent
10e0442437
commit
984f7c641c
13 changed files with 626 additions and 82 deletions
|
|
@ -2,7 +2,7 @@ class_name ArtShopStock
|
|||
extends RefCounted
|
||||
|
||||
const ART_KIT_ITEM_ID: StringName = &"art_kit"
|
||||
const ART_KIT_PRICE: int = 1000
|
||||
const ART_KIT_PRICE: int = 50
|
||||
const UPGRADE_PRICE: int = 50
|
||||
|
||||
const MARKER_PRODUCTS: Array[StringName] = [
|
||||
|
|
|
|||
|
|
@ -931,6 +931,10 @@ func _apply_runtime_settings(settings: PlayerSettingsType) -> void:
|
|||
settings.auto_click_enabled,
|
||||
settings.auto_click_interval
|
||||
)
|
||||
_game_ui.set_edge_docks(
|
||||
settings.chat_dock_right,
|
||||
settings.paint_dock_right,
|
||||
)
|
||||
|
||||
|
||||
func _apply_world_pixelation(pixel_size: int) -> void:
|
||||
|
|
|
|||
|
|
@ -28,6 +28,13 @@ const MAX_RECENT_REQUEST_IDS: int = 64
|
|||
const GRID_PREVIEW_SURFACE_OFFSET: float = 0.03
|
||||
const POINTER_EDGE_MARGIN: float = 2.0
|
||||
|
||||
enum GuideAction {
|
||||
NONE,
|
||||
HIDE,
|
||||
RESTORE,
|
||||
FINALIZE,
|
||||
}
|
||||
|
||||
var _session: NetworkSession
|
||||
var _spawn_service: PlayerSpawnService
|
||||
var _relationships: PlayerRelationshipStore
|
||||
|
|
@ -51,6 +58,10 @@ var _color_ids: Array[StringName] = []
|
|||
var _color_index: int = 0
|
||||
var _painting: bool = false
|
||||
var _erasing: bool = false
|
||||
var _eraser_mode: bool = false
|
||||
var _armed_guide_action: int = GuideAction.NONE
|
||||
var _armed_return_placement_mode: bool = false
|
||||
var _armed_return_eraser_mode: bool = false
|
||||
var _camera_look_active: bool = false
|
||||
var _prior_mouse_mode: Input.MouseMode = Input.MOUSE_MODE_VISIBLE
|
||||
var _last_edited_cell := Vector3i(-1, -1, -1)
|
||||
|
|
@ -127,6 +138,9 @@ func handle_input(event: InputEvent, can_open: bool) -> bool:
|
|||
deactivate()
|
||||
return false
|
||||
if event.is_action_pressed("ui_cancel"):
|
||||
if _armed_guide_action != GuideAction.NONE:
|
||||
_cancel_armed_guide_action()
|
||||
return true
|
||||
if _placing_grid:
|
||||
_set_placement_mode(false)
|
||||
return true
|
||||
|
|
@ -173,7 +187,9 @@ func handle_input(event: InputEvent, can_open: bool) -> bool:
|
|||
MOUSE_BUTTON_LEFT:
|
||||
if _placing_grid:
|
||||
if mouse_event.pressed:
|
||||
if mouse_event.shift_pressed and mouse_event.ctrl_pressed:
|
||||
if _armed_guide_action != GuideAction.NONE:
|
||||
_execute_armed_guide_action()
|
||||
elif mouse_event.shift_pressed and mouse_event.ctrl_pressed:
|
||||
_finalize_selected_guide()
|
||||
elif mouse_event.shift_pressed:
|
||||
_remove_selected_guide()
|
||||
|
|
@ -182,8 +198,11 @@ func handle_input(event: InputEvent, can_open: bool) -> bool:
|
|||
return true
|
||||
if mouse_event.pressed:
|
||||
_begin_stroke()
|
||||
_painting = mouse_event.pressed and not mouse_event.shift_pressed
|
||||
_erasing = mouse_event.pressed and mouse_event.shift_pressed
|
||||
_erasing = (
|
||||
mouse_event.pressed
|
||||
and (mouse_event.shift_pressed or _eraser_mode)
|
||||
)
|
||||
_painting = mouse_event.pressed and not _erasing
|
||||
if _painting or _erasing:
|
||||
_submit_current_brush(_erasing, true)
|
||||
else:
|
||||
|
|
@ -210,6 +229,8 @@ func activate() -> void:
|
|||
return
|
||||
_active = true
|
||||
_placing_grid = true
|
||||
_eraser_mode = false
|
||||
_clear_armed_guide_action(false)
|
||||
_refresh_local_unlocks()
|
||||
_rebuild_placement_preview()
|
||||
_reset_stroke()
|
||||
|
|
@ -228,6 +249,8 @@ func deactivate() -> void:
|
|||
return
|
||||
_active = false
|
||||
_placing_grid = false
|
||||
_eraser_mode = false
|
||||
_clear_armed_guide_action(false)
|
||||
_camera_look_active = false
|
||||
_reset_stroke()
|
||||
_selected_canvas_id = ""
|
||||
|
|
@ -258,12 +281,63 @@ func set_color_id(color_id: StringName) -> bool:
|
|||
var color_index: int = _color_ids.find(color_id)
|
||||
if color_index < 0:
|
||||
return false
|
||||
_clear_armed_guide_action(true)
|
||||
_eraser_mode = false
|
||||
_color_index = color_index
|
||||
_reset_stroke()
|
||||
_emit_hud_state("")
|
||||
return true
|
||||
|
||||
|
||||
func set_eraser_mode(enabled: bool) -> void:
|
||||
if not _active:
|
||||
return
|
||||
_clear_armed_guide_action(true)
|
||||
_eraser_mode = enabled
|
||||
if _eraser_mode and _placing_grid:
|
||||
_placing_grid = false
|
||||
_reset_stroke()
|
||||
_selected_canvas_id = ""
|
||||
_update_aim()
|
||||
_refresh_stencil_visibility()
|
||||
_emit_hud_state("eraser selected" if _eraser_mode else "marker selected")
|
||||
|
||||
|
||||
func is_eraser_mode() -> bool:
|
||||
return _eraser_mode
|
||||
|
||||
|
||||
func arm_guide_action(action: int) -> bool:
|
||||
if (
|
||||
not _active
|
||||
or action not in [GuideAction.HIDE, GuideAction.RESTORE, GuideAction.FINALIZE]
|
||||
):
|
||||
return false
|
||||
if _armed_guide_action == action:
|
||||
_cancel_armed_guide_action()
|
||||
return false
|
||||
if _armed_guide_action == GuideAction.NONE:
|
||||
_armed_return_placement_mode = _placing_grid
|
||||
_armed_return_eraser_mode = _eraser_mode
|
||||
_armed_guide_action = action
|
||||
_placing_grid = true
|
||||
_eraser_mode = false
|
||||
_reset_stroke()
|
||||
_selected_canvas_id = ""
|
||||
_update_aim()
|
||||
_refresh_stencil_visibility()
|
||||
_emit_hud_state("click a grid to %s it" % _guide_action_verb(action))
|
||||
return true
|
||||
|
||||
|
||||
func get_armed_guide_action() -> int:
|
||||
return _armed_guide_action
|
||||
|
||||
|
||||
func cancel_armed_guide_action() -> void:
|
||||
_cancel_armed_guide_action()
|
||||
|
||||
|
||||
func set_brush_size(value: int) -> bool:
|
||||
if _art_unlocks == null or not _art_unlocks.is_brush_size_unlocked(value):
|
||||
return false
|
||||
|
|
@ -1751,7 +1825,11 @@ func _rebuild_placement_preview() -> void:
|
|||
|
||||
|
||||
func _set_placement_mode(enabled: bool) -> void:
|
||||
if not _active or _placing_grid == enabled:
|
||||
if not _active:
|
||||
return
|
||||
_clear_armed_guide_action(true)
|
||||
if _placing_grid == enabled:
|
||||
_emit_hud_state("")
|
||||
return
|
||||
_placing_grid = enabled
|
||||
_reset_stroke()
|
||||
|
|
@ -1767,6 +1845,51 @@ func _set_placement_mode(enabled: bool) -> void:
|
|||
)
|
||||
|
||||
|
||||
func _execute_armed_guide_action() -> void:
|
||||
var action: int = _armed_guide_action
|
||||
match action:
|
||||
GuideAction.HIDE:
|
||||
_remove_selected_guide()
|
||||
GuideAction.RESTORE:
|
||||
_restore_selected_guide()
|
||||
GuideAction.FINALIZE:
|
||||
_finalize_selected_guide()
|
||||
_clear_armed_guide_action(true)
|
||||
_emit_hud_state("")
|
||||
|
||||
|
||||
func _cancel_armed_guide_action() -> void:
|
||||
if _armed_guide_action == GuideAction.NONE:
|
||||
return
|
||||
_clear_armed_guide_action(true)
|
||||
_emit_hud_state("")
|
||||
|
||||
|
||||
func _clear_armed_guide_action(restore_tool: bool) -> void:
|
||||
if _armed_guide_action == GuideAction.NONE:
|
||||
return
|
||||
_armed_guide_action = GuideAction.NONE
|
||||
if restore_tool:
|
||||
_placing_grid = _armed_return_placement_mode
|
||||
_eraser_mode = _armed_return_eraser_mode
|
||||
_armed_return_placement_mode = false
|
||||
_armed_return_eraser_mode = false
|
||||
_reset_stroke()
|
||||
_update_aim()
|
||||
_refresh_stencil_visibility()
|
||||
|
||||
|
||||
func _guide_action_verb(action: int) -> String:
|
||||
match action:
|
||||
GuideAction.HIDE:
|
||||
return "hide"
|
||||
GuideAction.RESTORE:
|
||||
return "restore"
|
||||
GuideAction.FINALIZE:
|
||||
return "finish"
|
||||
return "use"
|
||||
|
||||
|
||||
func _remove_selected_guide() -> void:
|
||||
if _selected_canvas_id.is_empty():
|
||||
_emit_hud_state("aim at a placed grid before removing its guide")
|
||||
|
|
@ -1782,6 +1905,21 @@ func _remove_selected_guide() -> void:
|
|||
_emit_hud_state("hiding grid guide...")
|
||||
|
||||
|
||||
func _restore_selected_guide() -> void:
|
||||
if _selected_canvas_id.is_empty():
|
||||
_emit_hud_state("aim at a hidden grid before restoring its guide")
|
||||
return
|
||||
var state: Dictionary = _canvas_states.get(_selected_canvas_id, {})
|
||||
if state.is_empty() or bool(state.get("finalized", false)):
|
||||
return
|
||||
if bool(state.get("guide_visible", true)):
|
||||
_emit_hud_state("this grid guide is already visible")
|
||||
return
|
||||
if request_guide_visibility(_selected_canvas_id, true):
|
||||
if not _session.is_host():
|
||||
_emit_hud_state("restoring grid guide...")
|
||||
|
||||
|
||||
func _finalize_selected_guide() -> void:
|
||||
if _selected_canvas_id.is_empty():
|
||||
_emit_hud_state("aim at an active grid before finishing it")
|
||||
|
|
@ -1805,6 +1943,8 @@ func _clamped_pointer_position(value: Vector2) -> Vector2:
|
|||
func _cycle_color(direction: int) -> void:
|
||||
if _color_ids.is_empty():
|
||||
return
|
||||
_clear_armed_guide_action(true)
|
||||
_eraser_mode = false
|
||||
_color_index = posmod(_color_index + direction, _color_ids.size())
|
||||
_reset_stroke()
|
||||
_emit_hud_state("")
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ const UI_COMPACT_RENDER_HEIGHTS: Array[int] = [0, 408, 336, 264, 192]
|
|||
@export var invert_camera_y: bool = false
|
||||
@export var chat_draft: String = ""
|
||||
@export var chat_collapsed: bool = false
|
||||
@export var chat_dock_right: bool = false
|
||||
@export var paint_dock_right: bool = true
|
||||
@export_range(1, 5, 1) var world_pixel_size: int = DEFAULT_WORLD_PIXEL_SIZE
|
||||
@export_range(1, 5, 1) var ui_pixel_size: int = DEFAULT_UI_PIXEL_SIZE
|
||||
|
||||
|
|
@ -62,6 +64,8 @@ func copy() -> PlayerSettings:
|
|||
result.invert_camera_y = invert_camera_y
|
||||
result.chat_draft = chat_draft
|
||||
result.chat_collapsed = chat_collapsed
|
||||
result.chat_dock_right = chat_dock_right
|
||||
result.paint_dock_right = paint_dock_right
|
||||
result.world_pixel_size = world_pixel_size
|
||||
result.ui_pixel_size = ui_pixel_size
|
||||
return result
|
||||
|
|
|
|||
|
|
@ -57,6 +57,14 @@ func load_settings() -> bool:
|
|||
presentation.has("chat_collapsed")
|
||||
and typeof(presentation["chat_collapsed"]) != TYPE_BOOL
|
||||
)
|
||||
or (
|
||||
presentation.has("chat_dock_right")
|
||||
and typeof(presentation["chat_dock_right"]) != TYPE_BOOL
|
||||
)
|
||||
or (
|
||||
presentation.has("paint_dock_right")
|
||||
and typeof(presentation["paint_dock_right"]) != TYPE_BOOL
|
||||
)
|
||||
):
|
||||
return _use_defaults_after_corruption("Player settings values are invalid.")
|
||||
var loaded := PlayerSettings.new()
|
||||
|
|
@ -98,6 +106,8 @@ func load_settings() -> bool:
|
|||
PlayerSettings.MAX_CHAT_DRAFT_CHARACTERS
|
||||
)
|
||||
loaded.chat_collapsed = bool(presentation.get("chat_collapsed", false))
|
||||
loaded.chat_dock_right = bool(presentation.get("chat_dock_right", false))
|
||||
loaded.paint_dock_right = bool(presentation.get("paint_dock_right", true))
|
||||
if not loaded.is_valid():
|
||||
return _use_defaults_after_corruption("Player settings values are invalid.")
|
||||
current_settings = loaded
|
||||
|
|
@ -170,6 +180,8 @@ func save_now() -> bool:
|
|||
"ui_pixel_size": current_settings.ui_pixel_size,
|
||||
"chat_draft": current_settings.chat_draft,
|
||||
"chat_collapsed": current_settings.chat_collapsed,
|
||||
"chat_dock_right": current_settings.chat_dock_right,
|
||||
"paint_dock_right": current_settings.paint_dock_right,
|
||||
},
|
||||
}
|
||||
if current_settings.chat_draft.is_empty():
|
||||
|
|
|
|||
|
|
@ -34,7 +34,50 @@ func _run() -> void:
|
|||
var toolbar := game_ui.get_node(
|
||||
"%SurfaceDrawingToolbar"
|
||||
) as SurfaceDrawingToolbar
|
||||
var chat_ui := game_ui.get_node("%ChatUI") as ChatUI
|
||||
assert(player != null and service != null and toolbar != null)
|
||||
assert(chat_ui != null)
|
||||
var settings_panel := game_ui.get(
|
||||
"_pause_settings_panel"
|
||||
) as SettingsPanel
|
||||
var chat_dock_button := settings_panel.get_node("%ChatDock") as BubbleButton
|
||||
var paint_dock_button := settings_panel.get_node("%PaintDock") as BubbleButton
|
||||
assert(chat_dock_button.neutral_size.x == chat_dock_button.neutral_size.y)
|
||||
assert(paint_dock_button.neutral_size.x == paint_dock_button.neutral_size.y)
|
||||
assert(
|
||||
chat_dock_button.compact_minimum_size.x
|
||||
== chat_dock_button.compact_minimum_size.y
|
||||
)
|
||||
assert(
|
||||
paint_dock_button.compact_minimum_size.x
|
||||
== paint_dock_button.compact_minimum_size.y
|
||||
)
|
||||
assert(not chat_ui.is_docked_right())
|
||||
assert(toolbar.is_docked_right())
|
||||
var settings_manager := main.get_node(
|
||||
"%PlayerSettingsManager"
|
||||
) as PlayerSettingsManager
|
||||
assert(settings_manager != null)
|
||||
var changed_docks: PlayerSettings = settings_manager.current_settings.copy()
|
||||
changed_docks.chat_dock_right = true
|
||||
changed_docks.paint_dock_right = false
|
||||
assert(settings_manager.apply_settings(changed_docks))
|
||||
await process_frame
|
||||
assert(chat_ui.is_docked_right())
|
||||
assert(not toolbar.is_docked_right())
|
||||
var reloaded_settings := PlayerSettingsManager.new()
|
||||
root.add_child(reloaded_settings)
|
||||
assert(reloaded_settings.load_settings())
|
||||
assert(reloaded_settings.current_settings.chat_dock_right)
|
||||
assert(not reloaded_settings.current_settings.paint_dock_right)
|
||||
reloaded_settings.queue_free()
|
||||
var default_docks: PlayerSettings = settings_manager.current_settings.copy()
|
||||
default_docks.chat_dock_right = false
|
||||
default_docks.paint_dock_right = true
|
||||
assert(settings_manager.apply_settings(default_docks))
|
||||
await process_frame
|
||||
assert(not chat_ui.is_docked_right())
|
||||
assert(toolbar.is_docked_right())
|
||||
assert(not service.can_activate())
|
||||
assert(not service.is_active() and not toolbar.visible)
|
||||
assert(player.bag.add_item(ArtShopStock.ART_KIT_ITEM_ID, 1))
|
||||
|
|
@ -47,12 +90,53 @@ func _run() -> void:
|
|||
await process_frame
|
||||
assert(service.is_active() and service.is_placement_mode())
|
||||
assert(toolbar.visible)
|
||||
assert(toolbar.position.is_equal_approx(Vector2(18.0, 18.0)))
|
||||
var ui_root := game_ui.get_node("%UIRoot") as Control
|
||||
assert(toolbar.get_parent() == ui_root)
|
||||
assert(is_zero_approx(toolbar.position.y))
|
||||
assert(
|
||||
is_equal_approx(
|
||||
toolbar.get_global_rect().end.x,
|
||||
ui_root.get_global_rect().end.x,
|
||||
)
|
||||
)
|
||||
assert(toolbar.get_global_rect().end.x <= 1280.0)
|
||||
assert(toolbar.get_global_rect().end.y <= 720.0)
|
||||
var top_panel := toolbar.get_node("%TopPanel") as PanelContainer
|
||||
var color_panel := toolbar.get_node("%ColorPanel") as PanelContainer
|
||||
assert(top_panel.position.is_equal_approx(Vector2.ZERO))
|
||||
assert(color_panel.position.x > 0.0)
|
||||
assert(is_equal_approx(color_panel.get_rect().end.x, top_panel.get_rect().end.x))
|
||||
assert(color_panel.position.y < top_panel.get_rect().end.y)
|
||||
assert(color_panel.get_rect().end.y > top_panel.get_rect().end.y)
|
||||
var toolbar_origin: Vector2 = toolbar.get_global_rect().position
|
||||
var top_pointer := InputEventMouseMotion.new()
|
||||
top_pointer.position = toolbar_origin + Vector2(200.0, 24.0)
|
||||
assert(toolbar.owns_pointer_event(top_pointer))
|
||||
var rail_pointer := InputEventMouseMotion.new()
|
||||
rail_pointer.position = color_panel.get_global_rect().get_center()
|
||||
assert(toolbar.owns_pointer_event(rail_pointer))
|
||||
var empty_pointer := InputEventMouseMotion.new()
|
||||
empty_pointer.position = toolbar_origin + Vector2(200.0, 180.0)
|
||||
assert(not toolbar.owns_pointer_event(empty_pointer))
|
||||
|
||||
var brush_option := toolbar.get_node("%BrushOption") as OptionButton
|
||||
var grid_option := toolbar.get_node("%GridOption") as OptionButton
|
||||
var mode_button := toolbar.get_node("%ModeButton") as Button
|
||||
var eraser_button := toolbar.get_node("%EraserButton") as Button
|
||||
var undo_button := toolbar.get_node("%UndoButton") as Button
|
||||
var hide_button := toolbar.get_node("%HideGuideButton") as Button
|
||||
var restore_button := toolbar.get_node("%RestoreGuideButton") as Button
|
||||
var finalize_button := toolbar.get_node("%FinalizeGuideButton") as Button
|
||||
var close_button := toolbar.get_node("%CloseButton") as Button
|
||||
assert(
|
||||
mode_button != null
|
||||
and eraser_button != null
|
||||
and undo_button != null
|
||||
and hide_button != null
|
||||
and restore_button != null
|
||||
and finalize_button != null
|
||||
and close_button != null
|
||||
)
|
||||
assert(brush_option.item_count == 4)
|
||||
assert(grid_option.item_count == 4)
|
||||
assert(not brush_option.get_popup().is_item_disabled(0))
|
||||
|
|
@ -79,6 +163,58 @@ func _run() -> void:
|
|||
assert(service.get_brush_size() == 4)
|
||||
assert(service.get_grid_size() == 128)
|
||||
|
||||
mode_button.pressed.emit()
|
||||
assert(not service.is_placement_mode())
|
||||
eraser_button.pressed.emit()
|
||||
assert(service.is_eraser_mode())
|
||||
assert(eraser_button.button_pressed)
|
||||
hide_button.pressed.emit()
|
||||
assert(service.is_placement_mode())
|
||||
assert(not service.is_eraser_mode())
|
||||
assert(
|
||||
service.get_armed_guide_action()
|
||||
== NetworkSurfaceDrawingService.GuideAction.HIDE
|
||||
)
|
||||
var world_click := InputEventMouseButton.new()
|
||||
world_click.button_index = MOUSE_BUTTON_LEFT
|
||||
world_click.pressed = true
|
||||
assert(service.handle_input(world_click, true))
|
||||
assert(
|
||||
service.get_armed_guide_action()
|
||||
== NetworkSurfaceDrawingService.GuideAction.NONE
|
||||
)
|
||||
assert(not service.is_placement_mode())
|
||||
assert(service.is_eraser_mode())
|
||||
|
||||
restore_button.pressed.emit()
|
||||
assert(
|
||||
service.get_armed_guide_action()
|
||||
== NetworkSurfaceDrawingService.GuideAction.RESTORE
|
||||
)
|
||||
restore_button.pressed.emit()
|
||||
assert(
|
||||
service.get_armed_guide_action()
|
||||
== NetworkSurfaceDrawingService.GuideAction.NONE
|
||||
)
|
||||
assert(not service.is_placement_mode() and service.is_eraser_mode())
|
||||
finalize_button.pressed.emit()
|
||||
assert(
|
||||
service.get_armed_guide_action()
|
||||
== NetworkSurfaceDrawingService.GuideAction.FINALIZE
|
||||
)
|
||||
assert(service.handle_input(world_click, true))
|
||||
assert(not service.is_placement_mode() and service.is_eraser_mode())
|
||||
(color_buttons[&"ocean_teal"] as Button).pressed.emit()
|
||||
assert(not service.is_eraser_mode())
|
||||
undo_button.pressed.emit()
|
||||
assert(service.is_active())
|
||||
close_button.pressed.emit()
|
||||
assert(not service.is_active() and not toolbar.visible)
|
||||
|
||||
assert(service.handle_input(paint_key, true))
|
||||
await process_frame
|
||||
assert(service.is_active() and toolbar.visible)
|
||||
|
||||
assert(service.handle_input(paint_key, true))
|
||||
await process_frame
|
||||
assert(not service.is_active() and not toolbar.visible)
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ var _pending_send_body: String = ""
|
|||
var _prior_movement: bool = true
|
||||
var _prior_camera: bool = true
|
||||
var _output_scale: float = 1.0
|
||||
var _dock_right: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
|
|
@ -85,6 +86,7 @@ func setup(
|
|||
_player = player
|
||||
_fishing_spot = fishing_spot
|
||||
_settings = settings
|
||||
set_dock_right(_settings.current_settings.chat_dock_right)
|
||||
_service.message_received.connect(_on_message)
|
||||
_service.local_message_confirmed.connect(_on_local_message_confirmed)
|
||||
_service.history_replaced.connect(_on_history)
|
||||
|
|
@ -333,10 +335,10 @@ func _build_ui() -> void:
|
|||
|
||||
func _chat_panel_style() -> StyleBoxFlat:
|
||||
var style := _borderless_style(Color(0.025, 0.13, 0.19, 0.94))
|
||||
style.corner_radius_top_left = 0
|
||||
style.corner_radius_bottom_left = 0
|
||||
style.corner_radius_top_right = 10
|
||||
style.corner_radius_bottom_right = 10
|
||||
style.corner_radius_top_left = 10 if _dock_right else 0
|
||||
style.corner_radius_bottom_left = 10 if _dock_right else 0
|
||||
style.corner_radius_top_right = 0 if _dock_right else 10
|
||||
style.corner_radius_bottom_right = 0 if _dock_right else 10
|
||||
style.content_margin_left = 12
|
||||
style.content_margin_right = 12
|
||||
style.content_margin_top = 10
|
||||
|
|
@ -568,10 +570,26 @@ func set_output_scale(output_scale: float) -> void:
|
|||
_output_scale = maxf(output_scale, 0.001)
|
||||
|
||||
|
||||
func set_dock_right(should_dock_right: bool) -> void:
|
||||
_dock_right = should_dock_right
|
||||
if not is_node_ready() or _panel == null:
|
||||
return
|
||||
_panel.add_theme_stylebox_override("panel", _chat_panel_style())
|
||||
_refresh_handle_labels(_presentation_state)
|
||||
_layout_presentation(false)
|
||||
|
||||
|
||||
func is_docked_right() -> bool:
|
||||
return _dock_right
|
||||
|
||||
|
||||
func _refresh_handle_labels(state: PresentationState) -> void:
|
||||
var collapsed := state == PresentationState.COLLAPSED
|
||||
var height_state := _visible_state_before_collapse if collapsed else state
|
||||
_collapse_button.text = ">" if collapsed else "<"
|
||||
if _dock_right:
|
||||
_collapse_button.text = "<" if collapsed else ">"
|
||||
else:
|
||||
_collapse_button.text = ">" if collapsed else "<"
|
||||
_collapse_button.tooltip_text = (
|
||||
"Show chat" if collapsed else "Hide chat"
|
||||
)
|
||||
|
|
@ -687,6 +705,9 @@ func _set_status(text: String) -> void:
|
|||
func _layout_presentation(animate: bool) -> void:
|
||||
if _panel == null:
|
||||
return
|
||||
var viewport_width := size.x
|
||||
if viewport_width <= 0.0:
|
||||
viewport_width = 1280.0
|
||||
var viewport_height := size.y
|
||||
if viewport_height <= 0.0:
|
||||
viewport_height = 720.0
|
||||
|
|
@ -704,32 +725,40 @@ func _layout_presentation(animate: bool) -> void:
|
|||
if layout_state == PresentationState.EXPANDED:
|
||||
height = maxf(MIN_HISTORY_HEIGHT, viewport_height - 2.0 * bottom_margin)
|
||||
height = minf(height, maxf(MIN_HISTORY_HEIGHT, bottom - MIN_TOP_MARGIN))
|
||||
var target_position := Vector2(
|
||||
-(PANEL_WIDTH - COLLAPSED_REVEAL_WIDTH)
|
||||
if _presentation_state == PresentationState.COLLAPSED
|
||||
else 0.0,
|
||||
bottom - height,
|
||||
)
|
||||
var collapsed := _presentation_state == PresentationState.COLLAPSED
|
||||
var panel_x: float
|
||||
if _dock_right:
|
||||
panel_x = (
|
||||
viewport_width - COLLAPSED_REVEAL_WIDTH
|
||||
if collapsed
|
||||
else viewport_width - PANEL_WIDTH
|
||||
)
|
||||
else:
|
||||
panel_x = -(PANEL_WIDTH - COLLAPSED_REVEAL_WIDTH) if collapsed else 0.0
|
||||
var target_position := Vector2(panel_x, bottom - height)
|
||||
var target_size := Vector2(PANEL_WIDTH, height)
|
||||
var handle_stack_height := HANDLE_SIZE.y * 2.0 + HANDLE_GAP
|
||||
var handle_stack_top := (
|
||||
bottom - COMPACT_HEIGHT * 0.5 - handle_stack_height * 0.5
|
||||
)
|
||||
var handle_x: float
|
||||
if _dock_right:
|
||||
handle_x = panel_x - HANDLE_SIZE.x
|
||||
else:
|
||||
handle_x = COLLAPSED_REVEAL_WIDTH if collapsed else PANEL_WIDTH
|
||||
var collapse_position := Vector2(
|
||||
COLLAPSED_REVEAL_WIDTH
|
||||
if _presentation_state == PresentationState.COLLAPSED
|
||||
else PANEL_WIDTH,
|
||||
handle_x,
|
||||
handle_stack_top + HANDLE_SIZE.y + HANDLE_GAP,
|
||||
)
|
||||
var height_position := Vector2(
|
||||
COLLAPSED_REVEAL_WIDTH
|
||||
if _presentation_state == PresentationState.COLLAPSED
|
||||
else PANEL_WIDTH,
|
||||
handle_stack_top,
|
||||
)
|
||||
var unread_position := collapse_position + Vector2(6.0, -18.0)
|
||||
var height_position := Vector2(handle_x, handle_stack_top)
|
||||
var unread_offset_x := -18.0 if _dock_right else 6.0
|
||||
var unread_position := collapse_position + Vector2(unread_offset_x, -18.0)
|
||||
var hint_position := Vector2(
|
||||
HINT_EDGE_MARGIN,
|
||||
(
|
||||
viewport_width - _hint.size.x - HINT_EDGE_MARGIN
|
||||
if _dock_right
|
||||
else HINT_EDGE_MARGIN
|
||||
),
|
||||
viewport_height - _hint.size.y - HINT_EDGE_MARGIN,
|
||||
)
|
||||
if _height_tween != null and _height_tween.is_valid():
|
||||
|
|
|
|||
|
|
@ -219,6 +219,10 @@ func setup(
|
|||
_shop_interaction = shop_interaction
|
||||
_surface_drawing = surface_drawing
|
||||
_surface_drawing_toolbar.setup(_surface_drawing, art_unlocks)
|
||||
set_edge_docks(
|
||||
settings_manager.current_settings.chat_dock_right,
|
||||
settings_manager.current_settings.paint_dock_right,
|
||||
)
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
|
|
@ -409,6 +413,11 @@ func set_effective_ui_pixel_size(pixel_size: int) -> void:
|
|||
_pause_settings_panel.set_effective_ui_pixel_size(pixel_size)
|
||||
|
||||
|
||||
func set_edge_docks(chat_dock_right: bool, paint_dock_right: bool) -> void:
|
||||
_chat_ui.set_dock_right(chat_dock_right)
|
||||
_surface_drawing_toolbar.set_dock_right(paint_dock_right)
|
||||
|
||||
|
||||
func focus_open_settings_back_button() -> void:
|
||||
if _title_settings_panel.visible:
|
||||
_title_settings_panel.focus_back_button()
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ mouse_filter = 2
|
|||
unique_name_in_owner = true
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="SurfaceDrawingToolbar" parent="UIRoot/CanonicalStage" instance=ExtResource("11_drawing_toolbar")]
|
||||
[node name="SurfaceDrawingToolbar" parent="UIRoot" instance=ExtResource("11_drawing_toolbar")]
|
||||
unique_name_in_owner = true
|
||||
|
||||
[node name="GameplayTransientHUD" type="Control" parent="UIRoot/CanonicalStage"]
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ enum PresentationMode {
|
|||
|
||||
@onready var _world_value: BubbleButton = %WorldValue
|
||||
@onready var _ui_value: BubbleButton = %UIValue
|
||||
@onready var _chat_dock: BubbleButton = %ChatDock
|
||||
@onready var _paint_dock: BubbleButton = %PaintDock
|
||||
@onready var _mouse_value: BubbleButton = %MouseValue
|
||||
@onready var _controller_value: BubbleButton = %ControllerValue
|
||||
@onready var _invert_y_toggle: BubbleButton = %InvertYToggle
|
||||
|
|
@ -133,6 +135,8 @@ func _ready() -> void:
|
|||
_ui_options[index].pressed.connect(
|
||||
_set_ui_pixelation.bind(index + 1)
|
||||
)
|
||||
_chat_dock.pressed.connect(_toggle_chat_dock)
|
||||
_paint_dock.pressed.connect(_toggle_paint_dock)
|
||||
%MouseDecrease.pressed.connect(_adjust_mouse_sensitivity.bind(-1))
|
||||
%MouseIncrease.pressed.connect(_adjust_mouse_sensitivity.bind(1))
|
||||
_mouse_value.pressed.connect(_adjust_mouse_sensitivity.bind(1))
|
||||
|
|
@ -642,14 +646,12 @@ func _apply_settings() -> void:
|
|||
if _settings_manager == null:
|
||||
_feedback.text = "settings are unavailable."
|
||||
return
|
||||
var edited := PlayerSettings.new()
|
||||
var edited: PlayerSettings = _settings_manager.current_settings.copy()
|
||||
edited.auto_click_enabled = _auto_click_enabled
|
||||
edited.auto_click_interval = _auto_click_interval_value
|
||||
edited.mouse_camera_sensitivity = _mouse_sensitivity
|
||||
edited.controller_camera_sensitivity = _controller_sensitivity
|
||||
edited.invert_camera_y = _invert_camera_y
|
||||
edited.world_pixel_size = _settings_manager.current_settings.world_pixel_size
|
||||
edited.ui_pixel_size = _settings_manager.current_settings.ui_pixel_size
|
||||
if _settings_manager.apply_settings(edited):
|
||||
if (
|
||||
_presentation_mode == PresentationMode.TITLE_EMBEDDED
|
||||
|
|
@ -686,6 +688,10 @@ func _refresh_value_labels() -> void:
|
|||
"ui\npixelation\n"
|
||||
+ _pixel_size_label(settings.ui_pixel_size)
|
||||
)
|
||||
_chat_dock.text = "chat dock\n" + ("right" if settings.chat_dock_right else "left")
|
||||
_paint_dock.text = (
|
||||
"paint dock\n" + ("right" if settings.paint_dock_right else "left")
|
||||
)
|
||||
_mouse_value.text = "mouse\nsensitivity\n%.4f" % _mouse_sensitivity
|
||||
_controller_value.text = (
|
||||
"controller\nsensitivity\n%.1f" % _controller_sensitivity
|
||||
|
|
@ -757,6 +763,28 @@ func _set_ui_pixelation(pixel_size: int) -> void:
|
|||
_refresh_value_labels()
|
||||
|
||||
|
||||
func _toggle_chat_dock() -> void:
|
||||
if _settings_manager == null:
|
||||
return
|
||||
var edited: PlayerSettings = _settings_manager.current_settings.copy()
|
||||
edited.chat_dock_right = not edited.chat_dock_right
|
||||
if not _settings_manager.apply_settings(edited):
|
||||
_feedback.text = "failed to save chat dock setting."
|
||||
return
|
||||
_refresh_value_labels()
|
||||
|
||||
|
||||
func _toggle_paint_dock() -> void:
|
||||
if _settings_manager == null:
|
||||
return
|
||||
var edited: PlayerSettings = _settings_manager.current_settings.copy()
|
||||
edited.paint_dock_right = not edited.paint_dock_right
|
||||
if not _settings_manager.apply_settings(edited):
|
||||
_feedback.text = "failed to save paint dock setting."
|
||||
return
|
||||
_refresh_value_labels()
|
||||
|
||||
|
||||
func _adjust_mouse_sensitivity(direction: int) -> void:
|
||||
_mouse_sensitivity = clampf(
|
||||
_mouse_sensitivity + float(direction) * 0.0005,
|
||||
|
|
|
|||
|
|
@ -157,8 +157,8 @@ grow_horizontal = 2
|
|||
grow_vertical = 2
|
||||
script = ExtResource("3_page")
|
||||
page_id = &"display"
|
||||
bubble_paths = Array[NodePath]([NodePath("BubbleCluster/WorldValue"), NodePath("BubbleCluster/WorldLegible"), NodePath("BubbleCluster/WorldCute"), NodePath("BubbleCluster/WorldRetro"), NodePath("BubbleCluster/WorldHardcore"), NodePath("BubbleCluster/WorldWtf"), NodePath("BubbleCluster/UIValue"), NodePath("BubbleCluster/UILegible"), NodePath("BubbleCluster/UICute"), NodePath("BubbleCluster/UIRetro"), NodePath("BubbleCluster/UIHardcore"), NodePath("BubbleCluster/UIWtf"), NodePath("BubbleCluster/DisplayBackButton")])
|
||||
focus_paths = Array[NodePath]([NodePath("BubbleCluster/WorldLegible"), NodePath("BubbleCluster/WorldCute"), NodePath("BubbleCluster/WorldRetro"), NodePath("BubbleCluster/WorldHardcore"), NodePath("BubbleCluster/WorldWtf"), NodePath("BubbleCluster/UILegible"), NodePath("BubbleCluster/UICute"), NodePath("BubbleCluster/UIRetro"), NodePath("BubbleCluster/UIHardcore"), NodePath("BubbleCluster/UIWtf"), NodePath("BubbleCluster/DisplayBackButton")])
|
||||
bubble_paths = Array[NodePath]([NodePath("BubbleCluster/WorldValue"), NodePath("BubbleCluster/WorldLegible"), NodePath("BubbleCluster/WorldCute"), NodePath("BubbleCluster/WorldRetro"), NodePath("BubbleCluster/WorldHardcore"), NodePath("BubbleCluster/WorldWtf"), NodePath("BubbleCluster/UIValue"), NodePath("BubbleCluster/UILegible"), NodePath("BubbleCluster/UICute"), NodePath("BubbleCluster/UIRetro"), NodePath("BubbleCluster/UIHardcore"), NodePath("BubbleCluster/UIWtf"), NodePath("BubbleCluster/ChatDock"), NodePath("BubbleCluster/PaintDock"), NodePath("BubbleCluster/DisplayBackButton")])
|
||||
focus_paths = Array[NodePath]([NodePath("BubbleCluster/WorldLegible"), NodePath("BubbleCluster/WorldCute"), NodePath("BubbleCluster/WorldRetro"), NodePath("BubbleCluster/WorldHardcore"), NodePath("BubbleCluster/WorldWtf"), NodePath("BubbleCluster/UILegible"), NodePath("BubbleCluster/UICute"), NodePath("BubbleCluster/UIRetro"), NodePath("BubbleCluster/UIHardcore"), NodePath("BubbleCluster/UIWtf"), NodePath("BubbleCluster/ChatDock"), NodePath("BubbleCluster/PaintDock"), NodePath("BubbleCluster/DisplayBackButton")])
|
||||
initial_focus_path = NodePath("BubbleCluster/WorldRetro")
|
||||
back_focus_path = NodePath("BubbleCluster/DisplayBackButton")
|
||||
compact_maximum_layout_size = Vector2(544, 400)
|
||||
|
|
@ -178,12 +178,12 @@ custom_minimum_size = Vector2(0, 0)
|
|||
mouse_filter = 2
|
||||
focus_mode = 0
|
||||
text = "world\npixelation\nretro"
|
||||
neutral_size = Vector2(160, 150)
|
||||
neutral_size = Vector2(140, 130)
|
||||
desktop_anchor = Vector2(160, 240)
|
||||
compact_anchor = Vector2(175, 210)
|
||||
compact_minimum_size = Vector2(132, 126)
|
||||
compact_minimum_size = Vector2(118, 110)
|
||||
minimum_font_size = 15
|
||||
maximum_font_size = 25
|
||||
maximum_font_size = 22
|
||||
motion_phase = 0.2
|
||||
|
||||
[node name="WorldLegible" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
|
|
@ -258,12 +258,12 @@ custom_minimum_size = Vector2(0, 0)
|
|||
mouse_filter = 2
|
||||
focus_mode = 0
|
||||
text = "ui\npixelation\nretro"
|
||||
neutral_size = Vector2(160, 150)
|
||||
neutral_size = Vector2(140, 130)
|
||||
desktop_anchor = Vector2(560, 240)
|
||||
compact_anchor = Vector2(545, 210)
|
||||
compact_minimum_size = Vector2(132, 126)
|
||||
compact_minimum_size = Vector2(118, 110)
|
||||
minimum_font_size = 15
|
||||
maximum_font_size = 25
|
||||
maximum_font_size = 22
|
||||
motion_phase = 3.55
|
||||
|
||||
[node name="UILegible" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
|
|
@ -332,6 +332,30 @@ minimum_font_size = 12
|
|||
maximum_font_size = 13
|
||||
motion_phase = 0.55
|
||||
|
||||
[node name="ChatDock" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
text = "chat dock\nleft"
|
||||
neutral_size = Vector2(96, 96)
|
||||
desktop_anchor = Vector2(190, 435)
|
||||
compact_anchor = Vector2(160, 378)
|
||||
compact_minimum_size = Vector2(82, 82)
|
||||
minimum_font_size = 12
|
||||
maximum_font_size = 16
|
||||
motion_phase = 1.1
|
||||
|
||||
[node name="PaintDock" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
text = "paint dock\nright"
|
||||
neutral_size = Vector2(96, 96)
|
||||
desktop_anchor = Vector2(530, 435)
|
||||
compact_anchor = Vector2(448, 378)
|
||||
compact_minimum_size = Vector2(82, 82)
|
||||
minimum_font_size = 12
|
||||
maximum_font_size = 16
|
||||
motion_phase = 1.65
|
||||
|
||||
[node name="DisplayBackButton" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
|
|
@ -342,7 +366,7 @@ compact_anchor = Vector2(315, 390)
|
|||
compact_minimum_size = Vector2(82, 78)
|
||||
minimum_font_size = 13
|
||||
maximum_font_size = 16
|
||||
motion_phase = 1.1
|
||||
motion_phase = 2.2
|
||||
|
||||
[node name="ControlsPage" type="Control" parent="."]
|
||||
unique_name_in_owner = true
|
||||
|
|
|
|||
|
|
@ -1,48 +1,94 @@
|
|||
class_name SurfaceDrawingToolbar
|
||||
extends PanelContainer
|
||||
extends Control
|
||||
|
||||
const UtilityPageStyleType = preload("res://ui/utility_page_style.gd")
|
||||
const TOOLBAR_WIDTH: float = 580.0
|
||||
const TOOLBAR_HEIGHT: float = 373.0
|
||||
const COLOR_RAIL_WIDTH: float = 46.0
|
||||
|
||||
@onready var _mode_button: Button = %ModeButton
|
||||
@onready var _brush_option: OptionButton = %BrushOption
|
||||
@onready var _grid_option: OptionButton = %GridOption
|
||||
@onready var _color_list: VBoxContainer = %ColorList
|
||||
@onready var _top_panel: PanelContainer = %TopPanel
|
||||
@onready var _color_panel: PanelContainer = %ColorPanel
|
||||
@onready var _eraser_button: Button = %EraserButton
|
||||
@onready var _undo_button: Button = %UndoButton
|
||||
@onready var _hide_guide_button: Button = %HideGuideButton
|
||||
@onready var _restore_guide_button: Button = %RestoreGuideButton
|
||||
@onready var _finalize_guide_button: Button = %FinalizeGuideButton
|
||||
@onready var _close_button: Button = %CloseButton
|
||||
|
||||
var _service: NetworkSurfaceDrawingService
|
||||
var _unlocks: PlayerArtUnlocks
|
||||
var _color_buttons: Dictionary[StringName, Button] = {}
|
||||
var _dock_right: bool = true
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
UtilityPageStyleType.apply_page(self)
|
||||
var panel: StyleBoxFlat = UtilityPageStyleType.panel_style()
|
||||
panel.content_margin_left = 10.0
|
||||
panel.content_margin_top = 10.0
|
||||
panel.content_margin_right = 10.0
|
||||
panel.content_margin_bottom = 10.0
|
||||
add_theme_stylebox_override("panel", panel)
|
||||
_apply_toolbar_panel(_top_panel)
|
||||
_apply_toolbar_panel(_color_panel)
|
||||
UtilityPageStyleType.apply_ocean_button(_mode_button)
|
||||
UtilityPageStyleType.apply_ocean_button(_brush_option)
|
||||
UtilityPageStyleType.apply_ocean_button(_grid_option)
|
||||
for button: Button in _action_buttons():
|
||||
UtilityPageStyleType.apply_ocean_button(button)
|
||||
button.custom_minimum_size = Vector2(48, 44)
|
||||
_make_button_round(button, 22)
|
||||
_mode_button.custom_minimum_size = Vector2(48, 48)
|
||||
_make_mode_button_round()
|
||||
_make_button_round(_mode_button, 24)
|
||||
_mode_button.pressed.connect(_toggle_mode)
|
||||
_eraser_button.pressed.connect(_toggle_eraser)
|
||||
_undo_button.pressed.connect(_undo_last_stroke)
|
||||
_hide_guide_button.pressed.connect(
|
||||
_arm_guide_action.bind(NetworkSurfaceDrawingService.GuideAction.HIDE)
|
||||
)
|
||||
_restore_guide_button.pressed.connect(
|
||||
_arm_guide_action.bind(NetworkSurfaceDrawingService.GuideAction.RESTORE)
|
||||
)
|
||||
_finalize_guide_button.pressed.connect(
|
||||
_arm_guide_action.bind(NetworkSurfaceDrawingService.GuideAction.FINALIZE)
|
||||
)
|
||||
_close_button.pressed.connect(_close_toolbar)
|
||||
_brush_option.item_selected.connect(_select_brush)
|
||||
_grid_option.item_selected.connect(_select_grid)
|
||||
_build_options()
|
||||
_apply_dock_side()
|
||||
hide()
|
||||
|
||||
|
||||
func _make_mode_button_round() -> void:
|
||||
func _apply_toolbar_panel(panel: PanelContainer) -> void:
|
||||
var style: StyleBoxFlat = UtilityPageStyleType.panel_style()
|
||||
style.content_margin_left = 6.0
|
||||
style.content_margin_top = 6.0
|
||||
style.content_margin_right = 6.0
|
||||
style.content_margin_bottom = 6.0
|
||||
style.set_corner_radius_all(10)
|
||||
panel.add_theme_stylebox_override("panel", style)
|
||||
|
||||
|
||||
func _action_buttons() -> Array[Button]:
|
||||
return [
|
||||
_eraser_button,
|
||||
_undo_button,
|
||||
_hide_guide_button,
|
||||
_restore_guide_button,
|
||||
_finalize_guide_button,
|
||||
_close_button,
|
||||
]
|
||||
|
||||
|
||||
func _make_button_round(button: Button, radius: int) -> void:
|
||||
for style_name: StringName in [
|
||||
&"normal", &"hover", &"pressed", &"focus", &"disabled",
|
||||
]:
|
||||
var existing: StyleBox = _mode_button.get_theme_stylebox(style_name)
|
||||
var existing: StyleBox = button.get_theme_stylebox(style_name)
|
||||
var style := existing.duplicate() as StyleBoxFlat
|
||||
if style == null:
|
||||
continue
|
||||
style.set_corner_radius_all(24)
|
||||
_mode_button.add_theme_stylebox_override(style_name, style)
|
||||
style.set_corner_radius_all(radius)
|
||||
button.add_theme_stylebox_override(style_name, style)
|
||||
|
||||
|
||||
func setup(
|
||||
|
|
@ -62,13 +108,42 @@ func setup(
|
|||
_refresh_unlocks()
|
||||
|
||||
|
||||
func set_dock_right(should_dock_right: bool) -> void:
|
||||
_dock_right = should_dock_right
|
||||
if is_node_ready():
|
||||
_apply_dock_side()
|
||||
|
||||
|
||||
func is_docked_right() -> bool:
|
||||
return _dock_right
|
||||
|
||||
|
||||
func _apply_dock_side() -> void:
|
||||
anchor_left = 1.0 if _dock_right else 0.0
|
||||
anchor_right = anchor_left
|
||||
offset_left = -TOOLBAR_WIDTH if _dock_right else 0.0
|
||||
offset_right = 0.0 if _dock_right else TOOLBAR_WIDTH
|
||||
offset_top = 0.0
|
||||
offset_bottom = TOOLBAR_HEIGHT
|
||||
_color_panel.offset_left = (
|
||||
TOOLBAR_WIDTH - COLOR_RAIL_WIDTH if _dock_right else 0.0
|
||||
)
|
||||
_color_panel.offset_right = (
|
||||
TOOLBAR_WIDTH if _dock_right else COLOR_RAIL_WIDTH
|
||||
)
|
||||
|
||||
|
||||
func owns_pointer_event(event: InputEvent) -> bool:
|
||||
if not visible:
|
||||
return false
|
||||
if _brush_option.get_popup().visible or _grid_option.get_popup().visible:
|
||||
return true
|
||||
if event is InputEventMouse:
|
||||
return get_global_rect().has_point((event as InputEventMouse).position)
|
||||
var pointer_position: Vector2 = (event as InputEventMouse).position
|
||||
return (
|
||||
_top_panel.get_global_rect().has_point(pointer_position)
|
||||
or _color_panel.get_global_rect().has_point(pointer_position)
|
||||
)
|
||||
return false
|
||||
|
||||
|
||||
|
|
@ -114,7 +189,11 @@ func _refresh_unlocks() -> void:
|
|||
_apply_color_button_style(
|
||||
button,
|
||||
color_id,
|
||||
_service != null and _service.get_color_id() == color_id,
|
||||
(
|
||||
_service != null
|
||||
and not _service.is_eraser_mode()
|
||||
and _service.get_color_id() == color_id
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -161,6 +240,26 @@ func _select_color(color_id: StringName) -> void:
|
|||
_service.set_color_id(color_id)
|
||||
|
||||
|
||||
func _toggle_eraser() -> void:
|
||||
if _service != null:
|
||||
_service.set_eraser_mode(not _service.is_eraser_mode())
|
||||
|
||||
|
||||
func _undo_last_stroke() -> void:
|
||||
if _service != null:
|
||||
_service.request_undo_last_stroke()
|
||||
|
||||
|
||||
func _arm_guide_action(action: int) -> void:
|
||||
if _service != null:
|
||||
_service.arm_guide_action(action)
|
||||
|
||||
|
||||
func _close_toolbar() -> void:
|
||||
if _service != null:
|
||||
_service.deactivate()
|
||||
|
||||
|
||||
func _on_unlocks_changed(_unlock_mask: int) -> void:
|
||||
_refresh_unlocks()
|
||||
|
||||
|
|
@ -185,9 +284,26 @@ func _on_service_state_changed(
|
|||
)
|
||||
_select_option_by_id(_brush_option, brush_size)
|
||||
_select_option_by_id(_grid_option, grid_size)
|
||||
_refresh_action_state()
|
||||
_refresh_unlocks()
|
||||
|
||||
|
||||
func _refresh_action_state() -> void:
|
||||
if _service == null:
|
||||
return
|
||||
_eraser_button.button_pressed = _service.is_eraser_mode()
|
||||
var guide_action: int = _service.get_armed_guide_action()
|
||||
_hide_guide_button.button_pressed = (
|
||||
guide_action == NetworkSurfaceDrawingService.GuideAction.HIDE
|
||||
)
|
||||
_restore_guide_button.button_pressed = (
|
||||
guide_action == NetworkSurfaceDrawingService.GuideAction.RESTORE
|
||||
)
|
||||
_finalize_guide_button.button_pressed = (
|
||||
guide_action == NetworkSurfaceDrawingService.GuideAction.FINALIZE
|
||||
)
|
||||
|
||||
|
||||
func _select_option_by_id(option: OptionButton, item_id: int) -> void:
|
||||
for index: int in range(option.item_count):
|
||||
if option.get_item_id(index) == item_id:
|
||||
|
|
|
|||
|
|
@ -3,55 +3,97 @@
|
|||
[ext_resource type="Script" path="res://ui/surface_drawing_toolbar.gd" id="1_script"]
|
||||
[ext_resource type="Theme" path="res://ui/game_theme.tres" id="2_theme"]
|
||||
|
||||
[node name="SurfaceDrawingToolbar" type="PanelContainer"]
|
||||
[node name="SurfaceDrawingToolbar" type="Control"]
|
||||
visible = false
|
||||
z_index = 85
|
||||
layout_mode = 0
|
||||
offset_left = 18.0
|
||||
offset_top = 18.0
|
||||
offset_right = 284.0
|
||||
offset_bottom = 340.0
|
||||
mouse_filter = 0
|
||||
anchors_preset = 1
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
offset_left = -580.0
|
||||
offset_bottom = 373.0
|
||||
grow_horizontal = 0
|
||||
mouse_filter = 2
|
||||
theme = ExtResource("2_theme")
|
||||
script = ExtResource("1_script")
|
||||
|
||||
[node name="Layout" type="HBoxContainer" parent="."]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 10
|
||||
|
||||
[node name="ColorList" type="VBoxContainer" parent="Layout"]
|
||||
[node name="TopPanel" type="PanelContainer" parent="."]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_right = 580.0
|
||||
offset_bottom = 60.0
|
||||
|
||||
[node name="Top" type="HBoxContainer" parent="TopPanel"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 5
|
||||
|
||||
[node name="Tools" type="VBoxContainer" parent="Layout"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/separation = 8
|
||||
|
||||
[node name="Top" type="HBoxContainer" parent="Layout/Tools"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 6
|
||||
|
||||
[node name="ModeButton" type="Button" parent="Layout/Tools/Top"]
|
||||
[node name="ModeButton" type="Button" parent="TopPanel/Top"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
tooltip_text = "switch between grid and marker mode"
|
||||
text = "▦"
|
||||
|
||||
[node name="BrushOption" type="OptionButton" parent="Layout/Tools/Top"]
|
||||
[node name="BrushOption" type="OptionButton" parent="TopPanel/Top"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(80, 48)
|
||||
layout_mode = 2
|
||||
tooltip_text = "brush size"
|
||||
|
||||
[node name="GridOption" type="OptionButton" parent="Layout/Tools/Top"]
|
||||
[node name="GridOption" type="OptionButton" parent="TopPanel/Top"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(92, 48)
|
||||
layout_mode = 2
|
||||
tooltip_text = "grid size"
|
||||
|
||||
[node name="Help" type="Label" parent="Layout/Tools"]
|
||||
[node name="EraserButton" type="Button" parent="TopPanel/Top"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "click place/draw\nshift click hide/erase\nctrl z undo\nshift scroll zoom"
|
||||
theme_override_colors/font_color = Color(0.623529, 0.811765, 0.823529, 1)
|
||||
theme_override_font_sizes/font_size = 14
|
||||
tooltip_text = "toggle eraser"
|
||||
toggle_mode = true
|
||||
text = "⌫"
|
||||
|
||||
[node name="UndoButton" type="Button" parent="TopPanel/Top"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
tooltip_text = "undo last stroke"
|
||||
text = "↶"
|
||||
|
||||
[node name="HideGuideButton" type="Button" parent="TopPanel/Top"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
tooltip_text = "hide grid on next click"
|
||||
toggle_mode = true
|
||||
text = "◌"
|
||||
|
||||
[node name="RestoreGuideButton" type="Button" parent="TopPanel/Top"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
tooltip_text = "restore hidden grid on next click"
|
||||
toggle_mode = true
|
||||
text = "▤"
|
||||
|
||||
[node name="FinalizeGuideButton" type="Button" parent="TopPanel/Top"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
tooltip_text = "finish grid on next click"
|
||||
toggle_mode = true
|
||||
text = "✓"
|
||||
|
||||
[node name="CloseButton" type="Button" parent="TopPanel/Top"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
tooltip_text = "close art tools"
|
||||
text = "×"
|
||||
|
||||
[node name="ColorPanel" type="PanelContainer" parent="."]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_left = 534.0
|
||||
offset_top = 54.0
|
||||
offset_right = 580.0
|
||||
offset_bottom = 373.0
|
||||
|
||||
[node name="ColorList" type="VBoxContainer" parent="ColorPanel"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 5
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue