Search code examples
c++mousesfml

How do I capture(trap) a mouse in a window in c++?


I am writing a tile map editor in SFML and C++. I have been having all sorts of troubles with the mouse. I am using the built in SFML Mouse:: static functions and recently managed to get a custom cursor moving on the screen and pointing accurately to a tile by doing as follows:`

Sprite cursor;
bool focus = false;

RenderWindow window(VideoMode(512, 288), "Tilemap editor");
window.setFramerateLimit(60);

Texture cursorTexture;


if(!cursorTexture.loadFromFile("Graphics/Cursor.png")) {
    std::cout << "Failed to load cursor texture\n";
    return 0;
}

cursor.setTexture(cursorTexture);

Mouse::setPosition(mousePos);

While(window.isOpen()) {

    window.setMouseCursorVisible(focus);


    if(Mouse::getPosition().x != lastMousePos.x) {
        mousePos.x = mousePos.x + (Mouse::getPosition().x - lastMousePos.x);
    }
    if(Mouse::getPosition().y != lastMousePos.y) {
        mousePos.y = mousePos.y + (Mouse::getPosition().y - lastMousePos.y);
    }

    cursor.setPosition(mousePos.x, mousePos.y);
        
    lastMousePos = Mouse::getPosition();

    window.clear();

    window.draw(cursor)
        
    window.display()
}

The built-in Mouse functions only display relativity to the desktop or the window and as I am using this app in a small window in which my view moves, I can't use either. The solution above moves a cursor independent of the desktop and with the ability to move the cursor if and when I want to move my view.

The issue is that my mouse will move off the side of the app when I try to click items in the top left corner.

Is there a good cross-platform (I'm on Linux BTW) way to trap the mouse inside of the window unless I enter a keystroke (like a VM window)? Also, is there a better way to do cross-platform mouse support in general? SFML kinda sucks. (Code obviously needs to be in a main function and the namespace must be sf with SFML/Graphics.hpp included)


Solution

  • There is already a method for that.

    void    setMouseCursorGrabbed (bool grabbed)
    // Grab or release the mouse cursor.
    

    You can also use these methods to convert your screen coordinates to mouse coordinates and vice versa.

    Vector2f    mapPixelToCoords (const Vector2i &point) const
    // Convert a point from target coordinates to world coordinates, using the current view.
     
    Vector2f    mapPixelToCoords (const Vector2i &point, const View &view) const
    // Convert a point from target coordinates to world coordinates.
     
    Vector2i    mapCoordsToPixel (const Vector2f &point) const
    // Convert a point from world coordinates to target coordinates, using the current view.
     
    Vector2i    mapCoordsToPixel (const Vector2f &point, const View &view) const
    // Convert a point from world coordinates to target coordinates.
    

    sf::RenderWindow Class Reference