grounders-slowjam-2024/addons/fmod/tool/ui/FmodBankExplorer.gd

257 lines
8.6 KiB
GDScript3
Raw Normal View History

2024-05-25 11:51:19 -06:00
@tool class_name FmodBankExplorer extends Window
enum ToDisplayFlags {
BANKS = 1,
BUSES = 2,
VCA = 4,
EVENTS = 8
}
static var _fmod_icon = load("res://addons/fmod/icons/fmod_icon.svg")
static var _vca_icon = load("res://addons/fmod/icons/vca_icon.svg")
static var _bank_icon = load("res://addons/fmod/icons/bank_icon.svg")
static var _event_icon = load("res://addons/fmod/icons/event_icon.svg")
static var _bus_icon = load("res://addons/fmod/icons/bus_icon.svg")
static var _snapshot_icon = load("res://addons/fmod/icons/snapshot_icon.svg")
signal emit_path_and_guid(path: String, guid: String)
var tree: Tree
@onready var copy_path_button := %PathLabel.get_child(0)
@onready var copy_guid_button := %GuidLabel.get_child(0)
var should_display_copy_buttons = true
var should_display_select_button = false
var _current_select_callable: Callable
var base_color: Color
var contrast: float
var background_color: Color
func _ready():
var main_window_size = get_parent().get_window().size
size = main_window_size * 0.5
var copy_texture : Texture = EditorInterface.get_editor_theme().get_icon("ActionCopy", "EditorIcons")
copy_guid_button.icon = copy_texture
copy_path_button.icon = copy_texture
copy_guid_button.visible = false
copy_path_button.visible = false
copy_path_button.pressed.connect(_on_copy_path_button)
copy_guid_button.pressed.connect(_on_copy_guid_button)
var emit_path_and_guid_callable = func emit_path_and_guid_callable():
var selected_item = tree.get_selected()
if selected_item == null:
return
var selected_fmod_element = selected_item.get_metadata(0)
if selected_fmod_element == null:
return
var path = selected_fmod_element.get_godot_res_path() if selected_fmod_element is FmodBank else selected_fmod_element.get_path()
emit_path_and_guid.emit(path, selected_fmod_element.get_guid())
%SelectButton.pressed.connect(emit_path_and_guid_callable)
%SelectButton.pressed.connect(close_window)
%CloseButton.pressed.connect(close_window)
close_requested.connect(close_window)
tree = %Tree
tree.item_selected.connect(_on_item_selected)
tree.columns = 1
regenerate_tree(ToDisplayFlags.BANKS | ToDisplayFlags.BUSES | ToDisplayFlags.VCA | ToDisplayFlags.EVENTS)
%RefreshBanksButton.pressed.connect(on_refresh_banks_button_pressed)
func regenerate_tree(to_display: int, callable: Callable = Callable()):
%SelectButton.visible = should_display_select_button
if _current_select_callable != Callable() && _current_select_callable.get_object() != null:
emit_path_and_guid.disconnect(_current_select_callable)
_current_select_callable = callable
tree.clear()
var root_item := tree.create_item()
root_item.set_text(0, "Fmod objects")
root_item.set_icon(0, _fmod_icon)
for bank in FmodServer.get_all_banks():
var fmod_bank := bank as FmodBank
var bank_item := tree.create_item(root_item)
bank_item.set_text(0, fmod_bank.get_godot_res_path())
bank_item.set_icon(0, _bank_icon)
bank_item.set_metadata(0, bank)
if to_display & ToDisplayFlags.BUSES:
var buses_item := tree.create_item(bank_item)
buses_item.set_text(0, "Buses")
buses_item.set_icon(0, _bus_icon)
var buses := fmod_bank.get_bus_list()
buses.sort_custom(sort_by_path)
_add_elements_as_tree(buses, buses_item)
if to_display & ToDisplayFlags.VCA:
var vca_item := tree.create_item(bank_item)
vca_item.set_text(0, "VCAs")
vca_item.set_icon(0, _vca_icon)
var vcas := fmod_bank.get_vca_list()
vcas.sort_custom(sort_by_path)
_add_elements_as_tree(vcas, vca_item)
if to_display & ToDisplayFlags.EVENTS:
var events_item := tree.create_item(bank_item)
events_item.set_text(0, "Events")
events_item.set_icon(0, _event_icon)
var events := fmod_bank.get_description_list()
events.sort_custom(sort_by_path)
_add_elements_as_tree(events, events_item)
if copy_path_button.visible:
copy_path_button.visible = should_display_copy_buttons
if copy_guid_button.visible:
copy_guid_button.visible = should_display_copy_buttons
if _current_select_callable != Callable():
print(_current_select_callable)
emit_path_and_guid.connect(_current_select_callable)
%SelectButton.visible = should_display_select_button and %GuidLabel.text != ""
func _add_elements_as_tree(elements: Array, parent: TreeItem):
var stack = Array()
for element in elements:
_add_element_to_stack(stack, parent, element)
func _add_element_to_stack(stack: Array, parent_root: TreeItem, path_element):
var fmod_path: String = path_element.get_path()
var path_parts := fmod_path.split("/")
if path_parts[path_parts.size() - 1] == "":
path_parts.remove_at(path_parts.size() - 1)
for i in range(0, path_parts.size()):
var path_part = path_parts[i]
path_part = path_part if path_part != "bus:" else "Master"
if i >= stack.size():
var parent_item = parent_root if stack.is_empty() else stack[stack.size() - 1]
var tree_item = tree.create_item(parent_item)
tree_item.set_text(0, path_part)
if i == path_parts.size() - 1:
tree_item.set_metadata(0, path_element)
tree_item.set_icon(0, _get_icon_for_fmod_path(fmod_path))
stack.append(tree_item)
continue
if stack[i].get_text(0) != path_part:
for j in range(stack.size() - 1, i - 1, -1):
stack.remove_at(j)
var parent_item = parent_root if stack.is_empty() else stack[stack.size() - 1]
var tree_item = tree.create_item(parent_item)
tree_item.set_text(0, path_part)
if i == path_parts.size() - 1:
tree_item.set_metadata(0, path_element)
tree_item.set_icon(0, _get_icon_for_fmod_path(fmod_path))
stack.append(tree_item)
func _on_item_selected():
var metadata = tree.get_selected().get_metadata(0)
if metadata == null or !metadata.get_guid():
%PathsBG.hide()
%EventPlayControls.hide()
copy_path_button.visible = false
copy_guid_button.visible = false
%SelectButton.visible = false
%ParametersLabel.visible = false
%ParametersContainer.visible = false
return
%GuidLabel.set_text(metadata.get_guid())
%PathLabel.set_text(metadata.get_path())
%PathsBG.show()
if should_display_copy_buttons:
copy_path_button.visible = true
copy_guid_button.visible = true
if should_display_select_button:
%SelectButton.visible = true
if metadata is FmodEventDescription:
%EventPlayControls.set_fmod_event(metadata)
var _show_parameter_controls : bool = %EventParametersDisplay.set_fmod_event(metadata)
%ParametersLabel.visible = _show_parameter_controls
%ParametersContainer.visible = _show_parameter_controls
return
%EventPlayControls.hide()
%EventParametersDisplay.hide()
%ParametersLabel.visible = false
%ParametersContainer.visible = false
func _on_copy_path_button():
DisplayServer.clipboard_set(%PathLabel.text)
func _on_copy_guid_button():
DisplayServer.clipboard_set(%GuidLabel.text)
func on_refresh_banks_button_pressed() -> void:
# unload banks
var current_banks : Array = FmodServer.get_all_banks()
for i : FmodBank in current_banks:
FmodServer.unload_bank(i.get_godot_res_path())
# get the banks to load
var path : String = ProjectSettings.get_setting("Fmod/General/banks_path", "")
if !path:
printerr("No banks path set in the project settings (Fmod/General/banks_path)")
return # no path set in the project settings
var bank_paths_to_load : Array[String]
var dir : DirAccess = DirAccess.open(path)
if dir:
dir.list_dir_begin()
var file_name : String = dir.get_next()
while file_name != "":
if dir.current_is_dir():
pass # the found item is a directory
else:
if file_name.ends_with(".bank"):
bank_paths_to_load.append(path + "/" + file_name)
file_name = dir.get_next()
if bank_paths_to_load:
# sort to first load the master bank and its strings
bank_paths_to_load.sort_custom(func(path1 : String, path2 : String) -> bool: return path1.contains("Master"))
else:
printerr("Could not find any banks in the specified directory")
for bank_path : String in bank_paths_to_load:
FmodServer.load_bank(bank_path, FmodServer.FMOD_STUDIO_LOAD_BANK_NORMAL)
else:
printerr("Couldn't access bank path, please make sure you specified a folder with the banks as direct children")
regenerate_tree(ToDisplayFlags.BANKS | ToDisplayFlags.BUSES | ToDisplayFlags.VCA | ToDisplayFlags.EVENTS)
func close_window():
%EventPlayControls.stop_event()
visible = false
static func _get_icon_for_fmod_path(fmod_path: String) -> Texture2D:
var icon: Texture2D = null
if fmod_path.begins_with("bus:/"):
icon = _bus_icon
elif fmod_path.begins_with("event:/"):
icon = _event_icon
elif fmod_path.begins_with("vca:/"):
icon = _vca_icon
elif fmod_path.begins_with("snapshot:/"):
icon = _snapshot_icon
return icon
static func sort_by_path(a, b):
return a.get_path().casecmp_to(b.get_path()) < 0