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

#376
The behavior is definitely inconsistent, but neither is really wrong.
Whether a widget should send out a signal when it is programmatically changed is debatable. On one hand, having setText send the TextChanged signal allows you to manually set a value which would be processed in the same way as what the user would have typed. On the other hand, if your TextChanged callback checks whether the text is valid or not and calls setText again when invalid, you probably wouldn't want that to trigger another callback.

I've discussed this topic with people in the past with CheckBox and in the end I removed the callback from the setChecked function. So it is possible that if I start looking into this, I would remove the callback from EditBox::setText instead of adding a callback in TextBox::setText.
#377
I've seen this error a couple times. Although I've never really found out the exact cause, it seems like some mismatch in libraries.
Make sure that the SFML version used by your project is the same as the one installed on your PC. Do you maybe have SFML installed from the package manager while also having another version on your PC? If you build SFML or TGUI yourself, did you install it by running "make install"?

Edit: Since this is about the gui-builder and not your own project, make sure SFML_DIR used when configuring TGUI points to the same SFML version than you have installed.
#378
Help requests / Re: CheckBoxRenderer
17 April 2020, 08:08:15
I should probably add the class to avoid confusion, but CheckBox just uses RadioButtonRenderer right now.
Code (cpp) Select
tgui::RadioButtonRenderer widgetRenderer{ theme->getRenderer("CheckBox") };

EDIT: tgui::CheckBoxRenderer has been added in the latest 0.8 version.
#379
Help requests / Re: Randering widgets update
08 April 2020, 18:13:07
No, but you decide for yourself when you update the canvas. The canvas only needs to be drawn on when its contents needs to change, but TGUI doesn't know when that is, it just keeps drawing the old content until you update the canvas.
#380
I don't really know CImg, but if the exception is coming from the sf::Image::create function then you may want to check what image_cimg.data() is returning.

According to the SFML documentation, the pixel data must be in 32-bits RGBA. This means that it will try to read 4*width*height bytes. Does image_cimg.size() return that amount? If not, then you should figure out how to get CImg to return the data in the correct format.

Alternatively, you can create the sf::Image without providing the pixel data and then use sf::Image::getPixelPtr and manually loop over the pixels from CImg and change them in the pixel data.

Either way, you need to understand exactly how the pixel data is formatted in your CImg image in order to figure out how to convert it to SFML (which stores the pixels as 4-byte RGBA values).
#381
Help requests / Re: Connect error
22 March 2020, 14:11:23
First of all, the only officially supported way to include TGUI is by including TGUI.hpp. If you chose to include other files directly then you are relying on implementation details and you could run into dependency issues like this.

The files have changed a lot, so I'm not sure if there still is a reason why it remains like this, but there are 2 reasons why the current design might have been chosen:
- To improve compilation speed. Lots of templates can slow down compilation, so it might be beneficial to only include them when needed instead of including them in a file that is included by practically every source file (like Widget.hpp). This of course only affects compiling TGUI itself as in your own code you need to include the signal header anyway, plus the performance difference might not be noticeable.
- To fix a circular dependency. Widget uses Signal, but Signal also uses Widget. Looking at the code, this doesn't seem to be an issue as SignalImpl uses shared_ptr<Widget> instead of Widget::Ptr, so that it doesn't need to include Widget.hpp. But it could have been the reason why the signal code was originally split into 2 files.
#382
Help requests / Re: Connect error
22 March 2020, 12:49:44
I would guess that SignalImpl.hpp isn't being included. Are you including TGUI.hpp or were you manually including other headers (in which case you also need to include SignalImpl.hpp)?
#383
You can have the last column fill the remaining space instead of manually setting the width (the configured width will be used as minimum column width, it could be set to 0 to make the minimum width of the column equal to the width of the "Value" string):
Code (cpp) Select
listView->setColumnWidth(0, window.getSize().x * 0.2f);
listView->setColumnWidth(1, 0);
listView->setExpandLastColumn(true);


Alternatively, you would have to manually subtract all pixels that are drawn next to your columns. Each column has an extra pixel next to it (the column separator). Even your last column has this, unless you set setExpandLastColumn to true. The default white theme also has a border of 1 pixel on each side. So the code you would need looks like this:
Code (cpp) Select
const double clientWidth = window.getSize().x - listView->getRenderer()->getBorders().getLeft() - listView->getRenderer()->getBorders().getRight();
listView->setColumnWidth(0, clientWidth * 0.2f - listView->getSeparatorWidth());
listView->setColumnWidth(1, clientWidth * 0.8f - listView->getSeparatorWidth());
#384
If the form is stored as a resource in the exe (which is Windows-specific) then you need to load it, get its contents in a string, put this string into an std::stringstream and pass this stringstream to gui.loadWidgetsFromFile.
You can't store your themes in resources without writing your own theme loader though, so you won't be able to easily put everything inside your exe.
#385
Help requests / Re: Highlighting Keywords
31 January 2020, 18:36:08
It's currently not possible to have multiple text colors on the same line. It also won't be added anywhere soon (unless someone were to contribute it).

Next time the signal system gets a rewrite I will try to implement a way to trigger signals from another widget, but it currently isn't possible. But can't you simply bind the same function for both the edit box and button?
Code (cpp) Select
void func()
{
  [If edit box contains something, add a line to chatbox]

  editBox-> setText("");
  editBox->setFocused(true); // In case the user clicked on the button
}

button->connect("pressed", &func);
editBox->connect("ReturnKeyPressed", &func);
#386
Help requests / Re: "Keyword list"
27 January 2020, 17:53:46
I haven't added it to the tutorial yet (I'll try to do so soon), but you can find the signal supported by each widget in the tgui::Signals namespace: https://tgui.eu/documentation/0.8/namespacetgui_1_1Signals.html
#387
Thanks for implementing this.
#388
It would indeed be useful. I'll add it to my todo list.
If you want it soon then you will have to implement it yourself though (the code is probably similar to DefaultText in EditBox).
#389
I have solved the issue now in the latest 0.8 version that you can download from github.

I don't know why it gives a linking error for this instead of a compile error, but I was just missing an "ostream" include.

The reason why my CI tests never failed was because I am doing a unity build to speed things up and it must have gotten the ostream include via another source file.
#390
The middle is passed as a (left, top, width, height) rect. If top is 0 and height is equal to the texture height then it splits the image in 3 parts. In this case the left and right parts will keep their ratio while the center part is stretched to fill the remaining of the area.
If the middle part doesn't has the same height as the texture and divides the image in 9 parts then 9-slice scaling is performed. The corners will not be scaled, the top and bottom bar will be stretched only horizontally, the left and right bars will only be stretched vertically and the center part is stretched to fill the remaining area.

The implementation itself is just a matter of creating triangles with the right texture coordinates.
#391
I test TGUI with a CI on mac and that build is still working: https://travis-ci.org/texus/TGUI/jobs/632626868
I'm not sure what the difference with your build is (and I don't have enough time to look at it right now), but maybe you can already check what you did differently which could narrow down the issue.

The String class is actually a class that shouldn't really have been added to 0.8. The file can't be removed, but almost none of these functions are used. So maybe you can also check if you can compile it if you put String.cpp#L2284-L2294 and String.hpp#L843-L844 in comments. I find it weird that it is giving a linking error for it though, that would imply that those operator<< functions are declared in the std headers but not in the standard library itself.

I'll try having a look at this tonight, but  I unfortunately no longer have a working mac VM to test on, so it might take a couple days before I can run tests here locally.
#392
Add the following to your derived class.
Code (cpp) Select
Signal onGropWidgetPress = {"GropWidgetPressed"};

Signal& getSignal(std::string signalName) override
{
    if (signalName == onGropWidgetPress.getName().toLower())
        return onGropWidgetPress;
    else
        return Group::getSignal(std::move(signalName));
}


In your code where you want the callback function to be called you call the emit function:
Code (cpp) Select
onGropWidgetPress.emit(this);
#393
I should probably add it to the onClose signal and at tgui::Signals::ChildWindow::Closed in the documentation. It seems like right now it is only mentioned at the destroy() function.

I wouldn't know which questions to best put in a FAQ. So far I only encountered a single question where I really felt that it belonged in a FAQ (because it was asked a few times already), but I didn't want to create a FAQ with only one question in it. Unfortunately I forgot where I wrote it down so I don't even know what that question was anymore :)
#394
This behavior is intentional, it allows you to block the closing of the window (e.g. to ask the user if he is certain that he wants to close it).
If the "closed" signal isn't connected then the window is destroyed when the close button is pressed, but if you connect to the signal then you have to destroy it yourself.
#395
Help requests / Re: Portability
08 December 2019, 20:12:39
Quotesfml-git package is not required by tgui-git
The tgui-git package requires "sfml" as a dependency, this can either be the actual "sfml" package or the "sfml-git" package. Either one has to be installed in order to install "tgui-git". If neither is installed, the "sfml" package will be installed as dependency when trying to install "tgui-git".

You should however not rely on "sfml-git" nor "tgui-git" at all for any project that you have to show somewhere else. Although it is unlikely to happen, the git version could be broken when I put a newer version online and make some mistake in the code. Although I will likely know about it as the CI will fail, there would be a period where the git version doesn't compile at all and you wouldn't be able to install your project at such time. The "sfml" and unofficial "tgui" packages would be a safer choice.

QuoteI don't have access as a user on that computer to install the dependencies
I'm not sure why you are mentioning the sfml-git and tgui-git packages, as I don't see how you would be able to use them in this case.

I have no experience with static linking on linux so I can't help you with that.
I have however been in the scenario where I needed to run a program on a pc without root access. The solution I used was to simply build the dependencies from source on the destination pc. This is of course only possible if gcc and cmake are preinstalled, but that was the case for me. Thinking about it now, I think that SFML was preinstalled, I only had to build TGUI which made the task significantly easier.

First of all you need to find out if you can build SFML on that computer. While TGUI only has SFML as a dependency, SFML has a lot of other dependencies that may not be preinstalled. If you can't build SFML from source (even dynamically) then you have to find another solution (it is possible to run a linux executable on a different pc than it was build on with some care, even when linking dynamically).

Assuming you can build SFML, and assuming you are using cmake for your own project, the easiest solution would probably be to include SFML and TGUI as subfolders to your project and build them together with your project. I haven't actually done this myself, but I know it can work (with some caveats as you will probable have to manually tell TGUI where to find SFML). This way your project can link to the SFML and TGUI targets that were just build and cmake hopefully takes care of finding the libraries even when dynamic linking. If not, you can either overwrite the linker search path when executing the program by setting some environment variable, or link the project with $ORIGIN in the rpath, but you will have to see when you get to this point.

If you get stuck somewhere I might be able to help further, but you may have to experiment a bit yourself first.
#396
HTML is rather complex and I'm not sure even a markdown renderer is in the scope of a gui library.

This request consists of 2 phases to me:
1) Create some kind of RichTextLabel that allows rendering text with different colors and text styles.
2) Implement an HTML or markdown widget that uses the RichTextLabel internally.

Although I would love to have both of these things in TGUI, it is very unlikely that the second phase will be implemented unless someone contributes it.
The RichTextLabel is something that is already on the TODO list, but it also shouldn't be expected anywhere soon.
#397
It's not easy to find, but there is a list of signals in the documentation. The available signals can be found under the Public Attributes section. There you can unfold the inherited properties to get a full list of all signals supported by the widget.

In TGUI 0.8.6 I also added a Signals namespace that can be used as alternative to using the strings. You can now use tgui::Signals::EditBox::ReturnKeyPressed instead of "ReturnKeyPressed", which means that auto-complete in an IDE might also give you a list of possible signals. The documentation of these structs also provide a list. I don't think the Signals namespace is mentioned in any tutorials yet, so it also easy to miss.

I always wanted to have a good overview of widgets somewhere, some place where it shows how every widget looks and what signals you can use etc, but I just don't have the time for it.
#398
EditBox also has signals that it inherits from the Widget base class, the "Unfocused" signal is one of them.

Both can be connected at once to the same function like this:
Code (cpp) Select
edit->connect({"ReturnKeyPressed", "Unfocused"}, []{ });
#399
QuoteI use references in function headers to avoid copies, but in combination with a foreign library i fail.
To keep it simple you can assume that Widget::Ptr is a Widget* (so if you copy it then you are just copying the pointer and not the actual widget), but to fully understand how it works you would need to understand std::shared_ptr because Widget::Ptr is just an alias for std::shared_ptr<Widget>.

QuoteI know its wrong what i did. (Although i dont know why. I just read that its wrong to have global variables)
There are 2 reasons why global variables are bad. The first one is mostly relevant to larger projects while the second one is typically only relevant for classes.

The first reason is simply because it can make the code harder to understand. Global variables can be changed from anywhere in your code, so it would be harder to follow where the value is changed throughout the code. This is why having "const" variables in global scope isn't a problem, it is only a problem with regular variables that can be changed.

The second reason is because there is no guaranteed order of construction and destruction of global variables across source files. If you have a global variables A and B then they are constructed in the order they appear in your cpp file, but if they appear in different cpp files then A could be constructed either before or after B. This is only a problem if you try to e.g. initialize A with the value of B.
SFML relies on some global variables to work, so if you create an sf::RenderWindow in global scope then it is possible that it crashes because the globals that sf::RenderWindow relies on aren't initialized yet when the window is created. It is also possible to get lucky and have the SFML globals initialized before your window in which case everything works fine, but that is not something you will want to rely on (although you will always get the exact same outcome as long as you don't change your linker settings).

So having a few integers in global scope isn't really a big issue when quickly writing a small piece of code.
#400
Actually putting those variables in the header isn't a good solution (I'm not even sure why it would work).
When I told you to use "=", I wasn't really looking at your code. The EraserON and Hue values probably still need to be passed as references to the lambda, by using "=" instead of "&" you are making copies of them and you would be changing a local variable inside the lambda instead of the variable that you had outside. You might want to look up how lambdas work, but the "=" and "&" are just the defaults for the variables. To pass some variables by value and some by reference you would do something like
Code (cpp) Select
slider->connect("ValueChanged", [&,slider]() { Hue = slider->getValue(); }); // All variables passed by reference except slider
or
Code (cpp) Select
slider->connect("ValueChanged", [=,&Hue]() { Hue = slider->getValue(); }); // All variables passed by value except Hue

QuoteWhen you choose a tool then the button stays pressed.
When u choose another tool then this button stays pressed and the previous goes back to unpressed.
I dont know if BitmapButton is the right choice here.
You might want to use RadioButton widgets for this. The downside is that the RadioButton places its text next to the image, so if you need text on top of the button then you would have to add a Label in front of it manually on which you call isIgnoringMouseEvents() to make sure clicks on the label are passed to the button instead of absorbed by the label. I'm not sure if there are better options, but if you don't need any text then what you need definitely sounds like how radio buttons work.