From 4a1a44174022f7183639f6272a59b306f67ed345 Mon Sep 17 00:00:00 2001 From: Souryo Date: Sat, 11 Mar 2017 10:59:26 -0500 Subject: [PATCH] Debugger: Click and drag selection + copy code to clipboard --- .../Controls/ctrlDebuggerCode.Designer.cs | 18 +++- GUI.NET/Debugger/Controls/ctrlDebuggerCode.cs | 11 +- .../Controls/ctrlScrollableTextbox.cs | 15 +-- GUI.NET/Debugger/Controls/ctrlTextbox.cs | 98 +++++++++++++----- GUI.NET/Debugger/LabelManager.cs | 2 +- GUI.NET/GUI.NET.csproj | 1 + GUI.NET/Properties/Resources.Designer.cs | 10 ++ GUI.NET/Properties/Resources.resx | 3 + GUI.NET/Resources/Copy.png | Bin 0 -> 393 bytes 9 files changed, 113 insertions(+), 45 deletions(-) create mode 100644 GUI.NET/Resources/Copy.png diff --git a/GUI.NET/Debugger/Controls/ctrlDebuggerCode.Designer.cs b/GUI.NET/Debugger/Controls/ctrlDebuggerCode.Designer.cs index e253ca43..07b9b167 100644 --- a/GUI.NET/Debugger/Controls/ctrlDebuggerCode.Designer.cs +++ b/GUI.NET/Debugger/Controls/ctrlDebuggerCode.Designer.cs @@ -31,6 +31,7 @@ this.contextMenuCode = new System.Windows.Forms.ContextMenuStrip(this.components); this.mnuEditSelectedCode = new System.Windows.Forms.ToolStripMenuItem(); this.mnuEditSubroutine = new System.Windows.Forms.ToolStripMenuItem(); + this.copySelectionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem7 = new System.Windows.Forms.ToolStripSeparator(); this.mnuShowNextStatement = new System.Windows.Forms.ToolStripMenuItem(); this.mnuSetNextStatement = new System.Windows.Forms.ToolStripMenuItem(); @@ -85,6 +86,7 @@ this.contextMenuCode.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.mnuEditSelectedCode, this.mnuEditSubroutine, + this.copySelectionToolStripMenuItem, this.toolStripMenuItem7, this.mnuShowNextStatement, this.mnuSetNextStatement, @@ -102,7 +104,7 @@ this.mnuNavigateBackward, this.mnuNavigateForward}); this.contextMenuCode.Name = "contextMenuWatch"; - this.contextMenuCode.Size = new System.Drawing.Size(259, 342); + this.contextMenuCode.Size = new System.Drawing.Size(259, 364); this.contextMenuCode.Closed += new System.Windows.Forms.ToolStripDropDownClosedEventHandler(this.contextMenuCode_Closed); this.contextMenuCode.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuCode_Opening); // @@ -111,7 +113,7 @@ this.mnuEditSelectedCode.Image = global::Mesen.GUI.Properties.Resources.Edit; this.mnuEditSelectedCode.Name = "mnuEditSelectedCode"; this.mnuEditSelectedCode.Size = new System.Drawing.Size(258, 22); - this.mnuEditSelectedCode.Text = "Edit selected code"; + this.mnuEditSelectedCode.Text = "Edit Selected Code"; this.mnuEditSelectedCode.Click += new System.EventHandler(this.mnuEditSelectedCode_Click); // // mnuEditSubroutine @@ -120,9 +122,18 @@ this.mnuEditSubroutine.Name = "mnuEditSubroutine"; this.mnuEditSubroutine.ShortcutKeys = System.Windows.Forms.Keys.F4; this.mnuEditSubroutine.Size = new System.Drawing.Size(258, 22); - this.mnuEditSubroutine.Text = "Edit subroutine"; + this.mnuEditSubroutine.Text = "Edit Subroutine"; this.mnuEditSubroutine.Click += new System.EventHandler(this.mnuEditSubroutine_Click); // + // copySelectionToolStripMenuItem + // + this.copySelectionToolStripMenuItem.Image = global::Mesen.GUI.Properties.Resources.Copy; + this.copySelectionToolStripMenuItem.Name = "copySelectionToolStripMenuItem"; + this.copySelectionToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C))); + this.copySelectionToolStripMenuItem.Size = new System.Drawing.Size(258, 22); + this.copySelectionToolStripMenuItem.Text = "Copy Selection"; + this.copySelectionToolStripMenuItem.Click += new System.EventHandler(this.copySelectionToolStripMenuItem_Click); + // // toolStripMenuItem7 // this.toolStripMenuItem7.Name = "toolStripMenuItem7"; @@ -520,5 +531,6 @@ private System.Windows.Forms.ToolStripSeparator toolStripMenuItem7; private System.Windows.Forms.ToolStripMenuItem mnuEditSubroutine; private System.Windows.Forms.ToolStripMenuItem mnuEditSelectedCode; + private System.Windows.Forms.ToolStripMenuItem copySelectionToolStripMenuItem; } } diff --git a/GUI.NET/Debugger/Controls/ctrlDebuggerCode.cs b/GUI.NET/Debugger/Controls/ctrlDebuggerCode.cs index 4be71117..819b79c5 100644 --- a/GUI.NET/Debugger/Controls/ctrlDebuggerCode.cs +++ b/GUI.NET/Debugger/Controls/ctrlDebuggerCode.cs @@ -163,18 +163,18 @@ namespace Mesen.GUI.Debugger public void SetActiveAddress(UInt32 address) { _currentActiveAddress = address; + this.UpdateLineColors(); } public void ClearActiveAddress() { _currentActiveAddress = null; + this.UpdateLineColors(); } public void UpdateLineColors() { - this.ctrlCodeViewer.BeginUpdate(); this.ctrlCodeViewer.StyleProvider = new LineStyleProvider(this); - this.ctrlCodeViewer.EndUpdate(); } public List GetCode(out int byteLength, ref int startAddress, int endAddress = -1) @@ -197,7 +197,7 @@ namespace Mesen.GUI.Debugger if(_codeContent.TryGetValue(i, out code)) { code = code.Split('\x2')[0].Trim(); - if(code.StartsWith("--") || code.StartsWith("__") || code.StartsWith("[[")) { + if(code.StartsWith("--") || code.StartsWith("__")) { //Stop adding code when we find a new section (new function, data blocks, etc.) break; } @@ -861,6 +861,11 @@ namespace Mesen.GUI.Debugger return null; } } + + private void copySelectionToolStripMenuItem_Click(object sender, EventArgs e) + { + this.ctrlCodeViewer.CopySelection(); + } } public class WatchEventArgs : EventArgs diff --git a/GUI.NET/Debugger/Controls/ctrlScrollableTextbox.cs b/GUI.NET/Debugger/Controls/ctrlScrollableTextbox.cs index 6577ed9b..f0885436 100644 --- a/GUI.NET/Debugger/Controls/ctrlScrollableTextbox.cs +++ b/GUI.NET/Debugger/Controls/ctrlScrollableTextbox.cs @@ -105,16 +105,6 @@ namespace Mesen.GUI.Debugger this.hScrollBar.Maximum = newMax; } - public void BeginUpdate() - { - this.ctrlTextbox.BeginUpdate(); - } - - public void EndUpdate() - { - this.ctrlTextbox.EndUpdate(); - } - public ctrlTextbox.ILineStyleProvider StyleProvider { set { this.ctrlTextbox.StyleProvider = value; } } public int GetLineIndex(int lineNumber) @@ -147,6 +137,11 @@ namespace Mesen.GUI.Debugger this.ctrlTextbox.ScrollToLineNumber(lineNumber, historyType); } + public void CopySelection() + { + this.ctrlTextbox.CopySelection(); + } + public int CurrentLine { get { return this.ctrlTextbox.CurrentLine; } diff --git a/GUI.NET/Debugger/Controls/ctrlTextbox.cs b/GUI.NET/Debugger/Controls/ctrlTextbox.cs index c4e21e58..2b943210 100644 --- a/GUI.NET/Debugger/Controls/ctrlTextbox.cs +++ b/GUI.NET/Debugger/Controls/ctrlTextbox.cs @@ -70,7 +70,6 @@ namespace Mesen.GUI.Debugger private int _extendedMarginWidth = 13; private float _maxLineWidth = 0; private int _maxLineWidthIndex = 0; - private bool _updating = false; public ctrlTextbox() { @@ -248,7 +247,7 @@ namespace Mesen.GUI.Debugger for(int i = 0, len = _contents.Length; i < len; i++) { string line = _contents[i] + Addressing?[i] + (Comments != null ? ("\t" + Comments[i]) : null); if(Regex.IsMatch(line, regex, matchCase ? RegexOptions.None : RegexOptions.IgnoreCase)) { - if(line.StartsWith("__") && line.EndsWith("__") || line.StartsWith("[[") && line.EndsWith("]]")) { + if(line.StartsWith("__") && line.EndsWith("__")) { line = "Block: " + line.Substring(2, line.Length - 4); } @@ -318,23 +317,21 @@ namespace Mesen.GUI.Debugger } } - public void BeginUpdate() - { - this._updating = true; - } - - public void EndUpdate() - { - this._updating = false; - this.Invalidate(); - } - public interface ILineStyleProvider { LineProperties GetLineStyle(int cpuAddress); } - public ILineStyleProvider StyleProvider { get; set; } + private ILineStyleProvider _styleProvider; + public ILineStyleProvider StyleProvider + { + get { return _styleProvider; } + set + { + _styleProvider = value; + this.Invalidate(); + } + } public LineProperties GetLineStyle(int lineNumber) { @@ -682,6 +679,8 @@ namespace Mesen.GUI.Debugger } } + int _clickedLine; + bool _mouseDragging; protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); @@ -692,29 +691,79 @@ namespace Mesen.GUI.Debugger } else if(e.Button == MouseButtons.XButton2) { this.NavigateForward(); } else { - int clickedLine = this.ScrollPosition + this.GetLineAtPosition(e.Y); + _clickedLine = this.ScrollPosition + this.GetLineAtPosition(e.Y); if(e.Button == MouseButtons.Right) { - if(clickedLine >= this.SelectionStart && clickedLine <= this.SelectionStart + this.SelectionLength) { + if(_clickedLine >= this.SelectionStart && _clickedLine <= this.SelectionStart + this.SelectionLength) { //Right-clicking on selection should not change it return; } } if(Control.ModifierKeys.HasFlag(Keys.Shift)) { - if(clickedLine > this.SelectedLine) { - MoveSelectionDown(clickedLine - this.SelectedLine); + if(_clickedLine > this.SelectedLine) { + MoveSelectionDown(_clickedLine - this.SelectedLine); } else { - MoveSelectionUp(this.SelectedLine - clickedLine); + MoveSelectionUp(this.SelectedLine - _clickedLine); } } else { - this.SelectedLine = clickedLine; - this.SelectionStart = clickedLine; + _mouseDragging = true; + this.SelectedLine = _clickedLine; + this.SelectionStart = _clickedLine; this.SelectionLength = 0; } } } + protected override void OnMouseUp(MouseEventArgs e) + { + _mouseDragging = false; + base.OnMouseUp(e); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + if(_mouseDragging) { + int lineUnderMouse = this.ScrollPosition + this.GetLineAtPosition(e.Y); + this.SelectedLine = lineUnderMouse; + this.SelectedLine = lineUnderMouse; + if(lineUnderMouse > _clickedLine) { + this.SelectionLength = lineUnderMouse - _clickedLine; + } else { + this.SelectedLine = lineUnderMouse; + this.SelectionStart = lineUnderMouse; + this.SelectionLength = _clickedLine - lineUnderMouse; + } + } + base.OnMouseMove(e); + } + + public void CopySelection() + { + StringBuilder sb = new StringBuilder(); + for(int i = this.SelectionStart, end = this.SelectionStart + this.SelectionLength; i <= end; i++) { + string indent = ""; + if(LineIndentations != null) { + indent = "".PadLeft(LineIndentations[i] / 10); + } + + string codeString = _contents[i].Trim(); + if(codeString.StartsWith("__") || codeString.StartsWith("--")) { + codeString = "--------" + codeString.Substring(2, codeString.Length - 4) + "--------"; + } + + string commentString = Comments?[i].Trim() ?? ""; + int padding = Math.Max(CommentSpacingCharCount, codeString.Length); + if(codeString.Length == 0) { + padding = 0; + } + + codeString = codeString.PadRight(padding); + sb.AppendLine(indent + codeString + commentString); + } + Clipboard.SetText(sb.ToString()); + } + public void NavigateForward() { this.ScrollToLineIndex(_history.GoForward(), eHistoryType.None); @@ -814,13 +863,6 @@ namespace Mesen.GUI.Debugger g.DrawString(text, this._noteFont, fgBrush, (marginLeft + this.Width - textLength) / 2, positionY + 4); g.DrawLine(Pens.Black, marginLeft, positionY+2, marginLeft+this.Width, positionY+2); g.TranslateTransform(-HorizontalScrollPosition * HorizontalScrollFactor, 0); - } else if(codeString.StartsWith("[[") && codeString.EndsWith("]]")) { - //Draw small centered text - g.TranslateTransform(HorizontalScrollPosition * HorizontalScrollFactor, 0); - string text = codeString.Substring(2, codeString.Length - 4); - float textLength = g.MeasureString(text, this._noteFont).Width; - g.DrawString(text, new Font(this._noteFont, FontStyle.Italic), fgBrush, (marginLeft + this.Width - textLength) / 2, positionY + 2); - g.TranslateTransform(-HorizontalScrollPosition * HorizontalScrollFactor, 0); } else { //Draw line content g.DrawString(codeString, this.Font, fgBrush, marginLeft, positionY); diff --git a/GUI.NET/Debugger/LabelManager.cs b/GUI.NET/Debugger/LabelManager.cs index a8d8a591..f519a1e4 100644 --- a/GUI.NET/Debugger/LabelManager.cs +++ b/GUI.NET/Debugger/LabelManager.cs @@ -69,7 +69,7 @@ namespace Mesen.GUI.Debugger _reverseLookup[label] = _labels[GetKey(address, type)]; } - InteropEmu.DebugSetLabel(address, type, label, comment); + InteropEmu.DebugSetLabel(address, type, label, comment.Replace(Environment.NewLine, "\n")); if(raiseEvent) { OnLabelUpdated?.Invoke(null, null); } diff --git a/GUI.NET/GUI.NET.csproj b/GUI.NET/GUI.NET.csproj index 4422d65e..f496eb7e 100644 --- a/GUI.NET/GUI.NET.csproj +++ b/GUI.NET/GUI.NET.csproj @@ -947,6 +947,7 @@ Always + diff --git a/GUI.NET/Properties/Resources.Designer.cs b/GUI.NET/Properties/Resources.Designer.cs index 67255edb..4fd61382 100644 --- a/GUI.NET/Properties/Resources.Designer.cs +++ b/GUI.NET/Properties/Resources.Designer.cs @@ -190,6 +190,16 @@ namespace Mesen.GUI.Properties { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Copy { + get { + object obj = ResourceManager.GetObject("Copy", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/GUI.NET/Properties/Resources.resx b/GUI.NET/Properties/Resources.resx index b6a26123..d9462ce9 100644 --- a/GUI.NET/Properties/Resources.resx +++ b/GUI.NET/Properties/Resources.resx @@ -286,4 +286,7 @@ ..\Resources\StepOver.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Copy.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/GUI.NET/Resources/Copy.png b/GUI.NET/Resources/Copy.png new file mode 100644 index 0000000000000000000000000000000000000000..29153704674562bb7911626981ac713c5f4c7a18 GIT binary patch literal 393 zcmV;40e1e0P) KMK`oJJU4u@cS5UYBKf&%yzLEJ@`|~Dem~&2^c_%Z2)^!C|aU9>D zpDUaza2)5h%`kwCFbvmuo=*eUpK+)CXzu_smt}#rZ4XP!vP|+>mJuhe>)uclMQ<%D ziUOLZk$*{&pss5W1ObvHA&{>u=Xt(1O>?OEzQ6M0I1>7qWy3ItWxOq2*SFf`a)DtO zfTI9}&>^sA@x@JYn-8Q_(JR{(Y)?C58JD2m%0AHdH5+-F(V_AYq#6h7&%7o};s<;X?aTRRiI nGpsNmux