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

#1
You will need the touch events that you get directly from SFML in your main loop for this.

I could maybe add a new event, something like a PinchZoom event, which works similarly to mouse wheel scrolling (i.e. has one + or - parameter with a relative value since the last position). I'm however uncertain how to properly detect a pinch zoom, and I'm not sure what the value should even be. As soon as you put 2 fingers down, TGUI will currently already think that you are scrolling with two fingers (which is an assumption I could only make because no other gestures were supported). So adding the event (which I'd be willing to do), is the least amount of work. Getting both zooming and scrolling with two fingers to behave well would be a lot harder (and not something that I'm currently willing to do).
#2
You are defining SMFL_STATIC (which even has a typo) and TGUI_STATIC, but you are linking to the dynamic libraries (i.e. the ones that don't end have "-s" in the name). So you should remove SMFL_STATIC and TGUI_STATIC from the PreprocessorDefinitions.
#3
I'm assuming you would also get a linking error when using e.g. tgui::Color::Black in your code?

While I haven't seen this issue with TGUI yet, I remember seeing similar issues before with SFML (where people got linking errors only for the "static" variables). I think the cause might have been mixing libraries like shared vs static ones.

Can you maybe share the .vcxproj file of your project so that I can check if I can see something unusual about it?
#4
My first instinct was to just render with both versions of the code and see which one looked correct, so that I didn't have to bother with understanding the math again, but I couldn't visually tell the difference between both variants :)

I think my code is correct though.

Let's examine the bottom left corner. The first point needs to be at the leftmost position (as it is connected by a vertical line from the last point of the top-left corner), while the last point needs to be at the bottom-most position (as it needs to be connected with a horizontal line to the first point of the bottom-right corner).
So when you plug in i=0 in the formula, you need to get a cos value of -1 and a sin value of 0. When you set i=nrCornerPoints-1 (the last iteration of the for loop), the cos value should be 0 and the sin value should be -1. I verified with WolframAlpha that this is the case when using my formula.

The thing that makes it weird is probably that when drawing a circle (instead of a rounded rectangle), the top, right, bottom and left points on the circle are duplicated. There is also the fact that the "nrPointsInCircle" might be a bad name. There are "4 * nrCornerPoints" points in total, but "nrPointsInCircle" is set to "4 * (nrCornerPoints - 1)" (the amount of unique points when drawing a circle instead of a rounded rectangle).
#5
Help requests / Re: ChildWindow
16 November 2023, 18:55:43
Thanks for the detailed description and sample code, I was able to quickly track down the bug in TGUI. There is a branch in setPosition that doesn't actually set any position (when KeepInParent is true and the provided position isn't outside the parent).

A workaround would be to call setKeepInParent(false) right before you call setPosition.

The issue has now been fixed in the latest development version.

QuoteUsing separated lambdas for each button which are not aware of status of the seconds is not ideal. Is there another way to do it?
You can move the state outside the lambda and let the lambda functions take a reference to it. Your lambda already starts with "[&]", so it already has access to all variables outside it by reference. You just have to be careful that the referenced parameter doesn't go out of scope and gets destroyed before the lambda is called.

Code (cpp) Select
bool maximized = false;
bool minimized = false

childWindow->onMaximize([&](){
    // You can use 'minimized' here as well.
    // Make sure to remove the "static bool maximized (false);" line from this lambda
});

childWindow->onMinimize([&](){
    // You can use 'maximized' here as well.
    // Make sure to remove the "static bool minimized (false);" line from this lambda
});

You can do the same for the other static variables.
#6
Help requests / Re: Texture class
15 November 2023, 21:37:19
Correct.

The reason why this change was made is because a copy was always being made before as well, the constructor overload that accepted an sf::Texture object is calling the slow copyToImage function internally. The deprecation makes it a lot more clear that this method shouldn't be used.

TGUI requires ownership of the sf::Texture, so you can't load one in your own code and then share it with TGUI.

If you load a tgui::Texture with a filename, TGUI's internal texture manager will already handle sharing the image between all tgui::Texture objects that were loaded with the same filename (and the image will be released once there are no more tgui::Texture objects with that image).
#7
TGUI can't update the width or height of a widget separately, it always goes through the setSize function that updates both. If the height depends on the width or vice versa, then the setSize function will be called multiple times recursively. I have updated the Layout class to only trigger once the recursion reaches 5 to 10 levels deep, so it should no longer trigger on this case.
#8
Help requests / Re: behavior on phone
08 October 2023, 14:37:08
The isDraggableWidget() function was removed. The return value of leftMousePressed was changed to bool, if it returns true then the event is a drag (and your code should do what it previously did if isDraggableWidget() returned true).

This is the information I posted about the change on Discord at the time, it contains most information you need to know:
QuoteThe way draggable widgets are implemented has been changed. No functionality was changed, so if you didn't write custom widgets then you don't need to care.

Draggable widgets are widgets that still receive mouse move events even when the mouse is no longer on top of them. For example, once you start dragging the thumb of a scrollbar, you can move the mouse outside the scrollbar and the thumb will continue to move up and down with the mouse.

Previously all widgets that needed such behavior would set a boolean flag in their constructor. Due to the way it was implemented, Container and all classes inheriting from it needed to be draggable as well. Custom widgets inheriting from SubwidgetContainer would act as draggable widgets (i.e. they receive no onMouseLeave callback while the left mouse button is pressed), whether they wanted this or not. In the new implementation, leftMousePressed will return a boolean based on whether the click initiated a potention drag or not.

Several breaking API changes were made to the Widget base class:
- isDraggableWidget() function and m_draggableWidget member have been removed
- Return type of leftMousePressed was changed from void to bool. True may be returned by draggable widgets, all other widgets will always return false.
- mousePressed function was removed (the function only existed for backwards-compatibility anyway, it called either leftMousePressed or rightMousePressed depending on the mouse button)
#9
It's possible that the cycle detection is a bit too strict. The group depends on the height of the last widget, so it depends on the size of the last widget. And the last widget depends on the width of the group, so it depends on the size of the group. A cyclic dependency is seen on the size, even though there is no cycle on either width or height alone.

The code used to crash when you created a cycle, the detection was added to stop the endless loop that caused the stack overflow to allow the program to still continue instead of crashing. But maybe the detection is triggering too early in this complex case and it wouldn't have crashed if the detection code is removed.

I'm not sure how to best fix this though, the initial detection code is already with more overhead than I'd like, so I'm not looking forward to adding even more complexity to it. And just removing the detection and causing hard to debug crashes again isn't a great option either. So I'll see if I can still find something to improve the situation (maybe replace the bool flag with an int counter and only show the error once you are several layers deep in the recursion).

The thing that I don't understand though is why you would only have an issue with m_timeProgressBar. I already have a cyclic dependency on the "m_group->setSize("25%", tgui::bindBottom(lastPtr)+tgui::bindWidth(m_group)*padding);" if I just create the "test" progressbar. I didn't even add the TimeProgressBar yet.

EDIT: The detection is definitely broken, I already get the dependency cycle just from doing "m_group->setSize(250, tgui::bindWidth(m_group) + tgui::bindWidth(m_group));". So it might just not like the same layout from being evaluated multiple times within the same chain.
#10
How are you setting the size and position of the label? Does either the position or size of m_label depend on m_timeProgressBar in any way?
If m_label has a fixed position and size then this warning shouldn't happen.
#11
Help requests / Re: bindParentSize ?
07 October 2023, 18:49:57
The bind functions require you to know the widget, but you can do it when the layout is a string because that gets parsed again after the widget is added to a parent.

So something like this should work:
Code (cpp) Select
ptr->setSize("min(parent.width, parent.height)*0.16", "min(parent.width, parent.height)*0.16");
#12
Help requests / Re: Strange crash since new build
04 October 2023, 22:08:38
This looks like a bug in TGUI. I'm assuming either launchAllLoading or launchSceneBase causes the focused widget to change. Your callback function gets called at the "m_focusedWidget->keyPressed" line, and probably does something that sets m_focusedWidget to a nullptr. After that, the "m_focusedWidget->canHandleKeyPress" line gets executed, but by that time m_focusedWidget is a nullptr.

So I need to add another check inbetween the keyPressed and canHandleKeyPress line to deal with this case.
Update: The issue has been fixed in the latest version.
#13
I've updated the CanvasSFML class to no longer copy the sf::Texture. This should provide better performance. With some luck it might even affect the upside-down issue.

In the SFML code, I can see a bug in the OpenGL ES implementation when copying the texture (or at least something that looks like a bug on first sight). In GLES, Texture::update is implemented by calling copyToImage() (which is very slow), and in Texture::copyToImage() the m_pixelsFlipped variable isn't accessed if SFML_OPENGL_ES is defined while it is being used when GLES isn't used (i.e. on desktop). So it looks to me like the GLES implementation doesn't properly flip the pixels.

This however doesn't explain the github issue, which has a flipped texture even without any copies. So maybe the issue is still somewhere else. I might look further into the SFML issue later, but that will require some testing with Android so it might take some time.

EDIT: The github issue does contain a copy of sf::Texture, so that is where the issue lies. I tried rendering an sf::RenderTexture on Android without copying the texture and that image indeed isn't flipped.
#14
Are you certain that it works with just SFML? Can you try the code from https://github.com/SFML/SFML/issues/2419 ?
#15
Resizing the canvas will call "renderTexture.create(newSize)", while "clear", "draw" and "display" are just forwarded to the renderTexture.

The only thing that could be different with using SFML directly is that in order to render the canvas contents to the screen I just access "renderTexture.getTexture()" and render that texture. So maybe that texture is still flipped on Android (i.e. when using OpenGL ES instead of when using desktop OpenGL). I'll try to check that later.

Performance-wise, the slowdown is probably me copying the sf::Texture (that I get with the "renderTexture.getTexture()" call), in the display() function, to a different location so that it works together with the other rendering code.