refactoring treeview

This commit is contained in:
Lars Brubaker 2023-03-24 17:23:05 -07:00
parent dfefb936ef
commit ca2843e5be
7 changed files with 224 additions and 284 deletions

View file

@ -44,7 +44,6 @@ using MatterHackers.DataConverters3D;
using MatterHackers.ImageProcessing;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.CustomWidgets;
using MatterHackers.MatterControl.DataStorage;
using MatterHackers.MatterControl.DesignTools.EditableTypes;
using MatterHackers.MatterControl.DesignTools.Operations;
using MatterHackers.MatterControl.Library.Widgets;

View file

@ -66,14 +66,14 @@ namespace MatterHackers.MatterControl.Library.Widgets
horizontalSplitter.Panel2.Padding = theme.DefaultContainerPadding;
treeView.AfterSelect += this.TreeView_AfterSelect;
TreeView.AfterSelect += this.TreeView_AfterSelect;
treeView.NodeMouseDoubleClick += (s, e) =>
TreeView.NodeMouseDoubleClick += (s, e) =>
{
if (e is MouseEventArgs mouseEvent
&& mouseEvent.Button == MouseButtons.Left
&& mouseEvent.Clicks == 2
&& treeView?.SelectedNode is TreeNode treeNode)
&& TreeView?.SelectedNode is TreeNode treeNode)
{
nextButton.InvokeClick();
}
@ -85,7 +85,7 @@ namespace MatterHackers.MatterControl.Library.Widgets
{
var rootNode = this.CreateTreeNode(rootDirectory);
rootNode.Expandable = true;
rootNode.TreeView = treeView;
rootNode.TreeView = TreeView;
contentPanel.AddChild(rootNode);
}
@ -120,43 +120,10 @@ namespace MatterHackers.MatterControl.Library.Widgets
horizontalSplitter.Panel2.AddChild(panel2Column);
}
protected override bool FilterTree(TreeNode context, string filter, bool parentVisible, List<TreeNode> matches)
protected override bool NodeMatchesFilter(TreeNode context, string filter)
{
// Filter against make/model for printers or make for top level nodes
string itemText = context.Text;
bool hasFilterText = itemText.IndexOf(filter, StringComparison.OrdinalIgnoreCase) != -1;
context.Visible = hasFilterText || parentVisible;
if (context.Visible
&& context.NodeParent != null)
{
context.NodeParent.Visible = true;
context.NodeParent.Expanded = true;
context.Expanded = true;
}
if (context.NodeParent != null
&& hasFilterText)
{
matches.Add(context);
}
bool childMatched = false;
foreach (var child in context.Nodes)
{
childMatched |= FilterTree(child, filter, hasFilterText || parentVisible, matches);
}
bool hasMatch = childMatched || hasFilterText;
if (hasMatch)
{
context.Visible = context.Expanded = true;
}
return hasMatch;
// check if the node matches the filter
return context.Text.IndexOf(filter, StringComparison.OrdinalIgnoreCase) != -1;
}
private static void SetImage(TreeNode node, ImageBuffer image)
@ -216,15 +183,15 @@ namespace MatterHackers.MatterControl.Library.Widgets
private void TreeView_AfterSelect(object sender, TreeNode e)
{
if (treeView.SelectedNode?.Tag != null)
if (TreeView.SelectedNode?.Tag != null)
{
UiThread.RunOnIdle(() =>
{
if (treeView.SelectedNode != null)
if (TreeView.SelectedNode != null)
{
string printerName = treeView.SelectedNode.Tag.ToString();
string printerName = TreeView.SelectedNode.Tag.ToString();
this.SelectedMaterial = treeView.SelectedNode.Tag as MaterialInfo;
this.SelectedMaterial = TreeView.SelectedNode.Tag as MaterialInfo;
materialInfo.CloseChildren();
var printerDetails = new PrinterDetails(
@ -266,7 +233,7 @@ namespace MatterHackers.MatterControl.Library.Widgets
printerDetails.ProductDataContainer.AddChild(settingsBackground);
};
nextButtonEnabled(treeView.SelectedNode != null);
nextButtonEnabled(TreeView.SelectedNode != null);
}
});
}

View file

@ -59,14 +59,14 @@ namespace MatterHackers.MatterControl.Library.Widgets
horizontalSplitter.Panel2.Padding = theme.DefaultContainerPadding;
treeView.AfterSelect += this.TreeView_AfterSelect;
TreeView.AfterSelect += this.TreeView_AfterSelect;
treeView.NodeMouseDoubleClick += (s, e) =>
TreeView.NodeMouseDoubleClick += (s, e) =>
{
if (e is MouseEventArgs mouseEvent
&& mouseEvent.Button == MouseButtons.Left
&& mouseEvent.Clicks == 2
&& treeView?.SelectedNode is TreeNode treeNode)
&& TreeView?.SelectedNode is TreeNode treeNode)
{
nextButton.InvokeClick();
}
@ -84,7 +84,7 @@ namespace MatterHackers.MatterControl.Library.Widgets
var rootNode = this.CreateTreeNode(oem);
rootNode.Expandable = true;
rootNode.TreeView = treeView;
rootNode.TreeView = TreeView;
rootNode.Load += (s, e) =>
{
var image = OemSettings.Instance.GetIcon(oem.Key, theme);
@ -226,46 +226,14 @@ namespace MatterHackers.MatterControl.Library.Widgets
this.PrinterNameError.Visible = true;
}
protected override bool FilterTree(TreeNode context, string filter, bool parentVisible, List<TreeNode> matches)
protected override bool NodeMatchesFilter(TreeNode context, string filter)
{
// Filter against make/model for printers or make for top level nodes
string itemText = (context.Tag as MakeModelInfo)?.ToString() ?? context.Text;
bool hasFilterText = itemText.IndexOf(filter, StringComparison.OrdinalIgnoreCase) != -1;
context.Visible = hasFilterText || parentVisible;
if (context.Visible
&& context.NodeParent != null)
{
context.NodeParent.Visible = true;
context.NodeParent.Expanded = true;
context.Expanded = true;
return itemText.IndexOf(filter, StringComparison.OrdinalIgnoreCase) != -1;
}
if (context.NodeParent != null
&& hasFilterText)
{
matches.Add(context);
}
bool childMatched = false;
foreach (var child in context.Nodes)
{
childMatched |= FilterTree(child, filter, hasFilterText || parentVisible, matches);
}
bool hasMatch = childMatched || hasFilterText;
if (hasMatch)
{
context.Visible = context.Expanded = true;
}
return hasMatch;
}
private void ClearError()
{
this.PrinterNameError.Text = "";
@ -314,24 +282,24 @@ namespace MatterHackers.MatterControl.Library.Widgets
private void TreeView_AfterSelect(object sender, TreeNode e)
{
nameSection.Enabled = treeView.SelectedNode != null;
nameSection.Enabled = TreeView.SelectedNode != null;
this.ClearError();
this.PrinterNameError.Visible = false;
if (nameSection.Enabled
&& treeView.SelectedNode.Tag != null)
&& TreeView.SelectedNode.Tag != null)
{
UiThread.RunOnIdle(() =>
{
if (usingDefaultName
&& treeView.SelectedNode != null)
&& TreeView.SelectedNode != null)
{
string printerName = treeView.SelectedNode.Tag.ToString();
string printerName = TreeView.SelectedNode.Tag.ToString();
printerNameInput.Text = Util.GetNonCollidingName(printerName, this.ExistingPrinterNames);
this.SelectedPrinter = treeView.SelectedNode.Tag as MakeModelInfo;
this.SelectedPrinter = TreeView.SelectedNode.Tag as MakeModelInfo;
printerInfo.CloseChildren();
@ -356,7 +324,7 @@ namespace MatterHackers.MatterControl.Library.Widgets
});
}
nextButtonEnabled(treeView.SelectedNode != null
nextButtonEnabled(TreeView.SelectedNode != null
&& !string.IsNullOrWhiteSpace(printerNameInput.Text));
}
});

View file

@ -27,25 +27,22 @@ of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using MatterHackers.Agg;
using MatterHackers.Agg.Platform;
using MatterHackers.Agg.UI;
using MatterHackers.ImageProcessing;
using MatterHackers.MatterControl.CustomWidgets;
using System;
using System.Collections.Generic;
using System.Linq;
namespace MatterHackers.MatterControl.Library.Widgets
{
public abstract class SearchableTreePanel : FlowLayoutWidget
{
protected TextEditWithInlineCancel searchBox;
protected TreeView treeView;
protected Splitter horizontalSplitter;
protected ThemeConfig theme;
protected FlowLayoutWidget contentPanel;
protected Splitter horizontalSplitter;
protected TextEditWithInlineCancel searchBox;
protected ThemeConfig theme;
public SearchableTreePanel(ThemeConfig theme)
: base(FlowDirection.TopToBottom)
@ -126,12 +123,12 @@ namespace MatterHackers.MatterControl.Library.Widgets
leftPanel.AddChild(searchBox);
treeView = new TreeView(theme)
TreeView = new TreeView(theme)
{
HAnchor = HAnchor.Stretch,
VAnchor = VAnchor.Stretch,
};
leftPanel.AddChild(treeView);
leftPanel.AddChild(TreeView);
horizontalSplitter.Panel1.AddChild(leftPanel);
@ -141,7 +138,17 @@ namespace MatterHackers.MatterControl.Library.Widgets
VAnchor = VAnchor.Fit,
Margin = new BorderDouble(left: 2)
};
treeView.AddChild(contentPanel);
TreeView.AddChild(contentPanel);
}
public bool TreeLoaded { get; protected set; }
public TreeView TreeView { get; set; }
protected abstract bool NodeMatchesFilter(TreeNode context, string filter);
protected virtual void OnClearSearch()
{
}
protected virtual void PerformSearch(string filter)
@ -157,11 +164,11 @@ namespace MatterHackers.MatterControl.Library.Widgets
if (matches.Count == 1)
{
treeView.SelectedNode = matches.First();
TreeView.SelectedNode = matches.First();
}
else
{
treeView.SelectedNode = null;
TreeView.SelectedNode = null;
}
searchBox.ResetButton.Visible = true;
@ -176,12 +183,47 @@ namespace MatterHackers.MatterControl.Library.Widgets
searchBox.Text = "";
searchBox.ResetButton.Visible = false;
treeView.SelectedNode = null;
TreeView.SelectedNode = null;
this.OnClearSearch();
}
protected abstract bool FilterTree(TreeNode context, string filter, bool parentVisible, List<TreeNode> matches);
private bool FilterTree(TreeNode context, string filter, bool parentVisible, List<TreeNode> matches)
{
var hasFilterText = NodeMatchesFilter(context, filter);
context.Visible = hasFilterText || parentVisible;
if (context.Visible
&& context.NodeParent != null)
{
context.NodeParent.Visible = true;
context.NodeParent.Expanded = true;
context.Expanded = true;
}
if (context.NodeParent != null
&& hasFilterText)
{
matches.Add(context);
}
bool childMatched = false;
foreach (var child in context.Nodes)
{
childMatched |= FilterTree(child, filter, hasFilterText || parentVisible, matches);
}
bool hasMatch = childMatched || hasFilterText;
if (hasMatch)
{
context.Visible = context.Expanded = true;
}
return hasMatch;
}
private void ResetTree(TreeNode context)
{
@ -193,11 +235,5 @@ namespace MatterHackers.MatterControl.Library.Widgets
ResetTree(child);
}
}
protected virtual void OnClearSearch()
{
}
public bool TreeLoaded { get; protected set; }
}
}

View file

@ -82,44 +82,11 @@ namespace MatterHackers.MatterControl
base.PerformSearch(filter);
}
protected override bool FilterTree(TreeNode context, string filter, bool parentVisible, List<TreeNode> matches)
protected override bool NodeMatchesFilter(TreeNode context, string filter)
{
// Filter against make/model for printers or make for top level nodes
string path = (context as HelpArticleTreeNode)?.HelpArticle.Path;
bool isSearchMatch = searchHits.Contains(path);
context.Visible = isSearchMatch || parentVisible;
if (context.Visible
&& context.NodeParent != null)
{
context.NodeParent.Visible = true;
context.NodeParent.Expanded = true;
context.Expanded = true;
}
if (context.NodeParent != null
&& isSearchMatch)
{
matches.Add(context);
}
bool childMatched = false;
foreach (var child in context.Nodes)
{
childMatched |= FilterTree(child, filter, isSearchMatch || parentVisible, matches);
}
bool hasMatch = childMatched || isSearchMatch;
if (hasMatch)
{
context.Visible = context.Expanded = true;
}
return hasMatch;
return searchHits.Contains(path);
}
protected override void OnClearSearch()
@ -268,7 +235,7 @@ namespace MatterHackers.MatterControl
Padding = new BorderDouble(left: theme.DefaultContainerPadding / 2)
};
treeView.AfterSelect += (s, e) =>
TreeView.AfterSelect += (s, e) =>
{
// Hide all sibling content controls
foreach (var child in horizontalSplitter.Panel2.Children)
@ -276,7 +243,7 @@ namespace MatterHackers.MatterControl
child.Visible = false;
}
if (treeView.SelectedNode?.Tag is HelpArticle article)
if (TreeView.SelectedNode?.Tag is HelpArticle article)
{
markdownWidget.MatchingText = this.MatchingText;
@ -296,34 +263,34 @@ namespace MatterHackers.MatterControl
// Show Markdown help page
markdownWidget.Visible = true;
}
else if (treeView.SelectedNode?.Tag is GuiWidget widget)
else if (TreeView.SelectedNode?.Tag is GuiWidget widget)
{
// Show non-markdown page
widget.Visible = true;
}
};
treeView.Load += (s, e) =>
TreeView.Load += (s, e) =>
{
rootNode.Expanded = true;
if (treeView.SelectedNode == null)
if (TreeView.SelectedNode == null)
{
if (string.IsNullOrEmpty(guideKey))
{
treeView.SelectedNode = rootNode.Nodes.FirstOrDefault();
TreeView.SelectedNode = rootNode.Nodes.FirstOrDefault();
}
else
{
if (initialSelection != null)
{
treeView.SelectedNode = initialSelection;
TreeView.SelectedNode = initialSelection;
}
// TODO: Implement or revise .Expanded
if (treeView.SelectedNode != null)
if (TreeView.SelectedNode != null)
{
foreach (var ancestor in treeView.SelectedNode.Parents<TreeNode>())
foreach (var ancestor in TreeView.SelectedNode.Parents<TreeNode>())
{
ancestor.Expanded = true;
}
@ -331,9 +298,9 @@ namespace MatterHackers.MatterControl
}
}
if (treeView.SelectedNode == null)
if (TreeView.SelectedNode == null)
{
treeView.SelectedNode = rootNode;
TreeView.SelectedNode = rootNode;
}
};
@ -348,7 +315,7 @@ namespace MatterHackers.MatterControl
rootNode = ProcessTree(ApplicationController.Instance.HelpArticles);
rootNode.Text = "Help";
rootNode.TreeView = treeView;
rootNode.TreeView = TreeView;
contentPanel.AddChild(rootNode);
@ -402,12 +369,12 @@ namespace MatterHackers.MatterControl
public string ActiveNodePath
{
get => treeView.SelectedNode?.Tag as string;
get => TreeView.SelectedNode?.Tag as string;
set
{
if (nodesByPath.TryGetValue(value, out HelpArticleTreeNode treeNode))
{
treeView.SelectedNode = treeNode;
TreeView.SelectedNode = treeNode;
}
}
}

View file

@ -691,6 +691,9 @@ Translated:Brim Extruder
English:Build Height
Translated:Build Height
English:Build Plates
Translated:Build Plates
English:BuildTak
Translated:BuildTak

@ -1 +1 @@
Subproject commit 0c10c4ad5d84538d71022c0342fe9cfba263da20
Subproject commit 0152308cca0c9768f6cd4c2efddc0a1376026828