public void MouseUp(MouseEventArgs e, Size parentControlSize) { _selectionMode = SelectionMode.None; if (_roomsToMove != null) { _editor.UndoManager.PushRoomsMoved(_roomsToMove.ToList(), new VectorInt3(0, _overallDelta, 0)); InvalidateParent?.Invoke(); _roomsToMove = null; } _roomMouseClicked = null; }
public void MouseMove(MouseEventArgs e, Size parentControlSize) { RectangleF barArea = getBarArea(parentControlSize); switch (_selectionMode) { case SelectionMode.SelectedLimit0: _selectedLimit0 = FromVisualY(barArea, e.Y); InvalidateParent?.Invoke(); break; case SelectionMode.SelectedLimit1: _selectedLimit1 = FromVisualY(barArea, e.Y); InvalidateParent?.Invoke(); break; case SelectionMode.SelectedLimitBoth: float barHeight = _selectedLimit1 - _selectedLimit0; float newBarPos = FromVisualY(barArea, _barMouseOffset + e.Y); newBarPos = (float)Math.Max(Math.Min(newBarPos + (double)barHeight, MaxDepth), MinDepth) - barHeight; _selectedLimit0 = newBarPos; _selectedLimit1 = newBarPos + barHeight; InvalidateParent?.Invoke(); break; case SelectionMode.RoomMove: float destinationHeight = FromVisualY(barArea, e.Y) - _roomMouseOffset; if (_roomsToMove == null) { HashSet <Room> roomsToMove = new HashSet <Room>(); // If multiple rooms are selected, build a list of rooms to move based on that. // Otherwise, use only room which was clicked before. if (_editor.SelectedRooms.Count > 1) { foreach (var room in _editor.SelectedRooms) { roomsToMove.UnionWith(_editor.Level.GetConnectedRooms(room)); } } else { roomsToMove = _editor.Level.GetConnectedRooms(_roomMouseClicked); } if (EditorActions.CheckForLockedRooms(GetParent?.Invoke(), roomsToMove)) { _roomsToMove = null; _selectionMode = SelectionMode.None; break; } _roomsToMove = roomsToMove; InvalidateParent?.Invoke(); } // limit room movement to valid range float maxHeight = MaxDepth; float minHeight = MinDepth; foreach (Room room in _roomsToMove) { float roomUpperLimit = MaxDepth - (room.Position.Y - _roomMouseClicked.Position.Y + room.GetHighestCorner()); float roomLowerLimit = MinDepth - (room.Position.Y - _roomMouseClicked.Position.Y + room.GetLowestCorner()); maxHeight = Math.Min(maxHeight, roomUpperLimit); minHeight = Math.Max(minHeight, roomLowerLimit); } destinationHeight = Math.Max(Math.Min(destinationHeight, maxHeight), minHeight); int delta = (int)(Math.Ceiling(destinationHeight) - _roomMouseClicked.Position.Y); // Snapping if (!(Control.ModifierKeys.HasFlag(Keys.Alt) || Control.ModifierKeys.HasFlag(Keys.Shift))) { HashSet <Room> roomsInGroup = new HashSet <Room>(); List <List <RelevantRoom> > roomSequences = groupBuildRoomSequences(Vector2.Zero, _groupMouseClicked); for (int i = 0; i < roomSequences.Count; ++i) { for (int j = 0; j < roomSequences[i].Count; ++j) { roomsInGroup.Add(roomSequences[i][j].Room); } } int highestGroupPoint = _editor.Level.GetHighestRoomGroupPoint(_roomsToMove); int lowestGroupPoint = _editor.Level.GetLowestRoomGroupPoint(_roomsToMove); Room nearbyRoom = _editor.Level.GetNearbyRoomBelow(_roomsToMove, roomsInGroup, lowestGroupPoint, _snappingMargin); if (nearbyRoom != null) { if (Math.Abs(delta) <= _snappingMargin) { int newDelta = -(lowestGroupPoint - (nearbyRoom.Position.Y + nearbyRoom.GetHighestCorner())); if (newDelta + highestGroupPoint > MaxDepth) { break; // Do not push room out of bounds } delta = newDelta; } else if (Math.Abs(delta) <= _snappingMargin + 1) { break; // Noise reduction } } else { nearbyRoom = _editor.Level.GetNearbyRoomAbove(_roomsToMove, roomsInGroup, highestGroupPoint, 5); if (nearbyRoom != null) { if (Math.Abs(delta) <= _snappingMargin) { int newDelta = ((nearbyRoom.Position.Y + nearbyRoom.GetLowestCorner()) - highestGroupPoint); if (newDelta + lowestGroupPoint < MinDepth) { break; // Do not push room out of bounds } delta = newDelta; } else if (Math.Abs(delta) <= _snappingMargin + 1) { break; // Noise reduction } } } } // do movement if (delta != 0) { _overallDelta += delta; EditorActions.MoveRooms(new VectorInt3(0, delta, 0), _roomsToMove, true); } break; } }
/// <returns>true, if the selection should continue in the background of the bar.</returns> public bool MouseDown(MouseEventArgs e, Size parentControlSize, Vector2 clickPos) { _selectionMode = SelectionMode.None; _overallDelta = 0; // check if the mouse click was in the bar area RectangleF barArea = getBarArea(parentControlSize); RectangleF selectionArea = barArea; selectionArea.Inflate(10.0f, _selectionMaxPixelDistanceForMove * 0.8f); if (!selectionArea.Contains(e.Location)) { return(true); } switch (e.Button) { case MouseButtons.Left: // check if the mouse click was on one of the two sliders float distanceToSelectedLimit0 = Math.Abs(e.Y - ToVisualY(barArea, _selectedLimit0)); float distanceToSelectedLimit1 = Math.Abs(e.Y - ToVisualY(barArea, _selectedLimit1)); if (distanceToSelectedLimit0 < distanceToSelectedLimit1) { if (distanceToSelectedLimit0 < _selectionMaxPixelDistanceForMove) { _selectionMode = SelectionMode.SelectedLimit0; } } else { if (distanceToSelectedLimit1 < _selectionMaxPixelDistanceForMove) { _selectionMode = SelectionMode.SelectedLimit1; } } // check if a the click happend on a room if (barArea.Contains(e.Location) && _selectionMode == SelectionMode.None) { for (int groupIndex = 0; groupIndex < GroupCount; ++groupIndex) { RectangleF groupArea = groupGetArea(barArea, groupIndex); if (groupArea.Contains(e.Location)) { _groupMouseClicked = groupIndex; float mouseDepth = FromVisualY(barArea, e.Y); List <List <RelevantRoom> > roomSequences = groupBuildRoomSequences(clickPos, groupIndex); float sequenceWidth = groupArea.Width / roomSequences.Count; for (int i = 0; i < roomSequences.Count; ++i) { float posX0 = groupArea.X + sequenceWidth * i; float posX1 = groupArea.X + sequenceWidth * (i + 1); if (e.X >= posX0 && e.X <= posX1) { for (int j = roomSequences[i].Count - 1; j >= 0; --j) { if (mouseDepth <= roomSequences[i][j].MaxDepth && mouseDepth >= roomSequences[i][j].MinDepth) { _roomMouseClicked = roomSequences[i][j].Room; _roomMouseOffset = mouseDepth - _roomMouseClicked.Position.Y; // If multiple rooms are selected, don't reset selection. if (_editor.SelectedRooms.Count <= 1 || !_editor.SelectedRooms.Contains(_roomMouseClicked)) { SelectedRoom?.Invoke(new[] { _roomMouseClicked }); } InvalidateParent?.Invoke(); _selectionMode = SelectionMode.RoomMove; return(false); } } } } break; } } selectionArea.Y = ToVisualY(barArea, Math.Max(_selectedLimit0, _selectedLimit1)); selectionArea.Height = Math.Abs(ToVisualY(barArea, _selectedLimit0) - ToVisualY(barArea, _selectedLimit1)); if (selectionArea.Contains(e.Location)) { _barMouseOffset = distanceToSelectedLimit0; _selectionMode = SelectionMode.SelectedLimitBoth; } } break; case MouseButtons.Middle: case MouseButtons.XButton1: case MouseButtons.XButton2: for (int groupIndex = 0; groupIndex < DepthProbes.Count; ++groupIndex) { RectangleF groupArea = groupGetArea(barArea, groupIndex); if (groupArea.Contains(e.Location)) { DepthProbes.RemoveAt(groupIndex); InvalidateParent?.Invoke(); break; } } break; } return(false); }