1+ namespace ExerciseTimer {
2+ [GtkTemplate (ui = "/xyz /safeworlds /hiit /ui /timer_page .ui ")]
3+ public class TimerPage : Adw.NavigationPage {
4+ public TimerPage (TrainingSetup setup) {
5+ Setup = setup;
6+ remaining_sets = setup. Sets ;
7+ if (setup. WarmupSec > 0 ) {
8+ current_state = State . Preparation ;
9+ remaining_sec = setup. WarmupSec ;
10+ } else {
11+ current_state = State . Exercise ;
12+ remaining_sec = setup. ExerciseSec ;
13+ }
14+
15+ var timer_id = GLib . Timeout . add(1000 , onTimeout);
16+ this . hidden. connect((_) = > {
17+ if (current_state != State . Finished ) {
18+ GLib . Source . remove(timer_id);
19+ }
20+ });
21+
22+ notifyProperties();
23+ updateCssClass();
24+ timer_label_box. set_direction(Gtk . TextDirection . LTR );
25+ }
26+
27+ public TrainingSetup Setup { get ; private set ; }
28+
29+ public bool Finished {
30+ get {
31+ return current_state == State . Finished ;
32+ }
33+ }
34+
35+ public string RemainingMinFormatted {
36+ owned get {
37+ var min = remaining_sec / 60 ;
38+ return " %02d " . printf(min);
39+ }
40+ }
41+
42+ public string RemainingSecFormatted {
43+ owned get {
44+ var sec = remaining_sec % 60 ;
45+ return " %02d " . printf(sec);
46+ }
47+ }
48+
49+ public string StateFormatted {
50+ owned get {
51+ switch (current_state) {
52+ case State . Preparation :
53+ // Translators: Shown on the timer page during preparation
54+ return _(" Preparation" );
55+ case State . Exercise :
56+ // Translators: Shown on the timer page during exercise
57+ return _(" Exercise" );
58+ case State . Rest :
59+ // Translators: Shown on the timer page during rest
60+ return _(" Rest" );
61+ case State . Finished :
62+ return " " ;
63+ default:
64+ assert_not_reached();
65+ }
66+ }
67+ }
68+
69+ private bool onTimeout() {
70+ bool retval;
71+ if (remaining_sec > 1 ) {
72+ -- remaining_sec;
73+ retval = true ;
74+ } else {
75+ switch (current_state) {
76+ case State . Preparation :
77+ current_state = State . Exercise ;
78+ remaining_sec = Setup . ExerciseSec ;
79+ retval = true ;
80+ break ;
81+ case State . Exercise :
82+ -- remaining_sets;
83+ if (remaining_sets > 0 ) {
84+ current_state = State . Rest ;
85+ remaining_sec = Setup . RestSec ;
86+ retval = true ;
87+ break ;
88+ } else {
89+ current_state = State . Finished ;
90+ retval = false ;
91+ break ;
92+ }
93+ case State . Rest :
94+ current_state = State . Exercise ;
95+ remaining_sec = Setup . ExerciseSec ;
96+ retval = true ;
97+ break ;
98+ default:
99+ assert_not_reached();
100+ }
101+ updateCssClass();
102+ }
103+
104+ notifyProperties();
105+ return retval;
106+ }
107+
108+ private void notifyProperties() {
109+ notify_property(" RemainingMinFormatted" );
110+ notify_property(" RemainingSecFormatted" );
111+ notify_property(" StateFormatted" );
112+ notify_property(" Finished" );
113+ }
114+
115+ private void updateCssClass() {
116+ var classes = new string [2 ];
117+ classes[0 ] = " card" ;
118+ switch (current_state) {
119+ case State . Preparation :
120+ classes[1 ] = " timer-warmup" ;
121+ break ;
122+ case State . Exercise :
123+ case State . Finished :
124+ classes[1 ] = " timer-exercise" ;
125+ break ;
126+ case State . Rest :
127+ classes[1 ] = " timer-rest" ;
128+ break ;
129+ default:
130+ assert_not_reached();
131+ }
132+ timer_card. css_classes = classes;
133+ }
134+
135+ private enum State {
136+ Preparation ,
137+ Exercise ,
138+ Rest ,
139+ Finished ,
140+ }
141+
142+ [GtkChild ]
143+ unowned Gtk . Box timer_card;
144+ [GtkChild ]
145+ unowned Gtk . Box timer_label_box;
146+
147+ private State current_state;
148+ private int remaining_sec;
149+ private int remaining_sets;
150+ }
151+ }
0 commit comments