/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, float transformedDeltaX, float transformedDeltaY, float sin, float cos, ResizeModifiers modifiers) { int idx = GetControlPointIndex(pointId); Debug.Assert(idx >= 0); int oldPosX, oldPosY; Geometry.CalcPolygonBalancePoint(shapePoints, out oldPosX, out oldPosY); shapePoints[idx].X += (int)Math.Round(transformedDeltaX); shapePoints[idx].Y += (int)Math.Round(transformedDeltaY); int newPosX, newPosY; Geometry.CalcPolygonBalancePoint(shapePoints, out newPosX, out newPosY); // Update (relative) vertex positions before moving the shape to the new balance point int dX = newPosX - oldPosX; int dY = newPosY - oldPosY; for (int i = shapePoints.Length - 1; i >= 0; --i) { shapePoints[i].X -= dX; shapePoints[i].Y -= dY; } MoveByCore((int)Math.Round((dX * cos) - (dY * sin)), (int)Math.Round((dX * sin) + (dY * cos))); return(true); }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, int origDeltaX, int origDeltaY, ResizeModifiers modifiers) { if (pointId == GlueControlPoint) { bool result = false; // If the glue ponit is connected, recalculate glue point calculation info ShapeConnectionInfo ci = GetConnectionInfo(GlueControlPoint, null); if (ci.IsEmpty) { // If the glue point is not connected, move the glue point to the desired position if (Geometry.IsValid(gluePointPos)) { gluePointPos.X += origDeltaX; gluePointPos.Y += origDeltaY; InvalidateDrawCache(); result = true; } } else { if (ci.OtherPointId != ControlPointId.Reference) { CalcGluePoint(GlueControlPoint, ci.OtherShape); } } return(result); } else { return(base.MovePointByCore(pointId, origDeltaX, origDeltaY, modifiers)); } }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, float transformedDeltaX, float transformedDeltaY, float sin, float cos, ResizeModifiers modifiers) { int idx = GetControlPointIndex(pointId); Debug.Assert(idx >= 0); // Normalize the movement to the first vector float segmentAngle = 360 / (float)pointCount; float ptAngle = (pointId - 1) * segmentAngle; float normalizedDeltaX = transformedDeltaX; float normalizedDeltaY = transformedDeltaY; Geometry.RotatePoint(0, 0, -ptAngle, ref normalizedDeltaX, ref normalizedDeltaY); //int tmpY = (int)diameter + 100; //Point p = Geometry.GetNearestPoint(0, tmpY, Geometry.IntersectPolygonLine(shapePoints, 0, 0, 0, tmpY, false)); //float dist = diameter - Geometry.DistancePointPoint(0, 0, p.X, p.Y); //float movementCorrectionFactor = (float)Math.Round(Geometry.DistancePointPoint(0, 0, p.X, p.Y) / diameter, 1); float dx = 0; float dy = (normalizedDeltaY / 2); // * movementCorrectionFactor; diameter = (int)Math.Round(diameter - (normalizedDeltaY - dy)); UpdateShapePoints(); // Update shape position Geometry.RotatePoint(0, 0, ptAngle, ref dx, ref dy); MoveByCore((int)Math.Round((dx * cos) - (dy * sin)), (int)Math.Round((dx * sin) + (dy * cos))); return(normalizedDeltaX == 0); }
public static bool TransformMouseMovement(int deltaX, int deltaY, int angleTenthsOfDeg, ResizeModifiers modifiers, int divFactorX, int divFactorY, out float transformedDeltaX, out float transformedDeltaY, out float sin, out float cos) { TransformMouseMovement(deltaX, deltaY, angleTenthsOfDeg, out transformedDeltaX, out transformedDeltaY, out sin, out cos); return AlignMovement(modifiers, divFactorX, divFactorY, ref transformedDeltaX, ref transformedDeltaY); }
/// <summary> /// Moves the TopRight corner of a (rotated) rectangle in order to resize it /// </summary> /// <param name="width">Width of the rectangle</param> /// <param name="height">Height of the rectangle</param> /// <param name="deltaX">Movement on X axis</param> /// <param name="deltaY">Movement on Y axis</param> /// <param name="cosAngle">Cosinus value of the rectangle's rotation angle</param> /// <param name="sinAngle">Sinus value of the rectangle's rotation angle</param> /// <param name="modifiers">Movement modifiers</param> /// <param name="centerOffsetX">Specifies the movement the rectangle's center has to perform for resizing</param> /// <param name="centerOffsetY">Specifies the movement the rectangle's center has to perform for resizing</param> /// <param name="newWidth">New width of the rectangle</param> /// <param name="newHeight">New height of the rectangle</param> /// <returns>Returns true if the movement could be performed as desired. /// Returns false if the movement could not be performed completely because of movement restrictions</returns> public static bool MoveRectangleTopRight(int width, int height, float deltaX, float deltaY, float cosAngle, float sinAngle, ResizeModifiers modifiers, out int centerOffsetX, out int centerOffsetY, out int newWidth, out int newHeight) { int minWidth = 0, minHeight = 0; GetMinValues(width, height, modifiers, out minWidth, out minHeight); return MoveRectangleTopRight(width, height, minWidth, minHeight, 0.5f, 0.5f, 2, 2, deltaX, deltaY, cosAngle, sinAngle, modifiers, out centerOffsetX, out centerOffsetY, out newWidth, out newHeight); }
/// <summary> /// Moves the right side of a (rotated) rectangle in order to resize it /// </summary> /// <param name="width">Width of the rectangle</param> /// <param name="height">Height of the rectangle</param> /// <param name="minValueX">Specifies the minimum width.</param> /// <param name="centerPosFactorX">Specifies where the center is located. Default value is 50% = 0.5</param> /// <param name="centerPosFactorY">Specifies where the center is located. Default value is 50% = 0.5</param> /// <param name="divFactorX">Specifies the factor through which the corrected and modified movement must be dividable without remainding.</param> /// <param name="divFactorY">Specifies the factor through which the corrected and modified movement must be dividable without remainding.</param> /// <param name="deltaX">Movement on X axis</param> /// <param name="deltaY">Movement on Y axis</param> /// <param name="cosAngle">Cosinus value of the rectangle's rotation angle</param> /// <param name="sinAngle">Sinus value of the rectangle's rotation angle</param> /// <param name="modifiers">Movement modifiers</param> /// <param name="centerOffsetX">Specifies the movement the rectangle's center has to perform for resizing</param> /// <param name="centerOffsetY">Specifies the movement the rectangle's center has to perform for resizing</param> /// <param name="newWidth">New width of the rectangle</param> /// <param name="newHeight">New height of the rectangle</param> /// <returns>Returns true if the movement could be performed as desired. /// Returns false if the movement could not be performed completely because of movement restrictions</returns> public static bool MoveRectangleRight(int width, int height, int minValueX, float centerPosFactorX, float centerPosFactorY, int divFactorX, int divFactorY, float deltaX, float deltaY, double cosAngle, double sinAngle, ResizeModifiers modifiers, out int centerOffsetX, out int centerOffsetY, out int newWidth, out int newHeight) { bool result = true; centerOffsetX = centerOffsetY = 0; newWidth = width; newHeight = height; // Aspect maintainence can be combined with both MirroredResizing and normal resizing if ((modifiers & ResizeModifiers.MaintainAspect) != 0) { //MaintainAspectRatio(newWidth, height, 1, -1, ref deltaX, ref deltaY); float aspectRatio = width / (float)height; deltaY = -deltaX / aspectRatio; } // Align to integer coordinates Geometry.AlignMovement(modifiers, divFactorX, divFactorY, ref deltaX, ref deltaY); if ((modifiers & ResizeModifiers.MirroredResize) != 0) { if (newWidth + deltaX + deltaX >= minValueX) newWidth += (int)Math.Round(deltaX + deltaX); else { newWidth = minValueX; result = false; } } else { if (newWidth + deltaX >= minValueX) newWidth += (int)Math.Round(deltaX); else { deltaX = minValueX - newWidth; newWidth = minValueX; result = false; } centerOffsetX = (int)Math.Round(deltaX * centerPosFactorX * cosAngle); centerOffsetY = (int)Math.Round(deltaX * centerPosFactorX * sinAngle); } if ((modifiers & ResizeModifiers.MaintainAspect) != 0) newHeight = (int)Math.Round(newWidth / (width / (float)height)); return result; }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, int deltaX, int deltaY, ResizeModifiers modifiers) { if (deltaX == 0 && deltaY == 0) { return(true); } Rectangle boundsBefore = Rectangle.Empty; if ((modifiers & ResizeModifiers.MaintainAspect) == ResizeModifiers.MaintainAspect) { boundsBefore = GetBoundingRectangle(true); } int vertexIdx = GetControlPointIndex(pointId); Point p = vertices[vertexIdx]; p.Offset(deltaX, deltaY); vertices[vertexIdx] = p; // Scale line if MaintainAspect flag is set and start- or endpoint was moved if ((modifiers & ResizeModifiers.MaintainAspect) == ResizeModifiers.MaintainAspect && (IsFirstVertex(pointId) || IsLastVertex(pointId))) { // ToDo: Improve maintaining aspect of polylines if (deltaX != 0 || deltaY != 0) { int dx = (int)Math.Round(deltaX / (float)(VertexCount - 1)); int dy = (int)Math.Round(deltaY / (float)(VertexCount - 1)); // The first and the last points are glue points, so move only the points between for (int i = VertexCount - 2; i > 0; --i) { p = vertices[i]; p.Offset(dx, dy); vertices[i] = p; } // After moving the vertices between the first and the last vertex, // we have to maintain the glue point positions again MaintainGluePointPosition(ControlPointId.LastVertex, GetPreviousVertexId(ControlPointId.LastVertex)); MaintainGluePointPosition(ControlPointId.FirstVertex, GetNextVertexId(ControlPointId.FirstVertex)); } } else { // Maintain glue point positions (if connected via "Point-To-Shape" MaintainGluePointPosition(ControlPointId.FirstVertex, pointId); MaintainGluePointPosition(ControlPointId.LastVertex, pointId); } return(true); }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, int deltaX, int deltaY, ResizeModifiers modifiers) { float transformedDeltaX, transformedDeltaY, sin, cos; bool result = Geometry.TransformMouseMovement(deltaX, deltaY, Angle, modifiers, DivFactorX, DivFactorY, out transformedDeltaX, out transformedDeltaY, out sin, out cos); if (!MovePointByCore(pointId, transformedDeltaX, transformedDeltaY, sin, cos, modifiers)) { result = false; } return(result); }
/// <summary> /// Moves the given control point to the indicated coordinates if possible. /// </summary> /// <param name="pointId"></param> /// <param name="toX"></param> /// <param name="toY"></param> /// <param name="modifiers"></param> /// <returns>True, if the control point could be moved, else false.</returns> public bool MoveControlPointTo(ControlPointId pointId, int toX, int toY, ResizeModifiers modifiers) { Point ptPos = GetControlPointPosition(pointId); return(MoveControlPointBy(pointId, toX - ptPos.X, toY - ptPos.Y, modifiers)); }
public static bool MoveSquareTopLeft(int size, float deltaX, float deltaY, float cosAngle, float sinAngle, ResizeModifiers modifiers, out int centerOffsetX, out int centerOffsetY, out int newSize) { return MoveSquareTopLeft(size, 0, 0.5f, 0.5f, deltaX, deltaY, cosAngle, sinAngle, modifiers, out centerOffsetX, out centerOffsetY, out newSize); }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, float transformedDeltaX, float transformedDeltaY, float sin, float cos, ResizeModifiers modifiers) { bool result = true; int dx = 0, dy = 0; int width = Width; int height = Height; switch ((int)pointId) { case ControlPointIds.TopCenterControlPoint: result = (transformedDeltaX == 0); if (!Geometry.MoveRectangleTop(width, height, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out width, out height)) { result = false; } break; case ControlPointIds.MiddleLeftControlPoint: result = (transformedDeltaY == 0); if (!Geometry.MoveRectangleLeft(width, height, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out width, out height)) { result = false; } break; case ControlPointIds.MiddleRightControlPoint: result = (transformedDeltaY == 0); if (!Geometry.MoveRectangleRight(width, height, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out width, out height)) { result = false; } break; case ControlPointIds.BottomCenterControlPoint: result = (transformedDeltaX == 0); if (!Geometry.MoveRectangleBottom(width, height, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out width, out height)) { result = false; } break; default: break; } if (result) { Width = width; Height = height; X += dx; Y += dy; } ControlPointsHaveMoved(); return(result); }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, float transformedDeltaX, float transformedDeltaY, float sin, float cos, ResizeModifiers modifiers) { int idx = GetControlPointIndex(pointId); Debug.Assert(idx >= 0); // Normalize the movement to the first vector float segmentAngle = 360 / (float)pointCount; float ptAngle = (pointId - 1) * segmentAngle; float normalizedDeltaX= transformedDeltaX; float normalizedDeltaY = transformedDeltaY; Geometry.RotatePoint(0, 0, -ptAngle, ref normalizedDeltaX, ref normalizedDeltaY); //int tmpY = (int)diameter + 100; //Point p = Geometry.GetNearestPoint(0, tmpY, Geometry.IntersectPolygonLine(shapePoints, 0, 0, 0, tmpY, false)); //float dist = diameter - Geometry.DistancePointPoint(0, 0, p.X, p.Y); //float movementCorrectionFactor = (float)Math.Round(Geometry.DistancePointPoint(0, 0, p.X, p.Y) / diameter, 1); float dx = 0; float dy = (normalizedDeltaY / 2); // * movementCorrectionFactor; diameter = (int)Math.Round(diameter - (normalizedDeltaY - dy)); UpdateShapePoints(); // Update shape position Geometry.RotatePoint(0, 0, ptAngle, ref dx, ref dy); MoveByCore((int)Math.Round((dx * cos) - (dy * sin)), (int)Math.Round((dx * sin) + (dy * cos))); return (normalizedDeltaX == 0); }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, int deltaX, int deltaY, ResizeModifiers modifiers) { bool result; if (pointId == ControlPointId.Reference || pointId == 2) result = MoveByCore(deltaX, deltaY); else { int oldX = x, oldY = y, oldW = w, oldH = h; int newX, newY, newW, newH; switch (pointId) { case 1: newX = x; newY = y; newW = oldW - deltaX; newH = oldH - deltaY; if (newW <= newH) newH = int.MaxValue; else newW = int.MaxValue; if (newW < minW) { newW = minW; newH = int.MaxValue; } else if (newH < minH) { newH = minH; newW = int.MaxValue; } if (newW == int.MaxValue) newW = newH*image.Width/image.Height; if (newH == int.MaxValue) newH = newW*image.Height/image.Width + ch; result = false; break; case 8: newH = oldH + deltaY; if (newH < minH) newH = minH; newW = (newH - ch)*image.Width/image.Height; if (newW < minW) { newW = minW; newH = newW*image.Height/image.Width + ch; } newX = oldX; newY = oldY - oldH/2 + newH/2; result = false; break; default: newW = w; newH = h; newX = x; newY = y; result = true; break; } x = newX; y = newY; w = newW; h = newH; captionUpdated = false; } return result; }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, float transformedDeltaX, float transformedDeltaY, float sin, float cos, ResizeModifiers modifiers) { bool result = true; int dx = 0, dy = 0; int size = DiameterInternal; int hSize = size, vSize = size; switch (pointId) { #region TopLeft case TopLeftControlPoint: if (Math.Abs(transformedDeltaX) > Math.Abs(transformedDeltaY)) { transformedDeltaY = transformedDeltaX; } else { transformedDeltaX = transformedDeltaY; } if (!Geometry.MoveRectangleTopLeft(size, size, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) { result = false; } size = Math.Min(hSize, vSize); break; #endregion #region TopCenter case TopCenterControlPoint: if (!Geometry.MoveRectangleTop(size, size, 0, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) { result = false; } size = vSize; break; #endregion #region TopRight case TopRightControlPoint: if (Math.Abs(transformedDeltaX) > Math.Abs(transformedDeltaY)) { transformedDeltaY = -transformedDeltaX; } else { transformedDeltaX = -transformedDeltaY; } if (!Geometry.MoveRectangleTopRight(size, size, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) { result = false; } size = Math.Min(hSize, vSize); break; #endregion #region Middle left case MiddleLeftControlPoint: if (!Geometry.MoveRectangleLeft(size, size, transformedDeltaX, 0, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) { result = false; } size = hSize; break; #endregion #region Middle right case MiddleRightControlPoint: if (!Geometry.MoveRectangleRight(size, size, transformedDeltaX, 0, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) { result = false; } size = hSize; break; #endregion #region Bottom left case BottomLeftControlPoint: if (Math.Abs(transformedDeltaX) > Math.Abs(transformedDeltaY)) { transformedDeltaY = -transformedDeltaX; } else { transformedDeltaX = -transformedDeltaY; } if (!Geometry.MoveRectangleBottomLeft(size, size, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) { result = false; } size = Math.Min(hSize, vSize); break; #endregion #region Bottom Center case BottomCenterControlPoint: if (!Geometry.MoveRectangleBottom(size, size, 0, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) { result = false; } size = vSize; break; #endregion #region Bottom right case BottomRightControlPoint: if (Math.Abs(transformedDeltaX) > Math.Abs(transformedDeltaY)) { transformedDeltaY = transformedDeltaX; } else { transformedDeltaX = transformedDeltaY; } if (!Geometry.MoveRectangleBottomRight(size, size, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) { result = false; } size = Math.Min(hSize, vSize); break; #endregion } // Perform Resizing DiameterInternal = size; MoveByCore(dx, dy); ControlPointsHaveMoved(); return(result); }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, int deltaX, int deltaY, ResizeModifiers modifiers) { if (deltaX == 0 && deltaY == 0) return true; Rectangle boundsBefore = Rectangle.Empty; if ((modifiers & ResizeModifiers.MaintainAspect) == ResizeModifiers.MaintainAspect) boundsBefore = GetBoundingRectangle(true); int vertexIdx = GetControlPointIndex(pointId); Point p = vertices[vertexIdx]; p.Offset(deltaX, deltaY); vertices[vertexIdx] = p; // Scale line if MaintainAspect flag is set and start- or endpoint was moved if ((modifiers & ResizeModifiers.MaintainAspect) == ResizeModifiers.MaintainAspect && (IsFirstVertex(pointId) || IsLastVertex(pointId))) { // ToDo: Improve maintaining aspect of polylines if (deltaX != 0 || deltaY != 0) { int dx = (int)Math.Round(deltaX / (float)(VertexCount - 1)); int dy = (int)Math.Round(deltaY / (float)(VertexCount - 1)); // The first and the last points are glue points, so move only the points between for (int i = VertexCount - 2; i > 0; --i) { p = vertices[i]; p.Offset(dx, dy); vertices[i] = p; } // After moving the vertices between the first and the last vertex, // we have to maintain the glue point positions again MaintainGluePointPosition(ControlPointId.LastVertex, GetPreviousVertexId(ControlPointId.LastVertex)); MaintainGluePointPosition(ControlPointId.FirstVertex, GetNextVertexId(ControlPointId.FirstVertex)); } } else { // Maintain glue point positions (if connected via "Point-To-Shape" MaintainGluePointPosition(ControlPointId.FirstVertex, pointId); MaintainGluePointPosition(ControlPointId.LastVertex, pointId); } return true; }
public static bool MoveSquareTopLeft(int size, int minValue, float centerPosFactorX, float centerPosFactorY, float deltaX, float deltaY, float cosAngle, float sinAngle, ResizeModifiers modifiers, out int centerOffsetX, out int centerOffsetY, out int newSize) { bool result = true; centerOffsetX = centerOffsetY = 0; newSize = size; MaintainAspectRatio(size, size, size - deltaX, size - deltaY, ref deltaX, ref deltaY); float delta = deltaX; if ((modifiers & ResizeModifiers.MirroredResize) != 0) { if (newSize - delta - delta >= minValue) newSize -= (int)Math.Round(delta + delta); else { newSize = minValue; result = false; } } else { if (newSize - delta >= minValue) { newSize -= (int)Math.Round(delta); } else { delta = newSize; newSize = minValue; result = false; } centerOffsetX = (int)Math.Round((delta * centerPosFactorX * cosAngle) - (delta * (1 - centerPosFactorY) * sinAngle)); centerOffsetY = (int)Math.Round((delta * centerPosFactorX * sinAngle) + (delta * (1 - centerPosFactorY) * cosAngle)); } return result; }
/// <summary> /// Aligns the (transformed) movement to pixels in order to ensure that the shape or its control points are moved to full integer coordinates. /// Returns false if the movement was modified. /// </summary> /// <param name="modifiers">Movement/Resizing modifiers</param> /// <param name="divFactorX">Ensures that transformedDeltaX is dividable by this factor without remainder</param> /// <param name="divFactorY">Ensures that transformedDeltaY is dividable by this factor without remainder</param> /// <param name="deltaX">Mouse movement on X axis</param> /// <param name="deltaY">Mouse movement on Y axis</param> public static bool AlignMovement(ResizeModifiers modifiers, int divFactorX, int divFactorY, ref float deltaX, ref float deltaY) { bool result = true; // Ensure that the mouse movement will be devidable without remainder // when *not* resizing in both directions if ((modifiers & ResizeModifiers.MirroredResize) == 0) { if (deltaX % divFactorX != 0) { deltaX -= deltaX % divFactorX; result = false; } if (deltaY % divFactorY != 0) { deltaY -= deltaY % divFactorY; result = false; } } return result; }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, float transformedDeltaX, float transformedDeltaY, float sin, float cos, ResizeModifiers modifiers) { int idx = GetControlPointIndex(pointId); Debug.Assert(idx >= 0); // Normalize the movement to the first vector float segmentAngle = 360 / (float)pointCount; float ptAngle = (pointId - 1) * segmentAngle; float normalizedDeltaX= transformedDeltaX; float normalizedDeltaY = transformedDeltaY; Geometry.RotatePoint(0, 0, -ptAngle, ref normalizedDeltaX, ref normalizedDeltaY); float dx = 0; float dy = (normalizedDeltaY / 2); diameter = (int)Math.Round(diameter - (normalizedDeltaY - dy)); UpdateShapePoints(); // Update shape position Geometry.RotatePoint(0, 0, ptAngle, ref dx, ref dy); MoveByCore((int)Math.Round((dx * cos) - (dy * sin)), (int)Math.Round((dx * sin) + (dy * cos))); return (normalizedDeltaX == 0); }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, float transformedDeltaX, float transformedDeltaY, float sin, float cos, ResizeModifiers modifiers) { bool result = true; int dx = 0, dy = 0; int width = size.Width; int height = size.Height; int newWidth = -1, newHeight = -1; switch (pointId) { case TopLeftControlPoint: if ( !Geometry.MoveRectangleTopLeft(width, height, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out newWidth, out newHeight)) result = false; break; case TopCenterControlPoint: result = (transformedDeltaX == 0); if ( !Geometry.MoveRectangleTop(width, height, 0, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out newWidth, out newHeight)) result = false; break; case TopRightControlPoint: if ( !Geometry.MoveRectangleTopRight(width, height, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out newWidth, out newHeight)) result = false; break; case MiddleLeftControlPoint: result = (transformedDeltaY == 0); if ( !Geometry.MoveRectangleLeft(width, height, transformedDeltaX, 0, cos, sin, modifiers, out dx, out dy, out newWidth, out newHeight)) result = false; break; case MiddleRightControlPoint: result = (transformedDeltaY == 0); if ( !Geometry.MoveRectangleRight(width, height, transformedDeltaX, 0, cos, sin, modifiers, out dx, out dy, out newWidth, out newHeight)) result = false; break; case BottomLeftControlPoint: if ( !Geometry.MoveRectangleBottomLeft(width, height, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out newWidth, out newHeight)) result = false; break; case BottomCenterControlPoint: result = (transformedDeltaX == 0); if ( !Geometry.MoveRectangleBottom(width, height, 0, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out newWidth, out newHeight)) result = false; break; case BottomRightControlPoint: if ( !Geometry.MoveRectangleBottomRight(width, height, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out newWidth, out newHeight)) result = false; break; default: throw new IndexOutOfRangeException(); } System.Diagnostics.Debug.Assert(newWidth >= 0 && newHeight >= 0); // Perform Resizing size.Width = newWidth; size.Height = newHeight; MoveByCore(dx, dy); return result; }
/// <override></override> public override bool MoveControlPointBy(ControlPointId pointId, int deltaX, int deltaY, ResizeModifiers modifiers) { bool result = false; if (pointId == ControlPointId.Reference) { result = MoveBy(deltaX, deltaY); } else { if (Owner != null) { Owner.NotifyChildResizing(this); } result = false; if (Owner != null) { Owner.NotifyChildResized(this); } } return(result); }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, float transformedDeltaX, float transformedDeltaY, float sin, float cos, ResizeModifiers modifiers) { int idx = GetControlPointIndex(pointId); Debug.Assert(idx >= 0); // Normalize the movement to the first vector float segmentAngle = 360 / (float)pointCount; float ptAngle = (pointId - 1) * segmentAngle; float normalizedDeltaX = transformedDeltaX; float normalizedDeltaY = transformedDeltaY; Geometry.RotatePoint(0, 0, -ptAngle, ref normalizedDeltaX, ref normalizedDeltaY); float dx = 0; float dy = (normalizedDeltaY / 2); diameter = (int)Math.Round(diameter - (normalizedDeltaY - dy)); UpdateShapePoints(); // Update shape position Geometry.RotatePoint(0, 0, ptAngle, ref dx, ref dy); MoveByCore((int)Math.Round((dx * cos) - (dy * sin)), (int)Math.Round((dx * sin) + (dy * cos))); return(normalizedDeltaX == 0); }
/// <summary>Overriden method. Check base class for documentation.</summary> protected override bool MovePointByCore(ControlPointId pointId, int deltaX, int deltaY, ResizeModifiers modifiers) { int idx = GetControlPointIndex(pointId); GetControlPoint(idx).Offset(deltaX, deltaY); return true; }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, int deltaX, int deltaY, ResizeModifiers modifiers) { float transformedDeltaX, transformedDeltaY, sin, cos; Geometry.TransformMouseMovement(deltaX, deltaY, Angle, out transformedDeltaX, out transformedDeltaY, out sin, out cos); return(MovePointByCore(pointId, transformedDeltaX, transformedDeltaY, sin, cos, modifiers)); }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, float transformedDeltaX, float transformedDeltaY, float sin, float cos, ResizeModifiers modifiers) { bool result = true; int dx = 0, dy = 0; int width = Width; int height = Height; switch ((int)pointId) { case ControlPointIds.TopLeftControlPoint: if (!Geometry.MoveRectangleTopLeft(width, height, 0, 0, CenterPosFactorX, CenterPosFactorY, DivFactorX, DivFactorY, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out width, out height)) { result = false; } break; case ControlPointIds.TopCenterControlPoint: result = (transformedDeltaX == 0); if (!Geometry.MoveRectangleTop(width, height, 0, CenterPosFactorX, CenterPosFactorY, DivFactorX, DivFactorY, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out width, out height)) { result = false; } break; case ControlPointIds.TopRightControlPoint: if (!Geometry.MoveRectangleTopRight(width, height, 0, 0, CenterPosFactorX, CenterPosFactorY, DivFactorX, DivFactorY, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out width, out height)) { result = false; } break; case ControlPointIds.BottomCenterControlPoint: result = (transformedDeltaX == 0); if (!Geometry.MoveRectangleBottom(width, height, 0, CenterPosFactorX, CenterPosFactorY, DivFactorX, DivFactorY, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out width, out height)) { result = false; } break; default: break; } if (Width != width || Height != height || dx != 0 || dy != 0) { Width = width; Height = height; MoveByCore(dx, dy); ControlPointsHaveMoved(); } return(result); }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, float transformedDeltaX, float transformedDeltaY, float sin, float cos, ResizeModifiers modifiers) { bool result = true; int dx = 0, dy = 0; int size = DiameterInternal; int hSize = size, vSize = size; switch (pointId) { #region TopLeft case TopLeftControlPoint: if (Math.Abs(transformedDeltaX) > Math.Abs(transformedDeltaY)) transformedDeltaY = transformedDeltaX; else transformedDeltaX = transformedDeltaY; if (!Geometry.MoveRectangleTopLeft(size, size, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) result = false; size = Math.Min(hSize, vSize); break; #endregion #region TopCenter case TopCenterControlPoint: if (!Geometry.MoveRectangleTop(size, size, 0, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) result = false; size = vSize; break; #endregion #region TopRight case TopRightControlPoint: if (Math.Abs(transformedDeltaX) > Math.Abs(transformedDeltaY)) transformedDeltaY = -transformedDeltaX; else transformedDeltaX = -transformedDeltaY; if (!Geometry.MoveRectangleTopRight(size, size, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) result = false; size = Math.Min(hSize, vSize); break; #endregion #region Middle left case MiddleLeftControlPoint: if (!Geometry.MoveRectangleLeft(size, size, transformedDeltaX, 0, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) result = false; size = hSize; break; #endregion #region Middle right case MiddleRightControlPoint: if (!Geometry.MoveRectangleRight(size, size, transformedDeltaX, 0, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) result = false; size = hSize; break; #endregion #region Bottom left case BottomLeftControlPoint: if (Math.Abs(transformedDeltaX) > Math.Abs(transformedDeltaY)) transformedDeltaY = -transformedDeltaX; else transformedDeltaX = -transformedDeltaY; if (!Geometry.MoveRectangleBottomLeft(size, size, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) result = false; size = Math.Min(hSize, vSize); break; #endregion #region Bottom Center case BottomCenterControlPoint: if (!Geometry.MoveRectangleBottom(size, size, 0, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) result = false; size = vSize; break; #endregion #region Bottom right case BottomRightControlPoint: if (Math.Abs(transformedDeltaX) > Math.Abs(transformedDeltaY)) transformedDeltaY = transformedDeltaX; else transformedDeltaX = transformedDeltaY; if (!Geometry.MoveRectangleBottomRight(size, size, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) result = false; size = Math.Min(hSize, vSize); break; #endregion } // Perform Resizing DiameterInternal = size; MoveByCore(dx, dy); ControlPointsHaveMoved(); return result; }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, int deltaX, int deltaY, ResizeModifiers modifiers) { int pointIndex = GetControlPointIndex(pointId); float radiusPtAngle = 0; //float lerpFactor = float.NaN, radiusPtDistance = float.NaN; bool maintainAspect = false; ControlPointId otherGluePtId = ControlPointId.None; ControlPointId nextPtId = ControlPointId.None; if ((modifiers & ResizeModifiers.MaintainAspect) == ResizeModifiers.MaintainAspect && (IsFirstVertex(pointId) || IsLastVertex(pointId))) { maintainAspect = true; // Get opposite glue point and the glue point next to the moved glue point // (may be identical to the opposite glue point) if (IsFirstVertex(pointId)) { otherGluePtId = ControlPointId.LastVertex; nextPtId = GetPreviousVertexId(otherGluePtId); } else { otherGluePtId = ControlPointId.FirstVertex; nextPtId = GetNextVertexId(otherGluePtId); } // Calculate the original angle for later use radiusPtAngle = Geometry.RadiansToDegrees(Geometry.Angle( GetControlPointPosition(pointId), GetControlPointPosition(otherGluePtId), GetControlPointPosition(nextPtId))); //PointF tmpPt = Geometry.IntersectLines(StartPoint.X, StartPoint.Y, EndPoint.X, EndPoint.Y, Center.X, Center.Y, RadiusPoint.X, RadiusPoint.Y); //lerpFactor = (Geometry.DistancePointPoint(StartPoint, tmpPt) / Geometry.DistancePointPoint(StartPoint, EndPoint)); //radiusPtDistance = Geometry.DistancePointLine(RadiusPoint, StartPoint, EndPoint, true); //radiusPtAngle = Geometry.RadiansToDegrees(Geometry.Angle(tmpPt, RadiusPoint)); } // Assign new position to vertex Point p = vertices[pointIndex]; p.Offset(deltaX, deltaY); vertices[pointIndex] = p; if (maintainAspect) { if (IsLine) { MaintainGluePointPosition(otherGluePtId, nextPtId); if (VertexCount > 2) vertices[1] = Geometry.VectorLinearInterpolation(StartPoint, EndPoint, 0.5f); } else { //PointF newPos = Geometry.VectorLinearInterpolation(StartPoint, EndPoint, lerpFactor); //newPos = Geometry.RotatePoint(newPos.X, newPos.Y, radiusPtAngle, newPos.X + radiusPtDistance, newPos.Y); //vertices[1] = Point.Round(newPos); // Try to maintain angle between StartPoint and RadiusPoint Point movedPtPos = GetControlPointPosition(pointId); Point otherGluePtPos = GetControlPointPosition(otherGluePtId); int hX = otherGluePtPos.X; int hY = otherGluePtPos.Y; Geometry.RotatePoint(movedPtPos.X, movedPtPos.Y, radiusPtAngle, ref hX, ref hY); int aPb, bPb, cPb; // perpendicular bisector int aR, bR, cR; // line through start point and radius point Geometry.CalcPerpendicularBisector(movedPtPos.X, movedPtPos.Y, otherGluePtPos.X, otherGluePtPos.Y, out aPb, out bPb, out cPb); Geometry.CalcLine(movedPtPos.X, movedPtPos.Y, hX, hY, out aR, out bR, out cR); Point newPos = Geometry.IntersectLines(aPb, bPb, cPb, aR, bR, cR); if (Geometry.IsValid(newPos)) vertices[1] = newPos; else Debug.Fail("Lines did not intersect!"); // After moving the point between the glue points, we have to recalculate the glue point // positions again MaintainGluePointPosition(ControlPointId.LastVertex, GetPreviousVertexId(ControlPointId.LastVertex)); MaintainGluePointPosition(ControlPointId.FirstVertex, GetNextVertexId(ControlPointId.FirstVertex)); } } else { MaintainGluePointPosition(ControlPointId.FirstVertex, pointId); MaintainGluePointPosition(ControlPointId.LastVertex, pointId); } return true; }
/// <summary> /// Moves the arrow tip of a rectangle based arrow /// </summary> public static bool MoveArrowPoint(Point center, Point movedPtPos, Point fixedPtPos, int angle, int minWidth, float centerPosFactorX, int untransformedDeltaX, int untransformedDeltaY, ResizeModifiers modifiers, out int centerOffsetX, out int centerOffsetY, out int newWidth, out int newAngle) { centerOffsetX = centerOffsetY = 0; newAngle = angle; newWidth = 0; // calculate new position of moved point Point newPtPos = movedPtPos; newPtPos.Offset(untransformedDeltaX, untransformedDeltaY); // calculate new shape location PointF newCenter = VectorLinearInterpolation((float)fixedPtPos.X, (float)fixedPtPos.Y, (float)newPtPos.X, (float)newPtPos.Y, centerPosFactorX); centerOffsetX = (int)Math.Round(newCenter.X - center.X); centerOffsetY = (int)Math.Round(newCenter.Y - center.Y); // calculate new angle float newAng = (360 + RadiansToDegrees(Geometry.Angle(fixedPtPos, newPtPos))) % 360; float oldAng = (360 + RadiansToDegrees(Geometry.Angle(fixedPtPos, movedPtPos))) % 360; newAngle = angle + DegreesToTenthsOfDegree(newAng - oldAng); // calculate new width newWidth = (int)Math.Round(DistancePointPoint(fixedPtPos, newPtPos)); return (movedPtPos.X == newPtPos.X && movedPtPos.Y == newPtPos.Y); }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, int deltaX, int deltaY, ResizeModifiers modifiers) { if (pointId == ControlPointIds.ArrowTipControlPoint || pointId == ControlPointIds.BodyEndControlPoint) { bool result = true; int dx = 0, dy = 0; int width = Width; int angle = Angle; Point tipPt = GetControlPointPosition(ControlPointIds.ArrowTipControlPoint); Point endPt = GetControlPointPosition(ControlPointIds.BodyEndControlPoint); if (pointId == ControlPointIds.ArrowTipControlPoint) { result = Geometry.MoveArrowPoint(Center, tipPt, endPt, angle, headWidth, 0.5f, deltaX, deltaY, modifiers, out dx, out dy, out width, out angle); } else { result = Geometry.MoveArrowPoint(Center, endPt, tipPt, angle, headWidth, 0.5f, deltaX, deltaY, modifiers, out dx, out dy, out width, out angle); } RotateCore(angle - Angle, X, Y); MoveByCore(dx, dy); Width = width; return(result); } else { return(base.MovePointByCore(pointId, deltaX, deltaY, modifiers)); } }
/// <summary> /// Moves the top side of a (rotated) rectangle in order to resize it /// </summary> /// <param name="width">Width of the rectangle</param> /// <param name="height">Height of the rectangle</param> /// <param name="minValueY">Specifies the minimum height.</param> /// <param name="centerPosFactorX">Specifies where the center is located. Default value is 50% = 0.5</param> /// <param name="centerPosFactorY">Specifies where the center is located. Default value is 50% = 0.5</param> /// <param name="divFactorX">Specifies the factor through which the corrected and modified movement must be dividable without remainding.</param> /// <param name="divFactorY">Specifies the factor through which the corrected and modified movement must be dividable without remainding.</param> /// <param name="deltaX">Movement on X axis</param> /// <param name="deltaY">Movement on Y axis</param> /// <param name="cosAngle">Cosinus value of the rectangle's rotation angle</param> /// <param name="sinAngle">Sinus value of the rectangle's rotation angle</param> /// <param name="modifiers">Movement modifiers</param> /// <param name="centerOffsetX">Specifies the movement the rectangle's center has to perform for resizing</param> /// <param name="centerOffsetY">Specifies the movement the rectangle's center has to perform for resizing</param> /// <param name="newWidth">New width of the rectangle</param> /// <param name="newHeight">New height of the rectangle</param> /// <returns>Returns true if the movement could be performed as desired. /// Returns false if the movement could not be performed completely because of movement restrictions</returns> public static bool MoveRectangleTop(int width, int height, int minValueY, float centerPosFactorX, float centerPosFactorY, int divFactorX, int divFactorY, float deltaX, float deltaY, double cosAngle, double sinAngle, ResizeModifiers modifiers, out int centerOffsetX, out int centerOffsetY, out int newWidth, out int newHeight) { bool result = true; centerOffsetX = centerOffsetY = 0; newWidth = width; newHeight = height; if ((modifiers & ResizeModifiers.MaintainAspect) != 0) { //MaintainAspectRatio(width, height, 1, -1, ref deltaX, ref deltaY); float aspectRatio = width / (float)height; deltaX = deltaY * aspectRatio; } // Align to integer coordinates Geometry.AlignMovement(modifiers, divFactorX, divFactorY, ref deltaX, ref deltaY); if ((modifiers & ResizeModifiers.MirroredResize) != 0) { if (newHeight - deltaY - deltaY >= minValueY) newHeight -= (int)Math.Round(deltaY + deltaY); else { newHeight = minValueY; result = false; } } else { if (newHeight - deltaY >= minValueY) newHeight -= (int)Math.Round(deltaY); else { deltaY = newHeight; newHeight = minValueY; result = false; } centerOffsetX = (int)Math.Round(-(deltaY * (1 - centerPosFactorY) * sinAngle)); centerOffsetY = (int)Math.Round((deltaY * (1 - centerPosFactorY) * cosAngle)); } if ((modifiers & ResizeModifiers.MaintainAspect) != 0) newWidth = (int)Math.Round(newHeight * (width / (float)height)); return result; }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, float transformedDeltaX, float transformedDeltaY, float sin, float cos, ResizeModifiers modifiers) { bool result = true; int dx = 0, dy = 0; int width = Width; int height = Height; switch (pointId) { case ControlPointIds.ArrowTopControlPoint: case ControlPointIds.ArrowBottomControlPoint: if (pointId == ControlPointIds.ArrowTopControlPoint) { //result = (transformedDeltaX == 0); if (!Geometry.MoveRectangleTop(width, height, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out width, out height)) { result = false; } } else { //result = (transformedDeltaX == 0); if (!Geometry.MoveRectangleBottom(width, height, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out width, out height)) { result = false; } } int newHeadWidth = HeadWidth + (int)Math.Round(transformedDeltaX); if (newHeadWidth < 0) { newHeadWidth = 0; result = false; } else if (newHeadWidth > Width) { newHeadWidth = Width; result = false; } HeadWidth = newHeadWidth; break; case ControlPointIds.BodyTopControlPoint: case ControlPointIds.BodyBottomControlPoint: result = (transformedDeltaX == 0); int newBodyHeight = 0; if (pointId == ControlPointIds.BodyTopControlPoint) { newBodyHeight = (int)Math.Round(BodyHeight - (transformedDeltaY * 2)); } else { newBodyHeight = (int)Math.Round(BodyHeight + (transformedDeltaY * 2)); } if (newBodyHeight > Height) { newBodyHeight = Height; result = false; } else if (newBodyHeight < 0) { newBodyHeight = 0; result = false; } BodyHeight = newBodyHeight; break; default: return(base.MovePointByCore(pointId, transformedDeltaX, transformedDeltaY, sin, cos, modifiers)); } if (width < headWidth) { width = headWidth; result = false; } MoveByCore(dx, dy); Width = width; Height = height; return(result); }
/// <summary> /// Moves the TopRight corner of a (rotated) rectangle in order to resize it /// </summary> /// <param name="width">Width of the rectangle</param> /// <param name="height">Height of the rectangle</param> /// <param name="minValueX">Specifies the minimum width.</param> /// <param name="minValueY">Specifies the minimum height.</param> /// <param name="centerPosFactorX">Specifies where the center is located. Default value is 50% = 0.5</param> /// <param name="centerPosFactorY">Specifies where the center is located. Default value is 50% = 0.5</param> /// <param name="divFactorX">Specifies the factor through which the corrected and modified movement must be dividable without remainding.</param> /// <param name="divFactorY">Specifies the factor through which the corrected and modified movement must be dividable without remainding.</param> /// <param name="deltaX">Movement on X axis</param> /// <param name="deltaY">Movement on Y axis</param> /// <param name="cosAngle">Cosinus value of the rectangle's rotation angle</param> /// <param name="sinAngle">Sinus value of the rectangle's rotation angle</param> /// <param name="modifiers">Movement modifiers</param> /// <param name="centerOffsetX">Specifies the movement the rectangle's center has to perform for resizing</param> /// <param name="centerOffsetY">Specifies the movement the rectangle's center has to perform for resizing</param> /// <param name="newWidth">New width of the rectangle</param> /// <param name="newHeight">New height of the rectangle</param> /// <returns>Returns true if the movement could be performed as desired. /// Returns false if the movement could not be performed completely because of movement restrictions</returns> public static bool MoveRectangleTopRight(int width, int height, int minValueX, int minValueY, float centerPosFactorX, float centerPosFactorY, int divFactorX, int divFactorY, float deltaX, float deltaY, float cosAngle, float sinAngle, ResizeModifiers modifiers, out int centerOffsetX, out int centerOffsetY, out int newWidth, out int newHeight) { bool result = true; centerOffsetX = centerOffsetY = 0; newWidth = width; newHeight = height; // Aspect maintainance can be combined with both MirroredResizing and normal resizing if ((modifiers & ResizeModifiers.MaintainAspect) != 0) MaintainAspectRatio(width, height, 1, -1, ref deltaX, ref deltaY); // Align to integer coordinates Geometry.AlignMovement(modifiers, divFactorX, divFactorY, ref deltaX, ref deltaY); if ((modifiers & ResizeModifiers.MirroredResize) != 0) { if (newWidth + deltaX + deltaX >= minValueX) newWidth += (int)Math.Round(deltaX + deltaX); else { newWidth = minValueX; result = false; } if (newHeight - deltaY - deltaY >= minValueY) newHeight -= (int)Math.Round(deltaY + deltaY); else { newHeight = minValueY; result = false; } } else { if (newWidth + deltaX >= minValueX) newWidth += (int)Math.Round(deltaX); else { deltaX = -newWidth; newWidth = minValueX; result = false; } if (newHeight - deltaY >= minValueY) newHeight -= (int)Math.Round(deltaY); else { deltaY = newHeight; newHeight = minValueY; result = false; } centerOffsetX = (int)Math.Round((deltaX * centerPosFactorX * cosAngle) - (deltaY * (1 - centerPosFactorY) * sinAngle)); centerOffsetY = (int)Math.Round((deltaX * centerPosFactorX * sinAngle) + (deltaY * (1 - centerPosFactorY) * cosAngle)); } return result; }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, float transformedDeltaX, float transformedDeltaY, float sin, float cos, ResizeModifiers modifiers) { bool result = base.MovePointByCore(pointId, transformedDeltaX, transformedDeltaY, sin, cos, modifiers); //for (int id = base.ControlPointCount + 1; id <= ControlPointCount; ++id) { // ControlPointHasMoved(id); //} return result; }
private static void GetMinValues(int width, int height, ResizeModifiers modifiers, out int minWidth, out int minHeight) { if ((modifiers & ResizeModifiers.MaintainAspect) != 0) { //if (width == height || width == 0 || height == 0) { // minWidth = minHeight = 1; //} else { // int gcf = CalcGreatestCommonFactor(width, height); // minHeight = height / gcf; // minWidth = width / gcf; //} // A simpler and less acurate but much faster alternative: float aspect = width / (float)height; minHeight = 1; minWidth = (int)Math.Round(1 * aspect); } else minWidth = minHeight = 0; }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, int deltaX, int deltaY, ResizeModifiers modifiers) { float transformedDeltaX, transformedDeltaY, sin, cos; Geometry.TransformMouseMovement(deltaX, deltaY, Angle, out transformedDeltaX, out transformedDeltaY, out sin, out cos); return MovePointByCore(pointId, transformedDeltaX, transformedDeltaY, sin, cos, modifiers); }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, float transformedDeltaX, float transformedDeltaY, float sin, float cos, ResizeModifiers modifiers) { bool result = true; int dx = 0, dy = 0; int width = Width; int height = Height; switch (pointId) { case TopCenterControlPoint: result = (transformedDeltaX == 0); if ( !Geometry.MoveRectangleTop(width, height, 0, centerPosFactorX, centerPosFactorY, DivFactorX, DivFactorY, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out width, out height)) result = false; break; case BottomLeftControlPoint: if ( !Geometry.MoveRectangleBottomLeft(width, height, 0, 0, centerPosFactorX, centerPosFactorY, DivFactorX, DivFactorY, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out width, out height)) result = false; break; case BottomRightControlPoint: if ( !Geometry.MoveRectangleBottomRight(width, height, 0, 0, centerPosFactorX, centerPosFactorY, DivFactorX, DivFactorY, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out width, out height)) result = false; break; case BottomCenterControlPoint: result = (transformedDeltaX == 0); if ( !Geometry.MoveRectangleBottom(width, height, 0, centerPosFactorX, centerPosFactorY, DivFactorX, DivFactorY, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out width, out height)) result = false; break; default: break; } Width = width; Height = height; MoveByCore(dx, dy); ControlPointsHaveMoved(); return result; }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, float transformedDeltaX, float transformedDeltaY, float sin, float cos, ResizeModifiers modifiers) { bool result = true; int dx = 0, dy = 0; int width = Width; int height = Height; switch ((int)pointId) { case TopCenterControlPoint: result = (transformedDeltaX == 0); if (!Geometry.MoveRectangleTop(width, height, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out width, out height)) result = false; break; case MiddleLeftControlPoint: result = (transformedDeltaY == 0); if (!Geometry.MoveRectangleLeft(width, height, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out width, out height)) result = false; break; case MiddleRightControlPoint: result = (transformedDeltaY == 0); if (!Geometry.MoveRectangleRight(width, height, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out width, out height)) result = false; break; case BottomCenterControlPoint: result = (transformedDeltaX == 0); if (!Geometry.MoveRectangleBottom(width, height, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out width, out height)) result = false; break; default: break; } if (result) { Width = width; Height = height; X += dx; Y += dy; } ControlPointsHaveMoved(); return result; }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, float transformedDeltaX, float transformedDeltaY, float sin, float cos, ResizeModifiers modifiers) { bool result = true; int dx = 0, dy = 0; int size = DiameterInternal; int hSize, vSize; // Diameter shapes always have to be resized with "MaintainAspect"! modifiers |= ResizeModifiers.MaintainAspect; switch (pointId) { // Top Left case TopLeftControlPoint: result = (transformedDeltaX == transformedDeltaY); if (!Geometry.MoveRectangleTopLeft(size, size, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) result = false; size = Math.Min(hSize, vSize); break; // Top Center case TopCenterControlPoint: result = (transformedDeltaX == 0); if (!Geometry.MoveRectangleTop(size, size, 0, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) result = false; size = vSize; break; // Top Right case TopRightControlPoint: result = (transformedDeltaX == -transformedDeltaY); if (!Geometry.MoveRectangleTopRight(size, size, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) result = false; size = Math.Min(hSize, vSize); break; // Middle left case MiddleLeftControlPoint: result = (transformedDeltaY == 0); if (!Geometry.MoveRectangleLeft(size, size, transformedDeltaX, 0, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) result = false; size = hSize; break; // Middle right case MiddleRightControlPoint: result = (transformedDeltaY == 0); if (!Geometry.MoveRectangleRight(size, size, transformedDeltaX, 0, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) result = false; size = hSize; break; // Bottom left case BottomLeftControlPoint: result = (-transformedDeltaX == transformedDeltaY); if (!Geometry.MoveRectangleBottomLeft(size, size, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) result = false; size = Math.Min(hSize, vSize); break; // Bottom Center case BottomCenterControlPoint: result = (transformedDeltaX == 0); if (!Geometry.MoveRectangleBottom(size, size, 0, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) result = false; size = vSize; break; // Bottom right case BottomRightControlPoint: result = (transformedDeltaX == transformedDeltaY); if (!Geometry.MoveRectangleBottomRight(size, size, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) result = false; size = Math.Min(hSize, vSize); break; } // Set field in order to avoid the shape being inserted into the owner's shape map internalDiameter = size; MoveByCore(dx, dy); ControlPointsHaveMoved(); return result; }
/// <summary> /// Moves the BottomRight corner of a (rotated) rectangle in order to resize it /// </summary> public static bool MoveRectangleBottomRight(int width, int height, int minValueX, int minValueY, float centerPosFactorX, float centerPosFactorY, float deltaX, float deltaY, double cosAngle, double sinAngle, ResizeModifiers modifiers, out int centerOffsetX, out int centerOffsetY, out int newWidth, out int newHeight) { bool result = true; centerOffsetX = centerOffsetY = 0; newWidth = width; newHeight = height; // aspect maintainence can be combined with both MirroredResizing and normal resizing if ((modifiers & ResizeModifiers.MaintainAspect) != 0) MaintainAspectRatio(width, height, width + deltaX, height + deltaY, ref deltaX, ref deltaY); if ((modifiers & ResizeModifiers.MirroredResize) != 0) { if (newWidth + deltaX + deltaX >= minValueX) newWidth += (int)Math.Round(deltaX + deltaX); else { newWidth = minValueX; result = false; } if (newHeight + deltaY + deltaY >= minValueY) newHeight += (int)Math.Round(deltaY + deltaY); else { newHeight = minValueY; result = false; } } else { if (newWidth + deltaX >= minValueX) newWidth += (int)Math.Round(deltaX); else { deltaX = -newWidth; newWidth = minValueX; result = false; } if (newHeight + deltaY >= minValueY) newHeight += (int)Math.Round(deltaY); else { deltaY = -newHeight; newHeight = minValueY; result = false; } centerOffsetX = (int)Math.Round((deltaX * centerPosFactorX * cosAngle) - (deltaY * centerPosFactorY * sinAngle)); centerOffsetY = (int)Math.Round((deltaX * centerPosFactorX * sinAngle) + (deltaY * centerPosFactorY * cosAngle)); } return result; }
/// <ToBeCompleted></ToBeCompleted> protected abstract bool MovePointByCore(ControlPointId pointId, float transformedDeltaX, float transformedDeltaY, float sin, float cos, ResizeModifiers modifiers);
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, int deltaX, int deltaY, ResizeModifiers modifiers) { int pointIndex = GetControlPointIndex(pointId); float radiusPtAngle = 0; bool maintainAspect = false; ControlPointId otherGluePtId = ControlPointId.None; ControlPointId nextPtId = ControlPointId.None; if ((modifiers & ResizeModifiers.MaintainAspect) == ResizeModifiers.MaintainAspect && (IsFirstVertex(pointId) || IsLastVertex(pointId))) { maintainAspect = true; // Get opposite glue point and the glue point next to the moved glue point // (may be identical to the opposite glue point) if (IsFirstVertex(pointId)) { otherGluePtId = ControlPointId.LastVertex; nextPtId = GetPreviousVertexId(otherGluePtId); } else { otherGluePtId = ControlPointId.FirstVertex; nextPtId = GetNextVertexId(otherGluePtId); } // Calculate the original angle for later use radiusPtAngle = Geometry.RadiansToDegrees(Geometry.Angle( GetControlPointPosition(pointId), GetControlPointPosition(otherGluePtId), GetControlPointPosition(nextPtId))); } // Assign new position to vertex GetControlPoint(pointIndex).Offset(deltaX, deltaY); if (maintainAspect) { int radPointIdx = GetControlPointIndex(radiusPointId); if (IsLine) { MaintainGluePointPosition(otherGluePtId, nextPtId); if (VertexCount > 2) GetControlPoint(radPointIdx).SetPosition(Geometry.VectorLinearInterpolation(StartPoint, EndPoint, 0.5f)); } else { // Try to maintain angle between StartPoint and RadiusPoint Point movedPtPos = GetControlPointPosition(pointId); Point otherGluePtPos = GetControlPointPosition(otherGluePtId); int hX = otherGluePtPos.X; int hY = otherGluePtPos.Y; Geometry.RotatePoint(movedPtPos.X, movedPtPos.Y, radiusPtAngle, ref hX, ref hY); int aPb, bPb, cPb; // perpendicular bisector int aR, bR, cR; // line through start point and radius point Geometry.CalcPerpendicularBisector(movedPtPos.X, movedPtPos.Y, otherGluePtPos.X, otherGluePtPos.Y, out aPb, out bPb, out cPb); Geometry.CalcLine(movedPtPos.X, movedPtPos.Y, hX, hY, out aR, out bR, out cR); Point newPos = Geometry.IntersectLines(aPb, bPb, cPb, aR, bR, cR); Debug.Assert(Geometry.IsValid(newPos)); if (Geometry.IsValid(newPos)) GetControlPoint(radPointIdx).SetPosition(newPos); // After moving the point between the glue points, we have to recalculate the glue point // positions again MaintainGluePointPosition(ControlPointId.LastVertex, GetPreviousVertexId(ControlPointId.LastVertex)); MaintainGluePointPosition(ControlPointId.FirstVertex, GetNextVertexId(ControlPointId.FirstVertex)); } } else { MaintainGluePointPosition(ControlPointId.FirstVertex, pointId); MaintainGluePointPosition(ControlPointId.LastVertex, pointId); } return true; }
/// <override></override> public override bool MoveControlPointBy(ControlPointId pointId, int deltaX, int deltaY, ResizeModifiers modifiers) { bool result = false; if (pointId == ControlPointId.Reference) result = MoveBy(deltaX, deltaY); else { if (Owner != null) Owner.NotifyChildResizing(this); result = false; if (Owner != null) Owner.NotifyChildResized(this); } return result; }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, int deltaX, int deltaY, ResizeModifiers modifiers) { if (autoSize && pointId != ControlPointId.Reference) { return(false); } else { return(base.MovePointByCore(pointId, deltaX, deltaY, modifiers)); } }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, float transformedDeltaX, float transformedDeltaY, float sin, float cos, ResizeModifiers modifiers) { bool result = true; int dx = 0, dy = 0; int size = DiameterInternal; int hSize, vSize; // Diameter shapes always have to be resized with "MaintainAspect"! modifiers |= ResizeModifiers.MaintainAspect; switch (pointId) { // Top Left case ControlPointIds.TopLeftControlPoint: result = (transformedDeltaX == transformedDeltaY); if (!Geometry.MoveRectangleTopLeft(size, size, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) { result = false; } size = Math.Min(hSize, vSize); break; // Top Center case ControlPointIds.TopCenterControlPoint: result = (transformedDeltaX == 0); if (!Geometry.MoveRectangleTop(size, size, 0, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) { result = false; } size = vSize; break; // Top Right case ControlPointIds.TopRightControlPoint: result = (transformedDeltaX == -transformedDeltaY); if (!Geometry.MoveRectangleTopRight(size, size, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) { result = false; } size = Math.Min(hSize, vSize); break; // Middle left case ControlPointIds.MiddleLeftControlPoint: result = (transformedDeltaY == 0); if (!Geometry.MoveRectangleLeft(size, size, transformedDeltaX, 0, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) { result = false; } size = hSize; break; // Middle right case ControlPointIds.MiddleRightControlPoint: result = (transformedDeltaY == 0); if (!Geometry.MoveRectangleRight(size, size, transformedDeltaX, 0, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) { result = false; } size = hSize; break; // Bottom left case ControlPointIds.BottomLeftControlPoint: result = (-transformedDeltaX == transformedDeltaY); if (!Geometry.MoveRectangleBottomLeft(size, size, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) { result = false; } size = Math.Min(hSize, vSize); break; // Bottom Center case ControlPointIds.BottomCenterControlPoint: result = (transformedDeltaX == 0); if (!Geometry.MoveRectangleBottom(size, size, 0, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) { result = false; } size = vSize; break; // Bottom right case ControlPointIds.BottomRightControlPoint: result = (transformedDeltaX == transformedDeltaY); if (!Geometry.MoveRectangleBottomRight(size, size, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out hSize, out vSize)) { result = false; } size = Math.Min(hSize, vSize); break; } if (_internalDiameter != size || dx != 0 || dy != 0) { // Set field in order to avoid the shape being inserted into the owner's shape map _internalDiameter = size; MoveByCore(dx, dy); ControlPointsHaveMoved(); } return(result); }
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, int deltaX, int deltaY, ResizeModifiers modifiers) { if (pointId == ArrowTipControlPoint || pointId == BodyEndControlPoint) { bool result = true; int dx = 0, dy = 0; int width = Width; int angle = Angle; Point tipPt = GetControlPointPosition(ArrowTipControlPoint); Point endPt = GetControlPointPosition(BodyEndControlPoint); if (pointId == ArrowTipControlPoint) result = Geometry.MoveArrowPoint(Center, tipPt, endPt, angle, headWidth, 0.5f, deltaX, deltaY, modifiers, out dx, out dy, out width, out angle); else result = Geometry.MoveArrowPoint(Center, endPt, tipPt, angle, headWidth, 0.5f, deltaX, deltaY, modifiers, out dx, out dy, out width, out angle); RotateCore(angle - Angle, X, Y); MoveByCore(dx, dy); Width = width; return result; } else return base.MovePointByCore(pointId, deltaX, deltaY, modifiers); }
/// <summary> /// Moves the given control point by the indicated distances if possible. /// </summary> /// <param name="pointId">Id of the point to move</param> /// <param name="deltaX">Distance on X axis</param> /// <param name="deltaY">Distance on Y axis</param> /// <param name="modifiers">Modifiers for the move action.</param> /// <returns>True, if the control point could be moved, else false.</returns> public abstract bool MoveControlPointBy(ControlPointId pointId, int deltaX, int deltaY, ResizeModifiers modifiers);
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, float transformedDeltaX, float transformedDeltaY, float sin, float cos, ResizeModifiers modifiers) { bool result = true; int dx = 0, dy = 0; int width = Width; int height = Height; switch (pointId) { case ArrowTopControlPoint: case ArrowBottomControlPoint: if (pointId == ArrowTopControlPoint) { //result = (transformedDeltaX == 0); if ( !Geometry.MoveRectangleTop(width, height, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out width, out height)) result = false; } else { //result = (transformedDeltaX == 0); if ( !Geometry.MoveRectangleBottom(width, height, transformedDeltaX, transformedDeltaY, cos, sin, modifiers, out dx, out dy, out width, out height)) result = false; } int newHeadWidth = HeadWidth + (int) Math.Round(transformedDeltaX); if (newHeadWidth < 0) { newHeadWidth = 0; result = false; } else if (newHeadWidth > Width) { newHeadWidth = Width; result = false; } HeadWidth = newHeadWidth; break; case BodyTopControlPoint: case BodyBottomControlPoint: result = (transformedDeltaX == 0); int newBodyHeight = 0; if (pointId == BodyTopControlPoint) newBodyHeight = (int) Math.Round(BodyHeight - (transformedDeltaY*2)); else newBodyHeight = (int) Math.Round(BodyHeight + (transformedDeltaY*2)); if (newBodyHeight > Height) { newBodyHeight = Height; result = false; } else if (newBodyHeight < 0) { newBodyHeight = 0; result = false; } BodyHeight = newBodyHeight; break; default: return base.MovePointByCore(pointId, transformedDeltaX, transformedDeltaY, sin, cos, modifiers); } if (width < headWidth) { width = headWidth; result = false; } MoveByCore(dx, dy); Width = width; Height = height; return result; }
/// <ToBeCompleted></ToBeCompleted> protected abstract bool MovePointByCore(ControlPointId pointId, float transformedDeltaX, float transformedDeltaY, float sin, float cos, ResizeModifiers modifiers);
/// <override></override> protected override bool MovePointByCore(ControlPointId pointId, float transformedDeltaX, float transformedDeltaY, float sin, float cos, ResizeModifiers modifiers) { int idx = GetControlPointIndex(pointId); Debug.Assert(idx >= 0); int oldPosX, oldPosY; Geometry.CalcPolygonBalancePoint(shapePoints, out oldPosX, out oldPosY); shapePoints[idx].X += (int)Math.Round(transformedDeltaX); shapePoints[idx].Y += (int)Math.Round(transformedDeltaY); int newPosX, newPosY; Geometry.CalcPolygonBalancePoint(shapePoints, out newPosX, out newPosY); // Update (relative) vertex positions before moving the shape to the new balance point int dX = newPosX - oldPosX; int dY = newPosY - oldPosY; for (int i = shapePoints.Length - 1; i >= 0; --i) { shapePoints[i].X -= dX; shapePoints[i].Y -= dY; } MoveByCore((int)Math.Round((dX * cos) - (dY * sin)), (int)Math.Round((dX * sin) + (dY * cos))); return true; }