From 3e65bf26fd69ed5cd9ed9c49b20ab5182c098430 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 4 Jul 2017 09:52:49 -0400 Subject: [PATCH] Port over the Terminal --- ShiftOS.Frontend/Apps/Terminal.cs | 183 ++++++++++++++---- ShiftOS.Frontend/Desktop/WindowManager.cs | 48 +++++ ShiftOS.Frontend/GUI/TextInput.cs | 4 +- .../GraphicsSubsystem/UIManager.cs | 2 +- ShiftOS.Frontend/ShiftOS.cs | 64 +----- ShiftOS_TheReturn/Shiftorium.cs | 2 +- 6 files changed, 204 insertions(+), 99 deletions(-) diff --git a/ShiftOS.Frontend/Apps/Terminal.cs b/ShiftOS.Frontend/Apps/Terminal.cs index 22e0d12..f3aeaf1 100644 --- a/ShiftOS.Frontend/Apps/Terminal.cs +++ b/ShiftOS.Frontend/Apps/Terminal.cs @@ -1,9 +1,12 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Drawing; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; +using Microsoft.Xna.Framework.Input; using ShiftOS.Engine; using ShiftOS.Frontend.GraphicsSubsystem; using static ShiftOS.Engine.SkinEngine; @@ -58,11 +61,17 @@ namespace ShiftOS.Frontend.Apps public class TerminalControl : GUI.TextInput, ITerminalWidget { + public TerminalControl() + { + Dock = GUI.DockStyle.Fill; + + } + public string[] Lines { get { - return Text.Split(new[] { "\n" }, StringSplitOptions.None); + return Text.Split(new[] { "\r\n" }, StringSplitOptions.None); } } @@ -87,8 +96,8 @@ namespace ShiftOS.Frontend.Apps { Engine.Desktop.InvokeOnWorkerThread(() => { + Text += text; SelectBottom(); - Text = Text.Insert(Index, text); Index += text.Length; RecalculateLayout(); InvalidateTopLevel(); @@ -126,66 +135,168 @@ namespace ShiftOS.Frontend.Apps { var cursorpos = GetPointAtIndex(gfx); var caretSize = gfx.SmartMeasureString(Text.ToString(), LoadedSkin.TerminalFont, Width - 4); - float initial = ((caretSize.Height) - cursorpos.Y) - _vertOffset; + float initial = (((float)Math.Floor(caretSize.Height)) + cursorpos.Y) - _vertOffset; if (initial < 0) { float difference = initial - Height; - _vertOffset += initial + difference; + _vertOffset = initial + difference; } if (initial > Height) { float difference = initial - Height; - _vertOffset -= initial - difference; + _vertOffset = initial - difference; } } } + protected override void OnLayout() + { + + } + /// /// Gets the X and Y coordinates (in pixels) of the caret. /// /// A object used for font measurements /// An absolute fucking mess. Seriously, can someone fix this method so it uhh WORKS PROPERLY? - public PointF GetPointAtIndex(Graphics gfx) + public Point GetPointAtIndex(Graphics gfx) { - float vertMeasure = 2.0f; - float horizMeasure = 2.0f; - int lineindexes = 0; - for (int l = 0; l <= GetCurrentLine(); l++) - { - var measure = gfx.SmartMeasureString(Lines[l], LoadedSkin.TerminalFont, Width - 4); - vertMeasure += measure.Width; - if(l == GetCurrentLine()) + int vertMeasure = 2; + int horizMeasure = 2; + var textSize = gfx.SmartMeasureString(Text, LoadedSkin.TerminalFont, Width - 4); + for(int i = 0; i <= Index && i < Text.Length; i++) + { + var size = gfx.SmartMeasureString((Text[i] == '\n') ? " " : Text[i].ToString(), LoadedSkin.TerminalFont); + if (Text[i] == '\n' || horizMeasure > Width - 4) { - string _linetext = Text.Substring(lineindexes, Index - lineindexes); - var lMeasure = gfx.SmartMeasureString(_linetext, LoadedSkin.TerminalFont); - horizMeasure = lMeasure.Width; - if (horizMeasure > Width - 4) - horizMeasure -= (Width-4); - } - else - { - lineindexes += Lines[l].Length; + horizMeasure = 2; + vertMeasure += (int)Math.Ceiling(size.Height); + continue; } + + horizMeasure += (int)Math.Floor(size.Width); } - return new PointF(horizMeasure, vertMeasure); + return new Point(horizMeasure, vertMeasure); } - protected override void OnKeyEvent(KeyEvent e) + protected override void OnKeyEvent(KeyEvent a) { - if (e.Key == Microsoft.Xna.Framework.Input.Keys.Enter) + if (a.Key == Keys.Enter) { - Text = Text.Insert(Index, "\r\n"); - Index++; + try + { + if (!TerminalBackend.PrefixEnabled) + { + string textraw = Lines[Lines.Length - 1]; + TerminalBackend.SendText(textraw); + return; + } + var text = Lines; + var text2 = text[text.Length - 1]; + var text3 = ""; + var text4 = Regex.Replace(text2, @"\t|\n|\r", ""); + + { + if (TerminalBackend.PrefixEnabled) + { + text3 = text4.Remove(0, $"{SaveSystem.CurrentUser.Username}@{SaveSystem.CurrentSave.SystemName}:~$ ".Length); + } + TerminalBackend.LastCommand = text3; + TerminalBackend.SendText(text4); + if (TerminalBackend.InStory == false) + { + { + var result = SkinEngine.LoadedSkin.CurrentParser.ParseCommand(text3); + + if (result.Equals(default(KeyValuePair>))) + { + Console.WriteLine("{ERR_SYNTAXERROR}"); + } + else + { + TerminalBackend.InvokeCommand(result.Key, result.Value); + } + + } + } + if (TerminalBackend.PrefixEnabled) + { + TerminalBackend.PrintPrompt(); + } + } + } + catch + { + } + } + else if (a.Key == Keys.Back) + { + try + { + var tostring3 = Lines[Lines.Length - 1]; + var tostringlen = tostring3.Length + 1; + var workaround = $"{SaveSystem.CurrentUser.Username}@{SaveSystem.CurrentSave.SystemName}:~$ "; + var derp = workaround.Length + 1; + if (tostringlen != derp) + { + AppearanceManager.CurrentPosition--; + base.OnKeyEvent(a); + RecalculateLayout(); + InvalidateTopLevel(); + } + } + catch + { + Debug.WriteLine("Drunky alert in terminal."); + } + } + else if (a.Key == Keys.Left) + { + if (SaveSystem.CurrentSave != null) + { + var getstring = Lines[Lines.Length - 1]; + var stringlen = getstring.Length + 1; + var header = $"{SaveSystem.CurrentUser.Username}@{SaveSystem.CurrentSave.SystemName}:~$ "; + var headerlen = header.Length + 1; + var selstart = Index; + var remstrlen = Text.Length - stringlen; + var finalnum = selstart - remstrlen; + + if (finalnum != headerlen) + { + AppearanceManager.CurrentPosition--; + base.OnKeyEvent(a); + } + } + } + else if (a.Key == Keys.Up) + { + var tostring3 = Lines[Lines.Length - 1]; + if (tostring3 == $"{SaveSystem.CurrentUser.Username}@{SaveSystem.CurrentSave.SystemName}:~$ ") + Console.Write(TerminalBackend.LastCommand); + ConsoleEx.OnFlush?.Invoke(); + return; + + } + else + { + if (TerminalBackend.InStory) + { + return; + } + if (a.KeyChar != '\0') + { + base.OnKeyEvent(a); + AppearanceManager.CurrentPosition++; + RecalculateLayout(); + InvalidateTopLevel(); + } } - base.OnKeyEvent(e); - RecalculateLayout(); - InvalidateTopLevel(); } protected override void OnPaint(Graphics gfx) - { - RecalculateLayout(); + { gfx.Clear(LoadedSkin.TerminalBackColorCC.ToColor()); if (!string.IsNullOrEmpty(Text)) { @@ -257,7 +368,8 @@ namespace ShiftOS.Frontend.Apps var textformat = new StringFormat(StringFormat.GenericTypographic); textformat.FormatFlags = StringFormatFlags.MeasureTrailingSpaces; textformat.Trimming = StringTrimming.None; - return gfx.MeasureString(s, font, width, textformat); + var measure = gfx.MeasureString(s, font, width, textformat); + return new SizeF((float)Math.Floor(measure.Width), (float)Math.Floor(measure.Height)); } public static SizeF SmartMeasureString(this Graphics gfx, string s, Font font) @@ -267,7 +379,8 @@ namespace ShiftOS.Frontend.Apps var textformat = new StringFormat(StringFormat.GenericTypographic); textformat.FormatFlags = StringFormatFlags.MeasureTrailingSpaces; textformat.Trimming = StringTrimming.None; - return gfx.MeasureString(s, font, int.MaxValue, textformat); + var measure = gfx.MeasureString(s, font, int.MaxValue, textformat); + return new SizeF((float)Math.Floor(measure.Width), (float)Math.Floor(measure.Height)); } } diff --git a/ShiftOS.Frontend/Desktop/WindowManager.cs b/ShiftOS.Frontend/Desktop/WindowManager.cs index 4f99a05..1fa5cfb 100644 --- a/ShiftOS.Frontend/Desktop/WindowManager.cs +++ b/ShiftOS.Frontend/Desktop/WindowManager.cs @@ -60,6 +60,20 @@ namespace ShiftOS.Frontend.Desktop win.OnSkinLoad(); } + private int MaxCount + { + get + { + if (Shiftorium.UpgradeInstalled("wm_unlimited_windows")) + return int.MaxValue; + if (Shiftorium.UpgradeInstalled("wm_4_windows")) + return 4; + if (Shiftorium.UpgradeInstalled("wm_2_windows")) + return 2; + return 1; + } + } + public override void SetupWindow(IShiftOSWindow win) { if (!Shiftorium.UpgradeAttributesUnlocked(win.GetType())) @@ -67,6 +81,11 @@ namespace ShiftOS.Frontend.Desktop Console.WriteLine("Application not found on system."); return; } + while(AppearanceManager.OpenForms.Count > MaxCount) + { + AppearanceManager.OpenForms[0].Close(); + AppearanceManager.OpenForms.RemoveAt(0); + } var wb = new WindowBorder(); wb.Width = (win as GUI.Control).Width + LoadedSkin.LeftBorderWidth + LoadedSkin.RightBorderWidth; wb.Height = (win as GUI.Control).Height + LoadedSkin.TitlebarHeight + LoadedSkin.BottomBorderWidth; @@ -78,7 +97,23 @@ namespace ShiftOS.Frontend.Desktop win.OnLoad(); win.OnUpgrade(); win.OnSkinLoad(); + if (!Shiftorium.UpgradeInstalled("wm_free_placement")) + { + TileWindows(); + } + } + public void TileWindows() + { + if (AppearanceManager.OpenForms.Count == 0) + return; + else if(AppearanceManager.OpenForms.Count == 1) + { + var wb = (WindowBorder)AppearanceManager.OpenForms[0]; + wb.X = 0; + wb.Y = 0; + wb.ResizeWindow(UIManager.Viewport.Width, UIManager.Viewport.Height); + } } } @@ -87,6 +122,19 @@ namespace ShiftOS.Frontend.Desktop private string _text = "ShiftOS window"; private GUI.Control _hostedwindow = null; + public void ResizeWindow(int width, int height) + { + int titleheight = Shiftorium.UpgradeInstalled("wm_titlebar") ? LoadedSkin.TitlebarHeight : 0; + int leftwidth = Shiftorium.UpgradeInstalled("window_borders") ? LoadedSkin.LeftBorderWidth : 0; + int bottomheight = Shiftorium.UpgradeInstalled("window_borders") ? LoadedSkin.BottomBorderWidth : 0; + int rightwidth = Shiftorium.UpgradeInstalled("window_borders") ? LoadedSkin.RightBorderWidth : 0; + _hostedwindow.Width = width - leftwidth - rightwidth; + _hostedwindow.Height = width - bottomheight - titleheight; + Width = width; + Height = height; + + } + public WindowBorder() { X = 720; diff --git a/ShiftOS.Frontend/GUI/TextInput.cs b/ShiftOS.Frontend/GUI/TextInput.cs index c4e5260..13ee596 100644 --- a/ShiftOS.Frontend/GUI/TextInput.cs +++ b/ShiftOS.Frontend/GUI/TextInput.cs @@ -32,9 +32,7 @@ namespace ShiftOS.Frontend.GUI _index = 0; return; } - _index = MathHelper.Clamp(value, 0, _text.Length - 1); - if (_text[_index] == '\n') - _index++; + _index = MathHelper.Clamp(value, 0, _text.Length); Invalidate(); } } diff --git a/ShiftOS.Frontend/GraphicsSubsystem/UIManager.cs b/ShiftOS.Frontend/GraphicsSubsystem/UIManager.cs index bb62ea4..b87dd32 100644 --- a/ShiftOS.Frontend/GraphicsSubsystem/UIManager.cs +++ b/ShiftOS.Frontend/GraphicsSubsystem/UIManager.cs @@ -16,7 +16,7 @@ namespace ShiftOS.Frontend.GraphicsSubsystem public static class UIManager { private static List topLevels = new List(); - + public static System.Drawing.Size Viewport { get; set; } public static GUI.Control FocusedControl = null; public static void LayoutUpdate() diff --git a/ShiftOS.Frontend/ShiftOS.cs b/ShiftOS.Frontend/ShiftOS.cs index fd3d784..9d7d503 100644 --- a/ShiftOS.Frontend/ShiftOS.cs +++ b/ShiftOS.Frontend/ShiftOS.cs @@ -22,6 +22,10 @@ namespace ShiftOS.Frontend GraphicsDevice = new GraphicsDeviceManager(this); GraphicsDevice.PreferredBackBufferHeight = 1080; GraphicsDevice.PreferredBackBufferWidth = 1920; + UIManager.Viewport = new System.Drawing.Size( + GraphicsDevice.PreferredBackBufferWidth, + GraphicsDevice.PreferredBackBufferHeight + ); Content.RootDirectory = "Content"; @@ -64,55 +68,8 @@ namespace ShiftOS.Frontend Engine.Infobox.Init(new Infobox()); - //Let's give it a try. - Engine.Infobox.Show("Welcome to ShiftOS!", "This is a test infobox. Clicking OK will dismiss it."); - //Let's initiate the engine just for a ha. - - //We'll create a few UI elements when the save system loads - SaveSystem.GameReady += () => - { - var headerLabel = new GUI.TextControl(); - headerLabel.Font = SkinEngine.LoadedSkin.HeaderFont; - headerLabel.AutoSize = true; - headerLabel.Text = "ShiftOS engine startup stats"; - headerLabel.X = 30; - headerLabel.Y = 30; - UIManager.AddTopLevel(headerLabel); - - var statslabel = new GUI.TextControl(); - statslabel.AutoSize = true; - statslabel.X = 30; - statslabel.Y = headerLabel.Y + headerLabel.Height + 30; - UIManager.AddTopLevel(statslabel); - statslabel.Text = $@"Save System -======================= - -System name: {SaveSystem.CurrentSave.SystemName} -Users: {SaveSystem.CurrentSave.Users.Count} - -Current user: {SaveSystem.CurrentUser.Username} - -Sandbox mode: {SaveSystem.IsSandbox} -Installed upgrades: {SaveSystem.CurrentSave.CountUpgrades()} - may be inaccurate if in sandbox mode -Available upgrades: {Shiftorium.GetAvailable().Count()} -Total upgrades: {Shiftorium.GetDefaults().Count()} - -ShiftFS -============================ - -Mounted file systems: {Objects.ShiftFS.Utils.Mounts.Count} - -Reflection Manager -===================== - -Reflection manager found {ReflectMan.Types.Count()} Common Language Runtime types that ShiftOS can reflect over. - - -"; - statslabel.Layout(); - }; - + TerminalBackend.TerminalRequested += () => { AppearanceManager.SetupWindow(new Apps.Terminal()); @@ -123,17 +80,6 @@ Reflection manager found {ReflectMan.Types.Count()} Common Language Runtime type SaveSystem.Begin(true); - var textinput = new GUI.TextInput(); - textinput.Width = 250; - textinput.Height = 20; - textinput.X = 0; - textinput.Y = 0; - UIManager.AddTopLevel(textinput); - - framerate.Width = GraphicsDevice.PreferredBackBufferWidth; - framerate.Height = GraphicsDevice.PreferredBackBufferHeight; - framerate.TextAlign = GUI.TextAlign.BottomRight; - base.Initialize(); } diff --git a/ShiftOS_TheReturn/Shiftorium.cs b/ShiftOS_TheReturn/Shiftorium.cs index e4c2a08..0362566 100644 --- a/ShiftOS_TheReturn/Shiftorium.cs +++ b/ShiftOS_TheReturn/Shiftorium.cs @@ -426,7 +426,7 @@ namespace ShiftOS.Engine try { if (SaveSystem.CurrentSave == null) - return true; + return false; if (SaveSystem.CurrentSave.StoriesExperienced == null) SaveSystem.CurrentSave.StoriesExperienced = new List();