示例#1
0
        /// <summary>
        /// Sets the fixed source or target terminal point on the given edge.
        /// </summary>
        /// <param name="edge">State whose terminal point should be updated.</param>
        /// <param name="terminal">State which represents the actual terminal.</param>
        /// <param name="source">Boolean that specifies if the terminal is the source.</param>
        /// <param name="constraint">Constraint that specifies the connection.</param>
        public void UpdateFixedTerminalPoint(mxCellState edge, mxCellState terminal,
                                             bool source, mxConnectionConstraint constraint)
        {
            mxPoint pt = null;

            if (constraint != null)
            {
                pt = graph.GetConnectionPoint(terminal, constraint);
            }

            if (pt == null && terminal == null)
            {
                mxPoint    orig = edge.Origin;
                mxGeometry geo  = graph.GetCellGeometry(edge.Cell);
                pt = geo.GetTerminalPoint(source);

                if (pt != null)
                {
                    pt = new mxPoint(scale * (translate.X + pt.X + orig.X),
                                     scale * (translate.Y + pt.Y + orig.Y));
                }
            }

            edge.SetAbsoluteTerminalPoint(pt, source);
        }
示例#2
0
        /// <summary>
        /// Updates the absolute points in the given state using the specified array
        /// of points as the relative points.
        /// </summary>
        /// <param name="edge">Cell state whose absolute points should be updated.</param>
        /// <param name="points">Array of points that constitute the relative points.</param>
        /// <param name="source">Cell that represents the source terminal.</param>
        /// <param name="target">Cell that represents the target terminal.</param>
        public void UpdatePoints(mxCellState edge, List <mxPoint> points, mxCellState source, mxCellState target)
        {
            if (edge != null)
            {
                List <mxPoint> pts = new List <mxPoint>();
                pts.Add(edge.AbsolutePoints[0]);
                mxEdgeStyleFunction edgeStyle = GetEdgeStyle(edge, points, source, target);

                if (edgeStyle != null)
                {
                    mxCellState src = GetTerminalPort(edge, source, true);
                    mxCellState trg = GetTerminalPort(edge, target, false);

                    ((mxEdgeStyleFunction)edgeStyle)(edge, src, trg, points, pts);
                }
                else if (points != null)
                {
                    for (int i = 0; i < points.Count; i++)
                    {
                        if (points[i] is mxPoint)
                        {
                            mxPoint pt = points[i].Clone();
                            pts.Add(TransformControlPoint(edge, pt));
                        }
                    }
                }

                List <mxPoint> tmp = edge.AbsolutePoints;
                pts.Add(tmp[tmp.Count - 1]);

                edge.AbsolutePoints = pts;
            }
        }
示例#3
0
        /// <summary>
        /// Returns a point that defines the location of the intersection point between
        /// the perimeter and the line between the center of the shape and the given point.
        /// </summary>
        /// <param name="terminal">State for the source or target terminal.</param>
        /// <param name="next">Point that lies outside of the given terminal.</param>
        /// <param name="orthogonal">Specifies if the orthogonal projection onto
        /// the perimeter should be returned. If this is false then the intersection
        /// of the perimeter and the line between the next and the center point is
        /// returned.</param>
        /// <param name="border">Optional border between the perimeter and the shape.</param>
        public mxPoint GetPerimeterPoint(mxCellState terminal, mxPoint next, bool orthogonal, double border)
        {
            mxPoint point = null;

            if (terminal != null)
            {
                mxPerimeterFunction perimeter = GetPerimeterFunction(terminal);

                if (perimeter != null && next != null)
                {
                    mxRectangle bounds = GetPerimeterBounds(terminal, border);

                    if (bounds.Width > 0 || bounds.Height > 0)
                    {
                        point = perimeter(bounds, terminal, next, orthogonal);
                    }
                }

                if (point == null)
                {
                    point = GetPoint(terminal);
                }
            }

            return(point);
        }
示例#4
0
        /// <summary>
        /// Draws the shadow.
        /// </summary>
        /// <param name="canvas"></param>
        /// <param name="state"></param>
        /// <param name="rotation"></param>
        /// <param name="flipH"></param>
        /// <param name="flipV"></param>
        /// <param name="bounds"></param>
        /// <param name="alpha"></param>
        protected void DrawShadow(mxGdiCanvas2D canvas, mxCellState state, double rotation, bool flipH,
                                  bool flipV, mxRectangle bounds, double alpha, bool filled)
        {
            // Requires background in generic shape for shadow, looks like only one
            // fillAndStroke is allowed per current path, try working around that
            // Computes rotated shadow offset
            double  rad    = rotation * Math.PI / 180;
            double  cos    = Math.Cos(-rad);
            double  sin    = Math.Sin(-rad);
            mxPoint offset = mxUtils.GetRotatedPoint(new mxPoint(mxConstants.SHADOW_OFFSETX, mxConstants.SHADOW_OFFSETY), cos, sin);

            if (flipH)
            {
                offset.X *= -1;
            }

            if (flipV)
            {
                offset.Y *= -1;
            }

            // TODO: Use save/restore instead of negative offset to restore (requires fix for HTML canvas)
            canvas.Translate(offset.X, offset.Y);

            // Returns true if a shadow has been painted (path has been created)
            if (DrawShape(canvas, state, bounds, true))
            {
                canvas.Alpha = mxConstants.STENCIL_SHADOW_OPACITY * alpha;
                // TODO: Implement new shadow
                //canvas.Shadow(mxConstants.STENCIL_SHADOWCOLOR, filled);
            }

            canvas.Translate(-offset.X, -offset.Y);
        }
        /// <summary>
        /// Returns the absolute, cummulated origin for the children inside the
        /// given parent.
        /// </summary>
        public mxPoint GetOrigin(Object cell)
        {
            mxPoint result = null;

            if (cell != null)
            {
                result = GetOrigin(GetParent(cell));

                if (!IsEdge(cell))
                {
                    mxGeometry geo = GetGeometry(cell);

                    if (geo != null)
                    {
                        result.X += geo.X;
                        result.Y += geo.Y;
                    }
                }
            }
            else
            {
                result = new mxPoint();
            }

            return(result);
        }
示例#6
0
        /// <summary>
        ///
        /// </summary>
        public void QuadTo(double x1, double y1, double x2, double y2)
        {
            if (currentPath != null)
            {
                mxPoint nextPoint = new mxPoint((state.dx + x2) * state.scale,
                                                (state.dy + y2) * state.scale);

                if (lastPoint != null)
                {
                    double cpx0 = lastPoint.X;
                    double cpy0 = lastPoint.Y;
                    double qpx1 = (state.dx + x1) * state.scale;
                    double qpy1 = (state.dy + y1) * state.scale;

                    double cpx1 = cpx0 + 2f / 3f * (qpx1 - cpx0);
                    double cpy1 = cpy0 + 2f / 3f * (qpy1 - cpy0);

                    double cpx2 = nextPoint.X + 2f / 3f * (qpx1 - nextPoint.X);
                    double cpy2 = nextPoint.Y + 2f / 3f * (qpy1 - nextPoint.Y);

                    currentPath.AddBezier((float)cpx0, (float)cpy0,
                                          (float)cpx1, (float)cpy1, (float)cpx2, (float)cpy2,
                                          (float)nextPoint.X, (float)nextPoint.Y);
                }

                lastPoint = nextPoint;
            }
        }
示例#7
0
        /// <summary>
        /// Transforms the given control point to an absolute point.
        /// </summary>
        public mxPoint TransformControlPoint(mxCellState state, mxPoint pt)
        {
            mxPoint orig = state.Origin;

            return(new mxPoint(scale * (pt.X + translate.X + orig.X),
                               scale * (pt.Y + translate.Y + orig.Y)));
        }
        /// <summary>
        /// Parses the bounds, absolute points and label information from the style
        /// of the state into its respective fields and returns the label of the
        /// cell.
        /// </summary>
        public string ParseState(mxCellState state, bool edge)
        {
            Dictionary <string, object> style = state.Style;

            // Parses the bounds
            state.X      = mxUtils.GetDouble(style, "x");
            state.Y      = mxUtils.GetDouble(style, "y");
            state.Width  = mxUtils.GetDouble(style, "width");
            state.Height = mxUtils.GetDouble(style, "height");

            // Parses the absolute points list
            List <mxPoint> pts = ParsePoints(mxUtils.GetString(style, "points"));

            if (pts.Count > 0)
            {
                state.AbsolutePoints = pts;
            }

            // Parses the label and label bounds
            string label = mxUtils.GetString(style, "label");

            if (label != null && label.Length > 0)
            {
                mxPoint offset = new mxPoint(mxUtils.GetDouble(style, "dx"),
                                             mxUtils.GetDouble(style, "dy"));
                mxRectangle vertexBounds = (!edge) ? state : null;
                state.LabelBounds = mxUtils.GetLabelPaintBounds(label, style,
                                                                mxUtils.IsTrue(style, "html", false), offset, vertexBounds,
                                                                scale);
            }

            return(label);
        }
示例#9
0
 /// <summary>
 ///
 /// </summary>
 public void MoveTo(double x, double y)
 {
     if (currentPath != null)
     {
         // StartFigure avoids connection between last figure and new figure
         currentPath.StartFigure();
         lastPoint = new mxPoint((state.dx + x) * state.scale, (state.dy + y) * state.scale);
     }
 }
示例#10
0
        /// <summary>
        /// Inner helper method to update the parent of the specified edge to the
        /// nearest-common-ancestor of its two terminals.
        /// </summary>
        /// <param name="edge">Specifies the edge to be updated.</param>
        /// <param name="root">Current root of the model.</param>
        public void UpdateEdgeParent(Object edge, Object root)
        {
            Object source = GetTerminal(edge, true);
            Object target = GetTerminal(edge, false);
            Object cell   = null;

            // Uses the first non-relative descendants of the source terminal
            while (source != null && !IsEdge(source) &&
                   GetGeometry(source) != null && GetGeometry(source).Relative)
            {
                source = GetParent(source);
            }

            // Uses the first non-relative descendants of the target terminal
            while (target != null && !IsEdge(target) &&
                   GetGeometry(target) != null && GetGeometry(target).Relative)
            {
                target = GetParent(target);
            }

            if (IsAncestor(root, source) &&
                IsAncestor(root, target))
            {
                if (source == target)
                {
                    cell = GetParent(source);
                }
                else
                {
                    cell = GetNearestCommonAncestor(source, target);
                }

                if (cell != null &&
                    GetParent(cell) != root &&
                    GetParent(edge) != cell)
                {
                    mxGeometry geo = GetGeometry(edge);

                    if (geo != null)
                    {
                        mxPoint origin1 = GetOrigin(GetParent(edge));
                        mxPoint origin2 = GetOrigin(cell);

                        double dx = origin2.X - origin1.X;
                        double dy = origin2.Y - origin1.Y;

                        geo = (mxGeometry)geo.Clone();
                        geo.Translate(-dx, -dy);
                        SetGeometry(edge, geo);
                    }

                    Add(cell, edge, GetChildCount(cell));
                }
            }
        }
示例#11
0
        /// <summary>
        /// Sets the sourcePoint or targetPoint to the given point and returns the
        /// new point.
        /// </summary>
        /// <param name="point">Point to be used as the new source or target point.</param>
        /// <param name="source">Boolean that specifies if the source or target point
        /// should be set.</param>
        /// <returns>Returns the new point.</returns>
        public mxPoint SetTerminalPoint(mxPoint point, bool source)
        {
            if (source)
            {
                sourcePoint = point;
            }
            else
            {
                targetPoint = point;
            }

            return(point);
        }
示例#12
0
        /// <summary>
        /// Updates the absolute terminal point in the given state for the given
        /// start and end state, where start is the source if source is true.
        /// </summary>
        /// <param name="edge">State whose terminal point should be updated.</param>
        /// <param name="start">for the terminal on "this" side of the edge.</param>
        /// <param name="end">for the terminal on the other side of the edge.</param>
        /// <param name="source">Boolean indicating if start is the source terminal state.</param>
        public void UpdateFloatingTerminalPoint(mxCellState edge, mxCellState start,
                                                mxCellState end, bool source)
        {
            start = GetTerminalPort(edge, start, source);
            mxPoint next   = GetNextPoint(edge, end, source);
            double  border = mxUtils.GetDouble(edge.Style, mxConstants.STYLE_PERIMETER_SPACING);

            border += mxUtils.GetDouble(edge.Style, (source) ?
                                        mxConstants.STYLE_SOURCE_PERIMETER_SPACING :
                                        mxConstants.STYLE_TARGET_PERIMETER_SPACING);
            mxPoint pt = GetPerimeterPoint(start, next, graph.IsOrthogonal(edge), border);

            edge.SetAbsoluteTerminalPoint(pt, source);
        }
示例#13
0
        /// <summary>
        ///
        /// </summary>
        public void LineTo(double x, double y)
        {
            if (currentPath != null)
            {
                mxPoint nextPoint = new mxPoint((state.dx + x) * state.scale, (state.dy + y) * state.scale);

                if (lastPoint != null)
                {
                    currentPath.AddLine((float)lastPoint.X, (float)lastPoint.Y,
                                        (float)nextPoint.X, (float)nextPoint.Y);
                }

                lastPoint = nextPoint;
            }
        }
示例#14
0
        /// <summary>
        /// Updates the terminal points in the given state after the edge style was
        /// computed for the edge.
        /// </summary>
        /// <param name="state">State whose terminal points should be updated.</param>
        /// <param name="source">State that represents the source terminal.</param>
        /// <param name="target">State that represents the target terminal.</param>
        public void UpdateFloatingTerminalPoints(mxCellState state, mxCellState source, mxCellState target)
        {
            mxPoint p0 = state.AbsolutePoints[0];
            mxPoint pe = state.AbsolutePoints[state.AbsolutePointCount() - 1];

            if (pe == null && target != null)
            {
                UpdateFloatingTerminalPoint(state, target, source, false);
            }

            if (p0 == null && source != null)
            {
                UpdateFloatingTerminalPoint(state, source, target, true);
            }
        }
示例#15
0
        /// <summary>
        /// Returns the nearest point in the list of absolute points or the center
        /// of the opposite terminal.
        /// </summary>
        /// <param name="edge">State that represents the edge.</param>
        /// <param name="opposite">State that represents the opposite terminal.</param>
        /// <param name="source">Boolean indicating if the next point for the source or target
        /// should be returned.</param>
        public mxPoint GetNextPoint(mxCellState edge, mxCellState opposite, bool source)
        {
            List <mxPoint> pts   = edge.AbsolutePoints;
            mxPoint        point = null;

            if (pts != null && pts.Count >= 2)
            {
                int count = pts.Count;
                int index = (source) ? Math.Min(1, count - 1) : Math.Max(0, count - 2);
                point = pts[index];
            }

            if (point == null && opposite != null)
            {
                point = new mxPoint(opposite.GetCenterX(), opposite.GetCenterY());
            }

            return(point);
        }
示例#16
0
        /// <summary>
        ///
        /// </summary>
        public void CurveTo(double x1, double y1, double x2, double y2, double x3,
                            double y3)
        {
            if (currentPath != null)
            {
                mxPoint nextPoint = new mxPoint((state.dx + x3) * state.scale, (state.dy + y3) * state.scale);

                if (lastPoint != null)
                {
                    currentPath.AddBezier((float)lastPoint.X, (float)lastPoint.Y,
                                          (float)((state.dx + x1) * state.scale),
                                          (float)((state.dy + y1) * state.scale),
                                          (float)((state.dx + x2) * state.scale),
                                          (float)((state.dy + y2) * state.scale),
                                          (float)nextPoint.X, (float)nextPoint.Y);
                }

                lastPoint = nextPoint;
            }
        }
示例#17
0
        /// <summary>
        /// Translates the geometry by the specified amount. That is, x and y of the
        /// geometry, the sourcePoint, targetPoint and all elements of points are
        /// translated by the given amount. X and y are only translated if the
        /// geometry is not relative. If TRANSLATE_CONTROL_POINTS is false, then
        /// are not modified by this function.
        /// </summary>
        /// <param name="dx">Integer that specifies the x-coordinate of the translation.</param>
        /// <param name="dy">Integer that specifies the y-coordinate of the translation.</param>
        public void Translate(double dx, double dy)
        {
            // Translates the geometry
            if (!Relative)
            {
                x += dx;
                y += dy;
            }

            // Translates the source point
            if (sourcePoint != null)
            {
                sourcePoint.X += dx;
                sourcePoint.Y += dy;
            }

            // Translates the target point
            if (targetPoint != null)
            {
                targetPoint.X += dx;
                targetPoint.Y += dy;
            }

            // Translate the control points
            if (TRANSLATE_CONTROL_POINTS &&
                points != null)
            {
                int count = points.Count;

                for (int i = 0; i < count; i++)
                {
                    mxPoint pt = points[i];

                    pt.X += dx;
                    pt.Y += dy;
                }
            }
        }
示例#18
0
        /// <summary>
        /// Sets the first or last point in the list of points depending on source.
        /// </summary>
        /// <param name="point">Point that represents the terminal point.</param>
        /// <param name="source">Boolean that specifies if the first or last point should
        /// be assigned.</param>
        public void SetAbsoluteTerminalPoint(mxPoint point, bool source)
        {
            if (source)
            {
                if (absolutePoints == null)
                {
                    absolutePoints = new List <mxPoint>();
                }

                if (absolutePoints == null ||
                    absolutePoints.Count == 0)
                {
                    absolutePoints.Add(point);
                }
                else
                {
                    absolutePoints[0] = point;
                }
            }
            else
            {
                if (absolutePoints == null)
                {
                    absolutePoints = new List <mxPoint>();
                    absolutePoints.Add(null);
                    absolutePoints.Add(point);
                }
                else if (absolutePoints.Count == 1)
                {
                    absolutePoints.Add(point);
                }
                else
                {
                    absolutePoints[absolutePoints.Count - 1] = point;
                }
            }
        }
示例#19
0
        /// <summary>
        /// Constructs a copy of the given geometry.
        /// </summary>
        /// <param name="geometry">Geometry to construct a copy of.</param>
        public mxGeometry(mxGeometry geometry)
            : base(geometry.X, geometry.Y, geometry.Width, geometry
                   .Height)
        {
            if (geometry.points != null)
            {
                points = new List <mxPoint>(geometry.points.Count);

                foreach (mxPoint pt in geometry.points)
                {
                    points.Add(pt.Clone());
                }
            }

            if (geometry.sourcePoint != null)
            {
                sourcePoint = geometry.sourcePoint.Clone();
            }

            if (geometry.targetPoint != null)
            {
                targetPoint = geometry.targetPoint.Clone();
            }

            if (geometry.offset != null)
            {
                offset = geometry.offset.Clone();
            }

            if (geometry.alternateBounds != null)
            {
                alternateBounds = geometry.alternateBounds.Clone();
            }

            relative = geometry.relative;
        }
 /// <summary>
 /// Constructs a new connection constraint for the given point and boolean
 /// arguments.
 /// </summary>
 /// <param name="point">Optional mxPoint that specifies the fixed location of the point
 /// in relative coordinates. Default is null.</param>
 /// <param name="perimeter">Optional boolean that specifies if the fixed point should be
 /// projected onto the perimeter of the terminal. Default is true.</param>
 public mxConnectionConstraint(mxPoint point, bool perimeter)
 {
     Point = point;
     Perimeter = perimeter;
 }
 /// <summary>
 /// Constructs a connection constraint for the given point.
 /// </summary>
 public mxConnectionConstraint(mxPoint point)
     : this(point, true)
 {
 }
示例#22
0
 /// <summary>
 /// Constructs a new connection constraint for the given point and boolean
 /// arguments.
 /// </summary>
 /// <param name="point">Optional mxPoint that specifies the fixed location of the point
 /// in relative coordinates. Default is null.</param>
 /// <param name="perimeter">Optional boolean that specifies if the fixed point should be
 /// projected onto the perimeter of the terminal. Default is true.</param>
 public mxConnectionConstraint(mxPoint point, bool perimeter)
 {
     Point     = point;
     Perimeter = perimeter;
 }
示例#23
0
 /// <summary>
 /// Constructs a connection constraint for the given point.
 /// </summary>
 public mxConnectionConstraint(mxPoint point) : this(point, true)
 {
 }
示例#24
0
        /// <summary>
        /// Updates the given state using the bounding box of the absolute points.
        /// Also updates terminal distance, length and segments.
        /// </summary>
        /// <param name="state">Cell state whose bounds should be updated.</param>
        public void UpdateEdgeBounds(mxCellState state)
        {
            List <mxPoint> points = state.AbsolutePoints;
            mxPoint        p0     = points[0];
            mxPoint        pe     = points[points.Count - 1];

            if (p0 == null || pe == null)
            {
                // Note: This is an error that normally occurs
                // if a connected edge has a null-terminal, ie.
                // edge.source == null or edge.target == null.
                states.Remove(state.Cell);
            }
            else
            {
                if (p0.X != pe.X || p0.Y != pe.Y)
                {
                    double dx = pe.X - p0.X;
                    double dy = pe.Y - p0.Y;
                    state.TerminalDistance = Math.Sqrt(dx * dx + dy * dy);
                }
                else
                {
                    state.TerminalDistance = 0;
                }

                double   length   = 0;
                double[] segments = new double[points.Count - 1];
                mxPoint  pt       = p0;

                if (pt != null)
                {
                    double minX = pt.X;
                    double minY = pt.Y;
                    double maxX = minX;
                    double maxY = minY;

                    for (int i = 1; i < points.Count; i++)
                    {
                        mxPoint tmp = points[i];
                        if (tmp != null)
                        {
                            double dx = pt.X - tmp.X;
                            double dy = pt.Y - tmp.Y;

                            double segment = Math.Sqrt(dx * dx + dy * dy);
                            segments[i - 1] = segment;
                            length         += segment;
                            pt = tmp;

                            minX = Math.Min(pt.X, minX);
                            minY = Math.Min(pt.Y, minY);
                            maxX = Math.Max(pt.X, maxX);
                            maxY = Math.Max(pt.Y, maxY);
                        }
                    }

                    state.Length   = length;
                    state.Segments = segments;
                    double markerSize = 1; // TODO: include marker size

                    state.X      = minX;
                    state.Y      = minY;
                    state.Width  = Math.Max(markerSize, maxX - minX);
                    state.Height = Math.Max(markerSize, maxY - minY);
                }
                else
                {
                    state.Length = 0;
                }
            }
        }
示例#25
0
        /// <summary>
        /// Returns the absolute point on the edge for the given relative
        /// geometry as a point. The edge is represented by the given cell state.
        /// </summary>
        /// <param name="state">Represents the state of the parent edge.</param>
        /// <param name="geometry">Represents the relative location.</param>
        public mxPoint GetPoint(mxCellState state, mxGeometry geometry)
        {
            double x = state.GetCenterX();
            double y = state.GetCenterY();

            if (state.Segments != null && (geometry == null || geometry.Relative))
            {
                double   gx         = (geometry != null) ? geometry.X / 2 : 0;
                int      pointCount = state.AbsolutePoints.Count;
                double   dist       = (gx + 0.5) * state.Length;
                double[] segments   = state.Segments;
                double   segment    = segments[0];
                double   length     = 0;
                int      index      = 1;

                while (dist > length + segment && index < pointCount - 1)
                {
                    length += segment;
                    segment = segments[index++];
                }

                double  factor = (segment == 0) ? 0 : (dist - length) / segment;
                mxPoint p0     = state.AbsolutePoints[index - 1];
                mxPoint pe     = state.AbsolutePoints[index];

                if (p0 != null &&
                    pe != null)
                {
                    double gy      = 0;
                    double offsetX = 0;
                    double offsetY = 0;

                    if (geometry != null)
                    {
                        gy = geometry.Y;
                        mxPoint offset = geometry.Offset;

                        if (offset != null)
                        {
                            offsetX = offset.X;
                            offsetY = offset.Y;
                        }
                    }

                    double dx = pe.X - p0.X;
                    double dy = pe.Y - p0.Y;
                    double nx = (segment == 0) ? 0 : dy / segment;
                    double ny = (segment == 0) ? 0 : dx / segment;

                    x = p0.X + dx * factor + (nx * gy + offsetX) * scale;
                    y = p0.Y + dy * factor - (ny * gy - offsetY) * scale;
                }
            }
            else if (geometry != null)
            {
                mxPoint offset = geometry.Offset;

                if (offset != null)
                {
                    x += offset.X;
                    y += offset.Y;
                }
            }

            return(new mxPoint(x, y));
        }
示例#26
0
 /// <summary>
 /// Returns a point that defines the location of the intersection point between
 /// the perimeter and the line between the center of the shape and the given point.
 /// </summary>
 public mxPoint GetPerimeterPoint(mxCellState terminal, mxPoint next, bool orthogonal)
 {
     return(GetPerimeterPoint(terminal, next, orthogonal, 0));
 }
示例#27
0
        /// <summary>
        /// Updates the given cell state.
        /// </summary>
        /// <param name="state"></param>
        public void UpdateCellState(mxCellState state, mxCellState source, mxCellState target)
        {
            state.AbsoluteOffset.X = 0;
            state.AbsoluteOffset.Y = 0;
            state.Origin.X         = 0;
            state.Origin.Y         = 0;
            state.Length           = 0;

            mxIGraphModel model  = graph.Model;
            mxCellState   pState = GetState(model.GetParent(state.Cell));

            if (pState != null)
            {
                state.Origin.X += pState.Origin.X;
                state.Origin.Y += pState.Origin.Y;
            }

            mxPoint offset = graph.GetChildOffsetForCell(state.Cell);

            if (offset != null)
            {
                state.Origin.X += offset.X;
                state.Origin.Y += offset.Y;
            }

            mxGeometry geo = graph.GetCellGeometry(state.Cell);

            if (geo != null)
            {
                if (!model.IsEdge(state.Cell))
                {
                    mxPoint origin = state.Origin;
                    offset = geo.Offset;

                    if (offset == null)
                    {
                        offset = EMPTY_POINT;
                    }

                    if (geo.Relative && pState != null)
                    {
                        if (model.IsEdge(pState.Cell))
                        {
                            mxPoint orig = GetPoint(pState, geo);

                            if (orig != null)
                            {
                                origin.X += (orig.X / scale) - pState.Origin.X - translate.X;
                                origin.Y += (orig.Y / scale) - pState.Origin.Y - translate.Y;
                            }
                        }
                        else
                        {
                            origin.X += geo.X * pState.Width / scale + offset.X;
                            origin.Y += geo.Y * pState.Height / scale + offset.Y;
                        }
                    }
                    else
                    {
                        state.AbsoluteOffset = new mxPoint(scale * offset.X,
                                                           scale * offset.Y);
                        origin.X += geo.X;
                        origin.Y += geo.Y;
                    }
                }

                state.X      = scale * (translate.X + state.Origin.X);
                state.Y      = scale * (translate.Y + state.Origin.Y);
                state.Width  = scale * geo.Width;
                state.Height = scale * geo.Height;

                if (model.IsVertex(state.Cell))
                {
                    UpdateVertexState(state, geo);
                }

                if (model.IsEdge(state.Cell))
                {
                    UpdateEdgeState(state, geo, source, target);
                }
            }
        }
示例#28
0
 /// <summary>
 ///
 /// </summary>
 public void Begin()
 {
     currentPath = new GraphicsPath();
     lastPoint   = null;
 }