V0.7 alphav0.2 listbox signals

Started by starkhorn, 15 October 2015, 22:24:55

starkhorn

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

Code (cpp) Select

        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?

Code (cpp) Select

#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

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.

starkhorn

arrrggh you are 100% correct (as usual).

This line

Code (cpp) Select


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

Code (cpp) Select

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


Thanks again