Updating Real Time

  • 2 Replies
  • 91 Views
Updating Real Time
« on: 01 May 2020, 03:30:21 »
Hello, I'm having trouble figuring out how to update the text live. I have 3 sliders, 3 labels sayings "Red, Green, Blue", and 3 labels that are supposed to show the value of each individual slider. The sliders change the color of the background of a child window. I've basically stripped out the "All Widgets Example" provided.

1st Question: How can I change the position of the slider at startup? It always starts at 0 (it's at zero now as I tried to fix), yet I assumed setValue would position it to the value correctly.
(UPDATE: I saw this on a thread " I've added a ThumbWithinTrack option to the renderer in TGUI 0.9-dev. Setting it to true will make the side of the thumb align with the side of the track when the thumb has minimum or maximum value."

2nd Question:   (SOLVED, I FIGURED IT OUT, HAD TO GET FROM GUI. I STILL HAVE TO CLICK EACH SLIDER FOR IT TO UPDATE THE VALUES FOR THE CHILD BACKGROUND)
   
int r = 0, g = 0, b = 0;
...
        // Red
        auto slider = tgui::Slider::create();
        slider->setRenderer(theme.getRenderer("Slider"));
        slider->setPosition(55, 360);
        slider->setSize(200, 18);
        slider->setValue(0);
        slider->setMaximum(255);
        slider->setMinimum(0);
        slider->connect("ValueChanged", [&]() {
            r = slider->getValue();

            child->getRenderer()->setBackgroundColor({ (sf::Uint8)r, (sf::Uint8)g, (sf::Uint8)b });
            gui.get<tgui::Label>("red_value")->setText(std::to_string((int)gui.get<tgui::Slider>("red").get()->getValue()));
        });
        gui.add(slider, "red");

        label = tgui::Label::create();
        label->setRenderer(theme.getRenderer("Label"));
        label->setText("Red");
        label->setPosition("red.left - width - 10","red.top");
        label->setTextSize(14);
        gui.add(label, "red_label");

        label = tgui::Label::create();
        label->setRenderer(theme.getRenderer("Label"));
        label->setText(std::to_string(r));
        label->setPosition("red.left + red.width + 10", "red.top");
        label->setTextSize(14);
        gui.add(label, "red_value");

        // Green
        slider = tgui::Slider::copy(slider);
        slider->setPosition("red.left", "red.top + 35");
        slider->connect("ValueChanged", [&]() {
            g = slider->getValue();

            child->getRenderer()->setBackgroundColor({ (sf::Uint8)r, (sf::Uint8)g, (sf::Uint8)b });
            gui.get<tgui::Label>("green_value")->setText(std::to_string((int)gui.get<tgui::Slider>("green").get()->getValue()));

            });
        gui.add(slider, "green");

        label = tgui::Label::create();
        label->setRenderer(theme.getRenderer("Label"));
        label->setText(std::to_string(g));

        label->setPosition("green.left + green.width + 10", "green.top");
        label->setTextSize(14);
        gui.add(label, "green_value");

        label = tgui::Label::create();
        label->setRenderer(theme.getRenderer("Label"));
        label->setText("Green");
        label->setPosition("green.left - width - 10", "green.top");
        label->setTextSize(14);
        gui.add(label, "green_label");

        // Blue
        slider = tgui::Slider::copy(slider);
        slider->setPosition("green.left", "green.top + 35");
        slider->connect("ValueChanged", [&]() {
            b = slider->getValue();
            child->getRenderer()->setBackgroundColor({ (sf::Uint8)r, (sf::Uint8)g, (sf::Uint8)b });
            gui.get<tgui::Label>("blue_value")->setText(std::to_string((int)gui.get<tgui::Slider>("blue").get()->getValue()));

            });
        gui.add(slider, "blue");

        label = tgui::Label::create();
        label->setRenderer(theme.getRenderer("Label"));
        label->setText("Blue");
        label->setPosition("blue.left - width - 10", "blue.top");
        label->setTextSize(14);
        gui.add(label, "blue_label");

        label = tgui::Label::create();
        label->setRenderer(theme.getRenderer("Label"));
        label->setText(std::to_string(b));
        label->setPosition("blue.left + blue.width + 10", "blue.top");
        label->setTextSize(14);
        gui.add(label, "blue_value");
 

Here is the code for what I'm doing with the sliders and labels. How can I get these label values to change as I scroll? EDIT: I got it to scroll and display the value correctly, but I realized the color of the background is definitely not accurate.

3rd: What does the method update actually do? (Besides the obvious) What is being updated and when would I want to manually call update? Also, what is updateTime() method in the Gui suppose to do?

4th: How do I manually call a Widgets connect callback?

Any help would greatly be appreciated, thanks!
« Last Edit: 01 May 2020, 06:28:12 by RamblingBaba »

*

texus

  • *****
  • 1544
    • View Profile
    • Texus's Blog
Re: Updating Real Time
« Reply #1 on: 01 May 2020, 09:39:10 »
Quote
1st Question: How can I change the position of the slider at startup? It always starts at 0 (it's at zero now as I tried to fix), yet I assumed setValue would position it to the value correctly.
Calling setSlider->setValue(x) after creating the slider does change the value and will set the thumb on a different position. If not then you are probably calling setValue(0) somewhere afterwards.

Quote
2nd Question:   (SOLVED, I FIGURED IT OUT, HAD TO GET FROM GUI. I STILL HAVE TO CLICK EACH SLIDER FOR IT TO UPDATE THE VALUES FOR THE CHILD BACKGROUND)
The "ValueChanged" callback is only going to be called when you actually change the value, either by clicking on it or by calling setValue(). So if you don't give your window the right background color initially then it of course won't be set until the first time you change the slider.

Quote
3rd: What does the method update actually do? (Besides the obvious) What is being updated and when would I want to manually call update? Also, what is updateTime() method in the Gui suppose to do?
The update function is an internal function which should never be called manually. It is used to inform widgets that time has passed. Only a few widgets do something with this information, e.g. edit box will blink its caret. The updateTime function in Gui (also meant for internal use and called from inside Gui::draw()), is the function that will call the update() function on all widgets in the gui.
I guess I should rename update() to updateTime() as well to make it more clear what is being updated.

Quote
4th: How do I manually call a Widgets connect callback?
You aren't meant to do this. If you really must, you could use slider->onValueChange.emit(slider.get(), slider->getValue());

Edit:
Quote
but I realized the color of the background is definitely not accurate.
You are using "[&]" as lambda capture. Is the "slider" object still alive when the lambda is executed (when the value is changed)? It not then you are causing undefined behavior. Widgets in TGUI are stored as pointers, so you can copy them inside the lambda by value:
slider->connect("ValueChanged", [&,slider]() { ... });
« Last Edit: 01 May 2020, 09:43:47 by texus »

Re: Updating Real Time
« Reply #2 on: 01 May 2020, 21:18:25 »
[SOLVED] I just retrieved from the gui and it worked correctly.  Thank you.




Here is the code, I posted it all for clarity. So the "red" slider starts off just a tad past zero. But the others start at zero. I checked for calls of setValue and it's only called on the sliders. I have 3 comments // Red, // Green, // Blue for where I initialize the Sliders. Thanks

tgui::Theme theme{ "themes/Black.txt" };

                gui.add(tgui::Picture::create("RedBackground.jpg"));

                auto r = 0.f, g = 0.f, b = 0.f;
                auto r2 = 0.f, g2 = 0.f, b2 = 0.f;


                auto menu = tgui::MenuBar::create();
                menu->setRenderer(theme.getRenderer("MenuBar"));
                menu->setSize(static_cast<float>(window.getSize().x), 22.f);
                menu->addMenu("File");
                menu->addMenuItem("Load");
                menu->addMenuItem("Save");
                menu->addMenuItem("Exit");
                menu->addMenu("Edit");
                menu->addMenuItem("Copy");
                menu->addMenuItem("Paste");
                menu->addMenu("Help");
                menu->addMenuItem("About");
                menu->connectMenuItem("File", "Exit", [&]() {window.close(); });
                gui.add(menu, "menu");

                auto child = tgui::ChildWindow::create();
                child->setRenderer(theme.getRenderer("ChildWindow"));
                child->setSize(250, 120);
                child->setPosition(420, 80);
                child->setTitle("Child window");
                gui.add(child, "child");

                auto label = tgui::Label::create();
                label->setRenderer(theme.getRenderer("Label"));
                label->setText("Hi! I'm a child window.");
                label->setPosition(30, 30);
                label->setTextSize(15);
                child->add(label, "child_label");

                auto editBox = tgui::EditBox::create();
                editBox->setRenderer(theme.getRenderer("EditBox"));
                editBox->setSize(200, 25);
                editBox->setTextSize(18);
                editBox->setPosition(10, 270);
                editBox->setDefaultText("Click to edit text...");
       
                editBox->onReturnKeyPress( [&]() {
                        gui.get("child")->setVisible(true);
                        auto lbl = gui.get<tgui::ChildWindow>("child")->get<tgui::Label>("child_label");
                        lbl->setText(gui.get<tgui::EditBox>("editbox")->getText());
                        });
                gui.add(editBox, "editbox");

                auto button = tgui::Button::create();
                button->setRenderer(theme.getRenderer("Button"));
                button->setPosition("editbox.left + editbox.width + 5", "editbox.top");
                button->setText("Show Popup");
                button->setSize(100, 30);
                button->onPress( [&]() {
                        gui.get<tgui::ChildWindow>("child")->setVisible(
                                !gui.get<tgui::ChildWindow>("child")->isVisible());
                        if (gui.get<tgui::ChildWindow>("child")->isVisible())
                                gui.get<tgui::Button>("toggleChildButton")->setText("Hide Child");
                        else
                                gui.get<tgui::Button>("toggleChildButton")->setText("Show Child");

                        });
                gui.add(button, "toggleChildButton");


                [b]// Red
                auto slider = tgui::Slider::create();
                slider->setRenderer(theme.getRenderer("Slider"));
                slider->setPosition(55, 360);
                slider->setSize(200, 18);
                slider->setValue(150);
                slider->setMaximum(255);
                slider->setMinimum(0);
                slider->setStep(1);
                slider->getRenderer()->setThumbWithinTrack(true);
                slider->onValueChange( [&]() {[/b]
                        const auto checkBG = gui.get<tgui::RadioButton>("rBGColor");
                        const auto checkTC = gui.get<tgui::RadioButton>("rTextColor");
                        if (checkBG->isChecked())
                        {
                                r = gui.get<tgui::Slider>("red")->getValue();
                                child->getRenderer()->setBackgroundColor({ static_cast<sf::Uint8>(r), static_cast<sf::Uint8>(g), static_cast<sf::Uint8>(b) });
                                gui.get<tgui::Label>("red_value")->setText(std::to_string(static_cast<int>(gui.get<tgui::Slider>("red").get()->getValue())));
                        }
                        else if (checkTC->isChecked()) {
                                r2 = gui.get<tgui::Slider>("red")->getValue();
                                auto lb = gui.get<tgui::ChildWindow>("child")->get<tgui::Label>("child_label");
                                lb->getRenderer()->setTextColor({ static_cast<sf::Uint8>(r2), static_cast<sf::Uint8>(g2), static_cast<sf::Uint8>(b2) });
                                gui.get<tgui::Label>("red_value")->setText(std::to_string(static_cast<int>(gui.get<tgui::Slider>("red").get()->getValue())));
                        }
                        });
                gui.add(slider, "red");

                label = tgui::Label::create();
                label->setRenderer(theme.getRenderer("Label"));
                label->setText("Red");
                label->setPosition("red.left - width - 10", "red.top");
                label->setTextSize(14);
                gui.add(label, "red_label");

                label = tgui::Label::create();
                label->setRenderer(theme.getRenderer("Label"));
                label->setText(std::to_string(r));
                label->setPosition("red.left + red.width + 10", "red.top");
                label->setTextSize(14);
                gui.add(label, "red_value");

                [b]// Green
                slider = tgui::Slider::create();
                slider->setRenderer(theme.getRenderer("Slider"));
                slider->setPosition("red.left", "red.top + 35");
                slider->setSize(200, 18);
                slider->setValue(150);
                slider->setMaximum(255);
                slider->setMinimum(0);
                slider->setStep(1);
                slider->onValueChange([&]() {[/b]
                        auto checkBG = gui.get<tgui::RadioButton>("rBGColor");
                        auto checkTC = gui.get<tgui::RadioButton>("rTextColor");
                        if (checkBG->isChecked())
                        {
                                g = gui.get<tgui::Slider>("green")->getValue();
                                child->getRenderer()->setBackgroundColor({ static_cast<sf::Uint8>(r), static_cast<sf::Uint8>(g), static_cast<sf::Uint8>(b) });
                                gui.get<tgui::Label>("green_value")->setText(std::to_string(static_cast<int>(gui.get<tgui::Slider>("green").get()->getValue())));
                        }
                        else if (checkTC->isChecked()) {
                                g2 = gui.get<tgui::Slider>("green")->getValue();
                                auto lb = gui.get<tgui::ChildWindow>("child")->get<tgui::Label>("child_label");
                                lb->getRenderer()->setTextColor({ static_cast<sf::Uint8>(r2), static_cast<sf::Uint8>(g2), static_cast<sf::Uint8>(b2) });
                                gui.get<tgui::Label>("green_value")->setText(std::to_string(static_cast<int>(gui.get<tgui::Slider>("green").get()->getValue())));
                        }
                        });
                gui.add(slider, "green");

                label = tgui::Label::create();
                label->setRenderer(theme.getRenderer("Label"));
                label->setText(std::to_string(g));
                label->setPosition("green.left + green.width + 10", "green.top");
                label->setTextSize(14);
                gui.add(label, "green_value");

                label = tgui::Label::create();
                label->setRenderer(theme.getRenderer("Label"));
                label->setText("Green");
                label->setPosition("green.left - width - 10", "green.top");
                label->setTextSize(14);
                gui.add(label, "green_label");

                [b]// Blue
                slider = tgui::Slider::create();
                slider->setRenderer(theme.getRenderer("Slider"));
                slider->setPosition("green.left", "green.top + 35");
                slider->setSize(200, 18);
                slider->setValue(150);
                slider->setMaximum(255);
                slider->setMinimum(0);
                slider->setStep(1);
       
                slider->onValueChange([&]() {[/b]
                        auto checkBG = gui.get<tgui::RadioButton>("rBGColor");
                        auto checkTC = gui.get<tgui::RadioButton>("rTextColor");
                        if (checkBG->isChecked())
                        {
                                b = gui.get<tgui::Slider>("blue")->getValue();
                                child->getRenderer()->setBackgroundColor({ static_cast<sf::Uint8>(r), static_cast<sf::Uint8>(g), static_cast<sf::Uint8>(b) });
                                gui.get<tgui::Label>("blue_value")->setText(std::to_string(static_cast<int>(gui.get<tgui::Slider>("blue").get()->getValue())));
                        }
                        else if (checkTC->isChecked()) {
                                b2 = gui.get<tgui::Slider>("blue")->getValue();
                                auto lb = gui.get<tgui::ChildWindow>("child")->get<tgui::Label>("child_label");
                                lb->getRenderer()->setTextColor({ static_cast<sf::Uint8>(r2), static_cast<sf::Uint8>(g2), static_cast<sf::Uint8>(b2) });
                                gui.get<tgui::Label>("blue_value")->setText(std::to_string(static_cast<int>(gui.get<tgui::Slider>("blue").get()->getValue())));
                        }
                        });

                gui.add(slider, "blue");

                label = tgui::Label::create();
                label->setRenderer(theme.getRenderer("Label"));
                label->setText("Blue");
                label->setPosition("blue.left - width - 10", "blue.top");
                label->setTextSize(14);
                gui.add(label, "blue_label");

                label = tgui::Label::create();
                label->setRenderer(theme.getRenderer("Label"));
                label->setText(std::to_string(b));
                label->setPosition("blue.left + blue.width + 10", "blue.top");
                label->setTextSize(14);
                gui.add(label, "blue_value");

                auto radioButton = tgui::RadioButton::create();
                radioButton->setRenderer(theme.getRenderer("RadioButton"));
                radioButton->setPosition(20, 140);
                radioButton->setText("Background Color");
                radioButton->setSize(25, 25);
               
                gui.add(radioButton, "rBGColor");

                radioButton = tgui::RadioButton::create();
                radioButton->setRenderer(theme.getRenderer("RadioButton"));
                radioButton->setPosition(20, "rBGColor.top - 27");
                radioButton->setText("Text Color");
                radioButton->setSize(25, 25);
                gui.add(radioButton, "rTextColor");

The reason I wanted to call a function manually is that when I change the radio button to "background" or "text color" the color doesn't update unless I click each individual slider again. Which was why I was curious of what update does. I guess I was just being lazy and didn't want to call the same color change inside the radio.onCheck() again. But it works when I do that, I was just hoping I could call the functions of the sliders to accomplish for me. Thanks
« Last Edit: 01 May 2020, 22:00:02 by RamblingBaba »