diff --git a/MatterControl.MeshOperations/IPropertyGridModifier.cs b/MatterControl.MeshOperations/IPropertyGridModifier.cs index 7fcbf470b..a74cccc92 100644 --- a/MatterControl.MeshOperations/IPropertyGridModifier.cs +++ b/MatterControl.MeshOperations/IPropertyGridModifier.cs @@ -36,7 +36,7 @@ namespace MatterHackers.MatterControl.DesignTools { public class PPEContext { - public IObject3D item { get; set; } + public object item { get; set; } public Dictionary editRows { get; private set; } = new Dictionary(); public GuiWidget GetEditRow(string propertyName) diff --git a/MatterControlLib/ApplicationView/ApplicationController.cs b/MatterControlLib/ApplicationView/ApplicationController.cs index 36608645d..fb744aeba 100644 --- a/MatterControlLib/ApplicationView/ApplicationController.cs +++ b/MatterControlLib/ApplicationView/ApplicationController.cs @@ -1544,12 +1544,7 @@ namespace MatterHackers.MatterControl this.IsReloading = true; var theme = ApplicationController.Instance.Theme; - SingleWindowProvider.SetWindowTheme(theme.TextColor, - theme.DefaultFontSize - 1, - () => theme.CreateSmallResetButton(), - theme.ToolbarPadding, - theme.TabBarBackground, - new Color(theme.PrimaryAccentColor, 175)); + SingleWindowProvider.SetWindowTheme(theme); reloadingOverlay = new GuiWidget { diff --git a/MatterControlLib/ApplicationView/Config/ExtensionsConfig.cs b/MatterControlLib/ApplicationView/Config/ExtensionsConfig.cs index 20da326cb..e32f24468 100644 --- a/MatterControlLib/ApplicationView/Config/ExtensionsConfig.cs +++ b/MatterControlLib/ApplicationView/Config/ExtensionsConfig.cs @@ -56,16 +56,16 @@ namespace MatterHackers.MatterControl { this.libraryConfig = libraryConfig; - objectEditorsByType = new Dictionary>(); + objectEditorsByType = new Dictionary>(); } - private void MapTypesToEditor(IObject3DEditor editor) + private void MapTypesToEditor(IObjectEditor editor) { foreach (Type type in editor.SupportedTypes()) { - if (!objectEditorsByType.TryGetValue(type, out HashSet mappedEditors)) + if (!objectEditorsByType.TryGetValue(type, out HashSet mappedEditors)) { - mappedEditors = new HashSet(); + mappedEditors = new HashSet(); objectEditorsByType.Add(type, mappedEditors); } @@ -73,16 +73,16 @@ namespace MatterHackers.MatterControl } } - public void Register(IObject3DEditor object3DEditor) + public void Register(IObjectEditor object3DEditor) { this.MapTypesToEditor(object3DEditor); } - private Dictionary> objectEditorsByType; + private Dictionary> objectEditorsByType; - public HashSet GetEditorsForType(Type selectedItemType) + public HashSet GetEditorsForType(Type selectedItemType) { - HashSet mappedEditors; + HashSet mappedEditors; objectEditorsByType.TryGetValue(selectedItemType, out mappedEditors); if (mappedEditors == null) diff --git a/MatterControlLib/ApplicationView/Themes/ThemeConfigExtensions.cs b/MatterControlLib/ApplicationView/Themes/ThemeConfigExtensions.cs index 7b752b273..a39e0a4b0 100644 --- a/MatterControlLib/ApplicationView/Themes/ThemeConfigExtensions.cs +++ b/MatterControlLib/ApplicationView/Themes/ThemeConfigExtensions.cs @@ -272,15 +272,6 @@ namespace MatterHackers.MatterControl }; } - public static GuiWidget CreateSmallResetButton(this ThemeConfig theme) - { - return new HoverImageWidget(theme.RestoreNormal, theme.RestoreHover) - { - VAnchor = VAnchor.Center, - Margin = new BorderDouble(0, 0, 5, 0) - }; - } - public static PopupMenuButton CreateSplitButton(this ThemeConfig theme, SplitButtonParams buttonParams, OperationGroup operationGroup = null) { PopupMenuButton menuButton = null; diff --git a/MatterControlLib/CustomWidgets/HoverImageWidget.cs b/MatterControlLib/DesignTools/Interfaces/ICustomEditorDraw.cs similarity index 64% rename from MatterControlLib/CustomWidgets/HoverImageWidget.cs rename to MatterControlLib/DesignTools/Interfaces/ICustomEditorDraw.cs index c9380ee6b..89350be7f 100644 --- a/MatterControlLib/CustomWidgets/HoverImageWidget.cs +++ b/MatterControlLib/DesignTools/Interfaces/ICustomEditorDraw.cs @@ -1,5 +1,5 @@ /* -Copyright (c) 2018, John Lewin +Copyright (c) 2018, Lars Brubaker, John Lewin All rights reserved. Redistribution and use in source and binary forms, with or without @@ -27,41 +27,14 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ -using MatterHackers.Agg.Image; +using System.Collections.Generic; using MatterHackers.Agg.UI; +using MatterHackers.MatterControl.PartPreviewWindow; -namespace MatterHackers.MatterControl +namespace MatterHackers.MatterControl.DesignTools { - public class HoverImageWidget : ImageWidget + public interface ICustomEditorDraw : IEditorDrawControled { - private ImageBuffer hoverImage; - - private bool mouseInBounds = false; - - public HoverImageWidget(ImageBuffer normalImage, ImageBuffer hoverImage) - : base(normalImage, listenForImageChanged: false) - { - this.hoverImage = hoverImage; - } - - public override ImageBuffer Image - { - get => mouseInBounds ? hoverImage : base.Image; - set => base.Image = value; - } - - public override void OnMouseEnterBounds(MouseEventArgs mouseEvent) - { - mouseInBounds = true; - base.OnMouseEnterBounds(mouseEvent); - this.Invalidate(); - } - - public override void OnMouseLeaveBounds(MouseEventArgs mouseEvent) - { - mouseInBounds = false; - base.OnMouseLeaveBounds(mouseEvent); - this.Invalidate(); - } + void AddEditorTransparents(Object3DControlsLayer object3DControlLayer, List transparentMeshes, DrawEventArgs e); } -} +} \ No newline at end of file diff --git a/MatterControlLib/DesignTools/Interfaces/IEditorDraw.cs b/MatterControlLib/DesignTools/Interfaces/IEditorDraw.cs index 85d6f6e8f..e52772882 100644 --- a/MatterControlLib/DesignTools/Interfaces/IEditorDraw.cs +++ b/MatterControlLib/DesignTools/Interfaces/IEditorDraw.cs @@ -1,5 +1,5 @@ /* -Copyright (c) 2018, Lars Brubaker, John Lewin +Copyright (c) 2023, Lars Brubaker, John Lewin All rights reserved. Redistribution and use in source and binary forms, with or without @@ -27,28 +27,17 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ -using System.Collections.Generic; using MatterHackers.Agg.UI; using MatterHackers.MatterControl.PartPreviewWindow; using MatterHackers.VectorMath; namespace MatterHackers.MatterControl.DesignTools { - public interface IEditorDraw + public interface IEditorDraw { void DrawEditor(Object3DControlsLayer object3DControlLayer, DrawEventArgs e); /// The worldspace AABB of any 3D editing geometry drawn by DrawEditor. AxisAlignedBoundingBox GetEditorWorldspaceAABB(Object3DControlsLayer layer); } - - public interface IEditorDrawControled : IEditorDraw - { - bool DoEditorDraw(bool isSelected); - } - - public interface ICustomEditorDraw : IEditorDrawControled - { - void AddEditorTransparents(Object3DControlsLayer object3DControlLayer, List transparentMeshes, DrawEventArgs e); - } } \ No newline at end of file diff --git a/MatterControlLib/DesignTools/Interfaces/IEditorDrawControled.cs b/MatterControlLib/DesignTools/Interfaces/IEditorDrawControled.cs new file mode 100644 index 000000000..822dad989 --- /dev/null +++ b/MatterControlLib/DesignTools/Interfaces/IEditorDrawControled.cs @@ -0,0 +1,36 @@ +/* +Copyright (c) 2023, Lars Brubaker, John Lewin +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +namespace MatterHackers.MatterControl.DesignTools +{ + public interface IEditorDrawControled : IEditorDraw + { + bool DoEditorDraw(bool isSelected); + } +} \ No newline at end of file diff --git a/MatterControlLib/DesignTools/Interfaces/Object3DUiWindowManager.cs b/MatterControlLib/DesignTools/Interfaces/Object3DUiWindowManager.cs new file mode 100644 index 000000000..bfc88939c --- /dev/null +++ b/MatterControlLib/DesignTools/Interfaces/Object3DUiWindowManager.cs @@ -0,0 +1,120 @@ +/* +Copyright (c) 2018, Lars Brubaker, John Lewin +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +using MatterHackers.Agg; +using MatterHackers.Agg.UI; +using MatterHackers.DataConverters3D; +using MatterHackers.MatterControl.PartPreviewWindow; +using MatterHackers.VectorMath; +using System.Linq; + +namespace MatterHackers.MatterControl.DesignTools +{ + public class Object3DUiWindowManager + { + public WindowWidget WindowWidget { get; private set; } + private Object3DControlsLayer controlLayer; + private IObject3D item; + + public Object3DUiWindowManager() + { + } + + public bool CreateWidgetIfRequired(IObject3D item, Object3DControlsLayer controlLayer, string title) + { + if (WindowWidget == null + || WindowWidget.Parents().Count() == 0) + { + if (WindowWidget != null) + { + WindowWidget.Close(); + } + + this.controlLayer = controlLayer; + this.item = item; + var theme = ApplicationController.Instance.Theme; + WindowWidget = new WindowWidget(theme, new RectangleDouble(10, 10, 700, 650)) + { + BackgroundColor = theme.BackgroundColor.WithAlpha(200), + }; + + WindowWidget.AddTitleBar(title, null); + + controlLayer.GuiSurface.AddChild(WindowWidget); + controlLayer.GuiSurface.AfterDraw += GuiSurface_AfterDraw; + + return true; + } + + return false; + } + + private void GuiSurface_AfterDraw(object sender, DrawEventArgs e) + { + if (!controlLayer.Scene.Contains(item)) + { + WindowWidget.Close(); + if (sender is GuiWidget guiWidget) + { + guiWidget.AfterDraw -= GuiSurface_AfterDraw; + } + } + else + { + if (controlLayer.Scene.SelectedItem == item) + { + WindowWidget.Visible = true; + } + else + { + WindowWidget.Visible = false; + } + } + } + + + public void AddObject3DControls(Object3DControlsLayer object3DControlsLayer) + { + throw new System.NotImplementedException(); + } + + public void Close() + { + if (WindowWidget != null) + { + WindowWidget.Close(); + } + } + + public AxisAlignedBoundingBox GetEditorWorldspaceAABB(Object3DControlsLayer layer) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/MatterControlLib/DesignTools/OpenSCAD/OpenSCADBuilder.cs b/MatterControlLib/DesignTools/OpenSCAD/OpenSCADBuilder.cs index ee0e15dc8..0f1531213 100644 --- a/MatterControlLib/DesignTools/OpenSCAD/OpenSCADBuilder.cs +++ b/MatterControlLib/DesignTools/OpenSCAD/OpenSCADBuilder.cs @@ -47,7 +47,7 @@ using Newtonsoft.Json; namespace MatterHackers.MatterControl.Library { - public class OpenSCADBuilder : IObject3DEditor + public class OpenSCADBuilder : IObjectEditor { private OpenScadObject3D item; @@ -84,7 +84,7 @@ namespace MatterHackers.MatterControl.Library return dictionary; } - public GuiWidget Create(IObject3D object3D, UndoBuffer undoBuffer, ThemeConfig theme) + public GuiWidget Create(object object3D, UndoBuffer undoBuffer, ThemeConfig theme) { this.item = object3D as OpenScadObject3D; diff --git a/MatterControlLib/DesignTools/Primitives/ComponentObject3D.cs b/MatterControlLib/DesignTools/Primitives/ComponentObject3D.cs index 285a61ea0..bc77749f7 100644 --- a/MatterControlLib/DesignTools/Primitives/ComponentObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/ComponentObject3D.cs @@ -172,7 +172,8 @@ namespace MatterHackers.MatterControl.DesignTools for (int i=0; i "Property Editor"; @@ -81,7 +80,7 @@ namespace MatterHackers.MatterControl.DesignTools private SafeList rows = new SafeList(); - public GuiWidget Create(IObject3D item, UndoBuffer undoBuffer, ThemeConfig theme) + public GuiWidget Create(object item, UndoBuffer undoBuffer, ThemeConfig theme) { var mainContainer = new FlowLayoutWidget(FlowDirection.TopToBottom) { @@ -96,7 +95,10 @@ namespace MatterHackers.MatterControl.DesignTools }; // CreateEditor - AddUnlockLinkIfRequired(context.item, mainContainer, theme); + if (context.item is IObject3D itemAsIObject3D) + { + AddUnlockLinkIfRequired(itemAsIObject3D, mainContainer, theme); + } AddMarkDownDescription(context.item, mainContainer, theme); @@ -171,7 +173,10 @@ namespace MatterHackers.MatterControl.DesignTools }; updateButton.Click += (s, e) => { - context.item.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties)); + if (context.item is IObject3D itemAsIObject3D) + { + itemAsIObject3D.Invalidate(new InvalidateArgs(itemAsIObject3D, InvalidateType.Properties)); + } }; mainContainer.AddChild(updateButton); } @@ -186,7 +191,7 @@ namespace MatterHackers.MatterControl.DesignTools return mainContainer; } - private void AddFunctionButtons(IObject3D item, FlowLayoutWidget mainContainer, ThemeConfig theme) + private void AddFunctionButtons(object item, FlowLayoutWidget mainContainer, ThemeConfig theme) { if (item is IEditorButtonProvider editorButtonProvider) { @@ -279,7 +284,7 @@ namespace MatterHackers.MatterControl.DesignTools return column; } - public static IEnumerable GetEditablePropreties(IObject3D item) + public static IEnumerable GetEditablePropreties(object item) { return item.GetType().GetProperties(OwnedPropertiesOnly) .Where(pi => (AllowedTypes.Contains(pi.PropertyType) || pi.PropertyType.IsEnum) @@ -307,9 +312,10 @@ namespace MatterHackers.MatterControl.DesignTools return null; } - var localItem = context.item; - var object3D = property.Item; - var propertyGridModifier = property.Item as IPropertyGridModifier; + var contextItem = context.item; + var contextObject3D = contextItem as IObject3D; + var propertyObject3D = property.Item as IObject3D; + var propertyGridModifier = property.Item as IPropertyGridModifier; GuiWidget rowContainer = null; @@ -346,20 +352,20 @@ namespace MatterHackers.MatterControl.DesignTools undoBuffer.AddAndDo(new UndoRedoActions(() => { property.SetValue(valueFromString(oldValue)); - object3D?.Invalidate(new InvalidateArgs(localItem, InvalidateType.Properties)); + propertyObject3D?.Invalidate(new InvalidateArgs(contextObject3D, InvalidateType.Properties)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }, () => { property.SetValue(valueFromString(newValue)); - object3D?.Invalidate(new InvalidateArgs(localItem, InvalidateType.Properties)); + propertyObject3D?.Invalidate(new InvalidateArgs(contextObject3D, InvalidateType.Properties)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); })); } else { property.SetValue(valueFromString(newValue)); - object3D?.Invalidate(new InvalidateArgs(localItem, InvalidateType.Properties)); + propertyObject3D?.Invalidate(new InvalidateArgs(contextObject3D, InvalidateType.Properties)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); } }; @@ -391,8 +397,8 @@ namespace MatterHackers.MatterControl.DesignTools } } - object3D.Invalidated += RefreshField; - valueField.Closed += (s, e) => object3D.Invalidated -= RefreshField; + propertyObject3D.Invalidated += RefreshField; + valueField.Closed += (s, e) => propertyObject3D.Invalidated -= RefreshField; } else // normal edit row { @@ -414,11 +420,14 @@ namespace MatterHackers.MatterControl.DesignTools } } - object3D.Invalidated += RefreshField; - field.Content.Descendants().First().Name = property.DisplayName + " Edit"; - field.Content.Closed += (s, e) => object3D.Invalidated -= RefreshField; + field.Content.Descendants().First().Name = property.DisplayName + " Edit"; + if (propertyObject3D != null) + { + propertyObject3D.Invalidated += RefreshField; + field.Content.Closed += (s, e) => propertyObject3D.Invalidated -= RefreshField; + } - if (property.PropertyInfo.GetCustomAttributes(true).OfType().FirstOrDefault() is MaxDecimalPlacesAttribute decimalPlaces) + if (property.PropertyInfo.GetCustomAttributes(true).OfType().FirstOrDefault() is MaxDecimalPlacesAttribute decimalPlaces) { field.Content.Descendants().First().MaxDecimalsPlaces = decimalPlaces.Number; } @@ -430,12 +439,12 @@ namespace MatterHackers.MatterControl.DesignTools } else if (propertyValue is Color color) { - var field = new ColorField(theme, object3D.Color, null, false); + var field = new ColorField(theme, color, null, false); field.Initialize(0); field.ValueChanged += (s, e) => { property.SetValue(field.Color); - object3D?.Invalidate(new InvalidateArgs(localItem, InvalidateType.Properties)); + propertyObject3D?.Invalidate(new InvalidateArgs(contextObject3D, InvalidateType.Properties)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; @@ -509,7 +518,7 @@ namespace MatterHackers.MatterControl.DesignTools field.ValueChanged += (s, e) => { property.SetValue(field.DirectionVector); - object3D?.Invalidate(new InvalidateArgs(localItem, InvalidateType.Properties)); + propertyObject3D?.Invalidate(new InvalidateArgs(contextObject3D, InvalidateType.Properties)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; @@ -560,7 +569,7 @@ namespace MatterHackers.MatterControl.DesignTools Normal = field1.DirectionVector.Normal, Origin = property.Item.Children.First().GetAxisAlignedBoundingBox().Center + field2.Vector3 }); - object3D?.Invalidate(new InvalidateArgs(localItem, InvalidateType.Properties)); + propertyObject3D?.Invalidate(new InvalidateArgs(contextObject3D, InvalidateType.Properties)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; field2.ValueChanged += (s, e) => @@ -570,7 +579,7 @@ namespace MatterHackers.MatterControl.DesignTools Normal = field1.DirectionVector.Normal, Origin = property.Item.Children.First().GetAxisAlignedBoundingBox().Center + field2.Vector3 }); - object3D?.Invalidate(new InvalidateArgs(localItem, InvalidateType.Properties)); + propertyObject3D?.Invalidate(new InvalidateArgs(contextObject3D, InvalidateType.Properties)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; @@ -618,13 +627,13 @@ namespace MatterHackers.MatterControl.DesignTools if (property.Item is OperationSourceContainerObject3D sourceContainer) { Action selected = null; - var showUpdate = localItem.GetType().GetCustomAttributes(typeof(ShowUpdateButtonAttribute), true).FirstOrDefault() as ShowUpdateButtonAttribute; + var showUpdate = contextItem.GetType().GetCustomAttributes(typeof(ShowUpdateButtonAttribute), true).FirstOrDefault() as ShowUpdateButtonAttribute; if (showUpdate == null || !showUpdate.SuppressPropertyChangeUpdates) { selected = () => { - object3D?.Invalidate(new InvalidateArgs(localItem, InvalidateType.Properties)); + propertyObject3D?.Invalidate(new InvalidateArgs(contextObject3D, InvalidateType.Properties)); }; } @@ -666,7 +675,7 @@ namespace MatterHackers.MatterControl.DesignTools ImageBuffer GetImageCheckingForErrors() { var image = imageBuffer; - if (object3D is ImageObject3D imageObject2) + if (propertyObject3D is ImageObject3D imageObject2) { image = imageObject2.Image; } @@ -705,10 +714,10 @@ namespace MatterHackers.MatterControl.DesignTools } } - object3D.Invalidated += RefreshField; - imageWidget.Closed += (s, e) => object3D.Invalidated -= RefreshField; + propertyObject3D.Invalidated += RefreshField; + imageWidget.Closed += (s, e) => propertyObject3D.Invalidated -= RefreshField; - if (object3D is IEditorWidgetModifier editorWidgetModifier) + if (propertyObject3D is IEditorWidgetModifier editorWidgetModifier) { editorWidgetModifier.ModifyEditorWidget(imageWidget, theme, UpdateEditorImage); } @@ -724,15 +733,15 @@ namespace MatterHackers.MatterControl.DesignTools { if (e.InvalidateType.HasFlag(InvalidateType.DisplayValues)) { - if (object3D is IImageProvider imageProvider) + if (propertyObject3D is IImageProvider imageProvider) { var _ = imageProvider.Image; } } } - object3D.Invalidated += RefreshField; - rowContainer.Closed += (s, e) => object3D.Invalidated -= RefreshField; + propertyObject3D.Invalidated += RefreshField; + rowContainer.Closed += (s, e) => propertyObject3D.Invalidated -= RefreshField; } else if (propertyValue is List stringList) { @@ -789,8 +798,8 @@ namespace MatterHackers.MatterControl.DesignTools } } - object3D.Invalidated += RefreshField; - valueField.Closed += (s, e) => object3D.Invalidated -= RefreshField; + propertyObject3D.Invalidated += RefreshField; + valueField.Closed += (s, e) => propertyObject3D.Invalidated -= RefreshField; } else // normal edit row { @@ -813,8 +822,11 @@ namespace MatterHackers.MatterControl.DesignTools } } - object3D.Invalidated += RefreshField; - field.Content.Closed += (s, e) => object3D.Invalidated -= RefreshField; + if (propertyObject3D != null) + { + propertyObject3D.Invalidated += RefreshField; + field.Content.Closed += (s, e) => propertyObject3D.Invalidated -= RefreshField; + } rowContainer = CreateSettingsRow(property, field.Content, theme); } @@ -851,7 +863,7 @@ namespace MatterHackers.MatterControl.DesignTools format = "0." + new string('#', Math.Min(10, decimalPlaces.Number)); } - field.SetValue(doubleExpresion.Value(object3D).ToString(format), false); + field.SetValue(doubleExpresion.Value(propertyObject3D).ToString(format), false); } field.ClearUndoHistory(); @@ -896,15 +908,15 @@ namespace MatterHackers.MatterControl.DesignTools format = "0." + new string('#', Math.Min(10, decimalPlaces.Number)); } - var rawValue = newValue.Value(object3D); + var rawValue = newValue.Value(propertyObject3D); field.TextValue = rawValue.ToString(format); } } } } - object3D.Invalidated += RefreshField; - field.Content.Closed += (s, e) => object3D.Invalidated -= RefreshField; + propertyObject3D.Invalidated += RefreshField; + field.Content.Closed += (s, e) => propertyObject3D.Invalidated -= RefreshField; } else if (propertyValue is IntOrExpression intExpresion) { @@ -926,7 +938,7 @@ namespace MatterHackers.MatterControl.DesignTools format = "0." + new string('#', Math.Min(10, decimalPlaces.Number)); } - field.SetValue(intExpresion.Value(object3D).ToString(format), false); + field.SetValue(intExpresion.Value(propertyObject3D).ToString(format), false); } field.ClearUndoHistory(); @@ -971,15 +983,15 @@ namespace MatterHackers.MatterControl.DesignTools format = "0." + new string('#', Math.Min(10, decimalPlaces.Number)); } - var rawValue = newValue.Value(object3D); + var rawValue = newValue.Value(propertyObject3D); field.TextValue = rawValue.ToString(format); } } } } - object3D.Invalidated += RefreshField; - field.Content.Closed += (s, e) => object3D.Invalidated -= RefreshField; + propertyObject3D.Invalidated += RefreshField; + field.Content.Closed += (s, e) => propertyObject3D.Invalidated -= RefreshField; } else if (propertyValue is string stringValue) { @@ -987,7 +999,7 @@ namespace MatterHackers.MatterControl.DesignTools { rowContainer = NewImageSearchWidget(theme); } - else if (object3D is AssetObject3D assetObject + else if (propertyObject3D is AssetObject3D assetObject && property.PropertyInfo.Name == "AssetPath") { // This is the AssetPath property of an asset object, add a button to set the AssetPath from a file @@ -1065,9 +1077,12 @@ namespace MatterHackers.MatterControl.DesignTools } } - object3D.Invalidated += RefreshField; - wrappedTextWidget.Closed += (s, e) => object3D.Invalidated -= RefreshField; - } + if (propertyObject3D != null) + { + propertyObject3D.Invalidated += RefreshField; + wrappedTextWidget.Closed += (s, e) => propertyObject3D.Invalidated -= RefreshField; + } + } else // normal edit row { if (property.PropertyInfo.GetCustomAttributes(true).OfType().FirstOrDefault() != null) @@ -1181,7 +1196,7 @@ namespace MatterHackers.MatterControl.DesignTools field.ValueChanged += (s, e) => { property.SetValue(Convert.ToChar(field.Value)); - object3D?.Invalidate(new InvalidateArgs(localItem, InvalidateType.Properties)); + propertyObject3D?.Invalidate(new InvalidateArgs(contextObject3D, InvalidateType.Properties)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; @@ -1229,7 +1244,7 @@ namespace MatterHackers.MatterControl.DesignTools if (property.Value.ToString() != field.Value) { property.SetValue(Enum.Parse(property.PropertyType, field.Value)); - object3D?.Invalidate(new InvalidateArgs(localItem, InvalidateType.Properties)); + propertyObject3D?.Invalidate(new InvalidateArgs(contextObject3D, InvalidateType.Properties)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); } }; @@ -1261,15 +1276,15 @@ namespace MatterHackers.MatterControl.DesignTools } } - if (object3D != null) + if (propertyObject3D != null) { - object3D.Invalidated += RefreshField; - field.Content.Closed += (s, e) => object3D.Invalidated -= RefreshField; + propertyObject3D.Invalidated += RefreshField; + field.Content.Closed += (s, e) => propertyObject3D.Invalidated -= RefreshField; } } else if (propertyValue is IObject3D item - && ApplicationController.Instance.Extensions.GetEditorsForType(property.PropertyType)?.FirstOrDefault() is IObject3DEditor iObject3DEditor) + && ApplicationController.Instance.Extensions.GetEditorsForType(property.PropertyType)?.FirstOrDefault() is IObjectEditor iObject3DEditor) { // Use known IObject3D editors rowContainer = iObject3DEditor.Create(item, undoBuffer, theme); @@ -1523,7 +1538,7 @@ namespace MatterHackers.MatterControl.DesignTools } } - public static void AddMarkDownDescription(IObject3D item, GuiWidget editControlsContainer, ThemeConfig theme) + public static void AddMarkDownDescription(object item, GuiWidget editControlsContainer, ThemeConfig theme) { if (item.GetType().GetCustomAttributes(typeof(MarkDownDescriptionAttribute), true).FirstOrDefault() is MarkDownDescriptionAttribute markdownDescription) { @@ -1554,7 +1569,7 @@ namespace MatterHackers.MatterControl.DesignTools return new SettingsRow("Demo Mode".Localize(), null, detailsLink, theme); } - public static void AddWebPageLinkIfRequired(IObject3D item, FlowLayoutWidget editControlsContainer, ThemeConfig theme) + public static void AddWebPageLinkIfRequired(object item, FlowLayoutWidget editControlsContainer, ThemeConfig theme) { if (item.GetType().GetCustomAttributes(typeof(WebPageLinkAttribute), true).FirstOrDefault() is WebPageLinkAttribute unlockLink) { diff --git a/MatterControlLib/DesignTools/PublicPropertySliderFunctions.cs b/MatterControlLib/DesignTools/PublicPropertySliderFunctions.cs index dedeb746c..10d0df00b 100644 --- a/MatterControlLib/DesignTools/PublicPropertySliderFunctions.cs +++ b/MatterControlLib/DesignTools/PublicPropertySliderFunctions.cs @@ -228,14 +228,15 @@ namespace MatterHackers.MatterControl.DesignTools private static void SetValue(EditableProperty property, PPEContext context, Func valueFromString, double sliderDownValue) { var localItem = context.item; - var object3D = property.Item; + var localObject3D = localItem as Object3D; + var object3D = property.Item; var propertyGridModifier = property.Item as IPropertyGridModifier; property.SetValue(valueFromString(sliderDownValue.ToString())); - object3D?.Invalidate(new InvalidateArgs(localItem, InvalidateType.Properties)); + object3D?.Invalidate(new InvalidateArgs(localObject3D, InvalidateType.Properties)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); - object3D?.Invalidate(new InvalidateArgs(localItem, InvalidateType.DisplayValues)); + object3D?.Invalidate(new InvalidateArgs(localObject3D, InvalidateType.DisplayValues)); } } } \ No newline at end of file diff --git a/MatterControlLib/Library/OpenInto/ExportStlToExecutable.cs b/MatterControlLib/Library/OpenInto/ExportStlToExecutable.cs index 16d732e2c..e33b71c4a 100644 --- a/MatterControlLib/Library/OpenInto/ExportStlToExecutable.cs +++ b/MatterControlLib/Library/OpenInto/ExportStlToExecutable.cs @@ -27,7 +27,6 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ -using Lucene.Net.Support; using MatterHackers.Agg.Platform; using MatterHackers.Agg.UI; using MatterHackers.DataConverters3D; @@ -42,14 +41,37 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; -using System.Threading; using System.Threading.Tasks; namespace MatterControlLib.Library.OpenInto { public abstract class OpenIntoExecutable { - private string pathToExe; + private string _pathToExe; + private string PathToExe + { + get + { + if (string.IsNullOrEmpty(_pathToExe)) + { + // get data from the registry for: Computer\HKEY_CLASSES_ROOT\ Bambu.Studio.1\Shell\Open\Command + RegistryKey key = Registry.ClassesRoot.OpenSubKey(regExKeyName); + + if (key != null) + { + _pathToExe = key.GetValue("").ToString(); + + var regex = "C:.+.exe"; + var match = System.Text.RegularExpressions.Regex.Match(_pathToExe, regex); + _pathToExe = match.Value; + + key.Close(); + } + } + + return _pathToExe; + } + } public int Priority => 2; @@ -119,22 +141,7 @@ namespace MatterControlLib.Library.OpenInto { get { - // get data from the registry for: Computer\HKEY_CLASSES_ROOT\ Bambu.Studio.1\Shell\Open\Command - RegistryKey key = Registry.ClassesRoot.OpenSubKey(regExKeyName); - - if (key != null) - { - pathToExe = key.GetValue("").ToString(); - - var regex = "C:.+.exe"; - var match = System.Text.RegularExpressions.Regex.Match(pathToExe, regex); - pathToExe = match.Value; - - key.Close(); - return true; - } - - return false; + return !string.IsNullOrEmpty(PathToExe); } } @@ -155,12 +162,7 @@ namespace MatterControlLib.Library.OpenInto if (bedExports.Count == 0) { - // open the file with the specified exe - ProcessStartInfo startInfo = new ProcessStartInfo(); - startInfo.FileName = $"\"{pathToExe}\""; - startInfo.Arguments = $"\"{exportFilename}\""; - - Process.Start(startInfo); + ExportToExe(exportFilename); return null; } @@ -174,5 +176,22 @@ namespace MatterControlLib.Library.OpenInto } }; } + + public bool ExportToExe(string exportFilename) + { + if (File.Exists(exportFilename) + && !string.IsNullOrEmpty(PathToExe)) + { + // open the file with the specified exe + ProcessStartInfo startInfo = new ProcessStartInfo(); + startInfo.FileName = $"\"{PathToExe}\""; + startInfo.Arguments = $"\"{exportFilename}\""; + + Process.Start(startInfo); + return true; + } + + return false; + } } } \ No newline at end of file diff --git a/MatterControlLib/Library/Widgets/AddMaterialWidget.cs b/MatterControlLib/Library/Widgets/AddMaterialWidget.cs index 6397f35ce..daecccfda 100644 --- a/MatterControlLib/Library/Widgets/AddMaterialWidget.cs +++ b/MatterControlLib/Library/Widgets/AddMaterialWidget.cs @@ -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 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); } }); } diff --git a/MatterControlLib/Library/Widgets/AddPrinterWidget.cs b/MatterControlLib/Library/Widgets/AddPrinterWidget.cs index 7970690ef..ef6de2f2e 100644 --- a/MatterControlLib/Library/Widgets/AddPrinterWidget.cs +++ b/MatterControlLib/Library/Widgets/AddPrinterWidget.cs @@ -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,45 +226,13 @@ namespace MatterHackers.MatterControl.Library.Widgets this.PrinterNameError.Visible = true; } - protected override bool FilterTree(TreeNode context, string filter, bool parentVisible, List matches) - { - // 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; - } - - 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; - } + 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; + return itemText.IndexOf(filter, StringComparison.OrdinalIgnoreCase) != -1; + } private void ClearError() { @@ -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)); } }); diff --git a/MatterControlLib/Library/Widgets/SearchableTreePanel.cs b/MatterControlLib/Library/Widgets/SearchableTreePanel.cs index d6be44ef8..afd2864f5 100644 --- a/MatterControlLib/Library/Widgets/SearchableTreePanel.cs +++ b/MatterControlLib/Library/Widgets/SearchableTreePanel.cs @@ -27,177 +27,213 @@ 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; + public abstract class SearchableTreePanel : FlowLayoutWidget + { + protected FlowLayoutWidget contentPanel; + protected Splitter horizontalSplitter; + protected TextEditWithInlineCancel searchBox; + protected ThemeConfig theme; - public SearchableTreePanel(ThemeConfig theme) - : base(FlowDirection.TopToBottom) - { - this.theme = theme; - this.TreeLoaded = false; + public SearchableTreePanel(ThemeConfig theme) + : base(FlowDirection.TopToBottom) + { + this.theme = theme; + this.TreeLoaded = false; - var searchIcon = StaticData.Instance.LoadIcon("icon_search_24x24.png", 16, 16).SetToColor(theme.TextColor).AjustAlpha(0.3); + var searchIcon = StaticData.Instance.LoadIcon("icon_search_24x24.png", 16, 16).SetToColor(theme.TextColor).AjustAlpha(0.3); - searchBox = new TextEditWithInlineCancel(theme) - { - Name = "Search", - HAnchor = HAnchor.Stretch, - Margin = new BorderDouble(6), - }; + searchBox = new TextEditWithInlineCancel(theme) + { + Name = "Search", + HAnchor = HAnchor.Stretch, + Margin = new BorderDouble(6), + }; - searchBox.ResetButton.Visible = false; + searchBox.ResetButton.Visible = false; - var searchInput = searchBox.TextEditWidget; + var searchInput = searchBox.TextEditWidget; - searchInput.BeforeDraw += (s, e) => - { - if (!searchBox.ResetButton.Visible) - { - e.Graphics2D.Render( - searchIcon, - searchInput.Width - searchIcon.Width - 5, - searchInput.LocalBounds.Bottom + searchInput.Height / 2 - searchIcon.Height / 2); - } - }; + searchInput.BeforeDraw += (s, e) => + { + if (!searchBox.ResetButton.Visible) + { + e.Graphics2D.Render( + searchIcon, + searchInput.Width - searchIcon.Width - 5, + searchInput.LocalBounds.Bottom + searchInput.Height / 2 - searchIcon.Height / 2); + } + }; - searchBox.ResetButton.Click += (s, e) => - { - this.ClearSearch(); - }; + searchBox.ResetButton.Click += (s, e) => + { + this.ClearSearch(); + }; - searchBox.KeyDown += (s, e) => - { - if (e.KeyCode == Keys.Escape) - { - this.ClearSearch(); - e.Handled = true; - } - }; + searchBox.KeyDown += (s, e) => + { + if (e.KeyCode == Keys.Escape) + { + this.ClearSearch(); + e.Handled = true; + } + }; - searchBox.TextEditWidget.ActualTextEditWidget.TextChanged += (s, e) => - { - if (string.IsNullOrWhiteSpace(searchBox.Text)) - { - this.ClearSearch(); - } - else - { - this.PerformSearch(searchBox.Text); - } - }; + searchBox.TextEditWidget.ActualTextEditWidget.TextChanged += (s, e) => + { + if (string.IsNullOrWhiteSpace(searchBox.Text)) + { + this.ClearSearch(); + } + else + { + this.PerformSearch(searchBox.Text); + } + }; - horizontalSplitter = new Splitter() - { - SplitterDistance = Math.Max(UserSettings.Instance.LibraryViewWidth, 20), - SplitterSize = theme.SplitterWidth, - SplitterBackground = theme.SplitterBackground - }; - horizontalSplitter.AnchorAll(); + horizontalSplitter = new Splitter() + { + SplitterDistance = Math.Max(UserSettings.Instance.LibraryViewWidth, 20), + SplitterSize = theme.SplitterWidth, + SplitterBackground = theme.SplitterBackground + }; + horizontalSplitter.AnchorAll(); - horizontalSplitter.DistanceChanged += (s, e) => - { - UserSettings.Instance.LibraryViewWidth = Math.Max(horizontalSplitter.SplitterDistance, 20); - }; + horizontalSplitter.DistanceChanged += (s, e) => + { + UserSettings.Instance.LibraryViewWidth = Math.Max(horizontalSplitter.SplitterDistance, 20); + }; - this.AddChild(horizontalSplitter); + this.AddChild(horizontalSplitter); - var leftPanel = new FlowLayoutWidget(FlowDirection.TopToBottom) - { - HAnchor = HAnchor.Stretch, - VAnchor = VAnchor.Stretch - }; + var leftPanel = new FlowLayoutWidget(FlowDirection.TopToBottom) + { + HAnchor = HAnchor.Stretch, + VAnchor = VAnchor.Stretch + }; - leftPanel.AddChild(searchBox); + leftPanel.AddChild(searchBox); - treeView = new TreeView(theme) - { - HAnchor = HAnchor.Stretch, - VAnchor = VAnchor.Stretch, - }; - leftPanel.AddChild(treeView); + TreeView = new TreeView(theme) + { + HAnchor = HAnchor.Stretch, + VAnchor = VAnchor.Stretch, + }; + leftPanel.AddChild(TreeView); - horizontalSplitter.Panel1.AddChild(leftPanel); + horizontalSplitter.Panel1.AddChild(leftPanel); - contentPanel = new FlowLayoutWidget(FlowDirection.TopToBottom) - { - HAnchor = HAnchor.Fit, - VAnchor = VAnchor.Fit, - Margin = new BorderDouble(left: 2) - }; - treeView.AddChild(contentPanel); - } + contentPanel = new FlowLayoutWidget(FlowDirection.TopToBottom) + { + HAnchor = HAnchor.Fit, + VAnchor = VAnchor.Fit, + Margin = new BorderDouble(left: 2) + }; + TreeView.AddChild(contentPanel); + } - protected virtual void PerformSearch(string filter) - { - var matches = new List(); + public bool TreeLoaded { get; protected set; } + + public TreeView TreeView { get; set; } - Console.WriteLine("Filter for: " + filter); + protected abstract bool NodeMatchesFilter(TreeNode context, string filter); - foreach (var rootNode in contentPanel.Children.OfType()) - { - FilterTree(rootNode, filter, false, matches); - } + protected virtual void OnClearSearch() + { + } - if (matches.Count == 1) - { - treeView.SelectedNode = matches.First(); - } - else - { - treeView.SelectedNode = null; - } + protected virtual void PerformSearch(string filter) + { + var matches = new List(); - searchBox.ResetButton.Visible = true; - } + Console.WriteLine("Filter for: " + filter); - private void ClearSearch() - { - foreach (var rootNode in contentPanel.Children.OfType()) - { - ResetTree(rootNode); - } + foreach (var rootNode in contentPanel.Children.OfType()) + { + FilterTree(rootNode, filter, false, matches); + } - searchBox.Text = ""; - searchBox.ResetButton.Visible = false; - treeView.SelectedNode = null; + if (matches.Count == 1) + { + TreeView.SelectedNode = matches.First(); + } + else + { + TreeView.SelectedNode = null; + } - this.OnClearSearch(); - } + searchBox.ResetButton.Visible = true; + } - protected abstract bool FilterTree(TreeNode context, string filter, bool parentVisible, List matches); + private void ClearSearch() + { + foreach (var rootNode in contentPanel.Children.OfType()) + { + ResetTree(rootNode); + } - private void ResetTree(TreeNode context) - { - context.Visible = true; - context.Expanded = false; + searchBox.Text = ""; + searchBox.ResetButton.Visible = false; + TreeView.SelectedNode = null; - foreach (var child in context.Nodes) - { - ResetTree(child); - } - } + this.OnClearSearch(); + } - protected virtual void OnClearSearch() - { - } + private bool FilterTree(TreeNode context, string filter, bool parentVisible, List matches) + { + var hasFilterText = NodeMatchesFilter(context, filter); - public bool TreeLoaded { get; protected set; } - } -} + 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) + { + context.Visible = true; + context.Expanded = false; + + foreach (var child in context.Nodes) + { + ResetTree(child); + } + } + } +} \ No newline at end of file diff --git a/MatterControlLib/PartPreviewWindow/SelectedObjectPanel.cs b/MatterControlLib/PartPreviewWindow/SelectedObjectPanel.cs index 6d2d21f5d..03db513a9 100644 --- a/MatterControlLib/PartPreviewWindow/SelectedObjectPanel.cs +++ b/MatterControlLib/PartPreviewWindow/SelectedObjectPanel.cs @@ -250,7 +250,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow editorSectionWidget.Text = selectedItem.Name ?? selectedItemType.Name; - HashSet mappedEditors = ApplicationController.Instance.Extensions.GetEditorsForType(selectedItemType); + HashSet mappedEditors = ApplicationController.Instance.Extensions.GetEditorsForType(selectedItemType); var undoBuffer = sceneContext.Scene.UndoBuffer; @@ -310,7 +310,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow else { if (item != null - && ApplicationController.Instance.Extensions.GetEditorsForType(item.GetType())?.FirstOrDefault() is IObject3DEditor editor) + && ApplicationController.Instance.Extensions.GetEditorsForType(item.GetType())?.FirstOrDefault() is IObjectEditor editor) { ShowObjectEditor((editor, item, item.Name), selectedItem); } @@ -559,7 +559,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow { if (instance is IObject3D object3D) { - if (ApplicationController.Instance.Extensions.GetEditorsForType(object3D.GetType())?.FirstOrDefault() is IObject3DEditor editor) + if (ApplicationController.Instance.Extensions.GetEditorsForType(object3D.GetType())?.FirstOrDefault() is IObjectEditor editor) { ShowObjectEditor((editor, object3D, object3D.Name), selectedItem); } @@ -668,7 +668,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow } } - private void ShowObjectEditor((IObject3DEditor editor, IObject3D item, string displayName) scopeItem, IObject3D rootSelection) + private void ShowObjectEditor((IObjectEditor editor, IObject3D item, string displayName) scopeItem, IObject3D rootSelection) { var selectedItem = scopeItem.item; diff --git a/MatterControlLib/PartPreviewWindow/View3D/Actions/SheetEditor.cs b/MatterControlLib/PartPreviewWindow/View3D/Actions/SheetEditor.cs index 9f82c59c9..343bdd8c3 100644 --- a/MatterControlLib/PartPreviewWindow/View3D/Actions/SheetEditor.cs +++ b/MatterControlLib/PartPreviewWindow/View3D/Actions/SheetEditor.cs @@ -237,13 +237,13 @@ namespace MatterHackers.MatterControl.DesignTools } } - public class SheetEditor : IObject3DEditor + public class SheetEditor : IObjectEditor { - string IObject3DEditor.Name => "Sheet Editor"; + string IObjectEditor.Name => "Sheet Editor"; - IEnumerable IObject3DEditor.SupportedTypes() => new[] { typeof(SheetObject3D) }; + IEnumerable IObjectEditor.SupportedTypes() => new[] { typeof(SheetObject3D) }; - public GuiWidget Create(IObject3D item, UndoBuffer undoBuffer, ThemeConfig theme) + public GuiWidget Create(object item, UndoBuffer undoBuffer, ThemeConfig theme) { if (item is SheetObject3D sheetObject) { diff --git a/MatterControlLib/PartPreviewWindow/View3D/IObject3DEditor.cs b/MatterControlLib/PartPreviewWindow/View3D/IObject3DEditor.cs index f65968557..cfd7ba308 100644 --- a/MatterControlLib/PartPreviewWindow/View3D/IObject3DEditor.cs +++ b/MatterControlLib/PartPreviewWindow/View3D/IObject3DEditor.cs @@ -35,10 +35,10 @@ using System.Collections.Generic; namespace MatterHackers.MatterControl.PartPreviewWindow { - public interface IObject3DEditor + public interface IObjectEditor { string Name { get; } IEnumerable SupportedTypes(); - GuiWidget Create(IObject3D item, UndoBuffer undoBuffer, ThemeConfig theme); + GuiWidget Create(object item, UndoBuffer undoBuffer, ThemeConfig theme); } } \ No newline at end of file diff --git a/MatterControlLib/PartSheet/PartsSheetCreator.cs b/MatterControlLib/PartSheet/PartsSheetCreator.cs index 8c549c1e6..3ddffd059 100644 --- a/MatterControlLib/PartSheet/PartsSheetCreator.cs +++ b/MatterControlLib/PartSheet/PartsSheetCreator.cs @@ -115,6 +115,11 @@ namespace MatterHackers.MatterControl var object3D = await item.CreateContent(); + if (object3D == null) + { + continue; + } + var loadedMeshGroups = object3D.VisibleMeshes().ToList(); if (loadedMeshGroups?.Count > 0) { diff --git a/MatterControlLib/SetupWizard/HelpTreePanel.cs b/MatterControlLib/SetupWizard/HelpTreePanel.cs index 91db50c6c..c3b72a051 100644 --- a/MatterControlLib/SetupWizard/HelpTreePanel.cs +++ b/MatterControlLib/SetupWizard/HelpTreePanel.cs @@ -82,45 +82,12 @@ namespace MatterHackers.MatterControl base.PerformSearch(filter); } - protected override bool FilterTree(TreeNode context, string filter, bool parentVisible, List matches) - { - // Filter against make/model for printers or make for top level nodes - string path = (context as HelpArticleTreeNode)?.HelpArticle.Path; + protected override bool NodeMatchesFilter(TreeNode context, string filter) + { + 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()) + foreach (var ancestor in TreeView.SelectedNode.Parents()) { 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; } } } diff --git a/Program.cs b/Program.cs index 2b073bc24..b288a5840 100644 --- a/Program.cs +++ b/Program.cs @@ -300,12 +300,7 @@ namespace MatterHackers.MatterControl var rootSystemWindow = Application.LoadRootWindow(width, height); var theme = ApplicationController.Instance.Theme; - SingleWindowProvider.SetWindowTheme(theme.TextColor, - theme.DefaultFontSize - 1, - () => theme.CreateSmallResetButton(), - theme.ToolbarPadding, - theme.TabBarBackground, - new Color(theme.PrimaryAccentColor, 175)); + SingleWindowProvider.SetWindowTheme(theme); ApplicationController.Instance.KeepAwake = KeepAwake; diff --git a/StaticData/Translations/Master.txt b/StaticData/Translations/Master.txt index b53fcae65..672fb1e77 100644 --- a/StaticData/Translations/Master.txt +++ b/StaticData/Translations/Master.txt @@ -415,12 +415,18 @@ Translated:Are you sure you want to sign out? You will not have access to your p English:Arrange All Parts Translated:Arrange All Parts +English:Arranging +Translated:Arranging + English:As the time to print a layer decreases to this, the fan speed will be increased up to its maximum speed. Translated:As the time to print a layer decreases to this, the fan speed will be increased up to its maximum speed. English:Ascending Translated:Ascending +English:Assets Folder +Translated:Assets Folder + English:At least 1 part must be selected Translated:At least 1 part must be selected @@ -505,6 +511,9 @@ Translated:Bad English:Bad Thermistor Translated:Bad Thermistor +English:Bambu Studio +Translated:Bambu Studio + English:Base Translated:Base @@ -535,6 +544,9 @@ Translated:Be sure you are not pressing down on the bed while moving the paper. English:Bed Translated:Bed +English:Bed Depth +Translated:Bed Depth + English:Bed Dislodged Translated:Bed Dislodged @@ -580,6 +592,9 @@ Translated:Bed Temperature Set to 0 English:Bed Temperature: Translated:Bed Temperature: +English:Bed Width +Translated:Bed Width + English:Bed Wipe Temperature Translated:Bed Wipe Temperature @@ -646,6 +661,9 @@ Translated:Bottom Solid Infill English:Bottom Solid Layers Translated:Bottom Solid Layers +English:Bottom Top Layers +Translated:Bottom Top Layers + English:Bowden Tube Popped Out Translated:Bowden Tube Popped Out @@ -676,6 +694,9 @@ Translated:Brim Extruder English:Build Height Translated:Build Height +English:Build Plates +Translated:Build Plates + English:BuildTak Translated:BuildTak @@ -823,6 +844,9 @@ Translated:Clear Bed English:Clear Bed G-Code Translated:Clear Bed G-Code +English:Clear Bed When Done +Translated:Clear Bed When Done + English:Clear Cache Translated:Clear Cache @@ -901,6 +925,9 @@ Translated:Color 3 English:Color 4 Translated:Color 4 +English:Color Name +Translated:Color Name + English:Color View Translated:Color View @@ -1138,6 +1165,9 @@ Translated:Create Part Sheet English:Create Perimeter Translated:Create Perimeter +English:Create Plates +Translated:Create Plates + English:Create Printer Translated:Create Printer @@ -1156,6 +1186,9 @@ Translated:Create Support English:Create Supports Translated:Create Supports +English:Create the plates for all the selected STLs. +Translated:Create the plates for all the selected STLs. + English:Creates a brim attached to the base of the print. Useful to prevent warping when printing ABS (and other warping-prone plastics) as it helps parts adhere to the bed. Translated:Creates a brim attached to the base of the print. Useful to prevent warping when printing ABS (and other warping-prone plastics) as it helps parts adhere to the bed. @@ -1381,6 +1414,9 @@ Translated:Distance From Object English:Distance or Loops Translated:Distance or Loops +English:Do CSG +Translated:Do CSG + English:Documents Translated:Documents @@ -1498,6 +1534,9 @@ Translated:Emulate Endstops English:Enable Auto Cooling Translated:Enable Auto Cooling +English:Enable Editing +Translated:Enable Editing + English:Enable Extruder Lift Translated:Enable Extruder Lift @@ -2296,6 +2335,9 @@ Translated:Hotend Temperature English:Hotend Temperature: Translated:Hotend Temperature: +English:ID +Translated:ID + English:Ideal for cloning settings across different physical printers Translated:Ideal for cloning settings across different physical printers @@ -2380,6 +2422,9 @@ Translated:Infill Angle English:Infill Overlap Translated:Infill Overlap +English:Infill Percent +Translated:Infill Percent + English:Infill Speeds Translated:Infill Speeds @@ -2512,6 +2557,12 @@ Translated:Iterations English:Jerk Velocity Translated:Jerk Velocity +English:Job Manager +Translated:Job Manager + +English:Jobs Folder +Translated:Jobs Folder + English:Junction Deviation [mm/s] Translated:Junction Deviation [mm/s] @@ -2542,6 +2593,9 @@ Translated:Layer English:Layer Change G-Code Translated:Layer Change G-Code +English:Layer Height +Translated:Layer Height + English:Layer Shift Translated:Layer Shift @@ -2695,6 +2749,9 @@ Translated:Loading GCode English:Loading Help Translated:Loading Help +English:Loading Stls +Translated:Loading Stls + English:Local Library Translated:Local Library @@ -3205,6 +3262,9 @@ Translated:Note: Slice Settings are applied before the print actually starts. Ch English:NOTE: Standard messaging rates may apply. Translated:NOTE: Standard messaging rates may apply. +English:Notes +Translated:Notes + English:Notifications Translated:Notifications @@ -3376,6 +3436,9 @@ Translated:Open Recent English:Open Settings View Options Translated:Open Settings View Options +English:Open With +Translated:Open With + English:OpenSCAD not installed Translated:OpenSCAD not installed @@ -3421,6 +3484,9 @@ Translated:Outlines (default) English:Output Translated:Output +English:Output Folder +Translated:Output Folder + English:Output only the first layer of the print. Especially useful for outputting gcode data for applications like engraving or cutting. Translated:Output only the first layer of the print. Especially useful for outputting gcode data for applications like engraving or cutting. @@ -3463,6 +3529,9 @@ Translated:Part Cooling Fan English:Part Cooling Fan {i} Translated:Part Cooling Fan {i} +English:Part Plater +Translated:Part Plater + English:Part Settings Translated:Part Settings @@ -3475,6 +3544,9 @@ Translated:Part(s) to Subtract and Replace English:Parts Translated:Parts +English:Parts Folder +Translated:Parts Folder + English:Password Translated:Password @@ -3520,6 +3592,12 @@ Translated:PEI Bed Temperature English:Percentage of Translated:Percentage of +English:Performe a union before exporting. Might be slower but can clean up some models. +Translated:Performe a union before exporting. Might be slower but can clean up some models. + +English:Performe Union +Translated:Performe Union + English:Perimeter Acceleration Translated:Perimeter Acceleration @@ -3766,6 +3844,9 @@ Translated:Print History English:Print History Note Translated:Print History Note +English:Print Job Manager +Translated:Print Job Manager + English:Print Leveling Translated:Print Leveling @@ -4372,6 +4453,12 @@ Translated:Save changes ? English:Save Changes? Translated:Save Changes? +English:Save Each Separately +Translated:Save Each Separately + +English:Save every object as a separate STL using its name. The save filename will be used if no name can be found. +Translated:Save every object as a separate STL using its name. The save filename will be used if no name can be found. + English:Save file: Translated:Save file: @@ -4399,6 +4486,9 @@ Translated:Saving changes English:Saving Changes Translated:Saving Changes +English:Saving PDF +Translated:Saving PDF + English:SCAD Script Translated:SCAD Script @@ -4471,6 +4561,9 @@ Translated:Select an object to copy its color English:Select cell to edit Translated:Select cell to edit +English:Select Folder +Translated:Select Folder + English:Select Parts Translated:Select Parts @@ -4492,6 +4585,9 @@ Translated:Select this option only if your printer does not appear in the list English:Select What to Import Translated:Select What to Import +English:Selecte a directory +Translated:Selecte a directory + English:Selected Children Translated:Selected Children diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index 69cf72c0b..04f575a31 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit 69cf72c0b7d04a9e630ee5abbea020b0a0fca7bb +Subproject commit 04f575a31a6d6d90b6c99aca7470292668a4b8fe