Lots of work on Array tool and support property editors
This commit is contained in:
parent
5675973207
commit
2cd09dd365
12 changed files with 503 additions and 61 deletions
|
|
@ -389,11 +389,11 @@ namespace MatterHackers.MatterControl
|
|||
new SceneSelectionSeparator(),
|
||||
new SceneSelectionOperation()
|
||||
{
|
||||
TitleResolver = () => "Array".Localize(),
|
||||
TitleResolver = () => "Linear Array".Localize(),
|
||||
Action = (scene) =>
|
||||
{
|
||||
scene.AddSelectionAsChildren(new ArrayObject3D());
|
||||
if(scene.SelectedItem is ArrayObject3D array)
|
||||
scene.AddSelectionAsChildren(new ArrayLinearObject3D());
|
||||
if(scene.SelectedItem is ArrayLinearObject3D array)
|
||||
{
|
||||
array.Rebuild();
|
||||
}
|
||||
|
|
@ -402,6 +402,36 @@ namespace MatterHackers.MatterControl
|
|||
IsEnabled = (scene) => scene.HasSelection && !(scene.SelectedItem is SelectionGroup),
|
||||
},
|
||||
new SceneSelectionOperation()
|
||||
{
|
||||
TitleResolver = () => "Radial Array".Localize(),
|
||||
Action = (scene) =>
|
||||
{
|
||||
scene.AddSelectionAsChildren(new ArrayRadialObject3D());
|
||||
if(scene.SelectedItem is ArrayRadialObject3D array)
|
||||
{
|
||||
array.Rebuild();
|
||||
}
|
||||
},
|
||||
Icon = AggContext.StaticData.LoadIcon("array.png").SetPreMultiply(),
|
||||
IsEnabled = (scene) => scene.HasSelection && !(scene.SelectedItem is SelectionGroup),
|
||||
},
|
||||
new SceneSelectionSeparator(),
|
||||
new SceneSelectionOperation()
|
||||
{
|
||||
TitleResolver = () => "Advanced Array".Localize(),
|
||||
Action = (scene) =>
|
||||
{
|
||||
scene.AddSelectionAsChildren(new ArrayAdvancedObject3D());
|
||||
if(scene.SelectedItem is ArrayAdvancedObject3D array)
|
||||
{
|
||||
array.Rebuild();
|
||||
}
|
||||
},
|
||||
Icon = AggContext.StaticData.LoadIcon("array.png").SetPreMultiply(),
|
||||
IsEnabled = (scene) => scene.HasSelection && !(scene.SelectedItem is SelectionGroup),
|
||||
},
|
||||
new SceneSelectionSeparator(),
|
||||
new SceneSelectionOperation()
|
||||
{
|
||||
TitleResolver = () => "Package".Localize(),
|
||||
Action = (scene) =>
|
||||
|
|
|
|||
|
|
@ -28,25 +28,35 @@ either expressed or implied, of the FreeBSD Project.
|
|||
*/
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using MatterHackers.DataConverters3D;
|
||||
using MatterHackers.VectorMath;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace MatterHackers.MatterControl.DesignTools.Operations
|
||||
{
|
||||
public class ArrayObject3D : Object3D, IRebuildable
|
||||
public class DirectionAxis
|
||||
{
|
||||
public Vector3 Origin { get; set; }
|
||||
public Vector3 Normal { get; set; }
|
||||
}
|
||||
|
||||
public class DirectionVector
|
||||
{
|
||||
public Vector3 Normal { get; set; }
|
||||
}
|
||||
|
||||
public class ArrayLinearObject3D : Object3D, IRebuildable
|
||||
{
|
||||
public int Count { get; set; } = 3;
|
||||
public double XOffset { get; set; } = 30;
|
||||
public double YOffset { get; set; } = 0;
|
||||
public double Rotate { get; set; } = 0;
|
||||
public double Scale { get; set; } = 1;
|
||||
public bool RotatePart { get; set; } = false;
|
||||
public bool ScaleOffset { get; set; } = false;
|
||||
public DirectionVector Direction { get; set; } = new DirectionVector { Normal = new Vector3(1, 0, 0) };
|
||||
public double Distance { get; set; } = 30;
|
||||
|
||||
public override string ActiveEditor => "PublicPropertyEditor";
|
||||
|
||||
public ArrayObject3D()
|
||||
public ArrayLinearObject3D()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -59,6 +69,92 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
|
|||
list.Add(lastChild);
|
||||
var offset = Vector3.Zero;
|
||||
for (int i=1; i<Count; i++)
|
||||
{
|
||||
var next = lastChild.Clone();
|
||||
next.Matrix *= Matrix4X4.CreateTranslation(Direction.Normal.GetNormal() * Distance);
|
||||
list.Add(next);
|
||||
lastChild = next;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class ArrayRadialObject3D : Object3D, IRebuildable
|
||||
{
|
||||
public int Count { get; set; } = 3;
|
||||
|
||||
public DirectionAxis Axis { get; set; } = new DirectionAxis() { Origin = new Vector3(-30, 0, 0), Normal = Vector3.UnitZ };
|
||||
public double Angle { get; set; } = 360;
|
||||
|
||||
[DisplayName("Keep Within Angle")]
|
||||
[Description("Keep the entire extents of the part within the angle described.")]
|
||||
public bool KeepInAngle { get; set; } = false;
|
||||
|
||||
[DisplayName("Rotate Part")]
|
||||
[Description("Rotate the part to the same angle as the array.")]
|
||||
public bool RotatePart { get; set; } = true;
|
||||
|
||||
public override string ActiveEditor => "PublicPropertyEditor";
|
||||
|
||||
public ArrayRadialObject3D()
|
||||
{
|
||||
}
|
||||
|
||||
public void Rebuild()
|
||||
{
|
||||
this.Children.Modify(list =>
|
||||
{
|
||||
IObject3D lastChild = list.First();
|
||||
var partCenter = lastChild.GetAxisAlignedBoundingBox().Center;
|
||||
|
||||
list.Clear();
|
||||
list.Add(lastChild);
|
||||
var offset = Vector3.Zero;
|
||||
for (int i = 1; i < Count; i++)
|
||||
{
|
||||
var angleRadians = MathHelper.DegreesToRadians(Angle);
|
||||
var nextOffset = Axis.Origin;
|
||||
|
||||
//nextOffset Rotate(angleRadians * i);
|
||||
var next = lastChild.Clone();
|
||||
next.Matrix *= Matrix4X4.CreateTranslation(nextOffset.X, nextOffset.Y, 0);
|
||||
|
||||
if (RotatePart)
|
||||
{
|
||||
next.ApplyAtBoundsCenter(Matrix4X4.CreateRotationZ(angleRadians));
|
||||
}
|
||||
|
||||
lastChild = next;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class ArrayAdvancedObject3D : Object3D, IRebuildable
|
||||
{
|
||||
public int Count { get; set; } = 3;
|
||||
public double XOffset { get; set; } = 30;
|
||||
public double YOffset { get; set; } = 0;
|
||||
public double Rotate { get; set; } = 0;
|
||||
public double Scale { get; set; } = 1;
|
||||
public bool RotatePart { get; set; } = false;
|
||||
public bool ScaleOffset { get; set; } = false;
|
||||
|
||||
public override string ActiveEditor => "PublicPropertyEditor";
|
||||
|
||||
public ArrayAdvancedObject3D()
|
||||
{
|
||||
}
|
||||
|
||||
public void Rebuild()
|
||||
{
|
||||
this.Children.Modify(list =>
|
||||
{
|
||||
IObject3D lastChild = list.First();
|
||||
list.Clear();
|
||||
list.Add(lastChild);
|
||||
var offset = Vector3.Zero;
|
||||
for (int i = 1; i < Count; i++)
|
||||
{
|
||||
var rotateRadians = MathHelper.DegreesToRadians(Rotate);
|
||||
var nextOffset = new Vector2(XOffset, YOffset);
|
||||
|
|
@ -80,7 +176,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
|
|||
}
|
||||
|
||||
next.ApplyAtBoundsCenter(Matrix4X4.CreateScale(Scale));
|
||||
list.Add(next.Clone());
|
||||
list.Add(next);
|
||||
lastChild = next;
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
|
||||
public double Height { get; set; } = 5;
|
||||
|
||||
[Sortable]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public NamedTypeFace Font { get; set; } = new NamedTypeFace();
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,10 @@ using MatterHackers.Agg.UI;
|
|||
using MatterHackers.DataConverters3D;
|
||||
using MatterHackers.Localizations;
|
||||
using MatterHackers.MatterControl.CustomWidgets;
|
||||
using MatterHackers.MatterControl.DesignTools.Operations;
|
||||
using MatterHackers.MatterControl.PartPreviewWindow;
|
||||
using MatterHackers.MatterControl.SlicerConfiguration;
|
||||
using MatterHackers.VectorMath;
|
||||
|
||||
namespace MatterHackers.MatterControl.DesignTools
|
||||
{
|
||||
|
|
@ -46,6 +49,11 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
void Rebuild();
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class SortableAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
public class PublicPropertyEditor : IObject3DEditor
|
||||
{
|
||||
private IObject3D item;
|
||||
|
|
@ -56,7 +64,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
|
||||
private static Type[] allowedTypes =
|
||||
{
|
||||
typeof(double), typeof(int), typeof(string), typeof(bool)
|
||||
typeof(double), typeof(int), typeof(string), typeof(bool), typeof(DirectionVector), typeof(DirectionAxis)
|
||||
};
|
||||
|
||||
public const BindingFlags OwnedPropertiesOnly = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;
|
||||
|
|
@ -129,42 +137,116 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
if (property.Value is double doubleValue)
|
||||
{
|
||||
FlowLayoutWidget rowContainer = CreateSettingsRow(property.DisplayName.Localize());
|
||||
var doubleEditWidget = new MHNumberEdit(doubleValue, pixelWidth: 50 * GuiWidget.DeviceScale, allowNegatives: true, allowDecimals: true, increment: .05)
|
||||
|
||||
var field = new DoubleField();
|
||||
field.Initialize(0);
|
||||
field.DoubleValue = doubleValue;
|
||||
field.ValueChanged += (s, e) =>
|
||||
{
|
||||
SelectAllOnFocus = true,
|
||||
VAnchor = VAnchor.Center
|
||||
};
|
||||
doubleEditWidget.ActuallNumberEdit.EditComplete += (s, e) =>
|
||||
{
|
||||
double editValue;
|
||||
if (double.TryParse(doubleEditWidget.Text, out editValue))
|
||||
{
|
||||
property.PropertyInfo.GetSetMethod().Invoke(this.item, new Object[] { editValue });
|
||||
}
|
||||
property.PropertyInfo.GetSetMethod().Invoke(this.item, new Object[] { field.DoubleValue });
|
||||
rebuildable?.Rebuild();
|
||||
};
|
||||
rowContainer.AddChild(doubleEditWidget);
|
||||
|
||||
rowContainer.AddChild(field.Content);
|
||||
tabContainer.AddChild(rowContainer);
|
||||
}
|
||||
else if (property.Value is Vector2 vector2)
|
||||
{
|
||||
FlowLayoutWidget rowContainer = CreateSettingsRow(property.DisplayName.Localize());
|
||||
|
||||
var field = new Vector2Field();
|
||||
field.Initialize(0);
|
||||
field.Vector2 = vector2;
|
||||
field.ValueChanged += (s, e) =>
|
||||
{
|
||||
property.PropertyInfo.GetSetMethod().Invoke(this.item, new Object[] { field.Vector2 });
|
||||
rebuildable?.Rebuild();
|
||||
};
|
||||
|
||||
rowContainer.AddChild(field.Content);
|
||||
tabContainer.AddChild(rowContainer);
|
||||
}
|
||||
else if (property.Value is Vector3 vector3)
|
||||
{
|
||||
FlowLayoutWidget rowContainer = CreateSettingsRow(property.DisplayName.Localize());
|
||||
|
||||
var field = new Vector3Field();
|
||||
field.Initialize(0);
|
||||
field.Vector3 = vector3;
|
||||
field.ValueChanged += (s, e) =>
|
||||
{
|
||||
property.PropertyInfo.GetSetMethod().Invoke(this.item, new Object[] { field.Vector3 });
|
||||
rebuildable?.Rebuild();
|
||||
};
|
||||
|
||||
rowContainer.AddChild(field.Content);
|
||||
tabContainer.AddChild(rowContainer);
|
||||
}
|
||||
else if (property.Value is DirectionVector directionVector)
|
||||
{
|
||||
FlowLayoutWidget rowContainer = CreateSettingsRow(property.DisplayName.Localize());
|
||||
|
||||
var field = new Vector3Field();
|
||||
field.Initialize(0);
|
||||
field.Vector3 = directionVector.Normal;
|
||||
field.ValueChanged += (s, e) =>
|
||||
{
|
||||
property.PropertyInfo.GetSetMethod().Invoke(this.item, new Object[] { new DirectionVector() { Normal = field.Vector3 } });
|
||||
rebuildable?.Rebuild();
|
||||
};
|
||||
|
||||
rowContainer.AddChild(field.Content);
|
||||
tabContainer.AddChild(rowContainer);
|
||||
}
|
||||
else if (property.Value is DirectionAxis directionAxis)
|
||||
{
|
||||
// add in the position
|
||||
FlowLayoutWidget originRowContainer = CreateSettingsRow(property.DisplayName.Localize());
|
||||
|
||||
var originField = new Vector3Field();
|
||||
originField.Initialize(0);
|
||||
originField.Vector3 = directionAxis.Origin;
|
||||
|
||||
var normalField = new Vector3Field();
|
||||
normalField.Initialize(0);
|
||||
normalField.Vector3 = directionAxis.Normal;
|
||||
|
||||
originField.ValueChanged += (s, e) =>
|
||||
{
|
||||
property.PropertyInfo.GetSetMethod().Invoke(this.item, new Object[] { new DirectionAxis() { Origin = originField.Vector3, Normal = normalField.Vector3 } });
|
||||
rebuildable?.Rebuild();
|
||||
};
|
||||
|
||||
originRowContainer.AddChild(originField.Content);
|
||||
tabContainer.AddChild(originRowContainer);
|
||||
|
||||
// add in the direction
|
||||
FlowLayoutWidget directionRowContainer = CreateSettingsRow(property.DisplayName.Localize());
|
||||
|
||||
normalField.ValueChanged += (s, e) =>
|
||||
{
|
||||
property.PropertyInfo.GetSetMethod().Invoke(this.item, new Object[] { new DirectionAxis() { Origin = originField.Vector3, Normal = normalField.Vector3 } });
|
||||
rebuildable?.Rebuild();
|
||||
};
|
||||
|
||||
directionRowContainer.AddChild(normalField.Content);
|
||||
tabContainer.AddChild(directionRowContainer);
|
||||
}
|
||||
// create a int editor
|
||||
else if (property.Value is int intValue)
|
||||
{
|
||||
FlowLayoutWidget rowContainer = CreateSettingsRow(property.DisplayName.Localize());
|
||||
var intEditWidget = new MHNumberEdit(intValue, pixelWidth: 50 * GuiWidget.DeviceScale, allowNegatives: true, allowDecimals: false, increment: 1)
|
||||
|
||||
var field = new IntField();
|
||||
field.Initialize(0);
|
||||
field.IntValue = intValue;
|
||||
field.ValueChanged += (s, e) =>
|
||||
{
|
||||
SelectAllOnFocus = true,
|
||||
VAnchor = VAnchor.Center
|
||||
};
|
||||
intEditWidget.ActuallNumberEdit.EditComplete += (s, e) =>
|
||||
{
|
||||
int editValue;
|
||||
if (int.TryParse(intEditWidget.Text, out editValue))
|
||||
{
|
||||
property.PropertyInfo.GetSetMethod().Invoke(this.item, new Object[] { editValue });
|
||||
}
|
||||
property.PropertyInfo.GetSetMethod().Invoke(this.item, new Object[] { field.IntValue });
|
||||
rebuildable?.Rebuild();
|
||||
};
|
||||
rowContainer.AddChild(intEditWidget);
|
||||
|
||||
rowContainer.AddChild(field.Content);
|
||||
tabContainer.AddChild(rowContainer);
|
||||
}
|
||||
// create a bool editor
|
||||
|
|
@ -172,14 +254,16 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
{
|
||||
FlowLayoutWidget rowContainer = CreateSettingsRow(property.DisplayName.Localize());
|
||||
|
||||
var doubleEditWidget = new CheckBox("");
|
||||
doubleEditWidget.Checked = boolValue;
|
||||
doubleEditWidget.CheckedStateChanged += (s, e) =>
|
||||
var field = new ToggleboxField(ApplicationController.Instance.Theme.Colors.PrimaryTextColor);
|
||||
field.Initialize(0);
|
||||
field.Checked = boolValue;
|
||||
field.ValueChanged += (s, e) =>
|
||||
{
|
||||
property.PropertyInfo.GetSetMethod().Invoke(this.item, new Object[] { doubleEditWidget.Checked });
|
||||
property.PropertyInfo.GetSetMethod().Invoke(this.item, new Object[] { field.Checked });
|
||||
rebuildable?.Rebuild();
|
||||
};
|
||||
rowContainer.AddChild(doubleEditWidget);
|
||||
|
||||
rowContainer.AddChild(field.Content);
|
||||
tabContainer.AddChild(rowContainer);
|
||||
}
|
||||
// create a string editor
|
||||
|
|
@ -199,7 +283,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
rowContainer.AddChild(textEditWidget);
|
||||
tabContainer.AddChild(rowContainer);
|
||||
}
|
||||
// create a NamedTypeFace editor
|
||||
// create a enum editor
|
||||
else if (property.PropertyType.IsEnum)
|
||||
{
|
||||
// Enum keyed on name to friendly name
|
||||
|
|
@ -216,16 +300,19 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
|
||||
var dropDownList = new DropDownList("Name".Localize(), theme.Colors.PrimaryTextColor, Direction.Down, pointSize: theme.DefaultFontSize);
|
||||
|
||||
foreach (var fontName in enumItems.OrderBy(n => n.Value))
|
||||
{
|
||||
MenuItem newItem = dropDownList.AddItem(fontName.Value);
|
||||
var sortableAttribute = property.PropertyInfo.GetCustomAttributes(true).OfType<SortableAttribute>().FirstOrDefault();
|
||||
var orderedItems = sortableAttribute != null ? enumItems.OrderBy(n => n.Value) : enumItems;
|
||||
|
||||
var localFontName = fontName;
|
||||
foreach (var orderItem in orderedItems)
|
||||
{
|
||||
MenuItem newItem = dropDownList.AddItem(orderItem.Value);
|
||||
|
||||
var localOredrItem = orderItem;
|
||||
newItem.Selected += (sender, e) =>
|
||||
{
|
||||
property.PropertyInfo.GetSetMethod().Invoke(
|
||||
this.item,
|
||||
new Object[] { Enum.Parse(property.PropertyType, localFontName.Key) });
|
||||
this.item,
|
||||
new Object[] { Enum.Parse(property.PropertyType, localOredrItem.Key) });
|
||||
rebuildable?.Rebuild();
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -200,6 +200,7 @@
|
|||
<Compile Include="SlicerConfiguration\SettingsOrganizer.cs" />
|
||||
<Compile Include="SlicerConfiguration\SlicerMapping\SliceEngineMapping.cs" />
|
||||
<Compile Include="SlicerConfiguration\UIFields\IpAddessField.cs" />
|
||||
<Compile Include="SlicerConfiguration\UIFields\Vector3Field.cs" />
|
||||
<Compile Include="Utilities\InspectForm.cs" Condition="'$(Configuration)' == 'Debug'">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
{
|
||||
private CheckBox checkBoxWidget;
|
||||
|
||||
public bool Checked => checkBoxWidget.Checked;
|
||||
|
||||
public override void Initialize(int tabIndex)
|
||||
{
|
||||
checkBoxWidget = new CheckBox("")
|
||||
|
|
@ -69,6 +71,18 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
private CheckBox checkBoxWidget;
|
||||
private Color textColor;
|
||||
|
||||
public bool Checked
|
||||
{
|
||||
get
|
||||
{
|
||||
return checkBoxWidget.Checked;
|
||||
}
|
||||
set
|
||||
{
|
||||
checkBoxWidget.Checked = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ToggleboxField(Color textColor)
|
||||
{
|
||||
this.textColor = textColor;
|
||||
|
|
|
|||
|
|
@ -35,19 +35,31 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
{
|
||||
public class DoubleField : NumberField
|
||||
{
|
||||
protected double doubleValue;
|
||||
double _doubleValue;
|
||||
public double DoubleValue
|
||||
{
|
||||
get { return _doubleValue; }
|
||||
set
|
||||
{
|
||||
if (_doubleValue != value)
|
||||
{
|
||||
_doubleValue = value;
|
||||
numberEdit.Value = _doubleValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override string ConvertValue(string newValue)
|
||||
{
|
||||
double.TryParse(newValue, out double currentValue);
|
||||
doubleValue = currentValue;
|
||||
DoubleValue = currentValue;
|
||||
|
||||
return doubleValue.ToString();
|
||||
return DoubleValue.ToString();
|
||||
}
|
||||
|
||||
protected override void OnValueChanged(FieldChangedEventArgs fieldChangedEventArgs)
|
||||
{
|
||||
numberEdit.ActuallNumberEdit.Value = doubleValue;
|
||||
numberEdit.ActuallNumberEdit.Value = DoubleValue;
|
||||
base.OnValueChanged(fieldChangedEventArgs);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,19 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
{
|
||||
public class IntField : NumberField
|
||||
{
|
||||
private int intValue;
|
||||
int _intValue;
|
||||
public int IntValue
|
||||
{
|
||||
get { return _intValue; }
|
||||
set
|
||||
{
|
||||
if (_intValue != value)
|
||||
{
|
||||
_intValue = value;
|
||||
numberEdit.Value = _intValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int MinValue { get; set; } = int.MinValue;
|
||||
|
||||
|
|
@ -44,15 +56,15 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
decimal.TryParse(newValue, out decimal currentValue);
|
||||
|
||||
// Clamp to range
|
||||
intValue = Math.Min((int)currentValue, this.MaxValue);
|
||||
intValue = Math.Max(intValue, this.MinValue);
|
||||
IntValue = Math.Min((int)currentValue, this.MaxValue);
|
||||
IntValue = Math.Max(IntValue, this.MinValue);
|
||||
|
||||
return intValue.ToString();
|
||||
return IntValue.ToString();
|
||||
}
|
||||
|
||||
protected override void OnValueChanged(FieldChangedEventArgs fieldChangedEventArgs)
|
||||
{
|
||||
numberEdit.ActuallNumberEdit.Value = intValue;
|
||||
numberEdit.ActuallNumberEdit.Value = IntValue;
|
||||
base.OnValueChanged(fieldChangedEventArgs);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,9 +42,9 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
protected override string ConvertValue(string newValue)
|
||||
{
|
||||
base.ConvertValue(newValue);
|
||||
doubleValue = doubleValue < 0 ? 0 : Math.Abs(doubleValue);
|
||||
DoubleValue = DoubleValue < 0 ? 0 : Math.Abs(DoubleValue);
|
||||
|
||||
return doubleValue.ToString();
|
||||
return DoubleValue.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ either expressed or implied, of the FreeBSD Project.
|
|||
|
||||
using MatterHackers.Agg;
|
||||
using MatterHackers.Agg.UI;
|
||||
using MatterHackers.VectorMath;
|
||||
|
||||
namespace MatterHackers.MatterControl.SlicerConfiguration
|
||||
{
|
||||
|
|
@ -40,6 +41,20 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
|
||||
private MHNumberEdit xEditWidget;
|
||||
|
||||
public Vector2 Vector2
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Vector2(xEditWidget.Value, yEditWidget.Value);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
xEditWidget.Value = value.X;
|
||||
yEditWidget.Value = value.Y;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Initialize(int tabIndex)
|
||||
{
|
||||
var container = new FlowLayoutWidget();
|
||||
|
|
|
|||
174
SlicerConfiguration/UIFields/Vector3Field.cs
Normal file
174
SlicerConfiguration/UIFields/Vector3Field.cs
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
Copyright (c) 2017, 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.VectorMath;
|
||||
|
||||
namespace MatterHackers.MatterControl.SlicerConfiguration
|
||||
{
|
||||
public class Vector3Field : UIField
|
||||
{
|
||||
public static readonly int VectorXYZEditWidth = (int)(60 * GuiWidget.DeviceScale + .5);
|
||||
|
||||
private MHNumberEdit xEditWidget;
|
||||
private MHNumberEdit yEditWidget;
|
||||
private MHNumberEdit zEditWidget;
|
||||
|
||||
public Vector3 Vector3
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Vector3(xEditWidget.Value, yEditWidget.Value, zEditWidget.Value);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
xEditWidget.Value = value.X;
|
||||
yEditWidget.Value = value.Y;
|
||||
zEditWidget.Value = value.Z;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Initialize(int tabIndex)
|
||||
{
|
||||
var container = new FlowLayoutWidget();
|
||||
|
||||
string[] xyzValueStrings = this.Value?.Split(',');
|
||||
if (xyzValueStrings == null
|
||||
|| xyzValueStrings.Length != 3)
|
||||
{
|
||||
xyzValueStrings = new string[] { "0", "0", "0" };
|
||||
}
|
||||
|
||||
double.TryParse(xyzValueStrings[0], out double currentXValue);
|
||||
|
||||
xEditWidget = new MHNumberEdit(currentXValue, allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYZEditWidth, tabIndex: tabIndex)
|
||||
{
|
||||
ToolTipText = this.HelpText,
|
||||
TabIndex = tabIndex,
|
||||
SelectAllOnFocus = true
|
||||
};
|
||||
xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
|
||||
{
|
||||
this.SetValue(
|
||||
string.Format("{0},{1},{2}",
|
||||
xEditWidget.ActuallNumberEdit.Value.ToString(),
|
||||
yEditWidget.ActuallNumberEdit.Value.ToString(),
|
||||
zEditWidget.ActuallNumberEdit.Value.ToString()),
|
||||
userInitiated: true);
|
||||
};
|
||||
|
||||
container.AddChild(new TextWidget("X:", pointSize: 10, textColor: ActiveTheme.Instance.PrimaryTextColor)
|
||||
{
|
||||
VAnchor = VAnchor.Center,
|
||||
Margin = new BorderDouble(5, 0),
|
||||
});
|
||||
container.AddChild(xEditWidget);
|
||||
|
||||
double.TryParse(xyzValueStrings[1], out double currentYValue);
|
||||
|
||||
yEditWidget = new MHNumberEdit(currentYValue, allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYZEditWidth, tabIndex: tabIndex)
|
||||
{
|
||||
ToolTipText = this.HelpText,
|
||||
TabIndex = tabIndex + 1,
|
||||
SelectAllOnFocus = true,
|
||||
};
|
||||
yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
|
||||
{
|
||||
this.SetValue(
|
||||
string.Format("{0},{1},{2}",
|
||||
xEditWidget.ActuallNumberEdit.Value.ToString(),
|
||||
yEditWidget.ActuallNumberEdit.Value.ToString(),
|
||||
zEditWidget.ActuallNumberEdit.Value.ToString()),
|
||||
userInitiated: true);
|
||||
};
|
||||
|
||||
container.AddChild(new TextWidget("Y:", pointSize: 10, textColor: ActiveTheme.Instance.PrimaryTextColor)
|
||||
{
|
||||
VAnchor = VAnchor.Center,
|
||||
Margin = new BorderDouble(15, 0, 5, 0),
|
||||
});
|
||||
container.AddChild(yEditWidget);
|
||||
|
||||
double.TryParse(xyzValueStrings[2], out double currentZValue);
|
||||
|
||||
zEditWidget = new MHNumberEdit(currentZValue, allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYZEditWidth, tabIndex: tabIndex)
|
||||
{
|
||||
ToolTipText = this.HelpText,
|
||||
TabIndex = tabIndex + 1,
|
||||
SelectAllOnFocus = true,
|
||||
};
|
||||
zEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
|
||||
{
|
||||
this.SetValue(
|
||||
string.Format("{0},{1},{2}",
|
||||
xEditWidget.ActuallNumberEdit.Value.ToString(),
|
||||
yEditWidget.ActuallNumberEdit.Value.ToString(),
|
||||
zEditWidget.ActuallNumberEdit.Value.ToString()),
|
||||
userInitiated: true);
|
||||
};
|
||||
|
||||
container.AddChild(new TextWidget("Z:", pointSize: 10, textColor: ActiveTheme.Instance.PrimaryTextColor)
|
||||
{
|
||||
VAnchor = VAnchor.Center,
|
||||
Margin = new BorderDouble(15, 0, 5, 0),
|
||||
});
|
||||
container.AddChild(zEditWidget);
|
||||
|
||||
this.Content = container;
|
||||
}
|
||||
|
||||
protected override string ConvertValue(string newValue)
|
||||
{
|
||||
// Ensure we have a two value CSV or force to '0,0'
|
||||
return (newValue?.Split(',').Length == 3) ? newValue.Trim() : "0,0";
|
||||
}
|
||||
|
||||
protected override void OnValueChanged(FieldChangedEventArgs fieldChangedEventArgs)
|
||||
{
|
||||
string[] xyzValueStrings3 = this.Value.Split(',');
|
||||
if (xyzValueStrings3.Length != 3)
|
||||
{
|
||||
xyzValueStrings3 = new string[] { "0", "0", "0" };
|
||||
}
|
||||
|
||||
double.TryParse(xyzValueStrings3[0], out double currentValue);
|
||||
xEditWidget.ActuallNumberEdit.Value = currentValue;
|
||||
|
||||
double.TryParse(xyzValueStrings3[1], out currentValue);
|
||||
yEditWidget.ActuallNumberEdit.Value = currentValue;
|
||||
|
||||
double.TryParse(xyzValueStrings3[2], out currentValue);
|
||||
zEditWidget.ActuallNumberEdit.Value = currentValue;
|
||||
|
||||
base.OnValueChanged(fieldChangedEventArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit ab9ae85941ee030e16762d0a6ec1cf5ee771fe30
|
||||
Subproject commit a2b16945b16273fa243153926b9121ec20f06911
|
||||
Loading…
Add table
Add a link
Reference in a new issue