Changeset 8980 for trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.cs
- Timestamp:
- 11/30/12 23:15:47 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.cs
r8946 r8980 21 21 22 22 using System; 23 using System.Collections.Generic; 23 24 using System.Drawing; 24 25 using System.Linq; … … 29 30 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views { 30 31 public sealed partial class InteractiveSymbolicExpressionTreeChart : SymbolicExpressionTreeChart { 31 private ISymbolicExpressionTreeNode tempNode; 32 private VisualSymbolicExpressionTreeNode lastSelected; // previously selected node 32 private ISymbolicExpressionTreeNode tempNode; // node in clipboard (to be cut/copy/pasted etc) 33 33 private VisualSymbolicExpressionTreeNode currSelected; // currently selected node 34 34 private enum EditOp { NoOp, CopyNode, CopySubtree, CutNode, CutSubtree, DeleteNode, DeleteSubtree } … … 37 37 private TreeState treeState = TreeState.Valid; // tree edit operations must leave the tree in a valid state 38 38 39 private Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> originalNodes; // map a new node to the original node it replaced 40 39 41 public InteractiveSymbolicExpressionTreeChart() { 40 42 InitializeComponent(); 41 // add extra actions in the context menu strips42 43 44 lastSelected = null;45 43 currSelected = null; 46 44 tempNode = null; 45 46 originalNodes = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>(); 47 47 } 48 48 … … 65 65 Repaint(); 66 66 } 67 foreach (var node in originalNodes.Keys) { 68 var visualNode = GetVisualSymbolicExpressionTreeNode(node); 69 if (visualNode == null) continue; 70 visualNode.LineColor = Color.DodgerBlue; 71 RepaintNode(visualNode); 72 } 67 73 } 68 74 69 75 private void contextMenuStrip_Opened(object sender, EventArgs e) { 70 var menu = sender as ContextMenuStrip; 71 if (menu == null) return; 76 var menuStrip = (ContextMenuStrip)sender; 77 var point = menuStrip.SourceControl.PointToClient(Cursor.Position); 78 var ea = new MouseEventArgs(MouseButtons.Left, 1, point.X, point.Y, 0); 79 InteractiveSymbolicExpressionTreeChart_MouseClick(null, ea); 80 72 81 if (currSelected == null) { 73 82 insertNodeToolStripMenuItem.Visible = false; 74 changeValueToolStripMenuItem.Visible = false;83 editNodeToolStripMenuItem.Visible = false; 75 84 copyToolStripMenuItem.Visible = false; 76 85 cutToolStripMenuItem.Visible = false; … … 79 88 } else { 80 89 var node = currSelected.SymbolicExpressionTreeNode; 81 changeValueToolStripMenuItem.Visible = (node is SymbolicExpressionTreeTerminalNode);82 insertNodeToolStripMenuItem.Visible = ! changeValueToolStripMenuItem.Visible;90 editNodeToolStripMenuItem.Visible = (node is SymbolicExpressionTreeTerminalNode); 91 insertNodeToolStripMenuItem.Visible = !editNodeToolStripMenuItem.Visible; 83 92 copyToolStripMenuItem.Visible = true; 84 93 cutToolStripMenuItem.Visible = true; … … 89 98 90 99 protected override void OnSymbolicExpressionTreeNodeClicked(object sender, MouseEventArgs e) { 91 var visualTreeNode = FindVisualSymbolicExpressionTreeNodeAt(e.X, e.Y); 92 if (visualTreeNode == null || visualTreeNode == currSelected) return; 93 lastSelected = currSelected; 94 if (lastSelected != null) 95 lastSelected.LineColor = Color.Black; 100 var visualTreeNode = (VisualSymbolicExpressionTreeNode)sender; 101 var lastSelected = currSelected; 102 if (lastSelected != null) { 103 lastSelected.LineColor = originalNodes.ContainsKey(lastSelected.SymbolicExpressionTreeNode) ? Color.DodgerBlue : Color.Black; 104 RepaintNode(lastSelected); 105 } 106 96 107 currSelected = visualTreeNode; 97 currSelected.LineColor = Color.LightGreen; 98 Repaint(); 99 base.OnSymbolicExpressionTreeNodeClicked(sender, e); 108 if (currSelected != null) { 109 currSelected.LineColor = Color.LightGreen; 110 RepaintNode(currSelected); 111 } 112 } 113 114 protected override void OnSymbolicExpressionTreeNodeDoubleClicked(object sender, MouseEventArgs e) { 115 var visualTreeNode = (VisualSymbolicExpressionTreeNode)sender; 116 if (originalNodes.ContainsKey(visualTreeNode.SymbolicExpressionTreeNode)) { 117 var originalNode = originalNodes[visualTreeNode.SymbolicExpressionTreeNode]; 118 119 var parent = visualTreeNode.SymbolicExpressionTreeNode.Parent; 120 var i = parent.IndexOfSubtree(visualTreeNode.SymbolicExpressionTreeNode); 121 parent.RemoveSubtree(i); 122 parent.InsertSubtree(i, originalNode); 123 124 originalNodes.Remove(visualTreeNode.SymbolicExpressionTreeNode); 125 visualTreeNode.SymbolicExpressionTreeNode = originalNode; 126 OnSymbolicExpressionTreeChanged(sender, EventArgs.Empty); 127 } else { 128 currSelected = null; // because the tree node will be folded/unfolded 129 base.OnSymbolicExpressionTreeNodeDoubleClicked(sender, e); 130 // at this point the tree got redrawn, so we mark the edited nodes 131 foreach (var node in originalNodes.Keys) { 132 var visualNode = GetVisualSymbolicExpressionTreeNode(node); 133 if (visualNode == null) continue; 134 visualNode.LineColor = Color.DodgerBlue; 135 RepaintNode(visualNode); 136 } 137 } 100 138 } 101 139 102 140 private void insertNodeToolStripMenuItem_Click(object sender, EventArgs e) { 103 141 if (currSelected == null || currSelected.SymbolicExpressionTreeNode is SymbolicExpressionTreeTerminalNode) return; 104 var node= currSelected.SymbolicExpressionTreeNode;142 var parent = currSelected.SymbolicExpressionTreeNode; 105 143 106 144 using (var dialog = new InsertNodeDialog()) { 107 dialog.SetAllowedSymbols(node.Grammar.AllowedSymbols.Where(s => s.Enabled && s.InitialFrequency > 0.0 && !(s is ProgramRootSymbol || s is StartSymbol || s is Defun))); 108 dialog.DialogValidated += InsertNodeDialog_Validated; 145 dialog.SetAllowedSymbols(parent.Grammar.AllowedSymbols.Where(s => s.Enabled && s.InitialFrequency > 0.0 && !(s is ProgramRootSymbol || s is StartSymbol || s is Defun))); 109 146 dialog.ShowDialog(this); 110 } 111 } 112 113 private void changeValueToolStripMenuItem_Click(object sender, EventArgs e) { 147 148 if (dialog.DialogResult == DialogResult.OK) { 149 var symbol = dialog.SelectedSymbol(); 150 var node = symbol.CreateTreeNode(); 151 if (node is ConstantTreeNode) { 152 var constant = node as ConstantTreeNode; 153 constant.Value = double.Parse(dialog.constantValueTextBox.Text); 154 } else if (node is VariableTreeNode) { 155 var variable = node as VariableTreeNode; 156 variable.Weight = double.Parse(dialog.variableWeightTextBox.Text); 157 variable.VariableName = dialog.variableNamesCombo.Text; 158 } else { 159 if (node.Symbol.MinimumArity <= parent.SubtreeCount && node.Symbol.MaximumArity >= parent.SubtreeCount) { 160 for (int i = parent.SubtreeCount - 1; i >= 0; --i) { 161 var child = parent.GetSubtree(i); 162 parent.RemoveSubtree(i); 163 node.AddSubtree(child); 164 } 165 } 166 } 167 if (parent.Symbol.MaximumArity > parent.SubtreeCount) { 168 parent.AddSubtree(node); 169 Tree = Tree; 170 } 171 OnSymbolicExpressionTreeChanged(sender, e); 172 } 173 } 174 } 175 176 private void editNodeToolStripMenuItem_Click(object sender, EventArgs e) { 114 177 if (currSelected == null) return; 115 var node = currSelected.SymbolicExpressionTreeNode; 116 using (var dialog = new ValueChangeDialog()) { 117 dialog.SetContent(node); 118 dialog.DialogValidated += ChangeValueDialog_Validated; 119 dialog.ShowDialog(this); 120 } 121 } 122 123 public event EventHandler SymbolicExpressionTreeNodeChanged; 124 private void OnSymbolicExpressionTreeNodeChanged(object sender, EventArgs e) { 125 var changed = SymbolicExpressionTreeNodeChanged; 126 if (changed != null) 127 SymbolicExpressionTreeNodeChanged(sender, e); 128 } 129 130 private void ChangeValueDialog_Validated(object sender, EventArgs e) { 131 OnSymbolicExpressionTreeNodeChanged(sender, e); 132 } 133 134 private void InsertNodeDialog_Validated(object sender, EventArgs e) { 135 var dialog = (InsertNodeDialog)sender; 136 var symbol = dialog.SelectedSymbol(); 137 var node = symbol.CreateTreeNode(); 138 var parent = currSelected.SymbolicExpressionTreeNode; 178 179 ISymbolicExpressionTreeNode node; 180 if (originalNodes.ContainsKey(currSelected.SymbolicExpressionTreeNode)) { 181 node = currSelected.SymbolicExpressionTreeNode; 182 } else { 183 node = (ISymbolicExpressionTreeNode)currSelected.SymbolicExpressionTreeNode.Clone(); 184 } 185 var originalNode = currSelected.SymbolicExpressionTreeNode; 186 ISymbolicExpressionTreeNode newNode = null; 187 var result = DialogResult.Cancel; 139 188 if (node is ConstantTreeNode) { 140 var constant = node as ConstantTreeNode; 141 constant.Value = double.Parse(dialog.constantValueTextBox.Text); 189 using (var dialog = new ConstantNodeEditDialog(node)) { 190 dialog.ShowDialog(this); 191 newNode = dialog.NewNode; 192 result = dialog.DialogResult; 193 } 142 194 } else if (node is VariableTreeNode) { 143 var variable = node as VariableTreeNode; 144 variable.Weight = double.Parse(dialog.variableWeightTextBox.Text); 145 variable.VariableName = dialog.variableNamesCombo.Text; 146 } else { 147 if (node.Symbol.MinimumArity <= parent.SubtreeCount && node.Symbol.MaximumArity >= parent.SubtreeCount) { 148 for (int i = parent.SubtreeCount - 1; i >= 0; --i) { 149 var child = parent.GetSubtree(i); 150 parent.RemoveSubtree(i); 151 node.AddSubtree(child); 152 } 153 } 154 } 155 if (parent.Symbol.MaximumArity > parent.SubtreeCount) { 156 parent.AddSubtree(node); 157 Tree = Tree; 158 } 159 OnSymbolicExpressionTreeChanged(sender, e); 195 using (var dialog = new VariableNodeEditDialog(node)) { 196 dialog.ShowDialog(this); 197 newNode = dialog.NewNode; 198 result = dialog.DialogResult; 199 } 200 } 201 if (result != DialogResult.OK) return; 202 if (originalNode != newNode) { 203 var parent = originalNode.Parent; 204 int i = parent.IndexOfSubtree(originalNode); 205 parent.RemoveSubtree(i); 206 parent.InsertSubtree(i, newNode); 207 originalNodes[newNode] = originalNode; 208 currSelected.SymbolicExpressionTreeNode = newNode; 209 } 210 OnSymbolicExpressionTreeChanged(sender, EventArgs.Empty); 160 211 } 161 212 … … 171 222 private void cutSubtreeToolStripMenuItem_Click(object sender, EventArgs e) { 172 223 lastOp = EditOp.CutSubtree; 173 tempNode = currSelected.SymbolicExpressionTreeNode; // should never be null224 tempNode = currSelected.SymbolicExpressionTreeNode; 174 225 foreach (var node in tempNode.IterateNodesPostfix()) { 175 226 var visualNode = GetVisualSymbolicExpressionTreeNode(node); … … 244 295 // check if the copied/cut node (stored in the tempNode) can be inserted as a child of the current selected node 245 296 var node = currSelected.SymbolicExpressionTreeNode; 246 if (node is ConstantTreeNode || node is VariableTreeNode) return; // nothing to do297 if (node is ConstantTreeNode || node is VariableTreeNode) return; 247 298 // check if the currently selected node can accept the copied node as a child 248 299 // no need to check the grammar, an arity check will do just fine here … … 254 305 // arity checks to see if parent can accept node's children (we assume the grammar is already ok with that) 255 306 // (otherise, the 'cut' part of the operation will just not do anything) 256 if (parent.Symbol.MaximumArity >= tempNode.SubtreeCount + parent.SubtreeCount - 1) { 257 // -1 because tempNode will be removed 307 if (parent.Symbol.MaximumArity >= tempNode.SubtreeCount + parent.SubtreeCount - 1) { // -1 because tempNode will be removed 258 308 parent.RemoveSubtree(parent.IndexOfSubtree(tempNode)); 259 309 for (int i = tempNode.SubtreeCount - 1; i >= 0; --i) { … … 263 313 } 264 314 lastOp = EditOp.CopyNode; 265 currSelected = null;266 315 } 267 316 break; … … 272 321 parent.RemoveSubtree(parent.IndexOfSubtree(tempNode)); 273 322 lastOp = EditOp.CopySubtree; // do this so the next paste will actually perform a copy 274 currSelected = null;275 323 break; 276 324 } 277 325 case (EditOp.CopyNode): { 278 326 // copy node 279 var clone = (SymbolicExpressionTreeNode)tempNode.Clone(); // should never be null327 var clone = (SymbolicExpressionTreeNode)tempNode.Clone(); 280 328 clone.Parent = tempNode.Parent; 281 329 tempNode = clone; … … 292 340 } 293 341 node.AddSubtree(tempNode); 294 Tree = Tree; // hack in order to trigger the reinitialization of the dictionaries after new nodes appeared in the graph342 Tree = Tree; // hack in order to trigger the reinitialization of the dictionaries after new nodes appeared in the tree 295 343 OnSymbolicExpressionTreeChanged(sender, e); 344 currSelected = null; // because the tree changed and was completely redrawn 296 345 } 297 346 } … … 305 354 return true; 306 355 } 356 357 private void InteractiveSymbolicExpressionTreeChart_MouseClick(object sender, MouseEventArgs e) { 358 var visualTreeNode = FindVisualSymbolicExpressionTreeNodeAt(e.X, e.Y); 359 if (currSelected != null) { 360 currSelected.LineColor = originalNodes.ContainsKey(currSelected.SymbolicExpressionTreeNode) ? Color.DodgerBlue : Color.Black; 361 } 362 currSelected = visualTreeNode; 363 if (currSelected != null) { 364 currSelected.LineColor = Color.LightGreen; 365 RepaintNode(currSelected); 366 } 367 } 307 368 } 308 369 }
Note: See TracChangeset
for help on using the changeset viewer.