Hi there!
I'm a C++ newbie, and I'm new to the forum as well. Recently I've been trying to write my own GUI classes, so I can use them in my later projects. While writing a combo box, I stumbled something strange. When I constructed a button I'd written, it was drawn 'perfectly fine' to the window. But when I pushed my button object to std::vector and called it to draw to the screen. This happened: https://drive.google.com/file/d/1QclBCkOzErf6zx9jbKtUh1X36Ox3PzFb/view?usp=sharing
Thanks.
It would've been also useful to provide some code. Try these:
- use a debugger and break before drawing
- make sure u use the "=" operator right
- prepare for us a minimal code which reproduces the problem
Here's the "simplified" version:
//////////BEGIN//////////
#include <iostream>
#include <string>
#include <functional>
#include "SFML/Graphics.hpp"
#define Log(x) std::cout << x << std::endl;
class Button
{
private:
float x, y, w, h;
std::string string;
std::function<void(void)> function;
sf::Font font;
sf::RenderWindow* window;
sf::Event* event;
sf::Text text;
sf::RectangleShape rectangle;
bool is_clicked()
{
if (this->event->type == sf::Event::MouseButtonPressed && this->rectangle.getGlobalBounds().contains(sf::Vector2<float>(sf::Mouse::getPosition(*window))))
{
return true;
}
else
{
return false;
}
}
public:
Button(const char* const string, float x, float y, sf::RenderWindow& window, sf::Event& event)
: x(x), y(y), w(100.f), h(25.f), string(string), window(&window), event(&event)
{
this->font.loadFromMemory(SOME_FONT, SOME_FONT_LENGTH);
this->text.setFont(this->font);
this->text.setString(this->string);
this->text.setFillColor(sf::Color::Black);
this->text.setOrigin(this->text.getGlobalBounds().width / 2.f, this->text.getGlobalBounds().height / 2.f);
this->text.setPosition(sf::Vector2<float>(this->x + this->w / 2.f, this->y - this->h / 10.f));
this->rectangle.setPosition(sf::Vector2<float>(this->x, this->y));
this->rectangle.setSize(sf::Vector2<float>(this->w, this->h));
this->rectangle.setFillColor(sf::Color::Blue);
}
~Button()
{
}
void draw()
{
this->window->draw(this->rectangle);
this->window->draw(this->text);
}
void update()
{
if (this->is_clicked())
{
this->function();
}
}
void set_function(const std::function<void(void)>& function)
{
this->function = function;
}
};
int main(int argc, char* argv[])
{
sf::Clock clock;
sf::Time delta_time = sf::Time::Zero;
sf::Time fps = sf::seconds(1.f / 60.f);
sf::RenderWindow window(sf::VideoMode(500, 500), "Sandbox");
sf::Event event;
std::vector<Button> list_of_buttons;
list_of_buttons.push_back(Button("Close 1", 25.f, 25.f + list_of_buttons.size() * 25.f, window, event));
list_of_buttons.push_back(Button("Close 2", 25.f, 25.f + list_of_buttons.size() * 25.f, window, event));
list_of_buttons.push_back(Button("Close 3", 25.f, 25.f + list_of_buttons.size() * 25.f, window, event));
for (int i = 0; i < list_of_buttons.size(); i++)
{
list_of_buttons
.set_function(std::function<void(void)>([&window]() {window.close(); }));
}
while (window.isOpen())
{
while (window.pollEvent(event))
{
switch (event.type)
{
case sf::Event::Closed:
window.close();
break;
default:
break;
}
//Update
{
for (int i = 0; i < list_of_buttons.size(); i++)
{
list_of_buttons.update();
}
}
if (delta_time > fps)
{
delta_time -= fps;
//Render
{
window.clear(sf::Color::White);
for (int i = 0; i < list_of_buttons.size(); i++)
{
list_of_buttons.draw();
}
window.display();
}
}
delta_time += clock.restart();
}
}
return 0;
}
///////////END///////////
https://drive.google.com/open?id=1Bu4cYQusKCf8MdwbWJ2_eypGI6SXqZgP
Although I rewrote the code, the problem is the same. (What I want to achieve is creating a list of buttons.)