Recent Posts

Pages: 1 [2] 3 4 ... 10
11
Feature requests / Re: Tab container/PanelHolder/Notebook widget
« Last post by texus on 24 July 2020, 19:57:18 »
I would call it TabContainer.
- The name PanelHolder doesn't indicate that there are tabs.
- Notebook widget is hopeless to search for due to Jupyter Notebook.
- I didn't have any better ideas myself, TabbedPanel doesn't sound good.
Googling for TabContainer does provide some results on what it is, so even if people don't immediately know what it does from the name they will easily be able to find a description.

The code mostly looks fine. A few remarks:
- Why double the height of the tab in the constructor?
- addPanelAt should be called insertPanel for consistency with other widgets
- Is "m_tabs->select(m_index);" in "m_tabs->onTabSelect" in tgPanelHolder constructor needed? Wouldn't it already be selected before this callback function is even called (and changed a second time in the Select function)?
- Perhaps you should only call "m_tabs->select(index);" in the Select function when the index in the tab is different (i.e. when the user called select himself). Right now you have something that looks like a recursion: Select calls m_tabs->select which triggers onTabSelect in which you call Select again. This works because the Tabs widget doesn't send another callback when the index didn't change, but it might be better to not rely on such internal behavior of Tabs (even if the behavior is never going to change).
- The documentation (comment above class) should probably mention that if you want just the tabs without the panels then the Tabs widget can be used. Similarly, the documentation for the existing Tabs widget should get an extra note that it doesn't contain any panels but if people want a panel directly below their tabs then they can use the TabContainer widget.
12
Feature requests / Tab container/PanelHolder/Notebook widget
« Last post by Kvaz1r on 24 July 2020, 16:25:31 »
Panel holder is a control, which manages multiple windows with associated tabs. This control also known either as Tab container or Notebook widget. It's popular widget so it would be good to have such control in TGUI.

I've made such simple implementation that I current use in own project:

Code: [Select]
class tgPanelHolder : public tgui::SubwidgetContainer
{
public:

    typedef std::shared_ptr<tgPanelHolder> Ptr; //!< Shared widget pointer
    typedef std::shared_ptr<const tgPanelHolder> ConstPtr; //!< Shared constant widget pointer

    tgPanelHolder(const tgui::Layout2d& size = { "100%", "100%" }) : m_index(-1)
    {
        m_type = "PanelHolder";
        setSize(size);
        m_tabs = tgui::Tabs::create();
        m_tabs->setSize({ size.x, m_tabs->getSize().y * 2 });
        m_tabs->onTabSelect([this]()
            {
                auto cur = m_tabs->getSelectedIndex();
                Select(cur);
                if (m_tabs->getSelectedIndex() != m_index)
                {
                    m_tabs->select(m_index);
                }
            });

        m_container->add(m_tabs, "Tabs");
    }

    static tgPanelHolder::Ptr create(const tgui::Layout2d& size = { "100%", "100%" })
    {
        return std::make_shared<tgPanelHolder>(size);
    }

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

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

    void addPanel(tgui::Panel::Ptr ptr, const tgui::String& name, bool select = true)
    {
        auto size = getSizeLayout();
        ptr->setSize({ size.x , size.y - m_tabs->getSize().y });
        ptr->setPosition({ tgui::bindLeft(m_tabs), tgui::bindBottom(m_tabs) });
        m_panels.push_back(ptr);
        m_tabs->add(name, select);
        if (select)
        {
            Select(m_panels.size() - 1, false);
        }
    }

    bool addPanelAt(tgui::Panel::Ptr ptr, const tgui::String& name, std::size_t index, bool select = true)
    {
        if (index > m_panels.size())
        {
            return false;
        }

        addPanel(ptr, name, select);
        auto size = m_panels.size();
        if (index != size)
        {
            std::swap(m_panels[index], m_panels[size - 1]);
        }
    }

    void RemovePanel(tgui::Panel::Ptr ptr)
    {
        if (ptr != nullptr)
        {
            auto idx = getIndex(ptr);
            if (idx != -1)
            {
                m_tabs->remove(idx);
                m_container->remove(m_panels[idx]);
                m_panels.erase(m_panels.begin() + idx);
                if (idx == 0)
                {
                    Select(m_panels.size() - 1);
                }
                else
                {
                    Select(idx - 1);
                }
            }
        }
    }

    void Select(std::size_t index, bool genEvents = true)
    {
        if (index >= m_panels.size() || index == static_cast<std::size_t>(m_index))
        {
            return;
        }
        if (genEvents)
        {
            bool isVetoed = false;
            onSelectionChanging.emit(this, index, &isVetoed);
            if (isVetoed)
            {
                return;
            }
        }

        if (m_container->getWidgets().size() == 2)
        {
            m_container->remove(m_panels[m_index]);
        }
        m_container->add(m_panels[index]);
        m_tabs->select(index);
        m_index = index;
        if (genEvents)
        {
            onSelectionChanged.emit(this, m_index);
        }
    }

    std::size_t Count() const
    {
        return m_panels.size();
    }

    int getIndex(tgui::Panel::Ptr ptr)
    {
        for (std::size_t i = 0; i < m_panels.size(); i++)
        {
            if (m_panels[i] == ptr)
            {
                return static_cast<int>(i);
            }
        }
        return -1;
    }

    tgui::Panel::Ptr getSelected()
    {
        return getPanel(m_index);
    }

    int getSelectedIndex() const
    {
        return m_index;
    }

    tgui::Panel::Ptr getPanel(int index)
    {
        if (index < 0 || index >= static_cast<int>(m_panels.size()))
        {
            return nullptr;
        }
        return m_panels[index];
    }

    tgui::Tabs::Ptr getTabs()
    {
        return m_tabs;
    }

    tgui::String getTabText(std::size_t index) const
    {
        return m_tabs->getText(index);
    }

    bool changeTabText(std::size_t index, const tgui::String& text)
    {
        return m_tabs->changeText(index, text);
    }

public:
    tgui::SignalInt onSelectionChanged = { "SelectionChanged" };
    tgui::SignalTyped2<int, bool*> onSelectionChanging = { "SelectionChanging" }; //can be vetoed

private:
    std::vector<tgui::Panel::Ptr> m_panels;
    int m_index;

    tgui::Tabs::Ptr m_tabs;
};

If it's OK - I'm going to open PR with proper changes (code style, tests, ...)
13
Not really, I don't even have a mac :)
You can probably just delete the .framework file (if you can find the folder where it gets installed to). Although I don't think the framework would be causing conflicts.

Have a look at https://stackoverflow.com/a/61536481 for a random recent guide on installing sfml. Maybe you still have some wrong directories in the library path?
14
Is there a libsfml-window.2.5.dylib file in /usr/local/opt/sfml/lib/?
You could try reinstalling sfml with homebrew, maybe something broke when uninstalling the other version?
There is.
I installed SFML with the frameworks method. Do you know what I'd need to do to uninstall it?
15
Is there a libsfml-window.2.5.dylib file in /usr/local/opt/sfml/lib/?
You could try reinstalling sfml with homebrew, maybe something broke when uninstalling the other version?
16
You should remove the one you installed yourself. They are likely identical versions and it won't matter which one is removed, but the homebrew TGUI package is build with the homebrew SFML version so you can be certain that those are compatible.
Thanks; I have, though now I get this error message:

Quote
dyld: Library not loaded: @rpath/libsfml-window.2.5.dylib
  Referenced from: /usr/local/opt/sfml/lib/libsfml-graphics.2.5.dylib
  Reason: image not found
(lldb)
17
You should remove the one you installed yourself. They are likely identical versions and it won't matter which one is removed, but the homebrew TGUI package is build with the homebrew SFML version so you can be certain that those are compatible.
18
Thanks; you appear to be right. Which version do you suggest I uninstall, the one I installed or the one homebrew did while installing TGUI?
19
It seems like you have 2 SFML versions installed on your computer (probably one installed manually and another installed via homebrew, possibly while installing tgui). One is installed in /usr/local/lib/ and the other is installed in /usr/local/opt/sfml/. The TGUI homebrew package was build with one of those (the one from homebrew) and will require exactly that one SFML version in order to work, so you have to uninstall the other one.
20
(For context, I use XCode, and the project name is "Vigor2.")

I've begun using TGUI for my SFML projects, as it looks very interesting and powerful. I followed the homebrew installation instructions, adding -ltgui to Other Linker Flags in the build settings. However, when I try to use TGUI at all, I get some strange console messages.

Quote
objc[63774]: Class SFApplication is implemented in both /usr/local/lib/libsfml-window.2.5.dylib (0x100bf2e78) and /usr/local/opt/sfml/lib/libsfml-window.2.5.dylib (0x100ba6198). One of the two will be used. Which one is undefined.
objc[63774]: Class SFApplicationDelegate is implemented in both /usr/local/lib/libsfml-window.2.5.dylib (0x100bf2ef0) and /usr/local/opt/sfml/lib/libsfml-window.2.5.dylib (0x100ba6210). One of the two will be used. Which one is undefined.
objc[63774]: Class SFOpenGLView is implemented in both /usr/local/lib/libsfml-window.2.5.dylib (0x100bf2f18) and /usr/local/opt/sfml/lib/libsfml-window.2.5.dylib (0x100ba6238). One of the two will be used. Which one is undefined.
objc[63774]: Class SFSilentResponder is implemented in both /usr/local/lib/libsfml-window.2.5.dylib (0x100bf2f90) and /usr/local/opt/sfml/lib/libsfml-window.2.5.dylib (0x100ba62b0). One of the two will be used. Which one is undefined.
objc[63774]: Class SFWindow is implemented in both /usr/local/lib/libsfml-window.2.5.dylib (0x100bf2fb8) and /usr/local/opt/sfml/lib/libsfml-window.2.5.dylib (0x100ba62d8). One of the two will be used. Which one is undefined.
objc[63774]: Class SFBlackView is implemented in both /usr/local/lib/libsfml-window.2.5.dylib (0x100bf3030) and /usr/local/opt/sfml/lib/libsfml-window.2.5.dylib (0x100ba6350). One of the two will be used. Which one is undefined.
objc[63774]: Class SFWindowController is implemented in both /usr/local/lib/libsfml-window.2.5.dylib (0x100bf3058) and /usr/local/opt/sfml/lib/libsfml-window.2.5.dylib (0x100ba6378). One of the two will be used. Which one is undefined.
objc[63774]: Class SFViewController is implemented in both /usr/local/lib/libsfml-window.2.5.dylib (0x100bf30a8) and /usr/local/opt/sfml/lib/libsfml-window.2.5.dylib (0x100ba63c8). One of the two will be used. Which one is undefined.
objc[63774]: Class SFApplication is implemented in both /usr/local/lib/libsfml-window.2.5.dylib (0x100bf2e78) and /Users/(my username)/Library/Developer/Xcode/DerivedData/Vigor2-guhwhorcosfnsqcxuglttibdbzyk/Build/Products/Debug/Vigor2.app/Contents/Frameworks/sfml-window.framework/Versions/2.5.1/sfml-window (0x10037ee78). One of the two will be used. Which one is undefined.
objc[63774]: Class SFApplicationDelegate is implemented in both /usr/local/lib/libsfml-window.2.5.dylib (0x100bf2ef0) and /Users/(my username)/Library/Developer/Xcode/DerivedData/Vigor2-guhwhorcosfnsqcxuglttibdbzyk/Build/Products/Debug/Vigor2.app/Contents/Frameworks/sfml-window.framework/Versions/2.5.1/sfml-window (0x10037eef0). One of the two will be used. Which one is undefined.
objc[63774]: Class SFOpenGLView is implemented in both /usr/local/lib/libsfml-window.2.5.dylib (0x100bf2f18) and /Users/(my username)/Library/Developer/Xcode/DerivedData/Vigor2-guhwhorcosfnsqcxuglttibdbzyk/Build/Products/Debug/Vigor2.app/Contents/Frameworks/sfml-window.framework/Versions/2.5.1/sfml-window (0x10037ef18). One of the two will be used. Which one is undefined.
objc[63774]: Class SFSilentResponder is implemented in both /usr/local/lib/libsfml-window.2.5.dylib (0x100bf2f90) and /Users/(my username)/Library/Developer/Xcode/DerivedData/Vigor2-guhwhorcosfnsqcxuglttibdbzyk/Build/Products/Debug/Vigor2.app/Contents/Frameworks/sfml-window.framework/Versions/2.5.1/sfml-window (0x10037ef90). One of the two will be used. Which one is undefined.
objc[63774]: Class SFWindow is implemented in both /usr/local/lib/libsfml-window.2.5.dylib (0x100bf2fb8) and /Users/(my username)/Library/Developer/Xcode/DerivedData/Vigor2-guhwhorcosfnsqcxuglttibdbzyk/Build/Products/Debug/Vigor2.app/Contents/Frameworks/sfml-window.framework/Versions/2.5.1/sfml-window (0x10037efb8). One of the two will be used. Which one is undefined.
objc[63774]: Class SFBlackView is implemented in both /usr/local/lib/libsfml-window.2.5.dylib (0x100bf3030) and /Users/(my username)/Library/Developer/Xcode/DerivedData/Vigor2-guhwhorcosfnsqcxuglttibdbzyk/Build/Products/Debug/Vigor2.app/Contents/Frameworks/sfml-window.framework/Versions/2.5.1/sfml-window (0x10037f030). One of the two will be used. Which one is undefined.
objc[63774]: Class SFWindowController is implemented in both /usr/local/lib/libsfml-window.2.5.dylib (0x100bf3058) and /Users/(my username)/Library/Developer/Xcode/DerivedData/Vigor2-guhwhorcosfnsqcxuglttibdbzyk/Build/Products/Debug/Vigor2.app/Contents/Frameworks/sfml-window.framework/Versions/2.5.1/sfml-window (0x10037f058). One of the two will be used. Which one is undefined.
objc[63774]: Class SFViewController is implemented in both /usr/local/lib/libsfml-window.2.5.dylib (0x100bf30a8) and /Users/(my username)/Library/Developer/Xcode/DerivedData/Vigor2-guhwhorcosfnsqcxuglttibdbzyk/Build/Products/Debug/Vigor2.app/Contents/Frameworks/sfml-window.framework/Versions/2.5.1/sfml-window (0x10037f0a8). One of the two will be used. Which one is undefined.
sfml-graphics requires support for OpenGL 1.1 or greater
Ensure that hardware acceleration is enabled if available

Additionally, TGUI widgets never show up on the window (though their connect methods do work) unless I draw an SFML drawable to the window before calling gui.draw(). I don't even have to give it a size or position, but unless I do that, the TGUI widgets are nowhere to be seen.

As I mentioned, I'm completely new to TGUI and I'm excited to start using it as soon as possible. Help figuring out one or both of my issues would be very appreciated.

Thanks!
Pages: 1 [2] 3 4 ... 10