Exemple #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);
        }
Exemple #2
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)));
        }
Exemple #3
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;
            }
        }
Exemple #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);
        }
Exemple #5
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);
        }
Exemple #6
0
        /// <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);
        }
Exemple #7
0
        /// <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);
        }
Exemple #8
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;
            }
        }
Exemple #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);
     }
 }
Exemple #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));
                }
            }
        }
Exemple #11
0
        /// <summary>
        /// Returns true if the given object equals this point.
        /// </summary>
        /// <returns>Returns true if obj is equal.</returns>
        new public Boolean Equals(Object obj)
        {
            if (obj is mxPoint)
            {
                mxPoint pt = (mxPoint)obj;

                return(pt.X == X &&
                       pt.Y == Y);
            }

            return(false);
        }
Exemple #12
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);
        }
Exemple #13
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);
        }
Exemple #14
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;
            }
        }
Exemple #15
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);
            }
        }
Exemple #16
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);
        }
Exemple #17
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;
            }
        }
Exemple #18
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;
                }
            }
        }
Exemple #19
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;
                }
            }
        }
Exemple #20
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;
        }
Exemple #21
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);
        }
Exemple #22
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));
 }
Exemple #23
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;
            }
        }
Exemple #24
0
        /// <summary>
        /// Validates the bounds of the given parent's child using the given parent
        /// state as the origin for the child. The validation is carried out
        /// recursively for all non-collapsed descendants.
        /// </summary>
        /// <param name="parentState">Cell state for the given parent.</param>
        /// <param name="cell">Cell for which the bounds in the state should be updated.</param>
        public void ValidateBounds(mxCellState parentState, Object cell)
        {
            mxIGraphModel model = graph.Model;
            mxCellState   state = GetState(cell, true);

            if (state != null)
            {
                if (!graph.IsCellVisible(cell))
                {
                    RemoveState(cell);
                }
                else if (parentState != null)
                {
                    state.AbsoluteOffset.X = 0;
                    state.AbsoluteOffset.Y = 0;
                    state.Origin           = new mxPoint(parentState.Origin.X,
                                                         parentState.Origin.Y);
                    mxGeometry geo = graph.GetCellGeometry(cell);

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

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

                            if (geo.Relative)
                            {
                                origin.X += geo.X * parentState.Width /
                                            Scale + offset.X;
                                origin.Y += geo.Y * parentState.Height /
                                            Scale + offset.Y;
                            }
                            else
                            {
                                state.AbsoluteOffset = new mxPoint(
                                    scale * offset.X,
                                    scale * offset.Y);
                                origin.X += geo.X;
                                origin.Y += geo.Y;
                            }
                        }

                        // Updates the cell state's bounds
                        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(cell))
                        {
                            UpdateVertexLabelOffset(state);
                        }
                    }
                }

                // Applies child offset to origin
                mxPoint childOffset = graph.GetChildOffsetForCell(cell);

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

            // Recursively validates the child bounds
            if (state != null &&
                !graph.IsCellCollapsed(cell))
            {
                int childCount = model.GetChildCount(cell);

                for (int i = 0; i < childCount; i++)
                {
                    ValidateBounds(state, model.GetChildAt(cell, i));
                }
            }
        }
Exemple #25
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);
     }
 }
Exemple #26
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;
            }
        }
Exemple #27
0
        /// <summary>
        /// Returns the paint bounds for the given label.
        /// </summary>
        /// <returns></returns>
        public static mxRectangle GetLabelPaintBounds(String label,
            Dictionary<string, Object> style, bool isHtml, mxPoint offset,
            mxRectangle vertexBounds, double scale)
        {
            bool horizontal = mxUtils.IsTrue(style, mxConstants.STYLE_HORIZONTAL, true);
            int w = 0;

            if (vertexBounds != null &&
                GetString(style, mxConstants.STYLE_WHITE_SPACE, "nowrap").Equals("wrap"))
            {
                if (horizontal)
                {
                    w = (int)(vertexBounds.Width / scale);
                }
                else
                {
                    w = (int)(vertexBounds.Height / scale);
                }
            }

            mxRectangle size = mxUtils.GetLabelSize(label, style, w);

            double x = offset.X;
            double y = offset.Y;
            double width = 0;
            double height = 0;

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

                // Limits the label to the swimlane title
                if (mxUtils.GetString(style, mxConstants.STYLE_SHAPE, "").Equals(
                    mxConstants.SHAPE_SWIMLANE))
                {
                    double start = mxUtils.GetDouble(style, mxConstants.STYLE_STARTSIZE,
                        mxConstants.DEFAULT_STARTSIZE) * scale;

                    if (horizontal)
                    {
                        width += vertexBounds.Width;
                        height += start;
                    }
                    else
                    {
                        width += start;
                        height += vertexBounds.Height;
                    }
                }
                else
                {
                    width += vertexBounds.Width;
                    height += vertexBounds.Height;
                }
            }

            return mxUtils.GetScaledLabelBounds(x, y,
                size, width, height, style, scale);
        }
Exemple #28
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;
        }
Exemple #29
0
        /// <summary>
        /// Returns the nearest point in the list of absolute points or the center
        /// of the opposite terminal.
        /// </summary>
        /// <param name="vertex">Cell state that represents the vertex.</param>
        /// <param name="constraint">Connection constraint that represents the connection
        /// point constraint as returned by getConnectionConstraint.</param>
        public mxPoint GetConnectionPoint(mxCellState vertex, mxConnectionConstraint constraint)
        {
            mxPoint point = null;

            if (vertex != null &&
                constraint.Point != null)
            {
                point = new mxPoint(vertex.X + constraint.Point.X * vertex.Width,
                        vertex.Y + constraint.Point.Y * vertex.Height);
            }

            if (point != null &&
                constraint.Perimeter)
            {
                point = View.GetPerimeterPoint(vertex, point, false);
            }

            return point;
        }
Exemple #30
0
        /// <summary>
        /// Rotates the given point by the given cos and sin.
        /// </summary>
        public static mxPoint GetRotatedPoint(mxPoint pt, double cos, double sin,
                mxPoint c)
        {
            double x = pt.X - c.X;
            double y = pt.Y - c.Y;

            double x1 = x * cos - y * sin;
            double y1 = y * cos + x * sin;

            return new mxPoint(x1 + c.X, y1 + c.Y);
        }
Exemple #31
0
        /// <summary>
        /// Draws the given lines as segments between all points of the given list
        /// of mxPoints.
        /// </summary>
        /// <param name="pts">List of points that define the line.</param>
        /// <param name="style">Style to be used for painting the line.</param>
        public void DrawLine(List<mxPoint> pts, Dictionary<string, Object> style)
        {
            Color? penColor = mxUtils.GetColor(style, mxConstants.STYLE_STROKECOLOR, Color.Black);
            float penWidth = mxUtils.GetFloat(style, mxConstants.STYLE_STROKEWIDTH, 1);
            Boolean rounded = mxUtils.IsTrue(style, mxConstants.STYLE_ROUNDED, false);

            if (penColor != null && penWidth > 0)
            {
                Pen pen = new Pen((Color)penColor, (float)(penWidth * scale));

                if (mxUtils.IsTrue(style, mxConstants.STYLE_DASHED, false))
                {
                    float[] tmp = { (float)(3 * scale), (float)(3 * scale) };
                    pen.DashPattern = tmp;
                }

                // Draws the shape
                string shape = mxUtils.GetString(style, mxConstants.STYLE_SHAPE, "");

                switch (shape)
                {
                    case (mxConstants.SHAPE_ARROW):
                    {
                        // Base vector (between end points)
                        mxPoint p0 = pts[0];
                        mxPoint pe = pts[pts.Count - 1];

                        int x = (int) Math.Min(p0.X, pe.X);
                        int y = (int) Math.Min(p0.Y, pe.Y);
                        int x1 = (int) Math.Max(p0.X, pe.X);
                        int y1 = (int) Math.Max(p0.Y, pe.Y);
                        int w = x1 - x;
                        int h = y1 - y;

                        Rectangle bounds = new Rectangle(x, y, w, h);

                        bool shadow = mxUtils.IsTrue(style, mxConstants.STYLE_SHADOW, false);
                        Color? fillColor = mxUtils.GetColor(style, mxConstants.STYLE_FILLCOLOR);
                        float opacity = mxUtils.GetFloat(style, mxConstants.STYLE_OPACITY, 100);
                        int alpha = (int)(255 * opacity / 100);
                        Brush brush = null;

                        if (fillColor != null)
                        {
                            Color fill = (Color)fillColor;

                            if (opacity != 100)
                            {
                                fill = Color.FromArgb(alpha, fill.R, fill.G, fill.B);
                            }

                            Color? gradientColor = mxUtils.GetColor(style, mxConstants.STYLE_GRADIENTCOLOR);

                            if (gradientColor != null)
                            {
                                String gradientDirection = mxUtils.GetString(style,
                                        mxConstants.STYLE_GRADIENT_DIRECTION);
                                LinearGradientMode mode = LinearGradientMode.ForwardDiagonal;

                                if (gradientDirection != null
                                        && !gradientDirection
                                                .Equals(mxConstants.DIRECTION_SOUTH))
                                {
                                    if (gradientDirection.Equals(mxConstants.DIRECTION_EAST))
                                    {
                                        mode = LinearGradientMode.BackwardDiagonal;
                                    }
                                    else if (gradientDirection.Equals(mxConstants.DIRECTION_NORTH))
                                    {
                                        mode = LinearGradientMode.Horizontal;
                                    }
                                    else if (gradientDirection.Equals(mxConstants.DIRECTION_WEST))
                                    {
                                        mode = LinearGradientMode.Vertical;
                                    }
                                }

                                brush = new LinearGradientBrush(bounds, fill, (Color)gradientColor, mode);
                            }
                            else
                            {
                                brush = new SolidBrush(fill);
                            }
                        }

                        // Geometry of arrow
                        double spacing = mxConstants.ARROW_SPACING * scale;
                        double width = mxConstants.ARROW_WIDTH * scale;
                        double arrow = mxConstants.ARROW_SIZE * scale;

                        double dx = pe.X - p0.X;
                        double dy = pe.Y - p0.Y;
                        double dist = Math.Sqrt(dx * dx + dy * dy);
                        double length = dist - 2 * spacing - arrow;

                        // Computes the norm and the inverse norm
                        double nx = dx / dist;
                        double ny = dy / dist;
                        double basex = length * nx;
                        double basey = length * ny;
                        double floorx = width * ny / 3;
                        double floory = -width * nx / 3;

                        // Computes points
                        double p0x = p0.X - floorx / 2 + spacing * nx;
                        double p0y = p0.Y - floory / 2 + spacing * ny;
                        double p1x = p0x + floorx;
                        double p1y = p0y + floory;
                        double p2x = p1x + basex;
                        double p2y = p1y + basey;
                        double p3x = p2x + floorx;
                        double p3y = p2y + floory;
                        // p4 not necessary
                        double p5x = p3x - 3 * floorx;
                        double p5y = p3y - 3 * floory;

                        Point[] poly = new Point[]{
                            new Point((int) p0x, (int) p0y),
                            new Point((int) p1x, (int) p1y),
                            new Point((int) p2x, (int) p2y),
                            new Point((int) p3x, (int) p3y),
                            new Point((int) (pe.X - spacing * nx), (int) (pe
                                .Y - spacing * ny)),
                            new Point((int) p5x, (int) p5y),
                            new Point((int) (p5x + floorx), (int) (p5y + floory))};
                        DrawPolygon(poly, brush, pen, shadow);

                        break;
                    }
                    default:
                    {
                        // TODO: Move code into DrawConnector method

                        // Draws the start marker
                        Object marker = mxUtils.GetString(style, mxConstants.STYLE_STARTARROW);

                        mxPoint p0 = pts[0];
                        mxPoint pt = pts[1];
                        mxPoint offset = null;

                        if (marker != null)
                        {
                            float size = (float) (mxUtils.GetFloat(style, mxConstants.STYLE_STARTSIZE,
                                mxConstants.DEFAULT_MARKERSIZE));
                            offset = DrawMarker(marker, pt, p0, size, pen);
                        }
                        else
                        {
                            double dx = pt.X - p0.X;
                            double dy = pt.Y - p0.Y;

                            double dist = Math.Max(1, Math.Sqrt(dx * dx + dy * dy));
                            double nx = dx * penWidth * scale / dist;
                            double ny = dy * penWidth * scale / dist;

                            offset = new mxPoint(nx / 2, ny / 2);
                        }

                        // Applies offset to point
                        if (offset != null)
                        {
                            p0 = p0.Clone();
                            p0.X += offset.X;
                            p0.Y += offset.Y;

                            offset = null;
                        }

                        // Draws the end marker
                        marker = mxUtils.GetString(style, mxConstants.STYLE_ENDARROW);

                        mxPoint pe = pts[pts.Count - 1];
                        pt = pts[pts.Count - 2];

                        if (marker != null)
                        {
                            float size = (float) (mxUtils.GetFloat(style, mxConstants.STYLE_ENDSIZE,
                                 mxConstants.DEFAULT_MARKERSIZE));
                            offset = DrawMarker(marker, pt, pe, size, pen);
                        }
                        else
                        {
                            double dx = pt.X - p0.X;
                            double dy = pt.Y - p0.Y;

                            double dist = Math.Max(1, Math.Sqrt(dx * dx + dy * dy));
                            double nx = dx * penWidth * scale / dist;
                            double ny = dy * penWidth * scale / dist;

                            offset = new mxPoint(nx / 2, ny / 2);
                        }

                        // Applies offset to the point
                        if (offset != null)
                        {
                            pe = pe.Clone();
                            pe.X += offset.X;
                            pe.Y += offset.Y;

                            offset = null;
                        }

                        // Draws the line using a GraphicsPath
                        GraphicsPath path = new GraphicsPath();
                        double arcSize = mxConstants.LINE_ARCSIZE * scale;
                        pt = p0;

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

                            if ((rounded && i < pts.Count - 1) && (dx != 0 || dy != 0)
                                    && scale > 0.3)
                            {
                                // Draws a line from the last point to the current point with a
                                // spacing of size off the current point into direction of the
                                // last point
                                double dist = Math.Sqrt(dx * dx + dy * dy);
                                double nx1 = dx * Math.Min(arcSize, dist / 2) / dist;
                                double ny1 = dy * Math.Min(arcSize, dist / 2) / dist;
                                path.AddLine((float)(pt.X), (float)(pt.Y),
                                    (float)(tmp.X + nx1), (float)(tmp.Y + ny1));

                                // Draws a line from the last point to the current point with a
                                // spacing of size off the current point into direction of the
                                // last point
                                mxPoint next = pts[i + 1];
                                dx = next.X - tmp.X;
                                dy = next.Y - tmp.Y;
                                dist = Math.Max(1, Math.Sqrt(dx * dx + dy * dy));
                                double nx2 = dx * Math.Min(arcSize, dist / 2) / dist;
                                double ny2 = dy * Math.Min(arcSize, dist / 2) / dist;
                                path.AddBezier(
                                    (float)(tmp.X + nx1), (float)(tmp.Y + ny1),
                                    (float)(tmp.X), (float)(tmp.Y),
                                    (float)(tmp.X), (float)(tmp.Y),
                                    (float)(tmp.X + nx2), (float)(tmp.Y + ny2));
                                tmp = new mxPoint(tmp.X + nx2, tmp.Y + ny2);
                            }
                            else
                            {
                                path.AddLine((float)(pt.X), (float)(pt.Y), (float)(tmp.X), (float)(tmp.Y));
                            }

                            pt = tmp;
                        }

                        path.AddLine((float)(pt.X), (float)(pt.Y), (float)(pe.X), (float)(pe.Y));
                        g.DrawPath(pen, path);

                        break;
                    }
                }
            }
        }
Exemple #32
0
        /// <summary>
        /// Draws the given type of marker.
        /// </summary>
        /// <param name="type"></param>
        /// <param name="p0"></param>
        /// <param name="pe"></param>
        /// <param name="size"></param>
        /// <param name="pen"></param>
        /// <returns></returns>
        public mxPoint DrawMarker(Object type, mxPoint p0, mxPoint pe, float size, Pen pen)
        {
            Brush brush = new SolidBrush(pen.Color);
            float strokeWidth = (float) (pen.Width / scale);
            mxPoint offset = null;

            // Computes the norm and the inverse norm
            double dx = pe.X - p0.X;
            double dy = pe.Y - p0.Y;

            double dist = Math.Max(1, Math.Sqrt(dx * dx + dy * dy));
            double absSize = size * scale;
            double nx = dx * absSize / dist;
            double ny = dy * absSize / dist;

            pe = (mxPoint)pe.Clone();
            pe.X -= nx * strokeWidth / (2 * size);
            pe.Y -= ny * strokeWidth / (2 * size);

            nx *= 0.5 + strokeWidth / 2;
            ny *= 0.5 + strokeWidth / 2;

            if (type.Equals(mxConstants.ARROW_CLASSIC))
            {
                GraphicsPath path = new GraphicsPath();
                path.AddLines(new Point[]{
                    new Point((int)Math.Round(pe.X), (int)Math.Round(pe.Y)),
                    new Point((int)Math.Round(pe.X - nx - ny / 2),
                        (int)Math.Round(pe.Y - ny + nx / 2)),
                    new Point((int)Math.Round(pe.X - nx * 3 / 4),
                        (int)Math.Round(pe.Y - ny * 3 / 4)),
                    new Point((int)Math.Round(pe.X + ny / 2 - nx),
                        (int)Math.Round(pe.Y - ny - nx / 2))});
                path.CloseFigure();

                g.FillPath(brush, path);
                g.DrawPath(pen, path);

                offset = new mxPoint(-nx * 3 / 4, -ny * 3 / 4);
            }
            else if (type.Equals(mxConstants.ARROW_BLOCK))
            {
                GraphicsPath path = new GraphicsPath();
                path.AddLines(new Point[]{
                    new Point((int)Math.Round(pe.X), (int)Math.Round(pe.Y)),
                    new Point((int)Math.Round(pe.X - nx - ny / 2),
                        (int)Math.Round(pe.Y - ny + nx / 2)),
                    new Point((int)Math.Round(pe.X + ny / 2 - nx),
                        (int)Math.Round(pe.Y - ny - nx / 2))});
                path.CloseFigure();

                g.FillPath(brush, path);
                g.DrawPath(pen, path);

                offset = new mxPoint(-nx * 3 / 4, -ny * 3 / 4);
            }
            else if (type.Equals(mxConstants.ARROW_OPEN))
            {
                nx *= 1.2;
                ny *= 1.2;

                g.DrawLine(pen, (int)Math.Round(pe.X - nx - ny / 2),
                        (int)Math.Round(pe.Y - ny + nx / 2),
                        (int)Math.Round(pe.X - nx / 6),
                        (int)Math.Round(pe.Y - ny / 6));
                g.DrawLine(pen, (int)Math.Round(pe.X - nx / 6),
                        (int)Math.Round(pe.Y - ny / 6),
                        (int)Math.Round(pe.X + ny / 2 - nx),
                        (int)Math.Round(pe.Y - ny - nx / 2));

                offset = new mxPoint(-nx / 4, -ny / 4);
            }
            else if (type.Equals(mxConstants.ARROW_OVAL))
            {
                nx *= 1.2;
                ny *= 1.2;
                absSize *= 1.2;

                int cx = (int)Math.Round(pe.X - nx / 2);
                int cy = (int)Math.Round(pe.Y - ny / 2);
                int a = (int)Math.Round(absSize / 2);
                int a2 = (int)Math.Round(absSize);

                g.FillEllipse(brush, cx - a, cy - a, a2, a2);
                g.DrawEllipse(pen, cx - a, cy - a, a2, a2);

                offset = new mxPoint(-nx / 2, -ny / 2);
            }
            else if (type.Equals(mxConstants.ARROW_DIAMOND))
            {
                nx *= 1.2;
                ny *= 1.2;

                Point[] poly = new Point[]{
                    new Point((int)Math.Round(pe.X + nx / 2),
                        (int)Math.Round(pe.Y + ny / 2)),
                    new Point((int)Math.Round(pe.X - ny / 2),
                        (int)Math.Round(pe.Y + nx / 2)),
                    new Point((int)Math.Round(pe.X - nx / 2),
                        (int)Math.Round(pe.Y - ny / 2)),
                    new Point((int)Math.Round(pe.X + ny / 2),
                        (int)Math.Round(pe.Y - nx / 2))};

                g.FillPolygon(brush, poly);
                g.DrawPolygon(pen, poly);
            }

            return offset;
        }
Exemple #33
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));
        }
Exemple #34
0
 /// <summary>
 ///
 /// </summary>
 public void Begin()
 {
     currentPath = new GraphicsPath();
     lastPoint   = null;
 }
Exemple #35
0
        /// <summary>
        /// Returns the bounding box of the rotated rectangle.
        /// </summary>
        public static mxRectangle GetBoundingBox(mxRectangle rect, double rotation)
        {
            // TODO: Check use of GraphicsPath (see mxGdiCanvas.DrawText)
            mxRectangle result = null;

            if (rect != null && rotation != 0)
            {
                double rad = ToRadians(rotation);
                double cos = Math.Cos(rad);
                double sin = Math.Sin(rad);

                mxPoint cx = new mxPoint(rect.X + rect.Width / 2,
                    rect.Y + rect.Height / 2);

                mxPoint p1 = new mxPoint(rect.X, rect.Y);
                mxPoint p2 = new mxPoint(rect.X + rect.Width, rect.Y);
                mxPoint p3 = new mxPoint(p2.X, rect.Y + rect.Height);
                mxPoint p4 = new mxPoint(rect.X, p3.Y);

                p1 = GetRotatedPoint(p1, cos, sin, cx);
                p2 = GetRotatedPoint(p2, cos, sin, cx);
                p3 = GetRotatedPoint(p3, cos, sin, cx);
                p4 = GetRotatedPoint(p4, cos, sin, cx);

                result = new mxRectangle((int)p1.X, (int)p1.Y, 0,
                        0);
                result.Add(new mxRectangle(p2.X, p2.Y, 0, 0));
                result.Add(new mxRectangle(p3.X, p3.Y, 0, 0));
                result.Add(new mxRectangle(p4.X, p4.Y, 0, 0));
            }

            return result;
        }
Exemple #36
0
        /// <summary>
        /// Validates the points for the state of the given cell recursively if the
        /// cell is not collapsed and returns the bounding box of all visited states
        /// as a rectangle.
        /// </summary>
        public mxRectangle ValidatePoints(mxCellState parentState, Object cell)
        {
            mxIGraphModel model = graph.Model;
            mxCellState   state = GetState(cell);
            mxRectangle   bbox  = null;

            if (state != null)
            {
                mxGeometry geo = graph.GetCellGeometry(cell);

                if (geo != null && model.IsEdge(cell))
                {
                    // Updates the points on the source terminal if its an edge
                    mxCellState source = GetState(GetVisibleTerminal(cell, true));

                    if (source != null && model.IsEdge(source.Cell) &&
                        !model.IsAncestor(source, cell))
                    {
                        mxCellState tmp = GetState(model.GetParent(source.Cell));
                        ValidatePoints(tmp, source.Cell);
                    }

                    // Updates the points on the target terminal if its an edge
                    mxCellState target = GetState(GetVisibleTerminal(cell, false));

                    if (target != null && model.IsEdge(target.Cell) &&
                        !model.IsAncestor(target.Cell, cell))
                    {
                        mxCellState tmp = GetState(model.GetParent(target.Cell));
                        ValidatePoints(tmp, target.Cell);
                    }

                    UpdateFixedTerminalPoints(state, source, target);
                    UpdatePoints(state, geo.Points, source, target);
                    UpdateFloatingTerminalPoints(state, source, target);
                    UpdateEdgeBounds(state);
                    state.AbsoluteOffset = GetPoint(state, geo);
                }
                else if (geo != null &&
                         geo.Relative &&
                         parentState != null &&
                         model.IsEdge(parentState.Cell))
                {
                    mxPoint origin = GetPoint(parentState, geo);

                    if (origin != null)
                    {
                        state.X = origin.X;
                        state.Y = origin.Y;

                        origin.X     = (origin.X / scale) - translate.X;
                        origin.Y     = (origin.Y / scale) - translate.Y;
                        state.Origin = origin;

                        childMoved(parentState, state);
                    }
                }

                if (model.IsEdge(cell) || model.IsVertex(cell))
                {
                    UpdateLabelBounds(state);
                    bbox = new mxRectangle(UpdateBoundingBox(state));
                }
            }

            if (state != null && !graph.IsCellCollapsed(cell))
            {
                int childCount = model.GetChildCount(cell);

                for (int i = 0; i < childCount; i++)
                {
                    Object      child  = model.GetChildAt(cell, i);
                    mxRectangle bounds = ValidatePoints(state, child);

                    if (bounds != null)
                    {
                        if (bbox == null)
                        {
                            bbox = bounds;
                        }
                        else
                        {
                            bbox.Add(bounds);
                        }
                    }
                }
            }

            return(bbox);
        }
Exemple #37
0
 /// <summary>
 /// Rotates the given point by the given cos and sin.
 /// </summary>
 public static mxPoint GetRotatedPoint(mxPoint pt, double cos, double sin)
 {
     return GetRotatedPoint(pt, cos, sin, new mxPoint());
 }
Exemple #38
0
        /// <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;
        }
Exemple #39
0
        /// <summary>
        /// Returns a connection constraint that describes the given connection
        /// point. This result can then be passed to getConnectionPoint.
        /// </summary>
        /// <param name="edge">Cell state that represents the edge.</param>
        /// <param name="terminal">Cell state that represents the terminal.</param>
        /// <param name="source">Boolean indicating if the terminal is the source or target.</param>
        /// <returns></returns>
        public mxConnectionConstraint GetConnectionConstraint(mxCellState edge, mxCellState terminal, bool source)
        {
            mxPoint point = null;
            string key = (source) ? mxConstants.STYLE_EXIT_X : mxConstants.STYLE_ENTRY_X;

            if (edge.Style.ContainsKey(key))
            {
                double x = mxUtils.GetDouble(edge.Style, key);
                key = (source) ? mxConstants.STYLE_EXIT_Y : mxConstants.STYLE_ENTRY_Y;

                if (edge.Style.ContainsKey(key))
                {
                    double y = mxUtils.GetDouble(edge.Style, key);
                    point = new mxPoint(x, y);
                }
            }

            bool perimeter = false;

            if (point != null)
            {
                perimeter = mxUtils.IsTrue(edge.Style, (source) ?
                    mxConstants.STYLE_EXIT_PERIMETER :
                    mxConstants.STYLE_ENTRY_PERIMETER, true);
            }

            return new mxConnectionConstraint(point, perimeter);
        }
Exemple #40
0
 /// <summary>
 /// Constructs a new point at the location of the given point.
 /// </summary>
 /// <param name="point">Point that specifies the location.</param>
 public mxPoint(mxPoint point) : this(point.X, point.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;
        }
Exemple #42
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;
        }
Exemple #43
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);
 }
Exemple #44
0
 /// <summary>
 /// 
 /// </summary>
 public void Begin()
 {
     currentPath = new GraphicsPath();
     lastPoint = null;
 }
Exemple #45
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 && (source || pts.Count > 2 || opposite == null))
            {
                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;
        }
Exemple #46
0
 /// <summary>
 /// Constructs a new point at the location of the given point.
 /// </summary>
 /// <param name="point">Point that specifies the location.</param>
 public mxPoint(mxPoint point)
     : this(point.X, point.Y)
 {
 }
Exemple #47
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;
                }
            }
        }
Exemple #48
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;
            }
        }
Exemple #49
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;
                }
            }
        }
Exemple #50
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));
        }
Exemple #51
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);
                }
            }
        }
Exemple #52
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;
        }