Search code examples
windowpositionmousesdlsdl-2

SDL2 Resizing the window + mouse position


I'm using SDL 2.0.4 + Code::Blocks 13.12 + GNU/Linux Ubuntu 14.04

My code explanation:
1st) I create a resizable window (SDL_Window with 1280x720 pixels)
2nd) I create a small rectangle inside it to act as a button (SDL_Rect with 150x50 pixels)
3rd) To get the mouse position and the rectangle area, I use this code:

SDL_Window window;
SDL_Rect rectangle; // <-- The button to click
SDL_Event events;

// Get current mouse position:
int mouseX = events.motion.x;
int mouseY = events.motion.y;

  // The "formula" to compare current mouse position with the rectangle area:
  if((mouseX>rectangle.x) && (mouseX<rectangle.x+rectangle.w)
  && (mouseY>rectangle.y) && (mouseY<rectangle.y+rectangle.h)) {       
   // You clicked inside the rectangle!...
  } else {
    // You missed the rectangle...
  };

If I run the above code the result is:
- Everything works fine, with no issues.

If I resize the window:
- The rectangle gets bigger (or smaller) according to the resized window (the rectangle is fitted proportionally as it should be). But then...

The Issue: http://sites.google.com/site/jorgerosaportfolio/home/UBUNTU_SDL_2_issue.jpg
- AFTER I resize the window, the original coordinates (mouse and rectangle) don't "match" anymore. How can I change that "formula" to be updated to the new rectangle area?... (OR... All this must be done in a totally different approach?)

[ADDED] THE SOLUTION:

SDL_Window window;
SDL_Rect rectangle; // <-- The button to click
SDL_Event events;

// Get current mouse position:
int mouseX = events.motion.x; // <-- In your case, most probably, will be: events.button.x;
int mouseY = events.motion.y; // <-- In your case, most probably, will be: events.button.y;

// Retrive window scale factor to apply it to mouse positions too:
int width, height;
SDL_GetWindowSize(window, &width, &height);
float scaleX = ((float)width / 1280.0);
float scaleY = ((float)height / 720.0);
mouseX /= scaleX;
mouseY /= scaleY;

  // After all, the "formula" stills the same as in the above code:
  if((mouseX>rectangle.x) && (mouseX<rectangle.x+rectangle.w)
  && (mouseY>rectangle.y) && (mouseY<rectangle.y+rectangle.h)) {       
   // You clicked inside the rectangle!...
  } else {
    // You missed the rectangle...
  };

Thankyou everyone. Thankyou joeforker! All I needed was just a "light" about this (I had to change your code to run properly, but now... It rocks!) Hope this helps someone else too.


Solution

  • If your whole drawing is scaling proportionally, then the mouse coordinates that would be inside the rectangle must also be scaled proportionally. You might try getting the window size on each frame (or whenever you get a resize event) to scale those coordinates relative to the new size.

    int width, height;
    SDL_GetWindowSize(window, &width, &height);
    scaled_x = (int)((float)width / 1280.0) * mouse_x;
    scaled_y = (int)((float)height / 720.0) * mouse_y;