Files
SurfaceSide-UI/scripts/layout_overview.gd
T

136 lines
4.7 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
extends Control
signal overview_changed(active: bool)
@export var grid_size := Vector2i(32, 18):
set(value):
grid_size = Vector2i(maxi(1, value.x), maxi(1, value.y))
if is_node_ready():
_update_grid()
@export var monitor_boundary := 0
@export_range(0.5, 0.95) var overview_scale := 0.82
@export var transition_seconds := 0.22
@export var hot_corner_enabled := true
@export var corner_size := 20.0
@export var corner_dwell := 0.18
var overview_active := false
var _pointer_in_window := false
var _corner_hover := false
var _corner_armed := true
var _dwell := 0.0
var _tween: Tween
@onready var dashboard: Control = $Dashboard
@onready var grid: Control = $Dashboard/Grid
@onready var canvas: Control = $Dashboard/Canvas
func _ready() -> void:
grid.gui_input.connect(canvas.handle_grid_input)
$Toolbar/Add.pressed.connect(func() -> void: $Library.visible = not $Library.visible)
$Library.element_requested.connect(_add_element)
canvas.layout_saved.connect(func() -> void: $Toolbar/Hint.text = "Esc to return")
canvas.load_failed.connect(func() -> void: $Toolbar/Hint.text = "Could not load saved layout")
$Toolbar/Reset.pressed.connect(canvas.reset_layout)
canvas.save_failed.connect(func() -> void: $Toolbar/Hint.text = "Could not save layout")
$Toolbar/Return.pressed.connect(func() -> void: set_overview(false))
resized.connect(_resize)
get_window().mouse_entered.connect(func() -> void: _pointer_in_window = true)
get_window().mouse_exited.connect(_leave_corner)
theme_changed.connect(queue_redraw)
_update_grid()
canvas.load_layout()
_resize()
func _input(event: InputEvent) -> void:
if event is InputEventMouseMotion and hot_corner_enabled:
_pointer_in_window = true
_update_corner(get_window().get_final_transform() * event.position)
elif overview_active and event is InputEventKey and event.pressed and event.keycode == KEY_ESCAPE:
if $Library.visible:
$Library.hide()
else:
set_overview(false)
get_viewport().set_input_as_handled()
elif overview_active and event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
var pointer: Vector2 = get_global_transform_with_canvas().affine_inverse() * event.position
var in_library: bool = $Library.visible and $Library.get_global_rect().has_point(event.position)
if not in_library and not preview_rect().has_point(pointer) and not $Toolbar.get_global_rect().has_point(event.position):
set_overview(false)
get_viewport().set_input_as_handled()
func _process(delta: float) -> void:
var window := get_window()
# Letterbox regions may not send canvas mouse-motion events.
if hot_corner_enabled and window.visible and (_pointer_in_window or window.has_focus()):
_update_corner(window.get_final_transform() * window.get_mouse_position())
else:
_leave_corner()
if hot_corner_enabled and _corner_hover and _corner_armed and not overview_active:
_dwell += delta
if _dwell >= corner_dwell:
_corner_armed = false
set_overview(true)
func _update_corner(window_position: Vector2) -> void:
_corner_hover = Rect2(Vector2.ZERO, Vector2.ONE * corner_size).has_point(window_position)
if not _corner_hover:
_corner_armed = true
_dwell = 0
func _leave_corner() -> void:
_pointer_in_window = false
_corner_hover = false
_dwell = 0
func set_overview(active: bool) -> void:
if overview_active == active:
return
if not active:
$Library.hide()
canvas.set_edit_mode(active)
overview_active = active
_corner_armed = false
_dwell = 0
if is_instance_valid(_tween):
_tween.kill()
grid.visible = active
$Toolbar.visible = active
queue_redraw()
var target := Vector2.ONE * overview_scale if active else Vector2.ONE
if transition_seconds <= 0:
dashboard.scale = target
else:
_tween = create_tween().set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT)
_tween.tween_property(dashboard, "scale", target, transition_seconds)
overview_changed.emit(active)
func _add_element(element_type: String) -> void:
if canvas.add_element(element_type) == null:
$Library.show_no_space()
else:
$Library.hide()
func preview_rect() -> Rect2:
return Rect2((size - size * dashboard.scale) / 2, size * dashboard.scale)
func _resize() -> void:
_dwell = 0
if is_instance_valid(_tween):
_tween.kill()
dashboard.pivot_offset = size / 2
dashboard.scale = Vector2.ONE * overview_scale if overview_active else Vector2.ONE
queue_redraw()
func _update_grid() -> void:
canvas.grid_size = grid_size
canvas.arrange_items()
grid.grid_size = grid_size
grid.monitor_boundary = monitor_boundary
grid.queue_redraw()
$Toolbar/Title.text = "LAYOUT OVERVIEW %d × %d" % [grid_size.x, grid_size.y]
func _draw() -> void:
if overview_active:
draw_rect(Rect2(Vector2.ZERO, size), get_theme_color("instrument_empty", "SurfaceSide"))