Changeset 12215


Ignore:
Timestamp:
03/17/15 15:04:16 (7 years ago)
Author:
pfleck
Message:

#2025

  • Added hierarchical structure for creatables (parsed from name).
  • Started adapting search to hierarchical structure.
  • Start implemented cursor navigation in treeview while focused searchbox.
Location:
branches/NewItemDialog/HeuristicLab.Optimizer/3.3
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/NewItemDialog/HeuristicLab.Optimizer/3.3/NewItemDialog.Designer.cs

    r12207 r12215  
    158158      this.searchTextBox.TabIndex = 1;
    159159      this.searchTextBox.TextChanged += new System.EventHandler(this.searchTextBox_TextChanged);
     160      this.searchTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.searchTextBox_KeyDown);
    160161      //
    161162      // clearSearchButton
  • branches/NewItemDialog/HeuristicLab.Optimizer/3.3/NewItemDialog.cs

    r12207 r12215  
    2121
    2222using System;
     23using System.Collections;
    2324using System.Collections.Generic;
    2425using System.Drawing;
     
    3031namespace HeuristicLab.Optimizer {
    3132  internal partial class NewItemDialog : Form {
     33    private const string RootMarker = "<ROOT>";
     34
    3235    private bool isInitialized;
    3336
     
    6366
    6467      var categories =
    65         from t in ApplicationManager.Manager.GetTypes(typeof(IItem))
    66         where CreatableAttribute.IsCreatable(t)
    67         orderby CreatableAttribute.GetCategory(t), ItemAttribute.GetName(t), ItemAttribute.GetVersion(t) ascending
    68         group t by CreatableAttribute.GetCategory(t) into c
    69         select c;
    70 
     68        from type in ApplicationManager.Manager.GetTypes(typeof(IItem))
     69        let category = CreatableAttribute.GetCategory(type)
     70        let name = ItemAttribute.GetName(type)
     71        let version = ItemAttribute.GetVersion(type)
     72        where CreatableAttribute.IsCreatable(type)
     73        orderby category, name, version ascending
     74        group type by category into categoryGroup
     75        select categoryGroup;
     76
     77      var rootNode = CreateCategoryTree(categories);
     78      CreateItemNodes(rootNode, categories);
     79
     80      foreach (TreeNode topNode in rootNode.Nodes)
     81        treeNodes.Add(topNode);
     82      foreach (var node in treeNodes)
     83        typesTreeView.Nodes.Add((TreeNode)node.Clone());
     84
     85      typesTreeView.TreeViewNodeSorter = new ItemTreeNodeComparer();
     86      typesTreeView.Sort();
     87
     88      isInitialized = true;
     89    }
     90
     91    private TreeNode CreateCategoryTree(IEnumerable<IGrouping<string, Type>> categories) {
    7192      imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Class);      // default icon
    7293      imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Namespace);  // plugins
    7394
     95      var rootNode = new TreeNode(RootMarker) { Name = RootMarker, Tag = RootMarker };
     96
    7497      foreach (var category in categories) {
    75         var categoryNode = new TreeNode(category.Key) {
    76           ImageIndex = 1,
    77           Tag = category.Key,
     98        var categoryFullName = category.Key;
     99        var categoryTokens = categoryFullName.Split('#');
     100        var categoryName = categoryTokens.Last();
     101        var parentCategories = categoryTokens.Take(categoryTokens.Length - 1);
     102
     103        var categoryNode = new TreeNode(categoryName, 1, 1) {
     104          Name = categoryName,
     105          Tag = categoryName
    78106        };
    79         categoryNode.SelectedImageIndex = categoryNode.ImageIndex;
    80 
     107
     108        var parentNode = FindOrCreateParentNode(rootNode, parentCategories);
     109        if (parentNode != null)
     110          parentNode.Nodes.Add(categoryNode);
     111        else
     112          rootNode.Nodes.Add(categoryNode);
     113      }
     114
     115      return rootNode;
     116    }
     117    private TreeNode FindOrCreateParentNode(TreeNode node, IEnumerable<string> parentCategories) {
     118      TreeNode parentNode = null;
     119      foreach (string parentCategory in parentCategories) {
     120        parentNode = node.Nodes.Find(parentCategory, searchAllChildren: false).SingleOrDefault();
     121        if (parentNode == null) {
     122          parentNode = new TreeNode(parentCategory, 1, 1) {
     123            Name = parentCategory,
     124            Tag = parentCategory
     125          };
     126          node.Nodes.Add(parentNode);
     127        }
     128        node = parentNode;
     129      }
     130      return parentNode;
     131    }
     132
     133    private void CreateItemNodes(TreeNode node, IEnumerable<IGrouping<string, Type>> categories) {
     134      foreach (var category in categories) {
     135        var categoryNode = FindCategoryNode(node, category.Key);
    81136        foreach (var creatable in category) {
    82           string name = ItemAttribute.GetName(creatable);
    83 
    84           var itemNode = new TreeNode(name) {
    85             ImageIndex = 0,
    86             Tag = creatable
    87           };
     137          var itemNode = CreateItemNode(creatable);
    88138          categoryNode.Nodes.Add(itemNode);
    89           var image = ItemAttribute.GetImage(creatable);
    90           if (image != null) {
    91             imageList.Images.Add(image);
    92             itemNode.ImageIndex = imageList.Images.Count - 1;
    93           }
    94           itemNode.SelectedImageIndex = itemNode.ImageIndex;
    95         }
    96         if (categoryNode.Nodes.Count > 0)
    97           treeNodes.Add(categoryNode);
    98       }
    99       foreach (var node in treeNodes)
    100         typesTreeView.Nodes.Add((TreeNode)node.Clone());
    101       isInitialized = true;
    102     }
     139        }
     140      }
     141    }
     142    private TreeNode FindCategoryNode(TreeNode node, string fullCategoryName) {
     143      var categories = fullCategoryName.Split('#');
     144      foreach (string category in categories)
     145        node = node.Nodes.Find(category, searchAllChildren: false).Single();
     146      return node;
     147    }
     148
     149    private TreeNode CreateItemNode(Type creatable) {
     150      string name = ItemAttribute.GetName(creatable);
     151
     152      var itemNode = new TreeNode(name) {
     153        ImageIndex = 0,
     154        Tag = creatable
     155      };
     156
     157      var image = ItemAttribute.GetImage(creatable);
     158      if (image != null) {
     159        imageList.Images.Add(image);
     160        itemNode.ImageIndex = imageList.Images.Count - 1;
     161      }
     162      itemNode.SelectedImageIndex = itemNode.ImageIndex;
     163
     164      return itemNode;
     165    }
     166
    103167    private void NewItemDialog_Shown(object sender, EventArgs e) {
    104168      searchTextBox.Text = string.Empty;
     
    131195          while (j < typesTreeView.Nodes[i].Nodes.Count) {
    132196            if (searchTokens.Any(searchToken => !typesTreeView.Nodes[i].Nodes[j].Text.ToLower().Contains(searchToken))) {
    133               if ((typesTreeView.Nodes[i].Nodes[j].Tag as Type).Equals(SelectedType))
     197              var node = typesTreeView.Nodes[i].Nodes[j];
     198              if (node != null && node.Tag is Type && (node.Tag as Type).Equals(SelectedType))
    134199                SelectedType = null;
    135200              typesTreeView.Nodes[i].Nodes[j].Remove();
     
    313378      searchTextBox.Focus();
    314379    }
     380
     381    private void searchTextBox_KeyDown(object sender, KeyEventArgs e) {
     382      if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Down) {
     383
     384        int? idx = typesTreeView.SelectedNode != null
     385          ? (int?)typesTreeView.SelectedNode.Index
     386          : null;
     387
     388        TreeNode newNode = null;
     389        if (e.KeyCode == Keys.Down) {
     390          if (idx.HasValue && idx < typesTreeView.Nodes.Count - 1) {
     391            newNode = typesTreeView.Nodes[idx.Value + 1];
     392          } else if (typesTreeView.Nodes.Count > 0) {
     393            newNode = typesTreeView.Nodes[0];
     394          }
     395        } else if (e.KeyCode == Keys.Up && idx.HasValue && idx > 0) {
     396          newNode = typesTreeView.Nodes[idx.Value - 1];
     397        }
     398
     399        if (newNode != null)
     400          typesTreeView.SelectedNode = newNode;
     401        e.Handled = true;
     402      }
     403    }
     404
     405    private class ItemTreeNodeComparer : IComparer {
     406      public int Compare(object x, object y) {
     407        var lhs = (TreeNode)x;
     408        var rhs = (TreeNode)y;
     409
     410        if (lhs.Tag is string && rhs.Tag is string) {
     411          return lhs.Name.CompareTo(rhs.Name);
     412        } else if (lhs.Tag is string) {
     413          return -1;
     414        } else
     415          return 1;
     416      }
     417    }
    315418  }
    316419}
Note: See TracChangeset for help on using the changeset viewer.