From 03b617823a0d6956b4a125de29903c4a71455255 Mon Sep 17 00:00:00 2001 From: "Mitch Capper (they, them)" Date: Mon, 24 Jul 2023 11:18:35 -0700 Subject: [PATCH] DependencyGraphViewer: Feature add same window navigation for NodeForm (#84542) * DependencyGraphViewer: Feature add same window navigation for NodeForm Add ability to reuse current window rather than open new, added history (forward/back) and arrow key accelerators as well. * Fix code formatting --------- Co-authored-by: David Wrighton --- .../aot/DependencyGraphViewer/NodeForm.Designer.cs | 50 ++++++++- .../tools/aot/DependencyGraphViewer/NodeForm.cs | 113 +++++++++++++++++++-- 2 files changed, 154 insertions(+), 9 deletions(-) diff --git a/src/coreclr/tools/aot/DependencyGraphViewer/NodeForm.Designer.cs b/src/coreclr/tools/aot/DependencyGraphViewer/NodeForm.Designer.cs index e01fe39..de1ee51 100644 --- a/src/coreclr/tools/aot/DependencyGraphViewer/NodeForm.Designer.cs +++ b/src/coreclr/tools/aot/DependencyGraphViewer/NodeForm.Designer.cs @@ -33,6 +33,9 @@ namespace DependencyLogViewer { this.nodeTitle = new System.Windows.Forms.Label(); this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.chkSameWindowNav = new System.Windows.Forms.CheckBox(); + this.btnBack = new System.Windows.Forms.Button(); + this.btnForward = new System.Windows.Forms.Button(); this.dependentsListBox = new System.Windows.Forms.ListBox(); this.exploreDependent = new System.Windows.Forms.Button(); this.dependeesListBox = new System.Windows.Forms.ListBox(); @@ -45,21 +48,22 @@ namespace DependencyLogViewer // // nodeTitle // - this.nodeTitle.AutoSize = true; this.nodeTitle.BackColor = System.Drawing.SystemColors.Info; this.nodeTitle.Dock = System.Windows.Forms.DockStyle.Top; this.nodeTitle.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); this.nodeTitle.Location = new System.Drawing.Point(0, 0); this.nodeTitle.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.nodeTitle.Name = "nodeTitle"; - this.nodeTitle.Size = new System.Drawing.Size(116, 30); + this.nodeTitle.Size = new System.Drawing.Size(1220, 75); this.nodeTitle.TabIndex = 0; this.nodeTitle.Text = "Node Title"; + this.nodeTitle.TextAlign = System.Drawing.ContentAlignment.BottomLeft; + this.nodeTitle.AutoEllipsis = true; // // splitContainer1 // this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; - this.splitContainer1.Location = new System.Drawing.Point(0, 30); + this.splitContainer1.Location = new System.Drawing.Point(0, 75); this.splitContainer1.Margin = new System.Windows.Forms.Padding(4); this.splitContainer1.Name = "splitContainer1"; this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; @@ -78,6 +82,39 @@ namespace DependencyLogViewer this.splitContainer1.SplitterWidth = 6; this.splitContainer1.TabIndex = 1; // + // chkSameWindowNav + // + this.chkSameWindowNav.AutoSize = true; + this.chkSameWindowNav.Location = new System.Drawing.Point(890, 0); + this.chkSameWindowNav.Name = "chkSameWindowNav"; + this.chkSameWindowNav.Size = new System.Drawing.Size(322, 36); + this.chkSameWindowNav.TabIndex = 5; + this.chkSameWindowNav.Text = "Same Window Nav"; + this.chkSameWindowNav.UseVisualStyleBackColor = true; + this.chkSameWindowNav.CheckedChanged += ChkSameWindowNav_CheckedChanged; + // + // btnBack + // + this.btnBack.Location = new System.Drawing.Point(607, 0); + this.btnBack.Margin = new System.Windows.Forms.Padding(4); + this.btnBack.Name = "btnBack"; + this.btnBack.Size = new System.Drawing.Size(124, 43); + this.btnBack.TabIndex = 3; + this.btnBack.Text = "Back"; + this.btnBack.UseVisualStyleBackColor = true; + this.btnBack.Click += btnBack_Click; + // + // btnForward + // + this.btnForward.Location = new System.Drawing.Point(750, 0); + this.btnForward.Margin = new System.Windows.Forms.Padding(4); + this.btnForward.Name = "btnForward"; + this.btnForward.Size = new System.Drawing.Size(124, 43); + this.btnForward.TabIndex = 4; + this.btnForward.Text = "Forward"; + this.btnForward.UseVisualStyleBackColor = true; + this.btnForward.Click += btnForward_Click; + // // dependentsListBox // this.dependentsListBox.Dock = System.Windows.Forms.DockStyle.Fill; @@ -133,6 +170,9 @@ namespace DependencyLogViewer this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 30F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(1126, 836); + Controls.Add(chkSameWindowNav); + Controls.Add(btnBack); + Controls.Add(btnForward); this.Controls.Add(this.splitContainer1); this.Controls.Add(this.nodeTitle); this.Margin = new System.Windows.Forms.Padding(4); @@ -148,6 +188,7 @@ namespace DependencyLogViewer } + #endregion private System.Windows.Forms.Label nodeTitle; @@ -156,5 +197,8 @@ namespace DependencyLogViewer private System.Windows.Forms.ListBox dependeesListBox; private System.Windows.Forms.Button exploreDependent; private System.Windows.Forms.ListBox dependentsListBox; + private System.Windows.Forms.Button btnBack; + private System.Windows.Forms.CheckBox chkSameWindowNav; + private System.Windows.Forms.Button btnForward; } } diff --git a/src/coreclr/tools/aot/DependencyGraphViewer/NodeForm.cs b/src/coreclr/tools/aot/DependencyGraphViewer/NodeForm.cs index 25c5a26..14793b7 100644 --- a/src/coreclr/tools/aot/DependencyGraphViewer/NodeForm.cs +++ b/src/coreclr/tools/aot/DependencyGraphViewer/NodeForm.cs @@ -10,17 +10,58 @@ namespace DependencyLogViewer public partial class NodeForm : Form { private readonly Graph _graph; - private readonly Node _node; + private Node _node; public NodeForm(Graph g, Node n) { _graph = g; - _node = n; - InitializeComponent(); + SetNode(n); + btnBack.Visible = btnForward.Visible = chkSameWindowNav.Checked; + var fixControls = new Control[] {btnBack, btnForward, chkSameWindowNav, exploreDependent, dependentsListBox, exploreDependee, dependeesListBox, this, this.splitContainer1 }; + foreach (var cntrl in fixControls) + { + cntrl.PreviewKeyDown += Cntrl_PreviewKeyDown; + cntrl.KeyDown += Cntrl_KeyDown; + } + } + + + private void Cntrl_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) { + if (!chkSameWindowNav.Checked) + return; + if (e.KeyCode == Keys.Left || e.KeyCode == Keys.Right) + e.IsInputKey = true; + } + + private void Cntrl_KeyDown(object sender, KeyEventArgs e) + { + if (!chkSameWindowNav.Checked) + return; + if (e.KeyCode == Keys.Left) + { + if (btnBack.Enabled) + btnBack.PerformClick(); + } + else if (e.KeyCode == Keys.Right) + { + if (btnForward.Enabled) + btnForward.PerformClick(); + } + else + return; + e.SuppressKeyPress = true; + e.Handled = true; + } + + public void SetNode(Node n) + { + + _node = n; this.Text = $"Graph Pid: {_graph.PID}, ID: {_graph.ID}, Node: {_node.ToString}"; - this.nodeTitle.Text = $"Current Node: {_node}"; + var nodeStr = _node.ToString().Replace(", ", "\n"); + this.nodeTitle.Text = $"Current Node: {nodeStr}"; lock (GraphCollection.Singleton) { @@ -39,6 +80,9 @@ namespace DependencyLogViewer this.dependentsListBox.DataSource = sourceNodes; this.dependeesListBox.DataSource = targetNodes; } + if (CurSpotInHistory == -1 && chkSameWindowNav.Checked)//if we are in history we dont modify history + AddSelfToHistory(); + SetNavButtonStates(); } private static void ExploreSelectedItem(Graph graph, ListBox listbox) @@ -54,14 +98,71 @@ namespace DependencyLogViewer private void exploreDependee_Click(object sender, EventArgs e) { - ExploreSelectedItem(_graph, dependeesListBox); + if (chkSameWindowNav.Checked != true) + { + ExploreSelectedItem(_graph, dependeesListBox); + return; + } + ClearHistoryIfIn(); + var selected = (BoxDisplay)dependeesListBox.SelectedItem; + SetNode(selected.node); } private void exploreDependent_Click(object sender, EventArgs e) { - ExploreSelectedItem(_graph, dependentsListBox); + if (chkSameWindowNav.Checked != true) + { + ExploreSelectedItem(_graph, dependentsListBox); + return; + } + ClearHistoryIfIn(); + var selected = (BoxDisplay)dependentsListBox.SelectedItem; + SetNode(selected.node); + } + private void AddSelfToHistory() + { + History.Add(_node); + } + private void ClearHistoryIfIn() + { + + if (CurSpotInHistory != -1) + { + var removeAfter = CurSpotInHistory + 1; + if (removeAfter != History.Count) + History.RemoveRange(removeAfter, History.Count - removeAfter); + CurSpotInHistory = -1; + } } + public int CurSpotInHistory = -1; + private List History = new(); + private void btnBack_Click(object sender, EventArgs e) + { + if (CurSpotInHistory == -1) + CurSpotInHistory = History.Count - 2; + else if (CurSpotInHistory == 0) // should not get here + return; + else + CurSpotInHistory--; + SetNode(History[CurSpotInHistory]); + } + private void btnForward_Click(object sender, EventArgs e) + { + if (CurSpotInHistory == -1)// should not get here + return; + else if (CurSpotInHistory == History.Count - 1) // should not get here + return; + else + CurSpotInHistory++; + SetNode(History[CurSpotInHistory]); + } + private void SetNavButtonStates() + { + btnBack.Enabled = CurSpotInHistory != 0 && History.Count > 1; + btnForward.Enabled = CurSpotInHistory != -1 && CurSpotInHistory != History.Count - 1; + } + private void ChkSameWindowNav_CheckedChanged(object sender, System.EventArgs e) => btnBack.Visible = btnForward.Visible = chkSameWindowNav.Checked; private void infoButton_LinkClicked(object sender, EventArgs e) { string dMessage = "Dependent nodes depend on the current node. The current node depends on the dependees."; -- 2.7.4