예제 #1
0
 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;
 }
예제 #2
0
        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;
            }
        }
예제 #3
0
        /// <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);
        }