123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978 |
- using FastReport.Utils;
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.Windows.Forms;
- namespace FastReport
- {
- partial class PolyLineObject : IHasEditor
- {
- //Current selected point, for move
- //internal PolyLineObjectToolBar toolbar; //deprecated
- #region Private Fields
- private PolyPoint currentPoint;
- private PolyPoint drawSelectedPointLine;
- private int drawSelectedPointLineNumber;
- private int selectedPoint;
- #endregion Private Fields
- #region Public Properties
- /// <inheritdoc/>
- public override float Height
- {
- get { return base.Height; }
- set
- {
- if (base.Height == 0)
- {
- base.Height = value;
- return;
- }
- if (IsSelected)
- {
- if (SelectionMode == PolygonSelectionMode.MoveAndScale)
- {
- float oldHeight = base.Height;
- if (oldHeight == value) return;
- if (pointsCollection.Count < 2)
- return;
- float scaleY = value / oldHeight;
- if (float.IsInfinity(scaleY))
- return;
- if (float.IsNaN(scaleY))
- return;
- if (scaleY == 0)
- return;
- center.Y = center.Y * scaleY;
- foreach (PolyPoint point in pointsCollection)
- {
- point.ScaleY(scaleY);
- }
- base.Height = value;
- }
- else
- RecalculateBounds();
- }
- else
- base.Height = value;
- }
- }
- /// <inheritdoc/>
- public override float Width
- {
- get { return base.Width; }
- set
- {
- if (base.Width == 0)
- {
- base.Width = value;
- return;
- }
- if (IsSelected)
- {
- if (SelectionMode == PolygonSelectionMode.MoveAndScale)
- {
- float oldWidth = base.Width;
- if (oldWidth == value) return;
- if (pointsCollection.Count < 2)
- return;
- float scaleX = value / oldWidth;
- if (float.IsInfinity(scaleX))
- return;
- if (float.IsNaN(scaleX))
- return;
- if (scaleX == 0)
- return;
- center.X = center.X * scaleX;
- foreach (PolyPoint point in pointsCollection)
- {
- point.ScaleX(scaleX);
- }
- base.Width = value;
- }
- else
- RecalculateBounds();
- }
- else
- base.Width = value;
- }
- }
- #endregion Public Properties
- #region Internal Properties
- internal PolygonSelectionMode SelectionMode
- {
- get
- {
- return polygonSelectionMode;
- }
- set
- {
- if (value != polygonSelectionMode)
- {
- polygonSelectionMode = value;
- try
- {
- if (IsSelected)
- {
- Report.Designer.SelectionChanged(this);
- }
- }
- catch
- {
- }
- polygonSelectionMode = value;
- }
- }
- }
- #endregion Internal Properties
- #region Public Methods
- /// <summary>
- /// Add point to end of polyline and recalculate bounds after add.
- /// Can be first point.
- /// Deprecated, use insert point
- /// </summary>
- /// <param name="localX">local x - relative to left-top point</param>
- /// <param name="localY">local y - relative to left-top point</param>
- [Obsolete]
- public void AddPointToEnd(float localX, float localY)
- {
- insertPoint(pointsCollection.Count, localX, localY, 1);
- if (Report != null)
- if (Report.Designer != null)
- Report.Designer.SetModified(this, "Change");
- }
- /// <summary>
- /// Add point to start of polyline and recalculate bounds after add
- /// Can be first point
- /// Deprecated, use insert point
- /// </summary>
- /// <param name="localX">local x - relative to left-top point</param>
- /// <param name="localY">local y - relative to left-top point</param>
- [Obsolete]
- public void AddPointToStart(float localX, float localY)
- {
- insertPoint(0, localX, localY, 1);
- if (Report != null)
- if (Report.Designer != null)
- Report.Designer.SetModified(this, "Change");
- }
- /// <inheritdoc/>
- public override void CheckNegativeSize(FRMouseEventArgs e)
- {
- // do nothing
- }
- /// <inheritdoc/>
- public override void DrawSelection(FRPaintEventArgs e)
- {
- if (SelectionMode == PolygonSelectionMode.AddToLine && drawSelectedPointLineNumber >= 0 && pointsCollection.Count > 0)
- {
- if (drawSelectedPointLine != null)
- {
- float absLeft = AbsLeft;
- float absTop = AbsTop;
- Pen p = e.Cache.GetPen(Color.DarkGray, 1, DashStyle.Solid);
- if (drawSelectedPointLineNumber > 0 && drawSelectedPointLineNumber - 1 < pointsCollection.Count || this is PolygonObject)
- {
- e.Graphics.DrawLine(p, GetPointF(drawSelectedPointLine, e.ScaleX, e.ScaleY, absLeft, absTop), GetPointF(drawSelectedPointLineNumber - 1, e.ScaleX, e.ScaleY, absLeft, absTop));
- }
- if (drawSelectedPointLineNumber < pointsCollection.Count || this is PolygonObject)
- {
- e.Graphics.DrawLine(p, GetPointF(drawSelectedPointLine, e.ScaleX, e.ScaleY, absLeft, absTop), GetPointF(drawSelectedPointLineNumber, e.ScaleX, e.ScaleY, absLeft, absTop));
- }
- }
- }
- if (SelectionMode == PolygonSelectionMode.MoveAndScale)
- {
- base.DrawSelection(e);
- }
- else
- {
- Pen help_p = e.Cache.GetPen(Color.Black, 1, DashStyle.Dash);
- if (Page == null)
- return;
- bool firstSelected = Report.Designer.SelectedObjects.IndexOf(this) == 0;
- Pen p = firstSelected ? Pens.Black : Pens.White;
- Brush b = firstSelected ? Brushes.White : Brushes.Black;
- SelectionPoint[] selectionPoints = GetSelectionPoints();
- IGraphics g = e.Graphics;
- SelectionPoint lastPoint = null;
- float m = Report.Designer.DpiMultiplier();
- foreach (SelectionPoint pt in selectionPoints)
- {
- switch (pt.sizingPoint)
- {
- case SizingPoint.LeftTop:
- {
- float x = pt.x * e.ScaleX;
- float y = pt.y * e.ScaleY;
- g.FillEllipse(Brushes.White, x - 5 * m, y - 5 * m, 10 * m, 10 * m);
- g.FillEllipse(Brushes.Red, x - 3 * m, y - 3 * m, 6 * m, 6 * m);
- g.DrawEllipse(Pens.Gray, x - 3 * m, y - 3 * m, 6 * m, 6 * m);
- lastPoint = pt;
- }
- break;
- case SizingPoint.RightTop:
- {
- float x = pt.x * e.ScaleX;
- float y = pt.y * e.ScaleY;
- if (lastPoint != null)
- {
- e.Graphics.DrawLine(help_p, lastPoint.x * e.ScaleX, lastPoint.y * e.ScaleY, x, y);
- }
- g.FillEllipse(Brushes.White, x - 3 * m, y - 3 * m, 6 * m, 6 * m);
- g.FillEllipse(Brushes.Blue, x - 2 * m, y - 2 * m, 4 * m, 4 * m);
- g.DrawEllipse(Pens.Gray, x - 2 * m, y - 2 * m, 4 * m, 4 * m);
- }
- break;
- default:
- lastPoint = pt;
- DrawSelectionPoint(e, p, b, pt.x, pt.y);
- break;
- }
- }
- }
- }
- /// <summary>
- /// Replace points with star
- /// </summary>
- /// <param name="spikes">Minimum value is 3</param>
- public void DrawStar(int spikes)
- {
- if (spikes < 3) spikes = 3;
- const float outerRadius = 50;
- const float innerRadius = 30;
- float rot = (float)(Math.PI / 2 * 3);
- const float cx = 0;
- const float cy = 0;
- float x = cx;
- float y = cy;
- float step = (float)(Math.PI / spikes);
- base.Width = 100;
- base.Height = 100;
- center = new PointF(50, 50);
- pointsCollection.Clear();
- pointsCollection.Add(new PolyPoint(cx, cy - outerRadius));
- for (int i = 0; i < spikes; i++)
- {
- x = cx + (float)Math.Cos(rot) * outerRadius;
- y = cy + (float)Math.Sin(rot) * outerRadius;
- pointsCollection.Add(new PolyPoint(x, y));
- rot += step;
- x = cx + (float)Math.Cos(rot) * innerRadius;
- y = cy + (float)Math.Sin(rot) * innerRadius;
- pointsCollection.Add(new PolyPoint(x, y));
- rot += step;
- }
- }
- /// <inheritdoc/>
- public override SizeF GetPreferredSize()
- {
- return new SizeF(0, 0);
- }
- /// <inheritdoc/>
- public override void HandleKeyDown(Control sender, KeyEventArgs e)
- {
- if (e.KeyCode == Keys.Delete)
- {
- if (SelectionMode != PolygonSelectionMode.MoveAndScale)
- {
- if (pointsCollection.Count > 0)
- {
- DeletePointByIndex(selectedPoint);
- selectedPoint--;
- Report.Designer.Refresh();
- e.Handled = true;
- }
- }
- }
- if (!e.Handled)
- base.HandleKeyDown(sender, e);
- }
- /// <inheritdoc/>
- public override void HandleMouseDown(FRMouseEventArgs e)
- {
- //if (toolbar.IsVisible && this.IsSelected)
- //{
- // if (toolbar.ClickPublic(new PointF(AbsLeft, AbsTop < 20 ? 20 : AbsTop), new PointF(e.x, e.y)))
- // {
- // e.handled = true;
- // return;
- // }
- //}
- if (e.button == MouseButtons.Left && currentPoint == null && this.IsSelected)
- {
- float absLeft = AbsLeft;
- float absTop = AbsTop;
- PointF mousePoint = new PointF(e.x, e.y);
- PointF mousePointAligned = new PointF((int)((e.x - absLeft - center.X) / Page.SnapSize.Width) * Page.SnapSize.Width, (int)((e.y - absTop - center.Y) / Page.SnapSize.Height) * Page.SnapSize.Height);
- switch (SelectionMode)
- {
- case PolygonSelectionMode.Normal:
- for (int i = 0; i < pointsCollection.Count; i++)
- {
- PolyPoint point = pointsCollection[i];
- if (point.LeftCurve != null && PointInSelectionPoint(absLeft + point.X + center.X + point.LeftCurve.X, absTop + point.Y + center.Y + point.LeftCurve.Y, mousePoint))
- {
- currentPoint = point.LeftCurve;
- e.mode = WorkspaceMode2.Custom;
- e.handled = true;
- break;
- }
- else if (point.RightCurve != null && PointInSelectionPoint(absLeft + point.X + center.X + point.RightCurve.X, absTop + point.Y + center.Y + point.RightCurve.Y, mousePoint))
- {
- currentPoint = point.RightCurve;
- e.mode = WorkspaceMode2.Custom;
- e.handled = true;
- break;
- }
- else if (PointInSelectionPoint(absLeft + point.X + center.X, absTop + point.Y + center.Y, mousePoint))
- {
- currentPoint = point;
- e.mode = WorkspaceMode2.Custom;
- e.handled = true;
- break;
- }
- }
- break;
- case PolygonSelectionMode.AddToLine:
- for (int i = 0; i < pointsCollection.Count; i++)
- {
- PolyPoint point = pointsCollection[i];
- if (PointInSelectionPoint(absLeft + point.X + center.X, absTop + point.Y + center.Y, mousePoint))
- {
- currentPoint = point;
- e.mode = WorkspaceMode2.Custom;
- e.handled = true;
- break;
- }
- }
- if (!e.handled)
- {
- e.handled = true;
- PolyPoint result = InsertPointByLocation(mousePointAligned.X, mousePointAligned.Y, 25);
- if (result != null)
- {
- e.mode = WorkspaceMode2.Custom;
- currentPoint = result;
- }
- }
- break;
- case PolygonSelectionMode.AddBezier:
- for (int i = 0; i < pointsCollection.Count; i++)
- {
- PolyPoint point = pointsCollection[i];
- if (point.LeftCurve != null)
- {
- if (PointInSelectionPoint(absLeft + point.X + center.X + point.LeftCurve.X, absTop + point.Y + center.Y + point.LeftCurve.Y, mousePoint))
- {
- currentPoint = point.LeftCurve;
- e.mode = WorkspaceMode2.Custom;
- e.handled = true;
- break;
- }
- }
- else if (i == selectedPoint)
- {
- if (i > 0 || (this is PolygonObject))
- {
- PolyPoint pseudoPoint = GetPseudoPoint(point, pointsCollection[i - 1]);
- if (PointInSelectionPoint(absLeft + pseudoPoint.X + center.X, absTop + pseudoPoint.Y + center.Y, mousePoint))
- {
- pseudoPoint.X -= point.X;
- pseudoPoint.Y -= point.Y;
- point.LeftCurve = pseudoPoint;
- currentPoint = pseudoPoint;
- e.mode = WorkspaceMode2.Custom;
- e.handled = true;
- break;
- }
- }
- }
- if (point.RightCurve != null)
- {
- if (PointInSelectionPoint(absLeft + point.X + center.X + point.RightCurve.X, absTop + point.Y + center.Y + point.RightCurve.Y, mousePoint))
- {
- currentPoint = point.RightCurve;
- e.mode = WorkspaceMode2.Custom;
- e.handled = true;
- break;
- }
- }
- else
- {
- if (i < pointsCollection.Count || (this is PolygonObject))
- {
- PolyPoint pseudoPoint = GetPseudoPoint(point, pointsCollection[i + 1]);
- if (PointInSelectionPoint(absLeft + pseudoPoint.X + center.X, absTop + pseudoPoint.Y + center.Y, mousePoint))
- {
- pseudoPoint.X -= point.X;
- pseudoPoint.Y -= point.Y;
- point.RightCurve = pseudoPoint;
- currentPoint = pseudoPoint;
- e.mode = WorkspaceMode2.Custom;
- e.handled = true;
- break;
- }
- }
- }
- if (PointInSelectionPoint(absLeft + point.X + center.X, absTop + point.Y + center.Y, mousePoint))
- {
- currentPoint = point;
- e.mode = WorkspaceMode2.Custom;
- e.handled = true;
- break;
- }
- }
- break;
- case PolygonSelectionMode.Delete:
- for (int i = 0; i < pointsCollection.Count; i++)
- {
- PolyPoint point = pointsCollection[i];
- if (point.LeftCurve != null && PointInSelectionPoint(absLeft + point.X + center.X + point.LeftCurve.X, absTop + point.Y + center.Y + point.LeftCurve.Y, mousePoint))
- {
- point.LeftCurve = null;
- currentPoint = null;
- e.mode = WorkspaceMode2.None;
- e.handled = true;
- return;
- }
- else if (point.RightCurve != null && PointInSelectionPoint(absLeft + point.X + center.X + point.RightCurve.X, absTop + point.Y + center.Y + point.RightCurve.Y, mousePoint))
- {
- point.RightCurve = null;
- currentPoint = null;
- e.mode = WorkspaceMode2.None;
- e.handled = true;
- return;
- }
- else if (PointInSelectionPoint(absLeft + point.X + center.X, absTop + point.Y + center.Y, mousePoint))
- {
- RemovePointAt(i);
- currentPoint = null;
- if (i < selectedPoint)
- selectedPoint--;
- e.mode = WorkspaceMode2.None;
- e.handled = true;
- return;
- }
- }
- break;
- case PolygonSelectionMode.MoveAndScale:
- if (pointsCollection.Count < 2)
- {
- for (int i = 0; i < pointsCollection.Count; i++)
- {
- PolyPoint point = pointsCollection[i];
- if (PointInSelectionPoint(absLeft + point.X + center.X, absTop + point.Y + center.Y, mousePoint))
- {
- currentPoint = point;
- e.mode = WorkspaceMode2.Custom;
- e.handled = true;
- break;
- }
- }
- }
- break;
- }
- }
- if (!e.handled)
- base.HandleMouseDown(e);
- }
- /// <inheritdoc/>
- public override void HandleMouseMove(FRMouseEventArgs e)
- {
- if (currentPoint != null)
- {
- currentPoint.X += e.delta.X;
- currentPoint.Y += e.delta.Y;
- //points[currentPoint] = point;
- RecalculateBounds();
- e.mode = WorkspaceMode2.Custom;
- e.handled = true;
- }
- if (!e.handled && SelectionMode == PolygonSelectionMode.AddToLine)
- {
- PolyPoint mousePointAligned = new PolyPoint((int)((e.x - AbsLeft - center.X) / Page.SnapSize.Width) * Page.SnapSize.Width, (int)((e.y - AbsTop - center.Y) / Page.SnapSize.Height) * Page.SnapSize.Height);
- drawSelectedPointLineNumber = GetBestPointPosition(mousePointAligned.X, mousePointAligned.Y);
- if (drawSelectedPointLine == null || !drawSelectedPointLine.Near(mousePointAligned))
- {
- drawSelectedPointLine = mousePointAligned;
- Report.Designer.Refresh();
- }
- }
- else
- {
- drawSelectedPointLineNumber = -1;
- }
- if (!e.handled)
- {
- base.HandleMouseMove(e);
- }
- if (e.handled)
- {
- e.cursor = Cursors.Cross;
- }
- if (IsSelected)
- {
- switch (SelectionMode)
- {
- case PolygonSelectionMode.AddToLine:
- case PolygonSelectionMode.AddBezier:
- e.handled = true;
- e.mode = WorkspaceMode2.Custom;
- break;
- }
- }
- //if (toolbar != null && toolbar.IsVisible)
- //{
- // //toolbar.MouseMove(e.x, e.y);
- //}
- }
- /// <inheritdoc/>
- public override void HandleMouseUp(FRMouseEventArgs e)
- {
- if (currentPoint != null)
- {
- RecalculateBounds();
- int index = pointsCollection.IndexOf(currentPoint);
- if (index >= 0)
- selectedPoint = index;
- currentPoint = null;
- if (Report != null)
- if (Report.Designer != null)
- Report.Designer.SetModified(this, "Change");
- }
- if (IsSelected)
- {
- int mode = (int)SelectionMode;
- if (0 < mode)
- {
- e.handled = true;
- }
- }
- if (!e.handled)
- base.HandleMouseUp(e);
- }
- /// <summary>
- /// Insert point to desired place of polyline
- /// Recalculate bounds after insert
- /// </summary>
- /// <param name="index">Index of place from zero to count</param>
- /// <param name="localX">local x - relative to left-top point</param>
- /// <param name="localY">local y - relative to left-top point</param>
- public void InsertPointByIndex(int index, float localX, float localY)
- {
- insertPoint(index, localX, localY, 0);
- if (Report != null)
- if (Report.Designer != null)
- Report.Designer.SetModified(this, "Change");
- }
- /// <summary>
- /// Insert point to near line
- /// Recalculate bounds after insert
- /// </summary>
- /// <param name="localX">local x - relative to left-top point</param>
- /// <param name="localY">local y - relative to left-top point</param>
- /// <param name="maxDistance">depricated</param>
- /// <returns>Index of inserted point</returns>
- public PolyPoint InsertPointByLocation(float localX, float localY, float maxDistance)
- {
- PolyPoint result;
- int pointNumber = -1;
- if (pointsCollection.Count == 0)
- {
- result = addPoint(0, 0, 0);
- pointNumber = 0;
- }
- else
- {
- pointNumber = GetBestPointPosition(localX, localY);
- result = insertPoint(pointNumber, localX, localY, 1);
- }
- RecalculateBounds();
- if (pointNumber >= 0)
- if (Report != null)
- if (Report.Designer != null)
- Report.Designer.SetModified(this, "Change");
- return result;
- }
- /// <inheritdoc/>
- public bool InvokeEditor()
- {
- if (IsSelected)
- {
- if (SelectionMode == PolygonSelectionMode.MoveAndScale)
- {
- Report report = Report;
- if (report != null)
- {
- SelectionMode = PolygonSelectionMode.Normal;
- }
- return true;
- }
- else if (SelectionMode == PolygonSelectionMode.Normal)
- {
- Report report = Report;
- if (report != null)
- {
- SelectionMode = PolygonSelectionMode.MoveAndScale;
- }
- return true;
- }
- }
- return false;
- }
- /// <inheritdoc/>
- public override void OnAfterInsert(InsertFrom source)
- {
- base.OnAfterInsert(source);
- if (Report != null)
- {
- SelectedObjectCollection selectionObjects = Report.Designer.SelectedObjects;
- selectionObjects.Clear();
- selectionObjects.Add(this);
- }
- if (pointsCollection.Count < 2)
- SelectionMode = PolygonSelectionMode.AddToLine;
- if (pointsCollection.Count > 1)
- SelectionMode = PolygonSelectionMode.MoveAndScale;
- }
- /// <inheritdoc/>
- public override void OnBeforeInsert(int flags)
- {
- float rotation = (float)((flags & 0xF) / 8.0 * Math.PI);
- int numberOfEdges = (flags & 0xF0) >> 4;
- if (numberOfEdges >= 5)
- {
- float x, y;
- pointsCollection.Clear();
- for (int i = 0; i < numberOfEdges; i++)
- {
- base.Width = 100;
- base.Height = 100;
- x = 50 + (float)(50 * Math.Cos(rotation + 2 * Math.PI * i / numberOfEdges));
- y = 50 + (float)(50 * Math.Sin(rotation + 2 * Math.PI * i / numberOfEdges));
- pointsCollection.Add(new PolyPoint(x, y));
- }
- }
- else
- {
- pointsCollection.Add(new PolyPoint(0, 0));
- Width = 5;
- Height = 5;
- }
- }
- /// <inheritdoc/>
- public override bool PointInObject(PointF point)
- {
- using (Pen pen = new Pen(Color.Black, 10))
- using (GraphicsPath path = new GraphicsPath())
- {
- float absLeft = AbsLeft;
- float absTop = AbsTop;
- if (pointsCollection.Count > 1 && currentPoint == null)
- for (int i = 0; i < pointsCollection.Count - 1; i++)
- {
- PolyPoint prev = pointsCollection[i];
- PolyPoint next = pointsCollection[i + 1];
- path.AddLine(absLeft + prev.X + center.X, absTop + prev.Y + center.Y, absLeft + next.X + center.X, absTop + next.Y + center.Y);
- }
- else
- path.AddLine(absLeft - 1 + CenterX, absTop - 1 + CenterY, AbsRight + 1 + CenterX, AbsBottom + 1 + CenterY);
- return path.IsOutlineVisible(point, pen);
- }
- }
- /// <summary>
- /// Delete point from polyline by index
- /// Recalculate bounds after remove
- /// </summary>
- /// <param name="index">Index of point in polyline</param>
- public void RemovePointAt(int index)
- {
- deletePoint(index);
- if (Report != null)
- if (Report.Designer != null)
- Report.Designer.SetModified(this, "Change");
- }
- /// <inheritdoc/>
- public override void SelectionChanged()
- {
- base.SelectionChanged();
- if (!IsSelected)
- SelectionMode = PolygonSelectionMode.MoveAndScale;
- }
- #endregion Public Methods
- #region Protected Methods
- /// <summary>
- /// Delete point from polyline by index.
- /// Recalculate bounds.
- /// </summary>
- /// <param name="index">Index of point in polyline</param>
- protected void DeletePointByIndex(int index)
- {
- pointsCollection.Remove(index);
- RecalculateBounds();
- }
- /// <inheritdoc/>
- protected override void DrawSelectionPoint(FRPaintEventArgs e, Pen p, Brush b, float x, float y)
- {
- if (SelectionMode == PolygonSelectionMode.MoveAndScale)
- {
- base.DrawSelectionPoint(e, p, b, x, y);
- }
- else
- {
- IGraphics g = e.Graphics;
- x = (float)Math.Round(x * e.ScaleX);
- y = (float)Math.Round(y * e.ScaleY);
- float m = Report.Designer.DpiMultiplier();
- RectangleF rect = new RectangleF(x - 3 * m, y - 3 * m, 6 * m, 6 * m);
- g.FillEllipse(b, rect);
- g.DrawEllipse(p, rect);
- }
- }
- /// <inheritdoc/>
- protected override SelectionPoint[] GetSelectionPoints()
- {
- List<SelectionPoint> selectionPoints = new List<SelectionPoint>();
- if (pointsCollection.Count == 0)
- {
- return new SelectionPoint[] {
- new SelectionPoint(AbsLeft + CenterX, AbsTop + CenterY,SizingPoint.None)
- };
- }
- if (SelectionMode == PolygonSelectionMode.MoveAndScale && pointsCollection.Count > 1)
- {
- return base.GetSelectionPoints();
- }
- if (pointsCollection.Count > 0)
- selectedPoint = (pointsCollection.Count + selectedPoint) % pointsCollection.Count;
- float absLeft = AbsLeft;
- float absTop = AbsTop;
- for (int i = 0; i < pointsCollection.Count; i++)
- {
- PolyPoint point = pointsCollection[i];
- selectionPoints.Add(new SelectionPoint(point.X + absLeft + center.X, point.Y + absTop + center.Y,
- i == selectedPoint ? SizingPoint.LeftTop : SizingPoint.RightBottom));
- if (SelectionMode != PolygonSelectionMode.AddToLine)
- {
- if (point.LeftCurve != null)
- {
- selectionPoints.Add(new SelectionPoint(point.X + absLeft + center.X + point.LeftCurve.X, point.Y + absTop + center.Y + point.LeftCurve.Y, SizingPoint.RightTop));
- }
- else if (SelectionMode == PolygonSelectionMode.AddBezier && i == selectedPoint)
- {
- if (i > 0 || (this is PolygonObject))
- {
- PolyPoint pseudoPoint = GetPseudoPoint(point, pointsCollection[i - 1]);
- selectionPoints.Add(new SelectionPoint(pseudoPoint.X + absLeft + center.X, pseudoPoint.Y + absTop + center.Y, SizingPoint.RightTop));
- }
- }
- if (point.RightCurve != null)
- {
- selectionPoints.Add(new SelectionPoint(point.X + absLeft + center.X + point.RightCurve.X, point.Y + absTop + center.Y + point.RightCurve.Y, SizingPoint.RightTop));
- }
- else if (SelectionMode == PolygonSelectionMode.AddBezier && i == selectedPoint)
- {
- if (i < pointsCollection.Count - 1 || (this is PolygonObject))
- {
- PolyPoint pseudoPoint = GetPseudoPoint(point, pointsCollection[i + 1]);
- selectionPoints.Add(new SelectionPoint(pseudoPoint.X + absLeft + center.X, pseudoPoint.Y + absTop + center.Y, SizingPoint.RightTop));
- }
- }
- }
- }
- return selectionPoints.ToArray();
- }
- #endregion Protected Methods
- #region Private Methods
- private void DrawDesign0(FRPaintEventArgs e)
- {
- if (IsSelected && SelectionMode == PolyLineObject.PolygonSelectionMode.MoveAndScale)
- {
- Pen pen = e.Cache.GetPen(Color.Gray, 1, DashStyle.Dot);
- e.Graphics.DrawRectangle(pen, AbsLeft * e.ScaleX, AbsTop * e.ScaleY, Width * e.ScaleX, Height * e.ScaleY);
- }
- }
- private void DrawDesign1(FRPaintEventArgs e)
- {
- }
- /// <summary>
- /// Returns best new point position based on mouse
- /// </summary>
- /// <returns></returns>
- private int GetBestPointPosition(float localX, float localY)
- {
- if (pointsCollection.Count > 0)
- {
- selectedPoint = (pointsCollection.Count + selectedPoint) % pointsCollection.Count;
- //add near select point
- //check if point is first or last
- if (selectedPoint == pointsCollection.Count - 1 && !(this is PolygonObject))
- {
- return pointsCollection.Count;
- }
- else if (selectedPoint == 0 && !(this is PolygonObject))
- {
- return 0;
- }
- else
- {
- PolyPoint local = new PolyPoint(localX, localY);
- PolyPoint pLeft = pointsCollection[selectedPoint - 1];
- PolyPoint pCenter = pointsCollection[selectedPoint];
- PolyPoint pRight = pointsCollection[selectedPoint + 1];
- //float pLeft_pLocal =
- // ((pLeft.X + CenterX - localX) * (pLeft.X + CenterX - localX) + (pLeft.Y + CenterY - localY) * (pLeft.Y + CenterY - localY));
- //float pRight_pLocal =
- // ((pRight.X + CenterX - localX) * (pRight.X + CenterX - localX) + (pRight.Y + CenterY - localY) * (pRight.Y + CenterY - localY));
- //float pLeft_pCenter = ((pLeft.X - pCenter.X) * (pLeft.X - pCenter.X) + (pLeft.Y - pCenter.Y) * (pLeft.Y - pCenter.Y));
- //float pRight_pCenter = ((pRight.X - pCenter.X) * (pRight.X - pCenter.X) + (pRight.Y - pCenter.Y) * (pRight.Y - pCenter.Y));
- //float distance1 = pLeft_pLocal/ pLeft_pCenter;
- //float distance2 = pRight_pLocal / pRight_pCenter;
- float distance1 = MATH_pnt_seg_dist(local, pLeft, pCenter);
- float distance2 = MATH_pnt_seg_dist(local, pCenter, pRight);
- if (distance1 < distance2)
- {
- return selectedPoint;
- }
- else
- {
- return selectedPoint + 1;
- }
- }
- }
- return 0;
- }
- private PointF GetPointF(int index, float scaleX, float scaleY, float absLeft, float absTop)
- {
- return GetPointF(pointsCollection[index], scaleX, scaleY, absLeft, absTop);
- }
- private PointF GetPointF(PolyPoint point, float scaleX, float scaleY, float absLeft, float absTop)
- {
- return new PointF(
- (point.X + absLeft + center.X) * scaleX,
- (point.Y + absTop + center.Y) * scaleY
- );
- }
- private void InitDesign()
- {
- currentPoint = null;
- SelectionMode = PolygonSelectionMode.MoveAndScale;
- //toolbar = new PolyLineObjectToolBar(this);
- }
- private float MATH_dot(float aX, float aY, float bX, float bY)
- {
- return aX * bX + aY * bY;
- }
- private float MATH_length_squared(PolyPoint a, PolyPoint b)
- {
- return (a.X - b.X) * (a.X - b.X) + (a.Y - b.Y) * (a.Y - b.Y);
- }
- private float MATH_pnt_seg_dist(PolyPoint p, PolyPoint v, PolyPoint w)
- {
- // Return minimum distance between line segment vw and point p
- float l2 = MATH_length_squared(v, w); // i.e. |w-v|^2 - avoid a sqrt
- if (l2 == 0.0) return MATH_length_squared(p, v); // v == w case
- // Consider the line extending the segment, parameterized as v + t (w - v).
- // We find projection of point p onto the line.
- // It falls where t = [(p-v) . (w-v)] / |w-v|^2
- // We clamp t from [0,1] to handle points outside the segment vw.
- float t = Math.Max(0, Math.Min(1, MATH_dot(p.X - v.X, p.Y - v.Y, w.X - v.X, w.Y - v.Y) / l2));
- PolyPoint projection = new PolyPoint(v.X + t * (w.X - v.X), v.Y + t * (w.Y - v.Y)); // Projection falls on the segment
- return MATH_length_squared(p, projection);
- }
- #endregion Private Methods
- }
- }
|