From 6e40ae80f39c766d611b4ca29aea0f6685db80dc Mon Sep 17 00:00:00 2001 From: MichaelTheShifter Date: Mon, 4 Jul 2016 17:43:04 -0400 Subject: [PATCH] Add luatextbox widget and more. - Syntax highlighting textbox for Lua API - That textbox also supports C# syntax highlighting - Added framework for custom desktop environments in Lua. --- source/WindowsFormsApplication1/API.cs | 3 +- .../Controls/SyntaxHighlighter.cs | 324 ++++++++++++++++++ .../Controls/WindowBorder.cs | 7 +- .../Desktop/ShiftOSDesktop.Designer.cs | 2 +- .../Desktop/ShiftOSDesktop.cs | 93 ++++- .../Engine/Lua_Interp.cs | 136 +++++++- .../Online/Hacking/Matchmaker.cs | 2 +- .../WindowsFormsApplication1/ShiftOS.csproj | 3 + 8 files changed, 556 insertions(+), 14 deletions(-) create mode 100644 source/WindowsFormsApplication1/Controls/SyntaxHighlighter.cs diff --git a/source/WindowsFormsApplication1/API.cs b/source/WindowsFormsApplication1/API.cs index 5ab9631..3ccab3c 100644 --- a/source/WindowsFormsApplication1/API.cs +++ b/source/WindowsFormsApplication1/API.cs @@ -1063,7 +1063,7 @@ public static void CreateForm(Form formToCreate, string AppName, Image AppIcon) { if (e.KeyCode == Keys.T && e.Control && formToCreate.Name != "Terminal") { - CreateForm(new Terminal(), CurrentSave.TerminalName, Properties.Resources.iconTerminal); + CurrentSession.InvokeCTRLT(); } if (formToCreate.Name != "Terminal" || Upgrades["windowedterminal"] == true) { @@ -1111,6 +1111,7 @@ public static void CreateForm(Form formToCreate, string AppName, Image AppIcon) } })); WindowComposition.SafeToAddControls = true; + API.CurrentSession.Invoke(new Action(() => { CurrentSession.InvokeWindowOp("open", formToCreate); })); }; bw.RunWorkerAsync(); } diff --git a/source/WindowsFormsApplication1/Controls/SyntaxHighlighter.cs b/source/WindowsFormsApplication1/Controls/SyntaxHighlighter.cs new file mode 100644 index 0000000..4e82af7 --- /dev/null +++ b/source/WindowsFormsApplication1/Controls/SyntaxHighlighter.cs @@ -0,0 +1,324 @@ +//Source: http://www.codeproject.com/KB/edit/SyntaxRichTextBox/SyntaxRichTextBox_src.zip + +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Windows.Forms; +using System.ComponentModel; +using System.Text.RegularExpressions; +using System.Drawing; + +namespace ShiftOS +{ + public class SyntaxRichTextBox : System.Windows.Forms.RichTextBox + { + private SyntaxSettings m_settings = new SyntaxSettings(); + private static bool m_bPaint = true; + private string m_strLine = ""; + private int m_nContentLength = 0; + private int m_nLineLength = 0; + private int m_nLineStart = 0; + private int m_nLineEnd = 0; + private string m_strKeywords = ""; + private int m_nCurSelection = 0; + + /// + /// The settings. + /// + public SyntaxSettings Settings + { + get { return m_settings; } + } + + /// + /// WndProc + /// + /// + protected override void WndProc(ref System.Windows.Forms.Message m) + { + if (m.Msg == 0x00f) + { + if (m_bPaint) + base.WndProc(ref m); + else + m.Result = IntPtr.Zero; + } + else + base.WndProc(ref m); + } + + public void SetLanguage(SyntaxSettings.Language lang) + { + Color white = Color.Black; + Color keyword = Color.Red; + Color integer = Color.LightGreen; + Color comment = Color.DarkGray; + Color str = Color.Orange; + Settings.EnableComments = true; + Settings.EnableIntegers = true; + Settings.EnableStrings = true; + if (API.Upgrades["limitlesscustomshades"]) + { + Settings.CommentColor = comment; + Settings.KeywordColor = keyword; + Settings.StringColor = str; + Settings.IntegerColor = integer; + } + else + { + Settings.CommentColor = white; + Settings.KeywordColor = white; + Settings.StringColor = white; + Settings.IntegerColor = white; + } + + switch (lang) + { + case SyntaxSettings.Language.Lua: + var kw = new List() { "function", "local", "return", "if", "else", "elseif", "while", "true", "do", "next", "end", "for", "pairs", "in", "{", "}", "false" }; + Settings.Keywords.Clear(); + foreach (var k in kw) + { + Settings.Keywords.Add(k); + } + Settings.Comment = "--"; + break; + case SyntaxSettings.Language.CSharp: + var cskw = new List() { "public", "private", "internal", "static", "dynamic", "namespace", "typeof", "(", ")", "[", "]", "{", "}", "sizeof", "int", "using", "<", ">", ";", "this", "base", ":", "class", "interface", "string", "double", "single", "char", "new", "if", "else", "while", "for", "foreach", "in", "var", "as", "is", "object", "~" }; + Settings.Keywords.Clear(); + foreach (var k in cskw) + { + Settings.Keywords.Add(k); + } + Settings.Comment = "//"; + break; + } + CompileKeywords(); + ProcessAllLines(); + } + + /// + /// OnTextChanged + /// + /// + protected override void OnTextChanged(EventArgs e) + { + // Calculate shit here. (NO. I didn't write this. This was there in codeproject... - Michael) + m_nContentLength = this.TextLength; + + int nCurrentSelectionStart = SelectionStart; + int nCurrentSelectionLength = SelectionLength; + + m_bPaint = false; + + // Find the start of the current line. + m_nLineStart = nCurrentSelectionStart; + while ((m_nLineStart > 0) && (Text[m_nLineStart - 1] != '\n')) + m_nLineStart--; + // Find the end of the current line. + m_nLineEnd = nCurrentSelectionStart; + while ((m_nLineEnd < Text.Length) && (Text[m_nLineEnd] != '\n')) + m_nLineEnd++; + // Calculate the length of the line. + m_nLineLength = m_nLineEnd - m_nLineStart; + // Get the current line. + m_strLine = Text.Substring(m_nLineStart, m_nLineLength); + + // Process this line. + ProcessLine(); + + m_bPaint = true; + } + /// + /// Process a line. + /// + private void ProcessLine() + { + // Save the position and make the whole line black + int nPosition = SelectionStart; + SelectionStart = m_nLineStart; + SelectionLength = m_nLineLength; + SelectionColor = ForeColor; + + // Process the keywords + ProcessRegex(m_strKeywords, Settings.KeywordColor); + // Process numbers + if (Settings.EnableIntegers) + ProcessRegex("\\b(?:[0-9]*\\.)?[0-9]+\\b", Settings.IntegerColor); + // Process strings + if (Settings.EnableStrings) + ProcessRegex("\"[^\"\\\\\\r\\n]*(?:\\\\.[^\"\\\\\\r\\n]*)*\"", Settings.StringColor); + // Process comments + if (Settings.EnableComments && !string.IsNullOrEmpty(Settings.Comment)) + ProcessRegex(Settings.Comment + ".*$", Settings.CommentColor); + + SelectionStart = nPosition; + SelectionLength = 0; + SelectionColor = Color.Black; + + m_nCurSelection = nPosition; + } + /// + /// Process a regular expression. + /// + /// The regular expression. + /// The color. + private void ProcessRegex(string strRegex, Color color) + { + Regex regKeywords = new Regex(strRegex, RegexOptions.IgnoreCase | RegexOptions.Compiled); + Match regMatch; + + for (regMatch = regKeywords.Match(m_strLine); regMatch.Success; regMatch = regMatch.NextMatch()) + { + // Process the words + int nStart = m_nLineStart + regMatch.Index; + int nLenght = regMatch.Length; + SelectionStart = nStart; + SelectionLength = nLenght; + SelectionColor = color; + } + } + /// + /// Compiles the keywords as a regular expression. + /// + public void CompileKeywords() + { + for (int i = 0; i < Settings.Keywords.Count; i++) + { + string strKeyword = Settings.Keywords[i]; + + if (i == Settings.Keywords.Count - 1) + m_strKeywords += "\\b" + strKeyword + "\\b"; + else + m_strKeywords += "\\b" + strKeyword + "\\b|"; + } + } + + public void ProcessAllLines() + { + m_bPaint = false; + + int nStartPos = 0; + int i = 0; + int nOriginalPos = SelectionStart; + while (i < Lines.Length) + { + m_strLine = Lines[i]; + m_nLineStart = nStartPos; + m_nLineEnd = m_nLineStart + m_strLine.Length; + + ProcessLine(); + i++; + + nStartPos += m_strLine.Length + 1; + } + + m_bPaint = true; + } + } + + /// + /// Class to store syntax objects in. + /// + public class SyntaxList + { + public List m_rgList = new List(); + public Color m_color = new Color(); + } + + /// + /// Settings for the keywords and colors. + /// + public class SyntaxSettings + { + SyntaxList m_rgKeywords = new SyntaxList(); + string m_strComment = ""; + Color m_colorComment = Color.Green; + Color m_colorString = Color.Gray; + Color m_colorInteger = Color.Red; + bool m_bEnableComments = true; + bool m_bEnableIntegers = true; + bool m_bEnableStrings = true; + + #region Properties + /// + /// A list containing all keywords. + /// + public List Keywords + { + get { return m_rgKeywords.m_rgList; } + } + /// + /// The color of keywords. + /// + public Color KeywordColor + { + get { return m_rgKeywords.m_color; } + set { m_rgKeywords.m_color = value; } + } + /// + /// A string containing the comment identifier. + /// + public string Comment + { + get { return m_strComment; } + set { m_strComment = value; } + } + /// + /// The color of comments. + /// + public Color CommentColor + { + get { return m_colorComment; } + set { m_colorComment = value; } + } + /// + /// Enables processing of comments if set to true. + /// + public bool EnableComments + { + get { return m_bEnableComments; } + set { m_bEnableComments = value; } + } + /// + /// Enables processing of integers if set to true. + /// + public bool EnableIntegers + { + get { return m_bEnableIntegers; } + set { m_bEnableIntegers = value; } + } + /// + /// Enables processing of strings if set to true. + /// + public bool EnableStrings + { + get { return m_bEnableStrings; } + set { m_bEnableStrings = value; } + } + /// + /// The color of strings. + /// + public Color StringColor + { + get { return m_colorString; } + set { m_colorString = value; } + } + /// + /// The color of integers. + /// + public Color IntegerColor + { + get { return m_colorInteger; } + set { m_colorInteger = value; } + } + #endregion + + public enum Language + { + Lua, + CSharp, + } + } +} diff --git a/source/WindowsFormsApplication1/Controls/WindowBorder.cs b/source/WindowsFormsApplication1/Controls/WindowBorder.cs index 751cb43..79d1c20 100644 --- a/source/WindowsFormsApplication1/Controls/WindowBorder.cs +++ b/source/WindowsFormsApplication1/Controls/WindowBorder.cs @@ -223,6 +223,7 @@ public void setupborders() pgright.Hide(); this.Size = new Size(this.Width - pgleft.Width - pgright.Width, this.Height - pgbottom.Height); } + API.CurrentSession.InvokeWindowOp("brdr_redraw", this.ParentForm); } private void closebutton_Click(object sender, EventArgs e) @@ -405,7 +406,7 @@ public void setuptitlebar() pnlicon.Image = this.AppIcon; //Replace with the correct icon for the program. } - + API.CurrentSession.InvokeWindowOp("tbar_redraw", this.ParentForm); } public void rollupanddown() @@ -446,6 +447,7 @@ public void resettitlebar() } lbtitletext.ForeColor = API.CurrentSkin.titletextcolour; } + API.CurrentSession.InvokeWindowOp("tbar_redraw", this.ParentForm); } // ERROR: Handles clauses are not supported in C# @@ -649,7 +651,7 @@ public void setskin() pgbottomrcorner.BackgroundImageLayout = (ImageLayout)API.CurrentSkin.bottomrightcornerlayout; pgbottomlcorner.BackgroundImageLayout = (ImageLayout)API.CurrentSkin.bottomleftcornerlayout; - + API.CurrentSession.InvokeWindowOp("redraw", this.ParentForm); } // ERROR: Handles clauses are not supported in C# @@ -660,6 +662,7 @@ private void Clock_FormClosing(object sender, FormClosingEventArgs e) e.Cancel = true; WindowComposition.CloseForm(this.ParentForm, pbtn, API.CurrentSkin.WindowCloseAnimation); } + API.CurrentSession.InvokeWindowOp("close", this.ParentForm); } } #endregion diff --git a/source/WindowsFormsApplication1/Desktop/ShiftOSDesktop.Designer.cs b/source/WindowsFormsApplication1/Desktop/ShiftOSDesktop.Designer.cs index fad1f66..0116fc9 100644 --- a/source/WindowsFormsApplication1/Desktop/ShiftOSDesktop.Designer.cs +++ b/source/WindowsFormsApplication1/Desktop/ShiftOSDesktop.Designer.cs @@ -1561,7 +1561,7 @@ private void InitializeComponent() public System.Windows.Forms.ImageList imgshiftnetapps; private System.Windows.Forms.Label lbldebug; private System.Windows.Forms.Label lblog; - private System.Windows.Forms.FlowLayoutPanel flicons; + public System.Windows.Forms.FlowLayoutPanel flicons; private System.Windows.Forms.ToolStripMenuItem scriptToolStripMenuItem; private System.Windows.Forms.ContextMenuStrip cmbfactions; private System.Windows.Forms.ToolStripMenuItem deleteToolStripMenuItem; diff --git a/source/WindowsFormsApplication1/Desktop/ShiftOSDesktop.cs b/source/WindowsFormsApplication1/Desktop/ShiftOSDesktop.cs index 9a6818e..84c9014 100644 --- a/source/WindowsFormsApplication1/Desktop/ShiftOSDesktop.cs +++ b/source/WindowsFormsApplication1/Desktop/ShiftOSDesktop.cs @@ -23,6 +23,71 @@ public ShiftOSDesktop() InitializeComponent(); } + //Event handler with no arguments. + public delegate void EmptyEventHandler(); + + //Event handler that passes a List + public delegate void ListEventHandler(List lst); + + //Window draw event handler. + public delegate void WindowDrawEventHandler(Form win); + + //Lua events. + public event EmptyEventHandler OnDesktopReload; + public event ListEventHandler OnAppLauncherPopulate; + public event ListEventHandler OnPanelButtonPopulate; + public event EmptyEventHandler OnClockSkin; + public event EmptyEventHandler CtrlTPressed; + public event EmptyEventHandler OnUnityCheck; + public event WindowDrawEventHandler WindowOpened; + public event WindowDrawEventHandler WindowClosed; + public event WindowDrawEventHandler WindowSkinReset; + public event WindowDrawEventHandler TitlebarReset; + public event WindowDrawEventHandler BorderReset; + public event ListEventHandler DesktopIconsPopulated; + + public void InvokeWindowOp(string operation, Form win) + { + switch(operation) + { + case "open": + WindowOpened?.Invoke(win); + break; + case "close": + WindowClosed?.Invoke(win); + break; + case "tbar_redraw": + TitlebarReset?.Invoke(win); + break; + case "brdr_redraw": + BorderReset?.Invoke(win); + break; + case "redraw": + WindowSkinReset?.Invoke(win); + break; + } + } + + public void AllowCtrlTIntercept() + { + _resetCtrlTEvent(); + CtrlTLuaIntercept = true; + } + + public void DisableCtrlTIntercept() + { + _resetCtrlTEvent(); + CtrlTLuaIntercept = false; + } + + + private void _resetCtrlTEvent() + { + CtrlTPressed = null; + } + + private bool CtrlTLuaIntercept = false; + public bool UnityEnabled = false; public ToolStripMenuItem AppLauncher { get { return this.ApplicationsToolStripMenuItem; } } @@ -80,6 +145,22 @@ public void EndGame_AttachEvents() }; } + + + public void InvokeCTRLT() + { + if (CtrlTLuaIntercept == true) + { + CtrlTPressed?.Invoke(); + } + else + { + //Show terminal on CTRL+T + + API.CreateForm(new Terminal(), API.CurrentSave.TerminalName, Properties.Resources.iconTerminal); + } + } + private void ShiftOSDesktop_Load(object sender, EventArgs e) { Viruses.CheckForInfected(); @@ -90,9 +171,7 @@ private void ShiftOSDesktop_Load(object sender, EventArgs e) { if (ea.KeyCode == Keys.T && ea.Control) { - //Show terminal on CTRL+T - - API.CreateForm(new Terminal(), API.CurrentSave.TerminalName, Properties.Resources.iconTerminal); + InvokeCTRLT(); } else if (ea.KeyCode == Keys.D && ea.Control) { @@ -269,6 +348,7 @@ public void SetupDesktop() } } } + OnDesktopReload?.Invoke(); } public void SetupWidgets() @@ -459,7 +539,7 @@ public void SetupDesktopIcons() }; flicons.Controls.Add(dl); } - + DesktopIconsPopulated?.Invoke(DesktopIconManager.Icons); } } @@ -734,6 +814,7 @@ public void SetupAppLauncher() else { ApplicationsToolStripMenuItem.Visible = false; } + OnAppLauncherPopulate?.Invoke(API.AppLauncherItems); } public void SetupGNOME2Elements() @@ -836,7 +917,7 @@ public void SetupPanelClock() else { timepanel.Hide(); } - + OnClockSkin?.Invoke(); } public void CheckUnity() @@ -864,6 +945,7 @@ public void CheckUnity() this.BackgroundImageLayout = (ImageLayout)API.CurrentSkin.desktopbackgroundlayout; } + OnUnityCheck?.Invoke(); } public void CheckForChristmas() @@ -935,6 +1017,7 @@ public void SetupPanelButtons() } pnlpanelbuttonholder.Padding = new Padding(API.CurrentSkin.panelbuttoninitialgap, 0, 0, 0); } + OnPanelButtonPopulate?.Invoke(API.PanelButtons); } public void setuppanelbuttonicons(ref PictureBox tbicon, Image image) diff --git a/source/WindowsFormsApplication1/Engine/Lua_Interp.cs b/source/WindowsFormsApplication1/Engine/Lua_Interp.cs index ed9c31f..21acb3c 100644 --- a/source/WindowsFormsApplication1/Engine/Lua_Interp.cs +++ b/source/WindowsFormsApplication1/Engine/Lua_Interp.cs @@ -111,6 +111,128 @@ public LuaInterpreter() /// public void RegisterCore() { + //Desktop environment + mod.on_unity_check += new Action((desktop, func) => + { + desktop.OnUnityCheck += () => + { + mod(func + "()"); + }; + }); + mod.on_desktop_reset += new Action((desktop, func) => + { + desktop.OnDesktopReload += () => + { + mod(func + "()"); + }; + }); + mod.on_clock_skin += new Action((desktop, func) => + { + desktop.OnClockSkin += () => + { + mod(func + "()"); + }; + }); + mod.on_window_open += new Action((desktop, func) => + { + desktop.WindowOpened += (win) => + { + mod.win = win; + mod(func + "(win)"); + }; + }); + mod.on_window_close += new Action((desktop, func) => + { + desktop.WindowClosed += (win) => + { + mod.win = win; + mod(func + "(win)"); + }; + }); + mod.on_window_titlebar_redraw += new Action((desktop, func) => + { + desktop.TitlebarReset += (win) => + { + mod.win = win; + mod(func + "(win)"); + }; + }); + mod.on_window_border_redraw += new Action((desktop, func) => + { + desktop.BorderReset += (win) => + { + mod.win = win; + mod(func + "(win)"); + }; + }); + mod.on_window_skin += new Action((desktop, func) => + { + desktop.WindowSkinReset += (win) => + { + mod.win = win; + mod(func + "(win)"); + }; + }); + mod.get_border = new Func((Form win) => + { + WindowBorder b = null; + foreach(Control c in win.Controls) + { + if ((string)c.Tag == "api_brdr") + b = (WindowBorder)c; + } + return b; + }); + + mod.on_app_launcher_populate += new Action((desktop, func) => + { + desktop.OnAppLauncherPopulate += (items) => + { + mod.al_items = items; + mod(func + "(clr_to_table(al_items))"); + }; + }); + mod.on_panelbutton_populate += new Action((desktop, func) => + { + desktop.OnPanelButtonPopulate += (items) => + { + mod.pb_items = items; + mod(func + "(clr_to_table(pb_items))"); + }; + }); + mod.intercept_ctrlt += new Action((func) => + { + API.CurrentSession.AllowCtrlTIntercept(); + API.CurrentSession.CtrlTPressed += () => + { + mod(func + "()"); + }; + }); + mod.stop_intercept_ctrlt += new Action(() => + { + API.CurrentSession.DisableCtrlTIntercept(); + + }); + + mod.on_desktopicon_populate += new Action((desktop, func) => + { + desktop.DesktopIconsPopulated += (items) => + { + mod.dl_items = items; + mod(func + "(clr_to_table(dl_items))"); + }; + }); + + + mod(@"function clr_to_table(clrlist) + local t = {} + local it = clrlist:GetEnumerator() + while it:MoveNext() do + t[#t+1] = it.Current + end + return t +end"); + mod.httpget = new Func((url) => { WebRequest request = WebRequest.Create(url); @@ -533,7 +655,7 @@ public void RegisterCore() } }; }); - mod.gen_font = new Func((style, size) => { + mod.font = new Func((style, size) => { return new Font(style, size); }); @@ -817,9 +939,9 @@ public void OpenFile(string fi, string fu) API.CreateFileSkimmerSession(fi, File_Skimmer.FileSkimmerMode.Open); API.FileSkimmerSession.FormClosing += (object s, FormClosingEventArgs a) => { - mod($"{fu}({API.GetFSResult()})"); + mod($"{fu}(\"{API.GetFSResult().Replace(Paths.SaveRoot, "").Replace("\\", "/")}\")"); }; - } + } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// Prompt user to save a file. @@ -831,7 +953,7 @@ public void SaveFile(string fi, string fu) API.CreateFileSkimmerSession(fi, File_Skimmer.FileSkimmerMode.Save); API.FileSkimmerSession.FormClosing += (object s, FormClosingEventArgs a) => { - mod($"{fu}({API.GetFSResult()})"); + mod($"{fu}(\"{API.GetFSResult().Replace(Paths.SaveRoot, "").Replace("\\", "/")}\")"); }; } @@ -933,6 +1055,12 @@ public Control ConstructControl(string type, string text, int x, int y, int widt var ctrl = new Control(); switch(type.ToLower()) { + case "luatextbox": + var stxt = new SyntaxRichTextBox(); + stxt.Text = text; + stxt.SetLanguage(SyntaxSettings.Language.Lua); + ctrl = stxt; + break; case "button": var btn = new Button(); btn.FlatStyle = FlatStyle.Flat; diff --git a/source/WindowsFormsApplication1/Online/Hacking/Matchmaker.cs b/source/WindowsFormsApplication1/Online/Hacking/Matchmaker.cs index 2c7d45b..1fb6f1b 100644 --- a/source/WindowsFormsApplication1/Online/Hacking/Matchmaker.cs +++ b/source/WindowsFormsApplication1/Online/Hacking/Matchmaker.cs @@ -140,7 +140,7 @@ public static void Matchmake(ServerInfo si) index += 1; } } - catch (Exception ex) + catch { } }; diff --git a/source/WindowsFormsApplication1/ShiftOS.csproj b/source/WindowsFormsApplication1/ShiftOS.csproj index 4066257..dcae2c7 100644 --- a/source/WindowsFormsApplication1/ShiftOS.csproj +++ b/source/WindowsFormsApplication1/ShiftOS.csproj @@ -103,6 +103,9 @@ Artpad.cs + + Component + Form