Converting TGUI 0.6 project to TGUI 0.8.5

Started by Hexile, 11 August 2019, 04:14:03

Hexile

So a while back I was working on something using TGUI 0.6 and now i'd like to move onto TGUI 0.8 only grabbing the basic import and event setup.

However, as there is still documentation missing. I'm not sure how to do this.

Should i really go back to 0.6 ?  :-\

i've attached the source of the old project after removing parts that were too similar.

texus

You would basically just have to read the 0.8 tutorials and relearn how widgets are created now and rewrite the code that deals with the gui.
If you don't want to rewrite your code then you will have to stick with 0.6, there have been 4 active years between those two version so a lot has changed (with most of the changes between 0.6 and 0.7).

Looking at the code you basically need the following changes:

Lines like
Code (cpp) Select
tgui::Checkbox::Ptr syncbox(gui);
basically have to be changed to
Code (cpp) Select
tgui::Checkbox::Ptr syncbox = tgui::Checkbox::create();  // You could use "auto" as type here, to not write "Checkbox" twice
gui.add(syncbox);


In 0.6 I think you still had to have a theme to render something, since 0.7 there actually is a default White theme that gets used if you don't set any theme. I'll just assume you want to keep using the Black theme. You will have to change THEME_CONFIG_FILE to "data/themes/Black.txt" as that is where the new Black theme would be located.

For the Black theme you will have to create a Theme object somewhere. Assuming you only use a single theme you can set it as a default as well. The "theme" object has to remain alive, if the variable is destructed (e.g. when it goes out of scope) then the built-in White theme will automatically be used again.
Code (cpp) Select
tgui::Theme theme{THEME_CONFIG_FILE};
tgui::Theme::setDefault(&theme);

If you have a default theme that you want to use then you can just remove lines like
Code (cpp) Select
syncbox->load(THEME_CONFIG_FILE);
If you don't have a default theme, then you need to replace the lines with something like
Code (cpp) Select
syncbox->setRenderer(theme.getRenderer("CheckBox"));

The biggest difference is probably going to be the callback code. TGUI 0.6 queued callbacks and let you get them later with pollCallback. (This code is so old that I had already forgotten that it used to work like that). Since TGUI 0.7 the callbacks are like interrupts, your callback function will be called immediately. You should definitely read the signal tutorial.
How you need to change the code depends on the structure of your code. If your code is really all in one big main function, then you should actually be able to port it without too much changes.
Code (cpp) Select
knob1->bindCallback(tgui::Knob::ValueChanged);
knob1->setCallbackId(Knob_CALLBACK_ID + 1);

and
Code (cpp) Select
case Knob_CALLBACK_ID + 1:
{
[...]
break;
}

would become
Code (cpp) Select
knob1->connect("ValueChanged", [&]{
    [...]
});


Those are just the differences that I saw when scrolling to the code. It is possible that there are other differences, but the biggest changes happened in the way widgets are created and their events. The functions of the widgets themselves (e.g. setPosition, addItem, setSelectedItem, etc.) will mostly be compatible.

Hexile

#2
So i let the project rest for a while and I'm having this issue when trying to compile:
defaulted default constructor cannot be constexpr because the corresponding implicitly declared default constructor would not be constexpr
in:
\TGUI-0.8.5\include\TGUI\Vector2f.hpp Line:44   
\TGUI-0.8.5\include\TGUI\AbsoluteOrRelativeValue.hpp Line:177   

Additionally, there is a warning:
Avoid unnamed objects with custom construction and destruction (es.84).
in: \TGUI-0.8.5\include\TGUI\to_string.hpp Line:40

And when AbsoluteOrRelative.hpp is examined, there is an another error on line 177 in to_string.hpp:
constexpr constructor calls non-constexpr function "tgui::AbsoluteOrRelativeValue::AbsoluteOrRelativeValue()"

This is on Visual Studio 2019 (not VScode)

texus

#3
I'm not sure what the problem is, it works here on VS2019 v16.2.3
Are you using the v142 platform toolset (can be seen in project properties)?

The warning in to_string.hpp is harmless.

Edit: I've found a bug report for VS, but it should have been fixed in VS2017 already (https://developercommunity.visualstudio.com/content/problem/203575/constexpr-default-constructor.html)

Hexile

* using build tools v142
* 16.2.5 after updating

The warning is gone, but the 3 errors remain.

Could it be because i'm using the windows 8.1 as my target platform?

texus

How do you change the target platform? Maybe I can try that here too. Although I don't think it should make a difference.

Could you send me the vcxproj file so that I can check if the settings match mine?

You could check if the errors are gone if you replace "= default;" with "{}"

Hexile

well, first off you need the windows 8.1 sdk, then you can try changing it in

Project Properties -> General -> Windows SDK Version

I tried to switch to windows 10 sdk, but it didn't change anything.

texus

Does it still give the error you just have an empty cpp file (that includes TGUI of course)? I really can't figure out why it won't work. I updated to VS v16.2.5 as well and downgraded TGUI to 0.8.5 and it just keeps working here. I didn't try changing the SDK version but that shouldn't be needed as it doesn't work with the windows 10 sdk for you either.

You should try my earlier suggestion of replacing "= default;" with "{}" in those 2 headers and let me know if that fixes it.

Hexile

i tried to compile this as a new project and i get the same issue;
https://tgui.eu/examples/0.8/many-different-widgets/

if i alter TGUI like you suggested, the compiler makes a silent crash while building and Visual Studio doesn't catch it  :(

texus

Maybe you should try reinstalling the compiler and maybe even visual studio? Having the compiler crash isn't normal.
Instead of replacing the "= default" you could also try to remove the "TGUI_CONSTEXPR" from those lines.

Hexile

#10
Quote from: texus on 15 September 2019, 18:06:16Instead of replacing the "= default" you could also try to remove the "TGUI_CONSTEXPR" from those lines.

No difference.

QuoteMaybe you should try reinstalling the compiler and maybe even visual studio? Having the compiler crash isn't normal.

Actually. i had accidentally changed something so only intellisense things would be shown and there was a path issue with the linker. Once resolved, the example compiled just fine.



So going back to my project, cleaning it and then trying to compile yielded some more errors:

Quoteuse of undefined type 'tgui::internal_signal::func_traits<void,std::reference_wrapper<tgui::Gui>,void (__cdecl &)(tgui::Gui &,tgui::Knob::Ptr,tgui::Scrollbar::Ptr,tgui::Label::Ptr,int,bool),tgui::Knob::Ptr &,tgui::Scrollbar::Ptr &,tgui::Label::Ptr &,int,bool>'

'unsigned int tgui::Signal::connect(const tgui::Signal::DelegateEx &)': cannot convert argument 1 from 'std::_Binder<std::_Unforced,tgui::Signal &,_Ty,void (__cdecl &)(tgui::Gui &,tgui::Knob::Ptr,tgui::Scrollbar::Ptr,tgui::Label::Ptr,int,bool),tgui::Knob::Ptr &,tgui::Scrollbar::Ptr &,tgui::Label::Ptr &,int,bool>' to 'const tgui::Signal::Delegate &'
        with
        [
            _Ty=std::reference_wrapper<tgui::Gui>
        ]

'id': an object of const-qualified type must be initialized   SystemCrashMP   C:\Users\ExileFox\Documents\projects\Project1\TGUI-0.8.5\include\TGUI\SignalImpl.hpp

use of undefined type 'tgui::internal_signal::func_traits<void,std::reference_wrapper<tgui::Gui>,void (__cdecl &)(tgui::Gui &,tgui::Knob::Ptr,tgui::Scrollbar::Ptr,tgui::Label::Ptr,int,bool),tgui::Knob::Ptr &,tgui::Scrollbar::Ptr &,tgui::Label::Ptr &,unsigned int,bool>'

'unsigned int tgui::Signal::connect(const tgui::Signal::DelegateEx &)': cannot convert argument 1 from 'std::_Binder<std::_Unforced,tgui::Signal &,_Ty,void (__cdecl &)(tgui::Gui &,tgui::Knob::Ptr,tgui::Scrollbar::Ptr,tgui::Label::Ptr,int,bool),tgui::Knob::Ptr &,tgui::Scrollbar::Ptr &,tgui::Label::Ptr &,unsigned int,bool>' to 'const tgui::Signal::Delegate &'
        with
        [
            _Ty=std::reference_wrapper<tgui::Gui>
        ]

File: \TGUI-0.8.5\include\TGUI\SignalImpl.hpp Line: 347


I think i'll reinstall visual studio as a next step as this just seems like another red herring.

texus

Th error mentions "std::_Binder", are you by any chance passing a parameter with std::bind to the connect function? TGUI 0.8.5 doesn't support that yet, so if you are using std::bind then that could be the cause for the error. The TGUI version on github does support std::bind.

Hexile

not bind, but std::ref like mentioned in the 0.8 tutorials.

After poking cmake with a stick i could get the sln file and compile tgui from github. the errors have been sorted out. Though i think i misunderstood something as my application is crashing when setting up a "signal"

listBox->connect( "clicked", PlaylistClicked, std::ref( gui ), listBox->getSelectedItemIndex(), listBox->getSelectedItemId(), listBox->getSelectedItem() );

void PlaylistClicked( tgui::Gui& gui, int selectItem, sf::String str_ItemId, sf::String str_ItemText ) { std::cout << "Playlist Clicked\n"; }

texus

std::ref doesn't cause any issues, it is only with std::bind where you need to either change your code or update to the github version.

The code isn't really crashing, it is throwing a tgui::Exception that you don't catch which tells you that there is no "clicked" event in ListBox.

Also, these bound parameters might not do what you want it to do. You are getting the selected item at the time of calling the connect function, so when the callback happens these parameters will always be the same. You should just leave a parameter unbound if you want TGUI to fill it in with the actually selected item.
Code (cpp) Select
void PlaylistClicked1(tgui::Gui& gui, int selectItem) { } // Only supported with version from github
void PlaylistClicked2(tgui::Gui& gui, sf::String str_ItemText) { }
void PlaylistClicked3(tgui::Gui& gui, sf::String str_ItemText, sf::String str_ItemId) { }
listBox->connect("ItemSelected", PlaylistClicked1, std::ref(gui));
listBox->connect("ItemSelected", PlaylistClicked2, std::ref(gui));
listBox->connect("ItemSelected", PlaylistClicked3, std::ref(gui));


In the github version you can replace "ItemSelected" with tgui::Signals::ListBox::ItemSelected. With autocomplete, this way you could get hints about what signals exist.