Debugger: Click and drag selection + copy code to clipboard

This commit is contained in:
Souryo 2017-03-11 10:59:26 -05:00
parent 2aa58ebd56
commit 4a1a441740
9 changed files with 113 additions and 45 deletions

View file

@ -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;
}
}

View file

@ -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<string> 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

View file

@ -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; }

View file

@ -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);

View file

@ -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);
}

View file

@ -947,6 +947,7 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Icon.ico" />
<None Include="Resources\Copy.png" />
<None Include="Resources\StepOut.png" />
<None Include="Resources\StepInto.png" />
<None Include="Resources\StepOver.png" />

View file

@ -190,6 +190,16 @@ namespace Mesen.GUI.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Copy {
get {
object obj = ResourceManager.GetObject("Copy", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>

View file

@ -286,4 +286,7 @@
<data name="StepOver" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\StepOver.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Copy" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Copy.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

BIN
GUI.NET/Resources/Copy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 B