diff --git a/demo/.idea/.idea.SofiaConsole/.idea/vcs.xml b/demo/.idea/.idea.SofiaConsole/.idea/vcs.xml
index 94a25f7..288b36b 100644
--- a/demo/.idea/.idea.SofiaConsole/.idea/vcs.xml
+++ b/demo/.idea/.idea.SofiaConsole/.idea/vcs.xml
@@ -1,6 +1,7 @@
+
\ No newline at end of file
diff --git a/demo/SofiaConsole.csproj b/demo/SofiaConsole.csproj
index 8ee8c44..578eae2 100644
--- a/demo/SofiaConsole.csproj
+++ b/demo/SofiaConsole.csproj
@@ -1,4 +1,4 @@
-
+
net6.0
true
diff --git a/demo/addons/sofiaconsole/Console.cs b/demo/addons/sofiaconsole/Console.cs
index 55b07c3..3e893e7 100644
--- a/demo/addons/sofiaconsole/Console.cs
+++ b/demo/addons/sofiaconsole/Console.cs
@@ -16,9 +16,12 @@ public partial class Console : Node
public static Console Instance;
public List Commands = new();
private readonly List _commandHistory = new();
+ private List _suggestions = new List();
+ private int _currentSuggestionIndex = -1;
public bool Open;
+ [Export] private int _maxSuggestions = 15;
[Export] private CanvasLayer _consoleCanvas;
[Export] private Panel _background;
[Export] private Button _closeButton;
@@ -26,6 +29,8 @@ public partial class Console : Node
[Export] private Button _commandSendButton;
[Export] private ScrollContainer _historyScrollContainer;
[Export] private VBoxContainer _historyContent;
+ [Export] private VBoxContainer _suggestionsContent;
+ [Export] private PanelContainer _suggestionsPanel;
public override void _EnterTree()
{
@@ -36,13 +41,19 @@ public override void _EnterTree()
_closeButton.Pressed += () => { SetConsole(false); };
_commandSendButton.Pressed += () => { ProcessCommand(_commandInput.Text); };
- _commandInput.TextSubmitted += ProcessCommand;
+ _commandInput.TextSubmitted += (t) =>
+ {
+ ProcessCommand(t);
+ UpdateUi(true);
+ };
LoadCommands();
Print("[SofiaConsole] Version 1.2.0", PrintType.Success);
Space();
+ GenerateSuggestionsNode();
+
GD.Print("[SofiaConsole] Done");
}
@@ -63,22 +74,61 @@ public override void _Input(InputEvent @event)
{
ToggleConsole();
}
-
- // Press Up to toggle between previous commands
- if (eventKey.Keycode == Key.Up && _commandInput.HasFocus() && _commandHistory.Count > 0)
+
+ if (eventKey.Keycode == Key.Down && _commandInput.HasFocus() && _suggestions.Count > 0)
+ {
+ _currentSuggestionIndex = (_currentSuggestionIndex + 1) % _suggestions.Count;
+ }
+ else if (eventKey.Keycode == Key.Up && _commandInput.HasFocus() && _suggestions.Count > 0)
+ {
+ _currentSuggestionIndex = (_currentSuggestionIndex - 1) % _suggestions.Count;
+ if (_currentSuggestionIndex < 0)
+ _currentSuggestionIndex = _suggestions.Count - 1;
+ }
+ else if (eventKey.Keycode == Key.Tab || eventKey.Keycode == Key.Enter && _commandInput.HasFocus() && _suggestions.Count > 0 && _currentSuggestionIndex < _suggestions.Count)
{
- var historyIndex = _commandHistory.FindIndex(x => x == _commandInput.Text);
- if (historyIndex == -1)
+ if (_suggestions.Count > 0 && _currentSuggestionIndex >= 0)
{
- historyIndex = _commandHistory.Count;
+ _commandInput.Text = "";
+ _commandInput.InsertTextAtCaret(_suggestions[_currentSuggestionIndex]);
+ _commandInput.GrabFocus();
}
+ }
+ }
+
+ if (@event is InputEventKey inputEventKey)
+ {
+ string inputText = _commandInput.Text;
+
+ if (inputText.Trim() == "")
+ {
+ _suggestions.Clear();
- if (historyIndex == 0)
+ // Press Up to toggle between previous commands
+ if (inputEventKey.Keycode == Key.Up && _commandInput.HasFocus() && _commandHistory.Count > 0)
{
- historyIndex = _commandHistory.Count;
+ var historyIndex = _commandHistory.FindIndex(x => x == _commandInput.Text);
+ if (historyIndex == -1)
+ {
+ historyIndex = _commandHistory.Count;
+ }
+
+ if (historyIndex == 0)
+ {
+ historyIndex = _commandHistory.Count;
+ }
+
+ _commandInput.Text = _commandHistory[historyIndex - 1];
}
-
- _commandInput.Text = _commandHistory[historyIndex - 1];
+ }
+ else
+ {
+ // Filter suggestions
+ _suggestions = Commands
+ .Where(cmd => cmd.Command.StartsWith(inputText))
+ .OrderBy(cmd => cmd.Command.IndexOf(inputText, StringComparison.CurrentCulture))
+ .Select(cmd => cmd.Command)
+ .ToList();
}
}
@@ -88,6 +138,71 @@ public override void _Input(InputEvent @event)
_commandInput.ReleaseFocus();
_commandSendButton.ReleaseFocus();
}
+
+ UpdateUi();
+ }
+
+ // Generate suggestions node when enter tree, to improve performance.
+ private void GenerateSuggestionsNode()
+ {
+ for (int i = 0; i < _maxSuggestions; i++)
+ {
+ var newLabel = new Label
+ {
+ Text = "",
+ Theme = new Theme
+ {
+ DefaultFontSize = 30
+ }
+ };
+
+ _suggestionsContent.AddChild(newLabel);
+ newLabel.Hide();
+ }
+ }
+
+ private void UpdateUi(bool close = false)
+ {
+ if (!Open) return;
+ if (close) return;
+
+ foreach (var node in _suggestionsContent.GetChildren())
+ {
+ if (node is Label label)
+ {
+ label.Hide();
+ }
+ }
+
+ if (_suggestions.Count == 0)
+ {
+ _suggestionsPanel.Hide();
+ return;
+ }
+
+ _suggestionsPanel.Show();
+
+ for (int i = 0; i < Mathf.Min(_maxSuggestions, _suggestions.Count); i++)
+ {
+ Label suggestionLabel = _suggestionsContent.GetChild(i) as Label;
+ if (suggestionLabel == null) continue;
+
+ suggestionLabel.Text = _suggestions[i];
+ suggestionLabel.Show();
+
+ if (_currentSuggestionIndex >= 0 && _suggestions.Count > 0 &&
+ _currentSuggestionIndex < _suggestions.Count &&
+ _suggestions[_currentSuggestionIndex] == _suggestions[i])
+ {
+ // Background color for selected suggestion
+ suggestionLabel.AddThemeStyleboxOverride("normal", GD.Load("res://addons/sofiaconsole/SelectedSuggestion.tres"));
+ }
+ else
+ {
+ // Background color for suggestion
+ suggestionLabel.RemoveThemeStyleboxOverride("normal");
+ }
+ }
}
public void ToggleConsole()
@@ -101,7 +216,8 @@ private void SetConsole(bool open)
_consoleCanvas.Visible = Open;
_background.MouseFilter = Open ? Control.MouseFilterEnum.Stop : Control.MouseFilterEnum.Ignore;
-
+ GetTree().Paused = Open;
+
if (Open)
{
_commandInput.GrabFocus();
@@ -229,7 +345,7 @@ public async void Print(string text, PrintType type = PrintType.Default)
Text = text,
Theme = new Theme
{
- DefaultFontSize = 12
+ DefaultFontSize = 30
}
};
diff --git a/demo/addons/sofiaconsole/Console.tscn b/demo/addons/sofiaconsole/Console.tscn
index 377c501..03e0fc0 100644
--- a/demo/addons/sofiaconsole/Console.tscn
+++ b/demo/addons/sofiaconsole/Console.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=13 format=3 uid="uid://dyya4j4ywm1k6"]
+[gd_scene load_steps=14 format=3 uid="uid://dyya4j4ywm1k6"]
[ext_resource type="Script" path="res://addons/sofiaconsole/Console.cs" id="1_dw41g"]
[ext_resource type="Script" path="res://addons/sofiaconsole/Commands/FpsCounterCommand.cs" id="2_nkfel"]
@@ -39,6 +39,9 @@ content_margin_right = 10.0
content_margin_bottom = 10.0
bg_color = Color(0.133333, 0.133333, 0.133333, 0)
+[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_wpanm"]
+bg_color = Color(0.0900985, 0.0900985, 0.0900985, 1)
+
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_25al0"]
content_margin_left = 10.0
content_margin_top = 10.0
@@ -58,15 +61,18 @@ outline_color = Color(0, 0, 0, 1)
shadow_size = 5
shadow_color = Color(0, 0, 0, 1)
-[node name="Console" type="Node" node_paths=PackedStringArray("_consoleCanvas", "_background", "_closeButton", "_commandInput", "_commandSendButton", "_historyScrollContainer", "_historyContent")]
+[node name="Console" type="Node" node_paths=PackedStringArray("_consoleCanvas", "_background", "_closeButton", "_commandInput", "_commandSendButton", "_historyScrollContainer", "_historyContent", "_suggestionsContent", "_suggestionsPanel")]
+process_mode = 3
script = ExtResource("1_dw41g")
_consoleCanvas = NodePath("ConsoleCanvas")
_background = NodePath("ConsoleCanvas/Background")
-_closeButton = NodePath("ConsoleCanvas/Background/Window/Content/Header/HBoxContainer/CloseButton")
-_commandInput = NodePath("ConsoleCanvas/Background/Window/Content/Input/HBoxContainer/CommandInput")
-_commandSendButton = NodePath("ConsoleCanvas/Background/Window/Content/Input/HBoxContainer/CommandSendButton")
-_historyScrollContainer = NodePath("ConsoleCanvas/Background/Window/Content/History/ScrollContainer")
-_historyContent = NodePath("ConsoleCanvas/Background/Window/Content/History/ScrollContainer/Content")
+_closeButton = NodePath("ConsoleCanvas/Background/MarginContainer/Window/Content/Header/HBoxContainer/CloseButton")
+_commandInput = NodePath("ConsoleCanvas/Background/MarginContainer/Window/Content/Input/HBoxContainer/CommandInput")
+_commandSendButton = NodePath("ConsoleCanvas/Background/MarginContainer/Window/Content/Input/HBoxContainer/CommandSendButton")
+_historyScrollContainer = NodePath("ConsoleCanvas/Background/MarginContainer/Window/Content/History/ScrollContainer")
+_historyContent = NodePath("ConsoleCanvas/Background/MarginContainer/Window/Content/History/ScrollContainer/Content")
+_suggestionsContent = NodePath("ConsoleCanvas/Background/MarginContainer/Window/Content/History/SuggestionsPanel/Suggestions/Suggestions")
+_suggestionsPanel = NodePath("ConsoleCanvas/Background/MarginContainer/Window/Content/History/SuggestionsPanel")
[node name="ConsoleCanvas" type="CanvasLayer" parent="."]
layer = 128
@@ -81,23 +87,24 @@ grow_vertical = 2
mouse_filter = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_cvk4f")
-[node name="Window" type="Panel" parent="ConsoleCanvas/Background"]
-custom_minimum_size = Vector2(600, 400)
+[node name="MarginContainer" type="MarginContainer" parent="ConsoleCanvas/Background"]
layout_mode = 1
-anchors_preset = 8
-anchor_left = 0.5
-anchor_top = 0.5
-anchor_right = 0.5
-anchor_bottom = 0.5
-offset_left = -350.0
-offset_top = -250.0
-offset_right = 350.0
-offset_bottom = 250.0
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
+theme_override_constants/margin_left = 50
+theme_override_constants/margin_top = 50
+theme_override_constants/margin_right = 50
+theme_override_constants/margin_bottom = 50
+
+[node name="Window" type="Panel" parent="ConsoleCanvas/Background/MarginContainer"]
+custom_minimum_size = Vector2(600, 400)
+layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_lpjvy")
-[node name="Content" type="VBoxContainer" parent="ConsoleCanvas/Background/Window"]
+[node name="Content" type="VBoxContainer" parent="ConsoleCanvas/Background/MarginContainer/Window"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
@@ -106,63 +113,87 @@ grow_horizontal = 2
grow_vertical = 2
theme_override_constants/separation = 0
-[node name="Header" type="PanelContainer" parent="ConsoleCanvas/Background/Window/Content"]
+[node name="Header" type="PanelContainer" parent="ConsoleCanvas/Background/MarginContainer/Window/Content"]
+custom_minimum_size = Vector2(0, 80)
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_t5a6w")
-[node name="HBoxContainer" type="HBoxContainer" parent="ConsoleCanvas/Background/Window/Content/Header"]
+[node name="HBoxContainer" type="HBoxContainer" parent="ConsoleCanvas/Background/MarginContainer/Window/Content/Header"]
layout_mode = 2
theme_override_constants/separation = 15
alignment = 1
-[node name="Label" type="Label" parent="ConsoleCanvas/Background/Window/Content/Header/HBoxContainer"]
+[node name="Label" type="Label" parent="ConsoleCanvas/Background/MarginContainer/Window/Content/Header/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
+theme_override_font_sizes/font_size = 40
text = "Console"
-[node name="CloseButton" type="Button" parent="ConsoleCanvas/Background/Window/Content/Header/HBoxContainer"]
+[node name="CloseButton" type="Button" parent="ConsoleCanvas/Background/MarginContainer/Window/Content/Header/HBoxContainer"]
custom_minimum_size = Vector2(65, 0)
layout_mode = 2
size_flags_horizontal = 8
+focus_mode = 0
text = "Close"
-[node name="History" type="PanelContainer" parent="ConsoleCanvas/Background/Window/Content"]
+[node name="History" type="PanelContainer" parent="ConsoleCanvas/Background/MarginContainer/Window/Content"]
layout_mode = 2
size_flags_vertical = 3
theme_override_styles/panel = SubResource("StyleBoxFlat_rquom")
-[node name="ScrollContainer" type="ScrollContainer" parent="ConsoleCanvas/Background/Window/Content/History"]
+[node name="ScrollContainer" type="ScrollContainer" parent="ConsoleCanvas/Background/MarginContainer/Window/Content/History"]
layout_mode = 2
size_flags_vertical = 3
theme_override_styles/panel = SubResource("StyleBoxFlat_fbsm3")
horizontal_scroll_mode = 0
vertical_scroll_mode = 2
-[node name="Content" type="VBoxContainer" parent="ConsoleCanvas/Background/Window/Content/History/ScrollContainer"]
+[node name="Content" type="VBoxContainer" parent="ConsoleCanvas/Background/MarginContainer/Window/Content/History/ScrollContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_constants/separation = 0
-[node name="Input" type="PanelContainer" parent="ConsoleCanvas/Background/Window/Content"]
+[node name="SuggestionsPanel" type="PanelContainer" parent="ConsoleCanvas/Background/MarginContainer/Window/Content/History"]
+visible = false
+layout_mode = 2
+theme_override_styles/panel = SubResource("StyleBoxFlat_wpanm")
+
+[node name="Suggestions" type="ScrollContainer" parent="ConsoleCanvas/Background/MarginContainer/Window/Content/History/SuggestionsPanel"]
+layout_mode = 2
+theme_override_styles/panel = SubResource("StyleBoxFlat_fbsm3")
+horizontal_scroll_mode = 0
+vertical_scroll_mode = 2
+
+[node name="Suggestions" type="VBoxContainer" parent="ConsoleCanvas/Background/MarginContainer/Window/Content/History/SuggestionsPanel/Suggestions"]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+theme_override_constants/separation = 0
+alignment = 2
+
+[node name="Input" type="PanelContainer" parent="ConsoleCanvas/Background/MarginContainer/Window/Content"]
layout_mode = 2
size_flags_vertical = 8
theme_override_styles/panel = SubResource("StyleBoxFlat_25al0")
-[node name="HBoxContainer" type="HBoxContainer" parent="ConsoleCanvas/Background/Window/Content/Input"]
+[node name="HBoxContainer" type="HBoxContainer" parent="ConsoleCanvas/Background/MarginContainer/Window/Content/Input"]
custom_minimum_size = Vector2(0, 40)
layout_mode = 2
theme_override_constants/separation = 15
-[node name="CommandInput" type="LineEdit" parent="ConsoleCanvas/Background/Window/Content/Input/HBoxContainer"]
+[node name="CommandInput" type="LineEdit" parent="ConsoleCanvas/Background/MarginContainer/Window/Content/Input/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
+theme_override_font_sizes/font_size = 40
placeholder_text = "Enter \"help\" for a list of commands"
flat = true
+caret_blink = true
-[node name="CommandSendButton" type="Button" parent="ConsoleCanvas/Background/Window/Content/Input/HBoxContainer"]
+[node name="CommandSendButton" type="Button" parent="ConsoleCanvas/Background/MarginContainer/Window/Content/Input/HBoxContainer"]
custom_minimum_size = Vector2(80, 0)
layout_mode = 2
size_flags_horizontal = 8
+focus_mode = 0
text = "Send"
[node name="BuiltinCommands" type="Node" parent="."]
diff --git a/demo/addons/sofiaconsole/SelectedSuggestion.tres b/demo/addons/sofiaconsole/SelectedSuggestion.tres
new file mode 100644
index 0000000..379b751
--- /dev/null
+++ b/demo/addons/sofiaconsole/SelectedSuggestion.tres
@@ -0,0 +1,10 @@
+[gd_resource type="StyleBoxFlat" format=3 uid="uid://b2ac5b6b26qbc"]
+
+[resource]
+bg_color = Color(0.300523, 0.695688, 0.398018, 1)
+border_width_left = 5
+border_color = Color(0.301961, 0.694118, 0.396078, 1)
+corner_radius_top_left = 5
+corner_radius_top_right = 5
+corner_radius_bottom_right = 5
+corner_radius_bottom_left = 5
diff --git a/demo/models/gdbot/gdbot.glb.import b/demo/models/gdbot/gdbot.glb.import
index 8aee40d..34bd0da 100644
--- a/demo/models/gdbot/gdbot.glb.import
+++ b/demo/models/gdbot/gdbot.glb.import
@@ -22,6 +22,7 @@ meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
+meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
@@ -9027,4 +9028,5 @@ _subresources={
}
}
}
+gltf/naming_version=0
gltf/embedded_image_handling=3
diff --git a/demo/models/gdbot/materials/heart_core_mat.tres b/demo/models/gdbot/materials/heart_core_mat.tres
index 9a20dfe..49eff02 100644
--- a/demo/models/gdbot/materials/heart_core_mat.tres
+++ b/demo/models/gdbot/materials/heart_core_mat.tres
@@ -4,4 +4,4 @@
albedo_color = Color(0, 0, 0, 1)
emission_enabled = true
emission = Color(0, 1, 0.392157, 1)
-emission_energy_multiplier = 2.25453
+emission_energy_multiplier = 2.26158
diff --git a/demo/project.godot b/demo/project.godot
index e7791e7..19631f8 100644
--- a/demo/project.godot
+++ b/demo/project.godot
@@ -12,7 +12,7 @@ config_version=5
config/name="SofiaConsole"
run/main_scene="res://demo.tscn"
-config/features=PackedStringArray("4.1", "C#", "Forward Plus")
+config/features=PackedStringArray("4.2", "C#", "Forward Plus")
config/icon="res://icon.svg"
[autoload]