Free cookie consent management tool by TermsFeed Policy Generator

Changeset 9043


Ignore:
Timestamp:
12/12/12 23:04:40 (12 years ago)
Author:
bburlacu
Message:

#1763: Fixed chart visual node coloring issues and some corner-case tree editing bugs.

Location:
trunk/sources
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionTreeChart.cs

    r8986 r9043  
    185185    }
    186186
    187     private void SymbolicExpressionTreeChart_MouseClick(object sender, MouseEventArgs e) {
     187    protected virtual void SymbolicExpressionTreeChart_MouseClick(object sender, MouseEventArgs e) {
    188188      VisualSymbolicExpressionTreeNode visualTreeNode = FindVisualSymbolicExpressionTreeNodeAt(e.X, e.Y);
    189189      if (visualTreeNode != null) {
     
    199199    }
    200200
    201     private void SymbolicExpressionTreeChart_MouseDoubleClick(object sender, MouseEventArgs e) {
     201    protected virtual void SymbolicExpressionTreeChart_MouseDoubleClick(object sender, MouseEventArgs e) {
    202202      VisualSymbolicExpressionTreeNode visualTreeNode = FindVisualSymbolicExpressionTreeNodeAt(e.X, e.Y);
    203203      if (visualTreeNode != null)
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.Designer.cs

    r9006 r9043  
    4949      this.splitContainer = new System.Windows.Forms.SplitContainer();
    5050      this.grpSimplify = new System.Windows.Forms.GroupBox();
     51      this.treeStatusValue = new System.Windows.Forms.Label();
    5152      this.flowLayoutPanel = new System.Windows.Forms.FlowLayoutPanel();
     53      this.btnOptimizeConstants = new System.Windows.Forms.Button();
    5254      this.btnSimplify = new System.Windows.Forms.Button();
    53       this.btnOptimizeConstants = new System.Windows.Forms.Button();
     55      this.treeStatusLabel = new System.Windows.Forms.Label();
     56      this.treeChart = new HeuristicLab.Problems.DataAnalysis.Symbolic.Views.InteractiveSymbolicExpressionTreeChart();
    5457      this.grpViewHost = new System.Windows.Forms.GroupBox();
    55       this.treeStatusLabel = new System.Windows.Forms.Label();
    56       this.treeStatusValue = new System.Windows.Forms.Label();
    57       this.treeChart = new HeuristicLab.Problems.DataAnalysis.Symbolic.Views.InteractiveSymbolicExpressionTreeChart();
    5858      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
    5959      this.splitContainer.Panel1.SuspendLayout();
     
    6767      // viewHost
    6868      //
    69       this.viewHost.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
    70             | System.Windows.Forms.AnchorStyles.Left)
     69      this.viewHost.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
     70            | System.Windows.Forms.AnchorStyles.Left) 
    7171            | System.Windows.Forms.AnchorStyles.Right)));
    7272      this.viewHost.Caption = "View";
     
    113113      this.grpSimplify.Text = "Simplify";
    114114      //
    115       // flowLayoutPanel
    116       //
    117       this.flowLayoutPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
    118             | System.Windows.Forms.AnchorStyles.Right)));
    119       this.flowLayoutPanel.Controls.Add(this.btnOptimizeConstants);
    120       this.flowLayoutPanel.Controls.Add(this.btnSimplify);
    121       this.flowLayoutPanel.Location = new System.Drawing.Point(6, 370);
    122       this.flowLayoutPanel.Name = "flowLayoutPanel";
    123       this.flowLayoutPanel.Size = new System.Drawing.Size(204, 29);
    124       this.flowLayoutPanel.TabIndex = 2;
    125       this.flowLayoutPanel.WrapContents = false;
    126       //
    127       // btnSimplify
    128       //
    129       this.btnSimplify.Location = new System.Drawing.Point(106, 3);
    130       this.btnSimplify.Name = "btnSimplify";
    131       this.btnSimplify.Size = new System.Drawing.Size(95, 23);
    132       this.btnSimplify.TabIndex = 1;
    133       this.btnSimplify.Text = "Simplify";
    134       this.btnSimplify.UseVisualStyleBackColor = true;
    135       this.btnSimplify.Click += new System.EventHandler(this.btnSimplify_Click);
    136       //
    137       // btnOptimizeConstants
    138       //
    139       this.btnOptimizeConstants.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
    140       this.btnOptimizeConstants.Enabled = false;
    141       this.btnOptimizeConstants.Location = new System.Drawing.Point(3, 3);
    142       this.btnOptimizeConstants.Name = "btnOptimizeConstants";
    143       this.btnOptimizeConstants.Size = new System.Drawing.Size(97, 23);
    144       this.btnOptimizeConstants.TabIndex = 2;
    145       this.btnOptimizeConstants.Text = "Optimize";
    146       this.btnOptimizeConstants.UseVisualStyleBackColor = true;
    147       this.btnOptimizeConstants.Click += new System.EventHandler(this.btnOptimizeConstants_Click);
    148       //
    149       // grpViewHost
    150       //
    151       this.grpViewHost.Controls.Add(this.viewHost);
    152       this.grpViewHost.Dock = System.Windows.Forms.DockStyle.Fill;
    153       this.grpViewHost.Location = new System.Drawing.Point(0, 0);
    154       this.grpViewHost.Name = "grpViewHost";
    155       this.grpViewHost.Size = new System.Drawing.Size(348, 405);
    156       this.grpViewHost.TabIndex = 1;
    157       this.grpViewHost.TabStop = false;
    158       this.grpViewHost.Text = "Details";
    159       //
    160       // treeStatusLabel
    161       //
    162       this.treeStatusLabel.AutoSize = true;
    163       this.treeStatusLabel.BackColor = System.Drawing.Color.Transparent;
    164       this.treeStatusLabel.Location = new System.Drawing.Point(6, 16);
    165       this.treeStatusLabel.Name = "treeStatusLabel";
    166       this.treeStatusLabel.Size = new System.Drawing.Size(68, 13);
    167       this.treeStatusLabel.TabIndex = 2;
    168       this.treeStatusLabel.Text = "Tree Status: ";
    169       //
    170115      // treeStatusValue
    171116      //
     
    179124      this.treeStatusValue.Text = "Valid";
    180125      //
     126      // flowLayoutPanel
     127      //
     128      this.flowLayoutPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
     129            | System.Windows.Forms.AnchorStyles.Right)));
     130      this.flowLayoutPanel.Controls.Add(this.btnSimplify);
     131      this.flowLayoutPanel.Controls.Add(this.btnOptimizeConstants);
     132      this.flowLayoutPanel.Location = new System.Drawing.Point(6, 370);
     133      this.flowLayoutPanel.Name = "flowLayoutPanel";
     134      this.flowLayoutPanel.Size = new System.Drawing.Size(204, 29);
     135      this.flowLayoutPanel.TabIndex = 2;
     136      this.flowLayoutPanel.WrapContents = false;
     137      //
     138      // btnOptimizeConstants
     139      //
     140      this.btnOptimizeConstants.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
     141      this.btnOptimizeConstants.Enabled = false;
     142      this.btnOptimizeConstants.Location = new System.Drawing.Point(104, 3);
     143      this.btnOptimizeConstants.Name = "btnOptimizeConstants";
     144      this.btnOptimizeConstants.Size = new System.Drawing.Size(97, 23);
     145      this.btnOptimizeConstants.TabIndex = 2;
     146      this.btnOptimizeConstants.Text = "Optimize";
     147      this.btnOptimizeConstants.UseVisualStyleBackColor = true;
     148      this.btnOptimizeConstants.Click += new System.EventHandler(this.btnOptimizeConstants_Click);
     149      //
     150      // btnSimplify
     151      //
     152      this.btnSimplify.Location = new System.Drawing.Point(3, 3);
     153      this.btnSimplify.Name = "btnSimplify";
     154      this.btnSimplify.Size = new System.Drawing.Size(95, 23);
     155      this.btnSimplify.TabIndex = 1;
     156      this.btnSimplify.Text = "Simplify";
     157      this.btnSimplify.UseVisualStyleBackColor = true;
     158      this.btnSimplify.Click += new System.EventHandler(this.btnSimplify_Click);
     159      //
     160      // treeStatusLabel
     161      //
     162      this.treeStatusLabel.AutoSize = true;
     163      this.treeStatusLabel.BackColor = System.Drawing.Color.Transparent;
     164      this.treeStatusLabel.Location = new System.Drawing.Point(6, 16);
     165      this.treeStatusLabel.Name = "treeStatusLabel";
     166      this.treeStatusLabel.Size = new System.Drawing.Size(68, 13);
     167      this.treeStatusLabel.TabIndex = 2;
     168      this.treeStatusLabel.Text = "Tree Status: ";
     169      //
    181170      // treeChart
    182171      //
    183       this.treeChart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
    184             | System.Windows.Forms.AnchorStyles.Left)
     172      this.treeChart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
     173            | System.Windows.Forms.AnchorStyles.Left) 
    185174            | System.Windows.Forms.AnchorStyles.Right)));
    186175      this.treeChart.BackgroundColor = System.Drawing.Color.White;
     
    197186      this.treeChart.SymbolicExpressionTreeNodeClicked += new System.Windows.Forms.MouseEventHandler(this.treeChart_SymbolicExpressionTreeNodeClicked);
    198187      this.treeChart.SymbolicExpressionTreeNodeDoubleClicked += new System.Windows.Forms.MouseEventHandler(this.treeChart_SymbolicExpressionTreeNodeDoubleClicked);
     188      //
     189      // grpViewHost
     190      //
     191      this.grpViewHost.Controls.Add(this.viewHost);
     192      this.grpViewHost.Dock = System.Windows.Forms.DockStyle.Fill;
     193      this.grpViewHost.Location = new System.Drawing.Point(0, 0);
     194      this.grpViewHost.Name = "grpViewHost";
     195      this.grpViewHost.Size = new System.Drawing.Size(348, 405);
     196      this.grpViewHost.TabIndex = 1;
     197      this.grpViewHost.TabStop = false;
     198      this.grpViewHost.Text = "Details";
    199199      //
    200200      // InteractiveSymbolicDataAnalysisSolutionSimplifierView
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs

    r9006 r9043  
    5353    /// </summary>
    5454    /// <param name="tree">The symbolic expression tree</param>
    55     /// <param name="node">The insertion point (the parent node who will receive a new child)</param>
     55    /// <param name="node">The insertion point (ie, the parent node who will receive a new child)</param>
    5656    /// <param name="oldChild">The subtree to be replaced</param>
    5757    /// <param name="newChild">The replacement subtree</param>
    5858    /// <param name="removeSubtree">Flag used to indicate if whole subtrees should be removed (default behavior), or just the subtree root</param>
    59     private void Modify(ISymbolicExpressionTree tree, ISymbolicExpressionTreeNode node, ISymbolicExpressionTreeNode oldChild, ISymbolicExpressionTreeNode newChild,
    60                         bool removeSubtree = true) {
     59    private void Modify(ISymbolicExpressionTree tree, ISymbolicExpressionTreeNode node, ISymbolicExpressionTreeNode oldChild, ISymbolicExpressionTreeNode newChild, bool removeSubtree = true) {
    6160      if (oldChild == null && newChild == null) throw new ArgumentException();
    6261      if (oldChild == null) { // insertion operation
    6362        node.AddSubtree(newChild);
    6463        newChild.Parent = node;
    65         treeChart.Tree = tree; // because a new node is present in the tree, the visualNodes dictionary needs to be updated
    6664      } else if (newChild == null) { // removal operation
    67         // use switch instead of if/else purely for aesthetical reasons (to avoid nested ifs and elses)
    68         switch (removeSubtree) {
    69           case true:
    70             // remove the whole subtree
    71             node.RemoveSubtree(node.IndexOfSubtree(oldChild));
    72             if (oldChild.SubtreeCount > 0)
    73               foreach (var subtree in oldChild.IterateNodesBreadth()) {
    74                 changedNodes.Remove(subtree);
    75                 foldedNodes.Remove(subtree);
    76               }
    77             break;
    78           case false:
    79             // only remove the current node and try to preserve its subtrees
    80             node.RemoveSubtree(node.IndexOfSubtree(oldChild));
    81             if (oldChild.SubtreeCount > 0)
    82               for (int i = oldChild.SubtreeCount - 1; i >= 0; --i) {
    83                 var subtree = oldChild.GetSubtree(i);
    84                 oldChild.RemoveSubtree(i);
    85                 node.AddSubtree(subtree);
    86               }
    87             break;
    88         }
     65        node.RemoveSubtree(node.IndexOfSubtree(oldChild));
    8966        changedNodes.Remove(oldChild);
    9067        foldedNodes.Remove(oldChild);
     68        if (removeSubtree) {
     69          foreach (var subtree in oldChild.IterateNodesPrefix()) {
     70            changedNodes.Remove(subtree);
     71            foldedNodes.Remove(subtree);
     72          }
     73        } else {
     74          for (int i = oldChild.SubtreeCount - 1; i >= 0; --i) {
     75            var subtree = oldChild.GetSubtree(i);
     76            oldChild.RemoveSubtree(i);
     77            node.AddSubtree(subtree);
     78          }
     79        }
    9180      } else { // replacement operation
    9281        var replacementIndex = node.IndexOfSubtree(oldChild);
     
    10190        }
    10291      }
    103 
    10492      if (IsValid(tree)) {
    10593        treeState = TreeState.Valid;
    10694        UpdateModel(Content.Model.SymbolicExpressionTree);
     95      } else {
     96        treeState = TreeState.Invalid;
     97      }
     98    }
     99
     100    private bool IsValid(ISymbolicExpressionTree tree) {
     101      treeChart.Tree = tree;
     102      treeChart.Repaint();
     103      bool valid = !tree.IterateNodesPostfix().Any(node => node.SubtreeCount < node.Symbol.MinimumArity || node.SubtreeCount > node.Symbol.MaximumArity);
     104      if (valid) {
    107105        btnOptimizeConstants.Enabled = true;
    108106        btnSimplify.Enabled = true;
    109107        treeStatusValue.Text = "Valid";
    110108        treeStatusValue.ForeColor = Color.Green;
    111         this.Refresh();
    112109      } else {
    113         treeState = TreeState.Invalid;
    114110        btnOptimizeConstants.Enabled = true;
    115111        btnSimplify.Enabled = true;
    116112        treeStatusValue.Text = "Invalid";
    117113        treeStatusValue.ForeColor = Color.Red;
    118         treeChart.Repaint();
    119         this.Refresh();
    120       }
    121       foreach (var changedNode in changedNodes.Keys) {
    122         var visualNode = treeChart.GetVisualSymbolicExpressionTreeNode(changedNode);
    123         visualNode.LineColor = Color.DodgerBlue;
    124         treeChart.RepaintNode(visualNode);
    125       }
    126     }
    127 
    128     private static bool IsValid(ISymbolicExpressionTree tree) {
    129       return !tree.IterateNodesPostfix().Any(node => node.SubtreeCount < node.Symbol.MinimumArity || node.SubtreeCount > node.Symbol.MaximumArity);
     114      }
     115      this.Refresh();
     116      return valid;
    130117    }
    131118
     
    183170
    184171    private void treeChart_SymbolicExpressionTreeNodeClicked(object sender, MouseEventArgs e) {
    185       var visualNode = (VisualSymbolicExpressionTreeNode)sender;
    186       if (visualNode == null) return;
    187       var treeNode = visualNode.SymbolicExpressionTreeNode;
    188       if (changedNodes.ContainsKey(treeNode)) {
    189         visualNode.LineColor = Color.DodgerBlue;
    190       } else if (treeNode is ConstantTreeNode && foldedNodes.ContainsKey(treeNode)) {
    191         visualNode.LineColor = Color.DarkOrange;
    192       } else {
    193         visualNode.LineColor = Color.Black;
    194       }
    195       visualNode.TextColor = Color.Black;
    196       treeChart.RepaintNode(visualNode);
    197172    }
    198173
     
    206181      int indexOfSubtree = parent.IndexOfSubtree(symbExprTreeNode);
    207182      if (changedNodes.ContainsKey(symbExprTreeNode)) {
     183        // undo node change
    208184        parent.RemoveSubtree(indexOfSubtree);
    209         ISymbolicExpressionTreeNode originalNode = changedNodes[symbExprTreeNode];
     185        var originalNode = changedNodes[symbExprTreeNode];
    210186        parent.InsertSubtree(indexOfSubtree, originalNode);
    211187        changedNodes.Remove(symbExprTreeNode);
    212188        UpdateModel(tree);
    213189      } else if (foldedNodes.ContainsKey(symbExprTreeNode)) {
     190        // undo node folding
    214191        SwitchNodeWithReplacementNode(parent, indexOfSubtree);
    215192        UpdateModel(tree);
     
    257234          }
    258235        }
    259         if (visualTree != null && treeNode is ConstantTreeNode && foldedNodes.ContainsKey(treeNode)) {
    260           visualTree.LineColor = Color.DarkOrange;
    261         }
    262       }
    263       // repaint nodes and refresh
     236        if (visualTree != null)
     237          if (changedNodes.ContainsKey(treeNode)) {
     238            visualTree.LineColor = Color.DodgerBlue;
     239          } else if (treeNode is ConstantTreeNode && foldedNodes.ContainsKey(treeNode)) {
     240            visualTree.LineColor = Color.DarkOrange;
     241          }
     242      }
    264243      treeChart.RepaintNodes();
    265       treeChart.Refresh();
    266244    }
    267245
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.cs

    r9006 r9043  
    2929namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
    3030  internal delegate void
    31   ModifyTree(ISymbolicExpressionTree tree, ISymbolicExpressionTreeNode node, ISymbolicExpressionTreeNode oldChild, ISymbolicExpressionTreeNode newChild,
    32              bool removeSubtree = true);
     31  ModifyTree(ISymbolicExpressionTree tree, ISymbolicExpressionTreeNode node, ISymbolicExpressionTreeNode oldChild, ISymbolicExpressionTreeNode newChild, bool removeSubtree = true);
    3332
    3433  internal sealed partial class InteractiveSymbolicExpressionTreeChart : SymbolicExpressionTreeChart {
    3534    private ISymbolicExpressionTreeNode tempNode; // node in clipboard (to be cut/copy/pasted etc)
    3635    private VisualSymbolicExpressionTreeNode currSelected; // currently selected node
    37     public enum EditOp { NoOp, CopySubtree, CutSubtree, ChangeNode, InsertNode, InsertSubtree, RemoveNode, RemoveSubtree }
     36    private enum EditOp { NoOp, CopySubtree, CutSubtree }
    3837    private EditOp lastOp = EditOp.NoOp;
    3938
     
    5251      var ea = new MouseEventArgs(MouseButtons.Left, 1, point.X, point.Y, 0);
    5352      var visualNode = FindVisualSymbolicExpressionTreeNodeAt(ea.X, ea.Y);
    54       if (visualNode != null) { OnSymbolicExpressionTreeNodeClicked(visualNode, ea); };
     53      if (visualNode != null) {
     54        OnSymbolicExpressionTreeNodeClicked(visualNode, ea);
     55      } else {
     56        currSelected = null;
     57      }
    5558
    5659      if (currSelected == null) {
     
    7679
    7780    protected override void OnSymbolicExpressionTreeNodeClicked(object sender, MouseEventArgs e) {
    78       var visualTreeNode = (VisualSymbolicExpressionTreeNode)sender;
    79       var lastSelected = currSelected;
    80       currSelected = visualTreeNode;
    8181      if (currSelected != null) {
    82         currSelected.LineColor = Color.LightGreen;
     82        currSelected.LineColor = Color.FromArgb(255, currSelected.LineColor);
    8383        RepaintNode(currSelected);
    8484      }
    85       if (lastSelected != null)
    86         base.OnSymbolicExpressionTreeNodeClicked(lastSelected, e);
     85      currSelected = (VisualSymbolicExpressionTreeNode)sender; ;
     86      if (currSelected != null) {
     87        currSelected.LineColor = Color.FromArgb(130, currSelected.LineColor);
     88        RepaintNode(currSelected);
     89      }
     90    }
     91
     92    protected override void SymbolicExpressionTreeChart_MouseClick(object sender, MouseEventArgs e) {
     93      var visualTreeNode = FindVisualSymbolicExpressionTreeNodeAt(e.X, e.Y);
     94      if (visualTreeNode != null) {
     95        OnSymbolicExpressionTreeNodeClicked(visualTreeNode, e);
     96      } else if (currSelected != null) {
     97        currSelected.LineColor = Color.FromArgb(255, currSelected.LineColor);
     98        RepaintNode(currSelected);
     99        currSelected = null;
     100      }
    87101    }
    88102
     
    124138      currSelected = null;
    125139    }
    126 
    127140    private void changeNodeToolStripMenuItem_Click(object sender, EventArgs e) {
    128141      if (currSelected == null) return;
     
    150163      currSelected = null;
    151164    }
    152 
    153165    private void cutToolStripMenuItem_Click(object sender, EventArgs e) {
    154166      lastOp = EditOp.CutSubtree;
     167      copySubtree();
     168    }
     169    private void copyToolStripMenuItem_Click(object sender, EventArgs e) {
     170      lastOp = EditOp.CopySubtree;
     171      copySubtree();
     172    }
     173    private void copySubtree() {
    155174      if (tempNode != null) {
    156175        foreach (var subtree in tempNode.IterateNodesBreadth()) {
    157176          var vNode = GetVisualSymbolicExpressionTreeNode(subtree);
    158           base.OnSymbolicExpressionTreeNodeClicked(vNode, null);
     177          vNode.LineColor = Color.FromArgb(255, vNode.LineColor); // reset the alpha value to 255
    159178          if (subtree.Parent != null) {
    160179            var vArc = GetVisualSymbolicExpressionTreeNodeConnection(subtree.Parent, subtree);
    161             vArc.LineColor = Color.Black;
     180            vArc.LineColor = Color.FromArgb(255, vArc.LineColor);
    162181          }
    163182        }
     
    166185      foreach (var node in tempNode.IterateNodesPostfix()) {
    167186        var visualNode = GetVisualSymbolicExpressionTreeNode(node);
    168         visualNode.LineColor = Color.LightGray;
    169         visualNode.TextColor = Color.LightGray;
    170         if (node.SubtreeCount > 0) {
    171           foreach (var subtree in node.Subtrees) {
    172             var visualLine = GetVisualSymbolicExpressionTreeNodeConnection(node, subtree);
    173             visualLine.LineColor = Color.LightGray;
    174           }
    175         }
    176       }
    177       currSelected = null;
    178       Repaint();
    179     }
    180     private void copyToolStripMenuItem_Click(object sender, EventArgs e) {
    181       lastOp = EditOp.CopySubtree;
    182       if (tempNode != null) {
    183         foreach (var subtree in tempNode.IterateNodesBreadth()) {
    184           var vNode = GetVisualSymbolicExpressionTreeNode(subtree);
    185           base.OnSymbolicExpressionTreeNodeClicked(vNode, null);
    186           if (subtree.Parent != null) {
    187             var vArc = GetVisualSymbolicExpressionTreeNodeConnection(subtree.Parent, subtree);
    188             vArc.LineColor = Color.Black;
    189           }
    190         }
    191       }
    192       tempNode = currSelected.SymbolicExpressionTreeNode;
    193       foreach (var node in tempNode.IterateNodesPostfix()) {
    194         var visualNode = GetVisualSymbolicExpressionTreeNode(node);
    195         visualNode.LineColor = Color.LightGray;
    196         visualNode.TextColor = Color.LightGray;
    197         if (node.SubtreeCount <= 0) continue;
     187        visualNode.LineColor = Color.FromArgb(100, visualNode.LineColor);
     188        visualNode.TextColor = Color.FromArgb(100, visualNode.TextColor);
    198189        foreach (var subtree in node.Subtrees) {
    199190          var visualLine = GetVisualSymbolicExpressionTreeNodeConnection(node, subtree);
    200           visualLine.LineColor = Color.LightGray;
     191          visualLine.LineColor = Color.FromArgb(100, visualLine.LineColor);
    201192        }
    202193      }
     
    205196    }
    206197    private void removeNodeToolStripMenuItem_Click(object sender, EventArgs e) {
    207       lastOp = EditOp.RemoveNode;
    208198      var node = currSelected.SymbolicExpressionTreeNode;
    209199      ModifyTree(Tree, node.Parent, node, null, removeSubtree: false);
     
    211201    }
    212202    private void removeSubtreeToolStripMenuItem_Click(object sender, EventArgs e) {
    213       lastOp = EditOp.RemoveNode;
    214203      var node = currSelected.SymbolicExpressionTreeNode;
    215204      ModifyTree(Tree, node.Parent, node, null, removeSubtree: true);
     
    227216      switch (lastOp) {
    228217        case EditOp.CutSubtree: {
     218            if (tempNode.IterateNodesBreadth().Contains(node))
     219              goto case EditOp.CopySubtree; // a subtree cannot be cut/pasted onto itself
    229220            ModifyTree(Tree, tempNode.Parent, tempNode, null); //remove node from its original parent
    230             ModifyTree(Tree, node, null, tempNode);//insert it as a child to the new parent
     221            ModifyTree(Tree, node, null, tempNode); //insert it as a child to the new parent
    231222            lastOp = EditOp.CopySubtree; //do this so the next paste will actually perform a copy   
    232223            break;
     
    241232      }
    242233      currSelected = null; // because the tree will have changed
     234      tempNode = null; // clear the clipboard after one paste
    243235    }
    244236  }
Note: See TracChangeset for help on using the changeset viewer.