Пример #1
0
		/// <summary>
		/// Initializes a new instance of the FlowChart class.
		/// </summary>
		public FlowChart()
		{
			license = LicenseManager.Validate(typeof(FlowChart), this);

			measureUnit = GraphicsUnit.Millimeter;

			// set control styles for flicker-free redraw
			SetStyle(ControlStyles.UserPaint, true);
			SetStyle(ControlStyles.AllPaintingInWmPaint, true);
			SetStyle(ControlStyles.Opaque, true);
			SetStyle(ControlStyles.ResizeRedraw, true);

			// we want to process keyboard input
			SetStyle(ControlStyles.Selectable, true);
     
			// init static objects
			lock (syncRoot)
			{
				Arrow.initHeadTemplates();
				CustomCursors.Init(new ResourceManager(
					"MindFusion.FlowChartX.Cursors", typeof(ChartObject).Assembly));
			}

			mouseMoved = false;

			boxFillColor = Color.FromArgb(220, 220, 255);
			boxFrameColor = Color.Black;
			arrowColor = Color.Black;
			arrowTextStyle = ArrowTextStyle.Center;
			arrowFillColor = Color.FromArgb(120, 220, 255);
			tableFrameColor = Color.Black;
			tableFillColor = Color.FromArgb(180, 160, 160);
			penDashStyle = DashStyle.Solid;
			penWidth = 0;
			BackColor = Color.FromArgb(170, 170, 200);

			// grid properties
			alignToGrid = true;
			showGrid = false;
			gridColor = Color.FromArgb(140, 140, 150);
			gridSizeX = 4;
			gridSizeY = 4;
			gridStyle = GridStyle.Points;

			// shadows properties
			shadowOffsetX = 1;
			shadowOffsetY = 1;
			shadowColor = Color.FromArgb(110, 110, 140);
			shadowsStyle = ShadowsStyle.OneLevel;

			activeMnpColor = Color.White;
			selMnpColor = Color.FromArgb(170, 170, 170);
			disabledMnpColor = Color.FromArgb(200, 0, 0);

			textFormat = new StringFormat();
			textFormat.Alignment = StringAlignment.Center;
			textFormat.LineAlignment = StringAlignment.Center;

			// Set some flags, because otherwise the serializer
			// generates noncompilable code
			textFormat.FormatFlags = StringFormatFlags.NoFontFallback;

			imagePos = ImageAlign.Document;

			boxStyle = BoxStyle.RoundedRectangle;
			tableStyle = TableStyle.Rectangle;

			boxPen = new Pen(boxFrameColor, penWidth);
			boxBrush = new SolidBrush(boxFillColor);
			boxBrush.AddRef();
			arrowPen = new Pen(arrowColor, penWidth);
			arrowBrush = new SolidBrush(arrowFillColor);
			arrowBrush.AddRef();
			tablePen = new Pen(tableFrameColor, penWidth);
			tableBrush = new SolidBrush(tableFillColor);
			tableBrush.AddRef();

			exteriorBrush = null;
			brush = new SolidBrush(BackColor);
			brush.AddRef();

			boxes = new BoxCollection();
			controlHosts = new ControlHostCollection();
			tables = new TableCollection();
			arrows = new ArrowCollection();
			selection = new Selection(this);
			selectionOnTop = true;

			groups = new GroupCollection();

			zOrder = new ChartObjectCollection();

			textColor = Color.Black;
			arrowStyle = MindFusion.FlowChartX.ArrowStyle.Polyline;
			arrowSegments = 1;
			activeObject = null;

			modificationStart = ModificationStyle.SelectedOnly;
			autoHandlesObj = null;
			autoAnchorsObj = null;

			interaction = null;

			scrollX = scrollY = 0;
			zoomFactor = 100.0f;
			allowRefLinks = true;
			Behavior = BehaviorType.FlowChart;
			arrowEndsMovable = true;
			selectAfterCreate = true;

			// init default custom draw properties
			boxCustomDraw = CustomDraw.None;
			tableCustomDraw = CustomDraw.None;
			cellCustomDraw = CustomDraw.None;
			arrowCustomDraw = CustomDraw.None;

			restrObjsToDoc = RestrictToDoc.Intersection;
			dynamicArrows = false;
			arrowsSnapToBorders = false;
			arrowsRetainForm = false;
			arrowCascadeOrientation = Orientation.Auto;

			curPointer = Cursors.Arrow;
			curCannotCreate = Cursors.No;
			curModify = Cursors.SizeAll;
			curArrowStart = Cursors.Hand;
			curArrowEnd = Cursors.Hand;
			curArrowCannotCreate = Cursors.No;
			curHorzResize = Cursors.SizeWE;
			curVertResize = Cursors.SizeNS;
			curMainDgnlResize = Cursors.SizeNWSE;
			curSecDgnlResize = Cursors.SizeNESW;
			curRotateShape = CustomCursors.Rotate;
			panCursor = Cursors.NoMove2D;

			tableRowsCount = 4;
			tableColumnsCount = 2;
			tableRowHeight = 6;
			tableColWidth = 18;
			tableCaptionHeight = 5;
			tableCaption = "Table";
			tableCellBorders = CellFrameStyle.System3D;

			selHandleSize = 2;

			showDisabledHandles = true;
			arrowSelStyle = HandlesStyle.SquareHandles;
			boxSelStyle = HandlesStyle.SquareHandles;
			chostSelStyle = HandlesStyle.HatchHandles;
			tableSelStyle = HandlesStyle.DashFrame;

			recursiveExpand = false;
			expandOnIncoming = false;
			boxesExpandable = false;
			tablesScrollable = false;
			tablesExpandable = false;
			controlHostsExpandable = false;

			arrowHead = ArrowHead.Arrow;
			arrowBase = ArrowHead.None;
			arrowInterm = ArrowHead.None;

			arrowHeadSize = 5;
			arrowBaseSize = 5;
			arrowIntermSize = 5;

			ShowScrollbars = true;
			DocExtents = new RectangleF(0, 0, 210, 297);

			autoScroll = true;
			autoScrDX = autoScrDY = 0;

			dirty = false;
			antiAlias = SmoothingMode.None;
			textRendering = TextRenderingHint.SystemDefault;
			sortGroupsByZ = false;

			// tooltips
			showToolTips = true;
			toolTip = "";
			toolTipCtrl = new ToolTip();
			toolTipCtrl.Active = showToolTips;

			shapeRotation = 0;
			DefaultShape = ShapeTemplate.FromId("Cylinder");

			inplaceEditAllowed = false;
			inplaceObject = null;
			nowEditing = false;
			inplaceEditFont = (Font)Font.Clone();
			inplaceAcceptOnEnter = false;
			inplaceCancelOnEsc = true;

			allowSplitArrows = false;

			printOptions = new PrintOptions(this);
			printOptions.EnableBackground = false;
			printOptions.EnableBackgroundImage = false;
			printOptions.PaintControls = true;

			displayOptions = new PrintOptions(this);
			renderOptions = displayOptions;

			previewOptions = new PreviewOptions();

			allowLinksRepeat = true;
			showAnchors = ShowAnchors.Auto;
			snapToAnchor = SnapToAnchor.OnCreate;

			beginPrintHandler = new PrintEventHandler(this.BeginPrint);
			printPageHandler = new PrintPageEventHandler(this.PrintPage);
			printRect = new RectangleF(0, 0, 1, 1);

			usePolyTextLt = false;

			userAction = false;

			tableLinkStyle = TableLinkStyle.Rows;

			undoManager = new UndoManager(this);

			defaultControlType = typeof(System.Windows.Forms.Button);
			hostedCtrlMouseAction = HostMouseAction.SelectHost;

			dummy = new DummyNode(this);
			allowUnconnectedArrows = false;
			allowUnanchoredArrows = true;

			autoSizeDoc = MindFusion.FlowChartX.AutoSize.None;
			panMode = false;

			enableStyledText = false;

			expandBtnPos = ExpandButtonPosition.OuterRight;
			focusLost = false;

			hitTestPriority = HitTestPriority.NodesBeforeArrows;

			boxText = arrowText = "";

			// arrow crossings
			arrowCrossings = ArrowCrossings.Straight;
			crossRadius = 1.5f;
			redrawNonModified = false;

			roundRectFactor = 1;

			scriptHelper = new ScriptHelper(this);

			// link routing options
			routingOptions = new RoutingOptions(this);
			routingGrid = new RoutingGrid(this);
			routeArrows = false;
			dontRouteForAwhile = false;

			validityChecks = true;
			_modifierKeyActions = new ModifierKeyActions();
			middleButtonAction = MouseButtonAction.None;
			forceCacheRedraw = false;

			showHandlesOnDrag = true;
			mergeThreshold = 0;

			expandButtonAction = ExpandButtonAction.ExpandTreeBranch;
		}
Пример #2
0
        /// <summary>
        /// mark obstacles and costs in the routing grid.
        /// </summary>
        private void markObstacles(RectangleF bounds,
                                   Arrow arrow, int cols, int rows)
        {
            RoutingOptions rop      = flowChart.RoutingOptions;
            float          gridSize = rop.GridSize;
            byte           ccost    = rop.CrossingCost;

            foreach (ChartObject obj in flowChart.Objects)
            {
                // if there is a crossing cost assigned, mark arrows in the route grid
                if (obj is Arrow && ccost > 0)
                {
                    if (obj == arrow)
                    {
                        continue;
                    }
                    Arrow link = obj as Arrow;

                    // at this time we handle only asPerpendicular links
                    if (link.Style == ArrowStyle.Cascading)
                    {
                        PointF cp1 = link.ControlPoints[0];
                        Point  gp1 = new Point(
                            (int)((cp1.X - bounds.Left) / gridSize),
                            (int)((cp1.Y - bounds.Top) / gridSize));

                        // iterate over all segments
                        for (int i = 0; i < link.ControlPoints.Count - 1; ++i)
                        {
                            PointF cp2 = link.ControlPoints[i + 1];
                            Point  gp2 = new Point(
                                (int)((cp2.X - bounds.Left) / gridSize),
                                (int)((cp2.Y - bounds.Top) / gridSize));

                            if (!gp1.Equals(gp2))
                            {
                                if (gp1.X == gp2.X)
                                {
                                    // vertical segment
                                    if (gp1.X >= 0 && gp1.X < cols)
                                    {
                                        int miny = Math.Min(gp1.Y, gp2.Y);
                                        miny = Math.Max(0, miny);
                                        int maxy = Math.Max(gp1.Y, gp2.Y);
                                        maxy = Math.Min(rows - 1, maxy);
                                        for (int y = miny; y <= maxy; ++y)
                                        {
                                            if (costGrid[gp1.X, y] < ccost)
                                            {
                                                costGrid[gp1.X, y] = ccost;
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    // horizontal segment
                                    if (gp1.Y >= 0 && gp1.Y < rows)
                                    {
                                        int minx = Math.Min(gp1.X, gp2.X);
                                        minx = Math.Max(0, minx);
                                        int maxx = Math.Max(gp1.X, gp2.X);
                                        maxx = Math.Min(cols - 1, maxx);
                                        for (int x = minx; x <= maxx; ++x)
                                        {
                                            if (costGrid[x, gp1.Y] < ccost)
                                            {
                                                costGrid[x, gp1.Y] = ccost;
                                            }
                                        }
                                    }
                                }
                            }

                            gp1 = gp2;
                        }
                    }
                    continue;
                }

                if (!(obj is Node))
                {
                    continue;
                }

                Node node = obj as Node;
                if (!node.Obstacle)
                {
                    continue;
                }
                if (node.MasterGroup != null && node.MasterGroup.MainObject == arrow)
                {
                    continue;
                }

                RectangleF nodeRect = node.getRotatedBounds();

                if (bounds.IntersectsWith(nodeRect))
                {
                    RectangleF intrRect = bounds;
                    intrRect.Intersect(nodeRect);

                    Point ptStart = new Point(
                        (int)((intrRect.Left - bounds.Left) / gridSize),
                        (int)((intrRect.Top - bounds.Top) / gridSize));
                    Point ptEnd = new Point(
                        (int)((intrRect.Right - bounds.Left) / gridSize),
                        (int)((intrRect.Bottom - bounds.Top) / gridSize));

                    if (ptStart.X < 0)
                    {
                        ptStart.X = 0;
                    }
                    if (ptStart.Y < 0)
                    {
                        ptStart.Y = 0;
                    }
                    if (ptEnd.X >= cols)
                    {
                        ptEnd.X = cols - 1;
                    }
                    if (ptEnd.Y >= rows)
                    {
                        ptEnd.Y = rows - 1;
                    }

                    // mark node interior as obstacle
                    for (int c = ptStart.X; c <= ptEnd.X; ++c)
                    {
                        for (int r = ptStart.Y; r <= ptEnd.Y; ++r)
                        {
                            costGrid[c, r] = 255;
                        }
                    }

                    // mark surrounding area with any cost assigned
                    // going lineary down to the outside directions
                    if (rop.NodeVicinityCost == 0)
                    {
                        continue;
                    }
                    for (int i = 1; i <= rop.NodeVicinitySize / gridSize; ++i)
                    {
                        byte cost = (byte)(rop.NodeVicinityCost / i);

                        int minc = Math.Max(0, ptStart.X - i);
                        int maxc = Math.Min(cols - 1, ptEnd.X + i);
                        int minr = Math.Max(0, ptStart.Y - i);
                        int maxr = Math.Min(rows - 1, ptEnd.Y + i);

                        // top side
                        int r = ptStart.Y - i;
                        if (r >= 0)
                        {
                            for (int c = minc; c <= maxc; ++c)
                            {
                                if (costGrid[c, r] < cost)
                                {
                                    costGrid[c, r] = cost;
                                }
                            }
                        }

                        // bottom side
                        r = ptEnd.Y + i;
                        if (r <= maxr)
                        {
                            for (int c = minc; c <= maxc; ++c)
                            {
                                if (costGrid[c, r] < cost)
                                {
                                    costGrid[c, r] = cost;
                                }
                            }
                        }

                        // left side
                        int cc = ptStart.X - i;
                        if (cc >= 0)
                        {
                            for (r = minr; r <= maxr; ++r)
                            {
                                if (costGrid[cc, r] < cost)
                                {
                                    costGrid[cc, r] = cost;
                                }
                            }
                        }

                        // right side
                        cc = ptEnd.X + i;
                        if (cc <= maxc)
                        {
                            for (r = minr; r <= maxr; ++r)
                            {
                                if (costGrid[cc, r] < cost)
                                {
                                    costGrid[cc, r] = cost;
                                }
                            }
                        }
                    }
                }
            }
        }