Changeset 9421


Ignore:
Timestamp:
05/02/13 13:34:32 (6 years ago)
Author:
bburlacu
Message:

#1772: Merged trunk changes for HeuristicLab.Optimization.Views.

Location:
branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Optimization.Views
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Optimization.Views

  • branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Optimization.Views/3.3/HeuristicLab.Optimization.Views-3.3.csproj

    r9296 r9421  
    4141    <DebugType>full</DebugType>
    4242    <Optimize>false</Optimize>
    43     <OutputPath>..\..\..\..\Trunk\sources\bin\</OutputPath>
     43    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
    4444    <DefineConstants>DEBUG;TRACE</DefineConstants>
    4545    <ErrorReport>prompt</ErrorReport>
     
    6060  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
    6161    <DebugSymbols>true</DebugSymbols>
    62     <OutputPath>$(SolutionDir)\bin\</OutputPath>
     62    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
    6363    <DefineConstants>DEBUG;TRACE</DefineConstants>
    6464    <DebugType>full</DebugType>
     
    8080  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
    8181    <DebugSymbols>true</DebugSymbols>
    82     <OutputPath>$(SolutionDir)\bin\</OutputPath>
     82    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
    8383    <DefineConstants>DEBUG;TRACE</DefineConstants>
    8484    <DebugType>full</DebugType>
     
    102102      <SpecificVersion>False</SpecificVersion>
    103103      <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Analysis-3.3.dll</HintPath>
     104      <Private>False</Private>
    104105    </Reference>
    105106    <Reference Include="HeuristicLab.Analysis.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
    106107      <SpecificVersion>False</SpecificVersion>
    107108      <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Analysis.Views-3.3.dll</HintPath>
     109      <Private>False</Private>
    108110    </Reference>
    109111    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
    110112      <SpecificVersion>False</SpecificVersion>
    111113      <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
     114      <Private>False</Private>
    112115    </Reference>
    113116    <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
    114117      <SpecificVersion>False</SpecificVersion>
    115118      <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
     119      <Private>False</Private>
    116120    </Reference>
    117121    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
    118122      <SpecificVersion>False</SpecificVersion>
    119123      <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
     124      <Private>False</Private>
    120125    </Reference>
    121126    <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
    122127      <SpecificVersion>False</SpecificVersion>
    123128      <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
     129      <Private>False</Private>
    124130    </Reference>
    125131    <Reference Include="HeuristicLab.Core.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
    126132      <SpecificVersion>False</SpecificVersion>
    127133      <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Core.Views-3.3.dll</HintPath>
     134      <Private>False</Private>
    128135    </Reference>
    129136    <Reference Include="HeuristicLab.Data-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
    130137      <SpecificVersion>False</SpecificVersion>
    131138      <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
     139      <Private>False</Private>
    132140    </Reference>
    133141    <Reference Include="HeuristicLab.Data.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
    134142      <SpecificVersion>False</SpecificVersion>
    135143      <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Data.Views-3.3.dll</HintPath>
     144      <Private>False</Private>
    136145    </Reference>
    137146    <Reference Include="HeuristicLab.MainForm-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
    138147      <SpecificVersion>False</SpecificVersion>
    139148      <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.MainForm-3.3.dll</HintPath>
     149      <Private>False</Private>
    140150    </Reference>
    141151    <Reference Include="HeuristicLab.MainForm.WindowsForms-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
    142152      <SpecificVersion>False</SpecificVersion>
    143153      <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.MainForm.WindowsForms-3.3.dll</HintPath>
     154      <Private>False</Private>
    144155    </Reference>
    145156    <Reference Include="HeuristicLab.Optimization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
    146157      <SpecificVersion>False</SpecificVersion>
    147158      <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
     159      <Private>False</Private>
    148160    </Reference>
    149161    <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
    150162      <SpecificVersion>False</SpecificVersion>
    151163      <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
     164      <Private>False</Private>
    152165    </Reference>
    153166    <Reference Include="HeuristicLab.Problems.Instances-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
    154167      <SpecificVersion>False</SpecificVersion>
    155168      <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
     169      <Private>False</Private>
    156170    </Reference>
    157171    <Reference Include="HeuristicLab.Problems.Instances.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
    158172      <SpecificVersion>False</SpecificVersion>
    159173      <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Problems.Instances.Views-3.3.dll</HintPath>
     174      <Private>False</Private>
    160175    </Reference>
    161176    <Reference Include="HeuristicLab.Visualization.ChartControlsExtensions-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
    162177      <SpecificVersion>False</SpecificVersion>
    163178      <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Visualization.ChartControlsExtensions-3.3.dll</HintPath>
     179      <Private>False</Private>
    164180    </Reference>
    165181    <Reference Include="Microsoft.CSharp" />
  • branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBoxPlotView.cs

    r8962 r9421  
    124124        this.categoricalMapping.Clear();
    125125        UpdateDataPoints();
     126        UpdateAxisLabels();
    126127      }
    127128    }
     
    137138        this.Invoke(new EventHandler(run_Changed), sender, e);
    138139      else if (!suppressUpdates) {
    139         IRun run = (IRun)sender;
    140140        UpdateDataPoints();
    141141      }
     
    326326    }
    327327    private double GetCategoricalValue(int dimension, string value) {
    328       if (!this.categoricalMapping.ContainsKey(dimension))
     328      if (!this.categoricalMapping.ContainsKey(dimension)) {
    329329        this.categoricalMapping[dimension] = new Dictionary<object, double>();
    330       if (!this.categoricalMapping[dimension].ContainsKey(value)) {
    331         if (this.categoricalMapping[dimension].Values.Count == 0)
    332           this.categoricalMapping[dimension][value] = 1.0;
    333         else
    334           this.categoricalMapping[dimension][value] = this.categoricalMapping[dimension].Values.Max() + 1.0;
     330        var orderedCategories = Content.Where(r=> r.Visible).Select(r => Content.GetValue(r, dimension).ToString())
     331                                .Distinct()
     332                                .OrderBy(x => x, new NaturalStringComparer());
     333        int count = 1;
     334        foreach (var category in orderedCategories) {
     335          this.categoricalMapping[dimension].Add(category, count);
     336          count++;
     337        }
    335338      }
    336339      return this.categoricalMapping[dimension][value];
  • branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBubbleChartView.Designer.cs

    r9240 r9421  
    6565      this.selectButton = new System.Windows.Forms.RadioButton();
    6666      this.radioButtonGroup = new System.Windows.Forms.GroupBox();
    67       this.colorButton = new System.Windows.Forms.Button();
     67      this.colorDialogButton = new System.Windows.Forms.Button();
    6868      this.colorDialog = new System.Windows.Forms.ColorDialog();
    6969      this.tooltip = new System.Windows.Forms.ToolTip(this.components);
     
    7373      this.sizeTrackBar = new System.Windows.Forms.TrackBar();
    7474      this.getDataAsMatrixToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
     75      this.transparencyTrackBar = new System.Windows.Forms.TrackBar();
     76      this.transparencyLabel = new System.Windows.Forms.Label();
     77      this.colorRunsButton = new System.Windows.Forms.Button();
     78      this.hideRunsButton = new System.Windows.Forms.Button();
    7579      ((System.ComponentModel.ISupportInitialize)(this.xTrackBar)).BeginInit();
    7680      ((System.ComponentModel.ISupportInitialize)(this.yTrackBar)).BeginInit();
     
    7882      this.radioButtonGroup.SuspendLayout();
    7983      ((System.ComponentModel.ISupportInitialize)(this.sizeTrackBar)).BeginInit();
     84      ((System.ComponentModel.ISupportInitialize)(this.transparencyTrackBar)).BeginInit();
    8085      this.SuspendLayout();
    8186      //
     
    254259      this.radioButtonGroup.Controls.Add(this.zoomButton);
    255260      this.radioButtonGroup.Controls.Add(this.selectButton);
    256       this.radioButtonGroup.Location = new System.Drawing.Point(3, 461);
     261      this.radioButtonGroup.Location = new System.Drawing.Point(2, 461);
    257262      this.radioButtonGroup.Name = "radioButtonGroup";
    258       this.radioButtonGroup.Size = new System.Drawing.Size(135, 32);
     263      this.radioButtonGroup.Size = new System.Drawing.Size(122, 32);
    259264      this.radioButtonGroup.TabIndex = 19;
    260265      this.radioButtonGroup.TabStop = false;
    261266      //
    262       // colorButton
    263       //
    264       this.colorButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
    265       this.colorButton.Enabled = false;
    266       this.colorButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
    267       this.colorButton.Location = new System.Drawing.Point(144, 469);
    268       this.colorButton.Name = "colorButton";
    269       this.colorButton.Size = new System.Drawing.Size(64, 21);
    270       this.colorButton.TabIndex = 20;
    271       this.colorButton.Text = "Color";
    272       this.colorButton.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
    273       this.colorButton.UseVisualStyleBackColor = true;
    274       this.colorButton.Click += new System.EventHandler(this.colorButton_Click);
     267      // colorDialogButton
     268      //
     269      this.colorDialogButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
     270      this.colorDialogButton.Enabled = false;
     271      this.colorDialogButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
     272      this.colorDialogButton.Location = new System.Drawing.Point(130, 469);
     273      this.colorDialogButton.Name = "colorDialogButton";
     274      this.colorDialogButton.Size = new System.Drawing.Size(21, 21);
     275      this.colorDialogButton.TabIndex = 20;
     276      this.colorDialogButton.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
     277      this.tooltip.SetToolTip(this.colorDialogButton, "Choose color");
     278      this.colorDialogButton.UseVisualStyleBackColor = true;
     279      this.colorDialogButton.Click += new System.EventHandler(this.colorDialogButton_Click);
    275280      //
    276281      // colorDialog
     
    318323      this.sizeTrackBar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
    319324      this.sizeTrackBar.Location = new System.Drawing.Point(787, 3);
    320       this.sizeTrackBar.Maximum = 50;
    321       this.sizeTrackBar.Minimum = 5;
     325      this.sizeTrackBar.Maximum = 20;
     326      this.sizeTrackBar.Minimum = -20;
    322327      this.sizeTrackBar.Name = "sizeTrackBar";
    323328      this.sizeTrackBar.Size = new System.Drawing.Size(64, 45);
    324329      this.sizeTrackBar.TabIndex = 24;
    325       this.sizeTrackBar.TickStyle = System.Windows.Forms.TickStyle.None;
    326       this.sizeTrackBar.Value = 10;
     330      this.sizeTrackBar.TickFrequency = 20;
     331      this.sizeTrackBar.TickStyle = System.Windows.Forms.TickStyle.TopLeft;
    327332      this.sizeTrackBar.ValueChanged += new System.EventHandler(this.sizeTrackBar_ValueChanged);
    328333      //
    329       // ToolStripMenuItem
     334      // getDataAsMatrixToolStripMenuItem
    330335      //
    331336      this.getDataAsMatrixToolStripMenuItem.Name = "getDataAsMatrixToolStripMenuItem";
     
    334339      this.getDataAsMatrixToolStripMenuItem.Click += new System.EventHandler(this.getDataAsMatrixToolStripMenuItem_Click);
    335340      //
     341      // transparencyTrackBar
     342      //
     343      this.transparencyTrackBar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
     344      this.transparencyTrackBar.LargeChange = 16;
     345      this.transparencyTrackBar.Location = new System.Drawing.Point(359, 470);
     346      this.transparencyTrackBar.Maximum = 254;
     347      this.transparencyTrackBar.Name = "transparencyTrackBar";
     348      this.transparencyTrackBar.Size = new System.Drawing.Size(64, 45);
     349      this.transparencyTrackBar.TabIndex = 24;
     350      this.transparencyTrackBar.TickStyle = System.Windows.Forms.TickStyle.None;
     351      this.tooltip.SetToolTip(this.transparencyTrackBar, "Sets the transparency of the colors");
     352      this.transparencyTrackBar.ValueChanged += new System.EventHandler(this.transparencyTrackBar_ValueChanged);
     353      //
     354      // transparencyLabel
     355      //
     356      this.transparencyLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
     357      this.transparencyLabel.AutoSize = true;
     358      this.transparencyLabel.Location = new System.Drawing.Point(278, 475);
     359      this.transparencyLabel.Name = "transparencyLabel";
     360      this.transparencyLabel.Size = new System.Drawing.Size(75, 13);
     361      this.transparencyLabel.TabIndex = 12;
     362      this.transparencyLabel.Text = "Transparency:";
     363      //
     364      // colorRunsButton
     365      //
     366      this.colorRunsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
     367      this.colorRunsButton.Enabled = false;
     368      this.colorRunsButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
     369      this.colorRunsButton.Location = new System.Drawing.Point(151, 469);
     370      this.colorRunsButton.Name = "colorRunsButton";
     371      this.colorRunsButton.Size = new System.Drawing.Size(43, 21);
     372      this.colorRunsButton.TabIndex = 25;
     373      this.colorRunsButton.Text = "Color";
     374      this.colorRunsButton.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
     375      this.tooltip.SetToolTip(this.colorRunsButton, "Color all selected runs");
     376      this.colorRunsButton.UseVisualStyleBackColor = true;
     377      this.colorRunsButton.Click += new System.EventHandler(this.colorRunsButton_Click);
     378      //
     379      // hideRunsButton
     380      //
     381      this.hideRunsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
     382      this.hideRunsButton.Enabled = false;
     383      this.hideRunsButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
     384      this.hideRunsButton.Location = new System.Drawing.Point(194, 469);
     385      this.hideRunsButton.Name = "hideRunsButton";
     386      this.hideRunsButton.Size = new System.Drawing.Size(43, 21);
     387      this.hideRunsButton.TabIndex = 26;
     388      this.hideRunsButton.Text = "Hide";
     389      this.hideRunsButton.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
     390      this.tooltip.SetToolTip(this.hideRunsButton, "Hides all selected runs");
     391      this.hideRunsButton.UseVisualStyleBackColor = true;
     392      this.hideRunsButton.Click += new System.EventHandler(this.hideRunsButton_Click);
     393      //
    336394      // RunCollectionBubbleChartView
    337395      //
    338       this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
    339396      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
    340397      this.BackColor = System.Drawing.SystemColors.Window;
    341398      this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
     399      this.Controls.Add(this.hideRunsButton);
     400      this.Controls.Add(this.colorRunsButton);
     401      this.Controls.Add(this.transparencyTrackBar);
    342402      this.Controls.Add(this.sizeTrackBar);
    343403      this.Controls.Add(this.colorYAxisButton);
    344404      this.Controls.Add(this.colorXAxisButton);
    345405      this.Controls.Add(this.noRunsLabel);
    346       this.Controls.Add(this.colorButton);
     406      this.Controls.Add(this.colorDialogButton);
    347407      this.Controls.Add(this.radioButtonGroup);
    348408      this.Controls.Add(this.chart);
     
    350410      this.Controls.Add(this.sizeComboBox);
    351411      this.Controls.Add(this.yJitterLabel);
     412      this.Controls.Add(this.transparencyLabel);
    352413      this.Controls.Add(this.xJitterlabel);
    353414      this.Controls.Add(this.xTrackBar);
     
    365426      this.radioButtonGroup.PerformLayout();
    366427      ((System.ComponentModel.ISupportInitialize)(this.sizeTrackBar)).EndInit();
     428      ((System.ComponentModel.ISupportInitialize)(this.transparencyTrackBar)).EndInit();
    367429      this.ResumeLayout(false);
    368430      this.PerformLayout();
     
    385447    private System.Windows.Forms.RadioButton selectButton;
    386448    private System.Windows.Forms.GroupBox radioButtonGroup;
    387     private System.Windows.Forms.Button colorButton;
     449    private System.Windows.Forms.Button colorDialogButton;
    388450    private System.Windows.Forms.ColorDialog colorDialog;
    389451    private System.Windows.Forms.ToolTip tooltip;
     
    395457    private System.Windows.Forms.TrackBar sizeTrackBar;
    396458    private System.Windows.Forms.ToolStripMenuItem getDataAsMatrixToolStripMenuItem;
     459    private System.Windows.Forms.TrackBar transparencyTrackBar;
     460    private System.Windows.Forms.Label transparencyLabel;
     461    private System.Windows.Forms.Button colorRunsButton;
     462    private System.Windows.Forms.Button hideRunsButton;
    397463  }
    398464}
  • branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBubbleChartView.cs

    r9240 r9421  
    2020#endregion
    2121
    22 using HeuristicLab.Common;
    23 using HeuristicLab.Core;
    24 using HeuristicLab.Data;
    25 using HeuristicLab.MainForm;
    26 using HeuristicLab.MainForm.WindowsForms;
    2722using System;
    2823using System.Collections.Generic;
     
    3126using System.Windows.Forms;
    3227using System.Windows.Forms.DataVisualization.Charting;
     28using HeuristicLab.Common;
     29using HeuristicLab.Core;
     30using HeuristicLab.Data;
     31using HeuristicLab.MainForm;
     32using HeuristicLab.MainForm.WindowsForms;
    3333
    3434namespace HeuristicLab.Optimization.Views {
     
    4343    private string sizeAxisValue;
    4444
    45     private Dictionary<IRun, List<DataPoint>> runToDataPointMapping;
    46     private Dictionary<int, Dictionary<object, double>> categoricalMapping;
    47     private Dictionary<IRun, double> xJitter;
    48     private Dictionary<IRun, double> yJitter;
     45    private readonly Dictionary<IRun, List<DataPoint>> runToDataPointMapping = new Dictionary<IRun, List<DataPoint>>();
     46    private readonly Dictionary<IRun, int> runToIndexMapping = new Dictionary<IRun, int>();
     47    private readonly Dictionary<int, Dictionary<object, double>> categoricalMapping = new Dictionary<int, Dictionary<object, double>>();
     48    private readonly Dictionary<IRun, double> xJitter = new Dictionary<IRun, double>();
     49    private readonly Dictionary<IRun, double> yJitter = new Dictionary<IRun, double>();
     50
     51    private readonly HashSet<IRun> selectedRuns = new HashSet<IRun>();
     52    private readonly Random random = new Random();
    4953    private double xJitterFactor = 0.0;
    5054    private double yJitterFactor = 0.0;
    51     private Random random;
    5255    private bool isSelecting = false;
    5356    private bool suppressUpdates = false;
     57
    5458
    5559    public RunCollectionBubbleChartView() {
     
    6165      chart.ContextMenuStrip.Opening += new System.ComponentModel.CancelEventHandler(ContextMenuStrip_Opening);
    6266
    63       runToDataPointMapping = new Dictionary<IRun, List<DataPoint>>();
    64       categoricalMapping = new Dictionary<int, Dictionary<object, double>>();
    65       xJitter = new Dictionary<IRun, double>();
    66       yJitter = new Dictionary<IRun, double>();
    67       random = new Random();
    68 
    6967      colorDialog.Color = Color.Black;
    70       colorButton.Image = this.GenerateImage(16, 16, this.colorDialog.Color);
     68      colorDialogButton.Image = this.GenerateImage(16, 16, this.colorDialog.Color);
    7169      isSelecting = false;
    7270
     
    8482    public IStringConvertibleMatrix Matrix {
    8583      get { return this.Content; }
     84    }
     85    public IEnumerable<IRun> SelectedRuns {
     86      get { return selectedRuns; }
    8687    }
    8788
     
    9394      Content.ItemsRemoved += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
    9495      Content.CollectionReset += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
     96      Content.OptimizerNameChanged += new EventHandler(Content_AlgorithmNameChanged);
    9597      Content.UpdateOfRunsInProgressChanged += new EventHandler(Content_UpdateOfRunsInProgressChanged);
    96       Content.OptimizerNameChanged += new EventHandler(Content_AlgorithmNameChanged);
    9798      RegisterRunEvents(Content);
    9899    }
     
    104105      Content.ItemsRemoved -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
    105106      Content.CollectionReset -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
     107      Content.OptimizerNameChanged -= new EventHandler(Content_AlgorithmNameChanged);
    106108      Content.UpdateOfRunsInProgressChanged -= new EventHandler(Content_UpdateOfRunsInProgressChanged);
    107       Content.OptimizerNameChanged -= new EventHandler(Content_AlgorithmNameChanged);
    108109      DeregisterRunEvents(Content);
    109110    }
     
    128129    }
    129130    private void run_Changed(object sender, EventArgs e) {
     131      if (suppressUpdates) return;
    130132      if (InvokeRequired)
    131133        this.Invoke(new EventHandler(run_Changed), sender, e);
     
    133135        IRun run = (IRun)sender;
    134136        UpdateRun(run);
     137        UpdateCursorInterval();
     138        chart.ChartAreas[0].RecalculateAxesScale();
     139        UpdateAxisLabels();
     140      }
     141    }
     142
     143    private void Content_UpdateOfRunsInProgressChanged(object sender, EventArgs e) {
     144      if (InvokeRequired)
     145        this.Invoke(new EventHandler(Content_UpdateOfRunsInProgressChanged), sender, e);
     146      else {
     147        suppressUpdates = Content.UpdateOfRunsInProgress;
     148        if (suppressUpdates) return;
     149
     150        foreach (var run in Content) UpdateRun(run);
     151        UpdateMarkerSizes();
     152        UpdateCursorInterval();
     153        chart.ChartAreas[0].RecalculateAxesScale();
     154        UpdateAxisLabels();
    135155      }
    136156    }
    137157
    138158    private void UpdateRun(IRun run) {
    139       if (!suppressUpdates) {
    140         if (runToDataPointMapping.ContainsKey(run)) {
    141           foreach (DataPoint point in runToDataPointMapping[run]) {
    142             point.Color = run.Color;
    143             if (!run.Visible) {
    144               this.chart.Series[0].Points.Remove(point);
    145               UpdateCursorInterval();
    146               chart.ChartAreas[0].RecalculateAxesScale();
    147             }
     159      if (runToDataPointMapping.ContainsKey(run)) {
     160        foreach (DataPoint point in runToDataPointMapping[run]) {
     161          if (!run.Visible) {
     162            this.chart.Series[0].Points.Remove(point);
     163            continue;
    148164          }
    149           if (!run.Visible) runToDataPointMapping.Remove(run);
    150         } else {
    151           AddDataPoint(run);
    152           UpdateCursorInterval();
    153           chart.ChartAreas[0].RecalculateAxesScale();
    154         }
    155 
    156         if (this.chart.Series[0].Points.Count == 0)
    157           noRunsLabel.Visible = true;
    158         else
    159           noRunsLabel.Visible = false;
    160       }
     165          if (selectedRuns.Contains(run)) {
     166            point.Color = Color.Red;
     167            point.MarkerStyle = MarkerStyle.Cross;
     168          } else {
     169            point.Color = Color.FromArgb(255 - transparencyTrackBar.Value, ((IRun)point.Tag).Color);
     170            point.MarkerStyle = MarkerStyle.Circle;
     171          }
     172
     173        }
     174        if (!run.Visible) runToDataPointMapping.Remove(run);
     175      } else {
     176        AddDataPoint(run);
     177      }
     178
     179      if (this.chart.Series[0].Points.Count == 0)
     180        noRunsLabel.Visible = true;
     181      else
     182        noRunsLabel.Visible = false;
    161183    }
    162184
     
    167189      UpdateDataPoints();
    168190      UpdateCaption();
    169     }
     191      RebuildInverseIndex();
     192    }
     193
     194    private void RebuildInverseIndex() {
     195      if (Content != null) {
     196        runToIndexMapping.Clear();
     197        int i = 0;
     198        foreach (var run in Content) {
     199          runToIndexMapping.Add(run, i);
     200          i++;
     201        }
     202      }
     203    }
     204
    170205    private void Content_ColumnNamesChanged(object sender, EventArgs e) {
    171206      if (InvokeRequired)
     
    210245          changed = true;
    211246        }
    212         if (changed)
     247        if (changed) {
    213248          UpdateDataPoints();
    214       }
    215     }
    216 
    217 
    218     private void Content_UpdateOfRunsInProgressChanged(object sender, EventArgs e) {
    219       if (InvokeRequired)
    220         Invoke(new EventHandler(Content_UpdateOfRunsInProgressChanged), sender, e);
    221       else {
    222         suppressUpdates = Content.UpdateOfRunsInProgress;
    223         if (!suppressUpdates) UpdateDataPoints();
     249          UpdateAxisLabels();
     250        }
    224251      }
    225252    }
     
    236263      else {
    237264        this.categoricalMapping.Clear();
     265        RebuildInverseIndex();
    238266        UpdateDataPoints();
     267        UpdateAxisLabels();
    239268      }
    240269    }
     
    244273      series.Points.Clear();
    245274      runToDataPointMapping.Clear();
     275      selectedRuns.Clear();
    246276
    247277      chart.ChartAreas[0].AxisX.IsMarginVisible = xAxisValue != AxisDimension.Index.ToString();
     
    272302
    273303    private void UpdateMarkerSizes() {
    274       double[] sizeValues = this.chart.Series[0].Points.Select(p => p.YValues[1]).ToArray();
     304      var series = chart.Series[0];
     305      if (series.Points.Count <= 0) return;
     306
     307      var sizeValues = series.Points.Select(p => p.YValues[1]);
    275308      double minSizeValue = sizeValues.Min();
    276309      double maxSizeValue = sizeValues.Max();
    277 
    278       for (int i = 0; i < sizeValues.Length; i++) {
    279         DataPoint point = this.chart.Series[0].Points[i];
    280         double sizeRange = maxSizeValue - minSizeValue;
     310      double sizeRange = maxSizeValue - minSizeValue;
     311
     312      const int smallestBubbleSize = 5;
     313
     314      foreach (DataPoint point in series.Points) {
     315        //calculates the relative size of the data point  0 <= relativeSize <= 1
    281316        double relativeSize = (point.YValues[1] - minSizeValue);
    282 
    283         if (sizeRange > double.Epsilon) relativeSize /= sizeRange;
    284         else relativeSize = 1;
    285 
    286         point.MarkerSize = (int)Math.Round((sizeTrackBar.Value - sizeTrackBar.Minimum) * relativeSize + sizeTrackBar.Minimum);
     317        if (sizeRange > double.Epsilon) {
     318          relativeSize /= sizeRange;
     319
     320          //invert bubble sizes if the value of the trackbar is negative
     321          if (sizeTrackBar.Value < 0) relativeSize = Math.Abs(relativeSize - 1);
     322        } else relativeSize = 1;
     323
     324        double sizeChange = Math.Abs(sizeTrackBar.Value) * relativeSize;
     325        point.MarkerSize = (int)Math.Round(sizeChange + smallestBubbleSize);
    287326      }
    288327    }
     
    344383      if (xValue.HasValue && yValue.HasValue && sizeValue.HasValue) {
    345384        xValue = xValue.Value;
    346 
    347385        yValue = yValue.Value;
    348386
     
    350388          DataPoint point = new DataPoint(xValue.Value, new double[] { yValue.Value, sizeValue.Value });
    351389          point.Tag = run;
    352           point.Color = run.Color;
    353390          series.Points.Add(point);
    354391          if (!runToDataPointMapping.ContainsKey(run)) runToDataPointMapping.Add(run, new List<DataPoint>());
    355392          runToDataPointMapping[run].Add(point);
     393          UpdateRun(run);
    356394        }
    357395      }
     
    391429    }
    392430    private double GetCategoricalValue(int dimension, string value) {
    393       if (!this.categoricalMapping.ContainsKey(dimension))
     431      if (!this.categoricalMapping.ContainsKey(dimension)) {
    394432        this.categoricalMapping[dimension] = new Dictionary<object, double>();
    395       if (!this.categoricalMapping[dimension].ContainsKey(value)) {
    396         if (this.categoricalMapping[dimension].Values.Count == 0)
    397           this.categoricalMapping[dimension][value] = 1.0;
    398         else
    399           this.categoricalMapping[dimension][value] = this.categoricalMapping[dimension].Values.Max() + 1.0;
     433        var orderedCategories = Content.Where(r => r.Visible).Select(r => Content.GetValue(r, dimension).ToString())
     434                                    .Distinct()
     435                                    .OrderBy(x => x, new NaturalStringComparer());
     436        int count = 1;
     437        foreach (var category in orderedCategories) {
     438          this.categoricalMapping[dimension].Add(category, count);
     439          count++;
     440        }
    400441      }
    401442      return this.categoricalMapping[dimension][value];
    402443    }
     444
    403445    private double GetValue(IRun run, AxisDimension axisDimension) {
    404446      double value = double.NaN;
    405447      switch (axisDimension) {
    406448        case AxisDimension.Index: {
    407             value = Content.ToList().IndexOf(run);
     449            value = runToIndexMapping[run];
    408450            break;
    409451          }
     
    428470    }
    429471    private void UpdateCursorInterval() {
    430       Series series = chart.Series[0];
    431       double[] xValues = (from point in series.Points
    432                           where !point.IsEmpty
    433                           select point.XValue)
    434                     .DefaultIfEmpty(1.0)
    435                     .ToArray();
    436       double[] yValues = (from point in series.Points
    437                           where !point.IsEmpty
    438                           select point.YValues[0])
    439                     .DefaultIfEmpty(1.0)
    440                     .ToArray();
    441 
    442       double xRange = xValues.Max() - xValues.Min();
    443       double yRange = yValues.Max() - yValues.Min();
     472      double xMin = double.MaxValue;
     473      double xMax = double.MinValue;
     474      double yMin = double.MaxValue;
     475      double yMax = double.MinValue;
     476
     477      foreach (var point in chart.Series[0].Points) {
     478        if (point.IsEmpty) continue;
     479        if (point.XValue < xMin) xMin = point.XValue;
     480        if (point.XValue > xMax) xMax = point.XValue;
     481        if (point.YValues[0] < yMin) yMin = point.YValues[0];
     482        if (point.YValues[0] > yMax) yMax = point.YValues[0];
     483      }
     484
     485      double xRange = 0.0;
     486      double yRange = 0.0;
     487      if (xMin != double.MaxValue && xMax != double.MinValue) xRange = xMax - xMin;
     488      if (yMin != double.MaxValue && yMax != double.MinValue) yRange = yMax - yMin;
     489
    444490      if (xRange.IsAlmost(0.0)) xRange = 1.0;
    445491      if (yRange.IsAlmost(0.0)) yRange = 1.0;
     
    479525
    480526    private void chart_MouseUp(object sender, MouseEventArgs e) {
    481       if (isSelecting) {
    482         System.Windows.Forms.DataVisualization.Charting.Cursor xCursor = chart.ChartAreas[0].CursorX;
    483         System.Windows.Forms.DataVisualization.Charting.Cursor yCursor = chart.ChartAreas[0].CursorY;
    484 
    485         double minX = Math.Min(xCursor.SelectionStart, xCursor.SelectionEnd);
    486         double maxX = Math.Max(xCursor.SelectionStart, xCursor.SelectionEnd);
    487         double minY = Math.Min(yCursor.SelectionStart, yCursor.SelectionEnd);
    488         double maxY = Math.Max(yCursor.SelectionStart, yCursor.SelectionEnd);
    489 
    490         //check for click to select model
    491         if (minX == maxX && minY == maxY) {
    492           HitTestResult hitTest = chart.HitTest(e.X, e.Y);
    493           if (hitTest.ChartElementType == ChartElementType.DataPoint) {
    494             int pointIndex = hitTest.PointIndex;
    495             IRun run = (IRun)this.chart.Series[0].Points[pointIndex].Tag;
    496             run.Color = colorDialog.Color;
    497           }
    498         } else {
    499           List<DataPoint> selectedPoints = new List<DataPoint>();
    500           foreach (DataPoint p in this.chart.Series[0].Points) {
    501             if (p.XValue >= minX && p.XValue < maxX &&
    502               p.YValues[0] >= minY && p.YValues[0] < maxY) {
    503               selectedPoints.Add(p);
    504             }
    505           }
    506           foreach (DataPoint p in selectedPoints) {
    507             IRun run = (IRun)p.Tag;
    508             run.Color = colorDialog.Color;
    509           }
    510         }
    511         this.chart.ChartAreas[0].CursorX.SelectionStart = this.chart.ChartAreas[0].CursorX.SelectionEnd;
    512         this.chart.ChartAreas[0].CursorY.SelectionStart = this.chart.ChartAreas[0].CursorY.SelectionEnd;
    513       }
     527      if (!isSelecting) return;
     528
     529      System.Windows.Forms.DataVisualization.Charting.Cursor xCursor = chart.ChartAreas[0].CursorX;
     530      System.Windows.Forms.DataVisualization.Charting.Cursor yCursor = chart.ChartAreas[0].CursorY;
     531
     532      double minX = Math.Min(xCursor.SelectionStart, xCursor.SelectionEnd);
     533      double maxX = Math.Max(xCursor.SelectionStart, xCursor.SelectionEnd);
     534      double minY = Math.Min(yCursor.SelectionStart, yCursor.SelectionEnd);
     535      double maxY = Math.Max(yCursor.SelectionStart, yCursor.SelectionEnd);
     536
     537      //check for click to select a single model
     538      if (minX == maxX && minY == maxY) {
     539        HitTestResult hitTest = chart.HitTest(e.X, e.Y, ChartElementType.DataPoint);
     540        if (hitTest.ChartElementType == ChartElementType.DataPoint) {
     541          int pointIndex = hitTest.PointIndex;
     542          var point = chart.Series[0].Points[pointIndex];
     543          IRun run = (IRun)point.Tag;
     544          point.Color = Color.Red;
     545          point.MarkerStyle = MarkerStyle.Cross;
     546          selectedRuns.Add(run);
     547
     548        } else ClearSelectedRuns();
     549      } else {
     550        foreach (DataPoint point in this.chart.Series[0].Points) {
     551          if (point.XValue < minX || point.XValue >= maxX) continue;
     552          if (point.YValues[0] < minY || point.YValues[0] >= maxY) continue;
     553          point.MarkerStyle = MarkerStyle.Cross;
     554          point.Color = Color.Red;
     555          IRun run = (IRun)point.Tag;
     556          selectedRuns.Add(run);
     557        }
     558      }
     559
     560      this.chart.ChartAreas[0].CursorX.SelectionStart = this.chart.ChartAreas[0].CursorX.SelectionEnd;
     561      this.chart.ChartAreas[0].CursorY.SelectionStart = this.chart.ChartAreas[0].CursorY.SelectionEnd;
     562      this.OnChanged();
    514563    }
    515564
    516565    private void chart_MouseMove(object sender, MouseEventArgs e) {
     566      if (Control.MouseButtons != MouseButtons.None) return;
    517567      HitTestResult h = this.chart.HitTest(e.X, e.Y);
    518568      string newTooltipText = string.Empty;
     
    638688    private void zoomButton_CheckedChanged(object sender, EventArgs e) {
    639689      this.isSelecting = selectButton.Checked;
    640       this.colorButton.Enabled = this.isSelecting;
     690      this.colorDialogButton.Enabled = this.isSelecting;
     691      this.colorRunsButton.Enabled = this.isSelecting;
     692      this.hideRunsButton.Enabled = this.isSelecting;
    641693      this.chart.ChartAreas[0].AxisX.ScaleView.Zoomable = !isSelecting;
    642694      this.chart.ChartAreas[0].AxisY.ScaleView.Zoomable = !isSelecting;
    643     }
    644     private void colorButton_Click(object sender, EventArgs e) {
    645       if (colorDialog.ShowDialog(this) == DialogResult.OK) {
    646         this.colorButton.Image = this.GenerateImage(16, 16, this.colorDialog.Color);
    647       }
    648     }
    649     private Image GenerateImage(int width, int height, Color fillColor) {
    650       Image colorImage = new Bitmap(width, height);
    651       using (Graphics gfx = Graphics.FromImage(colorImage)) {
    652         using (SolidBrush brush = new SolidBrush(fillColor)) {
    653           gfx.FillRectangle(brush, 0, 0, width, height);
    654         }
    655       }
    656       return colorImage;
     695      ClearSelectedRuns();
    657696    }
    658697
     
    673712    }
    674713    private void hideRunToolStripMenuItem_Click(object sender, EventArgs e) {
    675       var constraint = Content.Constraints.OfType<RunCollectionContentConstraint>().Where(c => c.Active).FirstOrDefault();
     714      var constraint = Content.Constraints.OfType<RunCollectionContentConstraint>().FirstOrDefault(c => c.Active);
    676715      if (constraint == null) {
    677716        constraint = new RunCollectionContentConstraint();
     
    680719      }
    681720      constraint.ConstraintData.Add(runToHide);
     721    }
     722    private void hideRunsButton_Click(object sender, EventArgs e) {
     723      if (!selectedRuns.Any()) return;
     724      var constraint = new RunCollectionContentConstraint();
     725      constraint.ConstraintData = new ItemSet<IRun>(selectedRuns);
     726      Content.Constraints.Add(constraint);
     727      ClearSelectedRuns();
     728      constraint.Active = true;
     729    }
     730
     731    private void ClearSelectedRuns() {
     732      foreach (var run in selectedRuns) {
     733        foreach (var point in runToDataPointMapping[run]) {
     734          point.MarkerStyle = MarkerStyle.Circle;
     735          point.Color = Color.FromArgb(255 - LogTransform(transparencyTrackBar.Value), run.Color);
     736        }
     737      }
     738      selectedRuns.Clear();
     739    }
     740
     741    // returns a value in [0..255]
     742    private int LogTransform(int x) {
     743      double min = transparencyTrackBar.Minimum;
     744      double max = transparencyTrackBar.Maximum;
     745      double r = (x - min) / (max - min);  // r \in [0..1]
     746      double l = Math.Log(r + 1) / Math.Log(2.0); // l \in [0..1]
     747      return (int)Math.Round(255.0 * l);
    682748    }
    683749
     
    692758    private void getDataAsMatrixToolStripMenuItem_Click(object sender, EventArgs e) {
    693759      int xCol = Matrix.ColumnNames.ToList().IndexOf(xAxisValue);
     760      int yCol = Matrix.ColumnNames.ToList().IndexOf(yAxisValue);
     761
    694762      var grouped = new Dictionary<string, List<string>>();
    695763      Dictionary<double, string> reverseMapping = null;
     
    698766      foreach (var run in Content.Where(r => r.Visible)) {
    699767        var x = GetValue(run, xAxisValue);
    700         var y = GetValue(run, yAxisValue);
    701         if (!(x.HasValue && y.HasValue)) continue;
     768        object y;
     769        if (categoricalMapping.ContainsKey(yCol))
     770          y = Content.GetValue(run, yAxisValue);
     771        else y = GetValue(run, yAxisValue);
     772        if (!(x.HasValue && y != null)) continue;
    702773
    703774        var category = reverseMapping == null ? x.Value.ToString() : reverseMapping[x.Value];
    704775        if (!grouped.ContainsKey(category)) grouped[category] = new List<string>();
    705         grouped[category].Add(y.Value.ToString());
     776        grouped[category].Add(y.ToString());
    706777      }
    707778
     
    717788        i++;
    718789      }
    719 
    720       MainFormManager.MainForm.ShowContent(matrix);
     790      matrix.SortableView = false;
     791      var view = MainFormManager.MainForm.ShowContent(matrix);
     792      view.ReadOnly = true;
     793    }
     794
     795    private void transparencyTrackBar_ValueChanged(object sender, EventArgs e) {
     796      foreach (var run in Content)
     797        UpdateRun(run);
    721798    }
    722799    #endregion
    723800
    724     #region Automatic coloring
     801    #region coloring
     802    private void colorDialogButton_Click(object sender, EventArgs e) {
     803      if (colorDialog.ShowDialog(this) == DialogResult.OK) {
     804        this.colorDialogButton.Image = this.GenerateImage(16, 16, this.colorDialog.Color);
     805      }
     806    }
     807    private Image GenerateImage(int width, int height, Color fillColor) {
     808      Image colorImage = new Bitmap(width, height);
     809      using (Graphics gfx = Graphics.FromImage(colorImage)) {
     810        using (SolidBrush brush = new SolidBrush(fillColor)) {
     811          gfx.FillRectangle(brush, 0, 0, width, height);
     812        }
     813      }
     814      return colorImage;
     815    }
     816
     817    private void colorRunsButton_Click(object sender, EventArgs e) {
     818      if (!selectedRuns.Any()) return;
     819      Content.UpdateOfRunsInProgress = true;
     820      foreach (var run in selectedRuns)
     821        run.Color = colorDialog.Color;
     822
     823      ClearSelectedRuns();
     824      Content.UpdateOfRunsInProgress = false;
     825    }
     826
    725827    private void colorXAxisButton_Click(object sender, EventArgs e) {
    726828      ColorRuns(xAxisValue);
    727829    }
    728 
    729830    private void colorYAxisButton_Click(object sender, EventArgs e) {
    730831      ColorRuns(yAxisValue);
    731832    }
    732 
    733833    private void ColorRuns(string axisValue) {
    734       var runs = Content.Where(r => r.Visible).Select(r => new { Run = r, Value = GetValue(r, axisValue) }).Where(r => r.Value.HasValue);
     834      var runs = Content.Where(r => r.Visible).Select(r => new { Run = r, Value = GetValue(r, axisValue) }).Where(r => r.Value.HasValue).ToList();
    735835      double minValue = runs.Min(r => r.Value.Value);
    736836      double maxValue = runs.Max(r => r.Value.Value);
    737837      double range = maxValue - minValue;
    738 
    739       foreach (var r in runs) {
    740         int colorIndex = 0;
    741         if (!range.IsAlmost(0)) colorIndex = (int)((ColorGradient.Colors.Count - 1) * (r.Value.Value - minValue) / (range));
    742         r.Run.Color = ColorGradient.Colors[colorIndex];
    743       }
     838      // UpdateOfRunsInProgress has to be set to true, otherwise run_Changed is called all the time (also in other views)
     839      Content.UpdateOfRunsInProgress = true;
     840      if (range.IsAlmost(0)) {
     841        Color c = ColorGradient.Colors[0];
     842        runs.ForEach(r => r.Run.Color = c);
     843      } else {
     844        int maxColorIndex = ColorGradient.Colors.Count - 1;
     845        foreach (var r in runs) {
     846          int colorIndex = (int)(maxColorIndex * (r.Value - minValue) / (range));
     847          r.Run.Color = ColorGradient.Colors[colorIndex];
     848        }
     849      }
     850      Content.UpdateOfRunsInProgress = false;
    744851    }
    745852    #endregion
Note: See TracChangeset for help on using the changeset viewer.