SFML community forums

Help => Graphics => Topic started by: iride on May 06, 2015, 05:13:59 am

Title: What is wrong with my code?
Post by: iride on May 06, 2015, 05:13:59 am
Hello, i'm building my own gui system.

i have a Container class that derives from sf::Transformable and stores children widgets. I also have a Panel class that derives from Container.
When I set a child widget's position, I want it to be relative to the parent's position.

auto panel = ui::Panel::create();
panel->setSize({ 100.f, 100.f });
panel->setPosition({ 50.f, 50.f });
panel->color = sf::Color::Blue;

auto panel2 = ui::Panel::create();
panel2->setSize({ 50.f, 50.f });
panel2->color = sf::Color::Green;

panel->add(panel2);

...
ui.add(panel);
window.draw(ui);
 

Since I never moved Green panel's position, I expect it to be at the same position as the Blue panel. However in my program it appears at 50, 50 relative to the blue panel.

What I get
(http://i.imgur.com/WoPz3Nu.png)

What I expect
(http://i.imgur.com/EoEUUwj.png)

void Panel::draw(sf::RenderTarget & target, sf::RenderStates states) const
{
        states.transform *= getTransform();
        sf::RectangleShape r;
        r.setFillColor(color);
        r.setSize(getSize());
        target.draw(r, states);
        Container::draw(target, states);
}

void Container::draw(sf::RenderTarget & target, sf::RenderStates states) const
{
        states.transform *= getTransform();
        for (auto w : m_widgets)
                target.draw(*w, states);
}

What's wrong?
Title: Re: What is wrong with my code?
Post by: Laurent on May 06, 2015, 08:00:40 am
You apply the object's transform twice, once in Panel::draw and once in Container::draw. But the second one will be applied only to children, that's why only your green square is wrong.

Your design is not optimal, you should rather do this:

void Panel::drawSelf(sf::RenderTarget & target, sf::RenderStates states) const
{
    sf::RectangleShape r;
    r.setFillColor(color);
    r.setSize(getSize());
    target.draw(r, states);
}

void Container::draw(sf::RenderTarget & target, sf::RenderStates states) const
{
    states.transform *= getTransform();
    drawSelf(target, states);
    for (auto w : m_widgets)
        target.draw(*w, states);
}
Title: Re: What is wrong with my code?
Post by: iride on May 06, 2015, 08:46:35 pm
Thanks!