예제 #1
0
파일: TextArea.cs 프로젝트: stuart2w/SAW
 protected override RectangleF CalculateBounds()
 {
     if (!m_BaseLineFixed)
     {
         RectangleF total = new RectangleF(Vertices[0], SizeF.Empty);
         Geometry.Extend(ref total, Vertices[1]);
         return(total);
     }
     else
     {
         // base would use text - but we need to include the corners for the highlighter
         EnsureTextFormatted();
         float height = 0;
         if (m_Fragments != null && m_Fragments.Count > 0)
         {
             height = m_Fragments[m_Fragments.Count - 1].Bounds.Bottom - m_Fragments[0].Bounds.Top;
         }
         RectangleF rct = new RectangleF();
         Geometry.Extend(ref rct, Vertices[0]);
         Geometry.Extend(ref rct, Vertices[1]);
         if (height > 0)
         {
             SizeF sz = Vertices[0].VectorTo(Vertices[1]).Perpendicular(1);                     // down vector
             sz = sz.ChangeLength(height);
             Geometry.Extend(ref rct, Vertices[0] + sz);
             Geometry.Extend(ref rct, Vertices[1] + sz);
         }
         return(rct);
     }
 }
예제 #2
0
        public override VerbResult OtherVerb(EditableView.ClickPosition position, SAW.Functions.Codes code)
        {
            switch (code)
            {
            case SAW.Functions.Codes.Increment:
            case SAW.Functions.Codes.Decrement:
                int   delta = code == SAW.Functions.Codes.Increment ? 1 : -1;
                float step  = position.ScalarSnapStep(0);
                if (step <= 0)
                {
                    step = delta * Globals.Root.CurrentConfig.ReadSingle(Config.Radius_Step, 1);
                }
                else
                {
                    step *= delta;
                }
                SizeF vector = Vertices[0].VectorTo(Vertices[1]);
                float length = vector.Length();
                if (length + step < 5 || length < Geometry.NEGLIGIBLESMALL)
                {
                    return(VerbResult.Rejected);
                }
                Vertices[1] = Vertices[0] + vector.ChangeLength(length + step);
                m_Bounds    = RectangleF.Empty;
                return(VerbResult.Continuing);

            default:
                return(VerbResult.Rejected);
            }
        }
예제 #3
0
        protected internal override void DoGrabMove(GrabMovement move)
        {
            switch (move.GrabType)
            {
            case GrabTypes.SingleVertex:
                if (move.ShapeIndex != 1)
                {
                    Debug.Fail("Isosceles.DoGrabMove(SingleVertex): index must be 1");
                    return;
                }
                if (move.Current.Snapped.ApproxEqual(Vertices[0]))
                {
                    return;
                }
                int   direction      = base.TurnDirection();                  // maintain the same winding direction, and transverse length (i.e. from baseline to third point)
                float transverseSize = Geometry.DistancePointToLine(Vertices[0], Vertices[1], Vertices[2]);
                Vertices[1] = move.Current.Snapped;
                SizeF transverseVector = BaseVector().Perpendicular(direction);
                transverseVector = transverseVector.ChangeLength(transverseSize);                         // the correct, new vector from the midpoint of the baseline
                Vertices[2]      = PointF.Add(Geometry.MidPoint(Vertices[0], Vertices[1]), transverseVector);
                m_Bounds         = CalculateBounds();
                break;

            case GrabTypes.Radius:                     // this moves the last point
                if (move.ShapeIndex != 2)
                {
                    Debug.Fail("Isosceles.DoGrabMove(Radius): index must be 1");
                    return;
                }
                PointF original   = Vertices[2];
                SizeF  baseVector = BaseVector().MultiplyBy(0.5f);                        // actually half the base vector
                Vertices[2] = Geometry.PerpendicularPoint(Vertices[0], Vertices[0] + baseVector, move.Current.Exact);
                if (VerticesFormLine(0))
                {
                    Vertices[2] = original;                             // cannot store this
                }
                m_Bounds = CalculateBounds();
                break;

            default:
                base.DoGrabMove(move);
                break;
            }
            DiscardPath();
        }
예제 #4
0
        public override bool Tidy(SnapModes mode, Page page)
        {
            int  direction = base.TurnDirection();
            bool changed   = base.TidyVertices(mode, page, 2);

            if (changed)
            {
                // just need to check that the vertices do not form a single line
                if (Geometry.PointApproxOnLine(Vertices[0], Vertices[1], Vertices[2]))
                {
                    // move the point again to get it off the line
                    if (direction == 0)
                    {
                        direction = 1;                         // just in case it was already a single line
                    }
                    SizeF vector = Vertices[0].VectorTo(Vertices[1]).Perpendicular(direction);
                    Vertices[2] = Vertices[2] + vector.ChangeLength(page.Paper.UnitStep);                     // UnitStep always returns a valid value
                }
            }
            return(changed);
        }
예제 #5
0
파일: Connector.cs 프로젝트: stuart2w/SAW
        private void ProcessExitVector(List <PointF> points, int index, float primaryAngle)
        {
            // index is 0 or 1; specifying which end we are looking at
            Shape shape = m_Links[index].Shape;             // the shape that this end is connected to

            if (shape == null)
            {
                return;                 // just stops at this point, no processing needed if not attached to a shape
            }
            SizeF exitVector = shape.SocketExitVector(ResolveIndefiniteSocket(index));
            float exitAngle  = Geometry.NormaliseAngle(exitVector.VectorAngle());
            float difference = Math.Abs(Geometry.AngleBetween(exitAngle, Geometry.NormaliseAngle(primaryAngle)));

            if (difference < EXITANGLETOLERANCE || difference > Geometry.ANGLE360 - EXITANGLETOLERANCE)
            {
                // the line exits in roughly the right direction, we don't need to add an exit stage
            }
            else
            {
                exitVector = exitVector.ChangeLength(EXITSTAGELENGTH);
                PointF exitPoint = points[0] + exitVector;
                // need to see if this has cleared the shape boundary
                RectangleF bounds = shape.Bounds;
                if (bounds.Contains(exitPoint))
                {
                    // find where the exit vector crosses the boundary
                    //initially set the exit point a long distance away to test for the intersections.  I think we need to test each of the four edges of the bounding rectangle separately
                    exitPoint = points[0] + exitVector.ChangeLength(1000);
                    // top:
                    PointF intersection = Intersection.Line_LineIntersection(points[0], exitPoint, new PointF(bounds.Left, bounds.Top), new PointF(bounds.Right, bounds.Top));
                    // right:
                    if (intersection.IsEmpty)
                    {
                        intersection = Intersection.Line_LineIntersection(points[0], exitPoint, new PointF(bounds.Right, bounds.Top), new PointF(bounds.Right, bounds.Bottom));
                    }
                    // bottom:
                    if (intersection.IsEmpty)
                    {
                        intersection = Intersection.Line_LineIntersection(points[0], exitPoint, new PointF(bounds.Left, bounds.Bottom), new PointF(bounds.Right, bounds.Bottom));
                    }
                    // left:
                    if (intersection.IsEmpty)
                    {
                        intersection = Intersection.Line_LineIntersection(points[0], exitPoint, new PointF(bounds.Left, bounds.Top), new PointF(bounds.Left, bounds.Bottom));
                    }
                    if (intersection.IsEmpty)
                    {
                        // huh
                        Debug.Fail("Failed to find where exit vector leaves the bounding rectangle");
                        // leave szExit with the default length
                    }
                    else
                    {
                        float length = Geometry.DistanceBetween(intersection, points[0]);
                        exitVector = exitVector.ChangeLength(length + EXITSTAGELENGTH / 2);                         // second term gets us a bit outside the rectangle
                    }
                    exitPoint = points[0] + exitVector;
                }
                points.Add(exitPoint);
            }
        }