Add PhantomCamera components and UI elements for improved scene management; refactor existing components for better integration

This commit is contained in:
2025-08-26 19:48:48 +02:00
parent cea3956fbb
commit 4c15f50f6e
65 changed files with 2654 additions and 61 deletions

View File

@@ -0,0 +1,112 @@
@tool
extends VBoxContainer
#region Constants
const _constants := preload("res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd")
const _host_list_item: PackedScene = preload("res://addons/phantom_camera/panel/viewfinder/host_list/host_list_item.tscn")
#endregion
signal pcam_host_removed(pcam_host: PhantomCameraHost)
@onready var _host_list_button: Button = %HostListButton
@onready var _host_list_scroll_container: ScrollContainer = %ScrollContainer
@onready var _host_list_item_container: VBoxContainer = %HostListContainer
var _host_list_open: bool = false
var _bottom_offset_value: float
var _pcam_host_list: Array[PhantomCameraHost]
var _pcam_manager: Node
var _viewfinder_panel: Control
#region Private Functions
func _ready() -> void:
_host_list_button.pressed.connect(_host_list_button_pressed)
if Engine.has_singleton(_constants.PCAM_MANAGER_NODE_NAME):
_pcam_manager = Engine.get_singleton(_constants.PCAM_MANAGER_NODE_NAME)
_pcam_manager.pcam_host_removed_from_scene.connect(_remove_pcam_host)
if not get_parent() is Control: return # To prevent errors when opening the scene on its own
_viewfinder_panel = get_parent()
_viewfinder_panel.resized.connect(_set_offset_top)
_host_list_item_container.resized.connect(_set_offset_top)
func _set_offset_top() -> void:
offset_top = _set_host_list_size()
func _host_list_button_pressed() -> void:
_host_list_open = !_host_list_open
var tween: Tween = create_tween()
var max_duration: float = 0.6
# 300 being the minimum size of the viewfinder's height
var duration: float = clampf(
max_duration / (300 / _host_list_item_container.size.y),
0.3,
max_duration)
tween.tween_property(self, "offset_top", _set_host_list_size(), duration)\
.set_ease(Tween.EASE_OUT)\
.set_trans(Tween.TRANS_QUINT)
func _set_host_list_size() -> float:
if not _host_list_open:
return clampf(
_viewfinder_panel.size.y - \
_host_list_item_container.size.y - \
_host_list_button.size.y - 20,
0,
INF
)
else:
return (_viewfinder_panel.size.y - _host_list_button.size.y / 2)
func _remove_pcam_host(pcam_host: PhantomCameraHost) -> void:
if _pcam_host_list.has(pcam_host):
_pcam_host_list.erase(pcam_host)
var freed_pcam_host: Control
for host_list_item_instance in _host_list_item_container.get_children():
if not host_list_item_instance.pcam_host == pcam_host: continue
freed_pcam_host = host_list_item_instance
host_list_item_instance.queue_free()
#endregion
#region Public Functions
func add_pcam_host(pcam_host: PhantomCameraHost, is_default: bool) -> void:
if _pcam_host_list.has(pcam_host): return
_pcam_host_list.append(pcam_host)
var host_list_item_instance: PanelContainer = _host_list_item.instantiate()
var switch_pcam_host_button: Button = host_list_item_instance.get_node("%SwitchPCamHost")
if is_default: switch_pcam_host_button.button_pressed = true
if not pcam_host.tree_exiting.is_connected(_remove_pcam_host):
pcam_host.tree_exiting.connect(_remove_pcam_host.bind(pcam_host))
host_list_item_instance.pcam_host = pcam_host
_host_list_item_container.add_child(host_list_item_instance)
func clear_pcam_host_list() -> void:
_pcam_host_list.clear()
for host_list_item_instance in _host_list_item_container.get_children():
host_list_item_instance.queue_free()
#endregion

View File

@@ -0,0 +1 @@
uid://c84cxry3t35ny

View File

@@ -0,0 +1,58 @@
@tool
extends Control
const button_group_resource: ButtonGroup = preload("res://addons/phantom_camera/panel/viewfinder/host_list/host_list_item_group.tres")
const _constants = preload("res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd")
@onready var select_pcam_host: Button = %SelectPCamHost
@onready var switch_pcam_host: Button = %SwitchPCamHost
var pcam_host: PhantomCameraHost:
set(value):
pcam_host = value
if not is_instance_valid(value): return
if not pcam_host.renamed.is_connected(_rename_pcam_host):
pcam_host.renamed.connect(_rename_pcam_host)
pcam_host.has_error.connect(_pcam_host_has_error)
get:
return pcam_host
var _pcam_manager: Node
#region Private fucntions
func _ready() -> void:
switch_pcam_host.button_group = button_group_resource
select_pcam_host.pressed.connect(_select_pcam)
switch_pcam_host.pressed.connect(_switch_pcam_host)
if not is_instance_valid(pcam_host): return
switch_pcam_host.text = pcam_host.name
_pcam_host_has_error()
func _pcam_host_has_error() -> void:
if pcam_host.show_warning:
%ErrorPCamHost.visible = true
else:
%ErrorPCamHost.visible = false
func _rename_pcam_host() -> void:
switch_pcam_host.text = pcam_host.name
func _select_pcam() -> void:
EditorInterface.get_selection().clear()
EditorInterface.get_selection().add_node(pcam_host)
func _switch_pcam_host() -> void:
if not Engine.has_singleton(_constants.PCAM_MANAGER_NODE_NAME): return
if not is_instance_valid(_pcam_manager):
_pcam_manager = Engine.get_singleton(_constants.PCAM_MANAGER_NODE_NAME)
_pcam_manager.viewfinder_pcam_host_switch.emit(pcam_host)
#endregion

View File

@@ -0,0 +1 @@
uid://bv24ubx8mutw7