Files
MuditaOS/module-apps/apps-common/widgets/ProgressTimer.cpp
Maciej Gibowicz 5a70754a4e [BH-1971] Changing the refresh rate of the progress bar screen
The longer the time countdown on the progress bar, the less frequently
the screen is refreshed, which results in less power consumption when
running the Meditation, Relaxation, Power Nap and Focus Timer
applications.
2024-05-15 12:45:29 +02:00

122 lines
3.4 KiB
C++

// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "ProgressTimer.hpp"
#include <Text.hpp>
#include <ProgressBar.hpp>
#include <ApplicationCommon.hpp>
#include <apps-common/GuiTimer.hpp>
#include <gsl/assert>
namespace app
{
ProgressTimer::ProgressTimer(app::ApplicationCommon *app,
gui::Item &parent,
std::string timerName,
std::chrono::milliseconds baseTick,
ProgressCountdownMode countdownMode,
utils::time::Duration::DisplayedFormat displayFormat)
: app{app}, parent{parent}, name{std::move(timerName)}, baseTickInterval{baseTick},
countdownMode{countdownMode}, displayFormat{displayFormat}
{}
void ProgressTimer::update()
{
app->refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST);
}
void ProgressTimer::reset(std::chrono::seconds _duration, std::chrono::seconds _interval)
{
Expects(_duration != std::chrono::seconds::zero());
duration = _duration;
elapsed = std::chrono::seconds::zero();
interval = _interval;
hasInterval = _interval != std::chrono::seconds::zero();
update();
}
void ProgressTimer::start()
{
startTimer();
isRunning = true;
}
void ProgressTimer::startTimer()
{
Expects(app != nullptr);
parent.timerCallback = [this]([[maybe_unused]] gui::Item &it, sys::Timer &task) {
return onTimerTimeout(task);
};
timerTask = app::GuiTimerFactory::createPeriodicTimer(app, &parent, name, baseTickInterval);
timerTask.start();
}
void ProgressTimer::updateInterval(std::chrono::milliseconds newInterval)
{
if (baseTickInterval != newInterval) {
baseTickInterval = newInterval;
timerTask.restart(newInterval);
}
}
auto ProgressTimer::onTimerTimeout(sys::Timer &task) -> bool
{
if (isStopped()) {
task.stop();
return false;
}
elapsed += baseTickInterval;
update();
if (isFinished()) {
task.stop();
if (isFinished() && onFinishedCallback != nullptr) {
onFinishedCallback();
}
return true;
}
if ((intervalReached() || isFinished()) && onIntervalCallback != nullptr) {
onIntervalCallback();
}
return true;
}
auto ProgressTimer::isFinished() const noexcept -> bool
{
return duration <= elapsed;
}
auto ProgressTimer::isStopped() const noexcept -> bool
{
return !isRunning;
}
auto ProgressTimer::intervalReached() const noexcept -> bool
{
return hasInterval &&
(std::chrono::duration_cast<std::chrono::seconds>(elapsed).count() % interval.count()) == 0;
}
void ProgressTimer::stop()
{
isRunning = false;
}
std::chrono::milliseconds ProgressTimer::getElapsed()
{
return elapsed;
}
void ProgressTimer::registerOnFinishedCallback(std::function<void()> cb)
{
onFinishedCallback = std::move(cb);
}
void ProgressTimer::registerOnIntervalCallback(std::function<void()> cb)
{
onIntervalCallback = std::move(cb);
}
} // namespace app