remember editor zoom and position
This commit is contained in:
parent
17107dbf14
commit
7f9cab6963
4 changed files with 58 additions and 68 deletions
|
|
@ -30,19 +30,37 @@ either expressed or implied, of the FreeBSD Project.
|
||||||
using MatterHackers.Agg.UI;
|
using MatterHackers.Agg.UI;
|
||||||
using MatterHackers.Agg.VertexSource;
|
using MatterHackers.Agg.VertexSource;
|
||||||
using MatterHackers.DataConverters3D;
|
using MatterHackers.DataConverters3D;
|
||||||
|
using MatterHackers.VectorMath;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace MatterHackers.MatterControl.DesignTools
|
namespace MatterHackers.MatterControl.DesignTools
|
||||||
{
|
{
|
||||||
public class PathEditorFactory : IPropertyEditorFactory
|
public class PathEditorFactory : IPropertyEditorFactory
|
||||||
{
|
{
|
||||||
|
public class EditableVertexStorage : VertexStorage
|
||||||
|
{
|
||||||
|
public Vector2 UnscaledOffset { get; set; } = Vector2.Zero;
|
||||||
|
public double Scale { get; set; } = 1;
|
||||||
|
}
|
||||||
|
|
||||||
private Object3D object3D;
|
private Object3D object3D;
|
||||||
|
|
||||||
public GuiWidget CreateEditor(PropertyEditor propertyEditor, EditableProperty property, EditorContext context, ref int tabIndex)
|
public GuiWidget CreateEditor(PropertyEditor propertyEditor, EditableProperty property, EditorContext context, ref int tabIndex)
|
||||||
{
|
{
|
||||||
if (property.Value is VertexStorage vertexStorage)
|
if (property.Value is EditableVertexStorage vertexStorage)
|
||||||
{
|
{
|
||||||
var pathEditorWidget = new PathEditorWidget(vertexStorage, propertyEditor.UndoBuffer, propertyEditor.Theme, VertexBufferChanged);
|
var pathEditorWidget = new PathEditorWidget(vertexStorage,
|
||||||
|
propertyEditor.UndoBuffer,
|
||||||
|
propertyEditor.Theme,
|
||||||
|
VertexBufferChanged,
|
||||||
|
vertexStorage.UnscaledOffset,
|
||||||
|
vertexStorage.Scale,
|
||||||
|
(unscaledOffset, scale) =>
|
||||||
|
{
|
||||||
|
vertexStorage.UnscaledOffset = unscaledOffset;
|
||||||
|
vertexStorage.Scale = scale;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
if (property.Source is Object3D object3D)
|
if (property.Source is Object3D object3D)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
{
|
{
|
||||||
private Vector2 lastMousePosition = new Vector2(0, 0);
|
private Vector2 lastMousePosition = new Vector2(0, 0);
|
||||||
private Vector2 mouseDownPosition = new Vector2(0, 0);
|
private Vector2 mouseDownPosition = new Vector2(0, 0);
|
||||||
private double pinchStartScale = 1;
|
private Action<Vector2, double> scaleChanged;
|
||||||
private double startDistanceBetweenPoints = 1;
|
|
||||||
private ThemeConfig theme;
|
private ThemeConfig theme;
|
||||||
|
|
||||||
private Vector2 unscaledRenderOffset = new Vector2(0, 0);
|
private Vector2 unscaledRenderOffset = new Vector2(0, 0);
|
||||||
|
|
@ -53,7 +52,13 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
|
|
||||||
private VertexStorage vertexStorage;
|
private VertexStorage vertexStorage;
|
||||||
|
|
||||||
public PathEditorWidget(VertexStorage vertexStorage, UndoBuffer undoBuffer, ThemeConfig theme, Action vertexChanged)
|
public PathEditorWidget(VertexStorage vertexStorage,
|
||||||
|
UndoBuffer undoBuffer,
|
||||||
|
ThemeConfig theme,
|
||||||
|
Action vertexChanged,
|
||||||
|
Vector2 unscaledRenderOffset = default(Vector2),
|
||||||
|
double layerScale = 1,
|
||||||
|
Action<Vector2, double> scaleChanged = null)
|
||||||
{
|
{
|
||||||
HAnchor = HAnchor.Stretch;
|
HAnchor = HAnchor.Stretch;
|
||||||
BackgroundOutlineWidth = 1;
|
BackgroundOutlineWidth = 1;
|
||||||
|
|
@ -61,8 +66,13 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
BorderColor = theme.TextColor;
|
BorderColor = theme.TextColor;
|
||||||
Margin = 1;
|
Margin = 1;
|
||||||
|
|
||||||
|
this.unscaledRenderOffset = unscaledRenderOffset;
|
||||||
|
this.layerScale = layerScale;
|
||||||
|
|
||||||
var topToBottom = this;
|
var topToBottom = this;
|
||||||
|
|
||||||
|
this.scaleChanged = scaleChanged;
|
||||||
|
|
||||||
SizeChanged += (s, e) =>
|
SizeChanged += (s, e) =>
|
||||||
{
|
{
|
||||||
Height = Width / 2;
|
Height = Width / 2;
|
||||||
|
|
@ -99,59 +109,39 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnSizeChanged(EventArgs e)
|
|
||||||
{
|
|
||||||
base.OnSizeChanged(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ETransformState TransformState { get; set; }
|
public ETransformState TransformState { get; set; }
|
||||||
private double layerScale { get; set; } = 1;
|
private double layerScale { get; set; } = 1;
|
||||||
|
|
||||||
private Affine ScalingTransform => Affine.NewScaling(layerScale, layerScale);
|
private Affine ScalingTransform => Affine.NewScaling(layerScale, layerScale);
|
||||||
private Affine TotalTransform => Affine.NewTranslation(unscaledRenderOffset) * ScalingTransform * Affine.NewTranslation(Width / 2, Height / 2);
|
private Affine TotalTransform => Affine.NewTranslation(unscaledRenderOffset) * ScalingTransform * Affine.NewTranslation(Width / 2, Height / 2);
|
||||||
|
|
||||||
|
public override void OnDraw(Graphics2D graphics2D)
|
||||||
|
{
|
||||||
|
new VertexSourceApplyTransform(vertexStorage, TotalTransform).RenderCurve(graphics2D, theme.TextColor, 2, true, theme.PrimaryAccentColor.Blend(theme.TextColor, .5), theme.PrimaryAccentColor);
|
||||||
|
|
||||||
|
base.OnDraw(graphics2D);
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnMouseDown(MouseEventArgs mouseEvent)
|
public override void OnMouseDown(MouseEventArgs mouseEvent)
|
||||||
{
|
{
|
||||||
base.OnMouseDown(mouseEvent);
|
base.OnMouseDown(mouseEvent);
|
||||||
if (MouseCaptured)
|
if (MouseCaptured)
|
||||||
{
|
{
|
||||||
if (mouseEvent.NumPositions == 1)
|
mouseDownPosition.X = mouseEvent.X;
|
||||||
{
|
mouseDownPosition.Y = mouseEvent.Y;
|
||||||
mouseDownPosition.X = mouseEvent.X;
|
|
||||||
mouseDownPosition.Y = mouseEvent.Y;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Vector2 centerPosition = (mouseEvent.GetPosition(1) + mouseEvent.GetPosition(0)) / 2;
|
|
||||||
mouseDownPosition = centerPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastMousePosition = mouseDownPosition;
|
lastMousePosition = mouseDownPosition;
|
||||||
|
|
||||||
if (mouseEvent.NumPositions > 1)
|
|
||||||
{
|
|
||||||
startDistanceBetweenPoints = (mouseEvent.GetPosition(1) - mouseEvent.GetPosition(0)).Length;
|
|
||||||
pinchStartScale = layerScale;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnMouseMove(MouseEventArgs mouseEvent)
|
public override void OnMouseMove(MouseEventArgs mouseEvent)
|
||||||
{
|
{
|
||||||
base.OnMouseMove(mouseEvent);
|
base.OnMouseMove(mouseEvent);
|
||||||
Vector2 mousePos = new Vector2();
|
var mousePos = new Vector2(mouseEvent.X, mouseEvent.Y);
|
||||||
if (mouseEvent.NumPositions == 1)
|
|
||||||
{
|
|
||||||
mousePos = new Vector2(mouseEvent.X, mouseEvent.Y);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Vector2 centerPosition = (mouseEvent.GetPosition(1) + mouseEvent.GetPosition(0)) / 2;
|
|
||||||
mousePos = centerPosition;
|
|
||||||
}
|
|
||||||
if (MouseCaptured)
|
if (MouseCaptured)
|
||||||
{
|
{
|
||||||
Vector2 mouseDelta = mousePos - lastMousePosition;
|
var mouseDelta = mousePos - lastMousePosition;
|
||||||
switch (TransformState)
|
switch (TransformState)
|
||||||
{
|
{
|
||||||
case ETransformState.Scale:
|
case ETransformState.Scale:
|
||||||
|
|
@ -165,15 +155,16 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
zoomDelta = 1 + (1 * mouseDelta.Y / 100);
|
zoomDelta = 1 + (1 * mouseDelta.Y / 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 mousePreScale = mouseDownPosition;
|
var mousePreScale = mouseDownPosition;
|
||||||
TotalTransform.inverse_transform(ref mousePreScale);
|
TotalTransform.inverse_transform(ref mousePreScale);
|
||||||
|
|
||||||
layerScale *= zoomDelta;
|
layerScale *= zoomDelta;
|
||||||
|
|
||||||
Vector2 mousePostScale = mouseDownPosition;
|
var mousePostScale = mouseDownPosition;
|
||||||
TotalTransform.inverse_transform(ref mousePostScale);
|
TotalTransform.inverse_transform(ref mousePostScale);
|
||||||
|
|
||||||
unscaledRenderOffset += (mousePostScale - mousePreScale);
|
unscaledRenderOffset += (mousePostScale - mousePreScale);
|
||||||
|
scaleChanged?.Invoke(unscaledRenderOffset, layerScale);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ETransformState.Move:
|
case ETransformState.Move:
|
||||||
|
|
@ -181,23 +172,14 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
ScalingTransform.inverse_transform(ref mouseDelta);
|
ScalingTransform.inverse_transform(ref mouseDelta);
|
||||||
|
|
||||||
unscaledRenderOffset += mouseDelta;
|
unscaledRenderOffset += mouseDelta;
|
||||||
|
scaleChanged?.Invoke(unscaledRenderOffset, layerScale);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
lastMousePosition = mousePos;
|
lastMousePosition = mousePos;
|
||||||
|
|
||||||
// check if we should do some scaling
|
|
||||||
if (TransformState == ETransformState.Move
|
|
||||||
&& mouseEvent.NumPositions > 1
|
|
||||||
&& startDistanceBetweenPoints > 0)
|
|
||||||
{
|
|
||||||
double curDistanceBetweenPoints = (mouseEvent.GetPosition(1) - mouseEvent.GetPosition(0)).Length;
|
|
||||||
|
|
||||||
double scaleAmount = pinchStartScale * curDistanceBetweenPoints / startDistanceBetweenPoints;
|
|
||||||
ScalePartAndFixPosition(mouseEvent, scaleAmount);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnMouseWheel(MouseEventArgs mouseEvent)
|
public override void OnMouseWheel(MouseEventArgs mouseEvent)
|
||||||
|
|
@ -210,19 +192,12 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
|
|
||||||
ScalePartAndFixPosition(mouseEvent, layerScale + layerScale * scaleAmount);
|
ScalePartAndFixPosition(mouseEvent, layerScale + layerScale * scaleAmount);
|
||||||
|
|
||||||
mouseEvent.Handled = true;
|
mouseEvent.WheelDelta = 0;
|
||||||
|
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDraw(Graphics2D graphics2D)
|
|
||||||
{
|
|
||||||
new VertexSourceApplyTransform(vertexStorage, TotalTransform).RenderCurve(graphics2D, theme.TextColor, 2, true, theme.PrimaryAccentColor.Blend(theme.TextColor, .5), theme.PrimaryAccentColor);
|
|
||||||
|
|
||||||
base.OnDraw(graphics2D);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Zoom(double scaleAmount)
|
public void Zoom(double scaleAmount)
|
||||||
{
|
{
|
||||||
ScalePartAndFixPosition(new MouseEventArgs(MouseButtons.None, 0, Width / 2, Height / 2, 0), layerScale * scaleAmount);
|
ScalePartAndFixPosition(new MouseEventArgs(MouseButtons.None, 0, Width / 2, Height / 2, 0), layerScale * scaleAmount);
|
||||||
|
|
@ -231,15 +206,17 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
|
|
||||||
private void ScalePartAndFixPosition(MouseEventArgs mouseEvent, double scaleAmount)
|
private void ScalePartAndFixPosition(MouseEventArgs mouseEvent, double scaleAmount)
|
||||||
{
|
{
|
||||||
Vector2 mousePreScale = new Vector2(mouseEvent.X, mouseEvent.Y);
|
var mousePreScale = new Vector2(mouseEvent.X, mouseEvent.Y);
|
||||||
TotalTransform.inverse_transform(ref mousePreScale);
|
TotalTransform.inverse_transform(ref mousePreScale);
|
||||||
|
|
||||||
layerScale = scaleAmount;
|
layerScale = scaleAmount;
|
||||||
|
|
||||||
Vector2 mousePostScale = new Vector2(mouseEvent.X, mouseEvent.Y);
|
var mousePostScale = new Vector2(mouseEvent.X, mouseEvent.Y);
|
||||||
TotalTransform.inverse_transform(ref mousePostScale);
|
TotalTransform.inverse_transform(ref mousePostScale);
|
||||||
|
|
||||||
unscaledRenderOffset += (mousePostScale - mousePreScale);
|
unscaledRenderOffset += (mousePostScale - mousePreScale);
|
||||||
|
|
||||||
|
scaleChanged?.Invoke(unscaledRenderOffset, layerScale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -51,22 +51,17 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
{
|
{
|
||||||
public class RadialPinchObject3D : OperationSourceContainerObject3D, IPropertyGridModifier, IEditorDraw
|
public class RadialPinchObject3D : OperationSourceContainerObject3D, IPropertyGridModifier, IEditorDraw
|
||||||
{
|
{
|
||||||
public class EditableVertexStorage : VertexStorage
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public RadialPinchObject3D()
|
public RadialPinchObject3D()
|
||||||
{
|
{
|
||||||
// make sure the path editor is registered
|
// make sure the path editor is registered
|
||||||
PropertyEditor.RegisterEditor(typeof(EditableVertexStorage), new PathEditorFactory());
|
PropertyEditor.RegisterEditor(typeof(PathEditorFactory.EditableVertexStorage), new PathEditorFactory());
|
||||||
|
|
||||||
Name = "Radial Pinch".Localize();
|
Name = "Radial Pinch".Localize();
|
||||||
}
|
}
|
||||||
|
|
||||||
[PathEditorFactory.TopAndBottomMoveXOnly]
|
[PathEditorFactory.TopAndBottomMoveXOnly]
|
||||||
[PathEditorFactory.XMustBeGreaterThan0]
|
[PathEditorFactory.XMustBeGreaterThan0]
|
||||||
public EditableVertexStorage PathForHorizontalOffsets { get; set; } = new EditableVertexStorage();
|
public PathEditorFactory.EditableVertexStorage PathForHorizontalOffsets { get; set; } = new PathEditorFactory.EditableVertexStorage();
|
||||||
|
|
||||||
[Description("Specifies the number of vertical cuts required to ensure the part can be pinched well.")]
|
[Description("Specifies the number of vertical cuts required to ensure the part can be pinched well.")]
|
||||||
[Slider(0, 50, snapDistance: 1)]
|
[Slider(0, 50, snapDistance: 1)]
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit b2e6f9c711ef750f4bc94b78e6ed0693315bd422
|
Subproject commit cd0eb8ef745dd76c97fff3080639207079a60a76
|
||||||
Loading…
Add table
Add a link
Reference in a new issue