Exemplo n.º 1
0
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            Point cursorPosition = e.GetPosition(this);

            switch (this.visualState)
            {
            case Visuals.VisualState.Idle:
            {
                VisualGraphics visualHit = this.DrawHandleWhenMouseOverVisual <VisualPolyline>(cursorPosition);

                // 处理鼠标状态
                this.ProcessSelectedVisualCursor(visualHit, cursorPosition);

                break;
            }

            case Visuals.VisualState.Translate:
            {
                double x = cursorPosition.X - this.previousPosition.X;
                double y = cursorPosition.Y - this.previousPosition.Y;

                this.translateVisual.Translate(x, y);

                foreach (GraphicsPolyline polyline in this.associatedPolylines)
                {
                    List <Point> pointList = null;

                    if (this.translateVisual.ID == polyline.AssociatedGraphics1)
                    {
                        // 移动的图形是第一个图形
                        Point firstConnector = this.translateVisual.GetConnectorPoint(polyline.Graphics1Handle);
                        ConnectionLocations firstConnectorLocation = this.translateVisual.GetConnectorLocation(polyline.Graphics1Handle);
                        Point secondConnector = polyline.PointList.LastOrDefault();

                        if (string.IsNullOrEmpty(polyline.AssociatedGraphics2))
                        {
                            // 连接点的另一端不在图形上
                            pointList = GraphicsUtility.MakeConnectionPath(firstConnector, firstConnectorLocation, secondConnector);
                        }
                        else
                        {
                            // 连接点的另一端在图形上
                            VisualGraphics      secondVisual            = this.VisualList.FirstOrDefault(v => v.ID == polyline.AssociatedGraphics2);
                            ConnectionLocations secondConnectorLocation = secondVisual.Graphics.GetConnectorLocation(polyline.Graphics2Handle);
                            pointList = GraphicsUtility.MakeConnectionPath(firstConnector, firstConnectorLocation, secondConnector, secondConnectorLocation);
                        }
                    }
                    else if (this.translateVisual.ID == polyline.AssociatedGraphics2)
                    {
                        // 移动的图形是第二个图形
                        Point secondConnector = this.translateVisual.GetConnectorPoint(polyline.Graphics2Handle);
                        ConnectionLocations secondConnectorLocation = this.translateVisual.GetConnectorLocation(polyline.Graphics2Handle);
                        Point firstConnector = polyline.PointList.FirstOrDefault();

                        if (string.IsNullOrEmpty(polyline.AssociatedGraphics1))
                        {
                            // 连接点的另一端不在图形上
                            // 规定必须在图形上,不允许只有第二个点在图形上,而第一个点不在。但是允许第一个点在图形上,第二个点不在
                            pointList = GraphicsUtility.MakeConnectionPath(secondConnector, secondConnectorLocation, firstConnector);
                            pointList.Reverse();
                        }
                        else
                        {
                            // 连接点的另一端在图形上
                            VisualGraphics      firstVisual            = this.VisualList.FirstOrDefault(v => v.ID == polyline.AssociatedGraphics1);
                            ConnectionLocations firstConnectorLocation = firstVisual.Graphics.GetConnectorLocation(polyline.Graphics1Handle);
                            pointList = GraphicsUtility.MakeConnectionPath(firstConnector, firstConnectorLocation, secondConnector, secondConnectorLocation);
                        }
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }

                    VisualPolyline visualPolyline = this.VisualList.OfType <VisualPolyline>().FirstOrDefault(v => v.ID == polyline.ID);
                    visualPolyline.Update(pointList);
                }

                this.previousPosition = cursorPosition;

                break;
            }

            case Visuals.VisualState.Connecting:
            {
                GraphicsPolyline graphicsPolyline = this.polyline.Graphics as GraphicsPolyline;

                Point secondConnector = cursorPosition;

                // 检测鼠标是否在某个图形上面
                VisualGraphics visualHit = this.DrawHandleWhenMouseOverVisual <VisualPolyline>(cursorPosition);
                if (visualHit == null || visualHit == this.firstVisual)
                {
                    this.secondVisual = null;
                    graphicsPolyline.AssociatedGraphics2 = null;

                    // 更新连接线
                    List <Point> points = GraphicsUtility.MakeConnectionPath(this.firstConnector, this.firstConnectorLocation, secondConnector);
                    this.polyline.Update(points);
                }
                else
                {
                    // 如果当前鼠标下的元素和选中的是不同一个元素,那么就表示有连接的元素了
                    // 运行到此处说明两个图形被连接起来了
                    this.secondVisual = visualHit;

                    // 运行到这里说明折线的另一端已经在图形的连接点范围内了
                    int   handle;
                    Point handlePoint;
                    ConnectionLocations secondConnectorLocation;
                    if (this.secondVisual.Graphics.GetNearestConnectorHandle(cursorPosition, out handle, out handlePoint, out secondConnectorLocation))
                    {
                        secondConnector = handlePoint;
                        graphicsPolyline.AssociatedGraphics2 = this.secondVisual.ID;
                        graphicsPolyline.Graphics2Handle     = handle;

                        // 更新连接线
                        List <Point> points = GraphicsUtility.MakeConnectionPath(this.firstConnector, this.firstConnectorLocation, secondConnector, secondConnectorLocation);
                        this.polyline.Update(points);
                    }
                    else
                    {
                        // 鼠标已经在第二个图形上了,但是没有放在连接点附近
                        List <Point> points = GraphicsUtility.MakeConnectionPath(this.firstConnector, this.firstConnectorLocation, secondConnector);
                        this.polyline.Update(points);
                    }
                }

                break;
            }

            case Visuals.VisualState.Resizing:
            {
                this.selectedVisual.Resize(this.resizeLocation, this.resizeCenter, cursorPosition);
                break;
            }

            case Visuals.VisualState.InputState:
            {
                break;
            }

            default:
                throw new NotImplementedException();
            }
        }
Exemplo n.º 2
0
        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonDown(e);

            this.previouseSelectedVisual = this.selectedVisual;

            Point cursorPosition = e.GetPosition(this);

            VisualGraphics visualHit = this.HitTestFirstVisual <ExcludedNullVisual>(cursorPosition);

            if (visualHit == null)
            {
                if (this.selectedVisual != null)
                {
                    this.selectedVisual.IsSelected   = false;
                    this.selectedVisual.IsDrawHandle = false;
                    this.selectedVisual.Render();
                    this.selectedVisual = null;
                }

                // 停止编辑状态
                this.StopVisualInputState(this.previouseSelectedVisual);
                TextBoxEditor.Visibility = Visibility.Collapsed;

                // 重置到空闲状态
                this.visualState = Visuals.VisualState.Idle;

                return;
            }

            this.ProcessSelectedVisualChanged(this.selectedVisual, visualHit);
            this.selectedVisual   = visualHit;
            this.previousPosition = cursorPosition;

            if (e.ClickCount == 2)
            {
                // 双击图形,那么进入编辑状态
                this.visualState = Visuals.VisualState.InputState;
                this.StartVisualInputState(this.selectedVisual);
            }
            else
            {
                this.StopVisualInputState(this.previouseSelectedVisual);

                #region 判断是否点击了连接点

                for (int i = 0; i < visualHit.ConnectionHandles; i++)
                {
                    Rect bounds = visualHit.GetConnectorBounds(i);
                    if (bounds.Contains(cursorPosition))
                    {
                        Point center = bounds.GetCenter();

                        ConnectionLocations location = visualHit.GetConnectorLocation(i);

                        this.visualState = Visuals.VisualState.Connecting;
                        GraphicsPolyline graphics = new GraphicsPolyline()
                        {
                            AssociatedGraphics1 = visualHit.ID,
                            Graphics1Handle     = i
                        };
                        this.polyline               = this.DrawVisual(graphics) as VisualPolyline;
                        this.firstConnector         = center;
                        this.firstConnectorLocation = location;
                        this.firstVisual            = visualHit;
                        return;
                    }
                }

                #endregion

                #region 判断是否点击了Reisze点

                for (int i = 0; i < visualHit.ResizeHandles; i++)
                {
                    Rect bounds = visualHit.GetResizeHandleBounds(i);
                    if (bounds.Contains(cursorPosition))
                    {
                        this.resizeCenter   = bounds.GetCenter();
                        this.resizeLocation = visualHit.Graphics.GetResizeLocation(this.resizeCenter);
                        this.visualState    = Visuals.VisualState.Resizing;
                        return;
                    }
                }

                #endregion

                #region 是平移状态

                // 获取当前被移动的图形所有的连接点信息

                this.associatedPolylines = this.GetAssociatedPolylines(visualHit.Graphics);
                Console.WriteLine("关联的折线有{0}个", this.associatedPolylines.Count);
                this.translateVisual = visualHit;
                this.visualState     = Visuals.VisualState.Translate;

                #endregion
            }
        }