Ejemplo n.º 1
0
        public override Matrix4? GetTransformationMatrix(Viewport2D viewport, ViewportEvent e, BaseBoxTool.BoxState state, Document doc, IEnumerable<Widget> activeWidgets)
        {
            var origin = viewport.ZeroUnusedCoordinate((state.PreTransformBoxStart + state.PreTransformBoxEnd) / 2);
            var rw = activeWidgets.OfType<RotationWidget>().FirstOrDefault();
            if (rw != null) origin = rw.GetPivotPoint();

            var forigin = viewport.Flatten(origin);

            var origv = (state.MoveStart - forigin).Normalise();
            var newv = (viewport.ScreenToWorld(e.X, viewport.Height - e.Y) - forigin).Normalise();

            var angle = DMath.Acos(Math.Max(-1, Math.Min(1, origv.Dot(newv))));
            if ((origv.Cross(newv).Z < 0)) angle = 2 * DMath.PI - angle;

            var shf = KeyboardState.Shift;
            var def = Select.RotationStyle;
            var snap = (def == RotationStyle.SnapOnShift && shf) || (def == RotationStyle.SnapOffShift && !shf);
            if (snap)
            {
                var deg = angle * (180 / DMath.PI);
                var rnd = Math.Round(deg / 15) * 15;
                angle = rnd * (DMath.PI / 180);
            }

            Matrix4 rotm;
            if (viewport.Direction == Viewport2D.ViewDirection.Top) rotm = Matrix4.CreateRotationZ((float)angle);
            else if (viewport.Direction == Viewport2D.ViewDirection.Front) rotm = Matrix4.CreateRotationX((float)angle);
            else rotm = Matrix4.CreateRotationY((float)-angle); // The Y axis rotation goes in the reverse direction for whatever reason

            var mov = Matrix4.CreateTranslation((float)-origin.X, (float)-origin.Y, (float)-origin.Z);
            var rot = Matrix4.Mult(mov, rotm);
            return Matrix4.Mult(rot, Matrix4.Invert(mov));
        }
Ejemplo n.º 2
0
 public void BeforeRender2D(Viewport2D viewport)
 {
     _offset = 3 / (double)viewport.Zoom;
     _fadeDistance = 200 / (double)viewport.Zoom;
     var mp = viewport.PointToClient(Control.MousePosition);
     _mousePos = viewport.ScreenToWorld(new Coordinate(mp.X, viewport.Height - mp.Y, 0));
     GL.Enable(EnableCap.LineSmooth);
     GL.Begin(BeginMode.Lines);
 }
Ejemplo n.º 3
0
        protected override void Render2D(Sledge.UI.Viewport2D viewport)
        {
            if (State.Action == BoxAction.ReadyToDraw || State.Action == BoxAction.DownToDraw)
            {
                return;
            }
            var start = viewport.Flatten(State.BoxStart);
            var end   = viewport.Flatten(State.BoxEnd);

            if (ShouldDrawBox(viewport))
            {
                var min = viewport.ScreenToWorld(0, 0);
                var max = viewport.ScreenToWorld(viewport.Width, viewport.Height);

                GL.Color4(Color.FromArgb(128, Color.Orange));
                GL.Begin(BeginMode.Quads);

                Coord(min.DX, min.DY, 0);
                Coord(max.DX, min.DY, 0);
                Coord(max.DX, start.DY, 0);
                Coord(min.DX, start.DY, 0);

                Coord(min.DX, end.DY, 0);
                Coord(max.DX, end.DY, 0);
                Coord(max.DX, max.DY, 0);
                Coord(min.DX, max.DY, 0);

                Coord(min.DX, start.DY, 0);
                Coord(start.DX, start.DY, 0);
                Coord(start.DX, end.DY, 0);
                Coord(min.DX, end.DY, 0);

                Coord(end.DX, start.DY, 0);
                Coord(max.DX, start.DY, 0);
                Coord(max.DX, end.DY, 0);
                Coord(end.DX, end.DY, 0);

                GL.End();


                GL.LineWidth(2);
                GL.Begin(BeginMode.LineLoop);
                GL.Color3(GetRenderBoxColour());
                Coord(start.DX, start.DY, start.DZ);
                Coord(end.DX, start.DY, start.DZ);
                Coord(end.DX, end.DY, start.DZ);
                Coord(start.DX, end.DY, start.DZ);
                GL.End();
                GL.LineWidth(1);
            }

            if (ShouldRenderResizeBox(viewport))
            {
                RenderResizeBox(viewport, start, end);
            }
        }
Ejemplo n.º 4
0
 public void Render2D(Viewport2D viewport, MapObject o)
 {
     if (Sledge.Settings.Select.CenterHandlesActiveViewportOnly && !viewport.IsFocused) return;
     var center = viewport.Flatten(o.BoundingBox.Center);
     double a = 192;
     if (Sledge.Settings.Select.CenterHandlesFollowCursor)
     {
         var dist = (double) (center - _mousePos).VectorMagnitude();
         if (dist >= _fadeDistance) return;
         a = 192 * ((_fadeDistance - dist) / _fadeDistance);
     }
     GL.Color4(Color.FromArgb((int) a, o.Colour));
     GL.Vertex2(center.DX - _offset, center.DY - _offset);
     GL.Vertex2(center.DX + _offset, center.DY + _offset);
     GL.Vertex2(center.DX - _offset, center.DY + _offset);
     GL.Vertex2(center.DX + _offset, center.DY - _offset);
 }
Ejemplo n.º 5
0
        public override Matrix4? GetTransformationMatrix(Viewport2D viewport, ViewportEvent e, BaseBoxTool.BoxState state, Document doc)
        {
            var shearUpDown = state.Handle == BaseBoxTool.ResizeHandle.Left || state.Handle == BaseBoxTool.ResizeHandle.Right;
            var shearTopRight = state.Handle == BaseBoxTool.ResizeHandle.Top || state.Handle == BaseBoxTool.ResizeHandle.Right;

            var nsmd = viewport.ScreenToWorld(e.X, viewport.Height - e.Y) - state.MoveStart;
            var mouseDiff = SnapIfNeeded(nsmd, doc);
            if (KeyboardState.Shift)
            {
                mouseDiff = doc.Snap(nsmd, doc.Map.GridSpacing / 2);
            }

            var relative = viewport.Flatten(state.PreTransformBoxEnd - state.PreTransformBoxStart);
            var shearOrigin = (shearTopRight) ? state.PreTransformBoxStart : state.PreTransformBoxEnd;

            var shearAmount = new Coordinate(mouseDiff.X / relative.Y, mouseDiff.Y / relative.X, 0);
            if (!shearTopRight) shearAmount *= -1;

            var shearMatrix = Matrix4.Identity;
            var sax = (float)shearAmount.X;
            var say = (float)shearAmount.Y;

            switch (viewport.Direction)
            {
                case Viewport2D.ViewDirection.Top:
                    if (shearUpDown) shearMatrix.M12 = say;
                    else shearMatrix.M21 = sax;
                    break;
                case Viewport2D.ViewDirection.Front:
                    if (shearUpDown) shearMatrix.M23 = say;
                    else shearMatrix.M32 = sax;
                    break;
                case Viewport2D.ViewDirection.Side:
                    if (shearUpDown) shearMatrix.M13 = say;
                    else shearMatrix.M31 = sax;
                    break;
            }

            var stran = Matrix4.CreateTranslation((float)-shearOrigin.X, (float)-shearOrigin.Y, (float)-shearOrigin.Z);
            var shear = Matrix4.Mult(stran, shearMatrix);
            return Matrix4.Mult(shear, Matrix4.Invert(stran));
        }
Ejemplo n.º 6
0
 private static Coordinate GetOriginForTransform(Viewport2D viewport, BaseBoxTool.BoxState state)
 {
     decimal x = 0;
     decimal y = 0;
     var cstart = viewport.Flatten(state.PreTransformBoxStart);
     var cend = viewport.Flatten(state.PreTransformBoxEnd);
     switch (state.Handle)
     {
         case BaseBoxTool.ResizeHandle.TopLeft:
         case BaseBoxTool.ResizeHandle.Top:
         case BaseBoxTool.ResizeHandle.TopRight:
         case BaseBoxTool.ResizeHandle.Left:
         case BaseBoxTool.ResizeHandle.Right:
             y = cstart.Y;
             break;
         case BaseBoxTool.ResizeHandle.BottomLeft:
         case BaseBoxTool.ResizeHandle.Bottom:
         case BaseBoxTool.ResizeHandle.BottomRight:
             y = cend.Y;
             break;
     }
     switch (state.Handle)
     {
         case BaseBoxTool.ResizeHandle.Top:
         case BaseBoxTool.ResizeHandle.TopRight:
         case BaseBoxTool.ResizeHandle.Right:
         case BaseBoxTool.ResizeHandle.BottomRight:
         case BaseBoxTool.ResizeHandle.Bottom:
             x = cstart.X;
             break;
         case BaseBoxTool.ResizeHandle.TopLeft:
         case BaseBoxTool.ResizeHandle.Left:
         case BaseBoxTool.ResizeHandle.BottomLeft:
             x = cend.X;
             break;
     }
     return viewport.Expand(new Coordinate(x, y, 0));
 }
Ejemplo n.º 7
0
 public override Matrix4? GetTransformationMatrix(Viewport2D viewport, ViewportEvent e, BaseBoxTool.BoxState state, Document doc)
 {
     var coords = GetBoxCoordinatesForSelectionResize(viewport, e, state, doc);
     state.BoxStart = coords.Item1;
     state.BoxEnd = coords.Item2;
     Matrix4 resizeMatrix;
     if (state.Handle == BaseBoxTool.ResizeHandle.Center)
     {
         var movement = state.BoxStart - state.PreTransformBoxStart;
         resizeMatrix = Matrix4.CreateTranslation((float)movement.X, (float)movement.Y, (float)movement.Z);
     }
     else
     {
         var resize = (state.PreTransformBoxStart - state.BoxStart) +
                      (state.BoxEnd - state.PreTransformBoxEnd);
         resize = resize.ComponentDivide(state.PreTransformBoxEnd - state.PreTransformBoxStart);
         resize += new Coordinate(1, 1, 1);
         var offset = -GetOriginForTransform(viewport, state);
         var trans = Matrix4.CreateTranslation((float)offset.X, (float)offset.Y, (float)offset.Z);
         var scale = Matrix4.Mult(trans, Matrix4.Scale((float)resize.X, (float)resize.Y, (float)resize.Z));
         resizeMatrix = Matrix4.Mult(scale, Matrix4.Invert(trans));
     }
     return resizeMatrix;
 }
Ejemplo n.º 8
0
        private void RenderTransformBox(Viewport2D viewport)
        {
            if (!CurrentTransform.HasValue) return;

            var box = new Box(State.PreTransformBoxStart, State.PreTransformBoxEnd);
            var trans = CreateMatrixMultTransformation(CurrentTransform.Value);
            box = box.Transform(trans);
            var s = viewport.Flatten(box.Start);
            var e = viewport.Flatten(box.End);

            GL.Enable(EnableCap.LineStipple);
            GL.LineStipple(10, 0xAAAA);
            GL.Begin(PrimitiveType.Lines);
            GL.Color4(Color.FromArgb(64, BoxColour));

            Coord(s.DX, s.DY, e.DZ);
            Coord(e.DX, s.DY, e.DZ);

            Coord(s.DX, e.DY, e.DZ);
            Coord(e.DX, e.DY, e.DZ);

            Coord(s.DX, s.DY, e.DZ);
            Coord(s.DX, e.DY, e.DZ);

            Coord(e.DX, s.DY, e.DZ);
            Coord(e.DX, e.DY, e.DZ);

            GL.End();
            GL.Disable(EnableCap.LineStipple);

            RenderBoxText(viewport, s, e);
        }
Ejemplo n.º 9
0
 private Matrix4? GetTransformMatrix(Viewport2D viewport, ViewportEvent e)
 {
     if (_currentTool == null) return null;
     return State.Handle == ResizeHandle.Center
                ? _tools.OfType<ResizeTool>().First().GetTransformationMatrix(viewport, e, State, Document, _widgets)
                : _currentTool.GetTransformationMatrix(viewport, e, State, Document, _widgets);
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Render all the handles as squares or circles depending on class implementation
        /// </summary>
        /// <param name="viewport">The viewport to draw in</param>
        /// <param name="start">The start of the box</param>
        /// <param name="end">The end of the box</param>
        private void RenderHandles(Viewport2D viewport, Coordinate start, Coordinate end)
        {
            if (_currentTool == null) return;
            var circles = _currentTool.RenderCircleHandles;

            // Get the filtered list of handles, and convert them to vector locations
            var z = (double)viewport.Zoom;
            var handles = _currentTool.GetHandles(start, end, viewport.Zoom)
                .Where(x => _currentTool.FilterHandle(x.Item1))
                .Select(x => new Vector2d((double)x.Item2, (double)x.Item3))
                .ToList();

            // Draw the insides of the handles in white
            GL.Color3(Color.White);
            foreach (var handle in handles)
            {
                GL.Begin(BeginMode.Polygon);
                if (circles) GLX.Circle(handle, 4, z, loop: true);
                else GLX.Square(handle, 4, z, true);
                GL.End();
            }

            // Draw the borders of the handles in black
            GL.Color3(Color.Black);
            GL.Begin(BeginMode.Lines);
            foreach (var handle in handles)
            {
                if (circles) GLX.Circle(handle, 4, z);
                else GLX.Square(handle, 4, z);
            }
            GL.End();
        }
Ejemplo n.º 11
0
        protected override void Render2D(Viewport2D viewport)
        {
            if (_currentTool == null)
            {
                base.Render2D(viewport);
                return;
            }

            var start = viewport.Flatten(State.BoxStart);
            var end = viewport.Flatten(State.BoxEnd);

            if (ShouldDrawBox(viewport))
            {
                RenderBox(viewport, start, end);
            }

            if (ShouldRenderResizeBox(viewport))
            {
                RenderResizeBox(viewport, start, end);
            }

            if (ShouldRenderHandles())
            {
                RenderHandles(viewport, start, end);
            }

            if (State.Action == BoxAction.Resizing && CurrentTransform.HasValue)
            {
                RenderTransformBox(viewport);
            }
            else if (ShouldDrawBox(viewport))
            {
                RenderBoxText(viewport, start, end);
            }
        }
Ejemplo n.º 12
0
 protected override bool ShouldRenderResizeBox(Viewport2D viewport)
 {
     if (_currentTool != null)
     {
         return State.Action == BoxAction.ReadyToResize && State.Handle == ResizeHandle.Center;
     }
     return base.ShouldRenderResizeBox(viewport);
 }
Ejemplo n.º 13
0
 protected override void LeftMouseDownToDraw(Viewport2D viewport, ViewportEvent e)
 {
     base.LeftMouseDownToDraw(viewport, e);
     if (_lastBox == null) return;
     State.BoxStart += viewport.GetUnusedCoordinate(_lastBox.Start);
     State.BoxEnd += viewport.GetUnusedCoordinate(_lastBox.End);
     _updatePreview = true;
 }
Ejemplo n.º 14
0
        public void Render2D(Viewport2D viewport, MapObject o)
        {
            if (viewport.Zoom < 1) return;

            var entityData = o.GetEntityData();
            if (entityData == null) return;

            var start = viewport.WorldToScreen(viewport.Flatten(o.BoundingBox.Start));
            var end = viewport.WorldToScreen(viewport.Flatten(o.BoundingBox.End));
            if (start.X >= viewport.Width || end.X <= 0 || start.Y >= viewport.Height || end.Y <= 0) return;

            var text = entityData.Name;
            var nameProp = entityData.GetPropertyValue("targetname");
            if (!String.IsNullOrWhiteSpace(nameProp)) text += ": " + nameProp;

            _printer.Print(text, _printerFont, o.Colour, new RectangleF((float)start.X + 2, viewport.Height - (float)end.Y - _printerFont.Height - 6, viewport.Width, viewport.Height));
        }
Ejemplo n.º 15
0
 protected override void LeftMouseUpDrawing(Viewport2D viewport, ViewportEvent e)
 {
     base.LeftMouseUpDrawing(viewport, e);
     if (Sledge.Settings.Select.AutoSelectBox)
     {
         BoxDrawnConfirm(viewport);
     }
 }
Ejemplo n.º 16
0
 public void BeforeRender2D(Viewport2D viewport)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 17
0
        protected override void LeftMouseClickOnResizeHandle(Viewport2D viewport, ViewportEvent e)
        {
            base.LeftMouseClickOnResizeHandle(viewport, e);

            if (_currentTool == null) return;

            if (KeyboardState.Ctrl)
            {
                var seltest = SelectionTest(viewport, e);
                if (seltest != null)
                {
                    var list = new[] { seltest };
                    SetSelected(seltest.IsSelected ? list : null, seltest.IsSelected ? null : list, false, IgnoreGrouping());
                    SelectionChanged();
                    return;
                }
            }

            // Cycle through active tools
            var idx = _tools.IndexOf(_currentTool);
            SetCurrentTool(_tools[(idx + 1) % _tools.Count]);
        }
Ejemplo n.º 18
0
        /// <summary>
        /// The select tool will deselect all selected objects if ctrl is not held down when drawing a box.
        /// </summary>
        /// <param name="viewport">The viewport to draw in</param>
        /// <param name="e">The mouse event</param>
        protected override void LeftMouseDownToDraw(Viewport2D viewport, ViewportEvent e)
        {
            // If we've clicked outside a selection box and not holding down control, clear the selection
            if (!Document.Selection.IsEmpty() && !KeyboardState.Ctrl)
            {
                SetSelected(null, null, true, IgnoreGrouping());
            }

            // We're drawing a selection box, so clear the current tool
            SetCurrentTool(null);

            base.LeftMouseDownToDraw(viewport, e);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// If the mouse is single-clicked in a 2D viewport, select the closest element that is under the cursor
        /// </summary>
        /// <param name="viewport">The 2D viewport</param>
        /// <param name="e">The mouse event</param>
        protected override void LeftMouseClick(Viewport2D viewport, ViewportEvent e)
        {
            var seltest = SelectionTest(viewport, e);
            if (seltest != null)
            {
                var list = new[] { seltest };
                SetSelected(seltest.IsSelected ? list : null, seltest.IsSelected ? null : list, false, IgnoreGrouping());
            }

            base.LeftMouseClick(viewport, e);
            SelectionChanged();
        }
Ejemplo n.º 20
0
 public abstract void Render2D(Viewport2D viewport);
Ejemplo n.º 21
0
 public abstract List<VMPoint> GetVerticesAtPoint(int x, int y, Viewport2D viewport);
Ejemplo n.º 22
0
        private MapObject SelectionTest(Viewport2D viewport, ViewportEvent e)
        {
            // Create a box to represent the click, with a tolerance level
            var unused = viewport.GetUnusedCoordinate(new Coordinate(100000, 100000, 100000));
            var tolerance = 4 / viewport.Zoom; // Selection tolerance of four pixels
            var used = viewport.Expand(new Coordinate(tolerance, tolerance, 0));
            var add = used + unused;
            var click = viewport.Expand(viewport.ScreenToWorld(e.X, viewport.Height - e.Y));
            var box = new Box(click - add, click + add);

            var centerHandles = Sledge.Settings.Select.DrawCenterHandles;
            var centerOnly = Sledge.Settings.Select.ClickSelectByCenterHandlesOnly;
            // Get the first element that intersects with the box, selecting or deselecting as needed
            return Document.Map.WorldSpawn.GetAllNodesIntersecting2DLineTest(box, centerHandles, centerOnly).FirstOrDefault();
        }
Ejemplo n.º 23
0
        private void Render2D(Viewport2D viewport, Document document)
        {
            var start = viewport.Flatten(document.Map.CordonBounds.Start);
            var end = viewport.Flatten(document.Map.CordonBounds.End);

            var min = viewport.ScreenToWorld(0, 0);
            var max = viewport.ScreenToWorld(viewport.Width, viewport.Height);

            GL.Color4(Color.FromArgb(128, Color.Purple));
            GL.Begin(BeginMode.Quads);

            GL.Vertex3(min.DX, min.DY, 0);
            GL.Vertex3(max.DX, min.DY, 0);
            GL.Vertex3(max.DX, start.DY, 0);
            GL.Vertex3(min.DX, start.DY, 0);

            GL.Vertex3(min.DX, end.DY, 0);
            GL.Vertex3(max.DX, end.DY, 0);
            GL.Vertex3(max.DX, max.DY, 0);
            GL.Vertex3(min.DX, max.DY, 0);

            GL.Vertex3(min.DX, start.DY, 0);
            GL.Vertex3(start.DX, start.DY, 0);
            GL.Vertex3(start.DX, end.DY, 0);
            GL.Vertex3(min.DX, end.DY, 0);

            GL.Vertex3(end.DX, start.DY, 0);
            GL.Vertex3(max.DX, start.DY, 0);
            GL.Vertex3(max.DX, end.DY, 0);
            GL.Vertex3(end.DX, end.DY, 0);

            GL.End();

            GL.LineWidth(2);
            GL.Begin(BeginMode.LineLoop);
            GL.Color3(Color.Red);
            GL.Vertex3(start.DX, start.DY, start.DZ);
            GL.Vertex3(end.DX, start.DY, start.DZ);
            GL.Vertex3(end.DX, end.DY, start.DZ);
            GL.Vertex3(start.DX, end.DY, start.DZ);
            GL.End();
            GL.LineWidth(1);
        }
Ejemplo n.º 24
0
 public override void OverrideViewportContextMenu(ViewportContextMenu menu, Viewport2D vp, ViewportEvent e)
 {
     menu.Items.Clear();
     if (State.Handle == ResizeHandle.Center)
     {
         var item = new ToolStripMenuItem("Create Object");
         item.Click += (sender, args) => BoxDrawnConfirm(vp);
         menu.Items.Add(item);
     }
 }
Ejemplo n.º 25
0
 public void AfterRender2D(Viewport2D viewport)
 {
     _printer.End();
 }
Ejemplo n.º 26
0
 protected override void Render2D(Viewport2D viewport)
 {
     base.Render2D(viewport);
     if (ShouldDrawBox(viewport) && _preview != null)
     {
         GL.Color3(GetRenderColour());
         Graphics.Helpers.Matrix.Push();
         var matrix = viewport.GetModelViewMatrix();
         GL.MultMatrix(ref matrix);
         MapObjectRenderer.DrawWireframe(_preview, true, false);
         Graphics.Helpers.Matrix.Pop();
     }
 }
Ejemplo n.º 27
0
 public void BeforeRender2D(Viewport2D viewport)
 {
     _printer.Begin();
 }
Ejemplo n.º 28
0
 public void Render2D(Viewport2D viewport, MapObject o)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 29
0
        protected override void MouseDraggingToResize(Viewport2D viewport, ViewportEvent e)
        {
            if (_currentTool == null)
            {
                base.MouseDraggingToResize(viewport, e);
                return;
            }

            State.Action = BoxAction.Resizing;
            CurrentTransform = GetTransformMatrix(viewport, e);
            if (CurrentTransform.HasValue)
            {
                Document.SetSelectListTransform(CurrentTransform.Value);
                var box = new Box(State.PreTransformBoxStart, State.PreTransformBoxEnd);
                var trans = CreateMatrixMultTransformation(CurrentTransform.Value);
                Mediator.Publish(EditorMediator.SelectionBoxChanged, box.Transform(trans));
            }
            else
            {
                //OnBoxChanged();
            }
        }
Ejemplo n.º 30
0
        protected override void LeftMouseUpResizing(Viewport2D viewport, ViewportEvent e)
        {
            if (_currentTool == null)
            {
                base.LeftMouseUpResizing(viewport, e);
                return;
            }

            // Execute the transform on the selection
            var transformation = GetTransformMatrix(viewport, e);
            if (transformation.HasValue)
            {
                var createClone = KeyboardState.Shift && State.Handle == ResizeHandle.Center;
                ExecuteTransform(_currentTool.GetTransformName(), CreateMatrixMultTransformation(transformation.Value), createClone);
            }
            Document.EndSelectionTransform();
            State.ActiveViewport = null;
            State.Action = BoxAction.Drawn;

            SelectionChanged();
        }
Ejemplo n.º 31
0
        /// <summary>
        /// When the mouse is hovering over the box, do collision tests against the handles and change the cursor if needed.
        /// </summary>
        /// <param name="viewport">The viewport</param>
        /// <param name="e">The mouse event</param>
        protected override void MouseHoverWhenDrawn(Viewport2D viewport, ViewportEvent e)
        {
            if (_currentTool == null)
            {
                base.MouseHoverWhenDrawn(viewport, e);
                return;
            }

            var padding = 7 / viewport.Zoom;

            viewport.Cursor = Cursors.Default;
            State.Action = BoxAction.Drawn;
            State.ActiveViewport = null;

            var now = viewport.ScreenToWorld(e.X, viewport.Height - e.Y);
            var start = viewport.Flatten(State.BoxStart);
            var end = viewport.Flatten(State.BoxEnd);

            var ccs = new Coordinate(Math.Min(start.X, end.X), Math.Min(start.Y, end.Y), 0);
            var cce = new Coordinate(Math.Max(start.X, end.X), Math.Max(start.Y, end.Y), 0);

            // Check center handle
            if (now.X > ccs.X && now.X < cce.X && now.Y > ccs.Y && now.Y < cce.Y)
            {
                State.Handle = ResizeHandle.Center;
                State.ActiveViewport = viewport;
                State.Action = BoxAction.ReadyToResize;
                viewport.Cursor = CursorForHandle(State.Handle);
                return;
            }

            // Check other handles
            foreach (var handle in _currentTool.GetHandles(start, end, viewport.Zoom).Where(x => _currentTool.FilterHandle(x.Item1)))
            {
                var x = handle.Item2;
                var y = handle.Item3;
                if (now.X < x - padding || now.X > x + padding || now.Y < y - padding || now.Y > y + padding) continue;
                State.Handle = handle.Item1;
                State.ActiveViewport = viewport;
                State.Action = BoxAction.ReadyToResize;
                viewport.Cursor = CursorForHandle(State.Handle);
                return;
            }
        }