Skip to content

Commit a008cff

Browse files
committed
changed cal options to have text fields instead of 0 and 1 + bugfix going to previous screen
1 parent 7724425 commit a008cff

File tree

6 files changed

+219
-40
lines changed

6 files changed

+219
-40
lines changed

main.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "ui/splash.hpp"
77
#include "ui/settings.hpp"
88
#include "ui/numeric_popup.hpp"
9+
#include "ui/popup.hpp"
910
#include "ui/time.hpp"
1011
#include "ui/calibration.hpp"
1112
#include "ui/config.hpp"
@@ -151,6 +152,7 @@ int main() {
151152

152153
// create the popup first as some other screens use it
153154
menu::numeric_popup<fb_t> numeric_popup = {};
155+
menu::popup<fb_t> string_popup = {};
154156

155157
// setup the first state. We initialize everything
156158
// except the screen in the splash screen. This speeds
@@ -160,7 +162,7 @@ int main() {
160162
menu::totp<fb_t, storage, rtc, usb_keyboard> totp = {};
161163
menu::settings<fb_t> settings = {};
162164
menu::time<fb_t, rtc_periph, rtc> time(numeric_popup);
163-
menu::calibration<fb_t, rtc_periph> calibration(numeric_popup);
165+
menu::calibration<fb_t, rtc_periph> calibration(numeric_popup, string_popup);
164166
menu::config<
165167
fb_t, storage, fat_helper,
166168
usb_keyboard, usb_massstorage
@@ -177,6 +179,7 @@ int main() {
177179
&config,
178180
&mouse,
179181
&numeric_popup,
182+
&string_popup,
180183
};
181184

182185
// get the current screen

ui/calibration.hpp

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "screen.hpp"
66
#include "numeric_popup.hpp"
7+
#include "popup.hpp"
78

89
namespace menu {
910
template <typename FrameBuffer, typename RtcPeriph>
@@ -26,7 +27,8 @@ namespace menu {
2627
bool direction;
2728

2829
// popup we use to show the numbers
29-
numeric_popup<FrameBuffer>& popup;
30+
numeric_popup<FrameBuffer>& num_popup;
31+
popup<FrameBuffer>& str_popup;
3032

3133
void next(int32_t value) {
3234
// store the value
@@ -73,61 +75,70 @@ namespace menu {
7375
}
7476

7577
void cancel() {
76-
// reset and go back to the previous screen
77-
current = steps::enabled;
78+
if (current == steps::enabled) {
79+
// go back to the menu
80+
screen_base::buffer.back();
81+
82+
return;
83+
}
7884

79-
// go back
80-
screen_base::buffer.back();
85+
// go back one screen
86+
current = static_cast<steps>(static_cast<uint32_t>(current) - 1);
87+
88+
// change to the previous screen
89+
change_screen(current);
8190
}
8291

8392
void change_screen(const steps current) {
8493
// get what state we are in
8594
switch (current) {
8695
case steps::enabled:
87-
popup.configure(
88-
"Cal enabled", static_cast<bool>(RtcPeriph::port->CCR & (0x1 << 4)),
89-
0, 1, [&](int32_t value){next(value);},
96+
str_popup.configure(
97+
"RTC calibration", static_cast<bool>(RtcPeriph::port->CCR & (0x1 << 4)),
98+
"enabled", "disabled", [&](bool value){next(value);},
9099
[&](){cancel();}
91100
);
92101
break;
93102
case steps::direction:
94-
popup.configure(
103+
str_popup.configure(
95104
"Cal direction", static_cast<bool>(RtcPeriph::port->CALIBRATION & (0x1 << 17)),
96-
0, 1, [&](int32_t value){next(value);},
105+
"backward", "forward", [&](bool value){next(value);},
97106
[&](){cancel();}
98107
);
99108
break;
100109
case steps::calibration:
101-
popup.configure(
110+
num_popup.configure(
102111
"Cal value", RtcPeriph::port->CALIBRATION & 0x1ffff,
103112
0, 0x1ffff, [&](int32_t value){next(value);},
104113
[&](){cancel();}
105114
);
106115
break;
107116
}
108117

109-
// change to the popup screen
110-
screen_base::buffer.change(screen_id::numeric_popup);
118+
if (current == steps::calibration) {
119+
// change to the popup screen
120+
screen_base::buffer.change(screen_id::numeric_popup);
121+
}
122+
else {
123+
// change to the popup screen
124+
screen_base::buffer.change(screen_id::string_popup);
125+
}
111126
}
112127

113128
public:
114-
calibration(numeric_popup<FrameBuffer>& popup):
115-
current(steps::enabled), popup(popup)
129+
calibration(numeric_popup<FrameBuffer>& num_popup, popup<FrameBuffer>& str_popup):
130+
current(steps::enabled), num_popup(num_popup), str_popup(str_popup)
116131
{}
117132

118133
virtual void main(const klib::time::us delta, const input::buttons& buttons) override {
119-
// check for the first entry
120-
if (current == steps::enabled) {
121-
// show the first screen
122-
change_screen(current);
123-
}
124-
else {
125-
// reset and go back to the previous screen
126-
current = steps::enabled;
134+
// change to the first step when we are called. We
135+
// are only called from the settings menu. The
136+
// popup callbacks will skip this by changing
137+
// directly to the new popup
138+
current = steps::enabled;
127139

128-
// go back
129-
screen_base::buffer.back();
130-
}
140+
// show the first screen
141+
change_screen(current);
131142
}
132143

133144
virtual void draw(FrameBuffer& frame_buffer, const klib::vector2u& offset) override {

ui/popup.hpp

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
#pragma once
2+
3+
#include <functional>
4+
5+
#include <klib/graphics/bitmap.hpp>
6+
7+
#include "screen.hpp"
8+
9+
namespace menu {
10+
template <typename FrameBuffer>
11+
class popup: public screen<FrameBuffer> {
12+
protected:
13+
using screen_base = screen<FrameBuffer>;
14+
15+
// callbacks for when we press a button
16+
std::function<void(bool)> next;
17+
std::function<void()> cancel;
18+
19+
// pointer to the string we should show
20+
const char *str;
21+
const char *up_str;
22+
const char *down_str;
23+
24+
// max length between the up and down strings
25+
uint32_t max_length;
26+
27+
// range of the numeric popup
28+
bool value;
29+
30+
public:
31+
popup():
32+
next(nullptr), cancel(nullptr), str(nullptr),
33+
up_str(nullptr), down_str(nullptr),
34+
max_length(0), value(false)
35+
{}
36+
37+
/**
38+
* @brief configure the popup
39+
*
40+
* @param str
41+
* @param continue
42+
* @param cancel
43+
*/
44+
void configure(const char* str, const bool value, const char* up_str,
45+
const char *down_str, std::function<void(bool)> next,
46+
std::function<void()> cancel)
47+
{
48+
// update the string
49+
this->str = str;
50+
51+
// update the options
52+
this->value = value;
53+
this->up_str = up_str;
54+
this->down_str = down_str;
55+
56+
this->max_length = klib::max(
57+
klib::string::strlen(up_str),
58+
klib::string::strlen(down_str)
59+
);
60+
61+
// update the callbacks
62+
this->next = next;
63+
this->cancel = cancel;
64+
}
65+
66+
virtual void main(const klib::time::us delta, const input::buttons& buttons) override {
67+
// check what button is pressed
68+
if (buttons.enter == input::state::pressed) {
69+
// before we do anything go back to the previous item
70+
// in the buffer
71+
screen_base::buffer.back();
72+
73+
// the enter button is pressed. Call the next screen
74+
if (next) {
75+
// call the next function with the value we got
76+
next(value);
77+
}
78+
}
79+
else if (buttons.enter == input::state::long_pressed) {
80+
// before we do anything go back to the previous item
81+
// in the buffer
82+
screen_base::buffer.back();
83+
84+
// the enter button is long pressed. Call the cancel screen
85+
if (cancel) {
86+
// call the next function with the value we got
87+
cancel();
88+
}
89+
}
90+
else if (input::is_pressed(buttons.down) || input::is_pressed(buttons.up)) {
91+
// the down button is pressed
92+
value ^= true;
93+
}
94+
}
95+
96+
virtual void draw(FrameBuffer& frame_buffer, const klib::vector2u& offset) override {
97+
// clear the background black
98+
frame_buffer.clear(klib::graphics::black);
99+
100+
// get the string we should display
101+
const char *ptr = value ? up_str : down_str;
102+
103+
// set the height to 40 pixels
104+
const int32_t h = 40;
105+
106+
// calculate the width. At least the same as the height
107+
const int32_t w = klib::max(h,
108+
((max_length * screen_base::large_text::font::width) + 20) / 2
109+
);
110+
111+
// draw the rectangle arround the number
112+
screen_base::draw_rectangle(frame_buffer, klib::graphics::blue,
113+
klib::vector2i{(240 / 2) - w, (134 / 2) - h} - offset.cast<int32_t>(),
114+
klib::vector2i{(240 / 2) + w, (134 / 2) + h} - offset.cast<int32_t>()
115+
);
116+
117+
// add 2 lines on both sides of the rectangle to round it a bit
118+
screen_base::draw_rectangle(frame_buffer, klib::graphics::blue,
119+
klib::vector2i{(240 / 2) - (w - 1), (134 / 2) - (h - 1)} - offset.cast<int32_t>(),
120+
klib::vector2i{(240 / 2) + w, (134 / 2) + (h - 1)} - offset.cast<int32_t>()
121+
);
122+
screen_base::draw_rectangle(frame_buffer, klib::graphics::blue,
123+
klib::vector2i{(240 / 2) - (w - 2), (134 / 2) - (h - 2)} - offset.cast<int32_t>(),
124+
klib::vector2i{(240 / 2) + (w - 1), (134 / 2) + (h - 2)} - offset.cast<int32_t>()
125+
);
126+
127+
screen_base::draw_rectangle(frame_buffer, klib::graphics::blue,
128+
klib::vector2i{(240 / 2) - w, (134 / 2) - (h - 1)} - offset.cast<int32_t>(),
129+
klib::vector2i{(240 / 2) + (w + 1), (134 / 2) + (h - 1)} - offset.cast<int32_t>()
130+
);
131+
screen_base::draw_rectangle(frame_buffer, klib::graphics::blue,
132+
klib::vector2i{(240 / 2) - (w + 1), (134 / 2) - (h - 2)} - offset.cast<int32_t>(),
133+
klib::vector2i{(240 / 2) + (w + 2), (134 / 2) + (h - 2)} - offset.cast<int32_t>()
134+
);
135+
136+
// draw the bigmaps of the arrows
137+
138+
// draw the string using the small font
139+
screen_base::large_text::template draw<FrameBuffer>(
140+
frame_buffer,
141+
str,
142+
klib::vector2i{
143+
(240 / 2) -
144+
static_cast<int32_t>(
145+
(klib::string::strlen(str) * screen_base::large_text::font::width) / 2
146+
), 2
147+
} - offset.cast<int32_t>(),
148+
klib::graphics::white
149+
);
150+
151+
// draw the string using the small font
152+
screen_base::large_text::template draw<FrameBuffer>(
153+
frame_buffer,
154+
ptr,
155+
klib::vector2i{
156+
(240 / 2) -
157+
static_cast<int32_t>(
158+
(klib::string::strlen(ptr) * screen_base::large_text::font::width) / 2
159+
), (134 / 2) - (screen_base::large_text::font::height / 2)
160+
} - offset.cast<int32_t>(),
161+
klib::graphics::white
162+
);
163+
}
164+
};
165+
}

ui/screen_id.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ namespace menu {
1010
config,
1111
mouse,
1212
numeric_popup,
13+
string_popup,
1314
};
1415
}

ui/settings.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ namespace menu {
3232
// all the text fields in the settings menu
3333
constexpr static char labels[label_count][16] = {
3434
"usb mode",
35-
"set time",
36-
"set cal",
35+
"time",
36+
"rtc cal",
3737
"usb jiggler",
3838
"version",
3939
};

ui/time.hpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ namespace menu {
105105

106106
// go back one screen
107107
current = static_cast<steps>(static_cast<uint32_t>(current) - 1);
108+
109+
// change to the previous screen
110+
change_screen(current);
108111
}
109112

110113
void change_screen(const steps current) {
@@ -181,18 +184,14 @@ namespace menu {
181184
{}
182185

183186
virtual void main(const klib::time::us delta, const input::buttons& buttons) override {
184-
// check for the first entry
185-
if (current == steps::timezone) {
186-
// show the first screen
187-
change_screen(current);
188-
}
189-
else {
190-
// reset and go back to the previous screen
191-
current = steps::year;
187+
// change to the first step when we are called. We
188+
// are only called from the settings menu. The
189+
// popup callbacks will skip this by changing
190+
// directly to the new popup
191+
current = steps::timezone;
192192

193-
// go back
194-
screen_base::buffer.back();
195-
}
193+
// show the first screen
194+
change_screen(current);
196195
}
197196

198197
virtual void draw(FrameBuffer& frame_buffer, const klib::vector2u& offset) override {

0 commit comments

Comments
 (0)