Click-and-Drag Selection

How do I implement a click-and-drag selection rectangle?

Implementing a selection rectangle involves tracking the start and current positions of a drag operation to define the rectangle's bounds. Here's how to create one:

#include <SDL.h>
#include <iostream>
#include "Window.h"

class SelectionBox {
 public:
  void Tick() {
    int MouseX, MouseY;
    Uint32 Buttons = SDL_GetMouseState(
      &MouseX, &MouseY);

    if (Buttons & SDL_BUTTON_LMASK) {
      if (!IsSelecting) {
        // Start new selection
        StartX = MouseX;
        StartY = MouseY;
        IsSelecting = true;
      }

      // Calculate rectangle bounds
      CurrentX = MouseX;
      CurrentY = MouseY;

      int Left = std::min(StartX, CurrentX);
      int Right = std::max(StartX, CurrentX);
      int Top = std::min(StartY, CurrentY);
      int Bottom = std::max(StartY, CurrentY);

      int Width = Right - Left;
      int Height = Bottom - Top;

      std::cout << "Selection: Position("
        << Left << ", " << Top << ") "
        << "Size(" << Width << ", "
        << Height << ")\n";
    } else if (IsSelecting) {
      // Selection complete
      IsSelecting = false;
      PrintFinalSelection();
    }
  }

 private:
  bool IsSelecting{false};
  int StartX{0}, StartY{0};
  int CurrentX{0}, CurrentY{0};

  void PrintFinalSelection() {
    int Left = std::min(StartX, CurrentX);
    int Right = std::max(StartX, CurrentX);
    int Top = std::min(StartY, CurrentY);
    int Bottom = std::max(StartY, CurrentY);

    std::cout << "Final selection area: ("
      << Left << ", " << Top << ") to ("
      << Right << ", " << Bottom << ")\n";
  }
};

int main(int argc, char** argv) {
  SDL_Init(SDL_INIT_VIDEO);
  Window GameWindow;
  SelectionBox Selection;
  SDL_Event E;

  while (true) {
    while (SDL_PollEvent(&E)) {
      // Handle other events...
    }

    Selection.Tick();
    GameWindow.Update();
  }

  SDL_Quit();
  return 0;
}
Selection: Position(100, 150) Size(5, 3)
Selection: Position(100, 150) Size(10, 8)
Selection: Position(100, 150) Size(15, 12)
Final selection area: (100, 150) to (115, 162)

How It Works

The selection rectangle system works by:

  1. Storing the initial click position when the left mouse button is first pressed
  2. Continuously updating the current mouse position while dragging
  3. Calculating the rectangle bounds by finding the minimum and maximum X/Y coordinates
  4. Supporting selections in any direction (up/down/left/right)

Enhanced Version

Here's an enhanced version that includes minimum size and snapping:

#include <SDL.h>

class AdvancedSelectionBox {
 public:
  void Tick() {
    int MouseX, MouseY;
    Uint32 Buttons = SDL_GetMouseState(
      &MouseX, &MouseY);

    if (Buttons & SDL_BUTTON_LMASK) {
      if (!IsSelecting) {
        StartX = MouseX;
        StartY = MouseY;
        IsSelecting = true;
      }

      CurrentX = MouseX;
      CurrentY = MouseY;

      // Add minimum size requirement
      int Width = std::abs(CurrentX - StartX);
      int Height = std::abs(CurrentY - StartY);

      if (Width < MinimumSize) {
        CurrentX = StartX + (CurrentX > StartX
          ? MinimumSize : -MinimumSize);
      }

      if (Height < MinimumSize) {
        CurrentY = StartY + (CurrentY > StartY
          ? MinimumSize : -MinimumSize);
      }

      // Snap to grid
      CurrentX = (CurrentX / GridSize) * GridSize;
      CurrentY = (CurrentY / GridSize) * GridSize;

      PrintSelection();
    } else if (IsSelecting) {
      IsSelecting = false;
      PrintFinalSelection();
    }
  }

 private:
  static const int MinimumSize = 10;
  static const int GridSize = 8;
  bool IsSelecting{false};
  int StartX{0}, StartY{0};
  int CurrentX{0}, CurrentY{0};
};

This enhanced version includes:

  • Minimum selection size requirement
  • Grid snapping for more precise selections
  • Support for selections in any direction
  • Clean separation of selection logic from rendering

The system is flexible enough to be used for many purposes:

  • Selecting multiple objects in a game
  • Drawing rectangles in an art program
  • Defining regions for game mechanics
  • Creating UI elements dynamically

Mouse State

Learn how to monitor mouse position and button states in real-time using SDL's state query functions

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Calculating Mouse Pointer Angle
How can I get the mouse pointer's angle relative to a position on the screen?
Calculating Mouse Speed
Can I get the mouse speed or how fast it's moving?
Click and Drag Detection
How do I detect if the user is clicking and dragging?
Events vs State for Mouse Input
What's the difference between using events and using state checking for mouse position?
Smooth Mouse Following
How can I make an object follow the mouse cursor smoothly?
Cursor Trail Effect
How do I implement a cursor trail effect?
Or Ask your Own Question
Purchase the course to ask your own questions