Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
11/22/12 15:03:32 (11 years ago)
Author:
bburlacu
Message:

#1763: Bugfixes and refactoring as suggested in the comments above.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.cs

    r8916 r8935  
    4040      InitializeComponent();
    4141      // add extra actions in the context menu strips
    42       this.contextMenuStrip.Opened += this.contextMenuStrip_Opened;
    43       this.contextMenuStrip.Items.AddRange(new ToolStripItem[] {
    44                                                insertNodeToolStripMenuItem,
    45                                                changeValueToolStripMenuItem,
    46                                                copyToolStripMenuItem,
    47                                                cutToolStripMenuItem,
    48                                                deleteToolStripMenuItem,
    49                                                pasteToolStripMenuItem });
     42
     43
    5044      lastSelected = null;
    5145      currSelected = null;
     
    5347    }
    5448
    55     public bool TreeValid {
    56       get { return TreeState.Valid == treeState; }
    57     }
    58 
     49    public bool TreeValid { get { return TreeState.Valid == treeState; } }
    5950    // expose an additional event for signaling to the parent view when the tree structure was modified
    6051    // the emitting of the signal is conditional on the tree being valid, otherwise only a Repaint is issued
     
    6657        treeState = TreeState.Valid;
    6758        var changed = SymbolicExpressionTreeChanged;
    68         if (changed != null) {
     59        if (changed != null)
    6960          changed(sender, e);
    70         }
    7161      } else {
    7262        treeStatusValue.Text = "Invalid";
     
    8070      var menu = sender as ContextMenuStrip;
    8171      if (menu == null) return;
    82       var point = menu.SourceControl.PointToClient(Cursor.Position);
    83       var visualNode = FindVisualSymbolicExpressionTreeNodeAt(point.X, point.Y);
    84       if (visualNode != null) {
    85         lastSelected = currSelected;
    86         if (lastSelected != null) lastSelected.LineColor = Color.Black;
    87         currSelected = visualNode;
    88         currSelected.LineColor = Color.LightGreen;
    89         EnableTreeEditingMenuItems();
    90         OnSymbolicExpressionTreeNodeClicked(currSelected, new MouseEventArgs(MouseButtons.Right, 1, point.X, point.Y, 0));
     72      if (currSelected == null) {
     73        insertNodeToolStripMenuItem.Visible = false;
     74        changeValueToolStripMenuItem.Visible = false;
     75        copyToolStripMenuItem.Visible = false;
     76        cutToolStripMenuItem.Visible = false;
     77        deleteToolStripMenuItem.Visible = false;
     78        pasteToolStripMenuItem.Visible = false;
    9179      } else {
    92         DisableTreeEditingMenuItems();
    93       }
    94     }
    95 
    96     private void DisableTreeEditingMenuItems() {
    97       insertNodeToolStripMenuItem.Visible = false;
    98       changeValueToolStripMenuItem.Visible = false;
    99       copyToolStripMenuItem.Visible = false;
    100       cutToolStripMenuItem.Visible = false;
    101       deleteToolStripMenuItem.Visible = false;
    102       pasteToolStripMenuItem.Visible = false;
    103     }
    104 
    105     private void EnableTreeEditingMenuItems() {
    106 
    107       var node = currSelected.SymbolicExpressionTreeNode;
    108       changeValueToolStripMenuItem.Visible = (node is SymbolicExpressionTreeTerminalNode);
    109       insertNodeToolStripMenuItem.Visible = !changeValueToolStripMenuItem.Visible;
    110       copyToolStripMenuItem.Visible = true;
    111       cutToolStripMenuItem.Visible = true;
    112       deleteToolStripMenuItem.Visible = true;
    113       pasteToolStripMenuItem.Visible = (lastOp == EditOp.CopyNode || lastOp == EditOp.CopySubtree || lastOp == EditOp.CutNode || lastOp == EditOp.CutSubtree) && insertNodeToolStripMenuItem.Visible;
    114     }
    115 
    116 
    117     protected override void SymbolicExpressionTreeChart_MouseClick(object sender, MouseEventArgs e) {
    118       VisualSymbolicExpressionTreeNode visualTreeNode = FindVisualSymbolicExpressionTreeNodeAt(e.X, e.Y);
    119       if (visualTreeNode != null) {
    120         lastSelected = currSelected;
    121         if (lastSelected != null) lastSelected.LineColor = Color.Black;
    122         currSelected = visualTreeNode;
    123         currSelected.LineColor = Color.LightGreen;
    124       }
    125       Repaint();
    126       base.SymbolicExpressionTreeChart_MouseClick(sender, e);
     80        var node = currSelected.SymbolicExpressionTreeNode;
     81        changeValueToolStripMenuItem.Visible = (node is SymbolicExpressionTreeTerminalNode);
     82        insertNodeToolStripMenuItem.Visible = !changeValueToolStripMenuItem.Visible;
     83        copyToolStripMenuItem.Visible = true;
     84        cutToolStripMenuItem.Visible = true;
     85        deleteToolStripMenuItem.Visible = true;
     86        pasteToolStripMenuItem.Visible = tempNode != null && insertNodeToolStripMenuItem.Visible;
     87      }
     88    }
     89
     90    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;
     96      currSelected = visualTreeNode;
     97      currSelected.LineColor = Color.LightGreen;
     98      Repaint();
     99      base.OnSymbolicExpressionTreeNodeClicked(sender, e);
    127100    }
    128101
     
    131104      var node = currSelected.SymbolicExpressionTreeNode;
    132105
    133       var dialog = new InsertNodeDialog();
    134       dialog.SetAllowedSymbols(node.Grammar.AllowedSymbols.Where(s => s.Enabled && s.InitialFrequency > 0.0 && !(s is ProgramRootSymbol || s is StartSymbol || s is Defun)));
    135       dialog.DialogValidated += OnInsertNodeDialogValidated;
    136       dialog.ShowDialog(this);
     106      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;
     109        dialog.ShowDialog(this);
     110      }
    137111    }
    138112
     
    140114      if (currSelected == null) return;
    141115      var node = currSelected.SymbolicExpressionTreeNode;
    142       var dialog = new ValueChangeDialog();
    143       dialog.SetContent(node);
    144       dialog.DialogValidated += OnChangeValueDialogValidated;
    145       dialog.ShowDialog(this);
     116      using (var dialog = new ValueChangeDialog()) {
     117        dialog.SetContent(node);
     118        dialog.DialogValidated += ChangeValueDialog_Validated;
     119        dialog.ShowDialog(this);
     120      }
    146121    }
    147122
    148123    public event EventHandler SymbolicExpressionTreeNodeChanged;
    149 
    150     private void OnChangeValueDialogValidated(object sender, EventArgs e) {
    151       SymbolicExpressionTreeNodeChanged(sender, e);
    152     }
    153 
    154     private void OnInsertNodeDialogValidated(object sender, EventArgs e) {
     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) {
    155135      var dialog = (InsertNodeDialog)sender;
    156136      var symbol = dialog.SelectedSymbol();
     
    172152          }
    173153        }
    174         // we assume that there is no case in which the parents subtrees get transferred to node, but node doesn't get added as a subtree of parent
    175154      }
    176155      if (parent.Symbol.MaximumArity > parent.SubtreeCount) {
     
    210189      lastOp = EditOp.CopyNode;
    211190      tempNode = currSelected.SymbolicExpressionTreeNode;
    212       var visualNode = visualTreeNodes[tempNode];
    213       visualNode.LineColor = Color.LightGray;
    214       visualNode.TextColor = Color.LightGray;
     191      currSelected.LineColor = Color.LightGray;
     192      currSelected.TextColor = Color.LightGray;
    215193      Repaint();
    216194    }
     
    223201        visualNode.LineColor = Color.LightGray;
    224202        visualNode.TextColor = Color.LightGray;
    225         if (node.SubtreeCount > 0) {
    226           foreach (var subtree in node.Subtrees) {
    227             var visualLine = visualLines[new Tuple<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>(node, subtree)];
    228             visualLine.LineColor = Color.LightGray;
    229           }
     203        if (node.SubtreeCount <= 0) continue;
     204        foreach (var subtree in node.Subtrees) {
     205          var visualLine = visualLines[new Tuple<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>(node, subtree)];
     206          visualLine.LineColor = Color.LightGray;
    230207        }
    231208      }
     
    237214      var node = currSelected.SymbolicExpressionTreeNode;
    238215      var parent = node.Parent;
     216      if (parent == null || parent.Symbol is StartSymbol || parent.Symbol is ProgramRootSymbol)
     217        return; // the operation would result in the deletion of the entire tree
    239218      if (parent.Symbol.MaximumArity >= node.SubtreeCount + parent.SubtreeCount - 1) { // -1 because tempNode will be removed
    240219        parent.RemoveSubtree(parent.IndexOfSubtree(node));
     
    244223          parent.AddSubtree(child);
    245224        }
    246       } else {
    247         // if the node cannot be deleted without breaking the tree, do nothing
    248         // TODO: decide what to do
    249       }
     225      }
     226      currSelected = null; // because the currently selected node was just deleted
    250227      OnSymbolicExpressionTreeChanged(sender, e);
    251228    }
     
    255232      var node = currSelected.SymbolicExpressionTreeNode;
    256233      var parent = node.Parent;
     234      if (parent == null || parent.Symbol is StartSymbol || parent.Symbol is ProgramRootSymbol)
     235        return; // the operation makes no sense as it would result in the deletion of the entire tree
    257236      parent.RemoveSubtree(parent.IndexOfSubtree(node));
     237      currSelected = null; // because the currently selected node was just deleted
    258238      OnSymbolicExpressionTreeChanged(sender, e);
    259239    }
     
    270250        switch (lastOp) {
    271251          case (EditOp.CutNode): {
    272               // cut node
     252              // when cutting a node from the tree, it's children become children of it's parent
    273253              var parent = tempNode.Parent;
    274254              // arity checks to see if parent can accept node's children (we assume the grammar is already ok with that)
     255              // (otherise, the 'cut' part of the operation will just not do anything)
    275256              if (parent.Symbol.MaximumArity >= tempNode.SubtreeCount + parent.SubtreeCount - 1) {
    276257                // -1 because tempNode will be removed
     
    282263                }
    283264                lastOp = EditOp.CopyNode;
     265                currSelected = null;
    284266              }
    285267              break;
     
    287269          case (EditOp.CutSubtree): {
    288270              // cut subtree
    289               tempNode.Parent.RemoveSubtree(tempNode.Parent.IndexOfSubtree(tempNode));
    290               lastOp = EditOp.CopySubtree; // do this so the next paste will actually perform a copy
     271              var parent = tempNode.Parent;
     272              parent.RemoveSubtree(parent.IndexOfSubtree(tempNode));
     273              lastOp = EditOp.CopySubtree; // do this so the next paste will actually perform a copy   
     274              currSelected = null;
    291275              break;
    292276            }
    293277          case (EditOp.CopyNode): {
    294278              // copy node
    295               var clone = tempNode.Clone() as ISymbolicExpressionTreeNode; // should never be null
     279              var clone = (SymbolicExpressionTreeNode)tempNode.Clone(); // should never be null
    296280              clone.Parent = tempNode.Parent;
    297281              tempNode = clone;
    298               if (tempNode != null && tempNode.SubtreeCount > 0) {
    299                 for (int i = tempNode.SubtreeCount - 1; i >= 0; --i)
    300                   tempNode.RemoveSubtree(i);
    301               }
     282              for (int i = tempNode.SubtreeCount - 1; i >= 0; --i) tempNode.RemoveSubtree(i);
    302283              break;
    303284            }
    304285          case (EditOp.CopySubtree): {
    305286              // copy subtree
    306               var clone = tempNode.Clone() as ISymbolicExpressionTreeNode;
    307               if (clone != null) {
    308                 clone.Parent = tempNode.Parent;
    309                 tempNode = clone;
    310               }
     287              var clone = (SymbolicExpressionTreeNode)tempNode.Clone();
     288              clone.Parent = tempNode.Parent;
     289              tempNode = clone;
    311290              break;
    312291            }
    313292        }
    314293        node.AddSubtree(tempNode);
    315         Tree = Tree;
    316         // hack in order to trigger the reinitialization of the dictionaries after new nodes appeared in the graph
     294        Tree = Tree; // hack in order to trigger the reinitialization of the dictionaries after new nodes appeared in the graph
    317295        OnSymbolicExpressionTreeChanged(sender, e);
    318       } else {
    319         // throw exception or show a warning to the user about invalid arity
    320296      }
    321297    }
Note: See TracChangeset for help on using the changeset viewer.