aboutsummaryrefslogtreecommitdiff
path: root/ShiftOS.Frontend/Apps
diff options
context:
space:
mode:
Diffstat (limited to 'ShiftOS.Frontend/Apps')
-rw-r--r--ShiftOS.Frontend/Apps/CodeShop.cs156
-rw-r--r--ShiftOS.Frontend/Apps/Pong.cs171
-rw-r--r--ShiftOS.Frontend/Apps/Terminal.cs403
3 files changed, 730 insertions, 0 deletions
diff --git a/ShiftOS.Frontend/Apps/CodeShop.cs b/ShiftOS.Frontend/Apps/CodeShop.cs
new file mode 100644
index 0000000..ad44fda
--- /dev/null
+++ b/ShiftOS.Frontend/Apps/CodeShop.cs
@@ -0,0 +1,156 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ShiftOS.Engine;
+using ShiftOS.Frontend.GraphicsSubsystem;
+
+namespace ShiftOS.Frontend.Apps
+{
+ [WinOpen("shiftorium")]
+ public class CodeShop : GUI.Control, IShiftOSWindow
+ {
+ private GUI.ListBox upgradelist = null;
+ private ShiftoriumUpgrade selectedUpgrade = null;
+ private GUI.ProgressBar upgradeprogress = null;
+ private GUI.Button buy = null;
+
+ public CodeShop()
+ {
+ Width = 720;
+ Height = 480;
+ }
+
+ protected override void OnLayout()
+ {
+ try
+ {
+ upgradelist.X = 30;
+ upgradelist.Y = 75;
+ upgradelist.Width = this.Width / 2;
+ upgradelist.Width -= 30;
+ upgradelist.Height = this.Height - upgradelist.Y - 75;
+ upgradeprogress.X = upgradelist.X;
+ upgradeprogress.Y = upgradelist.Y + upgradelist.Height + 10;
+ upgradeprogress.Width = upgradelist.Width;
+ upgradeprogress.Height = 24;
+ upgradeprogress.Maximum = Shiftorium.GetDefaults().Count;
+ upgradeprogress.Value = SaveSystem.CurrentSave.CountUpgrades();
+ buy.X = Width - buy.Width - 15;
+ buy.Y = Height - buy.Height - 15;
+ buy.Visible = (selectedUpgrade != null);
+
+ }
+ catch
+ {
+
+ }
+ }
+
+ public void OnLoad()
+ {
+ buy = new GUI.Button();
+ buy.Text = "Buy upgrade";
+ buy.AutoSize = true;
+ buy.Font = SkinEngine.LoadedSkin.MainFont;
+ buy.Click += () =>
+ {
+ if(Shiftorium.Buy(selectedUpgrade.ID, selectedUpgrade.Cost) == true)
+ {
+ Engine.Infobox.Show("Upgrade installed!", "You have successfully bought and installed the " + selectedUpgrade.Name + " upgrade for " + selectedUpgrade.Cost + " Codepoints.");
+ SelectUpgrade(null);
+ PopulateList();
+ }
+ else
+ {
+ Engine.Infobox.Show("Insufficient funds.", "You do not have enough Codepoints to buy this upgrade. You need " + (selectedUpgrade.Cost - SaveSystem.CurrentSave.Codepoints) + " more.");
+ }
+ };
+ AddControl(buy);
+ upgradelist = new GUI.ListBox();
+ upgradeprogress = new GUI.ProgressBar();
+ AddControl(upgradeprogress);
+ AddControl(upgradelist);
+ upgradelist.SelectedIndexChanged += () =>
+ {
+ string itemtext = upgradelist.SelectedItem.ToString();
+ var upg = Shiftorium.GetAvailable().FirstOrDefault(x => $"{x.Category}: {x.Name} - {x.Cost}CP" == itemtext);
+ if(upg != null)
+ {
+ SelectUpgrade(upg);
+ }
+ };
+ PopulateList();
+ }
+
+ public void SelectUpgrade(ShiftoriumUpgrade upgrade)
+ {
+ if(selectedUpgrade != upgrade)
+ {
+ selectedUpgrade = upgrade;
+ Invalidate();
+ }
+ }
+
+ public void PopulateList()
+ {
+ upgradelist.ClearItems();
+ foreach(var upgrade in Shiftorium.GetAvailable())
+ {
+ upgradelist.AddItem($"{upgrade.Category}: {upgrade.Name} - {upgrade.Cost}CP");
+ Invalidate();
+ }
+ }
+
+ public void OnSkinLoad()
+ {
+ }
+
+ public bool OnUnload()
+ {
+ return true;
+ }
+
+ public void OnUpgrade()
+ {
+ PopulateList();
+ }
+
+ protected override void OnPaint(GraphicsContext gfx)
+ {
+ base.OnPaint(gfx);
+
+ string title = "Welcome to the Shiftorium!";
+ string desc = @"The Shiftorium is a place where you can buy upgrades for your computer. These upgrades include hardware enhancements, kernel and software optimizations and features, new programs, upgrades to existing programs, and more.
+
+As you continue through your job, going further up the ranks, you will unlock additional upgrades which can be found here. You may also find upgrades which are not available within the Shiftorium when hacking more difficult and experienced targets. These upgrades are very rare and hard to find, though. You'll find them in the ""Installed Upgrades"" list.";
+
+ if(selectedUpgrade != null)
+ {
+ title = selectedUpgrade.Category + ": " + selectedUpgrade.Name;
+
+ desc = selectedUpgrade.Description;
+ }
+
+ int wrapwidth = (Width - (upgradelist.X + upgradelist.Width)) - 45;
+ var titlemeasure = gfx.MeasureString(title, SkinEngine.LoadedSkin.Header2Font, wrapwidth);
+
+ var descmeasure = gfx.MeasureString(desc, SkinEngine.LoadedSkin.MainFont, wrapwidth);
+
+ int availablewidth = Width - (upgradelist.X + upgradelist.Width);
+ int titlelocx = (availablewidth - (int)titlemeasure.X) / 2;
+ titlelocx += (Width - availablewidth);
+ int titlelocy = 30;
+ gfx.DrawString(title, titlelocx, titlelocy, SkinEngine.LoadedSkin.ControlTextColor.ToMonoColor(), SkinEngine.LoadedSkin.Header2Font);
+
+ int desclocy = (Height - (int)descmeasure.Y) / 2;
+ int desclocx = (Width - availablewidth) + ((availablewidth - (int)descmeasure.X) / 2);
+ gfx.DrawString(desc, desclocx, desclocy, SkinEngine.LoadedSkin.ControlTextColor.ToMonoColor(), SkinEngine.LoadedSkin.MainFont, wrapwidth);
+
+ string shiftorium = "Shiftorium";
+ var smeasure = gfx.MeasureString(shiftorium, SkinEngine.LoadedSkin.HeaderFont);
+ gfx.DrawString(shiftorium, upgradelist.X + ((upgradelist.Width - (int)smeasure.X) / 2), 20, SkinEngine.LoadedSkin.ControlTextColor.ToMonoColor(), SkinEngine.LoadedSkin.HeaderFont);
+ }
+ }
+}
diff --git a/ShiftOS.Frontend/Apps/Pong.cs b/ShiftOS.Frontend/Apps/Pong.cs
new file mode 100644
index 0000000..aed7cf1
--- /dev/null
+++ b/ShiftOS.Frontend/Apps/Pong.cs
@@ -0,0 +1,171 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.Xna.Framework;
+using ShiftOS.Engine;
+using ShiftOS.Frontend.GraphicsSubsystem;
+
+namespace ShiftOS.Frontend.Apps
+{
+ [Launcher("{TITLE_PONG}", true, "al_pong", "{AL_GAMES}")]
+ [WinOpen("{WO_PONG}")]
+ [DefaultTitle("{TITLE_PONG}")]
+ [DefaultIcon("iconPong")]
+ public class Pong : GUI.Control, IShiftOSWindow
+ {
+ public Pong()
+ {
+ Width = 720;
+ Height = 480;
+ MouseMove += (loc) =>
+ {
+ double _y = linear(loc.Y, 0, Height, -1, 1);
+ if(_y != playerY)
+ {
+ playerY = _y;
+ Invalidate();
+ }
+ };
+ }
+
+ #region Private variables
+ private double ballX = 0.0f;
+ private double ballY = 0.0f;
+ private double aiBallX = 0.0f;
+ private double aiBallY = 0.0f;
+ private double speedFactor = 0.0125;
+ private double xVel = 1;
+ private double yVel = 1;
+ private double aiXVel = 1;
+ private double aiYVel = 1;
+ private int paddleWidth;
+ private long codepointsToEarn = 0;
+ private int level = 1;
+ private double playerY = 0.0;
+ private double opponentY = 0.0;
+ private int secondsleft = 60;
+ bool doAi = true;
+ bool doBallCalc = true;
+ private string header = "";
+ private string counter = "";
+ #endregion
+
+ #region Control behaviour overrides
+
+ protected override void OnPaint(GraphicsContext gfx)
+ {
+ //This is where we'll dump the winforms painting code
+ //By now, Layout() would have calculated the game's state
+
+ paddleWidth = Width / 30;
+ double ballXLocal = linear(ballX, -1.0, 1.0, 0, Width);
+ double ballYLocal = linear(ballY, -1.0, 1.0, 0, Height);
+
+ ballXLocal -= ((double)paddleWidth / 2);
+ ballYLocal -= ((double)paddleWidth / 2);
+
+ double aiballXLocal = linear(aiBallX, -1.0, 1.0, 0, Width);
+ double aiballYLocal = linear(aiBallY, -1.0, 1.0, 0, Height);
+
+ aiballXLocal -= ((double)paddleWidth / 2);
+ aiballYLocal -= ((double)paddleWidth / 2);
+
+
+ base.OnPaint(gfx);
+
+ //draw the ball
+ if (doBallCalc)
+ {
+ gfx.DrawRectangle((int)ballXLocal, (int)ballYLocal, paddleWidth, paddleWidth, UIManager.SkinTextures["ControlTextColor"]);
+ }
+ double playerYLocal = linear(playerY, -1.0, 1.0, 0, Height);
+ double opponentYLocal = linear(opponentY, -1.0, 1.0, 0, Height);
+
+ int paddleHeight = Height / 5;
+
+ int paddleStart = paddleWidth;
+
+ //draw player paddle
+ gfx.DrawRectangle(paddleWidth, (int)playerYLocal - (paddleHeight / 2), paddleWidth, paddleHeight, UIManager.SkinTextures["ControlTextColor"]);
+
+
+ //draw opponent
+ gfx.DrawRectangle(Width - (paddleWidth*2), (int)opponentYLocal - (paddleHeight / 2), paddleWidth, paddleHeight, UIManager.SkinTextures["ControlTextColor"]);
+
+ string cp_text = Localization.Parse("{PONG_STATUSCP}", new Dictionary<string, string>
+ {
+ ["%cp"] = codepointsToEarn.ToString()
+ });
+
+ var tSize = gfx.MeasureString(cp_text, SkinEngine.LoadedSkin.Header3Font);
+
+ var tLoc = new Vector2((Width - (int)tSize.X) / 2,
+ (Height - (int)tSize.Y)
+
+ );
+
+ gfx.DrawString(cp_text, (int)tLoc.X, (int)tLoc.Y, SkinEngine.LoadedSkin.ControlTextColor.ToMonoColor(), SkinEngine.LoadedSkin.Header3Font);
+
+ tSize = gfx.MeasureString(counter, SkinEngine.LoadedSkin.Header2Font);
+
+ tLoc = new Vector2((Width - (int)tSize.X) / 2,
+ (Height - (int)tSize.Y) / 2
+
+ );
+ gfx.DrawString(counter, (int)tLoc.X, (int)tLoc.Y, SkinEngine.LoadedSkin.ControlTextColor.ToMonoColor(), SkinEngine.LoadedSkin.Header2Font);
+ tSize = gfx.MeasureString(header, SkinEngine.LoadedSkin.Header2Font);
+
+ tLoc = new Vector2((Width - (int)tSize.X) / 2,
+ (Height - (int)tSize.Y) / 4
+
+ );
+ gfx.DrawString(header, (int)tLoc.X, (int)tLoc.Y, SkinEngine.LoadedSkin.ControlTextColor.ToMonoColor(), SkinEngine.LoadedSkin.Header2Font);
+
+ string l = Localization.Parse("{PONG_STATUSLEVEL}", new Dictionary<string, string>
+ {
+ ["%level"] = level.ToString(),
+ ["%time"] = secondsleft.ToString()
+ });
+ tSize = gfx.MeasureString(l, SkinEngine.LoadedSkin.Header3Font);
+
+ tLoc = new Vector2((Width - (int)tSize.X) / 2,
+ (tSize.Y)
+ );
+ gfx.DrawString(l, (int)tLoc.X, (int)tLoc.Y, SkinEngine.LoadedSkin.ControlTextColor.ToMonoColor(), SkinEngine.LoadedSkin.Header3Font);
+
+
+ }
+
+ #endregion
+
+
+ static public double linear(double x, double x0, double x1, double y0, double y1)
+ {
+ if ((x1 - x0) == 0)
+ {
+ return (y0 + y1) / 2;
+ }
+ return y0 + (x - x0) * (y1 - y0) / (x1 - x0);
+ }
+
+ public void OnLoad()
+ {
+ doBallCalc = true;
+ }
+
+ public void OnSkinLoad()
+ {
+ }
+
+ public bool OnUnload()
+ {
+ return true;
+ }
+
+ public void OnUpgrade()
+ {
+ }
+ }
+}
diff --git a/ShiftOS.Frontend/Apps/Terminal.cs b/ShiftOS.Frontend/Apps/Terminal.cs
new file mode 100644
index 0000000..67c7f7f
--- /dev/null
+++ b/ShiftOS.Frontend/Apps/Terminal.cs
@@ -0,0 +1,403 @@
+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;
+
+namespace ShiftOS.Frontend.Apps
+{
+ [FileHandler("Shell script", ".trm", "fileicontrm")]
+ [Launcher("{TITLE_TERMINAL}", false, null, "{AL_UTILITIES}")]
+ [WinOpen("{WO_TERMINAL}")]
+ [DefaultTitle("{TITLE_TERMINAL}")]
+ [DefaultIcon("iconTerminal")]
+ public class Terminal : GUI.Control, IShiftOSWindow
+ {
+ private TerminalControl _terminal = null;
+
+ public Terminal()
+ {
+ Width = 493;
+ Height = 295;
+ }
+
+ public void OnLoad()
+ {
+ _terminal = new Apps.TerminalControl();
+ _terminal.Dock = GUI.DockStyle.Fill;
+ AddControl(_terminal);
+ _terminal.Layout();
+ AppearanceManager.ConsoleOut = _terminal;
+ AppearanceManager.StartConsoleOut();
+ TerminalBackend.PrintPrompt();
+ SaveSystem.GameReady += () =>
+ {
+ if (Shiftorium.UpgradeInstalled("desktop"))
+ {
+ AppearanceManager.Close(this);
+ }
+ else
+ TerminalBackend.PrintPrompt();
+ };
+ }
+
+ protected override void OnLayout()
+ {
+ if (ContainsFocusedControl || IsFocusedControl)
+ AppearanceManager.ConsoleOut = _terminal;
+ }
+
+ public void OnSkinLoad()
+ {
+
+ }
+
+ public bool OnUnload()
+ {
+ return true;
+ }
+
+ public void OnUpgrade()
+ {
+ }
+ }
+
+ public class TerminalControl : GUI.TextInput, ITerminalWidget
+ {
+ public TerminalControl()
+ {
+ Dock = GUI.DockStyle.Fill;
+
+ }
+
+ public string[] Lines
+ {
+ get
+ {
+ return Text.Split(new[] { "\r\n" }, StringSplitOptions.None);
+
+ }
+ }
+
+ public void Clear()
+ {
+ Text = "";
+ Index = 0;
+ _vertOffset = 0;
+ Invalidate();
+ }
+
+ public void SelectBottom()
+ {
+ Index = Text.Length - 1;
+ RecalculateLayout();
+ InvalidateTopLevel();
+ }
+
+
+
+ public void Write(string text)
+ {
+ Engine.Desktop.InvokeOnWorkerThread(() =>
+ {
+ Text += Localization.Parse(text);
+ SelectBottom();
+ Index += text.Length;
+ RecalculateLayout();
+ InvalidateTopLevel();
+ });
+ }
+
+ public void WriteLine(string text)
+ {
+ Write(text + Environment.NewLine);
+ }
+
+
+ public int GetCurrentLine()
+ {
+ int line = 0;
+ for(int i = 0; i < Text.Length; i++)
+ {
+ if(Text[i]=='\n')
+ {
+ line++;
+ continue;
+ }
+ if (i == Index)
+ return line;
+ }
+ return 0;
+ }
+
+ float _vertOffset = 0.0f;
+
+ protected void RecalculateLayout()
+ {
+ if(!string.IsNullOrEmpty(Text))
+ using (var gfx = Graphics.FromImage(new Bitmap(1, 1)))
+ {
+ var textsize = gfx.SmartMeasureString(Text, LoadedSkin.TerminalFont, Width);
+ float initial = textsize.Height - _vertOffset;
+ if(initial > Height)
+ {
+ float difference = Height - initial;
+ _vertOffset = initial - difference;
+ }
+ else if(initial < 0)
+ {
+ float difference = Height - initial;
+ _vertOffset = initial + difference;
+ }
+ }
+ }
+
+ protected override void OnLayout()
+ {
+
+ }
+
+ /// <summary>
+ /// Gets the X and Y coordinates (in pixels) of the caret.
+ /// </summary>
+ /// <param name="gfx">A <see cref="System.Drawing.Graphics"/> object used for font measurements</param>
+ /// <returns>An absolute fucking mess. Seriously, can someone fix this method so it uhh WORKS PROPERLY?</returns>
+ public Point GetPointAtIndex(Graphics gfx)
+ {
+ int vertMeasure = 2;
+ int horizMeasure = 2;
+ var textSize = gfx.SmartMeasureString(Text, LoadedSkin.TerminalFont, Width - 4);
+ int lineindex = 0;
+ int line = GetCurrentLine();
+ for (int l = 0; l < line; l++)
+ {
+ lineindex += Lines[l].Length;
+ var stringMeasure = gfx.SmartMeasureString(Lines[l] == "\r" ? " " : Lines[l], LoadedSkin.TerminalFont, Width - 4);
+ vertMeasure += (int)stringMeasure.Height;
+
+ }
+ var lnMeasure = gfx.SmartMeasureString(Text.Substring(lineindex, Index - lineindex), LoadedSkin.TerminalFont);
+ int w = (int)Math.Floor(lnMeasure.Width);
+ if (w > Width - 4)
+ w = w - (Width - 4);
+ horizMeasure = w;
+ return new Point(horizMeasure, vertMeasure);
+ }
+
+ private PointF CaretPosition = new PointF(2, 2);
+ private Size CaretSize = new Size(2, 15);
+
+ protected override void OnKeyEvent(KeyEvent a)
+ {
+ if (a.Key == Keys.Enter)
+ {
+ 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", "");
+ WriteLine("");
+ {
+ 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<string, Dictionary<string, string>>)))
+ {
+ 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')
+ {
+ Text = Text.Insert(Index, a.KeyChar.ToString());
+ Index++;
+ AppearanceManager.CurrentPosition++;
+// RecalculateLayout();
+ InvalidateTopLevel();
+ }
+ }
+ }
+
+ protected override void OnPaint(GraphicsContext gfx)
+ {
+ gfx.Clear(LoadedSkin.TerminalBackColorCC.ToColor().ToMonoColor());
+ if (!string.IsNullOrEmpty(Text))
+ {
+ //Draw the caret.
+ if (IsFocusedControl)
+ {
+ PointF cursorPos;
+ using (var cgfx = System.Drawing.Graphics.FromImage(new System.Drawing.Bitmap(1, 1)))
+ {
+ cursorPos = GetPointAtIndex(cgfx);
+
+ }
+ var cursorSize = gfx.MeasureString(Text[Index-1].ToString(), LoadedSkin.TerminalFont);
+ gfx.DrawRectangle((int)cursorPos.X, (int)cursorPos.Y - (int)_vertOffset, (int)cursorSize.X, (int)cursorSize.Y, LoadedSkin.TerminalForeColorCC.ToColor().ToMonoColor());
+ }//Draw the text
+
+
+ gfx.DrawString(Text, 2, 2 - (int)Math.Floor(_vertOffset), LoadedSkin.TerminalForeColorCC.ToColor().ToMonoColor(), LoadedSkin.TerminalFont, Width - 4);
+ }
+ }
+
+ }
+
+ public static class ConsoleColorExtensions
+ {
+ public static Color ToColor(this ConsoleColor cc)
+ {
+ switch (cc)
+ {
+ case ConsoleColor.Black:
+ return Color.Black;
+ case ConsoleColor.Blue:
+ return Color.Blue;
+ case ConsoleColor.Cyan:
+ return Color.Cyan;
+ case ConsoleColor.DarkBlue:
+ return Color.DarkBlue;
+ case ConsoleColor.DarkCyan:
+ return Color.DarkCyan;
+ case ConsoleColor.DarkGray:
+ return Color.DarkGray;
+ case ConsoleColor.DarkGreen:
+ return Color.DarkGreen;
+ case ConsoleColor.DarkMagenta:
+ return Color.DarkMagenta;
+ case ConsoleColor.DarkRed:
+ return Color.DarkRed;
+ case ConsoleColor.DarkYellow:
+ return Color.Orange;
+ case ConsoleColor.Gray:
+ return Color.Gray;
+ case ConsoleColor.Green:
+ return Color.Green;
+ case ConsoleColor.Magenta:
+ return Color.Magenta;
+ case ConsoleColor.Red:
+ return Color.Red;
+ case ConsoleColor.White:
+ return Color.White;
+ case ConsoleColor.Yellow:
+ return Color.Yellow;
+ }
+ return Color.Empty;
+ }
+ }
+
+ public static class GraphicsExtensions
+ {
+ public static SizeF SmartMeasureString(this Graphics gfx, string s, Font font, int width)
+ {
+ if (string.IsNullOrEmpty(s))
+ s = " ";
+ var textformat = new StringFormat(StringFormat.GenericTypographic);
+ textformat.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
+ textformat.Trimming = StringTrimming.None;
+ textformat.FormatFlags |= StringFormatFlags.NoClip;
+
+ gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
+ var measure = gfx.MeasureString(s, font, width, textformat);
+ return new SizeF((float)Math.Ceiling(measure.Width), (float)Math.Ceiling(measure.Height));
+ }
+
+ public static SizeF SmartMeasureString(this Graphics gfx, string s, Font font)
+ {
+ return SmartMeasureString(gfx, s, font, int.MaxValue);
+ }
+
+ }
+}