commit
42b9dcf101
14 changed files with 248 additions and 29 deletions
|
|
@ -322,8 +322,6 @@ namespace MatterHackers.MatterControl
|
|||
"$.Children<BaseObject3D>.Children<LinearExtrudeObject3D>.Children<SmoothPathObject3D>.Children<ImageToPathObject3D_2>.AnalysisType",
|
||||
"$.Children<BaseObject3D>.Children<LinearExtrudeObject3D>.Children<SmoothPathObject3D>.Children<ImageToPathObject3D_2>.TransparencyMessage",
|
||||
"$.Children<BaseObject3D>.Children<LinearExtrudeObject3D>.Children<SmoothPathObject3D>.Children<ImageToPathObject3D_2>.Histogram",
|
||||
"$.Children<BaseObject3D>.Children<LinearExtrudeObject3D>.Height",
|
||||
"$.Children<BaseObject3D>.Children<LinearExtrudeObject3D>.Children<SmoothPathObject3D>.SmoothDistance",
|
||||
"$.Children<BaseObject3D>",
|
||||
}
|
||||
};
|
||||
|
|
|
|||
48
MatterControlLib/DesignTools/Attributes/SliderAttribute.cs
Normal file
48
MatterControlLib/DesignTools/Attributes/SliderAttribute.cs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
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 System;
|
||||
|
||||
namespace MatterHackers.MatterControl.DesignTools
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class SliderAttribute : Attribute
|
||||
{
|
||||
public SliderAttribute(double min, double max, double increment)
|
||||
{
|
||||
this.Min = min;
|
||||
this.Max = max;
|
||||
this.Incement = increment;
|
||||
}
|
||||
|
||||
public double Min { get; set; }
|
||||
public double Max { get; set; }
|
||||
public double Incement { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -57,7 +57,7 @@ namespace MatterHackers.MatterControl.Plugins.Lithophane
|
|||
[DisplayName("Pixels Per mm"), Range(0.5, 3, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
|
||||
public double PixelsPerMM { get; set; } = 1.5;
|
||||
|
||||
[Range(0.5, 3, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
|
||||
[Slider(0.5, 3, .2)]
|
||||
public double Height { get; set; } = 2.5;
|
||||
|
||||
public int Width { get; set; } = 150;
|
||||
|
|
|
|||
|
|
@ -68,11 +68,11 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
|
||||
public double Diameter { get; set; } = double.MinValue;
|
||||
|
||||
[Range(3, 360, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
|
||||
[Slider(3, 360, 1)]
|
||||
[Description("Ensures the rotated part has a minimum number of sides per complete rotation")]
|
||||
public double MinSidesPerRotation { get; set; } = 3;
|
||||
|
||||
[Range(0, 100, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
|
||||
[Slider(0, 100, 1)]
|
||||
[Description("Where to start the bend as a percent of the width of the part")]
|
||||
public double StartPercent { get; set; } = 50;
|
||||
|
||||
|
|
|
|||
|
|
@ -64,11 +64,11 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
|
||||
public double Diameter { get; set; } = double.MaxValue;
|
||||
|
||||
[Range(3, 360, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
|
||||
[Slider(3, 360, 1)]
|
||||
[Description("Ensures the rotated part has a minimum number of sides per complete rotation")]
|
||||
public double MinSidesPerRotation { get; set; } = 30;
|
||||
|
||||
[Range(0, 100, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
|
||||
[Slider(0, 100, 1)]
|
||||
[Description("Where to start the bend as a percent of the width of the part")]
|
||||
public double StartPercent { get; set; } = 50;
|
||||
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
[DescriptionImage("https://lh3.googleusercontent.com/h-s2FyBKO5etYDr_9YSLtGmGmQTcmSGMu4p0mRqX4_7Z62Ndn2QRLoFICC6X9scbhr1EP29RiYRj4EmhLMUwiNTAG-PIiFbzI_jAses")]
|
||||
public BendDirections BendDirection { get; set; } = BendDirections.Bend_Up;
|
||||
|
||||
[Range(0, 100, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
|
||||
[Slider(0, 100, 1)]
|
||||
[Description("Where to start the bend as a percent from the left side")]
|
||||
[DescriptionImage("https://lh3.googleusercontent.com/eOeWjr98uz_E924PnNaXrasepv15nWEuvhqH-jbaQyvrOVdX5MHXF00HdZQGC8NLpJc9ok1sToMtyPx1wnnDgFwTTGA5MjoMFu612AY1")]
|
||||
public double StartPercent { get; set; } = 50;
|
||||
|
|
@ -95,7 +95,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
[Description("Split the mesh so it has enough geometry to create a smooth curve")]
|
||||
public bool SplitMesh { get; set; } = true;
|
||||
|
||||
[Range(3, 360, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
|
||||
[Slider(3, 360, 1)]
|
||||
[Description("Ensures the rotated part has a minimum number of sides per complete rotation")]
|
||||
[DescriptionImage("https://lh3.googleusercontent.com/p9MyKu3AFP55PnobUKZQPqf6iAx11GzXyX-25f1ddrUnfCt8KFGd1YtHOR5HqfO0mhlX2ZVciZV4Yn0Kzfm43SErOS_xzgsESTu9scux")]
|
||||
public double MinSidesPerRotation { get; set; } = 30;
|
||||
|
|
|
|||
|
|
@ -173,10 +173,10 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
[JsonIgnore]
|
||||
private ImageBuffer Image => this.Descendants<ImageObject3D>().FirstOrDefault()?.Image;
|
||||
|
||||
[Range(0, 1, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
|
||||
[Slider(0, 1, .05)]
|
||||
public DoubleOrExpression RangeStart { get; set; } = .1;
|
||||
|
||||
[Range(0, 1, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
|
||||
[Slider(0, 1, .05)]
|
||||
public DoubleOrExpression RangeEnd { get; set; } = 1;
|
||||
|
||||
public IVertexSource VertexSource { get; set; } = new VertexStorage();
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ using MatterHackers.Localizations;
|
|||
using MatterHackers.MarchingSquares;
|
||||
using MatterHackers.MatterControl.DesignTools.Operations;
|
||||
using MatterHackers.MatterControl.PartPreviewWindow;
|
||||
using MatterHackers.VectorMath;
|
||||
using Newtonsoft.Json;
|
||||
using Polygon = System.Collections.Generic.List<ClipperLib.IntPoint>;
|
||||
using Polygons = System.Collections.Generic.List<System.Collections.Generic.List<ClipperLib.IntPoint>>;
|
||||
|
|
@ -116,7 +117,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
}
|
||||
|
||||
|
||||
private AnalysisTypes _featureDetector = AnalysisTypes.Intensity;
|
||||
private AnalysisTypes _featureDetector = AnalysisTypes.Intensity;
|
||||
[EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Tabs)]
|
||||
public AnalysisTypes AnalysisType
|
||||
{
|
||||
|
|
@ -162,6 +163,10 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
[DisplayName("Select Range")]
|
||||
public Histogram Histogram { get; set; } = new Histogram();
|
||||
|
||||
[Slider(0, 10, 1)]
|
||||
[Description("The minimum area each loop needs to be for inclusion")]
|
||||
public double MinSurfaceArea {get; set; } = 1;
|
||||
|
||||
public IVertexSource VertexSource { get; set; } = new VertexStorage();
|
||||
|
||||
public void AddObject3DControls(Object3DControlsLayer object3DControlsLayer)
|
||||
|
|
@ -200,34 +205,50 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
int pixelsToIntPointsScale = 1000;
|
||||
var lineLoops = marchingSquaresData.CreateLineLoops(pixelsToIntPointsScale);
|
||||
|
||||
if (MinSurfaceArea > 0)
|
||||
{
|
||||
var minimumSurfaceArea = Math.Pow(MinSurfaceArea * 1000, 2);
|
||||
|
||||
for (int i=lineLoops.Count - 1; i >=0; i--)
|
||||
{
|
||||
var area = Math.Abs(Clipper.Area(lineLoops[i]));
|
||||
if (area < minimumSurfaceArea)
|
||||
{
|
||||
lineLoops.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
progressReporter?.Invoke(.15, null);
|
||||
|
||||
var min = new IntPoint(-10, -10);
|
||||
var max = new IntPoint(10 + image.Width * pixelsToIntPointsScale, 10 + image.Height * pixelsToIntPointsScale);
|
||||
|
||||
var boundingPoly = new Polygon();
|
||||
boundingPoly.Add(min);
|
||||
boundingPoly.Add(new IntPoint(min.X, max.Y));
|
||||
boundingPoly.Add(max);
|
||||
boundingPoly.Add(new IntPoint(max.X, min.Y));
|
||||
var boundingPoly = new Polygon
|
||||
{
|
||||
min,
|
||||
new IntPoint(min.X, max.Y),
|
||||
max,
|
||||
new IntPoint(max.X, min.Y)
|
||||
};
|
||||
|
||||
// now clip the polygons to get the inside and outside polys
|
||||
var clipper = new Clipper();
|
||||
clipper.AddPaths(lineLoops, PolyType.ptSubject, true);
|
||||
clipper.AddPath(boundingPoly, PolyType.ptClip, true);
|
||||
|
||||
var polygonShape = new Polygons();
|
||||
var polygonShapes = new Polygons();
|
||||
progressReporter?.Invoke(.3, null);
|
||||
|
||||
clipper.Execute(ClipType.ctIntersection, polygonShape);
|
||||
clipper.Execute(ClipType.ctIntersection, polygonShapes);
|
||||
|
||||
progressReporter?.Invoke(.55, null);
|
||||
|
||||
polygonShape = Clipper.CleanPolygons(polygonShape, 100);
|
||||
polygonShapes = Clipper.CleanPolygons(polygonShapes, 100);
|
||||
|
||||
progressReporter?.Invoke(.75, null);
|
||||
|
||||
VertexStorage rawVectorShape = polygonShape.PolygonToPathStorage();
|
||||
VertexStorage rawVectorShape = polygonShapes.PolygonToPathStorage();
|
||||
|
||||
var aabb = this.VisibleMeshes().FirstOrDefault().GetAxisAlignedBoundingBox();
|
||||
var xScale = aabb.XSize / image.Width;
|
||||
|
|
@ -242,12 +263,67 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
}
|
||||
}
|
||||
|
||||
private bool ColorDetected(ImageBuffer sourceImage, out double hueDetected)
|
||||
{
|
||||
byte[] sourceBuffer = sourceImage.GetBuffer();
|
||||
var min = new Vector3(double.MaxValue, double.MaxValue, double.MaxValue);
|
||||
var max = new Vector3(double.MinValue, double.MinValue, double.MinValue);
|
||||
|
||||
for(int y = 0; y < sourceImage.Height; y++)
|
||||
{
|
||||
int imageOffset = sourceImage.GetBufferOffsetY(y);
|
||||
for (int x = 0; x < sourceImage.Width; x++)
|
||||
{
|
||||
int offset = imageOffset + x * 4;
|
||||
var b = sourceBuffer[offset + 0];
|
||||
var g = sourceBuffer[offset + 1];
|
||||
var r = sourceBuffer[offset + 2];
|
||||
|
||||
var color = new ColorF(r / 255.0, g / 255.0, b / 255.0);
|
||||
color.GetHSL(out double hue, out double saturation, out double lightness);
|
||||
|
||||
min = Vector3.ComponentMin(min, new Vector3(hue, saturation, lightness));
|
||||
max = Vector3.ComponentMax(max, new Vector3(hue, saturation, lightness));
|
||||
|
||||
if (saturation > .4 && lightness > .1 && lightness < .9)
|
||||
{
|
||||
hueDetected = hue;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hueDetected = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override async void OnInvalidate(InvalidateArgs invalidateArgs)
|
||||
{
|
||||
if (invalidateArgs.InvalidateType.HasFlag(InvalidateType.Image)
|
||||
&& invalidateArgs.Source != this
|
||||
&& !RebuildLocked)
|
||||
{
|
||||
// try to pick the best processing mode
|
||||
if (SourceImage.HasTransparency)
|
||||
{
|
||||
AnalysisType = AnalysisTypes.Transparency;
|
||||
Histogram.RangeStart = 0;
|
||||
Histogram.RangeEnd = .9;
|
||||
}
|
||||
else if (ColorDetected(SourceImage, out double hue))
|
||||
{
|
||||
AnalysisType = AnalysisTypes.Colors;
|
||||
Histogram.RangeStart = Math.Max(0, hue - .2);
|
||||
Histogram.RangeEnd = Math.Min(1, hue + .2);
|
||||
}
|
||||
else
|
||||
{
|
||||
AnalysisType = AnalysisTypes.Intensity;
|
||||
Histogram.RangeStart = 0;
|
||||
Histogram.RangeEnd = .9;
|
||||
}
|
||||
|
||||
|
||||
if (AnalysisType != AnalysisTypes.Transparency)
|
||||
{
|
||||
Histogram.BuildHistogramFromImage(SourceImage, AnalysisType);
|
||||
|
|
@ -259,6 +335,8 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
Image?.CopyFrom(SourceImage);
|
||||
}
|
||||
await Rebuild();
|
||||
|
||||
this.ReloadEditorPannel();
|
||||
}
|
||||
else if ((invalidateArgs.InvalidateType.HasFlag(InvalidateType.Properties) && invalidateArgs.Source == this))
|
||||
{
|
||||
|
|
@ -334,6 +412,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
public void UpdateControls(PublicPropertyChange change)
|
||||
{
|
||||
change.SetRowVisible(nameof(Histogram), () => AnalysisType != AnalysisTypes.Transparency);
|
||||
change.SetRowVisible(nameof(MinSurfaceArea), () => AnalysisType != AnalysisTypes.Transparency);
|
||||
change.SetRowVisible(nameof(TransparencyMessage), () => AnalysisType == AnalysisTypes.Transparency);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,6 +99,33 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
|
|||
return null;
|
||||
}
|
||||
|
||||
public static InteractiveScene ContainingScene(this IObject3D object3D)
|
||||
{
|
||||
foreach (var workspace in ApplicationController.Instance.Workspaces)
|
||||
{
|
||||
if (workspace.SceneContext.Scene.Descendants().Contains(object3D))
|
||||
{
|
||||
return workspace.SceneContext.Scene;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void ReloadEditorPannel(this IObject3D object3D)
|
||||
{
|
||||
// de-select and select this object
|
||||
var scene = object3D.ContainingScene();
|
||||
if (scene != null
|
||||
&& (object3D.Parents().Contains(scene.SelectedItem)
|
||||
|| object3D == scene.SelectedItem))
|
||||
{
|
||||
var selection = scene.SelectedItem;
|
||||
scene.SelectedItem = null;
|
||||
scene.SelectedItem = selection;
|
||||
}
|
||||
}
|
||||
|
||||
public static int EstimatedMemory(this IObject3D object3D)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -101,11 +101,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
|
||||
GLHelper.Render(
|
||||
sceneContext.Mesh,
|
||||
theme.UnderBedColor,
|
||||
theme.UnderBedColor.WithAlpha(32),
|
||||
RenderTypes.Shaded,
|
||||
world.ModelviewMatrix,
|
||||
blendTexture: !this.LookingDownOnBed,
|
||||
forceCullBackFaces: true);
|
||||
forceCullBackFaces: false);
|
||||
|
||||
if (sceneContext.PrinterShape != null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -305,6 +305,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
if (selectedItem is ComponentObject3D componentObject
|
||||
&& componentObject.Finalized)
|
||||
{
|
||||
var context = new PPEContext();
|
||||
PublicPropertyEditor.AddUnlockLinkIfRequired(selectedItem, editorPanel, theme);
|
||||
foreach (var selector in componentObject.SurfacedEditors)
|
||||
{
|
||||
|
|
@ -356,8 +357,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
}
|
||||
else if (JsonPathContext.ReflectionValueSystem.LastMemberValue is ReflectionTarget reflectionTarget)
|
||||
{
|
||||
var context = new PPEContext();
|
||||
|
||||
if (reflectionTarget.Source is IObject3D editedChild)
|
||||
{
|
||||
context.item = editedChild;
|
||||
|
|
@ -374,6 +373,9 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
{
|
||||
editorPanel.AddChild(editor);
|
||||
}
|
||||
|
||||
// Init with custom 'UpdateControls' hooks
|
||||
(context.item as IPropertyGridModifier)?.UpdateControls(new PublicPropertyChange(context, "Update_Button"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,11 +109,74 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
}
|
||||
}
|
||||
|
||||
private void EnableReduceWidth(RadioTextButton enumTab)
|
||||
{
|
||||
var deviceScale = GuiWidget.DeviceScale;
|
||||
var padingSize = enumTab.Padding.Left * deviceScale;
|
||||
enumTab.MinimumSize = new Vector2(padingSize * 3, enumTab.Height);
|
||||
enumTab.HAnchor = HAnchor.Stretch;
|
||||
|
||||
// delay this for an update so that the layout of the text widget has happened and its size has been updated.
|
||||
var textWidget = enumTab.Descendants<TextWidget>().First();
|
||||
textWidget.Margin = new BorderDouble(enumTab.Padding.Left, 0, 0, 0);
|
||||
textWidget.HAnchor = HAnchor.Left;
|
||||
|
||||
enumTab.AfterDraw += (s, e) =>
|
||||
{
|
||||
if (enumTab.Width < enumTab.MaximumSize.X)
|
||||
{
|
||||
var bounds = enumTab.LocalBounds;
|
||||
var g = e.Graphics2D;
|
||||
var color = enumTab.SelectedBackgroundColor;
|
||||
if (!enumTab.Checked)
|
||||
{
|
||||
foreach (var parent in enumTab.Parents<GuiWidget>())
|
||||
{
|
||||
if (parent.BackgroundColor.alpha > 200)
|
||||
{
|
||||
color = parent.BackgroundColor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// cover the text with an alpha mask
|
||||
for (int i = 0; i < padingSize + 1; i++)
|
||||
{
|
||||
var x = bounds.Right - padingSize + i;
|
||||
g.Line(x, bounds.Bottom, x, bounds.Top, color.WithAlpha(Math.Min(255, i / 10.0 * deviceScale)));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// the text
|
||||
var maxWidth = textWidget.Width + enumTab.Padding.Width * deviceScale;
|
||||
enumTab.MaximumSize = new Vector2(maxWidth, enumTab.MaximumSize.Y);
|
||||
enumTab.Padding = new BorderDouble(0, enumTab.Padding.Bottom, 0, enumTab.Padding.Top);
|
||||
|
||||
if (string.IsNullOrEmpty(enumTab.ToolTipText))
|
||||
{
|
||||
// wait for this size change to take effect and update the tool tip
|
||||
enumTab.BoundsChanged += (s, e) =>
|
||||
{
|
||||
if (enumTab.Width < enumTab.MaximumSize.X)
|
||||
{
|
||||
enumTab.ToolTipText = textWidget.Text;
|
||||
}
|
||||
else
|
||||
{
|
||||
enumTab.ToolTipText = "";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
enumTab.HAnchor = HAnchor.Stretch;
|
||||
}
|
||||
|
||||
private void AddTabs(IEnumerable<(string Key, string Value)> enumItems, List<string> descriptions)
|
||||
{
|
||||
var menuRow = new FlowLayoutWidget()
|
||||
{
|
||||
Margin = 5
|
||||
Margin = 5,
|
||||
};
|
||||
|
||||
int index = 0;
|
||||
|
|
@ -123,7 +186,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
|
||||
var radioButton = new RadioTextButton(enumItem.Value, theme)
|
||||
{
|
||||
ToolTipText = descriptions[index]
|
||||
ToolTipText = descriptions[index],
|
||||
};
|
||||
|
||||
menuRow.AfterDraw += (s, e) =>
|
||||
|
|
@ -145,6 +208,8 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
radioButton.Checked = true;
|
||||
}
|
||||
|
||||
EnableReduceWidth(radioButton);
|
||||
|
||||
menuRow.AddChild(radioButton);
|
||||
|
||||
var localItem = enumItem;
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit cfdb25b9b6564ff8039777531656a162fd2cae99
|
||||
Subproject commit 2ae23e64a38e0d13da4ba6c9e8803ee07d8daf05
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 07f063560762f7762553f6cd67de90ed89fd8463
|
||||
Subproject commit cb957e18fa363d13c6b36e02b603a5bf687bc2f5
|
||||
Loading…
Add table
Add a link
Reference in a new issue