Hi,
I want to create own GUI system and I create a simple button test. After added second button this button wrong detects a cursor position. How to fix this?
#include <SFML/Graphics.hpp>
#include <SFML\Network.hpp>
#include <string>
#include <memory>
#include <ctime>
#include <iostream>
#include <functional>
struct button {
public:
explicit button() {}
explicit button(std::string t,sf::Vector2f position,sf::RenderWindow *w) : text(t), win(w) {
std::cout << "Start init button\n";
buttonArea.top = position.x;
buttonArea.left = position.y;
buttonArea.width = 175.0f;
buttonArea.height = 90.0f;
drawText.setString(text);
drawText.setFillColor(sf::Color::Black);
drawText.setCharacterSize(24);
drawText.setPosition( position.x + (buttonArea.width / 2 ), position.y + (buttonArea.height / 2) - 24 );
colorNormal = sf::Color(115, 90, 246, 150);
c = colorNormal;
colorOnButton = colorNormal * sf::Color(200, 200, 200);
shape.setFillColor(c);
shape.setPosition(position);
shape.setSize( sf::Vector2f(buttonArea.width, buttonArea.height));
sf::Texture *tex = new sf::Texture();
tex->loadFromFile("button_tex.png");
shape.setTexture(tex);
}
void handleEvent(sf::Event &e)
{
if (isOnButton())
{
if (e.type == sf::Event::MouseButtonReleased && e.mouseButton.button == sf::Mouse::Left)
{
shape.setFillColor(colorOnButton);
if(isOnButton())
pressed = true;
}
}
}
void connect(const std::function<bool()> &f)
{
function = std::move(f);
std::cout << "Function connect\n";
}
void update()
{
sf::Vector2i mousePos = sf::Mouse::getPosition(*win);
drawText.setString(std::to_string(mousePos.x) + ", " + std::to_string(mousePos.y));
if (pressed)
{
//wykona się funkcja
function();
++num;
std::cout << "Pressed " + std::to_string(num) +"\n";
c = colorNormal;
pressed = false;
}
if (isOnButton())
{
c = colorOnButton;
shape.setFillColor(c);
}
else
{
c = colorNormal;
shape.setFillColor(c);
}
}
void setFont(sf::Font &f) {
drawText.setFont(f);
}
void setWindow(sf::RenderWindow *w) {
win = w;
}
void draw(std::unique_ptr<sf::RenderWindow> &w) {
w->draw(shape);
w->draw(drawText);
}
sf::FloatRect getRect() const {
return buttonArea;
}
private:
sf::RenderWindow * win = nullptr;
bool pressed = false;
bool isOnButton()
{
if (win == nullptr)
{
std::cout << "Button window is empty!!!!\n";
return false;
}
sf::Vector2i mousePos = sf::Mouse::getPosition(*win);
if(buttonArea.contains(win->mapPixelToCoords(mousePos)))
{
return true;
}
return false;
}
static int num;
sf::FloatRect buttonArea;
std::function<bool()> function = nullptr;
std::string text;
sf::Text drawText;
sf::RectangleShape shape;
sf::Color colorNormal, colorOnButton;
sf::Color c;
};
int button::num = 0;
namespace def_sett
{
constexpr int w = 1920;
constexpr int h = 1080;
unsigned short port = 48000;
}
std::vector<sf::CircleShape> c;
std::vector<sf::RectangleShape> r;
bool test()
{
bool b = ((rand() % 2) == 1)? true : false;
if (b)
{
sf::CircleShape s;
s.setFillColor(sf::Color(rand() % 255, rand() % 255, rand() % 255));
double r = 10 + rand() % 80;
s.setRadius(r);
s.setPointCount(800);
sf::Vector2f pos = sf::Vector2f(rand() % def_sett::w, rand() % def_sett::h);
if (r + pos.x >= def_sett::w || r + pos.y >= def_sett::h)
pos = sf::Vector2f(pos.x - r, pos.y = r);
s.setPosition(pos);
c.push_back(s);
}
else
{
sf::RectangleShape s;
s.setFillColor(sf::Color(rand() % 255, rand() % 255, rand() % 255));
s.setSize(sf::Vector2f(rand() % 150, rand() % 150));
sf::Vector2f pos = sf::Vector2f(rand() % def_sett::w, rand() % def_sett::h);
s.setPosition(pos);
r.push_back(s);
}
return true;
}
int main()
{
sf::Uint8 myStyle = sf::Style::Fullscreen; //sf::Style::Close | sf::Style::Titlebar | sf::Style::Resize;
sf::ContextSettings settings;
settings.antialiasingLevel = 8;
settings.majorVersion = 3;
settings.minorVersion = 3;
std::string title = "Simple multiplayer game";
std::unique_ptr<sf::RenderWindow> window = std::make_unique<sf::RenderWindow>(sf::VideoMode(def_sett::w, def_sett::h),
title,myStyle,settings);
window->setVerticalSyncEnabled(!true);
sf::Clock clock;
sf::Time time = clock.restart(),last = clock.restart();
sf::Font f;
if (!f.loadFromFile("Ubuntu-R.ttf"))
return 0;
button b,b1;
try
{
b = button("Hello World", sf::Vector2f(100, 100), window.get());
b.setFont(f);
b.connect(std::bind(test));
b1 = button("Hello World2", sf::Vector2f(1000, 800), window.get());
b1.setFont(f);
b1.connect(std::bind(test));
}
catch (std::exception &e)
{
std::cout << e.what() << "\n";
}
sf::Text mousP;
mousP.setFont(f);
mousP.setCharacterSize(24);
mousP.setPosition(sf::Vector2f(10, 10));
while (window->isOpen())
{
time = clock.restart();
sf::Event event;
while (window->pollEvent(event))
{
b.handleEvent(event);
b1.handleEvent(event);
if (event.type == sf::Event::Closed || sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
window->close();
if (event.type == sf::Event::Resized)
{
window->setView(sf::View(sf::FloatRect(0, 0, event.size.width, event.size.height)));
b1.setWindow(window.get());
}
}
mousP.setString(std::string("button 1 pos: " + std::to_string(b.getRect().top) + ", " + std::to_string(b.getRect().left) +
"\nbutton 2 pos" + std::to_string(b1.getRect().top) + ", " + std::to_string(b1.getRect().left) ));
b.update();
b1.update();
for (auto & i : c)
window->draw(i);
for (auto &i : r)
window->draw(i);
b.draw(window);
b1.draw(window);
window->draw(mousP);
window->display();
last = time;
}
return 0;
}