diff --git a/ApplicationView/PrinterModels.cs b/ApplicationView/PrinterModels.cs index 46e619f65..4500473e6 100644 --- a/ApplicationView/PrinterModels.cs +++ b/ApplicationView/PrinterModels.cs @@ -660,6 +660,42 @@ namespace MatterHackers.MatterControl } } } + + public double SceneTreeHeight + { + get + { + if (double.TryParse(UserSettings.Instance.get(UserSettingsKey.SceneTreeHeight), out double controlHeight)) + { + return Math.Max(controlHeight, 35); + } + + return 35; + } + set + { + var minimumValue = Math.Max(value, 35); + UserSettings.Instance.set(UserSettingsKey.SceneTreeHeight, minimumValue.ToString()); + } + } + + public double SelectedObjectEditorHeight + { + get + { + if (double.TryParse(UserSettings.Instance.get(UserSettingsKey.SelectedObjectEditorHeight), out double controlHeight)) + { + return Math.Max(controlHeight, 35); + } + + return 120; + } + set + { + var minimumValue = Math.Max(value, 35); + UserSettings.Instance.set(UserSettingsKey.SelectedObjectEditorHeight, minimumValue.ToString()); + } + } } public class PrinterViewState @@ -768,42 +804,6 @@ namespace MatterHackers.MatterControl UserSettings.Instance.set(UserSettingsKey.SelectedObjectPanelWidth, minimumValue.ToString()); } } - - public double SceneTreeHeight - { - get - { - if (double.TryParse(UserSettings.Instance.get(UserSettingsKey.SceneTreeHeight), out double controlHeight)) - { - return Math.Max(controlHeight, 35); - } - - return 35; - } - set - { - var minimumValue = Math.Max(value, 35); - UserSettings.Instance.set(UserSettingsKey.SceneTreeHeight, minimumValue.ToString()); - } - } - - public double SelectedObjectEditorHeight - { - get - { - if (double.TryParse(UserSettings.Instance.get(UserSettingsKey.SelectedObjectEditorHeight), out double controlHeight)) - { - return Math.Max(controlHeight, 35); - } - - return 120; - } - set - { - var minimumValue = Math.Max(value, 35); - UserSettings.Instance.set(UserSettingsKey.SelectedObjectEditorHeight, minimumValue.ToString()); - } - } } public class PrinterConfig diff --git a/CustomWidgets/TreeView/TreeNode.cs b/CustomWidgets/TreeView/TreeNode.cs index d0acfd609..46ff08106 100644 --- a/CustomWidgets/TreeView/TreeNode.cs +++ b/CustomWidgets/TreeView/TreeNode.cs @@ -90,10 +90,18 @@ namespace MatterHackers.MatterControl.CustomWidgets.TreeView this.TitleBar.AddChild(expandCheckBox); + this.SelectionBar = new FlowLayoutWidget() + { + VAnchor = VAnchor.Fit, + HAnchor = HAnchor.Fit, + Selectable = false + }; + this.TitleBar.AddChild(this.SelectionBar); + // add a check box if (Image != null) { - this.TitleBar.AddChild(imageWidget = new ImageWidget(this.Image) + this.SelectionBar.AddChild(imageWidget = new ImageWidget(this.Image) { VAnchor = VAnchor.Center, BackgroundColor = new Color(theme.Colors.PrimaryTextColor, 12), @@ -101,7 +109,9 @@ namespace MatterHackers.MatterControl.CustomWidgets.TreeView Selectable = false }); }; - this.TitleBar.AddChild(textWidget = new TextWidget(this.Text, pointSize: theme.DefaultFontSize, textColor: theme.Colors.PrimaryTextColor) + + + this.SelectionBar.AddChild(textWidget = new TextWidget(this.Text, pointSize: theme.DefaultFontSize, textColor: theme.Colors.PrimaryTextColor) { Selectable = false, AutoExpandBoundsToText = true, @@ -113,7 +123,7 @@ namespace MatterHackers.MatterControl.CustomWidgets.TreeView HAnchor = HAnchor.Fit | HAnchor.Left, Visible = false, // content starts out not visible Name = "content", - Margin = new BorderDouble(25, 3), + Margin = new BorderDouble(12, 3), }; AddChild(content); @@ -122,6 +132,8 @@ namespace MatterHackers.MatterControl.CustomWidgets.TreeView public FlowLayoutWidget TitleBar { get; } + public FlowLayoutWidget SelectionBar { get; } + public void BeginEdit() { throw new NotImplementedException(); @@ -378,7 +390,14 @@ namespace MatterHackers.MatterControl.CustomWidgets.TreeView // A TreeView that represents the parent tree view that the // tree node is assigned to, or null if the node has not been assigned to a tree // view. - public virtual TreeView TreeView => NodeParent.TreeView; + + private TreeView _treeView; + + public virtual TreeView TreeView + { + get => _treeView ?? NodeParent.TreeView; + set => _treeView = value; + } private void OnImageChanged(EventArgs args) { diff --git a/CustomWidgets/TreeView/TreeView.cs b/CustomWidgets/TreeView/TreeView.cs index 8c7e36526..858960094 100644 --- a/CustomWidgets/TreeView/TreeView.cs +++ b/CustomWidgets/TreeView/TreeView.cs @@ -29,40 +29,32 @@ either expressed or implied, of the FreeBSD Project. using System; using System.Collections; -using System.Linq; using MatterHackers.Agg; using MatterHackers.Agg.UI; using MatterHackers.VectorMath; namespace MatterHackers.MatterControl.CustomWidgets.TreeView { - public class TopNode : TreeNode + public interface IVisualLeafNode { - internal TreeView treeView; - public override TreeView TreeView => treeView; } public class TreeView : ScrollableWidget { private ThemeConfig theme; - public TreeView(TopNode topNode, ThemeConfig theme) - : this(topNode, 0, 0, theme) + public TreeView(ThemeConfig theme) + : this(0, 0, theme) { } - public TreeView(TopNode topNode, int width, int height, ThemeConfig theme) + public TreeView(int width, int height, ThemeConfig theme) : base(width, height) { this.theme = theme; this.AutoScroll = true; this.HAnchor = HAnchor.Stretch; this.VAnchor = VAnchor.Stretch; - this.TopNode = topNode; - - topNode.treeView = this; - - this.AddChild(TopNode); } #region Events @@ -207,19 +199,20 @@ namespace MatterHackers.MatterControl.CustomWidgets.TreeView public TreeNode SelectedNode { - get => _selectedNode; set + get => _selectedNode; + set { if (value != _selectedNode) { OnBeforeSelect(null); - foreach (var node in this.Descendants().Where((c) => c != value)) + if (_selectedNode != null) { - node.TitleBar.BackgroundColor = Color.Transparent; + _selectedNode.SelectionBar.BackgroundColor = Color.Transparent; } _selectedNode = value; - _selectedNode.TitleBar.BackgroundColor = theme.AccentMimimalOverlay; + _selectedNode.SelectionBar.BackgroundColor = theme.AccentMimimalOverlay; OnAfterSelect(null); } } @@ -230,7 +223,6 @@ namespace MatterHackers.MatterControl.CustomWidgets.TreeView public bool ShowPlusMinus { get; set; } public bool ShowRootLines { get; set; } public bool Sorted { get; set; } - public TreeNode TopNode { get; } public IComparer TreeViewNodeSorter { get; set; } diff --git a/DesignTools/Operations/Object3DExtensions.cs b/DesignTools/Operations/Object3DExtensions.cs index 2c5baaf33..47dcb0c5e 100644 --- a/DesignTools/Operations/Object3DExtensions.cs +++ b/DesignTools/Operations/Object3DExtensions.cs @@ -250,7 +250,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations return currentTransform; } - + public static Vector3 GetCenter(this IObject3D item) { return item.GetAxisAlignedBoundingBox(Matrix4X4.Identity).Center; diff --git a/DesignTools/Primitives/TextObject3D.cs b/DesignTools/Primitives/TextObject3D.cs index 385f5b706..cacaeb0dd 100644 --- a/DesignTools/Primitives/TextObject3D.cs +++ b/DesignTools/Primitives/TextObject3D.cs @@ -37,6 +37,7 @@ using MatterHackers.Agg.VertexSource; using MatterHackers.DataConverters3D; using MatterHackers.DataConverters3D.UndoCommands; using MatterHackers.Localizations; +using MatterHackers.MatterControl.CustomWidgets.TreeView; using MatterHackers.MatterControl.DesignTools.Operations; using MatterHackers.VectorMath; using Newtonsoft.Json; @@ -44,7 +45,7 @@ using Newtonsoft.Json.Converters; namespace MatterHackers.MatterControl.DesignTools { - public class TextObject3D : Object3D, IPublicPropertyObject + public class TextObject3D : Object3D, IPublicPropertyObject, IVisualLeafNode { public TextObject3D() { diff --git a/PartPreviewWindow/Object3DTreeBuilder.cs b/PartPreviewWindow/Object3DTreeBuilder.cs index 12d1ee034..717108dc6 100644 --- a/PartPreviewWindow/Object3DTreeBuilder.cs +++ b/PartPreviewWindow/Object3DTreeBuilder.cs @@ -31,52 +31,33 @@ using MatterHackers.Agg.UI; using MatterHackers.DataConverters3D; using MatterHackers.MatterControl.CustomWidgets; using MatterHackers.MatterControl.CustomWidgets.TreeView; +using MatterHackers.MatterControl.DesignTools; using MatterHackers.MatterControl.Library; +using MatterHackers.MatterControl.PartPreviewWindow.View3D; namespace MatterHackers.MatterControl.PartPreviewWindow { public static class Object3DTreeBuilder { - public static TreeView GetPartTreeView(IObject3D rootItem, ThemeConfig theme) + public static TreeNode BuildTree(IObject3D rootItem, ThemeConfig theme) { - var topNode = new TopNode() - { - Text = BuildDefaultName(rootItem), - Tag = rootItem, - TextColor = theme.Colors.PrimaryTextColor, - PointSize = theme.DefaultFontSize - }; - - var treeView = new TreeView(topNode, theme) - { - TextColor = theme.Colors.PrimaryTextColor, - PointSize = theme.DefaultFontSize - }; - - treeView.SuspendLayout(); - - //selectionTreeNodes.Clear(); - //selectionTreeNodes.Add(rootItem, topNode); - - // add the children to the root node - foreach (var child in rootItem.Children) - { - AddTree(child, topNode, theme); - } - - treeView.ResumeLayout(); - - return treeView; + return AddTree(rootItem, null, theme); } - private static void AddTree(IObject3D item, TreeNode parent, ThemeConfig theme) + private static TreeNode AddTree(IObject3D item, TreeNode parent, ThemeConfig theme) { - var node = AddItem(item, parent, theme); + // Suppress MeshWrapper nodes in treeview - retain parent node as context reference + var contextNode = (item is MeshWrapper) ? parent : AddItem(item, parent, theme); - foreach (var child in item.Children) + if (!(item is IVisualLeafNode)) { - AddTree(child, node, theme); + foreach (var child in item.Children) + { + AddTree(child, contextNode, theme); + } } + + return contextNode; } private static TreeNode AddItem(IObject3D item, TreeNode parentNode, ThemeConfig theme) @@ -108,12 +89,16 @@ namespace MatterHackers.MatterControl.PartPreviewWindow iconView.ImageSet += (s1, e1) => { node.Image = iconView.imageWidget.Image; + node.Invalidate(); }; }; } - parentNode.Nodes.Add(node); - parentNode.Expanded = true; + if (parentNode != null) + { + parentNode.Nodes.Add(node); + parentNode.Expanded = true; + } return node; } diff --git a/PartPreviewWindow/SelectedObjectPanel.cs b/PartPreviewWindow/SelectedObjectPanel.cs index 3b420e9d2..27a3b21d1 100644 --- a/PartPreviewWindow/SelectedObjectPanel.cs +++ b/PartPreviewWindow/SelectedObjectPanel.cs @@ -48,9 +48,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow private IObject3D item = new Object3D(); private ThemeConfig theme; + private BedConfig sceneContext; private View3DWidget view3DWidget; - private InteractiveScene scene; - private PrinterConfig printer; private SectionWidget editorSection; private TextButton editButton; @@ -58,7 +57,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow private InlineTitleEdit inlineTitleEdit; private BottomResizeContainer editorColumn; - public SelectedObjectPanel(View3DWidget view3DWidget, InteractiveScene scene, ThemeConfig theme, PrinterConfig printer) + public SelectedObjectPanel(View3DWidget view3DWidget, BedConfig sceneContext, ThemeConfig theme) : base(FlowDirection.TopToBottom) { this.HAnchor = HAnchor.Stretch; @@ -66,8 +65,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow this.Padding = 0; this.view3DWidget = view3DWidget; this.theme = theme; - this.scene = scene; - this.printer = printer; + this.sceneContext = sceneContext; this.ContentPanel = new FlowLayoutWidget(FlowDirection.TopToBottom) { @@ -91,7 +89,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Absolute, - Height = printer.ViewState.SelectedObjectEditorHeight + Height = sceneContext.ViewState.SelectedObjectEditorHeight }; var toolbar = new Toolbar(theme) @@ -102,6 +100,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow }; editorColumn.AddChild(toolbar); + var scene = sceneContext.Scene; + editButton = new TextButton("Edit".Localize(), theme) { BackgroundColor = theme.MinimalShade, @@ -252,11 +252,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow public void SetActiveItem(IObject3D selectedItem) { - if (!scene.HasSelection) - { - this.Parent.Visible = false; - return; - } var selectedItemType = selectedItem.GetType(); @@ -266,8 +261,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow this.item = selectedItem; - var viewMode = printer?.ViewState.ViewMode; - HashSet mappedEditors = ApplicationController.Instance.GetEditorsForType(selectedItemType); var activeEditors = new List<(IObject3DEditor, IObject3D, string)>(); @@ -358,7 +351,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow button.EnsureAvailablity(); button.Click += (s, e) => { - nodeOperation.Operation(selectedItem, scene).ConfigureAwait(false); + nodeOperation.Operation(selectedItem, sceneContext.Scene).ConfigureAwait(false); }; buttons.Add(button); @@ -410,7 +403,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow public override void OnClosed(ClosedEventArgs e) { - printer.ViewState.SelectedObjectEditorHeight = editorColumn.Height; + sceneContext.ViewState.SelectedObjectEditorHeight = editorColumn.Height; base.OnClosed(e); } } diff --git a/PartPreviewWindow/View3D/View3DWidget.cs b/PartPreviewWindow/View3D/View3DWidget.cs index 2bb6af5a3..6147a2983 100644 --- a/PartPreviewWindow/View3D/View3DWidget.cs +++ b/PartPreviewWindow/View3D/View3DWidget.cs @@ -149,7 +149,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow TrackballTumbleWidget.TransformState = TrackBallTransformType.Rotation; - selectedObjectPanel = new SelectedObjectPanel(this, Scene, theme, printer) + selectedObjectPanel = new SelectedObjectPanel(this, sceneContext, theme) { VAnchor = VAnchor.Stretch, }; @@ -187,12 +187,23 @@ namespace MatterHackers.MatterControl.PartPreviewWindow { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Absolute, - Height = Printer.ViewState.SceneTreeHeight + Height = sceneContext.ViewState.SceneTreeHeight }; modelViewSidePanel.AddChild(treeSection); // add the tree view - this.RebuildTreeSection(new Object3D(), theme); + treeView = new TreeView(theme) + { + TextColor = theme.Colors.PrimaryTextColor, + PointSize = theme.DefaultFontSize, + HAnchor =HAnchor.Stretch, + VAnchor = VAnchor.Stretch + }; + treeView.AfterSelect += (s, e) => + { + selectedObjectPanel.SetActiveItem((IObject3D)treeView.SelectedNode.Tag); + }; + treeSection.AddChild(treeView); modelViewSidePanel.AddChild(selectedObjectPanel); splitContainer.AddChild(modelViewSidePanel); @@ -236,24 +247,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow } } - private void RebuildTreeSection(IObject3D selection, ThemeConfig theme) - { - treeSection.CloseAllChildren(); - - treeView = Object3DTreeBuilder.GetPartTreeView(selection, theme); - treeSection.AddChild(treeView); - treeView.AfterSelect += (s, e) => - { - selectedObjectPanel.SetActiveItem((IObject3D)treeView.SelectedNode.Tag); - }; - - if (this.Parent != null) - { - treeView.TopNode.Padding = treeView.TopNode.Padding.Clone(left: 8, top: 8); - treeView.SelectedNode = treeView.TopNode; - } - } - private void UpdateRenderView(object sender, EventArgs e) { TrackballTumbleWidget.CenterOffsetX = -modelViewSidePanel.Width; @@ -365,10 +358,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow public override void OnClosed(ClosedEventArgs e) { - if (Printer != null) - { - Printer.ViewState.SceneTreeHeight = treeSection.Height; - } + sceneContext.ViewState.SceneTreeHeight = treeSection.Height; viewControls3D.TransformStateChanged -= ViewControls3D_TransformStateChanged; Scene.SelectionChanged -= Scene_SelectionChanged; @@ -689,11 +679,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow if (e == null) { Scene.ClearSelection(); - - foreach (var sceneItem in matchingSceneChildren.ToList()) - { - Scene.AddToSelection(sceneItem); - } + Scene.SetSelection(matchingSceneChildren.ToList()); } else { @@ -1225,9 +1211,20 @@ namespace MatterHackers.MatterControl.PartPreviewWindow } // Top level selection only - rebuild tree - if (Scene.Children.Contains(Scene.SelectedItem)) + var selection = Scene.SelectedItem; + if (Scene.Children.Contains(selection)) { - this.RebuildTreeSection(Scene.SelectedItem, theme); + treeView.ScrollArea.CloseAllChildren(); + + var rootNode = Object3DTreeBuilder.BuildTree(selection, theme); + treeView.AddChild(rootNode); + rootNode.TreeView = treeView; + + if (this.Parent != null) + { + rootNode.Padding = rootNode.Padding.Clone(left: 8, top: 8); + treeView.SelectedNode = rootNode; + } } } diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index a38d5e68b..44c6128a0 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit a38d5e68bcaace904d1dc18e416ea9ace6756ac2 +Subproject commit 44c6128a05217f6ca0a928e7061e087c05173d08