remember editor zoom and position

This commit is contained in:
Lars Brubaker 2023-11-03 21:45:39 -07:00
parent 17107dbf14
commit 7f9cab6963
4 changed files with 58 additions and 68 deletions

View file

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

View file

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

View file

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