Implement Widget tweening and layout order.
This commit is contained in:
@@ -62,61 +62,8 @@ namespace JUI {
|
||||
Event<Widget *> Destroying;
|
||||
public:
|
||||
|
||||
void TweenPositionTo(const UDim2& goal)
|
||||
{
|
||||
UDim2 start_position = this->Position();
|
||||
float progress = 0;
|
||||
|
||||
Tween t;
|
||||
|
||||
|
||||
std::function<void(float)> updateTillGoalReached = [this, t, start_position, progress, goal] (float elapsed) mutable
|
||||
{
|
||||
|
||||
UDim2 current_pos = this->Position();
|
||||
|
||||
// TODO: Implement UDim equality operators (with epsilon)
|
||||
// TODO: Implement UDim::Lerp
|
||||
// TODO: Implement UDim2::Lerp
|
||||
if (current_pos.X.Pixels == goal.X.Pixels && current_pos.Y.Pixels == goal.Y.Pixels && current_pos.X.Scale == goal.X.Scale && current_pos.Y.Scale == goal.Y.Scale)
|
||||
{
|
||||
// Reached Goal, Complete this tween.
|
||||
return;
|
||||
}
|
||||
|
||||
progress += elapsed;
|
||||
|
||||
if (progress >= 1.f)
|
||||
{
|
||||
progress = 1.f;
|
||||
t.Completed.Invoke();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
float modified_progress = EasingFunctions::EaseOutElastic(progress);
|
||||
|
||||
|
||||
UDim2 pos = current_pos;
|
||||
|
||||
pos.X.Pixels = Math::Lerp(start_position.X.Pixels, goal.X.Pixels, modified_progress);
|
||||
pos.Y.Pixels = Math::Lerp(start_position.Y.Pixels, goal.Y.Pixels, modified_progress);
|
||||
pos.X.Scale = Math::Lerp(start_position.X.Scale, goal.X.Scale, modified_progress);
|
||||
pos.Y.Scale = Math::Lerp(start_position.Y.Scale, goal.Y.Scale, modified_progress);
|
||||
|
||||
|
||||
Position(pos);
|
||||
};
|
||||
|
||||
|
||||
t.tick_func = updateTillGoalReached;
|
||||
|
||||
tweens.push_back(t);
|
||||
|
||||
}
|
||||
void TweenPositionFromTo();
|
||||
void TweenSizeTo();
|
||||
void TweenSizeFromTo();
|
||||
Tween* TweenPositionTo(const UDim2& goal, TweenInfo params = {});
|
||||
Tween* TweenSizeTo(const UDim2& goal, TweenInfo params = {});
|
||||
|
||||
|
||||
|
||||
@@ -299,6 +246,8 @@ namespace JUI {
|
||||
/// Returns whether or not the mouse is inside this widget's approximate bounding-box.
|
||||
bool IsMouseInside() const;
|
||||
|
||||
int LayoutOrder() const { return layout_order; }
|
||||
void LayoutOrder(int value) { layout_order = value;}
|
||||
|
||||
|
||||
/// Returns the complete bounding box around this instance that will be rendered onto.
|
||||
@@ -356,7 +305,7 @@ namespace JUI {
|
||||
UDim2 size = {50_px, 50_px};
|
||||
Widget* parent = nullptr;
|
||||
std::vector<Widget*> children;
|
||||
std::vector<Tween> tweens;
|
||||
std::vector<Tween*> tweens;
|
||||
float rotation = 0;
|
||||
std::string name;
|
||||
bool selected = false;
|
||||
@@ -373,6 +322,7 @@ namespace JUI {
|
||||
Widget* next = nullptr;
|
||||
Widget* prev = nullptr;
|
||||
int zindex = 0;
|
||||
int layout_order = 0;
|
||||
|
||||
Vector2 viewport_size{0,0};
|
||||
|
||||
|
5
main.cpp
5
main.cpp
@@ -130,7 +130,9 @@ JUI::Scene* CreateScene() {
|
||||
other_window->Size({30_percent, 25_percent});
|
||||
other_window->SetTitle("Another Window");
|
||||
|
||||
other_window->TweenPositionTo({50_percent, 50_percent});
|
||||
Tween* t = other_window->TweenPositionTo({50_percent, 50_percent}, {.time = 5});
|
||||
|
||||
t->Completed += [] () { std::cout << "This Dick" << std::endl; };
|
||||
|
||||
scroller = new JUI::ScrollingRect(other_window->ViewportInstance());
|
||||
scroller->Size({100_percent, 100_percent});
|
||||
@@ -224,6 +226,7 @@ public:
|
||||
auto* text = new JUI::TextRect(list);
|
||||
text->Size({50_percent, 20_px});
|
||||
text->ZIndex(iter);
|
||||
text->LayoutOrder(-iter);
|
||||
text->SetContent(std::format("{} Sampled Delta: {}ms", -iter, Math::Floor(elapsed*1000.f)));
|
||||
scroller->scroll_size += 20;
|
||||
}
|
||||
|
@@ -287,10 +287,14 @@ namespace JUI {
|
||||
|
||||
void Widget::UpdateTweens(float elapsed)
|
||||
{
|
||||
for (Tween& t: tweens)
|
||||
{
|
||||
t.tick(elapsed);
|
||||
for (Tween* t: tweens) {
|
||||
t->Update(elapsed);
|
||||
}
|
||||
|
||||
// TODO: Remove tweens if "dead"
|
||||
std::ranges::remove_if(tweens.begin(), tweens.end(), [](Tween* t){
|
||||
return t->HasCompleted();
|
||||
});
|
||||
}
|
||||
|
||||
void Widget::Update(float delta) {
|
||||
@@ -417,4 +421,26 @@ namespace JUI {
|
||||
return {GetAbsolutePosition(), GetAbsoluteSize()};
|
||||
}
|
||||
|
||||
Tween *Widget::TweenPositionTo(const UDim2 &goal, TweenInfo params) {
|
||||
UDim2 start_position = this->Position();
|
||||
TweenTickFunc updateTillGoalReached = [this, start_position, goal] (float elapsed, float progress) mutable {
|
||||
UDim2 pos = start_position.Lerp(goal, progress);
|
||||
Position(pos);
|
||||
};
|
||||
Tween* t = new Tween(updateTillGoalReached, params);
|
||||
tweens.push_back(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
Tween *Widget::TweenSizeTo(const UDim2 &goal, TweenInfo info) {
|
||||
UDim2 start_size = this->Size();
|
||||
TweenTickFunc updateTillGoalReached = [this, start_size, goal] (float elapsed, float progress) mutable {
|
||||
UDim2 step_size = start_size.Lerp(goal, progress);
|
||||
Size(step_size);
|
||||
};
|
||||
Tween* t = new Tween(updateTillGoalReached, info);
|
||||
tweens.push_back(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user