Added animations to file selector
This commit is contained in:
parent
4e17d6e40c
commit
2d039dc47b
10 changed files with 250 additions and 178 deletions
|
|
@ -11,59 +11,6 @@ void LayoutElement::layout(const Clay_ElementId& id, const std::function<void(La
|
|||
layout(this, id);
|
||||
}
|
||||
|
||||
void LayoutElement::update() {
|
||||
for(auto& [id, animation] : animations) {
|
||||
switch(animation.state) {
|
||||
case InternalFloatAnimation::State::RUN: {
|
||||
animation.currentTime += gui.io.deltaTime;
|
||||
if(animation.currentTime >= animation.anim.duration) {
|
||||
animation.currentTime = animation.anim.duration;
|
||||
animation.state = InternalFloatAnimation::State::DONE;
|
||||
}
|
||||
gui.set_to_layout();
|
||||
break;
|
||||
}
|
||||
case InternalFloatAnimation::State::RUN_REVERSE: {
|
||||
animation.currentTime -= gui.io.deltaTime;
|
||||
if(animation.currentTime <= 0.0f) {
|
||||
animation.currentTime = 0.0f;
|
||||
animation.state = InternalFloatAnimation::State::DONE;
|
||||
}
|
||||
gui.set_to_layout();
|
||||
break;
|
||||
}
|
||||
case InternalFloatAnimation::State::DONE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float LayoutElement::get_float_animation(const char* animationID, const FloatAnimation& animation) {
|
||||
InternalFloatAnimation internalAnim;
|
||||
internalAnim.anim = animation;
|
||||
auto [it, placed] = animations.emplace(animationID, internalAnim);
|
||||
const InternalFloatAnimation& actualInternalAnim = it->second;
|
||||
return std::lerp(actualInternalAnim.anim.startVal, actualInternalAnim.anim.endVal, actualInternalAnim.anim.easing(it->second.currentTime / actualInternalAnim.anim.duration));
|
||||
}
|
||||
|
||||
void LayoutElement::animation_trigger(const char* animationID) {
|
||||
auto it = animations.find(animationID);
|
||||
if(it != animations.end()) {
|
||||
InternalFloatAnimation& animation = it->second;
|
||||
if(animation.currentTime < animation.anim.duration)
|
||||
animation.state = InternalFloatAnimation::State::RUN;
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutElement::animation_trigger_reverse(const char* animationID) {
|
||||
auto it = animations.find(animationID);
|
||||
if(it != animations.end()) {
|
||||
InternalFloatAnimation& animation = it->second;
|
||||
if(animation.currentTime > 0.0f)
|
||||
animation.state = InternalFloatAnimation::State::RUN_REVERSE;
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutElement::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {
|
||||
if(c.mouseButton) c.mouseButton(this, button);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#pragma once
|
||||
#include "Element.hpp"
|
||||
#include "Helpers/BezierEasing.hpp"
|
||||
|
||||
namespace GUIStuff {
|
||||
|
||||
|
|
@ -13,32 +12,12 @@ class LayoutElement : public Element {
|
|||
std::function<void(LayoutElement* l, const InputManager::MouseWheelCallbackArgs& wheel)> mouseWheel;
|
||||
std::function<void(LayoutElement* l, const InputManager::KeyCallbackArgs& key)> key;
|
||||
};
|
||||
struct FloatAnimation {
|
||||
float startVal = 0.0f;
|
||||
float endVal = 1.0f;
|
||||
float duration = 1.0f;
|
||||
BezierEasing easing = BezierEasing::linear;
|
||||
};
|
||||
void layout(const Clay_ElementId& id, const std::function<void(LayoutElement*, const Clay_ElementId&)>& layout, const Callbacks& c = {});
|
||||
virtual void update() override;
|
||||
float get_float_animation(const char* animationID, const FloatAnimation& animation);
|
||||
void animation_trigger(const char* animationID);
|
||||
void animation_trigger_reverse(const char* animationID);
|
||||
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) override;
|
||||
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override;
|
||||
virtual void input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel) override;
|
||||
virtual void input_key_callback(const InputManager::KeyCallbackArgs& key) override;
|
||||
private:
|
||||
struct InternalFloatAnimation {
|
||||
enum class State {
|
||||
RUN,
|
||||
RUN_REVERSE,
|
||||
DONE
|
||||
} state = State::DONE;
|
||||
float currentTime = 0.0f;
|
||||
FloatAnimation anim;
|
||||
};
|
||||
std::unordered_map<const char*, InternalFloatAnimation> animations;
|
||||
Callbacks c;
|
||||
};
|
||||
|
||||
|
|
|
|||
68
src/GUIStuff/GUIFloatAnimation.cpp
Normal file
68
src/GUIStuff/GUIFloatAnimation.cpp
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
#include "GUIFloatAnimation.hpp"
|
||||
#include "GUIManager.hpp"
|
||||
|
||||
namespace GUIStuff {
|
||||
|
||||
GUIFloatAnimation::GUIFloatAnimation(const GUIFloatAnimationData& animData):
|
||||
anim(animData),
|
||||
animVal(animData.startVal)
|
||||
{}
|
||||
|
||||
bool GUIFloatAnimation::is_at_start() {
|
||||
return state == State::DONE && currentTime == 0.0f;
|
||||
}
|
||||
|
||||
bool GUIFloatAnimation::is_at_end() {
|
||||
return state == State::DONE && currentTime == anim.duration;
|
||||
}
|
||||
|
||||
bool GUIFloatAnimation::is_done() {
|
||||
return state == State::DONE;
|
||||
}
|
||||
|
||||
void GUIFloatAnimation::calculate_anim_val() {
|
||||
animVal = std::lerp(anim.startVal, anim.endVal, anim.easing(currentTime / anim.duration));
|
||||
}
|
||||
|
||||
void GUIFloatAnimation::update(GUIManager& gui) {
|
||||
switch(state) {
|
||||
case State::RUN: {
|
||||
currentTime += gui.io.deltaTime;
|
||||
if(currentTime >= anim.duration) {
|
||||
currentTime = anim.duration;
|
||||
state = State::DONE;
|
||||
}
|
||||
calculate_anim_val();
|
||||
gui.set_to_layout();
|
||||
break;
|
||||
}
|
||||
case State::RUN_REVERSE: {
|
||||
currentTime -= gui.io.deltaTime;
|
||||
if(currentTime <= 0.0f) {
|
||||
currentTime = 0.0f;
|
||||
state = State::DONE;
|
||||
}
|
||||
calculate_anim_val();
|
||||
gui.set_to_layout();
|
||||
break;
|
||||
}
|
||||
case State::DONE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float GUIFloatAnimation::get_val() const {
|
||||
return animVal;
|
||||
}
|
||||
|
||||
void GUIFloatAnimation::animation_trigger() {
|
||||
if(currentTime < anim.duration)
|
||||
state = State::RUN;
|
||||
}
|
||||
|
||||
void GUIFloatAnimation::animation_trigger_reverse() {
|
||||
if(currentTime > 0.0f)
|
||||
state = State::RUN_REVERSE;
|
||||
}
|
||||
|
||||
}
|
||||
40
src/GUIStuff/GUIFloatAnimation.hpp
Normal file
40
src/GUIStuff/GUIFloatAnimation.hpp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
#include <Helpers/BezierEasing.hpp>
|
||||
|
||||
namespace GUIStuff {
|
||||
|
||||
class GUIManager;
|
||||
|
||||
struct GUIFloatAnimationData {
|
||||
float startVal = 0.0f;
|
||||
float endVal = 1.0f;
|
||||
float duration = 1.0f;
|
||||
BezierEasing easing = BezierEasing::linear;
|
||||
};
|
||||
|
||||
class GUIFloatAnimation {
|
||||
public:
|
||||
GUIFloatAnimation(const GUIFloatAnimationData& animData);
|
||||
void update(GUIManager& gui);
|
||||
void animation_trigger();
|
||||
void animation_trigger_reverse();
|
||||
float get_val() const;
|
||||
|
||||
bool is_at_start();
|
||||
bool is_at_end();
|
||||
bool is_done();
|
||||
|
||||
bool isUsedThisFrame;
|
||||
private:
|
||||
void calculate_anim_val();
|
||||
enum class State {
|
||||
RUN,
|
||||
RUN_REVERSE,
|
||||
DONE
|
||||
} state = State::DONE;
|
||||
float currentTime = 0.0f;
|
||||
GUIFloatAnimationData anim;
|
||||
float animVal;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -506,6 +506,19 @@ void GUIManager::update_invalidated_draw_area_from_layout() {
|
|||
void GUIManager::update() {
|
||||
for(ElementContainer* e : orderedElements)
|
||||
e->elem->update();
|
||||
for(auto& [id, animation] : animations)
|
||||
animation.update(*this);
|
||||
}
|
||||
|
||||
GUIFloatAnimation* GUIManager::float_animation(const char* animationID, const GUIFloatAnimationData& animation) {
|
||||
GUIFloatAnimation* toRet = nullptr;
|
||||
new_id(animationID, [&] {
|
||||
auto [it, placed] = animations.emplace(idStack, animation);
|
||||
GUIFloatAnimation& actualInternalAnim = it->second;
|
||||
actualInternalAnim.isUsedThisFrame = true;
|
||||
toRet = &actualInternalAnim;
|
||||
});
|
||||
return toRet;
|
||||
}
|
||||
|
||||
void GUIManager::update_window(const Vector2f& windowPos, const Vector2f& windowSize, float guiScaleMultiplier) {
|
||||
|
|
@ -539,6 +552,8 @@ void GUIManager::layout() {
|
|||
void GUIManager::layout_begin() {
|
||||
for(auto& [id, e] : elements)
|
||||
e.isUsedThisFrame = false;
|
||||
for(auto& [id, a] : animations)
|
||||
a.isUsedThisFrame = false;
|
||||
|
||||
Clay_SetLayoutDimensions(Clay_Dimensions(io.windowSize.x(), io.windowSize.y()));
|
||||
Clay_SetCurrentContext(clayInstance);
|
||||
|
|
@ -557,6 +572,9 @@ void GUIManager::layout_end() {
|
|||
std::erase_if(elements, [](auto& p) {
|
||||
return !p.second.isUsedThisFrame;
|
||||
});
|
||||
std::erase_if(animations, [](auto& p) {
|
||||
return !p.second.isUsedThisFrame;
|
||||
});
|
||||
std::stable_sort(orderedElements.begin(), orderedElements.end(), [](ElementContainer* a, ElementContainer* b) {
|
||||
return b->elem->zIndex < a->elem->zIndex; // Order from highest to lowest zIndex
|
||||
});
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "GUIManagerID.hpp"
|
||||
#include <clay.h>
|
||||
#include "Elements/Element.hpp"
|
||||
#include "GUIFloatAnimation.hpp"
|
||||
|
||||
using namespace Eigen;
|
||||
|
||||
|
|
@ -22,6 +23,8 @@ class GUIManager {
|
|||
void set_to_layout();
|
||||
void layout_if_necessary();
|
||||
|
||||
GUIFloatAnimation* float_animation(const char* animationID, const GUIFloatAnimationData& animation);
|
||||
|
||||
void update();
|
||||
void update_window(const Vector2f& windowPos, const Vector2f& windowSize, float guiScaleMultiplier);
|
||||
|
||||
|
|
@ -101,6 +104,8 @@ class GUIManager {
|
|||
|
||||
bool cursor_obstructed() const;
|
||||
private:
|
||||
std::unordered_map<GUIManagerIDStack, GUIFloatAnimation> animations;
|
||||
|
||||
void layout();
|
||||
void layout_begin();
|
||||
void layout_end();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue