Exemple #1
0
        protected GraphSetting graphSetting; // 绘图参数配置对象

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="line">缩放控制点所属的插槽容器</param>
        /// <param name="location">缩放控制点的位置</param>
        /// <param name="size">缩放控制点的大小</param>
        public ResizeControler(SlotContainer slotContainer, Point location, Size size)
            : base(location)
        {
            this.slotContainer = slotContainer;
            this.location = location;
            this.elementSize = size;
        }
        /// <summary>
        /// 初始化图结点
        /// </summary>
        /// <param name="graphElement">结点对象</param>
        /// <param name="id">结点ID</param>
        /// <param name="name">结点名称</param>
        private void InitSlotContainer(SlotContainer slotContainer, int id, string name)
        {
            slotContainer.ID = id;
            slotContainer.Name = name;
            slotContainer.Init();
            graphManager.SlotContainerList.Add(slotContainer);

            description = "创建图元 " + slotContainer.Name;
            dataManager.AddDataElement(slotContainer);            
            graphManager.SelectGraphElement(slotContainer, false);
            graphManager.ReconstructCanvasGraphElementList(); 
        }
Exemple #3
0
 /// <summary>
 /// 添加插槽容器到区域
 /// </summary>
 /// <param name="slotContainer">插槽容器</param>
 public void Add(SlotContainer slotContainer)
 {
     if (!slotContainers.Contains(slotContainer))
     {
         slotContainers.Add(slotContainer);
     }
 }
Exemple #4
0
        /// <summary>
        /// 检查插槽容器是否与连接线相交
        /// </summary>
        /// <param name="slotContainer">插槽容器</param>
        /// <param name="pointList">连接线的连接点坐标</param>
        /// <returns>是否相交</returns>
        private bool CheckSlotContainerIntersect6(SlotContainer slotContainer, List<Point> pointList)
        {
            bool intersect = false;
            Rectangle rectangle = slotContainer.TextRectangle;

            if (LineIntersect(rectangle, pointList[1], pointList[2])
                || LineIntersect(rectangle, pointList[2], pointList[3])
                || LineIntersect(rectangle, pointList[3], pointList[4]))
            {
                intersect = true;                
            }
            else
            {
                if (slotContainer == inSlotContainer)
                {
                    if (pointList[0].Y > pointList[1].Y)
                    {
                        intersect = true;                        
                    }
                }
                else if (slotContainer == outSlotContainer)
                {
                    if (pointList[4].Y > pointList[5].Y)
                    {
                        intersect = true;                                                
                    }
                }
                else                
                {
                    if (LineIntersect(rectangle, pointList[0], pointList[1])
                        || LineIntersect(rectangle, pointList[4], pointList[5]))
                    {
                        intersect = true;
                    }
                }
            }

            return intersect;
        }
Exemple #5
0
        /// <summary>
        /// 检查连接线是否与插槽容器相交
        /// </summary>
        /// <param name="slotContainer">插槽容器</param>
        /// <param name="headPoint">头结点</param>
        /// <param name="tailPoint">尾结点</param>
        /// <returns>是否相交</returns>
        private bool LineIntersect(SlotContainer slotContainer, Point headPoint, Point tailPoint)
        {
            if (slotContainer != inSlotContainer && slotContainer != outSlotContainer)
            {
                Rectangle rectangle = slotContainer.TextRectangle;
                
                int x1 = headPoint.X;
                int y1 = headPoint.Y;
                int x2 = tailPoint.X;
                int y2 = tailPoint.Y;
                int x, y;

                int topY = y1;
                int bottomY = y2;
                if (y1 > y2)
                {
                    topY = y2;
                    bottomY = y1;
                }

                int leftX = x1;
                int rightX = x2;
                if (x1 > x2)
                {
                    leftX = x2;
                    rightX = x1;
                }

                if (x1 == x2) // 垂直线
                {
                    if (x1 >= rectangle.Left && x1 <= rectangle.Right && topY <= rectangle.Top
                        && bottomY >= rectangle.Bottom)
                    {
                        return true;
                    }
                }
                else if (y1 == y2) // 水平线
                {
                    if (y1 >= rectangle.Top && y1 <= rectangle.Bottom && leftX < rectangle.Left
                        && rightX >= rectangle.Right)
                    {
                        return true;
                    }
                }
                else
                {
                    // 检查上边
                    x = (x2 - x1) * (rectangle.Top - y1) / (y2 - y1) + x1;
                    if (x > rectangle.Left && x < rectangle.Right
                        && topY < rectangle.Top && bottomY > rectangle.Top)
                    {
                        return true;
                    }

                    // 检查下边
                    x = (x2 - x1) * (rectangle.Bottom - y1) / (y2 - y1) + x1;
                    if (x > rectangle.Left && x < rectangle.Right
                        && topY < rectangle.Bottom && bottomY > rectangle.Bottom)
                    {
                        return true;
                    }

                    // 检查左边
                    y = (y2 - y1) * (rectangle.Left - x1) / (x2 - x1) + y1;
                    if (y > rectangle.Top && y < rectangle.Bottom
                        && leftX < rectangle.Left && rightX > rectangle.Left)
                    {
                        return true;
                    }

                    // 检查右边
                    y = (y2 - y1) * (rectangle.Right - x1) / (x2 - x1) + y1;
                    if (y > rectangle.Top && y < rectangle.Bottom
                        && leftX < rectangle.Right && rightX > rectangle.Right)
                    {
                        return true;
                    }
                }                
            }

            return false;
        }
Exemple #6
0
        /// <summary>
        /// 自动连接图元
        /// </summary>
        /// <param name="previousContainer">连出的插槽容器</param>
        /// <param name="currentContainer">连入的插槽容器</param>
        private void ConnectGraphElement(SlotContainer previousContainer, SlotContainer currentContainer)
        {
            SlotGraphElement outSlot = previousContainer.GetOutSlot();
            SlotGraphElement inSlot = currentContainer.GetInSlot();            

            if(outSlot != null && inSlot != null) // 可能有些结点不能分配出新插槽
            {
                FlowChartCreateAndConnectLineCommand cmd = new FlowChartCreateAndConnectLineCommand(this, "创建并连接图元");
                InitFirstCommand(cmd);

                if (cmd.Execute(new object[] { outSlot, inSlot })) // 命令执行成功
                {
                    AdjustCommandList(cmd);

                    ConnectorContainer line = selectedGraphElement as ConnectorContainer;
                    regionManager.AddToRegion(line); // 调整图元所在区域                    
                    
                    // 自动调整连接线                    
                    AdjustLine(line, currentContainer);

                    if (previousContainer is ConditionGraphElement) // 编辑条件结点连出的连接线
                    {
                        FlowChartEditCommand editCommand = new FlowChartEditCommand(this, "编辑图元");

                        if (editCommand.Execute(line))
                        {
                            AdjustCommandList(editCommand);
                        }
                    }
                }
            }                       

            autoConnect = false;
        }
Exemple #7
0
        /// <summary>
        /// 调整连接线
        /// </summary>
        /// <param name="slotContainer">插槽容器</param>
        private void AdjustLine(SlotContainer slotContainer)
        {
            List<ConnectorContainer> lineList = regionManager.GetConnectorContainerList(slotContainer.InvalidRectangle);

            foreach (ConnectorContainer line in lineList)
            {
                if (line.LineIntersect(slotContainer))
                {
                    AdjustLine(line, slotContainer);
                }
            }
        }   
Exemple #8
0
        /// <summary>
        /// 创建调整网格线
        /// </summary>
        /// <param name="slotContaienr">当前插槽容器</param>
        private void CreateAdjustLine(SlotContainer slotContainer, Direction direction, bool autoAdjust)
        {
            canvas.CurrentGuideLine.ClearGuideLineList();

            Rectangle rectangle = Rectangle.Empty;
            rectangle.Location = canvas.ClientRectangle.Location - (Size)canvas.AutoScrollPosition;
            rectangle.Size = canvas.ClientSize;
            List<SlotContainer> list = regionManager.GetSlotContainerList(rectangle);            
            int leftX = -1;
            int rightX = -1;
            int topY = -1;
            int bottomY = -1;

            canvas.PaintCanvas = false;

            foreach(SlotContainer s in list)
            {
                if (s != slotContainer)
                {
                    // 插槽调整线
                    if (s.TextRectangle.Left < slotContainer.TextRectangle.Right &&
                        s.TextRectangle.Right > slotContainer.TextRectangle.Left)
                    {
                        if (s.TextRectangle.Bottom < slotContainer.TextRectangle.Top)
                        {
                            foreach (SlotGraphElement slot1 in s.GetOutSlotList())
                            {
                                foreach (SlotGraphElement slot2 in slotContainer.GetInSlotList())
                                {
                                    if (slot1.Location.X == slot2.Location.X)
                                    {
                                        canvas.CurrentGuideLine.AddGuideLine(new Point[] { slot1.Location, slot2.Location });
                                    }
                                }
                            }
                        }

                        if (s.TextRectangle.Top > slotContainer.TextRectangle.Bottom)
                        {
                            foreach (SlotGraphElement slot1 in s.GetInSlotList())
                            {
                                foreach (SlotGraphElement slot2 in slotContainer.GetOutSlotList())
                                {
                                    if (slot1.Location.X == slot2.Location.X)
                                    {
                                        canvas.CurrentGuideLine.AddGuideLine(new Point[] { slot1.Location, slot2.Location });
                                    }
                                }
                            }
                        }
                    }                   

                    // 显示边框调整线
                    switch (direction)
                    {
                        case Direction.Left:
                            {                                
                                if (slotContainer.TextRectangle.Left - s.TextRectangle.Left >= 0 &&
                                    slotContainer.TextRectangle.Left - s.TextRectangle.Left < moveAdjustWidth)
                                {
                                    canvas.CurrentGuideLine.AddGuideLine(new Point[]{ new Point(s.TextRectangle.Left, canvas.VisibleRectangle.Top), 
                                                                                      new Point(s.TextRectangle.Left, canvas.VisibleRectangle.Bottom)});   
                                    
                                    if (s.TextRectangle.Left < leftX || leftX == -1)
                                    {
                                        leftX = s.TextRectangle.Left;
                                    }
                                }

                                break;
                            }
                        case Direction.Right:
                            {
                                if (s.TextRectangle.Right - slotContainer.TextRectangle.Right >= 0 &&
                                    s.TextRectangle.Right - slotContainer.TextRectangle.Right < moveAdjustWidth)
                                {
                                    canvas.CurrentGuideLine.AddGuideLine(new Point[]{ new Point(s.TextRectangle.Right, canvas.VisibleRectangle.Top), 
                                                                                      new Point(s.TextRectangle.Right, canvas.VisibleRectangle.Bottom)});

                                    if (s.TextRectangle.Right > rightX || rightX == -1)
                                    {
                                        rightX = s.TextRectangle.Right;
                                    }
                                }

                                break;
                            }
                        case Direction.Up:
                            {
                                if (slotContainer.TextRectangle.Top - s.TextRectangle.Top >= 0 &&
                                    slotContainer.TextRectangle.Top - s.TextRectangle.Top < moveAdjustWidth)
                                {
                                    canvas.CurrentGuideLine.AddGuideLine(new Point[]{ new Point(canvas.VisibleRectangle.Left, s.TextRectangle.Top), 
                                                                                      new Point(canvas.VisibleRectangle.Right, s.TextRectangle.Top)});

                                    if (s.TextRectangle.Top < topY || topY == -1)
                                    {
                                        topY = s.TextRectangle.Top;
                                    }
                                }

                                break;
                            }
                        case Direction.Down:
                            {
                                if (s.TextRectangle.Bottom - slotContainer.TextRectangle.Bottom >= 0 &&
                                    s.TextRectangle.Bottom - slotContainer.TextRectangle.Bottom < moveAdjustWidth)
                                {
                                    canvas.CurrentGuideLine.AddGuideLine(new Point[]{ new Point(canvas.VisibleRectangle.Left, s.TextRectangle.Bottom), 
                                                                                      new Point(canvas.VisibleRectangle.Right, s.TextRectangle.Bottom)});

                                    if (s.TextRectangle.Bottom > bottomY || bottomY == -1)
                                    {
                                        bottomY = s.TextRectangle.Bottom;
                                    }
                                }

                                break;
                            }
                    }                                      
                }                
            }               
            
            if (autoAdjust) // 自动调整位置
            {
                bool requireAdjust = false;
                Size moveSize = Size.Empty;
                int lagPosition = -1;

                switch (direction)
                {
                    case Direction.Left:
                        {
                            if (leftX != -1)
                            {
                                moveSize.Width = leftX - slotContainer.TextRectangle.Left;
                                lagPosition = leftX;

                                if (moveSize.Width < moveLagOffset)
                                {
                                    requireAdjust = true;
                                }                                
                            }

                            break;
                        }
                    case Direction.Right:
                        {
                            if (rightX != -1)
                            {
                                moveSize.Width = rightX - slotContainer.TextRectangle.Right;
                                lagPosition = rightX;

                                if (moveSize.Width < moveLagOffset)
                                {
                                    requireAdjust = true;
                                }   
                            }

                            break;
                        }
                    case Direction.Up:
                        {
                            if (topY != -1)
                            {
                                moveSize.Height = topY - slotContainer.TextRectangle.Top;
                                lagPosition = topY;

                                if (moveSize.Height < moveLagOffset)
                                {
                                    requireAdjust = true;
                                }
                            }

                            break;
                        }
                    case Direction.Down:
                        {
                            if (bottomY != -1)
                            {
                                moveSize.Height = bottomY - slotContainer.TextRectangle.Bottom;
                                lagPosition = bottomY;

                                if (moveSize.Height < moveLagOffset)
                                {
                                    requireAdjust = true;
                                }   
                            }

                            break;
                        }
                    default:
                        {
                            break;
                        }
                }

                if (requireAdjust)
                {
                    slotContainer.Move(moveSize);

                    if (LagMove(direction, lagPosition)) // 移动延迟 
                    {
                        Cursor.Position += moveSize;     
                    }
                }
            }            

            canvas.PaintCanvas = true;
        }      
Exemple #9
0
            /// <summary>
            /// 检查区域中是否包含当前插槽容器
            /// </summary>
            /// <param name="slotContainer">当前插槽容器</param>
            /// <returns>区域是否包含当前插槽容器</returns>
            public bool Contains(SlotContainer slotContainer)
            {
                bool result = slotContainers.Contains(slotContainer);

                return result;
            }
Exemple #10
0
 /// <summary>
 /// 删除区域中的插槽容器
 /// </summary>
 /// <param name="slotContainer">当前插槽容器</param>
 public void Remove(SlotContainer slotContainer)
 {
     slotContainers.Remove(slotContainer);
 }
Exemple #11
0
        /// <summary>
        /// 更新插槽容器所在的区域
        /// </summary>
        /// <param name="slotContainer">当前插槽容器</param>
        private void ChangeRegion(SlotContainer slotContainer)
        {
            bool added = false; // 是否已经添加到区域中

            foreach (RegionData regionData in regionDataList)
            {
                if (regionData.Contains(slotContainer) && !regionData.IsInRegion(slotContainer.InvalidRectangle))
                {
                    regionData.Remove(slotContainer);
                }

                if (!regionData.Contains(slotContainer) && regionData.IsInRegion(slotContainer.InvalidRectangle))
                {
                    regionData.Add(slotContainer);
                    added = true;
                }
            }

            if (!added)
            {
                backupRegionData.Add(slotContainer);
            }

            // 更新相关连接线所在的区域            
            foreach (ConnectorContainer line in slotContainer.GetConnectedLine())
            {
                ChangeRegion(line);
            }
        }
Exemple #12
0
        /// <summary>
        /// 将插槽容器从区域中删除
        /// </summary>
        /// <param name="slotContainer">当前插槽容器</param>
        private void DeleteFromRegion(SlotContainer slotContainer)
        {
            foreach (RegionData regionData in regionDataList)
            {
                regionData.Remove(slotContainer);
            }

            backupRegionData.Remove(slotContainer);

            // 更新网格数据
            ClearSlotContainerGrid(slotContainer);
        }
Exemple #13
0
        /// <summary>
        /// 将插槽容器加入区域中
        /// </summary>
        /// <param name="slotContainer">当前插槽容器</param>
        private void AddToRegion(SlotContainer slotContainer)
        {
            bool added = false;

            foreach (RegionData regionData in regionDataList)
            {
                if (regionData.IsInRegion(slotContainer.InvalidRectangle))
                {
                    regionData.Add(slotContainer);
                    added = true;
                }
            }

            if (!added)
            {
                backupRegionData.Add(slotContainer);
            }

            // 更新网格数据
            UpdateSlotContainerGrid(slotContainer);
        }
Exemple #14
0
        /// <summary>
        /// 获取插槽容器覆盖网格点的集合
        /// </summary>
        /// <param name="slotContainer">插槽容器</param>
        /// <param name="gridWidth">网格宽度</param>
        /// <returns>插槽容器覆盖网格点的集合</returns>
        private List<Point> GetGridPointList(SlotContainer slotContainer, int gridWidth)
        {
            List<Point> list = new List<Point>();
            Rectangle rectangle = slotContainer.TextRectangle;
            int leftX = (int)Math.Ceiling((float)rectangle.Left / gridWidth) * gridWidth;
            int rightX = (int)Math.Floor((float)rectangle.Right / gridWidth) * gridWidth;
            int topY = (int)Math.Ceiling((float)rectangle.Top / gridWidth) * gridWidth;
            int bottomY = (int)Math.Floor((float)rectangle.Bottom / gridWidth) * gridWidth;
            Point point = Point.Empty;

            for (int i = leftX; i <= rightX; i += gridWidth)
            {
                for (int j = topY; j <= bottomY; j += gridWidth)
                {
                    point.X = i;
                    point.Y = j;
                    list.Add(point);
                }
            }

            return list;
        }
Exemple #15
0
        /// <summary>
        /// 清除插槽容器对应的网格
        /// </summary>
        /// <param name="slotContainer">插槽容器</param>
        private void ClearSlotContainerGrid(SlotContainer slotContainer)
        {
            Rectangle rectangle = slotContainer.InvalidRectangle;
            List<Point> gridPointList = GetGridPointList(slotContainer, gridWidth);

            foreach (Point point in gridPointList)
            {
                int gridX = (int)(point.X / gridWidth);
                int gridY = (int)(point.Y / gridWidth);

                if (gridX >= 0 && gridX < gridBoardWidth && point.Y >= 0 && point.Y < gridBoardHeight)
                {
                    canvasGridBoard[gridX, gridY] = false;
                }
            }
        }
Exemple #16
0
        /// <summary>
        /// 检查插槽容器的所有连出的线是否有效
        /// </summary>
        /// <param name="slotContainer">插槽容器</param>
        private void CheckLineValid(DataManager dataManager, SlotContainer slotContainer)
        {
            int invalidLineCount = 0;
            List<ConnectorContainer> list = new List<ConnectorContainer>();

            foreach (SlotGraphElement slot in slotContainer.GetOutSlotList())
            {
                if (slot.Binded)
                {
                    object data = dataManager.GetData(slot.BindingConnector.Line);
                    if (data == null)
                    {
                        list.Add(slot.BindingConnector.Line);
                        invalidLineCount++;
                    }
                    else
                    {
                        slot.BindingConnector.Line.Invalid = false;
                    }
                }
            }

            if (invalidLineCount == 1) // 无效连接线数等于1
            {
                foreach (ConnectorContainer line in list)
                {
                    line.Invalid = false;
                    line.Text = "else";
                    line.ShowText = true;
                    line.AdjustText();
                }
            }
            else if (invalidLineCount > 1) // 无效连接线数大于1
            {
                foreach (ConnectorContainer line in list)
                {
                    line.Invalid = true;
                    line.Text = "×";
                    line.ShowText = true;
                    line.AdjustText();
                }
            }
            else
            {
                foreach (ConnectorContainer line in list)
                {
                    line.Invalid = false;
                    line.ShowText = false;
                }
            }
        }
Exemple #17
0
        /// <summary>
        /// 获取连入的所有插槽容器的链表
        /// </summary>
        /// <param name="slotContainer">当前插槽容器</param>
        /// <returns>连入的所有插槽容器的链表</returns>
        public List<SlotContainer> GetAllPreviousSlotContainers(SlotContainer slotContainer)
        {
            List<SlotContainer> list = new List<SlotContainer>();

            GetAllPreviousSlotContainers(slotContainer, list);

            return list;
        }
Exemple #18
0
        /// <summary>
        /// 获取连入的所有插槽容器的链表(辅助函数)
        /// </summary>
        /// <param name="slotContainer">当前插槽容器</param>
        /// <param name="list">当前搜索的所有插槽容器的练表</param>
        public void GetAllPreviousSlotContainers(SlotContainer slotContainer, List<SlotContainer> list)
        {
            if(!list.Contains(slotContainer)) // 避免出现死循环
            {
                list.Add(slotContainer);

                foreach(SlotGraphElement slot in slotContainer.GetInSlotList())
                {
                    if(slot.Binded && slot.BindingConnector.Line.InSlotContainer != null)
                    {
                        GetAllPreviousSlotContainers(slot.BindingConnector.Line.InSlotContainer, list);
                    }
                }
            }
        }
Exemple #19
0
 /// <summary>
 /// 标记插槽容器相关的连接线
 /// </summary>
 /// <param name="slotContainer">当前插槽容器</param>
 /// <param name="mark">是否标记</param>
 private void MarkRelavateLines(SlotContainer slotContainer, bool mark)
 {            
     foreach (ConnectorContainer line in slotContainer.GetConnectedLine())
     {
         line.Marked = mark;
     }
 }
Exemple #20
0
        /// <summary>
        /// 获取连出的插槽容器链表
        /// </summary>
        /// <param name="slotContainer">当前插槽容器</param>
        /// <returns>连出的插槽容器链表</returns>
        public List<SlotContainer> GetNextSlotContainers(SlotContainer slotContainer)
        {
            List<SlotContainer> list = new List<SlotContainer>();

            foreach(SlotGraphElement slot in slotContainer.GetOutSlotList())
            {
                if(slot.Binded && slot.BindingConnector.Line.OutSlotContainer != null
                    && !list.Contains(slot.BindingConnector.Line.OutSlotContainer))
                {
                    list.Add(slot.BindingConnector.Line.OutSlotContainer);
                }
            }

            return list;
        }
Exemple #21
0
        /// <summary>
        /// 检查是否图元被选中
        /// </summary>
        /// <param name="p">鼠标当前所在点</param>
        public void CheckGraphElementSelected(Point point)
        {
            Point p = AdjustMouseLocation(point);
            RecordLastSelectedPoint(p);          
  
            selectedGraphElement = null;
            ConnectorContainer newLine = null; // 自动新建的连接线
            bool selected = false; // 是否已经有图元被选中
            GraphElement graphElement = null; // 当前图元

            if (lastSelectedGraphElement != null) // 将上一个被选中的图元置为非选中状态
            {
                if (!selectedGraphElementList.Contains(lastSelectedGraphElement)) // 在多选状态需要检查上一个被选中的图元是否在多选容器中
                {
                    lastSelectedGraphElement.Selected = false;
                }
            }

            if (lastResizingGraphElement != null) // 将上一个缩放的插槽容器置为非缩放状态
            {
                lastResizingGraphElement.Resizing = false;
            }

            // 检查游标是否被选中
            if (canvas.CurrentRodman.IsInRegion(p))
            {
                InitMoveGraphElementList();
                graphElement = canvas.CurrentRodman;
                selected = true;
            }

            // 索引检查是否有连接线控制点容器被选中
            foreach (ConnectorContainer connectorContainer in regionManager.GetConnectorContainerList(p))
            {
                if (selected) // 已经有图元被选中时自动跳出循环
                {
                    break;
                }

                // 先遍历检查是否有连接线控制点被选中
                ConnectorGraphElement connector = connectorContainer.GetConnectorInRegion(p);

                if (connector != null)
                {
                    graphElement = connector;
                    selected = true;
                    break;
                }

                if (connectorContainer.IsInRegion(p)) // 连接线被选中
                {
                    graphElement = connectorContainer;
                    selected = true;
                    break;
                }
            }

            foreach (SlotContainer slotContainer in regionManager.GetSlotContainerList(p)) // 索引检查是否有插槽容器被选中
            {
                if (selected) // 如果有图元被选中的话则自动跳出循环
                {
                    break;
                }

                // 检查是否有缩放控制点被选中
                ResizeControler resizeControler = slotContainer.GetResizeControlerInRegion(p);
                
                if (resizeControler != null)
                {
                    graphElement = resizeControler;
                    selected = true;
                    slotContainer.Resizing = true;
                    lastResizingGraphElement = slotContainer;
                    ChangeMouseCursur(resizeControler.CurrentDirection); // 改变鼠标指针形状
                    break;
                }
                
                // 检查是否有按钮被选中
                BaseButton baseButton = slotContainer.GetButtonInRegion(p);

                if (baseButton != null)
                {
                    if (baseButton is ConnectButton) // 是连接按钮
                    {
                        SlotGraphElement slot = (baseButton as ConnectButton).BindingSlot;

                        if (!slot.Binded && slot.IsOutSlot) // 插槽没有绑定连接线控制点,则新建连接线并绑定到当前插槽上
                        {
                            FlowChartCreateLineCommand cmd = new FlowChartCreateLineCommand(this, "创建图元");
                            InitFirstCommand(cmd);

                            if (cmd.Execute(new object[] { slot, p }))
                            {
                                AdjustCommandList(cmd);
                                newLine = selectedGraphElement as ConnectorContainer;
                                ConnectorGraphElement connector = newLine.GetConnectorList()[1];
                                graphElement = connector;
                                selected = true;
                            }

                            break;
                        }
                    }
                    else if (baseButton is AddButton) // 是添加按钮
                    {
                        SlotGraphElement slot = slotContainer.AddOutSlot();
                        graphElement = slotContainer;
                        selected = true;
                        break;
                    }
                }

                // 检查是否有注释图元被选中
                if (slotContainer.RemarkNode != null)
                {
                    if (slotContainer.RemarkNode.IsInRegion(p))
                    {
                        graphElement = slotContainer.RemarkNode;
                        selected = true;
                        break;
                    }
                }
                
                if (slotContainer.IsInRegion(p))
                {
                    SlotGraphElement slot = slotContainer.GetSlotInRegion(p);

                    if (slot != null)
                    {
                        graphElement = slot;
                        selected = true;
                        break;
                    }

                    slotContainer.Resizing = true;
                    lastResizingGraphElement = slotContainer;
                    graphElement = slotContainer;
                    selected = true;
                    break;
                }
            }

            if (selected) // 已经有图元被选中
            {
                SelectGraphElement(graphElement, p);
                userOperation = UserOperation.SingleSelect;

                if (selectedGraphElementList.Contains(selectedGraphElement)) // 进行多图元操作
                {
                    if (controlMode) // 在control模式下需要反选图元
                    {
                        selectedGraphElementList.Remove(selectedGraphElement);
                        selectedGraphElement.Selected = false;
                        selectedGraphElement = null;
                        lastSelectedGraphElement = null;
                        userOperation = UserOperation.None;

                        if (selectedGraphElementList.Count == 0)
                        {
                            canvas.CurrentMultiSelectMark.Visible = false;
                        }
                        else
                        {
                            CreateMultiSelectRegion();
                        }
                    }
                    else
                    {
                        userOperation = UserOperation.MultiSelect;
                    }
                }
                else
                {
                    if (controlMode) // 在control模式下需要加入图元
                    {
                        selectedGraphElementList.Add(selectedGraphElement);
                        CreateMultiSelectRegion();

                        userOperation = UserOperation.MultiSelect;
                    }
                    else
                    {
                        if (graphElement is Rodman)
                        {
                            userOperation = UserOperation.MoveRodman;
                            CreateMultiMoveRegion();
                        }

                        // 清空多选图元链表
                        ClearSelectedGraphElementList();
                    }
                }
            }
            else // 没有图元被选中
            {
                userOperation = UserOperation.RegionSelect;

                // 显示背景属性                
                documentManager.ShowObjectProperty(background);
                multiSelectStartPoint = p;

                // 清空多选图元链表
                ClearSelectedGraphElementList();
            }            

            RefreshCanvas();
        }
Exemple #22
0
        /// <summary>
        /// 获取插槽容器对应的事件结点的数据
        /// </summary>
        /// <param name="slotContainer">当前插槽容器</param>
        /// <returns>事件结点的数据</returns>
        public object GetEventData(SlotContainer slotContainer)
        {
            object data = null;

            List<DataElement> eventList = GetEventList(slotContainer);
            if(eventList.Count > 0)
            {
                data = eventList[0].Data;
            }

            return data;
        }
Exemple #23
0
        /// <summary>
        /// 调整连接线
        /// </summary>
        /// <param name="line">当前连接线</param>
        /// <param name="slotContainer">相关的插槽容器</param>
        private void AdjustLine(ConnectorContainer line , SlotContainer slotContainer)
        {
            Rectangle adjustRectangle = line.GetAdjustRectangle(background.CanvasSize, background.GridSize.Width);
            List<SlotContainer> totalSlotContainerList = regionManager.GetSlotContainerList(adjustRectangle);
            List<ConnectorContainer> totalLineList = regionManager.GetConnectorContainerList(adjustRectangle);

            line.AdjustLine(slotContainer, totalSlotContainerList, totalLineList, background.GridSize.Width, background.BaseSize, regionManager.CanvasGridBoard);
            line.AdjustRectangle();  
        }
Exemple #24
0
        /// <summary>
        /// 获取插槽容器对应的事件结点数据链表
        /// </summary>
        /// <param name="slotContainer">当前插槽容器</param>
        /// <returns>插槽容器对应的事件结点数据链表</returns>
        public List<DataElement> GetEventList(SlotContainer slotContainer)
        {
            List<DataElement> list = new List<DataElement>();
            List<SlotContainer> slotContainerList = GetAllPreviousSlotContainers(slotContainer);
            foreach(SlotContainer s in slotContainerList)
            {
                if(s is EventGraphElement)
                {
                    DataElement dataElement = graphTable[s] as DataElement;
                    if(dataElement != null)
                    {
                        list.Add(dataElement);
                    }
                }
            }

            return list;
        }
Exemple #25
0
        private SlotContainer slotContainer; // 添加按钮对应的插槽        

        public AddButton(SlotContainer slotContainer, Point location, Size elementSize)
            :base(location, elementSize)
        {
            this.slotContainer = slotContainer;
        }
Exemple #26
0
        /// <summary>
        /// 检查是否连接有事件结点
        /// </summary>
        /// <param name="slotContainer">当前插槽容器</param>
        /// <returns>是否连接有事件结点</returns>
        public bool IsConnectEventNode(SlotContainer slotContainer)
        {
            bool result = false;
            
            if (slotContainer.RequireEvent) // 需要入口事件
            {
                if (GetEventList(slotContainer).Count > 0)
                {
                    result = true;
                }
            }
            else
            {
                result = true;
            }                                    

            return result;
        }
Exemple #27
0
        /// <summary>
        /// 检查矩形是否与当前连接线相交
        /// </summary>
        /// <param name="slotContainer">插槽容器</param>
        /// <return>是否相交</return>
        public bool LineIntersect(SlotContainer slotContainer)
        {
            if (slotContainer != inSlotContainer && slotContainer != outSlotContainer)
            {
                Rectangle rectangle = slotContainer.TextRectangle;

                if(connectorList.Count == 6)
                {
                    if (LineIntersect(rectangle, connectorList[0].Location, connectorList[1].Location))
                    {
                        return true;
                    }

                    if (LineIntersect(rectangle, connectorList[1].Location, connectorList[2].Location))
                    {
                        return true;
                    }

                    if (LineIntersect(rectangle, connectorList[2].Location, connectorList[3].Location))
                    {
                        return true;
                    }

                    if (LineIntersect(rectangle, connectorList[3].Location, connectorList[4].Location))
                    {
                        return true;
                    }

                    if (LineIntersect(rectangle, connectorList[4].Location, connectorList[5].Location))
                    {
                        return true;
                    }
                }
                else
                {
                    int x1 = connectorList[0].Location.X;
                    int y1 = connectorList[0].Location.Y;
                    int x2 = connectorList[1].Location.X;
                    int y2 = connectorList[1].Location.Y;
                    int x, y;

                    int topY = y1;
                    int bottomY = y2;
                    if (y1 > y2)
                    {
                        topY = y2;
                        bottomY = y1;
                    }

                    int leftX = x1;
                    int rightX = x2;
                    if (x1 > x2)
                    {
                        leftX = x2;
                        rightX = x1;
                    }

                    if(x1 == x2) // 垂直线
                    {
                        if (x1 >= rectangle.Left && x1 <= rectangle.Right && topY <= rectangle.Top
                            && bottomY >= rectangle.Bottom)
                        {
                            return true;
                        }
                    }
                    else if (y1 == y2) // 水平线
                    {
                        if (y1 >= rectangle.Top && y1 <= rectangle.Bottom && leftX < rectangle.Left
                            && rightX >= rectangle.Right)
                        {
                            return true;
                        }
                    }
                    else
                    {
                        // 检查上边
                        x = (x2 - x1) * (rectangle.Top - y1) / (y2 - y1) + x1;
                        if (x > rectangle.Left && x < rectangle.Right
                            && topY < rectangle.Top && bottomY > rectangle.Top)
                        {
                            return true;
                        }                        

                        // 检查下边
                        x = (x2 - x1) * (rectangle.Bottom - y1) / (y2 - y1) + x1;
                        if (x > rectangle.Left && x < rectangle.Right
                            && topY < rectangle.Bottom && bottomY > rectangle.Bottom)
                        {
                            return true;
                        }

                        // 检查左边
                        y = (y2 - y1) * (rectangle.Left - x1) / (x2 - x1) + y1;
                        if (y > rectangle.Top && y < rectangle.Bottom
                            && leftX < rectangle.Left && rightX > rectangle.Left)
                        {
                            return true;
                        }

                        // 检查右边
                        y = (y2 - y1) * (rectangle.Right - x1) / (x2 - x1) + y1;
                        if (y > rectangle.Top && y < rectangle.Bottom
                            && leftX < rectangle.Right && rightX > rectangle.Right)
                        {
                            return true;
                        }
                    }
                }
            }                  

            return false;
        }
Exemple #28
0
        /// <summary>
        /// 复制数据
        /// </summary>
        /// <param name="srcSlotContainer">源插槽容器</param>
        /// <param name="destSlotContainer">目标插槽容器</param>
        protected virtual void CopyData(SlotContainer srcSlotContainer, SlotContainer destSlotContainer)
        {
            destSlotContainer.Name = srcSlotContainer.Name;
            destSlotContainer.Remark = srcSlotContainer.Remark;
            destSlotContainer.Text = srcSlotContainer.Text;
            destSlotContainer.DisplayText = srcSlotContainer.DisplayText;
            destSlotContainer.TooltipText = srcSlotContainer.TooltipText;
            destSlotContainer.ShowText = srcSlotContainer.ShowText;

            // 初始化绘图参数
            destSlotContainer.Init();
            destSlotContainer.InSlotCount = srcSlotContainer.InSlotCount;
            destSlotContainer.OutSlotCount = srcSlotContainer.OutSlotCount;
            destSlotContainer.AdjustText();
            destSlotContainer.AdjustResizeControlerList();
            destSlotContainer.AdjustButtonList();
        }
Exemple #29
0
        /// <summary>
        /// 调整连接线
        /// </summary>
        /// <param name="currentSlotContainer">当前移动的插槽容器</param>
        /// <param name="slotContainerList">插槽容器链表</param>
        /// <param name="connectorContainerList">连接线链表</param>
        /// <param name="gridWidth">网格的边长</param>
        /// <param name="canvasSize">绘图板的大小</param>
        /// <param name="gridBoard">网格数据绘图板</param>
        public virtual void AdjustLine(SlotContainer currentSlotContainer, List<SlotContainer> slotContainerList, List<ConnectorContainer> connectorContainerList, int gridWidth, Size canvasSize, bool[,] gridBoard)
        {
            if (inSlotContainer != null && outSlotContainer != null) // 连接线两端均已连接图元
            {
                int headX = headConnector.Location.X;
                int headY = headConnector.Location.Y;
                int tailX = tailConnector.Location.X;
                int tailY = tailConnector.Location.Y;

                ConnectorGraphElement connector1 = null;
                ConnectorGraphElement connector2 = null;
                ConnectorGraphElement connector3 = null;
                ConnectorGraphElement connector4 = null;
                ConnectorGraphElement connector5 = null;
                ConnectorGraphElement connector6 = null;                

                if (CheckRequireAdjust(slotContainerList, canvasSize)) // 需要寻路避让
                {
                    // 先尝试用寻路算法
                    bool findLine = false;
                    Rectangle regionRectangle = Rectangle.Empty;
                    List<SlotContainer> nodeList;
                    List<ConnectorContainer> lineList;

                    // 备用线路,允许连接线重合
                    bool findBackup = false;
                    Point[] backupPoints = new Point[4];
                    backupPoints[0] = Point.Empty;
                    backupPoints[1] = Point.Empty;
                    backupPoints[2] = Point.Empty;
                    backupPoints[3] = Point.Empty;                     
                   
                    List<Point> pointList = new List<Point>();
                    List<Point[]> validPoints = new List<Point[]>(); // 有效点的集合
                    bool preCheck = false; // 是否开启预检查
                    bool valid = true;

                    // 记住上一次被阻隔的图元
                    SlotContainer lastBlockSlotContainer = null;
                    ConnectorContainer lastBlockLine = null;    
                    
                    // 初始化数据
                    int leftX;
                    int rightX;
                    int topY;
                    int bottomY;

                    if (inSlotContainer.Location.X < outSlotContainer.Location.X)
                    {
                        leftX = inSlotContainer.Location.X;
                    }
                    else
                    {
                        leftX = outSlotContainer.Location.X;
                    }

                    if (inSlotContainer.TextRectangle.Right > outSlotContainer.TextRectangle.Right)
                    {
                        rightX = inSlotContainer.TextRectangle.Right;
                    }
                    else
                    {
                        rightX = outSlotContainer.TextRectangle.Right;
                    }

                    if (inSlotContainer.Location.Y < outSlotContainer.Location.Y)
                    {
                        topY = inSlotContainer.Location.Y;
                    }
                    else
                    {
                        topY = outSlotContainer.Location.Y;
                    }

                    if (inSlotContainer.TextRectangle.Bottom >
                        outSlotContainer.TextRectangle.Bottom)
                    {
                        bottomY = inSlotContainer.TextRectangle.Bottom;
                    }
                    else
                    {
                        bottomY = outSlotContainer.TextRectangle.Bottom;
                    }

                    // 先尝试连接控制点数量点为4的情况
                    if (head.Y > tail.Y)
                    {
                        bool requireRestore = false; // 是否需要保存当前连接控制点坐标
                        Point[] restorePointArray = new Point[6]; // 保存当前连接线控制点坐标的数组

                        if (connectorCount == 6)
                        {
                            requireRestore = true;
                            restorePointArray[0] = connectorList[0].Location;
                            restorePointArray[1] = connectorList[1].Location;
                            restorePointArray[2] = connectorList[2].Location;
                            restorePointArray[3] = connectorList[3].Location;
                            restorePointArray[4] = connectorList[4].Location;
                            restorePointArray[5] = connectorList[5].Location;
                        }

                        ConnectorCount = 4;
                        connector1 = connectorList[0];
                        connector2 = connectorList[1];
                        connector3 = connectorList[2];
                        connector4 = connectorList[3];                        

                        // 筛选需要避让的结点和连接线                        
                        regionRectangle.Location = new Point(leftX, topY);
                        regionRectangle.Size = new Size(rightX - leftX, bottomY - topY);

                        nodeList = GetSlotContainerInRegion(regionRectangle, slotContainerList);
                        lineList = GetLineInRegion(regionRectangle, connectorContainerList);

                        // 预检查一次                                               
                        if (currentSlotContainer == inSlotContainer)
                        {
                            connector1Location.X = connector1.Location.X;
                            connector1Location.Y = connector1.Location.Y;
                            connector2Location.X = connector1.Location.X;
                            connector2Location.Y = connector2.Location.Y;
                            connector3Location.X = connector4.Location.X;
                            connector3Location.Y = connector2.Location.Y;
                            connector4Location.X = connector4.Location.X;
                            connector4Location.Y = connector4.Location.Y;

                            preCheck = true;
                        }
                        else if (currentSlotContainer == outSlotContainer)
                        {
                            connector1Location.X = connector1.Location.X;
                            connector1Location.Y = connector1.Location.Y;
                            connector2Location.X = connector1.Location.X;
                            connector2Location.Y = connector3.Location.Y;
                            connector3Location.X = connector4.Location.X;
                            connector3Location.Y = connector3.Location.Y;
                            connector4Location.X = connector4.Location.X;
                            connector4Location.Y = connector4.Location.Y;

                            preCheck = true;
                        }

                        // 校正连接线的形状
                        if (connector2Location.X != connector1Location.X)
                        {
                            connector2Location.X = connector1Location.X;
                        }

                        if (connector3Location.Y != connector2Location.Y)
                        {
                            connector3Location.Y = connector2Location.Y;
                        }

                        if (connector3Location.X != connector4Location.X)
                        {
                            connector3Location.Y = connector5Location.X;
                        }

                        if (preCheck)
                        {
                            if (!CheckPointInGrid(connector2Location, connector3Location, gridBoard, gridWidth))
                            {
                                List<Point> checkPointList = new List<Point>();
                                checkPointList.Add(connector1Location);
                                checkPointList.Add(connector2Location);
                                checkPointList.Add(connector3Location);
                                checkPointList.Add(connector4Location);

                                foreach (SlotContainer slotContainer in nodeList)
                                {                                    
                                    if (CheckSlotContainerIntersect4(slotContainer, checkPointList))
                                    {
                                        valid = false;
                                        lastBlockSlotContainer = slotContainer;
                                        break;
                                    }
                                }
                            }
                        }
                        else
                        {
                            valid = false;
                        }

                        if (valid) // 预检查选择的线路成功,直接调整连接线
                        {
                            validPoints.Add(new Point[] { connector2Location, connector3Location });
                            findLine = true;
                        }
                        else
                        {
                            int tempY1 = (int)Math.Ceiling((float)inSlotContainer.TextRectangle.Bottom / gridWidth) * gridWidth;
                            int tempY2 = (int)Math.Floor((float)outSlotContainer.TextRectangle.Top / gridWidth) * gridWidth;

                            for (int i = tempY1; i < tempY2; i += gridWidth)
                            {
                                valid = true;

                                connector2Location.X = connector1Location.X;
                                connector2Location.Y = i;
                                connector3Location.X = connector4Location.X;
                                connector3Location.Y = i;

                                List<Point> checkPointList = new List<Point>();
                                checkPointList.Add(connector1Location);
                                checkPointList.Add(connector2Location);
                                checkPointList.Add(connector3Location);
                                checkPointList.Add(connector4Location);

                                if (CheckPointInGrid(connector2Location, connector3Location, gridBoard, gridWidth))
                                {
                                    valid = false;
                                    continue;
                                }

                                if (lastBlockSlotContainer != null)
                                {                                    
                                    if (CheckSlotContainerIntersect4(lastBlockSlotContainer, checkPointList))
                                    {
                                        valid = false;
                                        continue;
                                    }                                    
                                }

                                foreach (SlotContainer slotContainer in nodeList)
                                {
                                    if (CheckSlotContainerIntersect4(slotContainer, checkPointList))
                                    {
                                        valid = false;
                                        lastBlockSlotContainer = slotContainer;
                                        break;
                                    }
                                }

                                if (valid)
                                {
                                    // 记录备用线路
                                    if (!findBackup)
                                    {
                                        findBackup = true;
                                        backupPoints[0].X = connector1Location.X;
                                        backupPoints[0].Y = i;
                                        backupPoints[1].X = connector4Location.Y;
                                        backupPoints[1].Y = i;
                                    }

                                    pointList.Clear();
                                    pointList.Add(connector1Location);
                                    pointList.Add(connector2Location);
                                    pointList.Add(connector3Location);
                                    pointList.Add(connector4Location);

                                    if (lastBlockLine != null)
                                    {
                                        List<ConnectorGraphElement> blockList = lastBlockLine.GetConnectorList();

                                        switch (blockList.Count)
                                        {
                                            case 4:
                                                {
                                                    if (PointInLine(blockList[1].Location, pointList) || PointInLine(blockList[2].Location, pointList))
                                                    {
                                                        valid = false;
                                                        continue;
                                                    }

                                                    break;
                                                }
                                            case 6:
                                                {
                                                    if (PointInLine(blockList[1].Location, pointList) || PointInLine(blockList[2].Location, pointList)
                                                        || (PointInLine(blockList[3].Location, pointList) || (PointInLine(blockList[4].Location, pointList))))
                                                    {
                                                        valid = false;
                                                        continue;
                                                    }

                                                    break;
                                                }
                                        }

                                    }
                                }

                                if (valid)
                                {
                                    validPoints.Add(new Point[] { connector2Location, connector3Location });
                                    findLine = true;
                                }
                            }                            
                        }
                        
                        if (!findLine)
                        {
                            if (requireRestore) // 恢复连接线控制点坐标
                            {
                                ConnectorCount = 6;
                                connectorList[0].Location = restorePointArray[0];
                                connectorList[1].Location = restorePointArray[1];
                                connectorList[2].Location = restorePointArray[2];
                                connectorList[3].Location = restorePointArray[3];
                                connectorList[4].Location = restorePointArray[4];
                                connectorList[5].Location = restorePointArray[5];
                            }
                        }
                    }

                    if (!findLine) // 再尝试连接线控制点数量为6的情况
                    {
                        // 初始化数据
                        valid = true;
                        preCheck = false;
                        findBackup = false;

                        pointList.Clear();
                        validPoints.Clear();

                        int leftLineX = (int)Math.Floor(((float)leftX - 10 * gridWidth) / gridWidth) * gridWidth;
                        if (leftLineX < 0)
                        {
                            leftLineX = gridWidth;
                        }

                        int rightLineX = (int)Math.Ceiling(((float)rightX + 10 * gridWidth) / gridWidth) * gridWidth;
                        if (rightLineX > canvasSize.Width)
                        {
                            rightLineX = canvasSize.Width;
                        }

                        int topLineY = (int)Math.Floor(((float)topY - 10 * gridWidth) / gridWidth) * gridWidth;
                        if (topLineY < 0)
                        {
                            topLineY = gridWidth;
                        }

                        int bottomLineY = (int)Math.Ceiling(((float)bottomY + 10 * gridWidth) / gridWidth) * gridWidth;
                        if (bottomLineY > canvasSize.Height)
                        {
                            bottomLineY = canvasSize.Height;
                        }

                        // 筛选需要避让的结点和连接线
                        regionRectangle.Location = new Point(leftLineX, topLineY);
                        regionRectangle.Size = new Size(rightLineX - leftLineX, bottomLineY - topLineY);

                        nodeList = GetSlotContainerInRegion(regionRectangle, slotContainerList);
                        lineList = GetLineInRegion(regionRectangle, connectorContainerList);            

                        List<int> verticalLineList = new List<int>();
                        List<int> horizontalLineList = new List<int>();                        

                        for (int i = leftLineX; i < rightLineX; i += gridWidth)
                        {
                            verticalLineList.Add(i);
                        }

                        for (int i = topLineY; i < bottomLineY; i += gridWidth)
                        {
                            horizontalLineList.Add(i);
                        }

                        ConnectorCount = 6;
                        connector1 = connectorList[0];
                        connector2 = connectorList[1];
                        connector3 = connectorList[2];
                        connector4 = connectorList[3];
                        connector5 = connectorList[4];
                        connector6 = connectorList[5];

                        // 开始遍历查找符合条件的路径
                        connector1Location = connector1.Location;                   
                        connector6Location = connector6.Location;

                        // 预检查一次
                        if (currentSlotContainer == inSlotContainer)
                        {
                            connector2Location.X = connector1.Location.X;
                            connector2Location.Y = connector2.Location.Y;
                            connector3Location.X = connector3.Location.X;
                            connector3Location.Y = connector3.Location.Y;
                            connector4Location.X = connector4.Location.X;
                            connector4Location.Y = connector4.Location.Y;
                            connector5Location.X = connector5.Location.X;
                            connector5Location.Y = connector5.Location.Y;
                            preCheck = true;
                        }
                        else if (currentSlotContainer == outSlotContainer)
                        {
                            connector2Location.X = connector1.Location.X;
                            connector2Location.Y = connector2.Location.Y;
                            connector3Location.X = connector3.Location.X;
                            connector3Location.Y = connector3.Location.Y;
                            connector4Location.X = connector4.Location.X;
                            connector4Location.Y = connector4.Location.Y;
                            connector5Location.X = connector6.Location.X;
                            connector5Location.Y = connector5.Location.Y;
                            preCheck = true;
                        }

                        // 校正连接线的形状
                        if (connector2Location.X != connector1Location.X)
                        {
                            connector2Location.X = connector1Location.X;
                        }

                        if (connector5Location.X != connector6Location.X)
                        {
                            connector5Location.X = connector6Location.X;
                        }

                        if (connector3Location.Y != connector2Location.Y)
                        {
                            connector3Location.Y = connector2Location.Y;
                        }

                        if (connector4Location.Y != connector5Location.Y)
                        {
                            connector4Location.Y = connector5Location.Y;
                        }

                        if (preCheck)
                        {
                            if (!CheckPointInGrid(connector2Location, connector3Location, connector4Location, connector5Location, gridBoard, gridWidth))
                            {
                                List<Point> checkPointList = new List<Point>();
                                checkPointList.Add(connector1Location);
                                checkPointList.Add(connector2Location);
                                checkPointList.Add(connector3Location);
                                checkPointList.Add(connector4Location);
                                checkPointList.Add(connector5Location);
                                checkPointList.Add(connector6Location);

                                foreach (SlotContainer slotContainer in nodeList)
                                {
                                    if (CheckSlotContainerIntersect6(slotContainer, checkPointList))
                                    {
                                        valid = false;
                                        lastBlockSlotContainer = slotContainer;
                                        break;
                                    }                                    
                                }
                            }
                        }
                        else
                        {
                            valid = false;
                        }

                        if (valid) // 预检查选择的线路成功,直接调整连接线
                        {
                            validPoints.Add(new Point[] { connector2Location, connector3Location, connector4Location, connector5Location });
                            findLine = true;
                        }
                        else
                        {
                            for (int i = 0; i < verticalLineList.Count; i++)
                            {
                                for (int j = 0; j < horizontalLineList.Count; j++)
                                {
                                    for (int k = 0; k < horizontalLineList.Count; k++)
                                    {
                                        valid = true;
                                        connector2Location.X = connector1Location.X;
                                        connector2Location.Y = horizontalLineList[k];
                                        connector3Location.X = verticalLineList[i];
                                        connector3Location.Y = horizontalLineList[k];
                                        connector4Location.X = verticalLineList[i];
                                        connector4Location.Y = horizontalLineList[j];
                                        connector5Location.X = connector6Location.X;
                                        connector5Location.Y = horizontalLineList[j];

                                        List<Point> checkPointList = new List<Point>();
                                        checkPointList.Add(connector1Location);
                                        checkPointList.Add(connector2Location);
                                        checkPointList.Add(connector3Location); 
                                        checkPointList.Add(connector4Location);
                                        checkPointList.Add(connector5Location);
                                        checkPointList.Add(connector6Location);

                                        if (CheckPointInGrid(connector2Location, connector3Location, connector4Location, connector5Location, gridBoard, gridWidth))
                                        {
                                            valid = false;
                                        }

                                        if (lastBlockSlotContainer != null)
                                        {
                                            if (CheckSlotContainerIntersect6(lastBlockSlotContainer, checkPointList))
                                            {
                                                valid = false;
                                                continue;
                                            }                                            
                                        }

                                        foreach (SlotContainer slotContainer in nodeList)
                                        {
                                            if (CheckSlotContainerIntersect6(slotContainer, checkPointList))
                                            {
                                                valid = false;
                                                lastBlockSlotContainer = slotContainer;
                                                break;
                                            }
                                        }

                                        if (valid)
                                        {
                                            // 记录备用线路
                                            if (!findBackup)
                                            {
                                                findBackup = true;
                                                backupPoints[0].X = connector1.Location.X;
                                                backupPoints[0].Y = horizontalLineList[k];
                                                backupPoints[1].X = verticalLineList[i];
                                                backupPoints[1].Y = horizontalLineList[k];
                                                backupPoints[2].X = verticalLineList[i];
                                                backupPoints[2].Y = horizontalLineList[j];
                                                backupPoints[3].X = connector6.Location.X;
                                                backupPoints[3].Y = horizontalLineList[j];
                                            }

                                            pointList.Clear();
                                            pointList.Add(connector1Location);
                                            pointList.Add(connector2Location);
                                            pointList.Add(connector3Location);
                                            pointList.Add(connector4Location);
                                            pointList.Add(connector5Location);
                                            pointList.Add(connector6Location);

                                            if (lastBlockLine != null)
                                            {
                                                List<ConnectorGraphElement> blockList = lastBlockLine.GetConnectorList();

                                                if (PointInLine(blockList[1].Location, pointList) || PointInLine(blockList[2].Location, pointList)
                                                    || (PointInLine(blockList[3].Location, pointList) || (PointInLine(blockList[4].Location, pointList))))
                                                {
                                                    valid = false;
                                                    continue;
                                                }
                                            }

                                            foreach (ConnectorContainer line in lineList)
                                            {
                                                if (line != this && line.ConnectorCount == 6)
                                                {
                                                    List<ConnectorGraphElement> list = line.GetConnectorList();

                                                    if (PointInLine(list[1].Location, pointList) || PointInLine(list[2].Location, pointList)
                                                        || (PointInLine(list[3].Location, pointList) || (PointInLine(list[4].Location, pointList))))
                                                    {
                                                        valid = false;
                                                        lastBlockLine = line;
                                                        break;
                                                    }
                                                }
                                            }
                                        }

                                        if (valid)
                                        {
                                            validPoints.Add(new Point[] { connector2Location, connector3Location, connector4Location, connector5Location });
                                            findLine = true;
                                        }
                                    }
                                }
                            }
                        }
                    }                                                                                                                                                                                                                                                                   

                    if (findLine) // 找到符合条件的路径
                    {
                        // 优选最佳线路
                        int index = 0;
                        int score = -1;

                        Point[] points;
                        int tempLength1;
                        int tempLength2;
                        int tempLength3;
                        int tempLength4;
                        int tempLength5;

                        switch (connectorCount)
                        {
                            case 4:
                                {
                                    for (int i = 0; i < validPoints.Count; i++)
                                    {
                                        points = validPoints[i];
                                        tempLength1 = points[0].Y - connector1Location.Y;
                                        tempLength2 = Math.Abs(points[0].X - points[1].X);
                                        tempLength3 = connector4Location.Y - points[1].Y;

                                        if (tempLength1 < gridWidth ||
                                            tempLength2 < gridWidth ||
                                            tempLength3 < gridWidth
                                            )
                                        {
                                            continue;
                                        }
                                        else
                                        {
                                            int currentScore = (Math.Abs(connector1Location.X - points[1].X) + Math.Abs(connector4Location.X - points[1].X)) * 10
                                                                                            + tempLength1 + tempLength3;
                                            if (currentScore < score || score == -1)
                                            {
                                                score = currentScore;
                                                index = i;
                                            }
                                        }
                                    }

                                    points = validPoints[index];
                                    connector2.Location = points[0];
                                    connector3.Location = points[1];

                                    break;
                                }
                            case 6:
                                {
                                    for (int i = 0; i < validPoints.Count; i++)
                                    {
                                        points = validPoints[i];
                                        tempLength1 = points[0].Y - connector1Location.Y;
                                        tempLength2 = Math.Abs(points[0].X - points[1].X);
                                        tempLength3 = Math.Abs(points[1].Y - points[2].Y);
                                        tempLength4 = Math.Abs(points[2].X - points[3].X);
                                        tempLength5 = connector6Location.Y - points[3].Y;

                                        if (tempLength1 < gridWidth ||
                                            tempLength2 < gridWidth ||
                                            tempLength3 < gridWidth ||
                                            tempLength4 < gridWidth ||
                                            tempLength5 < gridWidth
                                            )
                                        {
                                            continue;
                                        }
                                        else
                                        {
                                            int currentScore = (Math.Abs(connector1Location.X - points[1].X) + Math.Abs(connector6Location.X - points[1].X)) * 10
                                                                                            + tempLength1 + tempLength5;
                                            if (currentScore < score || score == -1)
                                            {
                                                score = currentScore;
                                                index = i;
                                            }
                                        }
                                    }

                                    points = validPoints[index];
                                    connector2.Location = points[0];
                                    connector3.Location = points[1];
                                    connector4.Location = points[2];
                                    connector5.Location = points[3];

                                    break;
                                }
                        }
                    }
                    else // 寻路算法失效之后的处理
                    {
                        if (findBackup) // 启用备用线路
                        {
                            switch (connectorCount)
                            {
                                case 4:
                                    {
                                        connector2.Location = backupPoints[0];
                                        connector3.Location = backupPoints[1];

                                        break;
                                    }
                                case 6:
                                    {
                                        connector2.Location = backupPoints[0];
                                        connector3.Location = backupPoints[1];
                                        connector4.Location = backupPoints[2];
                                        connector5.Location = backupPoints[3];

                                        break;
                                    }
                            }                            
                        }
                        else
                        {
                            if (headY > tailY) // 头结点在尾结点之下
                            {
                                ConnectorCount = 2;                                
                            }
                            else // 头结点在尾结点之上
                            {
                                switch(connectorCount)
                                {
                                    case 4:
                                        {
                                            int middleY = (int)((connector1.Location.Y + connector4.Location.Y) / 2);
                                            connector2.Location = new Point(connector1Location.X + 50, middleY);
                                            connector3.Location = new Point(connector4Location.X - 50, middleY);

                                            break;
                                        }
                                    case 6:
                                        {
                                            int middleX = (int)((connector1.Location.X + connector6.Location.X) / 2);
                                            connector2.Location = connector1Location + new Size(0, 50);
                                            connector5.Location = connector6Location + new Size(0, -50);
                                            connector3.Location = new Point(middleX, connector2Location.Y);
                                            connector4.Location = new Point(middleX, connector5Location.Y);

                                            break;
                                        }
                                }                                
                            }
                        }
                    }
                }
            }
        }
Exemple #30
0
        protected GraphSetting graphSetting; // 绘图参数配置对象

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="slotContainner">插槽所属容器</param>
        /// <param name="location">插槽的位置</param>
        /// <param name="size">插槽的大小</param>
        /// <param name="id">插槽的id</param>
        public SlotGraphElement(SlotContainer slotContainer, Point location, Size size)
            : base(location)
        {
            this.slotContainer = slotContainer;
            this.elementSize = size;
        }