Example #1
0
        public override void MouseDown(ViewportBase vp, ViewportEvent e)
        {
            _clickSelectionDone = false;
            if (_currentTool != null)
            {
                // If the current tool handles the event, we're done
                _currentTool.MouseDown(vp, e);
                if (e.Handled)
                {
                    return;
                }
            }
            if (!(vp is Viewport2D))
            {
                MouseDown((Viewport3D)vp, e);
                return;
            }

            if (_currentTool == null)
            {
                return;
            }

            if (_currentTool.NoSelection())
            {
                return;
            }

            var viewport = (Viewport2D)vp;

            // Otherwise we try a selection
            // Find the clicked vertices
            var vtxs = _currentTool.GetVerticesAtPoint(e.X, viewport.Height - e.Y, viewport);

            if (!vtxs.Any())
            {
                // Nothing clicked
                if (!KeyboardState.Ctrl)
                {
                    // Deselect all the points if not ctrl-ing
                    Points.ForEach(x => x.IsSelected = false);
                }

                // Try to select in 2D

                // 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 = Select.DrawCenterHandles;
                var centerOnly    = Select.ClickSelectByCenterHandlesOnly;
                // Get the first element that intersects with the box
                var solid = Document.Map.WorldSpawn.GetAllNodesIntersecting2DLineTest(box, centerHandles, centerOnly).OfType <Solid>().FirstOrDefault();

                if (solid != null)
                {
                    // select solid
                    var select   = new[] { solid };
                    var deselect = !KeyboardState.Ctrl ? Document.Selection.GetSelectedObjects() : new MapObject[0];
                    Document.PerformAction("Select VM solid", new ChangeSelection(select, deselect));

                    // Don't do other click operations
                    return;
                }

                base.MouseDown(vp, e);
                return;
            }

            var vtx = vtxs.First();

            // When clicking, only select vertices in a single solid
            vtxs = vtxs.Where(x => x.Solid == vtx.Solid).ToList();

            // If any vertices are selected, don't change the selection yet
            if (!vtxs.Any(x => x.IsSelected))
            {
                _clickSelectionDone = true;
                DoSelection(vtxs, viewport);
            }

            // Only move selected vertices
            vtxs = vtxs.Where(x => x.IsSelected).ToList();
            if (!vtxs.Any())
            {
                return;
            }

            // Use the fist vertex as the control point
            _currentTool.DragStart(vtxs);
            MoveSelection    = vtxs;
            _snapPointOffset = SnapIfNeeded(viewport.Expand(viewport.ScreenToWorld(e.X, viewport.Height - e.Y))) - viewport.ZeroUnusedCoordinate(vtx.Coordinate);
            _movingPoint     = vtx;
        }