private void ContinueResizeAndDrag(InputContext context) { if (!_isResizing && !_isDragging) { // Nothing to do. return; } var screen = Screen; var inputService = InputService; // ----- Stop dragging/resizing bool cancel = inputService.IsDown(Keys.Escape); if (cancel) { inputService.IsKeyboardHandled = true; RestoreBounds(); } if (cancel // <ESC> cancels dragging/resizing. || inputService.IsUp(MouseButtons.Left) // Mouse button is up. || inputService.IsMouseOrTouchHandled // Mouse was handled by another control. || _isResizing && !CanResize // CanResize has been reset by user during resizing. || _isDragging && !CanDrag) // CanDrag has been reset by user during dragging. { screen.UIService.Cursor = null; _setSpecialCursor = false; _isResizing = false; _isDragging = false; return; } // Clamp mouse position to screen. (Only relevant if game runs in windowed-mode.) Vector2F screenMousePosition = context.ScreenMousePosition; float left = screen.ActualX; float right = left + screen.ActualWidth; float top = screen.ActualY; float bottom = top + screen.ActualHeight; screenMousePosition.X = MathHelper.Clamp(screenMousePosition.X, left, right); screenMousePosition.Y = MathHelper.Clamp(screenMousePosition.Y, top, bottom); Vector2F delta = screenMousePosition - _mouseStartPosition; // Undo render transform of screen. if (screen.HasRenderTransform) delta = screen.RenderTransform.FromRenderDirection(delta); if (delta != Vector2F.Zero) { // ----- Handle ongoing resizing operation. if (_isResizing) { // Resizing only works when there is no render transform or the render // transform origin is the top, left corner. Otherwise, it does not work // correct because resizing the window simultaneously changes the render // transform! // Restore original render transform. var transform = new Rendering.RenderTransform(_startPosition, _startSize.X, _startSize.Y, RenderTransformOrigin, RenderScale, RenderRotation, RenderTranslation); // Apply delta in local space of window. delta = transform.FromRenderDirection(delta); // Ensure limits. if ((_resizeDirection & ResizeDirection.E) != 0) { float width = _startSize.X + delta.X; width = MathHelper.Clamp(width, MinWidth, MaxWidth); delta.X = width - _startSize.X; } else if ((_resizeDirection & ResizeDirection.W) != 0) { float width = _startSize.X - delta.X; width = MathHelper.Clamp(width, MinWidth, MaxWidth); delta.X = _startSize.X - width; } else { delta.X = 0; } if ((_resizeDirection & ResizeDirection.S) != 0) { float height = _startSize.Y + delta.Y; height = MathHelper.Clamp(height, MinHeight, MaxHeight); delta.Y = height - _startSize.Y; } else if ((_resizeDirection & ResizeDirection.N) != 0) { float height = _startSize.Y - delta.Y; height = MathHelper.Clamp(height, MinHeight, MaxHeight); delta.Y = _startSize.Y - height; } else { delta.Y = 0; } Vector2F topLeft = _startPosition; Vector2F bottomRight = _startPosition + _startSize; switch (_resizeDirection) { case ResizeDirection.N: case ResizeDirection.W: case ResizeDirection.NW: topLeft += delta; break; case ResizeDirection.NE: bottomRight.X += delta.X; topLeft.Y += delta.Y; break; case ResizeDirection.E: case ResizeDirection.SE: case ResizeDirection.S: bottomRight += delta; break; case ResizeDirection.SW: topLeft.X += delta.X; bottomRight.Y += delta.Y; break; } topLeft = transform.ToRenderPosition(topLeft); bottomRight = transform.ToRenderPosition(bottomRight); X = topLeft.X; // Note: Setting X, Y changes the render transform! Y = topLeft.Y; transform = RenderTransform; topLeft = transform.FromRenderPosition(topLeft); bottomRight = transform.FromRenderPosition(bottomRight); Width = bottomRight.X - topLeft.X; Height = bottomRight.Y - topLeft.Y; InvalidateArrange(); inputService.IsMouseOrTouchHandled = true; return; } // ----- Handle ongoing dragging operation. if (_isDragging) { X = _startPosition.X + delta.X; Y = _startPosition.Y + delta.Y; InvalidateArrange(); inputService.IsMouseOrTouchHandled = true; } } }