Merge pull request #5421 from larsbrubaker/main

main
This commit is contained in:
Lars Brubaker 2023-03-28 09:44:39 -07:00 committed by GitHub
commit c7ab93fb81
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 632 additions and 458 deletions

View file

@ -36,7 +36,7 @@ namespace MatterHackers.MatterControl.DesignTools
{
public class PPEContext
{
public IObject3D item { get; set; }
public object item { get; set; }
public Dictionary<string, GuiWidget> editRows { get; private set; } = new Dictionary<string, GuiWidget>();
public GuiWidget GetEditRow(string propertyName)

View file

@ -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
{

View file

@ -56,16 +56,16 @@ namespace MatterHackers.MatterControl
{
this.libraryConfig = libraryConfig;
objectEditorsByType = new Dictionary<Type, HashSet<IObject3DEditor>>();
objectEditorsByType = new Dictionary<Type, HashSet<IObjectEditor>>();
}
private void MapTypesToEditor(IObject3DEditor editor)
private void MapTypesToEditor(IObjectEditor editor)
{
foreach (Type type in editor.SupportedTypes())
{
if (!objectEditorsByType.TryGetValue(type, out HashSet<IObject3DEditor> mappedEditors))
if (!objectEditorsByType.TryGetValue(type, out HashSet<IObjectEditor> mappedEditors))
{
mappedEditors = new HashSet<IObject3DEditor>();
mappedEditors = new HashSet<IObjectEditor>();
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<Type, HashSet<IObject3DEditor>> objectEditorsByType;
private Dictionary<Type, HashSet<IObjectEditor>> objectEditorsByType;
public HashSet<IObject3DEditor> GetEditorsForType(Type selectedItemType)
public HashSet<IObjectEditor> GetEditorsForType(Type selectedItemType)
{
HashSet<IObject3DEditor> mappedEditors;
HashSet<IObjectEditor> mappedEditors;
objectEditorsByType.TryGetValue(selectedItemType, out mappedEditors);
if (mappedEditors == null)

View file

@ -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;

View file

@ -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<Object3DView> transparentMeshes, DrawEventArgs e);
}
}
}

View file

@ -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);
/// <returns>The worldspace AABB of any 3D editing geometry drawn by DrawEditor.</returns>
AxisAlignedBoundingBox GetEditorWorldspaceAABB(Object3DControlsLayer layer);
}
public interface IEditorDrawControled : IEditorDraw
{
bool DoEditorDraw(bool isSelected);
}
public interface ICustomEditorDraw : IEditorDrawControled
{
void AddEditorTransparents(Object3DControlsLayer object3DControlLayer, List<Object3DView> transparentMeshes, DrawEventArgs e);
}
}

View file

@ -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);
}
}

View file

@ -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<SystemWindow>().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();
}
}
}

View file

@ -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;

View file

@ -172,7 +172,8 @@ namespace MatterHackers.MatterControl.DesignTools
for (int i=0; i<SurfacedEditors.Count; i++)
{
var (cellId, cellData) = this.DecodeContent(i);
if (cellData.StartsWith("="))
if (cellData != null
&& cellData.StartsWith("="))
{
var expression = new DoubleOrExpression(cellData);
var controledSheet = ControledSheet;

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;
@ -55,7 +54,7 @@ using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.DesignTools
{
public class PublicPropertyEditor : IObject3DEditor
public class PublicPropertyEditor : IObjectEditor
{
public string Name => "Property Editor";
@ -81,7 +80,7 @@ namespace MatterHackers.MatterControl.DesignTools
private SafeList<SettingsRow> rows = new SafeList<SettingsRow>();
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<EditableProperty> GetEditablePropreties(IObject3D item)
public static IEnumerable<EditableProperty> 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<InternalTextEditWidget>().First().Name = property.DisplayName + " Edit";
field.Content.Closed += (s, e) => object3D.Invalidated -= RefreshField;
field.Content.Descendants<InternalTextEditWidget>().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<MaxDecimalPlacesAttribute>().FirstOrDefault() is MaxDecimalPlacesAttribute decimalPlaces)
if (property.PropertyInfo.GetCustomAttributes(true).OfType<MaxDecimalPlacesAttribute>().FirstOrDefault() is MaxDecimalPlacesAttribute decimalPlaces)
{
field.Content.Descendants<InternalNumberEdit>().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<string> 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<MultiLineEditAttribute>().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)
{

View file

@ -228,14 +228,15 @@ namespace MatterHackers.MatterControl.DesignTools
private static void SetValue(EditableProperty property, PPEContext context, Func<string, object> 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));
}
}
}

View file

@ -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;
}
}
}

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,45 +226,13 @@ namespace MatterHackers.MatterControl.Library.Widgets
this.PrinterNameError.Visible = true;
}
protected override bool FilterTree(TreeNode context, string filter, bool parentVisible, List<TreeNode> 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));
}
});

View file

@ -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<TreeNode>();
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<TreeNode>())
{
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<TreeNode>();
searchBox.ResetButton.Visible = true;
}
Console.WriteLine("Filter for: " + filter);
private void ClearSearch()
{
foreach (var rootNode in contentPanel.Children.OfType<TreeNode>())
{
ResetTree(rootNode);
}
foreach (var rootNode in contentPanel.Children.OfType<TreeNode>())
{
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<TreeNode> matches);
private void ClearSearch()
{
foreach (var rootNode in contentPanel.Children.OfType<TreeNode>())
{
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<TreeNode> 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);
}
}
}
}

View file

@ -250,7 +250,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
editorSectionWidget.Text = selectedItem.Name ?? selectedItemType.Name;
HashSet<IObject3DEditor> mappedEditors = ApplicationController.Instance.Extensions.GetEditorsForType(selectedItemType);
HashSet<IObjectEditor> 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;

View file

@ -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<Type> IObject3DEditor.SupportedTypes() => new[] { typeof(SheetObject3D) };
IEnumerable<Type> 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)
{

View file

@ -35,10 +35,10 @@ using System.Collections.Generic;
namespace MatterHackers.MatterControl.PartPreviewWindow
{
public interface IObject3DEditor
public interface IObjectEditor
{
string Name { get; }
IEnumerable<Type> SupportedTypes();
GuiWidget Create(IObject3D item, UndoBuffer undoBuffer, ThemeConfig theme);
GuiWidget Create(object item, UndoBuffer undoBuffer, ThemeConfig theme);
}
}

View file

@ -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)
{

View file

@ -82,45 +82,12 @@ namespace MatterHackers.MatterControl
base.PerformSearch(filter);
}
protected override bool FilterTree(TreeNode context, string filter, bool parentVisible, List<TreeNode> 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<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

@ -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;

View file

@ -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

@ -1 +1 @@
Subproject commit 69cf72c0b7d04a9e630ee5abbea020b0a0fca7bb
Subproject commit 04f575a31a6d6d90b6c99aca7470292668a4b8fe