mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-01-01 02:19:00 -05:00
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.
122 lines
3.4 KiB
C++
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
|