Changeset 12397


Ignore:
Timestamp:
05/26/15 12:09:33 (7 years ago)
Author:
pfleck
Message:

#2387

  • Adapted behavior of the matching in the TypeSelector that it behave the same as the NewItemDialog. The search string is tokenized by space and matches if all tokens are contained, (eg. "Sym Reg" matches "SymbolicRegression...").
  • Enabled navigation with up- and down-arrow in the tree while the search-box is focused.
  • Improved response time of NewItemDialog and TypeSelector when they contain a large amount of nodes.
Location:
trunk/sources
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Core.Views/3.3/TypeSelector.Designer.cs

    r12012 r12397  
    152152      this.toolTip.SetToolTip(this.searchTextBox, "Enter string to search for types");
    153153      this.searchTextBox.TextChanged += new System.EventHandler(this.searchTextBox_TextChanged);
     154      this.searchTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.searchTextBox_KeyDown);
    154155      //
    155156      // typeParametersGroupBox
  • trunk/sources/HeuristicLab.Core.Views/3.3/TypeSelector.cs

    r12012 r12397  
    192192        // remove nodes
    193193        typesTreeView.BeginUpdate();
     194        var searchTokens = searchString.Split(' ');
     195
    194196        int i = 0;
    195197        while (i < typesTreeView.Nodes.Count) {
    196           int j = 0;
    197           while (j < typesTreeView.Nodes[i].Nodes.Count) {
    198             if (!typesTreeView.Nodes[i].Nodes[j].Text.ToLower().Contains(searchString)) {
    199               if ((typesTreeView.Nodes[i].Nodes[j].Tag as Type).Equals(selectedType))
    200                 SelectedType = null;
    201               typesTreeView.Nodes[i].Nodes[j].Remove();
    202             } else
    203               j++;
    204           }
    205           if (typesTreeView.Nodes[i].Nodes.Count == 0)
    206             typesTreeView.Nodes[i].Remove();
    207           else
    208             i++;
     198          var node = typesTreeView.Nodes[i];
     199          bool remove = FilterNode(node, searchTokens);
     200          if (remove)
     201            typesTreeView.Nodes.RemoveAt(i);
     202          else i++;
    209203        }
    210204        typesTreeView.EndUpdate();
    211205        currentSearchString = searchString;
    212206
    213         // if there is just one type node left, select by default
    214         if (typesTreeView.Nodes.Count == 1) {
    215           if (typesTreeView.Nodes[0].Nodes.Count == 1) {
    216             typesTreeView.SelectedNode = typesTreeView.Nodes[0].Nodes[0];
    217           }
    218         }
     207        // select first item
     208        typesTreeView.BeginUpdate();
     209        var firstNode = typesTreeView.Nodes.Count > 0 ? typesTreeView.Nodes[0] : null;
     210        while (firstNode != null && !(firstNode.Tag is Type))
     211          firstNode = firstNode.NextVisibleNode;
     212        if (firstNode != null)
     213          typesTreeView.SelectedNode = firstNode;
    219214
    220215        if (typesTreeView.Nodes.Count == 0) {
     
    225220          typesTreeView.Enabled = true;
    226221        }
     222        typesTreeView.EndUpdate();
    227223        UpdateDescription();
    228224      }
     225    }
     226
     227    private bool FilterNode(TreeNode node, string[] searchTokens) {
     228      if (node.Tag is IPluginDescription) { // Plugin node
     229        int i = 0;
     230        while (i < node.Nodes.Count) {
     231          bool remove = FilterNode(node.Nodes[i], searchTokens);
     232          if (remove)
     233            node.Nodes.RemoveAt(i);
     234          else i++;
     235        }
     236        return node.Nodes.Count == 0;
     237      } if (node.Tag is Type) { // Type node
     238        var text = node.Text;
     239        if (searchTokens.Any(searchToken => !text.ToLower().Contains(searchToken))) {
     240          var typeTag = (Type)node.Tag;
     241          if (typeTag == SelectedType) {
     242            SelectedType = null;
     243            typesTreeView.SelectedNode = null;
     244          }
     245          return true;
     246        }
     247        return false;
     248      }
     249      throw new InvalidOperationException("Encountered neither a plugin nor a type node during tree traversal.");
    229250    }
    230251
     
    355376      SetTypeParameter();
    356377    }
     378    private void searchTextBox_KeyDown(object sender, KeyEventArgs e) {
     379      if (typesTreeView.Nodes.Count == 0)
     380        return;
     381
     382      if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Down) {
     383        var selectedNode = typesTreeView.SelectedNode;
     384
     385        if (selectedNode == null) { // nothing selected => select first
     386          if (e.KeyCode == Keys.Down) typesTreeView.SelectedNode = typesTreeView.Nodes.Count > 0 ? typesTreeView.Nodes[0] : null;
     387        } else {
     388          if (e.KeyCode == Keys.Down && selectedNode.NextVisibleNode != null)
     389            typesTreeView.SelectedNode = selectedNode.NextVisibleNode;
     390          if (e.KeyCode == Keys.Up && selectedNode.PrevVisibleNode != null)
     391            typesTreeView.SelectedNode = selectedNode.PrevVisibleNode;
     392        }
     393        e.Handled = true;
     394      }
     395    }
    357396    #endregion
    358397
  • trunk/sources/HeuristicLab.Optimizer/3.3/NewItemDialog.cs

    r12393 r12397  
    202202
    203203        // select first item
     204        typesTreeView.BeginUpdate();
    204205        var firstNode = FirstVisibleNode;
    205206        while (firstNode != null && !(firstNode.Tag is Type))
     
    215216          typesTreeView.Enabled = true;
    216217        }
     218        typesTreeView.EndUpdate();
    217219        UpdateDescription();
    218220      }
Note: See TracChangeset for help on using the changeset viewer.