V0.7 alphav0.2 listbox signals
« on: 15 October 2015, 22:24:55 »
Hey,

I'm trying to use the listbox signals but everytime I try to connect a signal to the listbox instance, I get an "Unhandled exception at 0x011611FA in BLAH.exe: 0xC0000005: Access violation reading location 0x000000A4."

When I break, it seems to be stopped in the signalbasewidget.hpp file at the below location

        template <typename Func, typename... Args>
        unsigned int connect(const std::string& signalNames, Func func, Args... args)
        {
            for (auto& signalName : extractSignalNames(signalNames))
            {
                if (m_signals.find(toLower(signalName)) != m_signals.end())     //<----------STOPS HERE STOPS HERE STOPS HERE
                {
                    try {
                        m_signals[toLower(signalName)]->connect(m_lastId, func, args...);
                        m_lastId++;
                    }
                    catch (const Exception& e) {
                        throw Exception{e.what() + (" The parameters are not valid for the '" + signalName + "' signal.")};
                    }
                }
 

I've tried ItemSelected, MouseEntered, MousePressed and all the same result. See below a full working exampe of what I am trying to do. Any ideas on what I am doing wrong here?

#include <TGUI/TGUI.hpp>
#include <string>
#include <math.h>
#define THEME_CONFIG_FILE "E:\\programming\\projects\\rome_vs2013\\rome_vs2013\\Debug\\\\widgets\\rome.txt"
#include "nation.h"

using namespace std;

class Test
{
public:

        Test();

        sf::RenderWindow gameWindow;
        sf::VideoMode desktop;
        sf::Event event;
        tgui::Callback callback;
        tgui::Gui gui;
        sf::Texture mainMenuBackGround;
        sf::Font font;
       
        tgui::Theme::Ptr theme;

        void initFont();
        void setThemeConfigFile(string passed_filename);
        void setupChildWindow(sf::Vector2i pos, sf::Vector2i size, string title_text, sf::Color titleText_Color, string passed_childName);
        void setupCanvas(sf::Vector2i pos, sf::Vector2i size, string passed_canvasName, tgui::Container::Ptr container = NULL);
        void initSubMenuCanvas(tgui::Container::Ptr container);
        void setupListBox(sf::Vector2i pos, sf::Vector2i size, int passed_TextSize, sf::Color passed_colour, string listBoxID, string passed_themeSection, tgui::Container::Ptr container = NULL);
        void addStringItemToListBox(string listBoxID, vector<string> passed_stringItemsToAdd);
        void drawCitySubMenu(Nation *passed_Nation, tgui::Canvas::Ptr canvas);

};

Test::Test()
{
        desktop = sf::VideoMode::getDesktopMode();
        gameWindow.create(sf::VideoMode(desktop.width, desktop.height, desktop.bitsPerPixel), "Test");
        gameWindow.setPosition(sf::Vector2i(0, 0));
        gui.setWindow(gameWindow);
        gui.setFont("E:\\programming\\projects\\rome_vs2013\\rome_vs2013\\Debug\\\\inputfiles\\fonts\\DejaVuSans.ttf");
        setThemeConfigFile(THEME_CONFIG_FILE);
       
}

void Test::initFont()
{
        font.loadFromFile("E:\\programming\\projects\\rome_vs2013\\rome_vs2013\\Debug\\inputfiles\\fonts\\DejaVuSans.ttf");
}

void Test::setThemeConfigFile(string passed_filename)
{
        // Load the black theme
        theme = std::make_shared<tgui::Theme>(passed_filename);
}

void Test::setupChildWindow(sf::Vector2i pos, sf::Vector2i size, string title_text, sf::Color titleText_Color, string passed_childName)
{
        if (gui.get(passed_childName) == NULL)
        {
                tgui::ChildWindow::Ptr childWin = theme->load("ChildWindow");
                childWin->setPosition(pos.x, pos.y);
                childWin->setSize(size.x, size.y);
                childWin->getRenderer()->setTitleColor(titleText_Color);
                childWin->setTitle(title_text);
                gui.add(childWin, passed_childName);
        }
}

void Test::setupCanvas(sf::Vector2i pos, sf::Vector2i size, string passed_canvasName, tgui::Container::Ptr container)
{
        if ((container != NULL && container->get(passed_canvasName) == NULL) || (container == NULL && gui.get(passed_canvasName) == NULL))
        {
                auto canvas = std::make_shared<tgui::Canvas>();
                canvas->setPosition(pos.x, pos.y);
                canvas->setSize(size.x, size.y);

                if (container == NULL)
                {
                        gui.add(canvas, passed_canvasName);
                }
                else
                {
                        container->add(canvas, passed_canvasName);
                }
        }
}

void Test::initSubMenuCanvas(tgui::Container::Ptr container)
{
        float childSizeX = container->getSize().x;
        float childSizeY = container->getSize().y;
        sf::Vector2f scaledValues;

        sf::Vector2i pos;
        sf::Vector2i size(childSizeX, childSizeY);;

        setupCanvas(pos, size, "subMenuCanvas", container);
       
        tgui::Canvas::Ptr canvas = container->get<tgui::Canvas>("subMenuCanvas");
        canvas->clear();
}

void Test::setupListBox(sf::Vector2i pos, sf::Vector2i size, int passed_TextSize, sf::Color passed_colour, string listBoxID, string passed_themeSection, tgui::Container::Ptr container)
{
        if ((container != NULL && container->get(listBoxID) == NULL) || (container == NULL && gui.get(listBoxID) == NULL))
        {
                tgui::ListBox::Ptr listbox = theme->load(passed_themeSection);
                listbox->setPosition(pos.x, pos.y);
                listbox->setSize(size.x, size.y);
                listbox->getRenderer()->setTextColor(passed_colour);
                listbox->setItemHeight(passed_TextSize);
               
                if (container == NULL)
                {
                        gui.add(listbox, listBoxID);
                }
                else
                {
                        container->add(listbox, listBoxID);
                }
        }
}

void Test::addStringItemToListBox(string listBoxID, vector<string> passed_stringItemsToAdd)
{
        tgui::ListBox::Ptr listbox = gui.get<tgui::ListBox>(listBoxID, true);

        if (listbox != NULL)
        {
                bool isLineAlreadyAdded = false;
                vector<sf::String> itemsList;

                for (int i = 0; i < passed_stringItemsToAdd.size(); i++)
                {
                        itemsList = listbox->getItems();
                        isLineAlreadyAdded = false;
                        for (int j = 0; j < itemsList.size(); j++)
                        {
                                if (itemsList.at(j) == passed_stringItemsToAdd[i])
                                {
                                        isLineAlreadyAdded = true;
                                }
                        }

                        if (!isLineAlreadyAdded)
                        {
                                listbox->addItem(passed_stringItemsToAdd[i]);
                        }
                }

        }
}

void Test::drawCitySubMenu(Nation *passed_Nation, tgui::Canvas::Ptr canvas)
{
        sf::Text msg("", font);


        msg.setCharacterSize(15);
        msg.setColor(sf::Color::White);
        msg.setPosition(10, 25);
        msg.setString("This is draw city sub menu");
        canvas->draw(msg);
}


int main()
{
        Test testClass;
        string themeSection;
        string childWinName = "testChild";
        string listboxID = "listbox";
        Nation passed_Nation;

        sf::Vector2i pos(testClass.gameWindow.getSize().x * 0.1, testClass.gameWindow.getSize().y * 0);
        sf::Vector2i size((testClass.gameWindow.getSize().x - (testClass.gameWindow.getSize().x * 0.25)), 400);

        testClass.setupChildWindow(pos, size, "Start Turn Summary", sf::Color::Red, childWinName);

        tgui::Container::Ptr container = testClass.gui.get<tgui::Container>(childWinName);
        testClass.initSubMenuCanvas(container);
        tgui::Canvas::Ptr canvas = container->get<tgui::Canvas>("subMenuCanvas");
        sf::Vector2f childSize(container->getSize());

        pos.x = 0;
        pos.y = 10;

        testClass.setupListBox(pos, size, 15, sf::Color::Green, listboxID, "Listbox", container);
        tgui::ListBox::Ptr regionListBox = testClass.gui.get<tgui::ListBox>(listboxID);
        regionListBox->connect("ItemSelected", &Test::drawCitySubMenu, &testClass, &passed_Nation, canvas);
        testClass.addStringItemToListBox(listboxID, passed_Nation.getNationListOfRegionsMenuData());

    // Main loop
        while (testClass.gameWindow.isOpen())
    {
        sf::Event event;
                while (testClass.gameWindow.pollEvent(event))
        {
            // When the window is closed, the application ends
            if (event.type == sf::Event::Closed)
                                testClass.gameWindow.close();


            // Pass the event to all the widgets
                        testClass.gui.handleEvent(event);
        }
               
                testClass.gameWindow.clear();
                testClass.gui.draw();
                testClass.gameWindow.display();
        }

        return 0;
}

 

*

texus

  • *****
  • 1163
    • View Profile
    • Texus's Blog
Re: V0.7 alphav0.2 listbox signals
« Reply #1 on: 15 October 2015, 22:32:39 »
I can't look into it right now, but you should check is you have a nullptr somewhere. My guess would be that you are calling the connect function on a nullptr.

Re: V0.7 alphav0.2 listbox signals
« Reply #2 on: 15 October 2015, 22:35:06 »
arrrggh you are 100% correct (as usual).

This line


tgui::ListBox::Ptr regionListBox = testClass.gui.get<tgui::ListBox>(listboxID);

 

But my listbox was added into the canvas which is in turn was in a childwindow.

Doing this works

tgui::ListBox::Ptr regionListBox = testClass.gui.get<tgui::ListBox>(listboxID, true);
 

Thanks again