I notice that the SFGUI website is still down, and since some developers read this thread, I take the liberty of asking my question here too.
The problem is as follows.
I have two spinbuttons, A and B.
Both can be changed individually by user interaction.
If I change the value of A by user interaction, the bound processing function also changes the value of B programmatically, through the SetValue function.
If I do this, button B gets two signals instead of the expected one.
Here is the code:
#include "stdafx.h"
#include <iostream>
#include "SFGUI/SFGUI.hpp"
#include "SFGUI/Widgets.hpp"
#include "SFML/Graphics.hpp"
using namespace std;
constexpr int SCREEN_WIDTH = 800;
constexpr int SCREEN_HEIGHT = 600;
class HelloWorld
{
public:
HelloWorld () {}
void value_changed (sfg::SpinButton::Ptr button);
void Run ();
private:
sfg::SFGUI sfgui;
sfg::SpinButton::Ptr _button_a;
sfg::SpinButton::Ptr _button_b;
};
void HelloWorld::value_changed (sfg::SpinButton::Ptr button)
{
auto value = button->GetValue ();
if (button == _button_a)
{
cout << "button A" << endl;
_button_b->SetValue (value);
}
if (button == _button_b)
{
cout << "button B" << endl;
}
}
void HelloWorld::Run ()
{
sf::RenderWindow render_window (sf::VideoMode (SCREEN_WIDTH, SCREEN_HEIGHT), "Hello world");
auto window = sfg::Window::Create ();
window->SetTitle ("Test spinbuttons");
auto table = sfg::Table::Create ();
auto fill = sfg::Table::AttachOption::FILL;
auto padding = sf::Vector2f (10.0f, 2.0f);
auto label_a = sfg::Label::Create();
label_a->SetText ("A");
table->Attach (label_a, sf::Rect<sf::Uint32> (0, 0, 1, 1), fill, fill, padding);
auto button_a = sfg::SpinButton::Create (1.0f, 10.0f, 1.0f);
_button_a = button_a;
button_a->SetValue (5.0f);
button_a->GetSignal (sfg::SpinButton::OnValueChanged).Connect ([=](){value_changed (button_a); });
button_a->SetRequisition (sf::Vector2f (60.0f, 0.0f));
table->Attach (button_a, sf::Rect<sf::Uint32> (1, 0, 1, 1), fill, fill, padding);
auto label_b = sfg::Label::Create ();
label_b->SetText ("B");
table->Attach (label_b, sf::Rect<sf::Uint32> (0, 1, 1, 1), fill, fill, padding);
auto button_b = sfg::SpinButton::Create (1.0f, 10.0f, 1.0f);
button_b->SetValue (5.0f);
_button_b = button_b;
button_b->SetRequisition (sf::Vector2f (60.0f, 0.0f));
button_b->GetSignal (sfg::SpinButton::OnValueChanged).Connect ([=](){value_changed (button_b); });
table->Attach (button_b, sf::Rect<sf::Uint32> (1, 1, 1, 1), fill, fill, padding);
window->Add (table);
sfg::Desktop desktop;
desktop.Add (window);
render_window.resetGLStates ();
sf::Event event;
sf::Clock clock;
while (render_window.isOpen ())
{
while (render_window.pollEvent (event))
{
desktop.HandleEvent (event);
if (event.type == sf::Event::Closed)
{
render_window.close ();
}
}
desktop.Update (clock.restart ().asSeconds ());
render_window.clear ();
sfgui.Display (render_window);
render_window.display ();
}
}
int main ()
{
HelloWorld hello_world;
hello_world.Run ();
return 0;
}
Now, if I click the up-button of spinbutton B, I get the expected output:
button B
But, if I click the up-button of spinbutton A, I get two signals on b:
button A
button B
button B
This is a problem, because I want to ignore signals originating from programmatical change of the value of B, while still handling the signals originating from user interaction with B.
It gets even stranger if I first click A, then B, en then A again. In this case the output is:
button A // click button A
button B // SetValue on B
button B // mysterious second signal on B
button B // click button B
button A // click button A
button B // SetValue on B, no second signal!
So, the number of signals received on B seems to depend on the exact sequence of clicks: if I click A after having clicked B, I get one signal on B. If I click A while the previous click was not on B, I get two signals on B.
Probably I am making some silly mistake, and probably I am making a fool of myself by asking, but I genuinely don't see it.