diff --git a/classes/connections/connections.gd b/classes/connections/connections.gd new file mode 100644 index 0000000..4acff4d --- /dev/null +++ b/classes/connections/connections.gd @@ -0,0 +1,3 @@ +class_name Connections + +static var obs_websocket diff --git a/classes/deck/nodes/obs_switch_scene.gd b/classes/deck/nodes/obs_switch_scene.gd new file mode 100644 index 0000000..dd4861b --- /dev/null +++ b/classes/deck/nodes/obs_switch_scene.gd @@ -0,0 +1,45 @@ +extends DeckNode + +var noobs: NoOBSWS + +func _init() -> void: + name = "Set Scene" + node_type = "obs_set_scene" + description = "" + category = "obs" + + props_to_serialize = [] + + add_input_port( + DeckType.Types.STRING, + "Scene Name", + "field" + ) + + add_input_port( + DeckType.Types.BOOL, + "Switch", + "button" + ) + + +func _receive(on_input_port: int, data: Variant, extra_data: Array = []) -> void: + if on_input_port != 1: + return + + if noobs == null: + noobs = Connections.obs_websocket + + var scene_name: String + if request_value(0) != null: + scene_name = request_value(0) + elif get_input_ports()[0].value_callback.get_object() && get_input_ports()[0].value_callback.call() != "": + scene_name = get_input_ports()[0].value_callback.call() + + if scene_name.is_empty(): + return + + noobs.make_generic_request( + "SetCurrentProgramScene", + {"scene_name": scene_name} + ) diff --git a/graph_node_renderer/deck_holder_renderer.gd b/graph_node_renderer/deck_holder_renderer.gd index 865eec2..e13fffb 100644 --- a/graph_node_renderer/deck_holder_renderer.gd +++ b/graph_node_renderer/deck_holder_renderer.gd @@ -22,9 +22,17 @@ enum FileMenuId { CLOSE = 6, } +enum ConnectionsMenuId { + OBS, +} + ## Weak Reference to the Deck that is currently going to be saved. var _deck_to_save: WeakRef +@onready var no_obsws: NoOBSWS = %NoOBSWS as NoOBSWS + +@onready var obs_setup_dialog: OBSWebsocketSetupDialog = $OBSWebsocketSetupDialog as OBSWebsocketSetupDialog + func _ready() -> void: tab_container.add_button_pressed.connect(add_empty_deck) @@ -36,6 +44,8 @@ func _ready() -> void: ) file_dialog.canceled.connect(disconnect_file_dialog_signals) + Connections.obs_websocket = no_obsws + ## Called when the File button in the [MenuBar] is pressed with the [param id] ## of the button within it that was pressed. @@ -142,3 +152,19 @@ func _on_deck_renderer_group_enter_requested(group_id: String, deck: Deck) -> vo tab_container.add_content(deck_renderer, "Group %s" % (tab_container.get_tab_count() + 1)) tab_container.set_tab_metadata(tab_container.get_current_tab(), group_deck) deck_renderer.group_enter_requested.connect(_on_deck_renderer_group_enter_requested.bind(deck_renderer.deck)) + + +func _on_connections_id_pressed(id: int) -> void: + match id: + ConnectionsMenuId.OBS: + obs_setup_dialog.popup_centered() + + +func _on_obs_websocket_setup_dialog_connect_button_pressed(state: OBSWebsocketSetupDialog.ConnectionState) -> void: + match state: + OBSWebsocketSetupDialog.ConnectionState.DISCONNECTED: + obs_setup_dialog.set_button_state(OBSWebsocketSetupDialog.ConnectionState.CONNECTING) + no_obsws.connect_to_obsws(obs_setup_dialog.get_port(), obs_setup_dialog.get_password()) + await no_obsws.connection_ready + obs_setup_dialog.set_button_state(OBSWebsocketSetupDialog.ConnectionState.CONNECTED) + diff --git a/graph_node_renderer/deck_holder_renderer.tscn b/graph_node_renderer/deck_holder_renderer.tscn index fa41b7e..68e7064 100644 --- a/graph_node_renderer/deck_holder_renderer.tscn +++ b/graph_node_renderer/deck_holder_renderer.tscn @@ -1,8 +1,10 @@ -[gd_scene load_steps=4 format=3 uid="uid://duaah5x0jhkn6"] +[gd_scene load_steps=6 format=3 uid="uid://duaah5x0jhkn6"] [ext_resource type="Script" path="res://graph_node_renderer/deck_holder_renderer.gd" id="1_67g2g"] [ext_resource type="PackedScene" uid="uid://b84f2ngtcm5b8" path="res://graph_node_renderer/tab_container_custom.tscn" id="1_s3ug2"] [ext_resource type="Theme" uid="uid://dqqdqscid2iem" path="res://graph_node_renderer/default_theme.tres" id="1_tgul2"] +[ext_resource type="Script" path="res://addons/no-obs-ws/NoOBSWS.gd" id="4_nu72u"] +[ext_resource type="PackedScene" uid="uid://eioso6jb42jy" path="res://graph_node_renderer/obs_websocket_setup_dialog.tscn" id="5_uo2gj"] [node name="DeckHolderRenderer" type="Control"] layout_mode = 3 @@ -57,6 +59,11 @@ item_6/id = 6 [node name="Edit" type="PopupMenu" parent="MarginContainer/VSplitContainer/VBoxContainer/MenuBar"] +[node name="Connections" type="PopupMenu" parent="MarginContainer/VSplitContainer/VBoxContainer/MenuBar"] +item_count = 1 +item_0/text = "OBS..." +item_0/id = 0 + [node name="TabContainerCustom" parent="MarginContainer/VSplitContainer/VBoxContainer" instance=ExtResource("1_s3ug2")] unique_name_in_owner = true layout_mode = 2 @@ -70,4 +77,14 @@ mode_overrides_title = false access = 2 use_native_dialog = true +[node name="Connections" type="Node" parent="."] + +[node name="NoOBSWS" type="Node" parent="Connections"] +unique_name_in_owner = true +script = ExtResource("4_nu72u") + +[node name="OBSWebsocketSetupDialog" parent="." instance=ExtResource("5_uo2gj")] + [connection signal="id_pressed" from="MarginContainer/VSplitContainer/VBoxContainer/MenuBar/File" to="." method="_on_file_id_pressed"] +[connection signal="id_pressed" from="MarginContainer/VSplitContainer/VBoxContainer/MenuBar/Connections" to="." method="_on_connections_id_pressed"] +[connection signal="connect_button_pressed" from="OBSWebsocketSetupDialog" to="." method="_on_obs_websocket_setup_dialog_connect_button_pressed"] diff --git a/graph_node_renderer/obs_websocket_setup_dialog.gd b/graph_node_renderer/obs_websocket_setup_dialog.gd new file mode 100644 index 0000000..81152c7 --- /dev/null +++ b/graph_node_renderer/obs_websocket_setup_dialog.gd @@ -0,0 +1,60 @@ +extends ConfirmationDialog +class_name OBSWebsocketSetupDialog + +@onready var port_spin_box: SpinBox = %PortSpinBox +@onready var password_line_edit: LineEdit = %PasswordLineEdit +@onready var connect_button: Button = %ConnectButton + +signal connect_button_pressed(state: ConnectionState) + +enum ConnectionState { + DISCONNECTED, + CONNECTING, + CONNECTED, +} +var state: ConnectionState + +@onready var _old_port: int = port_spin_box.value +@onready var _old_password: String = password_line_edit.text + + +func get_port() -> int: + return int(port_spin_box.value) + + +func get_password() -> String: + return password_line_edit.text + + +func set_button_state(p_state: ConnectionState) -> void: + connect_button.disabled = p_state == ConnectionState.CONNECTING + state = p_state + + match p_state: + ConnectionState.DISCONNECTED: + connect_button.text = "Connect" + ConnectionState.CONNECTING: + connect_button.text = "Connecting..." + ConnectionState.CONNECTED: + connect_button.text = "Disconnect" + + +func _ready() -> void: + connect_button.pressed.connect( + func(): + connect_button_pressed.emit(state) + ) + + canceled.connect( + func(): + print("canceled") + port_spin_box.value = float(_old_port) + password_line_edit.text = _old_password + ) + + confirmed.connect( + func(): + print("confirmed") + _old_port = int(port_spin_box.value) + _old_password = password_line_edit.text + ) diff --git a/graph_node_renderer/obs_websocket_setup_dialog.tscn b/graph_node_renderer/obs_websocket_setup_dialog.tscn new file mode 100644 index 0000000..3cfd516 --- /dev/null +++ b/graph_node_renderer/obs_websocket_setup_dialog.tscn @@ -0,0 +1,51 @@ +[gd_scene load_steps=2 format=3 uid="uid://eioso6jb42jy"] + +[ext_resource type="Script" path="res://graph_node_renderer/obs_websocket_setup_dialog.gd" id="1_6ggla"] + +[node name="OBSWebsocketSetupDialog" type="ConfirmationDialog"] +title = "OBS Websocket Setup" +initial_position = 4 +size = Vector2i(500, 300) +script = ExtResource("1_6ggla") + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +offset_left = 8.0 +offset_top = 8.0 +offset_right = 492.0 +offset_bottom = 251.0 + +[node name="GridContainer" type="GridContainer" parent="VBoxContainer"] +layout_mode = 2 +columns = 2 + +[node name="Label" type="Label" parent="VBoxContainer/GridContainer"] +layout_mode = 2 +text = "Port" + +[node name="PortSpinBox" type="SpinBox" parent="VBoxContainer/GridContainer"] +unique_name_in_owner = true +layout_mode = 2 +max_value = 25565.0 +value = 4455.0 + +[node name="Label2" type="Label" parent="VBoxContainer/GridContainer"] +layout_mode = 2 +text = "Password" + +[node name="PasswordLineEdit" type="LineEdit" parent="VBoxContainer/GridContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +secret = true + +[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer"] +layout_mode = 2 +theme_override_constants/margin_bottom = 20 + +[node name="CenterContainer" type="CenterContainer" parent="VBoxContainer"] +layout_mode = 2 + +[node name="ConnectButton" type="Button" parent="VBoxContainer/CenterContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Connect" diff --git a/project.godot b/project.godot index e609bcd..051a5ad 100644 --- a/project.godot +++ b/project.godot @@ -23,10 +23,6 @@ config/icon="res://icon.svg" NodeDB="*res://classes/deck/node_db.gd" -[display] - -window/subwindows/embed_subwindows=false - [editor_plugins] enabled=PackedStringArray("res://addons/no-obs-ws/plugin.cfg")