Implement Widget tweening and layout order.

This commit is contained in:
2025-02-10 16:42:33 -05:00
parent 1b2fdecc18
commit 24e38b9ec3
3 changed files with 39 additions and 60 deletions

View File

@@ -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};

View File

@@ -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;
}

View File

@@ -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;
}
}