BallanceStalker/scripts/stages/ConsolePanel.cs

102 lines
3.5 KiB
C#

using Godot;
using System;
using System.Collections.Generic;
public enum LabelConsoleMessageType {
Normal,
Highlight,
Error
}
public class ConsolePanel : Control {
private LineEdit mCmdInput;
private ScrollContainer mScrollbar;
private VScrollBar mScrollbarVChild;
private VBoxContainer mMessageContainer;
private PackedScene mTemplateLabelConsole;
private Queue<LabelConsole> mMessageQueue = new Queue<LabelConsole>();
private readonly int QUEUE_MAX_SIZE = 100;
public override void _Ready() {
mTemplateLabelConsole = ResourceLoader.Load<PackedScene>("res://scenes/user_interface/LabelConsole.tscn");
mCmdInput = GetNode<LineEdit>("CommandInput");
mScrollbar = GetNode<ScrollContainer>("ScrollSet/Scrollbar");
mScrollbarVChild = mScrollbar.GetVScrollbar();
mMessageContainer = GetNode<VBoxContainer>("ScrollSet/Scrollbar/MessageContainer");
mCmdInput.Connect("text_entered", this, nameof(Proc_LineEdit_TextEntered));
mScrollbarVChild.Connect("changed", this, nameof(Proc_ScrollbarVChild_Changed));
BallanceStalkerCore.StalkerManager.Singleton.EventControllerChanged += Proc_StalkerManager_EventControllerChanged;
}
private void Proc_StalkerManager_EventControllerChanged(BallanceStalkerCore.EventControllerSource obj) {
if (obj == BallanceStalkerCore.EventControllerSource.Chat) {
this.Visible = true;
mCmdInput.GrabFocus();
} else if (obj == BallanceStalkerCore.EventControllerSource.Console) {
// same process of chat
// but only add a extra preset charcater in cmd input
this.Visible = true;
mCmdInput.Text = "/";
mCmdInput.CaretPosition = 1;
mCmdInput.GrabFocus();
} else {
this.Visible = false;
}
}
public override void _Input(InputEvent @event) {
if (!this.Visible) return;
if (@event.IsActionPressed("ballance_esc")) {
// clean input
mCmdInput.Text = "";
// back to camera
BallanceStalkerCore.StalkerManager.Singleton.SetEventController(BallanceStalkerCore.EventControllerSource.None);
// mark handled to prevent loop call
GetTree().SetInputAsHandled();
}
}
private void AddMessage(string strl, LabelConsoleMessageType t) {
LabelConsole target;
if (mMessageQueue.Count > QUEUE_MAX_SIZE) {
// popup last item and remove it from scene first
target = mMessageQueue.Dequeue();
mMessageContainer.RemoveChild(target);
} else {
target = mTemplateLabelConsole.Instance<LabelConsole>();
}
// add into scene and queue
mMessageQueue.Enqueue(target);
mMessageContainer.AddChild(target);
// set text
target.SetText(strl, t);
}
private void Proc_LineEdit_TextEntered(string new_strl) {
if (new_strl != string.Empty) {
// todo: finish cmd parse
if (new_strl.StartsWith("/")) {
AddMessage(new_strl, LabelConsoleMessageType.Highlight);
} else if (new_strl.StartsWith("!")) {
AddMessage(new_strl, LabelConsoleMessageType.Error);
} else {
AddMessage(new_strl, LabelConsoleMessageType.Normal);
}
// clean cmd
mCmdInput.Text = "";
}
}
private void Proc_ScrollbarVChild_Changed() {
mScrollbar.ScrollVertical = (int)mScrollbarVChild.MaxValue;
}
}