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

#91
Help requests / Re: behavior on phone
05 March 2023, 15:23:01
TGUI isn't optimized for touch devices at all. While it can be used on Android and iOS, it provides you with the same behavior as on a desktop. Touch events are supported, but they are internally translated to mouse events before being passed to the widgets.

SFML also provides limited support for Android and iOS.
First of all you will need to use the 2.6.x branch, as Android support in SFML 2.5.1 is pretty broken.
Secondly, there is a serious limitation with the SFML backend related to the software keyboard. Touching an edit box will bring up the software keyboard on your phone/tablet, but the OS has no idea where the edit box is located on your screen. So the keyboard can appear on top of the edit box and hide it. When using the SDL_RENDERER backend, TGUI has the ability to tell SDL where the edit box is placed, and the view will automatically be shifted to keep the edit box visible while typing.

Quote- Do TGUI have differents behavior with some events, due the usage of fingers ? For example onHover event
Everything is the same except for touch events, which work like this:
- Any fingers other than the first one are ignored.
- The finger down event is translated to a MousePressed event (and a MouseMove event that is send right before the MousePressed event is send).
- While the finger is down, finger motion events are translated to a MouseMoved events.
- The finger up event in translated to a MouseReleased event.

Quote- How scrolling is handled ? Do we need to pinch two fingers or there is something else ?
Quote- With scrollPanel, can we drag finger anywhere on the panel to move it or do we must drag only the bar ? If only the bar, what is the best way to have the first behavior ?
You have to use the scrollbar.

Using only one finger to drag the panel could probably be implemented relatively easily, but it wouldn't work when the finger goes down on top of a widget inside the panel (e.g. press and drag in edit box would start selecting text instead of scrolling the panel).

I'm not sure what can be done to get two finger scrolling working. Manually examining touch events to extract gestures doesn't sound easy. Apparently SDL has a SDL_MultiGesture event for this which I could in theory translate to a scroll event when two fingers are used (but doing so might not be as straightforward as it sounds). That won't help you when using SFML though, as it has no support for touch gestures at all (it just provides you with information about which finger is located where).
#92
Help requests / Re: SpriteSheet in v1.0
04 March 2023, 10:56:33
setVisibleRect isn't what you need. It was added to the sprite just for being able to partially display the loading bar image, it effectively clips part of your sprite (so the size of the sprite would still be the entire loading bar while only part of the bar is shown).

Sprites and textures do work a bit differently in TGUI than in other libraries. I think originally the current Sprite and Texture classes were even a single class.
A sprite always shows the entire texture.
A texture on the other hand may contain only part of an image.

What you need to do is load multiple Texture objects, with the same filename, but with different partRect parameters.
That may sound very inefficient, but it works because TGUI will internally reuse the texture when loading the same filename multiple times. So you would end up with only one internal sf::Texture (containing the full 2000x2000 image), and multiple tgui::Texture objects that refer to (part of) the same resource.

All rectangles used by sprites and textures use pixel ranges.
If your image is 2000x2000, the PartRect of your Texture is (0,0,50,50) and the sprite size is 100x100 then the top 50x50 part of your image will be 2x scaled and shown as 100x100 on your screen.
#93
I would just recommend copying the code from the Tabs class and editing that copy.

You could technically inherit from Tabs, but then you would need to store a list of images that has the same length as the list of tabs. So every function that adds or removes a tab needs to be overridden in your new class (and these functions aren't virtual, so you need to understand the limitations of doing this and watch out for them).
#94
Help requests / Re: ToolTip on click
14 February 2023, 18:32:12
setToolTip is used to tell the Gui that the widget has a tool tip, so that it can be shown when the mouse stands still on the widget for a while. Calling setToolTip won't actually display anything.

You could call tgui::ToolTip::setInitialDelay(0) at the beginning of your code to make tool tips appear without a timeout, but I'm not certain if it will work because tool tip might be suppressed while the mouse button is down.

I suggest you show the bubble manually, instead of the existing tool tip system, because what you want is different from how tool tips typically work. Something like the following:
- When you press the mouse button, set the position of the bubble and call "getParent()->add(bubble)"
- When you receive a mouse release event, call "getParent()->remove(bubble)"
- In your constructor, set m_draggableWidget to true so that your widget keeps receiving mouse move events while the mouse is pressed, even when the bubble is below the mouse.
- Optionally move the bubble on mouse move events while m_mouseDown is true
#95
Feature requests / Re: Menu with checks/checkbox
30 January 2023, 18:25:24
It's a feature that I also want in the future, but it isn't supported currently.

You might be able to hack it together yourself by altering the text:
addMenuItem(U"\u2610 Unchecked")
addMenuItem(U"\u2611 Checked")
addMenuItem(U"    Normal")

And then use changeMenuItem later to alter the first part when checking/unchecking.
#96
Help requests / Re: Tree View Tutorials?
17 January 2023, 08:15:02
There are no examples in the documentation or tutorials yet. A hidden example can be found in the tests: https://github.com/texus/TGUI/blob/0.10/tests/Widgets/TreeView.cpp#L372-L378

So you have to add 2 items: {"Object", "Subobject"} and {"Object", "Subobject2"}
#97
Most functionality about how a widget looks is now part of the renderer (which can be accessed with "getRenderer()"). So you can change it with "panel->getRenderer()->setBackgroundColor(...)"
#98
In the latest TGUI 0.10-dev version the handleEvent function will now return true when scrolling while on top of a widget.
#99
I never thought about that case before, for that use case the old behavior indeed worked a lot better.

I've looked at the behavior in Firefox again on both Windows and Linux and this is what I intend to implement for nested scrolling now:
- When you start scrolling, a panel remembers which widget is getting the scroll events and "locks" it.
- Any scroll events that occur while a widget is locked will be passed to the locked widget instead of the widget below the mouse.
- If no scrollbar has moved for one second, the scrollbars are unlocked. (The time seems much longer than 1s in Firefox, but I'm going to start with just one second in TGUI and determine if it needs to be changed later)
- If a mouse move event is received, the scrollbars are unlocked.

While that would fix nested scrollbars, it might not yet solve your situation. For your case there are several options:
1) Do nothing. Right now the behavior is a big problem for you because the view changes immediately when the scrollbar reaches the tip. If I implement the locking, the scroll event will be absorbed for a second (and handleEvent will still return true for scroll events that happen immediately after the scrollbar reached the tip). If the scrollbar is already at the tip, and the user then moves its mouse on top of the panel and starts scrolling, is it really an issue if it zooms your view? If so, then I will need to implement one of the other options.
2) Make handleEvent always return true for mouse wheel events when the mouse is on top of a TGUI widget. This is probably easy to implement and probably works well for most people. But it would also absorb scroll events when the mouse is e.g. on top of a button or a non-scrollable panel. If this becomes a problem for other people then I could add a boolean in the gui to decide on what behavior to use.
3) Adding a boolean to the ScrollablePanel to make it absorb all scroll events. I don't like this option simply because ScrollablePanel isn't the only widget that can handle scroll events, I would need to do the same for widgets like Label and TextArea as well.

So if you need the behavior then I will implement the second option, otherwise I will go with the first option and only fix the scrolling that occurs directly after the scrollbar reaches the tip.
#100
Creating a custom widget that inherits from ScrollablePanel and overrides the mouseWheelScrolled would be an option, but I feel like this is a behavior that can still be improved in TGUI itself (e.g. by adding a boolean flag to the widget to allow you to choose the behavior).

The behavior of passing the scroll event to the parent is actually rather new, it was only added 4 months ago and I knew someone was going to ask for a different behavior at some point (and I decided to wait with "fixing" this issue until someone actually needed a fix).

There are two behaviors that are easy to implement, and I like neither of them:
- Absorb all scroll events. You won't be able to scroll the outer scrollbar while the mouse is on top of the scrollable panel. This is what you are asking and this is the old behavior. I've worked with interfaces that work like that and I really disliked it: you can get into situations where you are scrolling the outer panel and suddenly the scrolling stops because your mouse is now on top of another panel and you have to move the mouse to continue scrolling.
- Pass event to parent when the panel can't scroll any further. This is the current behavior. The big downside is that you practically always end up scrolling too far and end up scrolling the outer panel while you just wanted to go to the end of the inner panel.

I've looked at how this is handled in other applications when I changed the code 4 months ago. What is typically done, and what I consider the correct/best behavior, is too not pass any events to the parent for a short time after scrolling. When the scrollbar reaches the end of the inner panel and you keep scrolling, nothing happens. But if you stop for a second and then start scrolling, the outer panel will scroll even when the mouse is still located on top of the inner panel. This is unfortunately harder to implement.

Which brings me to my question: do you really want to fully disable scrolling of the outer panel while the mouse is on top of the inner panel? Or would it also work for your use case if the events where only suppressed for a short time after scrolling the inner panel?
#101
The issue has been fixed (github commit).
Your code should work now with the latest 1.0-dev version.
#102
I figured out what is going on, but I will look into the details and check if I can do something against this tomorrow.

ScrollablePanel::setSize is looping over its bound layouts to update them. This is where your ItemContainerWidget::setSize function is called. Here you call "newSize = size" which copies the layout. During the copy, the layout registers itself to ScrollablePanel. The problem is that ScrollablePanel is still looping over the list of bound layouts, which is now being changed. This causes it to get corrupted and crash.

So for now its forbidden to copy the layout (i.e. the "size" variable) inside the setSize function.
#103
I can reproduce it here consistently, it happens immediately when I resize the window.
On first sight this looks like a bug in TGUI itself, it looks like the layout somehow gets corrupted, it doesn't look like a recursion issue.

It only crashes when copying "size" to the "newSize" variable (even if you don't change newSize.x) and only when the size contains a math operation (i.e. binding just the height of scrollable panel works, but when subtracting a constant from it such as the scrollbar width causes it to fail). So my guess is that it triggers some edge case in the layout system.

I will investigate this further and try to figure out where the crash is coming from tomorrow. Thanks for providing the simple code example that allowed me to quickly reproduce the issue.

While testing I did find another unrelated crash:
If you make your window too small, the size becomes negative (because the scrollable window height is less than the scrollbar height). In this case you call text.setCharacterSize with a negative number, which becomes a very large number because the character size is unsigned. This causes TGUI to crash while loading the font glyph to figure out the size of the text.
#104
Quotethe fact that I change the size before passing it to Widget::setSize could be the problem
No. I saw you were doing that earlier, but there is no reason why it wouldn't work.

QuoteHow it is managed with Label and its auto size feature ?
As long as you don't call setSize on the label, changing the text will trigger an update to the size at src/Widgets/Label.cpp#L699
So no layouts are used for the auto-sizing, it just recalculates the size each time the text is updated.
#105
m_boundSizeLayouts being endless might imply data corruption. If somehow a callback gets triggered to a widget that no longer exists, then m_boundSizeLayouts would contain garbage and it could crash there. But I guess there are probably ways to get stuck there without corruption as well.

The parent size is changed first. The order of events is as follows:
- You resize the window
- The gui view is updates, which updates the size of the RootContainer (which is the part of the Gui to which all widgets are added)
- m_scrollPanel's size is part of the m_boundSizeLayouts of the RootContainer (because you called m_scrollPanel->setSize("100%", "20%")), so RootContainer::setSize calls recalculateValue which calls ScrollablePanel::setSize
- ScrollablePanel::setSize will call Widget::setSize to begin applying its size
- The layout of itemContainerW is bound to ScrollablePanel, so this will call ItemContainerWidget::setSize (via the recalculateValue call again).
- Your ItemContainerWidget::setSize function should call Widget::setSize like you do in the code you showed
- The m_boundSizeLayouts of your widget should be empty, if no other widget has bound the size of ItemContainerWidget, so no further calls are made.
- After Widget::size finished, your ItemContainerWidget::setSize function you can rely on the m_size variable to contain the current widget size.
- Each mentioned function will now finish in opposite order, i.e. the remaining code of ItemContainerWidget::setSize will be executed before setting the size of ScrollablePanel in ScrollablePanel::setSize finished.

So one thing you could still test is to check that m_boundSizeLayouts is really empty in ItemContainerWidget::setSize.

If you replace "itemContainerW->setSize(800, tgui::bindHeight(m_scrollPanel)-m_scrollPanel->getScrollbarWidth());" with just "itemContainerW->setSize(800,600)", does the program work fine?

I don't see anything wrong based on your descriptions, there is probably some small mistake somewhere. Could you perhaps share your code so that I can try to reproduce it here?