示例#1
0
        /// <summary>
        /// Draws the given cell and label onto the specified canvas. No
        /// children or descendants are painted.
        /// </summary>
        public void DrawState(mxICanvas canvas, mxCellState state, String label)
        {
            Object cell = (state != null) ? state.Cell : null;

            if (cell != null && cell != model.Root && (model.IsVertex(cell) || model.IsEdge(cell)))
            {
                Object obj = canvas.DrawCell(state);
                Object lab = null;

                // Holds the current clipping region in case the label will
                // be clipped
                Region clip = null;
                Region newClip = new Region(state.GetRectangle());

                // Indirection for image canvas that contains a graphics canvas
                mxICanvas clippedCanvas = (mxUtils.GetString(state.Style, mxConstants.
                    STYLE_OVERFLOW, "").Equals("hidden")) ? canvas : null;

                if (clippedCanvas is mxImageCanvas)
                {
                    clippedCanvas = ((mxImageCanvas) clippedCanvas).GdiCanvas;
                    Point pt = ((mxImageCanvas) canvas).Translate;
                    newClip.Translate(pt.X, pt.Y);
                }

                if (clippedCanvas is mxGdiCanvas)
                {
                    Graphics g = ((mxGdiCanvas) clippedCanvas).Graphics;
                    clip = g.Clip;
                    g.Clip = newClip;
                }

                if (label != null && state.LabelBounds != null)
                {
                    lab = canvas.DrawLabel(label, state, false);
                }

                // Restores the previous clipping region
                if (clippedCanvas is mxGdiCanvas)
                {
                    ((mxGdiCanvas)clippedCanvas).Graphics.Clip = clip;
                }

                // Invokes the cellDrawn callback with the object which was created
                // by the canvas to represent the cell graphically
                if (obj != null)
                {
                    // LATER: Add inner callback for rendering
                    //CellDrawn(cell, obj, lab);
                }
            }
        }
示例#2
0
        /// <summary>
        /// Returns the bottom-most cell that intersects the given point (x, y) in
        /// the cell hierarchy that starts at the given parent.
        /// </summary>
        /// <param name="state"></param>
        /// <param name="rect"></param>
        /// <returns>Returns true if the given cell state and rectangle intersect.</returns>
        public bool Intersects(mxCellState state, Rectangle rect)
        {
            if (state != null)
            {
                // Checks if the label intersects
                if (state.LabelBounds != null
                        && state.LabelBounds.GetRectangle().IntersectsWith(rect))
                {
                    return true;
                }

                int pointCount = state.AbsolutePointCount();

                // Checks if the segments of the edge intersect
                if (pointCount > 0)
                {
                    mxRectangle tmp = new mxRectangle(rect);
                    tmp.Grow(tolerance);
                    rect = tmp.GetRectangle();

                    mxPoint p0 = state.AbsolutePoints[0];

                    for (int i = 0; i < pointCount; i++)
                    {
                        mxPoint p1 = state.AbsolutePoints[i];

                        // FIXME: Implement line intersection check
                        //if (rect.IntersectsLine(p0.X, p0.Y, p1.X, p1
                        //        .Y))
                        //    return true;

                        p0 = p1;
                    }
                }
                else
                {
                    // Checks if the bounds of the shape intersect
                    return state.GetRectangle().IntersectsWith(rect);
                }
            }

            return false;
        }
示例#3
0
        /// <summary>
        /// Updates the bounding box in the given cell state.
        /// </summary>
        /// <param name="state">Cell state whose bounding box should be
        /// updated.</param>
        /// <returns></returns>
        public mxRectangle UpdateBoundingBox(mxCellState state)
        {
            // Gets the cell bounds and adds shadows and markers
            mxRectangle rect = new mxRectangle(state.GetRectangle());
            Dictionary <string, Object> style = state.Style;

            // Adds extra pixels for the marker and stroke assuming
            // that the border stroke is centered around the bounds
            // and the first pixel is drawn inside the bounds
            double strokeWidth = Math.Max(1, Math.Round(mxUtils.GetInt(style,
                                                                       mxConstants.STYLE_STROKEWIDTH, 1)
                                                        * scale));

            strokeWidth -= Math.Max(1, strokeWidth / 2);

            if (graph.Model.IsEdge(state.Cell))
            {
                int ms = 0;

                if (style.ContainsKey(mxConstants.STYLE_ENDARROW) ||
                    style.ContainsKey(mxConstants.STYLE_STARTARROW))
                {
                    ms = (int)Math.Round(mxConstants.DEFAULT_MARKERSIZE * scale);
                }

                // Adds the strokewidth
                rect.Grow(ms + strokeWidth);

                // Adds worst case border for an arrow shape
                if (mxUtils.GetString(style, mxConstants.STYLE_SHAPE, "").Equals(
                        mxConstants.SHAPE_ARROW))
                {
                    rect.Grow(mxConstants.ARROW_WIDTH / 2);
                }
            }
            else
            {
                rect.Grow(strokeWidth);
            }

            // Adds extra pixels for the shadow
            if (mxUtils.IsTrue(style, mxConstants.STYLE_SHADOW))
            {
                rect.Width  += mxConstants.SHADOW_OFFSETX;
                rect.Height += mxConstants.SHADOW_OFFSETY;
            }

            // Adds oversize images in labels
            if (mxUtils.GetString(style, mxConstants.STYLE_SHAPE, "").Equals(
                    mxConstants.SHAPE_LABEL))
            {
                if (mxUtils.GetString(style, mxConstants.STYLE_IMAGE) != null)
                {
                    double w = mxUtils.GetInt(style,
                                              mxConstants.STYLE_IMAGE_WIDTH,
                                              mxConstants.DEFAULT_IMAGESIZE) * scale;
                    double h = mxUtils.GetInt(style,
                                              mxConstants.STYLE_IMAGE_HEIGHT,
                                              mxConstants.DEFAULT_IMAGESIZE) * scale;

                    double x = state.X;
                    double y = 0;

                    string imgAlign = mxUtils
                                      .GetString(style, mxConstants.STYLE_IMAGE_ALIGN,
                                                 mxConstants.ALIGN_LEFT);
                    string imgValign = mxUtils.GetString(style,
                                                         mxConstants.STYLE_IMAGE_VERTICAL_ALIGN,
                                                         mxConstants.ALIGN_MIDDLE);

                    if (imgAlign.Equals(mxConstants.ALIGN_RIGHT))
                    {
                        x += state.Width - w;
                    }
                    else if (imgAlign.Equals(mxConstants.ALIGN_CENTER))
                    {
                        x += (state.Width - w) / 2;
                    }

                    if (imgValign.Equals(mxConstants.ALIGN_TOP))
                    {
                        y = state.Y;
                    }
                    else if (imgValign.Equals(mxConstants.ALIGN_BOTTOM))
                    {
                        y = state.Y + state.Height - h;
                    }
                    else
                    {
                        y = state.Y + (state.Height - h) / 2;
                    }

                    rect.Add(new mxRectangle(x, y, w, h));
                }
            }

            // Adds the rotated bounds to the bounding box if the
            // shape is rotated
            double      rotation = mxUtils.GetDouble(style, mxConstants.STYLE_ROTATION);
            mxRectangle bbox     = mxUtils.GetBoundingBox(rect, rotation);

            // Add the rotated bounding box to the non-rotated so
            // that all handles are also covered
            if (bbox != null)
            {
                rect.Add(bbox);
            }

            // Unifies the cell bounds and the label bounds
            if (!mxUtils.GetString(style, mxConstants.STYLE_OVERFLOW, "").Equals("hidden"))
            {
                rect.Add(state.LabelBounds);
            }

            state.BoundingBox = rect;

            return(rect);
        }
示例#4
0
        /// <summary>
        /// see com.mxgraph.mxICanvas.DrawLabel()
        /// </summary>
        public override Object DrawLabel(string text, mxCellState state, bool html)
        {
            Dictionary<string, object> style = state.Style;
            GraphicsState graphicsState = g.Save();

            // Applies the local translation
            g.TranslateTransform(translate.X, translate.Y);

            Rectangle bounds = (state.LabelBounds != null) ? state.LabelBounds.GetRectangle() : state.GetRectangle();
            DrawText(text, bounds.X, bounds.Y, bounds.Width, bounds.Height, style);

            // Resets all changes to the graphics configuration
            g.Restore(graphicsState);

            return null;
        }
示例#5
0
        /// <summary>
        /// see com.mxgraph.mxICanvas.DrawCell()
        /// </summary>
        public override Object DrawCell(mxCellState state)
        {
            Dictionary<string, object> style = state.Style;
            GraphicsState graphicsState = g.Save();

            // Applies the local translation
            g.TranslateTransform(translate.X, translate.Y);

            // Checks if the cell is an edge
            if (state.AbsolutePointCount() > 1)
            {
                DrawLine(state.AbsolutePoints, style);
            }
            else
            {
                Rectangle bounds = state.GetRectangle();
                int x = bounds.X;
                int y = bounds.Y;
                int w = bounds.Width;
                int h = bounds.Height;

                // Applies the rotation on the graphics object and stores
                // the previous transform so that it can be restored
                float rotation = mxUtils.GetFloat(style, mxConstants.STYLE_ROTATION);

                if (rotation != 0)
                {
                    int cx = x + w / 2;
                    int cy = y + h / 2;

                    g.TranslateTransform(cx, cy);
                    g.RotateTransform(rotation);
                    g.TranslateTransform(-cx, -cy);
                }

                // Draws a swimlane if start is > 0
                string shape = mxUtils.GetString(style, mxConstants.STYLE_SHAPE, "");

                if (!shape.Equals(mxConstants.SHAPE_SWIMLANE))
                {
                    // NOTE: Should draw built-in shapes first
                    mxStencil stencil = mxStencilRegistry.GetStencil(shape);

                    if (stencil != null)
                    {
                        stencil.PaintShape(this, state);
                    }
                    else
                    {
                        DrawShape(x, y, w, h, style);
                    }
                }
                else
                {
                    int start = (int)Math.Round(mxUtils.GetDouble(style,
                        mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE) * scale);

                    // Removes some styles to draw the content area
                    Dictionary<string, Object> cloned = new Dictionary<string, Object>(style);
                    cloned.Remove(mxConstants.STYLE_FILLCOLOR);
                    cloned.Remove(mxConstants.STYLE_ROUNDED);

                    if (mxUtils.IsTrue(style, mxConstants.STYLE_HORIZONTAL, true))
                    {
                        DrawShape(x, y, w, Math.Min(h, start), style);
                        DrawShape(x, y + start, w, h - start, cloned);
                    }
                    else
                    {
                        DrawShape(x, y, Math.Min(w, start), h, style);
                        DrawShape(x + start, y, w - start, h, cloned);
                    }
                }
            }

            // Resets all changes to the graphics configuration
            g.Restore(graphicsState);

            return null;
        }
示例#6
0
        /// <summary>
        /// Updates the bounding box in the given cell state.
        /// </summary>
        /// <param name="state">Cell state whose bounding box should be
        /// updated.</param>
        /// <returns></returns>
        public mxRectangle UpdateBoundingBox(mxCellState state)
        {
            // Gets the cell bounds and adds shadows and markers
            mxRectangle rect = new mxRectangle(state.GetRectangle());
            Dictionary<string, Object> style = state.Style;

            // Adds extra pixels for the marker and stroke assuming
            // that the border stroke is centered around the bounds
            // and the first pixel is drawn inside the bounds
            double strokeWidth = Math.Max(1, Math.Round(mxUtils.GetInt(style,
                    mxConstants.STYLE_STROKEWIDTH, 1)
                    * scale));
            strokeWidth -= Math.Max(1, strokeWidth / 2);

            if (graph.Model.IsEdge(state.Cell))
            {
                int ms = 0;

                if (style.ContainsKey(mxConstants.STYLE_ENDARROW)
                        || style.ContainsKey(mxConstants.STYLE_STARTARROW))
                {
                    ms = (int) Math.Round(mxConstants.DEFAULT_MARKERSIZE * scale);
                }

                // Adds the strokewidth
                rect.Grow(ms + strokeWidth);

                // Adds worst case border for an arrow shape
                if (mxUtils.GetString(style, mxConstants.STYLE_SHAPE, "").Equals(
                        mxConstants.SHAPE_ARROW))
                {
                    rect.Grow(mxConstants.ARROW_WIDTH / 2);
                }
            }
            else
            {
                rect.Grow(strokeWidth);
            }

            // Adds extra pixels for the shadow
            if (mxUtils.IsTrue(style, mxConstants.STYLE_SHADOW))
            {
                rect.Width += mxConstants.SHADOW_OFFSETX;
                rect.Height += mxConstants.SHADOW_OFFSETY;
            }

            // Adds oversize images in labels
            if (mxUtils.GetString(style, mxConstants.STYLE_SHAPE, "").Equals(
                    mxConstants.SHAPE_LABEL))
            {
                if (mxUtils.GetString(style, mxConstants.STYLE_IMAGE) != null)
                {
                    double w = mxUtils.GetInt(style,
                            mxConstants.STYLE_IMAGE_WIDTH,
                            mxConstants.DEFAULT_IMAGESIZE) * scale;
                    double h = mxUtils.GetInt(style,
                            mxConstants.STYLE_IMAGE_HEIGHT,
                            mxConstants.DEFAULT_IMAGESIZE) * scale;

                    double x = state.X;
                    double y = 0;

                    string imgAlign = mxUtils
                            .GetString(style, mxConstants.STYLE_IMAGE_ALIGN,
                                    mxConstants.ALIGN_LEFT);
                    string imgValign = mxUtils.GetString(style,
                            mxConstants.STYLE_IMAGE_VERTICAL_ALIGN,
                            mxConstants.ALIGN_MIDDLE);

                    if (imgAlign.Equals(mxConstants.ALIGN_RIGHT))
                    {
                        x += state.Width - w;
                    }
                    else if (imgAlign.Equals(mxConstants.ALIGN_CENTER))
                    {
                        x += (state.Width - w) / 2;
                    }

                    if (imgValign.Equals(mxConstants.ALIGN_TOP))
                    {
                        y = state.Y;
                    }
                    else if (imgValign.Equals(mxConstants.ALIGN_BOTTOM))
                    {
                        y = state.Y + state.Height - h;
                    }
                    else
                    {
                        y = state.Y + (state.Height - h) / 2;
                    }

                    rect.Add(new mxRectangle(x, y, w, h));
                }
            }

            // Adds the rotated bounds to the bounding box if the
            // shape is rotated
            double rotation = mxUtils.GetDouble(style, mxConstants.STYLE_ROTATION);
            mxRectangle bbox = mxUtils.GetBoundingBox(rect, rotation);

            // Add the rotated bounding box to the non-rotated so
            // that all handles are also covered
            if (bbox != null)
            {
                rect.Add(bbox);
            }

            // Unifies the cell bounds and the label bounds
            if (!mxUtils.GetString(style, mxConstants.STYLE_OVERFLOW, "").Equals("hidden"))
            {
                rect.Add(state.LabelBounds);
            }

            state.BoundingBox = rect;

            return rect;
        }