-
Alright, so I know that you can make a window that is completely borderless, meaning no title bar, no Exit/Max/Min buttons, no resizing frame, but there are plenty of examples out there of borderless windows that you can still move around. How would I go about doing this in SFML?
-
You could see if a user has their mouse in the window plus holding the left mouse button using events. If they do, simply use sf::RenderWindow::setPosition with the new coordinates.
-
Correct method is something like this...
bool windowdrag = false;
sf::Vector2i mouseoffset;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::MouseDown && dragableArea.contains(event.mousePos))
{
windowdrag = true;
mouseoffset = event.mousePos;
}
else if (event.type == sf::Event::MouseMove && windowdrag)
{
window.setPosition(event.mousePos - mouseoffset);
}
else if (event.type == sf::Event::MouseUp)
{
windowdrag = false;
}
}
}
-
I'm glad you posed this problem. It was an interesting thing to solve. This can be run as-is:
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600), "", sf::Style::None);
sf::Vector2i grabbedOffset;
bool grabbedWindow = false;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
else if (event.type == sf::Event::KeyPressed)
{
if (event.key.code == sf::Keyboard::Escape)
window.close();
}
else if (event.type == sf::Event::MouseButtonPressed)
{
if (event.mouseButton.button == sf::Mouse::Left)
{
grabbedOffset = window.getPosition() - sf::Mouse::getPosition();
grabbedWindow = true;
}
}
else if (event.type == sf::Event::MouseButtonReleased)
{
if (event.mouseButton.button == sf::Mouse::Left)
grabbedWindow = false;
}
else if (event.type == sf::Event::MouseMoved)
{
if (grabbedWindow)
window.setPosition(sf::Mouse::getPosition() + grabbedOffset);
}
}
window.clear(sf::Color::Red);
window.display();
}
}
It works on all window types, not just borderless.
You can press Escape to close or use another closing method (taskbar etc.)
EDIT: removed some code I was using for testing.
EDIT 2: just noticed that it also works in fullscreen mode :o
-
I would move some of your code outside the event loop to prevent some unwanted behaviour like dragging on an edge and moving too fast -> window doesn't move until the mouse is inside the window again and you have to click again to free the mouse^^
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600), "", sf::Style::None);
sf::Vector2i grabbedOffset;
bool grabbedWindow = false;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
else if (event.type == sf::Event::KeyPressed)
{
if (event.key.code == sf::Keyboard::Escape)
window.close();
}
else if (event.type == sf::Event::MouseButtonPressed)
{
if (event.mouseButton.button == sf::Mouse::Left)
grabbedOffset = window.getPosition() - sf::Mouse::getPosition();
}
}
window.clear(sf::Color::Red);
grabbedWindow = sf::Mouse::isButtonPressed(sf::Mouse::Left);
if (grabbedWindow)
window.setPosition(sf::Mouse::getPosition() + grabbedOffset);
window.display();
}
}
-
If someone insists on moving that fast, they deserve to have to click to reset it :P