Client LuaCsForBarotrauma
BarotraumaClient/ClientSource/Items/Components/Signal/Terminal.cs
3 using Microsoft.Xna.Framework;
4 using System.Linq;
5 using System.Xml.Linq;
6 
8 {
9  partial class Terminal : ItemComponent, IClientSerializable, IServerSerializable
10  {
11  private readonly struct ClientEventData : IEventData
12  {
13  public readonly string Text;
14 
15  public ClientEventData(string text)
16  {
17  Text = text;
18  }
19  }
20 
21  private GUIListBox historyBox;
22  private GUITextBlock fillerBlock;
23  private GUITextBox inputBox;
24  private bool shouldSelectInputBox;
25 
26  partial void InitProjSpecific(XElement element)
27  {
28  float marginMultiplier = element.GetAttributeFloat("marginmultiplier", 1.0f);
29 
30  var layoutGroup = new GUILayoutGroup(new RectTransform(GuiFrame.Rect.Size - GUIStyle.ItemFrameMargin.Multiply(marginMultiplier), GuiFrame.RectTransform, Anchor.Center) { AbsoluteOffset = GUIStyle.ItemFrameOffset.Multiply(marginMultiplier) })
31  {
32  ChildAnchor = Anchor.TopCenter,
33  RelativeSpacing = 0.02f,
34  Stretch = true
35  };
36 
37  historyBox = new GUIListBox(new RectTransform(new Vector2(1, .9f), layoutGroup.RectTransform), style: null)
38  {
39  AutoHideScrollBar = this.AutoHideScrollbar
40  };
41 
42  if (!Readonly)
43  {
45 
46  new GUIFrame(new RectTransform(new Vector2(0.9f, 0.01f), layoutGroup.RectTransform), style: "HorizontalLine");
47 
48  inputBox = new GUITextBox(new RectTransform(new Vector2(1, .1f), layoutGroup.RectTransform), textColor: TextColor)
49  {
50  MaxTextLength = MaxMessageLength,
51  OverflowClip = true,
52  OnEnterPressed = (GUITextBox textBox, string text) =>
53  {
54  if (GameMain.NetworkMember == null)
55  {
56  SendOutput(text);
57  }
58  else
59  {
60  item.CreateClientEvent(this, new ClientEventData(text));
61  }
62  textBox.Text = string.Empty;
63  return true;
64  }
65  };
66  }
67 
68  layoutGroup.Recalculate();
69  }
70 
71  // Create fillerBlock to cover historyBox so new values appear at the bottom of historyBox
72  // This could be removed if GUIListBox supported aligning its children
73  public void CreateFillerBlock()
74  {
75  fillerBlock = new GUITextBlock(new RectTransform(new Vector2(1, 1), historyBox.Content.RectTransform, anchor: Anchor.TopCenter), string.Empty)
76  {
77  CanBeFocused = false
78  };
79  }
80 
81  private void SendOutput(string input)
82  {
83  if (input.Length > MaxMessageLength)
84  {
85  input = input.Substring(0, MaxMessageLength);
86  }
87 
88  OutputValue = input;
89  ShowOnDisplay(input, addToHistory: true, TextColor, isWelcomeMessage: false);
90  item.SendSignal(input, "signal_out");
91  }
92 
93  partial void ShowOnDisplay(string input, bool addToHistory, Color color, bool isWelcomeMessage)
94  {
95  if (addToHistory)
96  {
97  messageHistory.Add(new TerminalMessage(input, color, isWelcomeMessage));
98  while (messageHistory.Count > MaxMessages)
99  {
100  messageHistory.RemoveAt(0);
101  }
102  while (historyBox.Content.CountChildren > MaxMessages)
103  {
104  historyBox.RemoveChild(historyBox.Content.Children.First());
105  }
106  }
107 
108  GUITextBlock newBlock = new GUITextBlock(
109  new RectTransform(new Vector2(1, 0), historyBox.Content.RectTransform, anchor: Anchor.TopCenter),
110  LineStartSymbol + TextManager.Get(input).Fallback(input),
111  textColor: color, wrap: true, font: UseMonospaceFont ? GUIStyle.MonospacedFont : GUIStyle.Font)
112  {
113  CanBeFocused = false
114  };
115 
116  if (fillerBlock != null)
117  {
118  float y = fillerBlock.RectTransform.RelativeSize.Y - newBlock.RectTransform.RelativeSize.Y;
119  if (y > 0)
120  {
121  fillerBlock.RectTransform.RelativeSize = new Vector2(1, y);
122  }
123  else
124  {
125  historyBox.RemoveChild(fillerBlock);
126  fillerBlock = null;
127  }
128  }
129 
130  historyBox.RecalculateChildren();
131  historyBox.UpdateScrollBarSize();
132  if (AutoScrollToBottom)
133  {
134  historyBox.ScrollBar.BarScrollValue = 1;
135  }
136  }
137 
138  public override bool Select(Character character)
139  {
140  shouldSelectInputBox = true;
141  return base.Select(character);
142  }
143 
144  // This method is overrided instead of the UpdateHUD method because this ensures the input box is selected
145  // even when the terminal component is selected for the very first time. Doing the input box selection in the
146  // UpdateHUD method only selects the input box on every terminal selection except for the very first time.
147  public override void AddToGUIUpdateList(int order = 0)
148  {
149  base.AddToGUIUpdateList(order: order);
150  if (shouldSelectInputBox && !Readonly)
151  {
152  inputBox.Select();
153  shouldSelectInputBox = false;
154  }
155  }
156 
157  public void ClientEventWrite(IWriteMessage msg, NetEntityEvent.IData extraData = null)
158  {
159  if (TryExtractEventData(extraData, out ClientEventData eventData))
160  {
161  msg.WriteString(eventData.Text);
162  }
163  }
164 
165  public void ClientEventRead(IReadMessage msg, float sendingTime)
166  {
167  SendOutput(msg.ReadString());
168  }
169  }
170 }
virtual Rectangle Rect
RectTransform RectTransform
void SendSignal(string signal, string connectionName)
void ClientEventWrite(IWriteMessage msg, NetEntityEvent.IData extraData=null)
Interface for entities that the clients can send events to the server
Interface for entities that the server can send events to the clients