Animations

Started by Garwin, 04 May 2022, 19:46:31

Garwin

I have several questions related to animation.

1. Resize with animation

I am trying different animations. It is quite nice that except showWithEffect and hideWithEffect there are couple of function that can be mixed to make our own animations quite easily. But I struggle with scaling animation.

I am trying to make animation to scale button (including text) 2 times larger trough animation.
The whole animation is that all options not choosen hideWithEffect left, only choosen option move to center and double the size.


First part (button itself):

float sizeX = m_options.at(buttonCount)->getScale().x*2;
float sizeY = m_options.at(buttonCount)->getScale().y*2;
std::cout << "Size     x: " << sizeX << "\t" << "y: " << sizeY << "\n";
tgui::Layout2d scale (sizeX,sizeY);
m_options.at(buttonCount)->resizeWithAnimation (scale,m_animationDelay);


But it does minimalize buttons, not increase it ....
I will need to ad setting origin to center of button, but it is not difficult.

Second part:
How can I do similar thing with text?
Or do I need to do my own application as TGUI supports only button resize without text?




2. temporary making button unclickable
As animations plays, buttons are still clickable. Better would be that for the time being there are not clickable. Is there something (flag) directly in TGUI?
Just a question as it would be not difficult to code through "isAnimationPlaying".

3. Reseting animation
I have different states through std::stack. The main menu is one state and after any chosen options except exit new state is pushed on stack.
Than when some of new states finished their state is destroyed and previous state (main manu) is on top. This means main loop works like:
peekState()->handleInput();
peekState()->update(dt);
m_window.clear (sf::Color::Black);
peekState()->draw(dt);
fps.draw(dt,m_window);
m_window.display();


There is state related to main menu. And when this state is going to exit there is:
setDefaultButtons ();
This function just recreate all buttons including starting animations (it is not most efficient way but it was fast to code as constructor of the state is just "setDefaultButtons();" with just small add-on.
But strange part is that when code is running and some other state is destroyed and everything is going back to main menu, everything is not drawn as set-up by setDefaultButtons, but all animations are finished directly meaning no buttons with showWithEffect.


Garwin

AD 1
I find it, it is not scaling (times original value), it is new value.

texus

I seem to have missed this topic somehow. Do you still have those questions?

Garwin

Relating to point 2, I haven't found how any single button could be disabled (disable the function click) but still visible, however I did it for the whole menu just adding an invisible Picture layer on top of it. Is there some methods through a single button? I cannot find anything.

Relating to point 3, I change how states work destroying them and creating a new ones with every change. But did not find a reason why the animation did not play when on top of the stack there was a new state and after destroying this new state, functions return back to the previous stack with buttons set to play the animation.
Does have TGUI centralized time no matter of TGUI instances?

texus

2.
You can use "button->setEnabled(false)" to disable the button which makes the button unclickable, but that might also change the look of the button depending on the theme, which might be undesirable.
One other thing you could do is temporarily disable the signal callback with "button->onPress.setEnabled(false)".

3.
Does each state have its own Gui object, or is there only a single Gui object that is shared between all states? (it is recommended to only have a single Gui per window)
Every Gui object contains a std::chrono::steady_clock which starts counting on the first call to draw(). Any calls you make to draw() afterwards will check the elapsed time since the last draw call and update animations with this amount of time.

So it sounds like when you go back to the previous stack, the elapsed time passed to the widgets is the entire time you spend within the last state, and hence the animations finish immediately. But that would only be the case if there was a Gui per state.

There might be multiple solutions to this (e.g. manually control the time of TGUI instead of letting the Gui handle it), but I would first need to better understand how things happen exactly before I can make suggestions on how to fix this.

Garwin

#5
2 - thanks, it is clear and works.
3 - It is more about understanding how it works for the future as I decided to change states that are always destroyed before the new state is applied.
The issue I had is clear, it certainly was because I had one gui object for each state and time went on even if this state was not active.

I read the tutorials and it seems that for me the best way to switch between different states that coexist together is using
tgui::Group and make gui object one level higher in hierarchy.