Main Menu
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - texus

#526
General Discussion / Re: TGUI and Unicode
07 May 2019, 22:30:39
TGUI uses sf::String on most places, which supports unicode, you just need to get the data into sf::String. If your data is UTF8 and stored in some array of "char" or "unsigned char", you should be able to use sf::String::fromUtf8(data.begin(), data.end()).

If you want to display special characters then you need to make sure to use a font that can render those characters. Maybe the default TGUI font can, but it is possible that it will just render squares in which case you need a different font.
#527
You can't access the same SFML or TGUI objects from multiple threads at the same time, it is up to you to do the synchronization. One way would be to use mutexes around the TGUI objects you access, but that will likely decrease performance as you would have to lock practically everywhere in the main thread (locks around both event handling and drawing and anywhere else where you access TGUI widgets). So the best way is probably to only let the main thread access TGUI and get your data to the main thread somehow. How to do this is of course not related to TGUI.

I don't have much experience with syncing between threads myself, other than on a windows-only project that uses the Windows functions like PostMessage, SetEvent and WaitForSingleObject.
A pure c++ alternative to SetEvent/WaitForSingleObject would probably be to have a mutex around a shared variable. Every frame (or every X milliseconds) you lock the mutex, check the variable and unlock the mutex again. In the other thread, when data is read from the card, it locks the mutex, writes the data in the variable and unlock the mutex again.
#528
QuoteI am bit confused by the tgui::Ptr's. They cannot be C++ class pointers, since I cannot do new/delete on them. But still, I have to use -> operator, not dot(.).
tgui::Widget::Ptr is simply a typedef for std::shared_ptr<tgui::Widget>. So they are pointers, but memory is managed automatically so you don't have to delete them.
In example code I always use e.g. tgui::Button::create() to create the widget, but std::make_shared<tgui::Button>() would work just as well (although the create function may take extra optional parameters and it is shorter to write).

QuoteI am worried to create memory/resource leaks.
Removing widgets from the Gui and releasing memory are 2 different things (although in many cases they happen at the same time). Because widgets are stored as shared_ptr objects, the memory is only released when all pointers to it are gone. The gui object has pointers to the widgets it contains (and the group has pointers to the child widgets inside the group) and you may store pointers to widgets in your own code. If you remove the group from the gui or destroy the entire gui, the widgets will automatically be destroyed with it unless you were still storing these widgets somewhere in your own code.

If you put one group in one gui then you indeed don't have to do setVisible(false) as you are destroying the group when destroying the gui. My suggestion was however to only have a single Gui object to which both groups are added. Then you have to hide one when showing the other or you will be seeing the widgets from both groups at the same time.
You can of course keep using a Gui per screen. The Gui was intended to be constructed only once per window, but currently creating a new Gui object probably takes less time than creating a widget, so there shouldn't be a problem with recreating it every time.
#529
If you really want then I could give you an example code that uses 2 windows (e.g. if you want to show the setup window while the main window is still displayed in the background), but creating a new sf::RenderWindow is always going to take some time (creating a new window is simply slow operation, it isn't related to SFML). Maybe if you make the window invisible instead of closing it, the second time you open the settings could be faster, but the first time will always be relatively slow.
I recommend doing it with just a single window and having only a single main loop.
#530
Is there anything that prevents you from just keeping the window and gui and just calling gui.removeAllWidgets() and adding the widgets for the next screen?
Multiple screens could be prepared upfront by creating a Group widget per screen (and adding the widgets to the group instead of to the gui). Then showing another screen is as simple as calling group1->setVisible(false); group2->setVisible(true);

Or maybe use a tgui::ChildWindow instead of an actual window?
#531
General Discussion / Re: Re-using RenderWindow
30 April 2019, 15:57:19
tgui::Gui just keeps a pointer to the RenderWindow, it will not destroy the window when the Gui gets destroyed. You only have to make sure not to call functions on the Gui object after the window it uses has been destroyed.

Why do you need a second sf::RenderWindow? Can't you just continue to use the existing window? If you really need a second window then you also need a second Gui that renders to that window.
#532
SFML_ROOT is for SFML < 2.5. You should pass -DSFML_DIR=... to cmake instead.
Maybe you could also try without having the dynamic libraries on your system and see what happens. Finding the dynamic libraries might be e.g. hide that it is looking in the wrong place.
#533
Help requests / Re: MessageBox how to use
26 April 2019, 18:56:33
The connectable signals of a widget are currently listed under "Public Attributes" in the documentation. E.g. for MessageBox: https://tgui.eu/documentation/0.8/classtgui_1_1MessageBox.html#pub-attribs
(I am aware that you might not search them there and that you have to know where to look before you can find them)

MessageBox has a "ButtonPressed" signal which has the text of the pressed button as optional parameter, so you would have something like this:
Code (cpp) Select
messageBox->connect("ButtonPressed", [&retVal](const std::string& button){
    if (button == "OK")
        retVal = 0;
    else if (button == "Cancel")
        retVal = 1;
});
#534
That option has to be set to FALSE, but it should be done in cmake (either by unchecking it in the gui or by specifying -DTGUI_SHARED_LIBS=FALSE at the command line). If that option is TRUE then you are building dynamic tgui libraries (which will obviously link to dynamic sfml libraries).
#535
How did you check which libraries TGUI depends on (to exclude that you are linking to the dynamic libraries yourself, and more importantly so that I can try it here)?

TGUI is supposed to always link in the same way as SFML unless you manually specify otherwise. Did you change some cmake flags? Are you adding defines other than SFML_STATIC in your project?
#536
The background color of all rendering is chosen in the window.clear() call. If you want a red background behind everything then you can just do window.clear(sf::Color::Red).
If the gui only fills part of the screen and you want to give it a different color then you can just add a Panel to the gui and add your widgets to the panel.
#537
You can use the get function which takes the name of the widget as parameter:
Code (cpp) Select
tgui::Widget::Ptr widget = gui.get("name"); // Without template you get the Widget base class (for when you don't need functions specific to the widget type)
tgui::Button::Ptr button = gui.get<tgui::Button>("name"); // With template you can get an object of the right type
#538
The merhaba function takes 2 parameter, neither of which the Button should provide (i.e. the last parameter isn't a string that should contain the caption of the button), so you have to provide both parameters to the connect function:
Code (cpp) Select
button->connect("pressed", &merhaba, std::ref(window), i);

The "i" value will however be copied, so the merhaba function will always be called with the same value.
If you want to get the value of the edit box at the moment you press the button then you should pass "yazialani" instead of "i" to the connect function (and change merhaba to take a tgui::EditBox::Ptr as second parameter) and put the "int i = std::atoi(yazialani->getText().toAnsiString().c_str());" at the start of the merhaba function.
#539
Feature requests / Re: Theme constructor
12 April 2019, 18:36:54
I'm the sole developer. Some people have contributed some pieces of code but most comes from just me.

Quotewe could prevent users to tamper with the theme
Personally I don't think we should prevent people from tampering with resources if they want to change things. But loading from memory can of course have its use cases other than preventing tampering so it might still a useful feature.

One problem with loading from memory is how to handle external resources. If you just want to load the theme file from memory and let the images still be loaded from files then it isn't difficult but you probably want textures to be loaded from memory as well. I'm not sure how that should be done.

Technically it is already possible with tgui to load themes without using filenames, but that is probably too much work to be useful. You could make a class that inherits from BaseThemeLoader (like the DefaultThemeLoader does) and call the static Theme::setThemeLoader function to change the loader. Then the THEME_BLACK could be defined as the string "1000" and the custom theme loader would implement a way to load the right theme based on that id.
But the way you load things from memory is probably too specific to your code to be used by others, otherwise someone would have to write it once and it could be shipped with TGUI as alternative to the DefaultThemeLoader.
#540
The Gui class and any container widget have a loadWidgetsFromFile function where you can pass the filename (and a loadWidgetsFromStream function in case you want to load it from memory).
#541
I didn't notice earlier that your last error was after the TGUI library was already build. Try disabling TGUI_BUILD_GUI_BUILDER when building TGUI. In the cmake gui uncheck the option or in the command line pass -DTGUI_BUILD_GUI_BUILDER=FALSE
This might be a problem with how the gui builder is linked.

Update:
I just tested it here and I also get these errors when TGUI_BUILD_GUI_BUILDER is on (default). I'll look into it.
Disabling the TGUI_BUILD_GUI_BUILDER fixes the issue.

Update 2:
I figured out why the gui-builder is giving these undefined reference errors.

SFML radically changed their cmake script in SFML 2.5 but in order to remain compatible with older SFML versions I added a compatibility layer. Since SFML_DIR is not defined, TGUI is using it's own way to find SFML which was apparently broken for static linking. This has now been fixed in the latest version on github.

However it turns out that if the compatibility layer isn't used (by setting SFML_DIR to /usr/local/lib/cmake/SFML/ or wherever SFML is installed), it will give undefined references to GLX functions instead. I had to manually link to GLX to build statically. This does look like an issue with SFML itself. I'll try to investigate it further in the next few days.
#542
QuoteI managed to install TGUI as Dynamic Library on my Raspberry PI 386 Debian Linux.
Did you encounter any issues in doing this? It's been a few years since I tested TGUI on a Respberry Pi, so I'm interested to hear whether or not it still works without manual changes.

QuoteIn the long run it creates a lot of support issues.
What kind of problems would you expect? I know it is possible to bundle the .so files with the application. It takes a lot of experimenting and you missed a file which causes it to break on newer linux systems several years later then you just need to ship that extra file. But I would consider the issues with .so files more on a short term, once you figure out how to do it properly it should continue to work on newer systems.

I've never build statically on linux so I can't help much. How did you get the other .a files? I'm not sure if they are all going to be compatible with each other when you download some random versions, but building them yourself is probably too difficult.

XRRQueryVersion and XRRGetScreenResources are part of the xrandr library. So maybe you have an incompatible libxrandr.a file or something?

I don't think this is specific to TGUI, if you reproduce it with only SFML then maybe you could ask it on their forum. Hopefully someone on the SFML forum would be able to help you further. You should try to make your own simple cmake project (which only uses SFML and not TGUI) and see if the issue still occurs, e.g. something like this:
Code (cmake) Select
cmake_minimum_required(VERSION 3.5)
project(CMake-test)

add_executable(Test main.cpp)

set(SFML_STATIC_LIBRARIES TRUE)
find_package(SFML 2 COMPONENTS graphics window system REQUIRED)
target_link_libraries(Test PRIVATE sfml-graphics)
#543
The parameters for generateRW don't match, in the connect function you pass one parameter too much, the m_ebChanceStartAlive.

The generateCA line looks fine, assuming the edit boxes are declared like this in the App class:
Code (cpp) Select
tgui::EditBox::Ptr m_ebNumSimulationSteps;

Can you show the full errors you get on the m_buttonGenerateCA->connect call?
#544
Can you show the declarations of generateRW, generateCA, instance and the other parameters you are passing?
#545
Help requests / Re: Grid
14 March 2019, 20:02:53
VerticalLayout spreads the entire height among all widgets inside it, in this case just the Grid. So the height of the VerticalLayout (100% of parent by default) will be passed to the Grid. So you can just limit the height of the vertical layout:
Code (cpp) Select
verticalLayout_->setSize("100%", 150);

But if you are only putting 1 widget in VerticalLayout then you don't need it and you can just add the Grid directly to the container and call that setSize function on the grid widget.
#546
Help requests / Re: Grid
14 March 2019, 19:35:02
All your images are wrong for that given code actually, including 5elm-5pr.jpg.
The VerticalLayout will tell the grid what it's size should be. When a Grid is given a size, it will rearrange the widgets to fill this space. This rearrangement was broken, which caused the weird results, but even with only one line there should be space between the widgets to fill the entire width.

6elm-5pr-without-verticallayout.jpg doesn't have any extra space between the widgets because it is auto-sizing (the size of the grid is determined by the widgets inside it, as the grid wasn't given a size).

In my opinion the result of your code should be similar to my attached screenshots. I didn't write the code that adds spaces between the widgets to fill the size though, so feel free to propose alternatives if you believe it should look different.

You can download the code with the fix in Grid on github.
#547
You should show the code you are using because it isn't the same as the example you quoted.
#548
Help requests / Re: ComboBox and State pattern
13 March 2019, 19:44:50
Using multiple Gui objects is not recommended at all, but I didn't fully understand what you meant and I was thinking the issue had to do with how events were sent.

I don't think it was possible yet to select a different item by holding the mouse in ListBox (which ComboBox uses internally) when the code was originally written like this in ComboBox. So this issue only appeared after an "unrelated" change in ListBox.

I've looked at how combo boxes work on my linux and a windows pc and they indeed only changes the value when the mouse is released. So I have updated my code to do the same. You can find the new version on github.
#549
Help requests / Re: ComboBox and State pattern
12 March 2019, 18:57:58
Are you using a separate Gui instance for A and B states?
If so then you should instead use the same Gui for both states and just put each state in a separate Group widget. When changing state you just have to show one group and hide the other.
Otherwise you should provide some simple example code that I can test here to get a better idea of what you are doing.
#550
The top example in your image would be harder to implement as it requires being able to set a different color for each item.
The bottom example can be implemented by just adding a default text. When the port becomes unavailable you just have to deselect the item, remove it from the list and set the default text.

So if it is enough for you then I'll just add a DefaultText property to ComboBox and a DefaultTextColor property to ComboBoxRenderer.

Edit: the default text was added to ComboBox (in the version that can be downloaded on github)