Error when adding text to textBox

Started by starkhorn, 22 January 2015, 09:27:00

starkhorn

Hey Folks,

So I'm trying to use textBox where I display some game data in an efficient way with scoll-bars. However I get an error when using the setText or addText methods. (using v0.6 btw)

Code (cpp) Select


tgui::TextBox::Ptr textBoxList;

textBoxList->load(themeConfFile);
textBoxList->setPosition(20, 20);
textBoxList->setSize(600, 300);
textBoxList->setBackgroundColor(sf::Color::White);
textBoxList->setSize(600, 300);
textBoxList->setText("Nation\t");



I get an run error with visual studio.



When I press retry, it breakpoints into dbgheap.c at line 1424.

Also I had another question about textbox and chatbox. Is there a way to automatically scroll down the textbox, i.e. if the amount of text exceeds the ysize, then can I move the scroll automatically so the last entry is the one that stays in focus within the textbox?

texus

#1
QuoteWhen I press retry, it breakpoints into dbgheap.c at line 1424.
At that point, you should look at the call stack. Since those lines of code don't give a problem here (testing on linux though), the callstack would give me some idea of where it happens.

You might also want to give me a minimal and complete example code (simple main function with code that reproduces this problem). Then I can decently test it if I can't find the mistake from the call stack.

QuoteAlso I had another question about textbox and chatbox. Is there a way to automatically scroll down the textbox, i.e. if the amount of text exceeds the ysize, then can I move the scroll automatically so the last entry is the one that stays in focus within the textbox?
textbox->setText, textbox->addText and chatbox->addLine should all scroll down to the bottom.

starkhorn

Hi,

Sorry for the delay in replying. I'm not sure of the best way to show you the callstack? See the below screenshot but I'm guessing you want more info or for me to click on one of them? If so which one? The below is the error I got with chatbox->addLine from the full example v0.6 code. I seem to get this error when using textbox->addtext or settext And it happens with chatbox->addline.





I've used the example v0.6 full code and I get the same error with chatbox->addline. See below, I added a small textbox section, however as mentioned I get the same error with chatbox as well.

Code (cpp) Select


#define THEME_CONFIG_FILE "C:/Users/mcgoldrickb/Documents/TGUI-0.6/widgets/Black.conf"
#include <TGUI/TGUI.hpp>
int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "TGUI window");
    tgui::Gui gui(window);

    if (gui.setGlobalFont("C:/Users/mcgoldrickb/Documents/TGUI-0.6/fonts/DejaVuSans.ttf") == false)
        return 1;

    tgui::Picture::Ptr picture(gui);
    picture->load("C:/Users/mcgoldrickb/Documents/TGUI-0.6/examples/Linux.jpg");

    tgui::Button::Ptr button(gui);
    button->load(THEME_CONFIG_FILE);
    button->setPosition(40, 25);
    button->setText("Quit");
    button->setCallbackId(1);
    button->bindCallback(tgui::Button::LeftMouseClicked);
    button->setSize(300, 40);

tgui::TextBox::Ptr textbox(gui);
textbox->load(THEME_CONFIG_FILE);
textbox->setSize(200, 100);
    textbox->setTextSize(20);
    textbox->setPosition(600, 25);
textbox->addText("Hello");

    tgui::ChatBox::Ptr chatbox(gui);
    chatbox->load(THEME_CONFIG_FILE);
    chatbox->setSize(200, 100);
    chatbox->setTextSize(20);
    chatbox->setPosition(400, 25);
    chatbox->addLine("Line 1", sf::Color::Red);
    chatbox->addLine("Line 2", sf::Color::Blue);
    chatbox->addLine("Line 3", sf::Color::Green);
    chatbox->addLine("Line 4", sf::Color::Yellow);
    chatbox->addLine("Line 5", sf::Color::Cyan);
    chatbox->addLine("Line 6", sf::Color::Magenta);

    tgui::Checkbox::Ptr checkbox(gui);
    checkbox->load(THEME_CONFIG_FILE);
    checkbox->setPosition(40, 80);
    checkbox->setText("Checkbox");
    checkbox->setSize(32, 32);

    tgui::ChildWindow::Ptr child(gui);
    child->load(THEME_CONFIG_FILE);
    child->setSize(200, 100);
    child->setBackgroundColor(sf::Color(80, 80, 80));
    child->setPosition(400, 460);
    child->setTitle("Child window");
    child->setIcon("C:/Users/mcgoldrickb/Documents/TGUI-0.6/examples/icon.jpg");

    tgui::ComboBox::Ptr comboBox(gui);
    comboBox->load(THEME_CONFIG_FILE);
    comboBox->setSize(120, 21);
    comboBox->setPosition(210, 440);
    comboBox->addItem("Item 1");
    comboBox->addItem("Item 2");
    comboBox->addItem("Item 3");
    comboBox->setSelectedItem("Item 2");

    tgui::EditBox::Ptr editBox(gui);
    editBox->load(THEME_CONFIG_FILE);
    editBox->setPosition(40, 200);
    editBox->setSize(300, 30);

    tgui::Label::Ptr label(gui);
    label->load(THEME_CONFIG_FILE);
    label->setText("Label");
    label->setPosition(40, 160);
    label->setTextColor(sf::Color(200, 200, 200));
    label->setTextSize(24);

    tgui::ListBox::Ptr listBox(gui);
    listBox->load(THEME_CONFIG_FILE);
    listBox->setSize(150, 120);
    listBox->setItemHeight(20);
    listBox->setPosition(40, 440);
    listBox->addItem("Item 1");
    listBox->addItem("Item 2");
    listBox->addItem("Item 3");

    tgui::LoadingBar::Ptr loadingbar(gui);
    loadingbar->load(THEME_CONFIG_FILE);
    loadingbar->setPosition(40, 330);
    loadingbar->setSize(300, 30);
    loadingbar->setValue(35);

    tgui::MenuBar::Ptr menu(gui);
    menu->load(THEME_CONFIG_FILE);
    menu->setSize(window.getSize().x, 20);
    menu->addMenu("File");
    menu->addMenuItem("File", "Load");
    menu->addMenuItem("File", "Save");
    menu->addMenuItem("File", "Exit");
    menu->bindCallback(tgui::MenuBar::MenuItemClicked);
    menu->setCallbackId(2);

    sf::Texture texture;
    texture.loadFromFile("C:/Users/mcgoldrickb/Documents/TGUI-0.6/examples/ThinkLinux.jpg");

    tgui::Panel::Ptr panel(gui);
    panel->setSize(200, 140);
    panel->setPosition(400, 150);
    panel->setBackgroundTexture(&texture);

    tgui::RadioButton::Ptr radioButton(gui);
    radioButton->load(THEME_CONFIG_FILE);
    radioButton->setPosition(40, 120);
    radioButton->setText("Radio Button");
    radioButton->setSize(32, 32);

    tgui::Slider::Ptr slider(gui);
    slider->load(THEME_CONFIG_FILE);
    slider->setVerticalScroll(false);
    slider->setPosition(40, 250);
    slider->setSize(300, 25);
    slider->setValue(2);

    tgui::Scrollbar::Ptr scrollbar(gui);
    scrollbar->load(THEME_CONFIG_FILE);
    scrollbar->setVerticalScroll(false);
    scrollbar->setPosition(40, 290);
    scrollbar->setSize(300, 25);
    scrollbar->setMaximum(5);
    scrollbar->setLowValue(3);

    tgui::Slider2d::Ptr slider2d(gui);
    slider2d->load("C:/Users/mcgoldrickb/Documents/TGUI-0.6/widgets/Slider2d/Black.conf");
    slider2d->setPosition(400, 300);
    slider2d->setSize(200, 150);

    tgui::SpinButton::Ptr spinButton(gui);
    spinButton->load(THEME_CONFIG_FILE);
    spinButton->setPosition(40, 410);
    spinButton->setVerticalScroll(false);
    spinButton->setSize(40, 20);

    tgui::SpriteSheet::Ptr spritesheet(gui);
    spritesheet->load("C:/Users/mcgoldrickb/Documents/TGUI-0.6/examples/ThinkLinux.jpg");
    spritesheet->setCells(4, 4);
    spritesheet->setVisibleCell(2, 3);
    spritesheet->setSize(160, 120);
    spritesheet->setPosition(620, 25);

    tgui::Tab::Ptr tab(gui);
    tab->load(THEME_CONFIG_FILE);
    tab->setPosition(40, 370);
    tab->add("Item 1");
    tab->add("Item 2");
    tab->add("Item 3");

    tgui::TextBox::Ptr textBox(gui);
    textBox->load(THEME_CONFIG_FILE);
    textBox->setPosition(210, 470);
    textBox->setSize(180, 120);
    textBox->setTextSize(16);

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();

            gui.handleEvent(event);
        }

        tgui::Callback callback;
        while (gui.pollCallback(callback))
        {
            if (callback.id == 1)
                window.close();

            else if (callback.id == 2)
            {
                if (callback.text == "Exit")
                    window.close();
            }
        }

        window.clear();
        gui.draw();
        window.display();
    }

    return 0;
}


texus

I would actually need to know what lines inside the tgui code cause the crash. In the stack frame you see those tgui-d.dll, I would have to know which line and which function exactly that it is referring to. Only then would I be able to figure out what is happening without debugging it myself.

After looking it up, I just realized again that on windows you need special files (.pdb files) in order to get that information. These are generated when compiling tgui yourself but not distributed in the pre-compiled library download. I still have this pdb file on my pc, you might want to try putting it next to your dll and see if it gives more information like that.

I'm going to sleep now (it's 3 am here), maybe I will try running that code on my pc tomorrow and see what it gives. But I can't promise anything, I still have to study for my last exam that I have Wednesday and debugging stuff can be too time consuming if the bug isn't immediately found.

starkhorn

Hi Texus,

Many thanks and yes I'm sorry that the information that I've provided has been less than helpful. I've put in the .pdb file and now I can see more info in the stack trace etc. It actually refers to the Textbox.cpp now.



Now I've gone through each stack trace file and copy/pasted a snippet from each file. Look for the //stopped here message. I started at begining of the trace and worked upwards.

dbgheap.c
Code (cpp) Select

        /* optionally reclaim memory */
        if (!(_crtDbgFlag & _CRTDBG_DELAY_FREE_MEM_DF))
        {
            /* remove from the linked list */
            if (pHead->pBlockHeaderNext)
            {
                pHead->pBlockHeaderNext->pBlockHeaderPrev = pHead->pBlockHeaderPrev;
            }
            else
            {
                _ASSERTE(_pLastBlock == pHead);
                _pLastBlock = pHead->pBlockHeaderPrev;
            }

            if (pHead->pBlockHeaderPrev)
            {
                pHead->pBlockHeaderPrev->pBlockHeaderNext = pHead->pBlockHeaderNext;
            }
            else
            {
                _ASSERTE(_pFirstBlock == pHead); //<---------Stopped here
                _pFirstBlock = pHead->pBlockHeaderNext;
            }

            /* fill the entire block including header with dead-land-fill */
            memset(pHead, _bDeadLandFill,
                sizeof(_CrtMemBlockHeader) + pHead->nDataSize + nNoMansLandSize);
            _free_base(pHead);
        }


xmemory0   
Code (cpp) Select

void deallocate(pointer _Ptr, size_type)
{ // deallocate object at _Ptr, ignore size
::operator delete(_Ptr); //<-----stopped here line 586
}


xstring
Code (cpp) Select

void _Free_proxy()
{ // destroy proxy
typename _Alloc::template rebind<_Container_proxy>::other
_Alproxy;
this->_Orphan_all();
_Alproxy.destroy(this->_Myproxy);
_Alproxy.deallocate(this->_Myproxy, 1);
this->_Myproxy = 0; //<---------- stopped here line 683
}


xstring (again)

Code (cpp) Select

#else /* _ITERATOR_DEBUG_LEVEL == 0 */
_String_alloc(const _Alloc& = _Alloc())
{ // construct allocator from _Al
_Alloc_proxy();
}

~_String_alloc() _NOEXCEPT
{ // destroy the object
_Free_proxy();
} //<----------stopped here line 656


xstring

Code (cpp) Select

~basic_string() _NOEXCEPT
{ // destroy the string
_Tidy(true);
} //<-----stopped here line 965


TextBox.cpp (tgui::TextBox::updateDisplayedText)

Code (cpp) Select

        // Loop through every character
        for (unsigned i=1; i < m_Text.getSize() + 1; ++i)
        {
            // Make sure the character is not a newline
            if (m_Text[i-1] != '\n')
            {
                // Add the next character to the text widget
                tempText.setString(m_Text.toWideString().substr(beginChar, i - beginChar));

                // Check if the string still fits on the line
                if (tempText.findCharacterPos(i).x > maxLineWidth) //<-------stopped here line 2114
                {
                    // Insert the newline character
                    m_DisplayedText.insert(i + newlinesAdded - 1, '\n');

                    // Prepare to find the next line end
                    beginChar = i - 1;
                    ++newlinesAdded;
                    ++m_Lines;
                }
            }


TextBox.cpp (tgui::TextBox::setSelectionPointPosition)

Code (cpp) Select

        // Check if there is a scrollbar
        if (m_Scroll != nullptr) //<------ stopped here line 650
        {
            unsigned int newlines = 0;
            unsigned int newlinesAdded = 0;
            unsigned int totalLines = 0;


TextBox.cpp (tgui::TextBox::addText)
Code (cpp) Select

    void TextBox::addText(const sf::String& text)
    {
        // Don't do anything when the text box wasn't loaded correctly
        if (m_Loaded == false)
            return;

        // Add the text
        m_Text += text;

        // Set the selection point behind the last character
        setSelectionPointPosition(m_Text.getSize());
    } // <------stopped here line 405

texus

Thanks. It doesn't really help in finding the mistake, but it at least rules out a lot of possibilities.

I just tried booting my windows but it is apparently no longer booting. It worked fine two days ago but now it seems like it won't get further than my grub bootloader. I'm going to try overwriting it with the windows bootloader but if that doesn't help then we have a serious issue as it is the only pc that I have which has the necessary programs installed on it.

What bothers me is that I can't reproduce it on linux.
Could you make sure that you are using the correct sfml libraries? If you downloaded the tgui libraries from my site then you need sfml 2.2, otherwise you must use the exact version which u used when compiling tgui. And also make sure that you use the debug libs for both sfml and tgui.

texus

I have been able to boot my windows again and I can reproduce the error. So it is definitely a bug in tgui.
I'll let you know when I fixed it.

texus

#7
I have solved the "problem". As far as I can see, there was nothing wrong with the code and this is all visual studios fault.

The following code crashed:
Code (cpp) Select
newText->setText(text.toWideString().substr(begin, length));

while the following worked fine:
Code (cpp) Select
std::wstring temp = text.toWideString().substr(begin, length);
newText->setText(temp);


But actually, since this code was only added because sfml 2.0 did not have a substring method (which it now has), I just replaced it to the following and therefore forcing people to update to sfml 2.2. But at least the problem is solved.
Code (cpp) Select
newText->setText(text.substring(begin, length));

To get the fix, you will have to download the latest version from github and compile tgui yourself.

EDIT: ChatBox::addLine still crashes apparently. It seems like VS2012 may have some serious problems with using the sf::String class as temporary value. I'm not sure if I can really fix this.

texus

I really wish I could help further but I have run out of time. I have to get my windows environment fixed first before I can continue. It seems to work in VS2013, but I'm also experiencing crashes on draw which may or may not be related to the tons of opengl errors in my terminal which are probably caused by my graphics driver. I probably won't be able to help further until wednesday.

You could try one thing yourself in the meantime though:
In addition to the changes that I have made in the version on github, also replace the line "label->setText(label->getText() + tempLine->getText());" in ChatBox.cpp (line 355) to
Code (cpp) Select
std::string temp1 = label->getText().toAnsiString();
std::string temp2 = tempLine->getText().toAnsiString();
label->setText(temp1 + temp2);
and then recompile tgui.

starkhorn

no worries at all mate and many thanks for looking at this so quickly.
I'm definitely using sfml2.2, so I'll grab the updated v0.7 and see if it makes a difference. however concentrate on your exams first....this can wait. :)