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(); }
private Tuple<Coordinate, Coordinate> SnapBoxCoordinatesIfNeeded(Viewport2D viewport, Coordinate start, Coordinate end) { if (State.Action == BoxAction.Resizing && State.Handle == ResizeHandle.Center) { // Pick the corner to snap var ms = State.MoveStart; var pts = viewport.Flatten(State.PreTransformBoxStart); var pte = viewport.Flatten(State.PreTransformBoxEnd); var ss = SnapIfNeeded(start); var se = SnapIfNeeded(end); var middle = (pts + pte) / 2; var delta = ss - start; if (ms.Y > middle.Y) { // Top delta.Y = se.Y - end.Y; } if (ms.X > middle.X) { // Right delta.X = se.X - end.X; } start += delta; end += delta; } var cstart = viewport.Expand(start) + viewport.GetUnusedCoordinate(State.BoxStart); var cend = viewport.Expand(end) + viewport.GetUnusedCoordinate(State.BoxEnd); return Tuple.Create(cstart, cend); }
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)); }
protected virtual void LeftMouseDownToDraw(Viewport2D viewport, ViewportEvent e) { State.ActiveViewport = viewport; State.Action = BoxAction.DownToDraw; State.BoxStart = SnapIfNeeded(viewport.Expand(viewport.ScreenToWorld(e.X, viewport.Height - e.Y))); State.BoxEnd = State.BoxStart; State.Handle = ResizeHandle.BottomLeft; OnBoxChanged(); }
protected Tuple<Coordinate, Coordinate> GetResizedBoxCoordinates(Viewport2D viewport, ViewportEvent e) { if (State.Action != BoxAction.Resizing && State.Action != BoxAction.Drawing) return Tuple.Create(State.BoxStart, State.BoxEnd); var now = SnapIfNeeded(viewport.ScreenToWorld(e.X, viewport.Height - e.Y)); var cstart = viewport.Flatten(State.BoxStart); var cend = viewport.Flatten(State.BoxEnd); // Proportional scaling var ostart = viewport.Flatten(State.PreTransformBoxStart ?? Coordinate.Zero); var oend = viewport.Flatten(State.PreTransformBoxEnd ?? Coordinate.Zero); var owidth = oend.X - ostart.X; var oheight = oend.Y - ostart.Y; var proportional = KeyboardState.Ctrl && State.Action == BoxAction.Resizing && owidth != 0 && oheight != 0; switch (State.Handle) { case ResizeHandle.TopLeft: cstart.X = now.X; cend.Y = now.Y; break; case ResizeHandle.Top: cend.Y = now.Y; break; case ResizeHandle.TopRight: cend.X = now.X; cend.Y = now.Y; break; case ResizeHandle.Left: cstart.X = now.X; break; case ResizeHandle.Center: var cdiff = cend - cstart; var distance = GetResizeDistance(viewport, e); if (distance == null) cstart = viewport.Flatten(State.PreTransformBoxStart) + now - SnapIfNeeded(State.MoveStart); else cstart = viewport.Flatten(State.PreTransformBoxStart) + distance; cend = cstart + cdiff; break; case ResizeHandle.Right: cend.X = now.X; break; case ResizeHandle.BottomLeft: cstart.X = now.X; cstart.Y = now.Y; break; case ResizeHandle.Bottom: cstart.Y = now.Y; break; case ResizeHandle.BottomRight: cend.X = now.X; cstart.Y = now.Y; break; default: throw new ArgumentOutOfRangeException(); } if (proportional) { var nwidth = cend.X - cstart.X; var nheight = cend.Y - cstart.Y; var mult = Math.Max(nwidth / owidth, nheight / oheight); var pwidth = owidth * mult; var pheight = oheight * mult; var wdiff = pwidth - nwidth; var hdiff = pheight - nheight; switch (State.Handle) { case ResizeHandle.TopLeft: cstart.X -= wdiff; cend.Y += hdiff; break; case ResizeHandle.TopRight: cend.X += wdiff; cend.Y += hdiff; break; case ResizeHandle.BottomLeft: cstart.X -= wdiff; cstart.Y -= hdiff; break; case ResizeHandle.BottomRight: cend.X += wdiff; cstart.Y -= hdiff; break; } } cstart = viewport.Expand(cstart) + viewport.GetUnusedCoordinate(State.BoxStart); cend = viewport.Expand(cend) + viewport.GetUnusedCoordinate(State.BoxEnd); return Tuple.Create(cstart, cend); }