Exemplo n.º 1
0
        /// <summary>
        /// 当鼠标移动到图形上的时候,画Handle
        /// </summary>
        /// <param name="cursorPosition">鼠标坐标的位置</param>
        /// <returns>返回鼠标移动到的图形</returns>
        private VisualGraphics DrawHandleWhenMouseOverVisual <ExcludedVisual>(Point cursorPosition) where ExcludedVisual : VisualGraphics
        {
            if (this.previouseHoveredVisual != null)
            {
                this.previouseHoveredVisual.IsDrawHandle = false;
                this.previouseHoveredVisual.Render();
                this.previouseHoveredVisual = null;
            }

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

            if (visualHit == null)
            {
                //if (this.previouseHoveredVisual != null)
                //{
                //    this.previouseHoveredVisual.IsDrawHandle = false;
                //    this.previouseHoveredVisual.Render();
                //    this.previouseHoveredVisual = null;
                //}
            }
            else
            {
                this.previouseHoveredVisual = visualHit;
                this.previouseHoveredVisual.IsDrawHandle = true;
                this.previouseHoveredVisual.Render();
            }

            return(visualHit);
        }
Exemplo n.º 2
0
        private void ProcessSelectedVisualCursor(VisualGraphics selectedVisual, Point cursorPosition)
        {
            if (selectedVisual == null)
            {
                this.Cursor = Cursors.Arrow;
                return;
            }

            for (int i = 0; i < selectedVisual.ConnectionHandles; i++)
            {
                Rect boundary = selectedVisual.GetConnectorBounds(i);
                if (boundary.Contains(cursorPosition))
                {
                    this.Cursor = Cursors.Cross;
                    return;
                }
            }

            for (int i = 0; i < selectedVisual.ResizeHandles; i++)
            {
                Rect boundary = selectedVisual.GetResizeHandleBounds(i);
                if (boundary.Contains(cursorPosition))
                {
                    this.Cursor = Cursors.Hand;
                    return;
                }
            }

            this.Cursor = Cursors.Arrow;
        }
Exemplo n.º 3
0
        public VisualGraphics DrawVisual(GraphicsBase graphics)
        {
            VisualGraphics visual = VisualFactory.Create(graphics);

            this.VisualList.Add(visual);

            this.AddVisualChild(visual);    // 该函数只会把DrawableVisual和DrawableVisualLayer关联起来,在渲染的时候并不会真正渲染。关联的目的是为了做命中测试(HitTest)。

            visual.Render();

            return(visual);
        }
Exemplo n.º 4
0
        /// <summary>
        /// 检测第一个被鼠标命中的元素
        /// </summary>
        /// <typeparam name="TExcluded">要排除在外的鼠标命中的元素的类型</typeparam>
        /// <param name="hitTestPos">鼠标坐标位置</param>
        /// <returns>第一个被鼠标命中的元素</returns>
        private VisualGraphics HitTestFirstVisual <TExcluded>(Point hitTestPos) where TExcluded : VisualGraphics
        {
            VisualTreeHelper.HitTest(this, null, this.HitTestResultCallback <TExcluded>, new PointHitTestParameters(hitTestPos));

            if (this.visualHits.Count == 0)
            {
                return(null);
            }

            // 被点击到的元素
            VisualGraphics visualHit = this.visualHits[0] as VisualGraphics;

            this.visualHits.Clear();

            return(visualHit);
        }
Exemplo n.º 5
0
        /// <summary>
        /// 保存图形里输入的文本
        /// </summary>
        private void StopVisualInputState(VisualGraphics visual)
        {
            if (this.visualState != Visuals.VisualState.InputState)
            {
                return;
            }

            if (visual == null)
            {
                return;
            }

            visual.Graphics.TextProperties.Text = this.TextBoxEditor.Text;
            visual.Render();    // 刷新文本信息
            this.TextBoxEditor.Text       = null;
            this.TextBoxEditor.Visibility = Visibility.Collapsed;
        }
Exemplo n.º 6
0
        /// <summary>
        /// 让一个图形进入编辑状态
        /// </summary>
        /// <param name="visual"></param>
        private void StartVisualInputState(VisualGraphics visual)
        {
            if (visual == null)
            {
                logger.WarnFormat("要编辑的图形为空");
                return;
            }

            Rect bounds = visual.GetTextBounds();

            this.TextBoxEditor.Width  = bounds.Width;
            this.TextBoxEditor.Height = bounds.Height;
            Canvas.SetLeft(this.TextBoxEditor, bounds.TopLeft.X);
            Canvas.SetTop(this.TextBoxEditor, bounds.TopLeft.Y);
            this.TextBoxEditor.Text       = visual.Graphics.TextProperties.Text;
            this.TextBoxEditor.Visibility = Visibility.Visible;
            this.TextBoxEditor.Focus();
        }
Exemplo n.º 7
0
        protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonUp(e);

            Point cursorPosition = e.GetPosition(this);

            switch (this.visualState)
            {
            case Visuals.VisualState.Translate:
            {
                this.visualState         = Visuals.VisualState.Idle;
                this.translateVisual     = null;
                this.associatedPolylines = null;
                break;
            }

            case Visuals.VisualState.Idle:
            {
                break;
            }

            case Visuals.VisualState.Connecting:
            {
                this.visualState  = Visuals.VisualState.Idle;
                this.firstVisual  = null;
                this.secondVisual = null;
                break;
            }

            case Visuals.VisualState.Resizing:
            {
                this.visualState = Visuals.VisualState.Idle;
                break;
            }

            case Visuals.VisualState.InputState:
            {
                break;
            }

            default:
                throw new NotImplementedException();
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// 当前选中的Visual改变的时候被调用
        /// 保证previouseSelected和selectedVisual都不为空
        /// </summary>
        /// <param name="previouseSelected"></param>
        /// <param name="selectedVisual"></param>
        private void ProcessSelectedVisualChanged(VisualGraphics previouseSelected, VisualGraphics selectedVisual)
        {
            if (previouseSelected == selectedVisual)
            {
                return;
            }

            if (previouseSelected != null)
            {
                if (previouseSelected != selectedVisual)
                {
                    previouseSelected.IsSelected = false;
                    previouseSelected.Render();

                    selectedVisual.IsSelected = true;
                    selectedVisual.Render();
                }
            }
            else
            {
                selectedVisual.IsSelected = true;
                selectedVisual.Render();
            }
        }
Exemplo n.º 9
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.º 10
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
            }
        }