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

Author Topic: Mouse Drag Box  (Read 2417 times)

0 Members and 1 Guest are viewing this topic.

juiceeYay

  • Newbie
  • *
  • Posts: 16
    • View Profile
Mouse Drag Box
« on: January 05, 2015, 07:39:44 pm »
So I am trying to implement a mouse drag box where as long as the mouse left-click is held, a box is drawn positioned at the point of the original click and drawn out from that original click to the mouse cursor's current position, like you would use in an operating system's file explorer to select multiple files or in a RTS game to select multiple units.

My implementation below somewhat works with this problem: it draws a rectangle positioned at (0,0), not the starting click position, and draws out to where the mouse is currently, however, it doesn't fully draw it, it just flashes briefly (and doesn't even fully draw, it draws like a very random portion of it) and disappears when I'm no longer dragging the mouse.

The latter I'm guessing is because I'm using 'sf::Event::MouseMoved', but any other implementations I tried involving 'sf::Event::MouseButtonPressed' or 'sf::Event::MouseButtonReleased' using if, for, or while loops didn't even draw the rectangle at all, so I am at a loss. There are a few discussions I've seen in the forum, and I've tried implementing similarly or even exactly, and it doesn't produce any better of a result, if anything at all.

class MouseEvents
{
//will probably make all of these variables and methods static later
private:
    sf::Vector2i mousePosOnClick;
    sf::Vector2i mousePosOnHold;
   
public:
    sf::RectangleShape mouseDrawnBox;
   
    void mouseDrawBox(sf::Event &event)
    {
        if( (event.type == sf::Event::MouseButtonPressed) && (event.mouseButton.button == sf::Mouse::Left) )
        {
            mousePosOnClick.x = event.mouseButton.x;
            mousePosOnClick.y = event.mouseButton.y;
        }

        if( (event.type == sf::Event::MouseMoved) && (sf::Mouse::isButtonPressed(sf::Mouse::Left)) )
        {
            mousePosOnHold.x = event.mouseMove.x;
            mousePosOnHold.y = event.mouseMove.y;
           
            //I will add logic for negative values in 'size' later, just want something to work at all first
            sf::Vector2f size( (mousePosOnHold.x - mousePosOnClick.x), (mousePosOnHold.y - mousePosOnClick.y) );
            mouseDrawnBox.setPosition(mousePosOnClick.x, mousePosOnClick.y);
            mouseDrawnBox.setSize(size);
           
            mouseDrawnBox.setFillColor( sf::Color(0,0,255) );
        }
    }
};

int main()
{
while (window.isOpen())
    {
        sf::Event event;
        MouseEvents mouseEvent;
       
        while (window.pollEvent(event))
        {
            // Close window : exit
            if (event.type == sf::Event::Closed) {
                window.close();
            }

            // Espace pressed : exit
            if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) {
                window.close();
            }

            mouseEvent.mouseDrawBox(event);
        }

        window.clear();
        window.draw(mouseEvent.mouseDrawnBox);
        window.display();
    }
   
    return EXIT_SUCCESS;
}
« Last Edit: January 05, 2015, 07:41:44 pm by juiceeYay »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Mouse Drag Box
« Reply #1 on: January 05, 2015, 08:18:47 pm »
The easiest way is to have the MouseButtonPressed/-Released events change for example some boolean variable, which "enables" or "disables" the dragging state. Then using the MouseMoved event you can change the object's position IF the dragging state is set to true. With another if statement you could also only draw the object if the dragging state is true.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Mouse Drag Box
« Reply #2 on: January 05, 2015, 08:28:09 pm »
The bug is that your MouseEvents object is being created inside the game loop, so every frame you have a brand new one that doesn't "remember" anything about its previous lives, much less previous mouse events.  That's why you only see the box getting drawn on the exact frames when events happen.

And exploiter is right, the code would be more readable if you went with his suggestions.

juiceeYay

  • Newbie
  • *
  • Posts: 16
    • View Profile
Re: Mouse Drag Box
« Reply #3 on: January 05, 2015, 11:47:00 pm »
D'oh! I didn't realize I left my creation of the 'MouseEvent' object in the loop, come to my rescue again Ixrec, thanks again for like the millionth time haha.

Thanks as well eXpl0it3r, I reorganized the method as you suggested so I didn't have to use the real-time 'isButtonPressed' in the method and just the Pressed/Released events.