Free cookie consent management tool by TermsFeed Policy Generator

Changeset 8980


Ignore:
Timestamp:
11/30/12 23:15:47 (11 years ago)
Author:
bburlacu
Message:

#1763: Refactored the tree simplifier. Improved tree/node edit operations.

Location:
trunk/sources
Files:
7 edited
2 copied
2 moved

Legend:

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

    r8942 r8980  
    127127    }
    128128
     129    public void RepaintNodes() {
     130      if (!suspendRepaint) {
     131        var graphics = Graphics.FromImage(image);
     132        graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
     133        graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
     134        foreach (var visualNode in visualTreeNodes.Values) {
     135          DrawTreeNode(graphics, visualNode);
     136        }
     137        this.Refresh();
     138      }
     139    }
     140
     141    public void RepaintNode(VisualSymbolicExpressionTreeNode visualNode) {
     142      if (!suspendRepaint) {
     143        var graphics = Graphics.FromImage(image);
     144        graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
     145        graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
     146        DrawTreeNode(graphics, visualNode);
     147        this.Refresh();
     148      }
     149    }
     150
    129151    private void GenerateImage() {
    130152      using (Graphics graphics = Graphics.FromImage(image)) {
     
    311333      }
    312334    }
     335
     336    protected void DrawTreeNode(VisualSymbolicExpressionTreeNode visualTreeNode) {
     337      using (var graphics = Graphics.FromImage(image)) {
     338        graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
     339        graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
     340        DrawTreeNode(graphics, visualTreeNode);
     341      }
     342    }
     343
     344    protected void DrawTreeNode(Graphics graphics, VisualSymbolicExpressionTreeNode visualTreeNode) {
     345      graphics.Clip = new Region(new Rectangle(visualTreeNode.X, visualTreeNode.Y, visualTreeNode.Width + 1, visualTreeNode.Height + 1));
     346      graphics.Clear(backgroundColor);
     347      var node = visualTreeNode.SymbolicExpressionTreeNode;
     348      var textBrush = new SolidBrush(visualTreeNode.TextColor);
     349      var nodeLinePen = new Pen(visualTreeNode.LineColor);
     350      var nodeFillBrush = new SolidBrush(visualTreeNode.FillColor);
     351      //draw terminal node
     352      if (node.SubtreeCount == 0) {
     353        graphics.FillRectangle(nodeFillBrush, visualTreeNode.X, visualTreeNode.Y, visualTreeNode.Width, visualTreeNode.Height);
     354        graphics.DrawRectangle(nodeLinePen, visualTreeNode.X, visualTreeNode.Y, visualTreeNode.Width, visualTreeNode.Height);
     355      } else {
     356        graphics.FillEllipse(nodeFillBrush, visualTreeNode.X, visualTreeNode.Y, visualTreeNode.Width, visualTreeNode.Height);
     357        graphics.DrawEllipse(nodeLinePen, visualTreeNode.X, visualTreeNode.Y, visualTreeNode.Width, visualTreeNode.Height);
     358      }
     359      //draw name of symbol
     360      var text = node.ToString();
     361      graphics.DrawString(text, textFont, textBrush, new RectangleF(visualTreeNode.X, visualTreeNode.Y, visualTreeNode.Width, visualTreeNode.Height), stringFormat);
     362    }
    313363    #endregion
    314364
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/VisualSymbolicExpressionTreeNode.cs

    r7259 r8980  
    8585    public ISymbolicExpressionTreeNode SymbolicExpressionTreeNode {
    8686      get { return this.symbolicExpressionTreeNode; }
     87      set {
     88        symbolicExpressionTreeNode = value;
     89        ToolTip = SymbolicExpressionTreeNode.ToString();
     90      }
    8791    }
    8892
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Views-3.4.csproj

    r8950 r8980  
    175175      <DependentUpon>VariableView.cs</DependentUpon>
    176176    </Compile>
    177     <Compile Include="TreeEditDialogs\SymbolicExpressionTreeNodeChangeValueDialog.cs">
     177    <Compile Include="TreeEditDialogs\SymbolicExpressionTreeConstantNodeEditDialog.cs">
    178178      <SubType>Form</SubType>
    179179    </Compile>
    180     <Compile Include="TreeEditDialogs\SymbolicExpressionTreeNodeChangeValueDialog.Designer.cs">
    181       <DependentUpon>SymbolicExpressionTreeNodeChangeValueDialog.cs</DependentUpon>
     180    <Compile Include="TreeEditDialogs\SymbolicExpressionTreeConstantNodeEditDialog.Designer.cs">
     181      <DependentUpon>SymbolicExpressionTreeConstantNodeEditDialog.cs</DependentUpon>
     182    </Compile>
     183    <Compile Include="TreeEditDialogs\SymbolicExpressionTreeVariableNodeEditDialog.cs">
     184      <SubType>Form</SubType>
     185    </Compile>
     186    <Compile Include="TreeEditDialogs\SymbolicExpressionTreeVariableNodeEditDialog.Designer.cs">
     187      <DependentUpon>SymbolicExpressionTreeVariableNodeEditDialog.cs</DependentUpon>
    182188    </Compile>
    183189    <Compile Include="TreeEditDialogs\SymbolicExpressionTreeNodeInsertDialog.cs">
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.Designer.cs

    r8946 r8980  
    159159      this.treeChart.Tree = null;
    160160      this.treeChart.SymbolicExpressionTreeChanged += new System.EventHandler(this.treeChart_SymbolicExpressionTreeChanged);
    161       this.treeChart.SymbolicExpressionTreeNodeChanged += new System.EventHandler(this.treeChart_SymbolicExpressionTreeNodeChanged);
    162161      this.treeChart.SymbolicExpressionTreeNodeDoubleClicked += new System.Windows.Forms.MouseEventHandler(this.treeChart_SymbolicExpressionTreeNodeDoubleClicked);
    163162      //
     
    190189      this.grpViewHost.ResumeLayout(false);
    191190      this.ResumeLayout(false);
    192 
    193191    }
    194192
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs

    r8946 r8980  
    3434    private Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> replacementNodes;
    3535    private Dictionary<ISymbolicExpressionTreeNode, double> nodeImpacts;
    36     private Dictionary<ISymbolicExpressionTreeNode, double> originalValues;
    37     private Dictionary<ISymbolicExpressionTreeNode, string> originalVariableNames;
    3836
    3937    public InteractiveSymbolicDataAnalysisSolutionSimplifierView() {
     
    4139      replacementNodes = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>();
    4240      nodeImpacts = new Dictionary<ISymbolicExpressionTreeNode, double>();
    43       originalValues = new Dictionary<ISymbolicExpressionTreeNode, double>();
    44       originalVariableNames = new Dictionary<ISymbolicExpressionTreeNode, string>();
    45 
    4641      this.Caption = "Interactive Solution Simplifier";
    4742    }
     
    105100      var symbExprTreeNode = (SymbolicExpressionTreeNode)visualNode.SymbolicExpressionTreeNode;
    106101      if (symbExprTreeNode == null) return;
     102      if (!replacementNodes.ContainsKey(symbExprTreeNode)) return;
    107103      var tree = Content.Model.SymbolicExpressionTree;
     104      var replacementNode = replacementNodes[symbExprTreeNode];
     105      int indexOfReplacementNode = symbExprTreeNode.Parent.IndexOfSubtree(symbExprTreeNode);
     106      SwitchNodeWithReplacementNode(symbExprTreeNode.Parent, indexOfReplacementNode);
     107      // show only interesting part of solution
     108      treeChart.Tree = tree.Root.SubtreeCount > 1
     109                         ? new SymbolicExpressionTree(tree.Root)
     110                         : new SymbolicExpressionTree(tree.Root.GetSubtree(0).GetSubtree(0));
     111      UpdateModel(tree);
     112      var vNode = treeChart.GetVisualSymbolicExpressionTreeNode(replacementNode);
     113      vNode.SymbolicExpressionTreeNode = replacementNode;
    108114
    109       bool update = false;
    110       // check if the node value/weight has been altered
    111       // if so, the first double click will return the node to its original value/weight/variable name
    112       // the next double click will replace the ConstantNode with the original SymbolicExpressionTreeNode
    113       if (originalVariableNames.ContainsKey(symbExprTreeNode)) {
    114         var variable = (VariableTreeNode)symbExprTreeNode;
    115         variable.VariableName = originalVariableNames[symbExprTreeNode];
    116         originalVariableNames.Remove(variable);
    117         update = true;
    118       } else if (originalValues.ContainsKey(symbExprTreeNode)) {
    119         double value = originalValues[symbExprTreeNode];
    120         if (symbExprTreeNode.Symbol is Constant) {
    121           var constantTreeNode = (ConstantTreeNode)symbExprTreeNode;
    122           constantTreeNode.Value = value;
    123         } else if (symbExprTreeNode.Symbol is Variable) {
    124           var variable = (VariableTreeNode)symbExprTreeNode;
    125           variable.Weight = value;
    126         }
    127         originalValues.Remove(symbExprTreeNode);
    128         update = true;
    129       } else if (replacementNodes.ContainsKey(symbExprTreeNode)) {
    130         foreach (var treeNode in tree.IterateNodesPostfix()) {
    131           for (int i = 0; i < treeNode.SubtreeCount; i++) {
    132             var subtree = treeNode.GetSubtree(i);
    133             if (subtree == symbExprTreeNode) {
    134               SwitchNodeWithReplacementNode(treeNode, i);
    135               // show only interesting part of solution
    136               treeChart.Tree = tree.Root.SubtreeCount > 1
    137                                  ? new SymbolicExpressionTree(tree.Root)
    138                                  : new SymbolicExpressionTree(tree.Root.GetSubtree(0).GetSubtree(0));
    139               update = true;
    140             }
    141           }
    142           if (update) break;
    143         }
    144       }
    145       if (update) UpdateModel(tree);
     115      vNode.LineColor = replacementNode is ConstantTreeNode ? Color.DarkOrange : Color.Black;
     116      treeChart.RepaintNode(vNode);
    146117    }
    147118
     
    149120      UpdateModel(Content.Model.SymbolicExpressionTree);
    150121      UpdateView();
    151     }
    152 
    153     private void treeChart_SymbolicExpressionTreeNodeChanged(object sender, EventArgs e) {
    154       var dialog = (ValueChangeDialog)sender;
    155       bool flag1 = false, flag2 = false;
    156       var node = dialog.Content;
    157 
    158       if (node is VariableTreeNode) {
    159         var variable = (VariableTreeNode)node;
    160         var weight = double.Parse(dialog.newValueTextBox.Text);
    161         var name = (string)dialog.variableNamesCombo.SelectedItem;
    162         if (!variable.Weight.Equals(weight)) {
    163           flag1 = true;
    164           originalValues[variable] = variable.Weight;
    165           variable.Weight = weight;
    166         }
    167         if (!variable.VariableName.Equals(name)) {
    168           flag2 = true;
    169           originalVariableNames[variable] = variable.VariableName;
    170           variable.VariableName = name;
    171         }
    172       } else if (node is ConstantTreeNode) {
    173         var constant = (ConstantTreeNode)node;
    174         var value = double.Parse(dialog.newValueTextBox.Text);
    175         if (!constant.Value.Equals(value)) {
    176           flag1 = true;
    177           originalValues[constant] = constant.Value;
    178           constant.Value = value;
    179         }
    180       }
    181       if (flag1 || flag2) {
    182         UpdateView();
    183       }
    184122    }
    185123
     
    202140      foreach (ISymbolicExpressionTreeNode treeNode in Content.Model.SymbolicExpressionTree.IterateNodesPostfix()) {
    203141        VisualSymbolicExpressionTreeNode visualTree = treeChart.GetVisualSymbolicExpressionTreeNode(treeNode);
    204         bool flag1 = replacementNodes.ContainsKey(treeNode);
    205         bool flag2 = originalValues.ContainsKey(treeNode);
    206         bool flag3 = treeNode is ConstantTreeNode;
    207 
    208         if (flag2) // constant or variable node was changed
    209           visualTree.ToolTip += Environment.NewLine + "Original value: " + originalValues[treeNode];
    210         else if (flag1 && flag3) // symbol node was folded to a constant
    211           visualTree.ToolTip += Environment.NewLine + "Original node: " + replacementNodes[treeNode];
    212142
    213143        if (!(treeNode is ConstantTreeNode) && nodeImpacts.ContainsKey(treeNode)) {
     
    232162          }
    233163        }
    234       }
    235       this.PaintCollapsedNodes();
    236       this.treeChart.Repaint();
    237     }
    238 
    239     private void PaintCollapsedNodes() {
    240       foreach (ISymbolicExpressionTreeNode treeNode in Content.Model.SymbolicExpressionTree.IterateNodesPostfix()) {
    241         bool flag1 = replacementNodes.ContainsKey(treeNode);
    242         bool flag2 = originalValues.ContainsKey(treeNode);
    243         if (flag1 && treeNode is ConstantTreeNode) {
    244           this.treeChart.GetVisualSymbolicExpressionTreeNode(treeNode).LineColor = flag2 ? Color.DarkViolet : Color.DarkOrange;
    245         } else if (flag2) {
    246           this.treeChart.GetVisualSymbolicExpressionTreeNode(treeNode).LineColor = Color.DodgerBlue;
     164        if (visualTree != null && treeNode is ConstantTreeNode && replacementNodes.ContainsKey(treeNode)) {
     165          visualTree.LineColor = Color.DarkOrange;
    247166        }
    248167      }
     168      // repaint nodes and refresh
     169      treeChart.RepaintNodes();
     170      treeChart.Refresh();
    249171    }
    250172
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.Designer.cs

    r8946 r8980  
    4747    /// </summary>
    4848    private void InitializeComponent() {
    49       this.DoubleBuffered = true;
    5049      this.insertNodeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
    51       this.changeValueToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
     50      this.editNodeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
    5251      this.copyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
    5352      this.copyNodeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
     
    6766      //
    6867      this.insertNodeToolStripMenuItem.Name = "insertNodeToolStripMenuItem";
    69       this.insertNodeToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
     68      this.insertNodeToolStripMenuItem.Size = new System.Drawing.Size(135, 22);
    7069      this.insertNodeToolStripMenuItem.Text = "Insert Node";
    7170      this.insertNodeToolStripMenuItem.Click += new System.EventHandler(this.insertNodeToolStripMenuItem_Click);
    7271      //
    73       // changeValueToolStripMenuItem
    74       //
    75       this.changeValueToolStripMenuItem.Name = "changeValueToolStripMenuItem";
    76       this.changeValueToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
    77       this.changeValueToolStripMenuItem.Text = "Change Value";
    78       this.changeValueToolStripMenuItem.Click += new System.EventHandler(this.changeValueToolStripMenuItem_Click);
     72      // editNodeToolStripMenuItem
     73      //
     74      this.editNodeToolStripMenuItem.Name = "editNodeToolStripMenuItem";
     75      this.editNodeToolStripMenuItem.Size = new System.Drawing.Size(135, 22);
     76      this.editNodeToolStripMenuItem.Text = "Edit";
     77      this.editNodeToolStripMenuItem.Click += new System.EventHandler(this.editNodeToolStripMenuItem_Click);
    7978      //
    8079      // copyToolStripMenuItem
     
    8483            this.copySubtreeToolStripMenuItem});
    8584      this.copyToolStripMenuItem.Name = "copyToolStripMenuItem";
    86       this.copyToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
     85      this.copyToolStripMenuItem.Size = new System.Drawing.Size(135, 22);
    8786      this.copyToolStripMenuItem.Text = "Copy";
    8887      //
     
    107106            this.cutSubtreeToolStripMenuItem});
    108107      this.cutToolStripMenuItem.Name = "cutToolStripMenuItem";
    109       this.cutToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
     108      this.cutToolStripMenuItem.Size = new System.Drawing.Size(135, 22);
    110109      this.cutToolStripMenuItem.Text = "Cut";
    111110      //
     
    130129            this.deleteSubtreeToolStripMenuItem});
    131130      this.deleteToolStripMenuItem.Name = "deleteToolStripMenuItem";
    132       this.deleteToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
     131      this.deleteToolStripMenuItem.Size = new System.Drawing.Size(135, 22);
    133132      this.deleteToolStripMenuItem.Text = "Delete";
    134133      //
     
    150149      //
    151150      this.pasteToolStripMenuItem.Name = "pasteToolStripMenuItem";
    152       this.pasteToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
     151      this.pasteToolStripMenuItem.Size = new System.Drawing.Size(135, 22);
    153152      this.pasteToolStripMenuItem.Text = "Paste";
    154153      this.pasteToolStripMenuItem.Click += new System.EventHandler(this.pasteToolStripMenuItem_Clicked);
    155       //
    156       // contextMenuStrip
    157       //
     154      // 
     155      // contextMenuStrip 
     156      // 
    158157      this.contextMenuStrip.Opened += this.contextMenuStrip_Opened;
    159       this.contextMenuStrip.Items.AddRange(new ToolStripItem[] { insertNodeToolStripMenuItem,
    160                                                                  changeValueToolStripMenuItem,
    161                                                                  copyToolStripMenuItem,
    162                                                                  cutToolStripMenuItem,
    163                                                                  deleteToolStripMenuItem,
    164                                                                  pasteToolStripMenuItem });
     158      this.contextMenuStrip.Items.AddRange(new ToolStripItem[] { insertNodeToolStripMenuItem, 
     159                                                                 editNodeToolStripMenuItem,
     160                                                                 copyToolStripMenuItem,
     161                                                                 cutToolStripMenuItem,
     162                                                                 deleteToolStripMenuItem,
     163                                                                 pasteToolStripMenuItem });
    165164      //
    166165      // treeStatusLabel
     
    191190      this.Controls.Add(this.treeStatusLabel);
    192191      this.Controls.Add(this.treeStatusValue);
     192      this.DoubleBuffered = true;
    193193      this.Name = "InteractiveSymbolicExpressionTreeChart";
     194      this.MouseClick += new System.Windows.Forms.MouseEventHandler(this.InteractiveSymbolicExpressionTreeChart_MouseClick);
    194195      this.ResumeLayout(false);
    195196      this.PerformLayout();
     
    198199
    199200    private ToolStripMenuItem insertNodeToolStripMenuItem;
    200     private ToolStripMenuItem changeValueToolStripMenuItem;
     201    private ToolStripMenuItem editNodeToolStripMenuItem;
    201202    private ToolStripMenuItem copyToolStripMenuItem;
    202203    private ToolStripMenuItem copyNodeToolStripMenuItem;
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.cs

    r8946 r8980  
    2121
    2222using System;
     23using System.Collections.Generic;
    2324using System.Drawing;
    2425using System.Linq;
     
    2930namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
    3031  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)
    3333    private VisualSymbolicExpressionTreeNode currSelected; // currently selected node
    3434    private enum EditOp { NoOp, CopyNode, CopySubtree, CutNode, CutSubtree, DeleteNode, DeleteSubtree }
     
    3737    private TreeState treeState = TreeState.Valid; // tree edit operations must leave the tree in a valid state
    3838
     39    private Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> originalNodes; // map a new node to the original node it replaced
     40
    3941    public InteractiveSymbolicExpressionTreeChart() {
    4042      InitializeComponent();
    41       // add extra actions in the context menu strips
    42 
    43 
    44       lastSelected = null;
    4543      currSelected = null;
    4644      tempNode = null;
     45
     46      originalNodes = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>();
    4747    }
    4848
     
    6565        Repaint();
    6666      }
     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      }
    6773    }
    6874
    6975    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
    7281      if (currSelected == null) {
    7382        insertNodeToolStripMenuItem.Visible = false;
    74         changeValueToolStripMenuItem.Visible = false;
     83        editNodeToolStripMenuItem.Visible = false;
    7584        copyToolStripMenuItem.Visible = false;
    7685        cutToolStripMenuItem.Visible = false;
     
    7988      } else {
    8089        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;
    8392        copyToolStripMenuItem.Visible = true;
    8493        cutToolStripMenuItem.Visible = true;
     
    8998
    9099    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
    96107      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      }
    100138    }
    101139
    102140    private void insertNodeToolStripMenuItem_Click(object sender, EventArgs e) {
    103141      if (currSelected == null || currSelected.SymbolicExpressionTreeNode is SymbolicExpressionTreeTerminalNode) return;
    104       var node = currSelected.SymbolicExpressionTreeNode;
     142      var parent = currSelected.SymbolicExpressionTreeNode;
    105143
    106144      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)));
    109146        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) {
    114177      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;
    139188      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        }
    142194      } 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);
    160211    }
    161212
     
    171222    private void cutSubtreeToolStripMenuItem_Click(object sender, EventArgs e) {
    172223      lastOp = EditOp.CutSubtree;
    173       tempNode = currSelected.SymbolicExpressionTreeNode; // should never be null
     224      tempNode = currSelected.SymbolicExpressionTreeNode;
    174225      foreach (var node in tempNode.IterateNodesPostfix()) {
    175226        var visualNode = GetVisualSymbolicExpressionTreeNode(node);
     
    244295      // check if the copied/cut node (stored in the tempNode) can be inserted as a child of the current selected node
    245296      var node = currSelected.SymbolicExpressionTreeNode;
    246       if (node is ConstantTreeNode || node is VariableTreeNode) return; // nothing to do
     297      if (node is ConstantTreeNode || node is VariableTreeNode) return;
    247298      // check if the currently selected node can accept the copied node as a child
    248299      // no need to check the grammar, an arity check will do just fine here
     
    254305              // arity checks to see if parent can accept node's children (we assume the grammar is already ok with that)
    255306              // (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
    258308                parent.RemoveSubtree(parent.IndexOfSubtree(tempNode));
    259309                for (int i = tempNode.SubtreeCount - 1; i >= 0; --i) {
     
    263313                }
    264314                lastOp = EditOp.CopyNode;
    265                 currSelected = null;
    266315              }
    267316              break;
     
    272321              parent.RemoveSubtree(parent.IndexOfSubtree(tempNode));
    273322              lastOp = EditOp.CopySubtree; // do this so the next paste will actually perform a copy   
    274               currSelected = null;
    275323              break;
    276324            }
    277325          case (EditOp.CopyNode): {
    278326              // copy node
    279               var clone = (SymbolicExpressionTreeNode)tempNode.Clone(); // should never be null
     327              var clone = (SymbolicExpressionTreeNode)tempNode.Clone();
    280328              clone.Parent = tempNode.Parent;
    281329              tempNode = clone;
     
    292340        }
    293341        node.AddSubtree(tempNode);
    294         Tree = Tree; // hack in order to trigger the reinitialization of the dictionaries after new nodes appeared in the graph
     342        Tree = Tree; // hack in order to trigger the reinitialization of the dictionaries after new nodes appeared in the tree
    295343        OnSymbolicExpressionTreeChanged(sender, e);
     344        currSelected = null; // because the tree changed and was completely redrawn
    296345      }
    297346    }
     
    305354      return true;
    306355    }
     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    }
    307368  }
    308369}
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeConstantNodeEditDialog.Designer.cs

    r8950 r8980  
    2121
    2222namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
    23   partial class ValueChangeDialog {
     23  partial class ConstantNodeEditDialog {
    2424    /// <summary>
    2525    /// Required designer variable.
     
    5151      this.newValueLabel = new System.Windows.Forms.Label();
    5252      this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
    53       this.variableNameLabel = new System.Windows.Forms.Label();
    54       this.variableNamesCombo = new System.Windows.Forms.ComboBox();
    5553      this.okButton = new System.Windows.Forms.Button();
    5654      this.cancelButton = new System.Windows.Forms.Button();
     
    6159      //
    6260      this.originalValueLabel.AutoSize = true;
    63       this.originalValueLabel.Location = new System.Drawing.Point(12, 45);
     61      this.originalValueLabel.Location = new System.Drawing.Point(12, 9);
    6462      this.originalValueLabel.Name = "originalValueLabel";
    6563      this.originalValueLabel.Size = new System.Drawing.Size(72, 13);
     
    6967      // oldValueTextBox
    7068      //
    71       this.oldValueTextBox.Location = new System.Drawing.Point(123, 42);
     69      this.oldValueTextBox.Location = new System.Drawing.Point(123, 6);
    7270      this.oldValueTextBox.Name = "oldValueTextBox";
    7371      this.oldValueTextBox.ReadOnly = true;
     
    7775      // newValueTextBox
    7876      //
    79       this.newValueTextBox.Location = new System.Drawing.Point(123, 82);
     77      this.newValueTextBox.Location = new System.Drawing.Point(123, 42);
    8078      this.newValueTextBox.Name = "newValueTextBox";
    8179      this.newValueTextBox.Size = new System.Drawing.Size(131, 20);
     
    8886      //
    8987      this.newValueLabel.AutoSize = true;
    90       this.newValueLabel.Location = new System.Drawing.Point(12, 85);
     88      this.newValueLabel.Location = new System.Drawing.Point(12, 45);
    9189      this.newValueLabel.Name = "newValueLabel";
    9290      this.newValueLabel.Size = new System.Drawing.Size(59, 13);
     
    10098      this.errorProvider.RightToLeft = true;
    10199      //
    102       // variableNameLabel
    103       //
    104       this.variableNameLabel.AutoSize = true;
    105       this.variableNameLabel.Location = new System.Drawing.Point(12, 7);
    106       this.variableNameLabel.Name = "variableNameLabel";
    107       this.variableNameLabel.Size = new System.Drawing.Size(76, 13);
    108       this.variableNameLabel.TabIndex = 6;
    109       this.variableNameLabel.Text = "Variable Name";
    110       this.variableNameLabel.Visible = false;
    111       //
    112       // variableNamesCombo
    113       //
    114       this.variableNamesCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
    115       this.variableNamesCombo.FormattingEnabled = true;
    116       this.variableNamesCombo.Location = new System.Drawing.Point(123, 4);
    117       this.variableNamesCombo.Name = "variableNamesCombo";
    118       this.variableNamesCombo.Size = new System.Drawing.Size(131, 21);
    119       this.variableNamesCombo.TabIndex = 7;
    120       this.variableNamesCombo.Visible = false;
    121       this.variableNamesCombo.KeyDown += new System.Windows.Forms.KeyEventHandler(this.childControl_KeyDown);
    122       this.variableNamesCombo.Validating += new System.ComponentModel.CancelEventHandler(this.variableNamesCombo_Validating);
    123       this.variableNamesCombo.Validated += new System.EventHandler(this.variableNamesCombo_Validated);
    124       //
    125100      // okButton
    126101      //
    127       this.okButton.Location = new System.Drawing.Point(15, 119);
     102      this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
     103      this.okButton.Location = new System.Drawing.Point(15, 79);
    128104      this.okButton.Name = "okButton";
    129105      this.okButton.Size = new System.Drawing.Size(75, 23);
     
    137113      this.cancelButton.CausesValidation = false;
    138114      this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
    139       this.cancelButton.Location = new System.Drawing.Point(179, 119);
     115      this.cancelButton.Location = new System.Drawing.Point(179, 79);
    140116      this.cancelButton.Name = "cancelButton";
    141117      this.cancelButton.Size = new System.Drawing.Size(75, 23);
     
    145121      this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
    146122      //
    147       // ValueChangeDialog
     123      // ConstantNodeEditDialog
    148124      //
    149125      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
     
    151127      this.AutoSize = true;
    152128      this.CancelButton = this.cancelButton;
    153       this.ClientSize = new System.Drawing.Size(269, 154);
     129      this.ClientSize = new System.Drawing.Size(269, 116);
    154130      this.ControlBox = false;
    155131      this.Controls.Add(this.cancelButton);
    156132      this.Controls.Add(this.okButton);
    157       this.Controls.Add(this.variableNamesCombo);
    158       this.Controls.Add(this.variableNameLabel);
    159133      this.Controls.Add(this.newValueLabel);
    160134      this.Controls.Add(this.newValueTextBox);
     
    164138      this.MaximizeBox = false;
    165139      this.MinimizeBox = false;
    166       this.Name = "ValueChangeDialog";
     140      this.Name = "ConstantNodeEditDialog";
    167141      this.ShowIcon = false;
    168142      this.ShowInTaskbar = false;
    169143      this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
    170       this.Text = "Change Value or Weight";
    171       this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.ValueChangeDialog_KeyDown);
     144      this.Text = "Edit constant value";
     145      this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.ConstantNodeEditDialog_KeyDown);
    172146      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
    173147      this.ResumeLayout(false);
     
    182156    private System.Windows.Forms.Label newValueLabel;
    183157    private System.Windows.Forms.ErrorProvider errorProvider;
    184     private System.Windows.Forms.Label variableNameLabel;
    185158    private System.Windows.Forms.Button cancelButton;
    186159    private System.Windows.Forms.Button okButton;
    187160    public System.Windows.Forms.TextBox newValueTextBox;
    188     public System.Windows.Forms.ComboBox variableNamesCombo;
    189161  }
    190162}
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeConstantNodeEditDialog.cs

    r8950 r8980  
    2828
    2929namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
    30   public partial class ValueChangeDialog : Form {
    31     private ISymbolicExpressionTreeNode content;
    32     public ISymbolicExpressionTreeNode Content {
    33       get { return content; }
     30  public partial class ConstantNodeEditDialog : Form {
     31    private ConstantTreeNode constantTreeNode;
     32    public ConstantTreeNode NewNode {
     33      get { return constantTreeNode; }
    3434      set {
    3535        if (InvokeRequired)
    36           Invoke(new Action<SymbolicExpressionTreeNode>(x => content = x), value);
     36          Invoke(new Action<SymbolicExpressionTreeNode>(x => constantTreeNode = (ConstantTreeNode)x), value);
    3737        else
    38           content = value;
     38          constantTreeNode = value;
    3939      }
    4040    }
    4141
    42     public ValueChangeDialog() {
     42    public ConstantNodeEditDialog(ISymbolicExpressionTreeNode node) {
    4343      InitializeComponent();
    4444      oldValueTextBox.TabStop = false; // cannot receive focus using tab key
     45      NewNode = (ConstantTreeNode)node;
     46      InitializeFields();
    4547    }
    4648
    47     public void SetContent(ISymbolicExpressionTreeNode content) {
    48       Content = content;
    49       if (Content is VariableTreeNode) {
    50         this.Text = "Change variable name or weight";
    51         var variable = Content as VariableTreeNode;
    52         newValueTextBox.Text = oldValueTextBox.Text = Math.Round(variable.Weight, 4).ToString();
    53         // add a dropbox containing all the available variable names
    54         variableNameLabel.Visible = true;
    55         variableNamesCombo.Visible = true;
    56         foreach (var name in variable.Symbol.VariableNames) variableNamesCombo.Items.Add(name);
    57         variableNamesCombo.SelectedIndex = variableNamesCombo.Items.IndexOf(variable.VariableName);
    58       } else if (Content is ConstantTreeNode) {
    59         this.Text = "Change constant value";
    60         var constant = Content as ConstantTreeNode;
    61         newValueTextBox.Text = oldValueTextBox.Text = Math.Round(constant.Value, 4).ToString();
     49    private void InitializeFields() {
     50      if (NewNode == null)
     51        throw new ArgumentException("Node is not a constant.");
     52      else {
     53        this.Text = "Edit constant";
     54        newValueTextBox.Text = oldValueTextBox.Text = Math.Round(constantTreeNode.Value, 4).ToString();
    6255      }
    6356    }
     
    9285    #endregion
    9386
    94     #region combo box validation and events
    95     private void variableNamesCombo_Validating(object sender, CancelEventArgs e) {
    96       if (!(Content is VariableTreeNode)) return;
    97       if (variableNamesCombo.Items.Contains(variableNamesCombo.SelectedItem)) return;
    98       e.Cancel = true;
    99       errorProvider.SetError(variableNamesCombo, "Invalid variable name");
    100       variableNamesCombo.SelectAll();
     87    // proxy handler passing key strokes to the parent control
     88    private void childControl_KeyDown(object sender, KeyEventArgs e) {
     89      ConstantNodeEditDialog_KeyDown(sender, e);
    10190    }
    10291
    103     private void variableNamesCombo_Validated(object sender, EventArgs e) {
    104       errorProvider.SetError(variableNamesCombo, String.Empty);
    105     }
    106     #endregion
    107     // proxy handler passing key strokes to the parent control
    108     private void childControl_KeyDown(object sender, KeyEventArgs e) {
    109       ValueChangeDialog_KeyDown(sender, e);
    110     }
    111 
    112     private void ValueChangeDialog_KeyDown(object sender, KeyEventArgs e) {
     92    private void ConstantNodeEditDialog_KeyDown(object sender, KeyEventArgs e) {
    11393      if ((e.KeyCode == Keys.Enter) || (e.KeyCode == Keys.Return)) {
    11494        if (!ValidateChildren()) return;
     
    120100    public event EventHandler DialogValidated;
    121101    private void OnDialogValidated(object sender, EventArgs e) {
     102      if (constantTreeNode == null) return;
     103      var value = double.Parse(newValueTextBox.Text);
     104      // we impose an extra validation condition: that the new value is different from the original value
     105      if (constantTreeNode.Value.Equals(value)) return;
     106
     107      constantTreeNode.Value = value;
     108      DialogResult = DialogResult.OK;
    122109      var dialogValidated = DialogValidated;
    123110      if (dialogValidated != null)
     
    135122      }
    136123    }
    137 
    138124  }
    139125}
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeVariableNodeEditDialog.Designer.cs

    r8950 r8980  
    2121
    2222namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
    23   partial class ValueChangeDialog {
     23  partial class VariableNodeEditDialog {
    2424    /// <summary>
    2525    /// Required designer variable.
     
    6161      //
    6262      this.originalValueLabel.AutoSize = true;
    63       this.originalValueLabel.Location = new System.Drawing.Point(12, 45);
     63      this.originalValueLabel.Location = new System.Drawing.Point(12, 48);
    6464      this.originalValueLabel.Name = "originalValueLabel";
    6565      this.originalValueLabel.Size = new System.Drawing.Size(72, 13);
     
    6969      // oldValueTextBox
    7070      //
    71       this.oldValueTextBox.Location = new System.Drawing.Point(123, 42);
     71      this.oldValueTextBox.Location = new System.Drawing.Point(123, 45);
    7272      this.oldValueTextBox.Name = "oldValueTextBox";
    7373      this.oldValueTextBox.ReadOnly = true;
     
    103103      //
    104104      this.variableNameLabel.AutoSize = true;
    105       this.variableNameLabel.Location = new System.Drawing.Point(12, 7);
     105      this.variableNameLabel.Location = new System.Drawing.Point(12, 12);
    106106      this.variableNameLabel.Name = "variableNameLabel";
    107107      this.variableNameLabel.Size = new System.Drawing.Size(76, 13);
     
    114114      this.variableNamesCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
    115115      this.variableNamesCombo.FormattingEnabled = true;
    116       this.variableNamesCombo.Location = new System.Drawing.Point(123, 4);
     116      this.variableNamesCombo.Location = new System.Drawing.Point(123, 9);
    117117      this.variableNamesCombo.Name = "variableNamesCombo";
    118118      this.variableNamesCombo.Size = new System.Drawing.Size(131, 21);
     
    125125      // okButton
    126126      //
     127      this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
    127128      this.okButton.Location = new System.Drawing.Point(15, 119);
    128129      this.okButton.Name = "okButton";
     
    145146      this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
    146147      //
    147       // ValueChangeDialog
     148      // VariableNodeEditDialog
    148149      //
    149150      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
     
    164165      this.MaximizeBox = false;
    165166      this.MinimizeBox = false;
    166       this.Name = "ValueChangeDialog";
     167      this.Name = "VariableNodeEditDialog";
    167168      this.ShowIcon = false;
    168169      this.ShowInTaskbar = false;
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeVariableNodeEditDialog.cs

    r8950 r8980  
    2828
    2929namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
    30   public partial class ValueChangeDialog : Form {
    31     private ISymbolicExpressionTreeNode content;
    32     public ISymbolicExpressionTreeNode Content {
    33       get { return content; }
     30  public partial class VariableNodeEditDialog : Form {
     31    private VariableTreeNode variableTreeNode;
     32    public VariableTreeNode NewNode {
     33      get { return variableTreeNode; }
    3434      set {
    3535        if (InvokeRequired)
    36           Invoke(new Action<SymbolicExpressionTreeNode>(x => content = x), value);
     36          Invoke(new Action<SymbolicExpressionTreeNode>(x => variableTreeNode = (VariableTreeNode)x), value);
    3737        else
    38           content = value;
     38          variableTreeNode = value;
    3939      }
    4040    }
    4141
    42     public ValueChangeDialog() {
     42    public VariableNodeEditDialog(ISymbolicExpressionTreeNode node) {
    4343      InitializeComponent();
    4444      oldValueTextBox.TabStop = false; // cannot receive focus using tab key
     45
     46      NewNode = (VariableTreeNode)node; // will throw an invalid cast exception if node is not of the correct type
     47      InitializeFields();
    4548    }
    4649
    47     public void SetContent(ISymbolicExpressionTreeNode content) {
    48       Content = content;
    49       if (Content is VariableTreeNode) {
    50         this.Text = "Change variable name or weight";
    51         var variable = Content as VariableTreeNode;
    52         newValueTextBox.Text = oldValueTextBox.Text = Math.Round(variable.Weight, 4).ToString();
     50    private void InitializeFields() {
     51      if (NewNode == null)
     52        throw new ArgumentException("Node is not a constant.");
     53      else {
     54        this.Text = "Edit variable";
     55        newValueTextBox.Text = oldValueTextBox.Text = Math.Round(variableTreeNode.Weight, 4).ToString();
    5356        // add a dropbox containing all the available variable names
    5457        variableNameLabel.Visible = true;
    5558        variableNamesCombo.Visible = true;
    56         foreach (var name in variable.Symbol.VariableNames) variableNamesCombo.Items.Add(name);
    57         variableNamesCombo.SelectedIndex = variableNamesCombo.Items.IndexOf(variable.VariableName);
    58       } else if (Content is ConstantTreeNode) {
    59         this.Text = "Change constant value";
    60         var constant = Content as ConstantTreeNode;
    61         newValueTextBox.Text = oldValueTextBox.Text = Math.Round(constant.Value, 4).ToString();
     59        foreach (var name in variableTreeNode.Symbol.VariableNames) variableNamesCombo.Items.Add(name);
     60        variableNamesCombo.SelectedIndex = variableNamesCombo.Items.IndexOf(variableTreeNode.VariableName);
    6261      }
    6362    }
     
    9493    #region combo box validation and events
    9594    private void variableNamesCombo_Validating(object sender, CancelEventArgs e) {
    96       if (!(Content is VariableTreeNode)) return;
    9795      if (variableNamesCombo.Items.Contains(variableNamesCombo.SelectedItem)) return;
    9896      e.Cancel = true;
     
    120118    public event EventHandler DialogValidated;
    121119    private void OnDialogValidated(object sender, EventArgs e) {
     120      double weight = double.Parse(newValueTextBox.Text);
     121      var variableName = (string)variableNamesCombo.SelectedItem;
     122      // we impose an extra validation condition: that the weight/value be different than the original ones
     123      if (variableTreeNode.Weight.Equals(weight) && variableTreeNode.VariableName.Equals(variableName)) return;
     124      variableTreeNode.Weight = weight;
     125      variableTreeNode.VariableName = variableName;
     126      DialogResult = DialogResult.OK;
    122127      var dialogValidated = DialogValidated;
    123128      if (dialogValidated != null)
     
    135140      }
    136141    }
    137 
    138142  }
    139143}
Note: See TracChangeset for help on using the changeset viewer.