diff --git a/godot/scenes/main.tscn b/godot/scenes/main.tscn index 7468a23..9f38a26 100644 --- a/godot/scenes/main.tscn +++ b/godot/scenes/main.tscn @@ -12,3 +12,38 @@ mesh = SubResource("BoxMesh_m77kh") [node name="DirectionalLight3D" type="DirectionalLight3D" parent="." unique_id=75522463] transform = Transform3D(0.61237246, -0.5, 0.61237246, 0.3535534, 0.8660254, 0.3535534, -0.7071068, 0, 0.7071068, 0, 1, 2) + +[node name="CommandLinePanel" type="CommandLinePanel" parent="." unique_id=398519161 node_paths=PackedStringArray("input_field", "text_field", "scroll_container")] +input_field = NodePath("InputField") +text_field = NodePath("ScrollContainer/TextField") +scroll_container = NodePath("ScrollContainer") +anchors_preset = 10 +anchor_right = 1.0 +offset_bottom = 307.0 +grow_horizontal = 2 + +[node name="InputField" type="TextEdit" parent="CommandLinePanel" unique_id=485869737] +layout_mode = 1 +anchors_preset = 10 +anchor_right = 1.0 +offset_top = 307.0 +offset_bottom = 342.0 +grow_horizontal = 2 +text = "Hello there!" + +[node name="ScrollContainer" type="ScrollContainer" parent="CommandLinePanel" unique_id=910897176] +custom_minimum_size = Vector2(-1, 0) +layout_mode = 1 +anchors_preset = 10 +anchor_right = 1.0 +offset_left = 1.0 +offset_right = -1.0 +offset_bottom = 292.0 +grow_horizontal = 2 + +[node name="TextField" type="Label" parent="CommandLinePanel/ScrollContainer" unique_id=2111638471] +custom_minimum_size = Vector2(1150, 0) +custom_maximum_size = Vector2(1150, -1) +layout_mode = 2 +vertical_alignment = 2 +clip_text = true diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 7207166..b5cf20a 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1,5 +1,7 @@ use godot::prelude::*; +mod ui; + struct MyExtension; #[gdextension] @@ -14,7 +16,6 @@ struct NetworkManager { #[godot_api] impl INode for NetworkManager { fn init(base: Base) -> Self { - godot_print!("Hello, world!"); NetworkManager { base } } } diff --git a/rust/src/ui/cmd.rs b/rust/src/ui/cmd.rs new file mode 100644 index 0000000..7c7e63a --- /dev/null +++ b/rust/src/ui/cmd.rs @@ -0,0 +1,70 @@ +use godot::classes::ScrollContainer; +use godot::prelude::*; + +use godot::{ + classes::{IPanel, Label, Panel, TextEdit}, + global::godot_print, + obj::Base, + register::{GodotClass, godot_api}, +}; + +#[derive(GodotClass)] +#[class(base=Panel)] +struct CommandLinePanel { + #[export] + pub input_field: Option>, + #[export] + pub text_field: Option>, + #[export] + pub scroll_container: Option>, + + scroll_next_update: bool, + + base: Base, +} + +#[godot_api] +impl IPanel for CommandLinePanel { + fn init(base: Base) -> Self { + CommandLinePanel { + input_field: None, + text_field: None, + scroll_container: None, + scroll_next_update: false, + base, + } + } + + fn process(&mut self, _delta: f64) { + if let Some(scroll) = &mut self.scroll_container + && self.scroll_next_update + { + scroll.set_v_scroll(i32::MAX); + self.scroll_next_update = false; + } + + if let Some(input) = self.input_field.clone() { + let text = input.get_text(); + if text.contains("\n") { + let parts = text.split("\n"); + let first = parts.get(0).unwrap(); + self.publish_message(first.to_string()); + self.input_field.as_mut().unwrap().clear(); + self.scroll_next_update = true; + } + } + } +} + +impl CommandLinePanel { + pub fn publish_message(&mut self, message: String) { + if let Some(field) = &mut self.text_field { + let mut text = field.get_text().to_string(); + if !text.is_empty() { + text += "\n"; + } + text += &message; + field.set_text(&text); + } + } +} diff --git a/rust/src/ui/mod.rs b/rust/src/ui/mod.rs new file mode 100644 index 0000000..287551a --- /dev/null +++ b/rust/src/ui/mod.rs @@ -0,0 +1 @@ +mod cmd;