Browse Source

Add in-VR numpad for IP/port input, update default server to 10.0.0.77

Quest system keyboard doesn't work in immersive XR mode, so added a
numpad overlay that appears when tapping input fields.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
master
melancholytron 3 weeks ago
parent
commit
9dcf950f2a
  1. 2
      scenes/start_screen.tscn
  2. 77
      scripts/start_screen.gd

2
scenes/start_screen.tscn

@ -71,7 +71,7 @@ text = "Server:"
[node name="HostInput" type="LineEdit" parent="UIMesh/SubViewport/PanelContainer/MarginContainer/VBox/ServerRow"]
layout_mode = 2
size_flags_horizontal = 3
text = "10.0.0.64"
text = "10.0.0.77"
placeholder_text = "IP address or hostname"
virtual_keyboard_enabled = true

77
scripts/start_screen.gd

@ -2,6 +2,7 @@ extends Node3D
## VR start screen UI panel.
## Renders a 2D UI in a SubViewport on a QuadMesh in VR space.
## Allows user to enter server URL/port, connect, and launch AR mode.
## Includes an in-VR numpad since the Quest system keyboard doesn't work in XR mode.
signal connect_requested(host: String, port: int)
signal launch_ar_requested()
@ -13,8 +14,11 @@ signal launch_ar_requested()
@onready var connect_button: Button = $UIMesh/SubViewport/PanelContainer/MarginContainer/VBox/ConnectButton
@onready var status_label: Label = $UIMesh/SubViewport/PanelContainer/MarginContainer/VBox/StatusLabel
@onready var launch_ar_button: Button = $UIMesh/SubViewport/PanelContainer/MarginContainer/VBox/LaunchARButton
@onready var vbox: VBoxContainer = $UIMesh/SubViewport/PanelContainer/MarginContainer/VBox
var _is_connected: bool = false
var _numpad_container: VBoxContainer
var _active_input: LineEdit # Which input field the numpad types into
func _ready() -> void:
@ -22,6 +26,13 @@ func _ready() -> void:
connect_button.pressed.connect(_on_connect_pressed)
launch_ar_button.pressed.connect(_on_launch_ar_pressed)
# Show numpad when input fields are focused
host_input.focus_entered.connect(_on_input_focused.bind(host_input))
port_input.focus_entered.connect(_on_input_focused.bind(port_input))
# Build the in-VR numpad
_build_numpad()
# Set up the mesh material to display the SubViewport
var material := StandardMaterial3D.new()
material.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
@ -32,7 +43,73 @@ func _ready() -> void:
print("[StartScreen] Ready")
func _build_numpad() -> void:
_numpad_container = VBoxContainer.new()
_numpad_container.add_theme_constant_override("separation", 6)
_numpad_container.visible = false
# Button rows: [1,2,3] [4,5,6] [7,8,9] [.,0,<-] [Clear, Done]
var rows := [
["1", "2", "3"],
["4", "5", "6"],
["7", "8", "9"],
[".", "0", "<"],
["Clear", "Done"],
]
for row in rows:
var hbox := HBoxContainer.new()
hbox.add_theme_constant_override("separation", 6)
hbox.alignment = BoxContainer.ALIGNMENT_CENTER
for key in row:
var btn := Button.new()
btn.text = key
btn.custom_minimum_size = Vector2(80, 55)
btn.size_flags_horizontal = Control.SIZE_EXPAND_FILL
if key == "Clear" or key == "Done":
btn.custom_minimum_size = Vector2(130, 55)
btn.add_theme_font_size_override("font_size", 26)
btn.pressed.connect(_on_numpad_key.bind(key))
hbox.add_child(btn)
_numpad_container.add_child(hbox)
# Insert numpad after the PortRow
var port_row_idx := port_input.get_parent().get_index()
vbox.add_child(_numpad_container)
vbox.move_child(_numpad_container, port_row_idx + 1)
func _on_input_focused(input: LineEdit) -> void:
_active_input = input
_numpad_container.visible = true
func _on_numpad_key(key: String) -> void:
if _active_input == null:
return
if key == "<":
# Backspace
var t := _active_input.text
if t.length() > 0:
_active_input.text = t.substr(0, t.length() - 1)
_active_input.caret_column = _active_input.text.length()
elif key == "Clear":
_active_input.text = ""
_active_input.caret_column = 0
elif key == "Done":
_numpad_container.visible = false
_active_input.release_focus()
_active_input = null
else:
_active_input.text += key
_active_input.caret_column = _active_input.text.length()
func _on_connect_pressed() -> void:
# Hide numpad if open
_numpad_container.visible = false
var host := host_input.text.strip_edges()
if host.is_empty():
update_status("Please enter a server address")

Loading…
Cancel
Save