~aleteoryx/muditaos

ref: a405cad694b867fcd2498984830bd97d4b9bde2f muditaos/module-apps/apps-common/widgets/ProgressTimer.cpp -rw-r--r-- 3.4 KiB
a405cad6Aleteoryx trim readme 8 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/blob/master/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