1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Drawing; 5 using System.Data; 6 using System.Linq; 7 using System.Text; 8 using System.Threading.Tasks; 9 using System.Windows.Forms; 10 using Mesen.GUI.Controls; 11 using System.Collections.ObjectModel; 12 using Mesen.GUI.Config; 13 14 namespace Mesen.GUI.Debugger.Controls 15 { 16 public partial class ctrlBreakpoints : BaseControl 17 { 18 public event EventHandler BreakpointNavigation; 19 private Font _markedColumnFont; 20 ctrlBreakpoints()21 public ctrlBreakpoints() 22 { 23 InitializeComponent(); 24 } 25 OnLoad(EventArgs e)26 protected override void OnLoad(EventArgs e) 27 { 28 base.OnLoad(e); 29 if(!IsDesignMode) { 30 _markedColumnFont = new Font(this.Font.FontFamily, 13f); 31 32 mnuShowLabels.Checked = ConfigManager.Config.DebugInfo.ShowBreakpointLabels; 33 mnuShowLabels.CheckedChanged += mnuShowLabels_CheckedChanged; 34 35 BreakpointManager.BreakpointsChanged += BreakpointManager_OnBreakpointChanged; 36 mnuRemoveBreakpoint.Enabled = false; 37 mnuEditBreakpoint.Enabled = false; 38 mnuGoToLocation.Enabled = false; 39 40 InitShortcuts(); 41 } 42 } 43 InitShortcuts()44 private void InitShortcuts() 45 { 46 mnuAddBreakpoint.InitShortcut(this, nameof(DebuggerShortcutsConfig.BreakpointList_Add)); 47 mnuEditBreakpoint.InitShortcut(this, nameof(DebuggerShortcutsConfig.BreakpointList_Edit)); 48 mnuRemoveBreakpoint.InitShortcut(this, nameof(DebuggerShortcutsConfig.BreakpointList_Delete)); 49 mnuGoToLocation.InitShortcut(this, nameof(DebuggerShortcutsConfig.BreakpointList_GoToLocation)); 50 } 51 BreakpointManager_OnBreakpointChanged(object sender, EventArgs e)52 private void BreakpointManager_OnBreakpointChanged(object sender, EventArgs e) 53 { 54 if(this.InvokeRequired) { 55 this.BeginInvoke((Action)(() => RefreshList())); 56 } else { 57 RefreshList(); 58 } 59 } 60 RefreshListAddresses()61 public void RefreshListAddresses() 62 { 63 lstBreakpoints.BeginUpdate(); 64 ReadOnlyCollection<Breakpoint> breakpoints = BreakpointManager.Breakpoints; 65 for(int i = 0; i < breakpoints.Count; i++) { 66 lstBreakpoints.Items[i].SubItems[3].Text = breakpoints[i].GetAddressString(mnuShowLabels.Checked); 67 } 68 lstBreakpoints.EndUpdate(); 69 } 70 RefreshList()71 public void RefreshList() 72 { 73 lstBreakpoints.ItemChecked -= new ItemCheckedEventHandler(lstBreakpoints_ItemChecked); 74 75 int topIndex = lstBreakpoints.TopItem != null ? lstBreakpoints.TopItem.Index : 0; 76 lstBreakpoints.BeginUpdate(); 77 lstBreakpoints.Items.Clear(); 78 foreach(Breakpoint breakpoint in BreakpointManager.Breakpoints) { 79 ListViewItem item = new ListViewItem(); 80 item.Tag = breakpoint; 81 item.Checked = breakpoint.Enabled; 82 item.UseItemStyleForSubItems = false; 83 item.SubItems.Add(breakpoint.MarkEvent ? "☑" : "☐").Font = _markedColumnFont; 84 item.SubItems.Add(breakpoint.ToReadableType()); 85 item.SubItems.Add(breakpoint.GetAddressString(mnuShowLabels.Checked)); 86 item.SubItems.Add(breakpoint.Condition); 87 lstBreakpoints.Items.Add(item); 88 } 89 lstBreakpoints.EndUpdate(); 90 if(lstBreakpoints.Items.Count > 0) { 91 lstBreakpoints.TopItem = lstBreakpoints.Items[lstBreakpoints.Items.Count > topIndex ? topIndex : lstBreakpoints.Items.Count - 1]; 92 } 93 94 lstBreakpoints.ItemChecked += new ItemCheckedEventHandler(lstBreakpoints_ItemChecked); 95 } 96 lstBreakpoints_ItemChecked(object sender, ItemCheckedEventArgs e)97 private void lstBreakpoints_ItemChecked(object sender, ItemCheckedEventArgs e) 98 { 99 if(((Breakpoint)e.Item.Tag).Enabled != e.Item.Checked) { 100 ((Breakpoint)e.Item.Tag).SetEnabled(e.Item.Checked); 101 } 102 } 103 lstBreakpoints_DoubleClick(object sender, EventArgs e)104 private void lstBreakpoints_DoubleClick(object sender, EventArgs e) 105 { 106 if(lstBreakpoints.SelectedItems.Count > 0) { 107 BreakpointManager.EditBreakpoint(((Breakpoint)lstBreakpoints.SelectedItems[0].Tag)); 108 } 109 } 110 mnuRemoveBreakpoint_Click(object sender, EventArgs e)111 private void mnuRemoveBreakpoint_Click(object sender, EventArgs e) 112 { 113 foreach(ListViewItem item in lstBreakpoints.SelectedItems) { 114 BreakpointManager.RemoveBreakpoint((Breakpoint)item.Tag); 115 } 116 } 117 mnuAddBreakpoint_Click(object sender, EventArgs e)118 private void mnuAddBreakpoint_Click(object sender, EventArgs e) 119 { 120 Breakpoint breakpoint = new Breakpoint(); 121 if(new frmBreakpoint(breakpoint).ShowDialog() == DialogResult.OK) { 122 BreakpointManager.AddBreakpoint(breakpoint); 123 } 124 } 125 mnuGoToLocation_Click(object sender, EventArgs e)126 private void mnuGoToLocation_Click(object sender, EventArgs e) 127 { 128 if(BreakpointNavigation != null) { 129 Breakpoint bp = lstBreakpoints.SelectedItems[0].Tag as Breakpoint; 130 if(bp.IsCpuBreakpoint && bp.GetRelativeAddress() >= 0) { 131 BreakpointNavigation(bp, null); 132 } 133 } 134 } 135 mnuEditBreakpoint_Click(object sender, EventArgs e)136 private void mnuEditBreakpoint_Click(object sender, EventArgs e) 137 { 138 if(lstBreakpoints.SelectedItems.Count > 0) { 139 BreakpointManager.EditBreakpoint(((Breakpoint)lstBreakpoints.SelectedItems[0].Tag)); 140 } 141 } 142 lstBreakpoints_SelectedIndexChanged(object sender, EventArgs e)143 private void lstBreakpoints_SelectedIndexChanged(object sender, EventArgs e) 144 { 145 mnuRemoveBreakpoint.Enabled = (lstBreakpoints.SelectedItems.Count > 0); 146 mnuEditBreakpoint.Enabled = (lstBreakpoints.SelectedItems.Count == 1); 147 if(lstBreakpoints.SelectedItems.Count == 1) { 148 Breakpoint bp = lstBreakpoints.SelectedItems[0].Tag as Breakpoint; 149 mnuGoToLocation.Enabled = bp.IsCpuBreakpoint && bp.GetRelativeAddress() >= 0; 150 } 151 152 } 153 mnuShowLabels_CheckedChanged(object sender, EventArgs e)154 private void mnuShowLabels_CheckedChanged(object sender, EventArgs e) 155 { 156 ConfigManager.Config.DebugInfo.ShowBreakpointLabels = mnuShowLabels.Checked; 157 ConfigManager.ApplyChanges(); 158 159 this.RefreshListAddresses(); 160 } 161 lstBreakpoints_MouseDown(object sender, MouseEventArgs e)162 private void lstBreakpoints_MouseDown(object sender, MouseEventArgs e) 163 { 164 ListViewHitTestInfo info = lstBreakpoints.HitTest(e.X, e.Y); 165 if(info != null && info.Item != null) { 166 int row = info.Item.Index; 167 int col = info.Item.SubItems.IndexOf(info.SubItem); 168 169 if(col == 1 && row < lstBreakpoints.Items.Count) { 170 this.BeginInvoke((Action)(() => { 171 Breakpoint bp = lstBreakpoints.Items[row].Tag as Breakpoint; 172 bp?.SetMarked(!bp.MarkEvent); 173 })); 174 } 175 } 176 } 177 } 178 } 179