::Ptr in class = no text

Started by SDH, 07 December 2014, 09:52:42

SDH

Example:

class CGuiBasePage
{
     public:
          virtual void construct();
          virtual void destruct();
}

class CButton : public CGuiBasePage
{
     private:
          tgui::Button::Ptr m_button;

     public:
          void construct();
          void destruct();
};

std::unique_ptr<CGuiBasePage> m_page;
m_page = std::move(std::make_unique<CGuiBasePage>());

main.cpp
m_page -> construct();


result of this code is that i can't see any text in Button or EditBox.

Using:
Visual Studio 2013
sfml 2.1
tgui 0.6.6
everything is compiled by me, but problem is reproducable even on sfml build from your website.

texus

Since you are not using the constructor of the button to initialize it like in the example codes (which I admit is sometimes practically impossible in v0.6 when having the widget in a class), could you show me the code where you actually create the widget?

If no text shows up it means that there is no font. The font is normally set with gui.setGlobalFont and then passed to the widget when connecting it to the gui.

It is really hard to say what is going wrong without seeing the contents of the construct method.

PS: Is there any reason why u don't use normal constructors and destructors?

SDH

#2
Minimal code:

construct()
   // load needed resources
   Assets::Data::loadFont("font", "xxx.otf");

   // UserName entry field
   m_entry_user -> load(THEME_CONFIG_FILE);
   m_entry_user -> setMaximumCharacters(20);
   m_entry_user -> setPosition(10,10);
   m_entry_user -> setSelectedTextBackgroundColor(sf::Color(0,0,50));
   m_entry_user -> setSize(size_x, size_y);
   m_entry_user -> setTextFont(Assets::Data::getFont("font"));
   m_entry_user -> setTransparency(200);

   // Button
   m_button -> load(THEME_CONFIG_FILE);
   m_button -> setSize(size_x, size_y);
   m_button -> setPosition(m_entry_user -> getPosition().x + m_entry_user -> getSize().x + offset, m_entry_user -> getPosition().y);
   m_button -> setText("Log-in");
   m_button -> setTextColor(sf::Color::Yellow);
   m_button -> setTextFont(Assets::Data::getFont("font"));
   m_button -> setTextSize(16);
   m_button -> bindCallback(tgui::Button::LeftMouseClicked);
   m_button -> setCallbackId(1);
   m_button -> setTransparency(200);

   fw::g_gui -> add(m_entry_user);
   fw::g_gui -> add(m_button);

destruct()
   fw::g_gui -> remove(m_entry_user);
   fw::g_gui -> remove(m_button);

BTW:
std::unique_ptr<thor::Gui> g_gui; // under namespace fw

when i'll declare (let's say tgui::Button) in function body then font-text works, but it's going to be a part of multiplayer game so i cant use function tgui::Gui::removeAllWidgets() because certain things must be still visible (it sucks when your game screen blinks)

Please dont blame functions load* get*, they work.

Quote from: texus on 07 December 2014, 11:14:39
If no text shows up it means that there is no font. The font is normally set with gui.setGlobalFont and then passed to the widget when connecting it to the gui.
Minimal code:
For some unknown reason it never worked.

Quote from: texus on 07 December 2014, 11:14:39
PS: Is there any reason why u don't use normal constructors and destructors?
I was in a hurry :) thanks ;) .

texus

I may have an idea about what the bug could be.
Could you try calling "widget->setTextFont(...)" after you call "fw::g_gui->add(widget)"?

But if that doesn't solve the problem then I'm going to need a minimal code that I can test myself.


Quotei cant use function tgui::Gui::removeAllWidgets() because certain things must be still visible (it sucks when your game screen blinks)
Your screen is only updated when drawing. If you call removeAllWidgets and then add the needed widgets before you update your screen then nothing will blink. Of course recreating widgets takes time and it is slightly more efficient to keep the ones that you need, but I just though I should mention it.

SDH

calling "widget->setTextFont(...)" after i call "fw::g_gui->add(widget)" works :) .

Quote
Your screen is only updated when drawing. If you call removeAllWidgets and then add the needed widgets before you update your screen then nothing will blink. Of course recreating widgets takes time and it is slightly more efficient to keep the ones that you need, but I just though I should mention it.
Thanks :) i'll try that.

texus

#5
This is a limitation in the way v0.6 works.

You aren't supposed to be using the gui.add function directly.
A better method would be to write:
Code (cpp) Select
m_button = tgui::Button::Ptr(*fw::g_gui);
m_button->load(THEME_CONFIG_FILE);
m_button->...
By doing so, the widget is fully initialized before you call any functions on it.

If all widgets need the same font, then instead of calling setTextFont on every widget you could also write the following on top of the construct method:
Code (cpp) Select
fw::g_gui->setGlobalFont(Assets::Data::getFont("font"));That would also have solved this problem.

SDH

#6
problem with "tgui::Gui::setGlobalFont(...)" is that it doesn't work.

Edit:
BTW: Render is in another thread.

Quote from: texus on 07 December 2014, 14:09:27
This is a limitation in the way v0.6 works.
i don't use 0.7 because resource has to be loaded at widget creation instead of giving reference as in 0.6.6

texus

QuoteBTW: Render is in another thread.
That complicates things a lot of course.

Neither sfml or tgui is thread safe, so you are responsible on making sure that you aren't changing anything while rendering it.

Calling removeAllWidgets without a mutex could indeed make your screen blink, but calling any other function on a widget could also give a strange artifact on that widget in that frame.

Quotei don't use 0.7 because every single resource has to be loaded directly from disk instead of giving reference as in 0.6.6
Its perfectly ok to still use v0.6, the new version still has its limitations. But I didn't understand that line, 0.7 should be better in any way regarding loading widgets (it just doesn't support loading widgets from a text file yet like 0.6 does).

SDH

i didn't use mutex cuz i was waiting when game crashes or shows any artifact, in short i was reckless :D .

texus

I of course don't know how skilled you are (its hard to say based on a few post), but unless you know what you are doing: don't use multi-threading. Its very attractive because beginners think it will make their code run faster, but in reality you probably don't need this small improvement and it will only give you headaches. Once you start using mutexes everywhere, you basically fall back to the same speed as a single threaded program. So a multi-threaded program has to be very carefully designed.
My advice: think carefully about whether you really need a separate thread for rendering.

SDH


SDH

#11
Sorry for double post.

I've identified the problem why unique_ptr::~unique_ptr was not calling destructor, cuz they were not tagged as virtual :P :D

texus

QuoteSorry for double post.
There is no problem with double-posting. I actually prefer it over editing a post that you made hours earlier.

If you make a new post, I will get an email and read it. But I don't get a mail if you edit a post. If it's just a small edit or if the post was only a few minutes ago then editing is better, but if like in the other topic there is half a day between the post and the edit, then you should have made a new post instead.

I'm not strict with rules for editing or double posting, you should just do what you find best for that situation.

QuoteI've identified the problem why unique_ptr::~unique_ptr was not calling destructor, cuz they were not tagged as virtual :P :D
Damn virtual destructors in c++ :)
I can think of reasons why they don't do it, but it would be so much easier if they were virtual automatically once you inherit from the class :)