Main Menu
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - texus

#76
QuoteTherefor what are the benefits to inherit from SubwidgetContainer instead of Group ?
The only benefit would be to not expose the container interface.
For example someone wrote a SpinControl widget which consists of an EditBox and a SpinButton. If SpinControl would inherit from Group, it would have functions such as "add" and "remove" (which you would never use). By inheriting from SubwidgetContainer, it doesn't have these functions.
#77
QuoteDo you plan to correct this behavior ? Or maybe forbid user to use the function with this class
I'm not sure how I can. The getAbsolutePosition call never actually reaches the SubwidgetContainer class (it ends in the m_container member which has no idea it is part of SubwidgetContainer), so I can't add code there to make an exception.

Widgets that are placed into the SubwidgetContainer aren't actually part of the gui, they are just part of your custom widget. While my first reaction was that the getAbsolutePosition might be buggy, the behavior is actually by design: the SubwidgetContainer really is the root of everything inside it. You should think of a SubwidgetContainer as a canvas on which you render: the widgets added to m_container are drawn to the canvas (without knowledge of the gui), and the canvas image is later drawn to the gui (without knowledge of how the image was created).

The only thing that I know I can do is better document this. While the current class description of "consist of subwidgets that act together as if they are a single widget" is accurate, it doesn't really mention any details about the consequences and side-effects of this design. The tutorial about custom widgets might also be improved to explain in which case you should or shouldn't use SubwidgetContainer.
#78
Does VehicleManager inherit from SubwidgetContainer?
If so then this is a bug and I will need to patch SubwidgetContainer.

Edit: this seems harder to fix than expected, I don't immediately see what I could change in SubwidgetContainer to make getAbsolutePosition work. What is the reason you need this function?

Edit 2: I think VehicleManager should inherit from Group instead of SubwidgetContainer (assuming this is what is happening). The SubwidgetContainer class exists so that you can create a widget that internally works like a container, but otherwise pretends to be a normal non-container widget to the rest of the gui. If VehicleManager should work like a container (which you seem to want with your getAbsolutePosition call), then you should probably inherit from a Container-based widget like Group.
#79
Ah ok, you aren't building TGUI yourself but you are using a library that was build with all backends included. In that case it won't be possible, as the TGUIConfig.cmake file will simply load all backends that existed when it was generated. The TGUI_BACKEND variable has no effect in your cmake script because it is only used while building TGUI.

The ubuntu package was build with SFML, SDL and GLFW and it indeed requires that libsfml-dev, libsdl2-dev, libsdl2-ttf-dev, libglfw3-dev and libfreetype-dev are installed on the system. It seems like my package is only listing the dependencies without the "-dev" postfix, which is why those weren't installed automatically. This is something that I will need to look into.

I don't really know what I can do to improve the situation. The ubuntu package was mostly provided for convenience, but I guess it might be even less useful than I though.

The only way right now to have a TGUI library that only contains the components that you need is to build it yourself with CMake.
#80
That should not be happening, it should only search for the selected backend.

If you don't specify TGUI_BACKEND, it will show an error on the first cmake run that no backend was selected, but will set to TGUI_BACKEND to SFML_GRAPHICS for the future. If you run the configure step again, it will thus search for SFML. The cmake script should never be searching for all backends unless you manually ask it to.

Can you clean your build directory, run cmake again and show its output?
#81
Help requests / Re: behavior on phone
25 March 2023, 18:58:46
Two finger scrolling should now work out of the box in the latest TGUI version!
#82
You currently will have to detect this yourself in your mouseMoved function (by checking if the mouse position lies outside the widget).

Draggable widgets (i.e. those that have "m_draggableWidget = true;" in their constructor, e.g. Slider or Scrollbar) will not receive mouseNoLongerOnWidget or mouseLeftWidget events when the mouse leaves with the button pressed. Instead they will continue to receive mouseMoved events until the mouse is released, even when the mouse is no longer on top of the widget.

Currently, containers (like SubwidgetContainer or Panel) are treated as if they are draggable widgets. This is why you don't receive mouseNoLongerOnWidget when you expect it.

Maybe this is something that should be changed. If I remember correctly then the reason for this is that a container could have a draggable widget inside it, so the mouse event is passed to the container just in case. If this really is the only reason, then a better design inside TGUI could be to check whether the leaf widget is draggable or not, and only pass mouse events to the container when that is the case.
#83
QuoteI thought that's sort of clipping to preserve draw computation when a widget is off screen, is that actually true ?
TGUI does indeed clip widgets that are outside the screen.

The clipping code was broken when rotation was applied. I've pushed a fixed version to github, so if you download the latest version again then the brace should stay visible.
#84
You should never inherit from 2 classes which both inherit from the Widget class.

ClickableWidget isn't that complex, you could in theory just copy its code in your custom widget if you really need it. Note that the main purpose of ClickableWidget is to provide a widget with the onClick signal, you don't actually need to inherit from it to support mouse events in your widget.

So you probably don't want to inherit from ClickableWidget and only inherit from SubwidgetContainer. Since SubwidgetContainer already forwards mouse events to the child widgets, the ClickableWidget implementation that consumes all mouse events itself wouldn't even be compatible anyway.

onPress will also be triggered when the button has focus and the user presses the space or return key on the keyboard, onClick will only be triggered as a result of a mouse click.
#85
Help requests / Re: Custom animation
16 March 2023, 19:43:46
Custom animations can't be provided, you will have to just implement the behavior in your own code (by keeping track of the elapsed time yourself and changing the widget properties at each timestep).

Combining existing animations might actually work: if you call showWithEffect (or hideWithEffect) twice (preferably with the same duration) but with a different type then both effects should take place simultaneously.

TGUI doesn't really have proper animation support, the showWithEffect and hideWithEffect functions only intended to provide bare minimum animation functionality.
#86
Help requests / Re: Picture with SVG
13 March 2023, 19:33:44
The nanosvg version has been updated.
#87
Help requests / Re: Picture with SVG
10 March 2023, 19:38:38
Are you calling setSize on the Picture?
Can you attach the svg file that you are trying to use?

Maybe it uses something that isn't supported (TGUI uses nanosvg which only supports simple SVGs and doesn't implement the entire SVG standard).
Can you try with loading the sample drawing.svg in the Picture (which is known to render correctly)?
#88
Help requests / Re: Sprite from SVG
07 March 2023, 22:11:54
The SvgImage class is used internally by the Texture class. You can simply pass a filename ending with ".svg" to the Texture class just like you would load e.g. a png file.
#89
Help requests / Re: behavior on phone
06 March 2023, 18:59:36
Doing it like that is indeed better. If you replace the leftMousePressed function in my previous post with the following then draggable widgets would be supported.
Code (cpp) Select
void leftMousePressed(tgui::Vector2f pos) override
{
    m_mouseDown = true;

    if (m_verticalScrollbar->isMouseOnWidget(pos - getPosition()))
        m_verticalScrollbar->leftMousePressed(pos - getPosition());
    else if (m_horizontalScrollbar->isMouseOnWidget(pos - getPosition()))
        m_horizontalScrollbar->leftMousePressed(pos - getPosition());
    else if (tgui::FloatRect{getPosition().x + getChildWidgetsOffset().x, getPosition().y + getChildWidgetsOffset().y, getInnerSize().x, getInnerSize().y}.contains(pos))
    {
        auto widgetBelowMouse = getWidgetBelowMouse(pos - getPosition() - getChildWidgetsOffset());
        if (widgetBelowMouse && widgetBelowMouse->isDraggableWidget())
            ScrollablePanel::leftMousePressed(pos);
        else
        {
            m_dragging = true;
            m_originalDragPos = pos;
            m_dragPos = pos;
        }
    }
}

When I find some time in the next few weeks I will investigate how much work it would be to get two-finger scrolling working. It would be a much better option if I can get it to work.
#90
Help requests / Re: behavior on phone
05 March 2023, 21:43:19
It can definitely be done.
I quickly implemented it myself to demonstrate it, but you will need to get the latest TGUI version as I had to make the scrollbars in ScrollablePanel protected instead of private in order to compile this code.
Code (cpp) Select
class CustomScrollablePanel : public tgui::ScrollablePanel
{
public:
    typedef std::shared_ptr<CustomScrollablePanel> Ptr;
    typedef std::shared_ptr<const CustomScrollablePanel> ConstPtr;

    CustomScrollablePanel(const char* typeName = "CustomScrollablePanel", bool initRenderer = true) :
        tgui::ScrollablePanel(typeName, initRenderer)
    {
    }

    void leftMousePressed(tgui::Vector2f pos) override
    {
        m_mouseDown = true;

        if (m_verticalScrollbar->isMouseOnWidget(pos - getPosition()))
            m_verticalScrollbar->leftMousePressed(pos - getPosition());
        else if (m_horizontalScrollbar->isMouseOnWidget(pos - getPosition()))
            m_horizontalScrollbar->leftMousePressed(pos - getPosition());
        else if (tgui::FloatRect{getPosition().x + getChildWidgetsOffset().x, getPosition().y + getChildWidgetsOffset().y, getInnerSize().x, getInnerSize().y}.contains(pos))
        {
            m_dragging = true;
            m_originalDragPos = pos;
            m_dragPos = pos;
        }
    }

    void leftMouseReleased(tgui::Vector2f pos) override
    {
        if (m_dragging)
        {
            m_dragging = false;

            if (std::abs(m_originalDragPos.x - pos.x) <= 2 && std::abs(m_originalDragPos.y - pos.y) <= 2)
            {
                if ((!m_verticalScrollbar->isMouseOnWidget(pos - getPosition()) && !m_horizontalScrollbar->isMouseOnWidget(pos - getPosition()))
                 && tgui::FloatRect{getPosition().x + getChildWidgetsOffset().x, getPosition().y + getChildWidgetsOffset().y, getInnerSize().x, getInnerSize().y}.contains(pos))
                {
                    ScrollablePanel::leftMousePressed({pos.x + static_cast<float>(m_horizontalScrollbar->getValue()),
                                                       pos.y + static_cast<float>(m_verticalScrollbar->getValue())});
                    ScrollablePanel::leftMouseReleased({pos.x + static_cast<float>(m_horizontalScrollbar->getValue()),
                                                        pos.y + static_cast<float>(m_verticalScrollbar->getValue())});
                }
            }

            return;
        }

        ScrollablePanel::leftMouseReleased(pos);
    }

    void mouseMoved(tgui::Vector2f pos) override
    {
        if (m_dragging)
        {
            const float delta = (pos.y - m_dragPos.y) / static_cast<float>(m_verticalScrollbar->getScrollAmount());
            m_verticalScrollbar->mouseWheelScrolled(delta, pos);
            m_dragPos = pos;
            return;
        }

        ScrollablePanel::mouseMoved(pos);
    }

    void leftMouseButtonNoLongerDown() override
    {
        m_dragging = false;
        ScrollablePanel::leftMouseButtonNoLongerDown();
    }

    static CustomScrollablePanel::Ptr create()
    {
        return std::make_shared<CustomScrollablePanel>();
    }

    static CustomScrollablePanel::Ptr copy(CustomScrollablePanel::ConstPtr widget)
    {
        if (widget)
            return std::static_pointer_cast<CustomScrollablePanel>(widget->clone());
        else
            return nullptr;
    }

protected:

    Widget::Ptr clone() const override
    {
        return std::make_shared<CustomScrollablePanel>(*this);
    }

private:
    bool m_dragging = false;
    tgui::Vector2f m_originalDragPos;
    tgui::Vector2f m_dragPos;
};

This method has noticeable downsides though. It breaks dragging in widgets, so you can't e.g. have a slider inside the panel. You also e.g. don't get a visual feedback on button presses: because the click happens instantly, you won't see the button go to down state. This actually caused me to believe the code wasn't working for a moment until I realized it and connected an onPress callback to properly test the button press.