Skip to content

Commit

Permalink
GUI2/Loading Screen: made animation time-based instead of frame-based
Browse files Browse the repository at this point in the history
Big thanks to @CelticMinstrel for help on this.
  • Loading branch information
Vultraz committed Jan 25, 2021
1 parent 745b774 commit 3757f2c
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 13 deletions.
14 changes: 6 additions & 8 deletions data/gui/window/loadscreen.cfg
Expand Up @@ -133,15 +133,13 @@
#
# Uses a bezier in-out easing to calculate the position of the dot each frame.
#
# First, it gets a normalized [0, 1] value based on the value of `tick` in the range [0, steps], then uses
# this value multiplied by the width of the drawing canvas (sans the width of the text, since there still
# needs to be enough horizontal space to render the dot on the last step of the loop) to get this frame's
# x-coordinate. Note that `steps` *must* be a decimal or the formula won't work.
# `time` represents the elapsed time since the animation began, in milliseconds. This gets a normalized
# [0, 1] value based on the ellapsed time in the current iteration of the range [0, duration] (also in
# milliseconds). That value is then multiplied b the width of the drawing canvas (sans the width of the
# test, since there still needs to be enough horizontal space to render the dor on the last step of the
# loop) to get this frame's x-coordinate.)"
#
# For the record, the original linear formula I came up with was:
# "(floor(jump * (tick % steps)) where jump = (width / steps) where steps = 40)"
#
x = "(round(w * (t * t * (3.0 - 2.0 * t))) where w = (width - text_width) where t = ((tick % steps) / steps) where steps = 40.0)"
x = "(round(w * (t * t * (3.0 - 2.0 * t))) where w = (width - text_width), t = (time % duration) / as_decimal(duration) where duration = 1000)"
y = 0
w = "(text_width)"
h = "(height)"
Expand Down
15 changes: 11 additions & 4 deletions src/gui/dialogs/loading_screen.cpp
Expand Up @@ -32,7 +32,6 @@
#include "preferences/general.hpp"
#include "video.hpp"

#include <chrono>
#include <cstdlib>
#include <functional>

Expand Down Expand Up @@ -75,12 +74,12 @@ REGISTER_DIALOG(loading_screen)
loading_screen* loading_screen::singleton_ = nullptr;

loading_screen::loading_screen(std::function<void()> f)
: animation_counter_(0)
, load_func_(f)
: load_func_(f)
, worker_result_()
, cursor_setter_()
, progress_stage_label_(nullptr)
, animation_(nullptr)
, animation_start_()
, current_stage_(loading_stage::none)
, visible_stages_()
, current_visible_stage_()
Expand Down Expand Up @@ -160,7 +159,15 @@ void loading_screen::draw_callback()
progress_stage_label_->set_label(iter->second);
}

animation_->get_drawing_canvas().set_variable("tick", wfl::variant(animation_counter_++));
using namespace std::chrono;
const auto now = steady_clock::now();

// We only need to set the start time once;
if(!animation_start_.has_value()) {
animation_start_ = now;
}

animation_->get_drawing_canvas().set_variable("time", wfl::variant(duration_cast<milliseconds>(now - *animation_start_).count()));
animation_->set_is_dirty(true);
}

Expand Down
5 changes: 4 additions & 1 deletion src/gui/dialogs/loading_screen.hpp
Expand Up @@ -19,8 +19,10 @@
#include "tstring.hpp"

#include <atomic>
#include <chrono>
#include <future>
#include <map>
#include <optional>
#include <vector>

namespace cursor
Expand Down Expand Up @@ -99,14 +101,15 @@ class loading_screen : public modal_dialog, public events::pump_monitor

static loading_screen* singleton_;

int animation_counter_;
std::function<void()> load_func_;
std::future<void> worker_result_;
std::unique_ptr<cursor::setter> cursor_setter_;

label* progress_stage_label_;
drawing* animation_;

std::optional<decltype(std::chrono::steady_clock::now())> animation_start_;

std::atomic<loading_stage> current_stage_;

using stage_map = std::map<loading_stage, t_string>;
Expand Down

0 comments on commit 3757f2c

Please sign in to comment.