extends Control var tab_container: TabContainer var support_tab_container: TabContainer # Reference to the instantiated clipboard/network engine var clipboard_engine: Node func _ready() -> void: # 1. Initialize the full-screen TabContainer tab_container = TabContainer.new() add_child(tab_container) tab_container.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) create_standard_tab("Game") create_standard_tab("Editor") create_standard_tab("Network") create_standard_tab("AI") create_standard_tab("Video") create_standard_tab("Audio") create_standard_tab("Support") # Connect the tab navigation signal natively tab_container.tab_changed.connect(_on_tab_changed) # Explicitly set the starting tab to ensure a clean state on launch tab_container.current_tab = 0 # Instantiate the clipboard/network engine as a child of the root Control. # This allows it to access the scene tree and multiplayer signals globally. var engine_script = preload("res://clipboard_engine.gd") clipboard_engine = engine_script.new() add_child(clipboard_engine) await get_tree().process_frame # Ensure child _ready runs # Bootup logic var has_config = clipboard_engine.load_network_config() if has_config: print("[Autoconnect] Secure config file loaded. Instantiating auto-client...") _switch_to_tab_by_name("Network") else: print("[Autoconnect] Initial default config file created.") func create_standard_tab(tab_name: String) -> void: # MarginContainer isolates your tab content from the very edge of the screen var tab_page := MarginContainer.new() tab_page.name = tab_name # Force the tab page to fill all space provided by the TabContainer tab_page.size_flags_horizontal = Control.SIZE_EXPAND | Control.SIZE_FILL tab_page.size_flags_vertical = Control.SIZE_EXPAND | Control.SIZE_FILL # Apply standard UI padding (16px - 24px is standard for modern apps) var padding := 20 tab_page.add_theme_constant_override("margin_top", padding) tab_page.add_theme_constant_override("margin_left", padding) tab_page.add_theme_constant_override("margin_right", padding) tab_page.add_theme_constant_override("margin_bottom", padding) tab_container.add_child(tab_page) # Add a vertical layout to separate main content from the bottom bar var layout_vbox := VBoxContainer.new() layout_vbox.size_flags_horizontal = Control.SIZE_EXPAND | Control.SIZE_FILL layout_vbox.size_flags_vertical = Control.SIZE_EXPAND | Control.SIZE_FILL tab_page.add_child(layout_vbox) # Placeholder for main content body (Expands to fill top area) var main_content := Control.new() main_content.size_flags_horizontal = Control.SIZE_EXPAND | Control.SIZE_FILL main_content.size_flags_vertical = Control.SIZE_EXPAND | Control.SIZE_FILL layout_vbox.add_child(main_content) # Standard locked bottom node (Only fills width, sits neatly at bottom) var bottom_bar := PanelContainer.new() bottom_bar.size_flags_horizontal = Control.SIZE_EXPAND | Control.SIZE_FILL bottom_bar.size_flags_vertical = Control.SIZE_FILL # Crucial: No expansion flag layout_vbox.add_child(bottom_bar) func _switch_to_tab_by_name(target_name: String) -> void: # Loop through tabs to match the node name for i in range(tab_container.get_tab_count()): var child_node = tab_container.get_child(i) if child_node.name == target_name: tab_container.current_tab = i return push_warning("Could not find a tab named: " + target_name) func _unhandled_input(event: InputEvent) -> void: # Handle input events efficiently without polling in _process if event.is_action_pressed("next_tab"): _cycle_tabs(1) elif event.is_action_pressed("previous_tab"): _cycle_tabs(-1) ## Safely increments or decrements the current tab with out-of-bounds protection. func _cycle_tabs(direction: int) -> void: var total_tabs: int = tab_container.get_tab_count() if total_tabs <= 1: return # posmod() prevents negative numbers and wraps index perfectly var target_index: int = posmod(tab_container.current_tab + direction, total_tabs) tab_container.current_tab = target_index ## Callback function triggered every time the tab changes. func _on_tab_changed(tab_index: int) -> void: var current_page: Node = tab_container.get_child(tab_index) match current_page.name: "Game": game_interface(current_page) "Network": # Pass the container and the engine instance to the UI builder load("res://clipboard_ui.gd").build_network_ui(current_page, clipboard_engine) "AI": ai_interface(current_page) "Video": video_settings() "Audio": audio_settings() "Support": support_interface(current_page) # Mock interfaces for other tabs func game_interface(_page_container: Node) -> void: pass func ai_interface(_page_container: Node) -> void: pass func video_settings() -> void: pass func audio_settings() -> void: pass func support_interface(_page_container: Node) -> void: pass