Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Elegant way to check if mouse position is within a rectangle?  (Read 30926 times)

0 Members and 2 Guests are viewing this topic.

WhiteWind

  • Newbie
  • *
  • Posts: 12
    • View Profile
    • Email
Elegant way to check if mouse position is within a rectangle?
« on: February 16, 2013, 04:15:08 am »
I'm trying to make right-click tooltip menus for my game and they work just fine, but the way it's implemented seems a bit messy.

// Right click inside of a rect:
if(sf::Mouse::isButtonPressed(sf::Mouse::Right)
&& sf::Mouse::getPosition(Screen).x >= statBox.getPosition().x
&& sf::Mouse::getPosition(Screen).x <= statBox.getPosition().x + statBox.getSize().x
&& sf::Mouse::getPosition(Screen).y >= statBox.getPosition().y
&& sf::Mouse::getPosition(Screen).y <= statBox.getPosition().y + statBox.getSize().y) {
    ttBox.setPosition(sf::Vector2f(sf::Mouse::getPosition(Screen)));
    ttTitle.setPosition(sf::Vector2f(ttBox.getPosition().x + 10.f, ttBox.getPosition().y + -.5f));
    ttTitle.setString("The Tooltip");
    drawTooltip = true;
}

Like I said this works but it isn't ideal. Isn't there a way to do "if object is hovered" or "if object is clicked"? My implementation just specifies a position on the screen equal to the space within corners of the box - it doesn't specifically state that you're clicking in the box if you understand what I'm saying? Sorry if this is confusing, I'll try to explain better if you don't understand.

Thanks in advance guys!
« Last Edit: February 16, 2013, 04:17:23 am by WhiteWind »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
AW: Elegant way to check if mouse position is within a rectangle?
« Reply #1 on: February 16, 2013, 06:04:20 am »
You can get or create the sf::Rect of the stat thingy and call rect.contains(static_cast<sf::FloatRect>(sf::Mouse::getPosition(window)))
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

kaB00M

  • Full Member
  • ***
  • Posts: 101
    • View Profile
    • Caffeware
    • Email
Re: Elegant way to check if mouse position is within a rectangle?
« Reply #2 on: February 16, 2013, 06:33:56 am »
How about wrapping sf::Mouse inside a mouse class.

#include "SFML/Window.hpp"
class MyMouse{

public:
        MyMouse(const sf::Window& _window, int mouse_width, int mouse_height) :
        window(_window)
        {
                //initialize box
                mouse_box.width = mouse_width;
                mouse_box.height = mouse_height;
        }

        sf::Vector2i getPosition(const sf::Window &relativeTo){
                return sf::Mouse::getPosition(relativeTo);
        }

        //WRAP THE REST OF sf::Mouse FUNCTIONS

        bool intersects(sf::FloatRect& other_box){

                //update before comparing
                mouse_box.left =  sf::Mouse::getPosition(window).x;
                mouse_box.top =  sf::Mouse::getPosition(window).y;

                return mouse_box.intersects(other_box);
        }

private:
        const sf::Window& window;
        sf::FloatRect mouse_box;
};
 

You can use it like:

MyMouse mouse(window, 16, 16); //initialize

mouse.intersects( statBox.getGlobalBounds() ); //assuming statBox is a sf::Sprite
 
« Last Edit: February 16, 2013, 06:35:56 am by kaB00M »



eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
AW: Elegant way to check if mouse position is within a rectangle?
« Reply #3 on: February 16, 2013, 07:00:08 am »
Personally I wouldn't do that. It's not the mouse's job to check for collision and doublicating parts of the sf::Mouse interface doesn't seem like the right way to go.
Usually you'll anyways have some logic part, that holds the 'collision' area. At best it will be stored directly as sf::Rect and thus you'll get instantly access to the contains() function of the rects.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

WhiteWind

  • Newbie
  • *
  • Posts: 12
    • View Profile
    • Email
Re: Elegant way to check if mouse position is within a rectangle?
« Reply #4 on: February 17, 2013, 04:15:05 am »
I knew there'd be an easier way to do it, thanks for the help. I should be good from here.

WhiteWind

  • Newbie
  • *
  • Posts: 12
    • View Profile
    • Email
Re: AW: Elegant way to check if mouse position is within a rectangle?
« Reply #5 on: February 18, 2013, 04:23:17 pm »
You can get or create the sf::Rect of the stat thingy and call rect.contains(static_cast<sf::FloatRect>(sf::Mouse::getPosition(window)))

Actually I just tried this and I can't get it to work properly.

        // Create tooltip:
        sf::RectangleShape ttBox;
        ttBox.setSize(120.f, 120.f);
        ttBox.setFillColor(sf::Color(0, 0, 0, 175));
        sf::FloatRect ttBoxRect(ttBox.getPosition().x, ttBox.getPosition().y, ttBox.getSize().x, ttBox.getSize().y);
       
        // ...

            if(sf::Mouse::isButtonPressed(sf::Mouse::Right)
            && ttBoxRect.contains(static_cast<sf::FloatRect>(sf::Mouse::getPosition(Screen)))) {
                ttBox.setPosition(sf::Vector2f(sf::Mouse::getPosition(Screen)));
                ttTitle.setPosition(sf::Vector2f(ttBox.getPosition().x + 10.f, ttBox.getPosition().y + -.5f));
                ttTitle.setString("The Tooltip");
                drawTooltip = true;
            }

error: no matching function for call to 'sf::Rect<float>::Rect(sf::Vector2i)'|

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Elegant way to check if mouse position is within a rectangle?
« Reply #6 on: February 18, 2013, 04:31:05 pm »
Well you then didn't understand what static_cast<sf::FloatRect> stand for.
There's no implicit conversation from sf::IntRect to sf::FloatRect or the other way around. Neither does sf::FloatRect have a constructor that takes a sf::IntRect. So to get from a sf::IntRect to a sf::FloatRect one has to cast it, either explicitly with static_cast<T> or implicitly but component-wise (sf::FloatRect(intRect.x, intRect.y)).

So on line 11 you'll have to change the setPosition() code.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Elegant way to check if mouse position is within a rectangle?
« Reply #7 on: February 18, 2013, 04:43:23 pm »
He just wrote what you told him to write, ie. a cast from Vector2i to FloatRect ;)

But the correct way to do it is not a cast, you must call window.mapPixelToCoord, so that it wtill works if you have a custom view applied.
Laurent Gomila - SFML developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Elegant way to check if mouse position is within a rectangle?
« Reply #8 on: February 18, 2013, 05:34:34 pm »
He just wrote what you told him to write, ie. a cast from Vector2i to FloatRect ;)
Never mind my post above then... ::)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

WhiteWind

  • Newbie
  • *
  • Posts: 12
    • View Profile
    • Email
Re: Elegant way to check if mouse position is within a rectangle?
« Reply #9 on: February 18, 2013, 10:18:34 pm »
Am I being simple here by not seeing that Window/RenderWindow function in the documentation listings?..

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Elegant way to check if mouse position is within a rectangle?
« Reply #10 on: February 18, 2013, 11:00:48 pm »
If you use an old SFML 2, it is convertCoords.
Laurent Gomila - SFML developer

WhiteWind

  • Newbie
  • *
  • Posts: 12
    • View Profile
    • Email
Re: Elegant way to check if mouse position is within a rectangle?
« Reply #11 on: February 19, 2013, 02:29:25 am »
Ah yes, I have that function. I should probably update SFML.

So I got it working correctly and it's certainly much cleaner than what I originally had. Do I really need to make an sf::FloatRect to pair with any sf::RectangleShape I make if I want it to be clickable though? Would you suggest I make a Clickable class, with sf::Rectangle, sf::FloatRect, sf::Color, sizes etc, so I can use the mouseclick check that I've gained from this thread with it?

Thanks for your help guys.

G.

  • Hero Member
  • *****
  • Posts: 1593
    • View Profile
Re: Elegant way to check if mouse position is within a rectangle?
« Reply #12 on: February 19, 2013, 12:42:53 pm »
You can get the bounding rectangle of your shape with the getGlobalBounds method.