Skip to content

Commit 7485516

Browse files
committed
feat(qr): orientation-aware viewer layout with density/brightness/frame-rate settings
QR sizes to full content width (portrait) or height (landscape/square), with the progress bar vertical at the right on landscape. Controls (settings gear + Done) overlay the QR, shown on tap and auto-hidden; Done replaces tap-to-return so accidental taps don't leave the page. Settings persist to NVS; density changes regenerate parts and notify to restart the scan. Progress bar spans full extent with a minimum visible cell size. Sliders share theme_apply_slider() with min_touch-sized knob; screen brightness gets a 10% floor.
1 parent 03c7e78 commit 7485516

12 files changed

Lines changed: 584 additions & 199 deletions

File tree

main/core/settings.c

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ static const char *KEY_NETWORK = "def_net";
1313
static const char *KEY_BRIGHTNESS = "bright";
1414
static const char *KEY_AE_TARGET = "ae_tgt";
1515
static const char *KEY_FOCUS_POS = "focus";
16+
static const char *KEY_QR_DENSITY = "qr_dens";
17+
static const char *KEY_QR_SHADE = "qr_shade";
18+
static const char *KEY_QR_FPS = "qr_fps";
1619
static const char *KEY_PERMISSIVE_SIGNING = "perm_sign";
1720
static const char *KEY_PARTIAL_SIGNING = "part_sign";
1821
static const char *KEY_EXPECTED_OWNED_SIGNING = "exp_own_sign";
@@ -104,10 +107,12 @@ esp_err_t settings_set_network(wallet_network_t network) {
104107

105108
uint8_t settings_get_brightness(void) {
106109
uint8_t val = settings_get_u8_or_default(KEY_BRIGHTNESS, 50);
107-
return (val <= 100) ? val : 50;
110+
return (val >= BRIGHTNESS_MIN && val <= 100) ? val : 50;
108111
}
109112

110113
esp_err_t settings_set_brightness(uint8_t brightness) {
114+
if (brightness < BRIGHTNESS_MIN)
115+
brightness = BRIGHTNESS_MIN;
111116
if (brightness > 100)
112117
brightness = 100;
113118
return settings_set_u8_and_commit(KEY_BRIGHTNESS, brightness);
@@ -139,6 +144,47 @@ esp_err_t settings_set_focus_position(uint16_t position) {
139144
return settings_set_u16_and_commit(KEY_FOCUS_POS, position);
140145
}
141146

147+
uint16_t settings_get_qr_density(void) {
148+
uint16_t val =
149+
settings_get_u16_or_default(KEY_QR_DENSITY, QR_DENSITY_DEFAULT);
150+
return (val >= QR_DENSITY_MIN && val <= QR_DENSITY_MAX) ? val
151+
: QR_DENSITY_DEFAULT;
152+
}
153+
154+
esp_err_t settings_set_qr_density(uint16_t chars_per_frame) {
155+
if (chars_per_frame < QR_DENSITY_MIN)
156+
chars_per_frame = QR_DENSITY_MIN;
157+
if (chars_per_frame > QR_DENSITY_MAX)
158+
chars_per_frame = QR_DENSITY_MAX;
159+
return settings_set_u16_and_commit(KEY_QR_DENSITY, chars_per_frame);
160+
}
161+
162+
uint8_t settings_get_qr_shade(void) {
163+
uint8_t val = settings_get_u8_or_default(KEY_QR_SHADE, QR_SHADE_DEFAULT);
164+
return (val >= QR_SHADE_MIN && val <= QR_SHADE_MAX) ? val : QR_SHADE_DEFAULT;
165+
}
166+
167+
esp_err_t settings_set_qr_shade(uint8_t shade) {
168+
if (shade < QR_SHADE_MIN)
169+
shade = QR_SHADE_MIN;
170+
if (shade > QR_SHADE_MAX)
171+
shade = QR_SHADE_MAX;
172+
return settings_set_u8_and_commit(KEY_QR_SHADE, shade);
173+
}
174+
175+
uint8_t settings_get_qr_fps(void) {
176+
uint8_t val = settings_get_u8_or_default(KEY_QR_FPS, QR_FPS_DEFAULT);
177+
return (val >= QR_FPS_MIN && val <= QR_FPS_MAX) ? val : QR_FPS_DEFAULT;
178+
}
179+
180+
esp_err_t settings_set_qr_fps(uint8_t fps) {
181+
if (fps < QR_FPS_MIN)
182+
fps = QR_FPS_MIN;
183+
if (fps > QR_FPS_MAX)
184+
fps = QR_FPS_MAX;
185+
return settings_set_u8_and_commit(KEY_QR_FPS, fps);
186+
}
187+
142188
bool settings_get_permissive_signing(void) {
143189
return settings_get_bool_or_default(KEY_PERMISSIVE_SIGNING, false);
144190
}

main/core/settings.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,21 @@
66
#include "wallet.h"
77
#include <esp_err.h>
88

9+
#define BRIGHTNESS_MIN 10
910
#define AE_TARGET_MIN 2
1011
#define AE_TARGET_MAX 235
1112
#define AE_TARGET_DEFAULT 80
1213
#define FOCUS_POSITION_MAX 1023
1314
#define FOCUS_POSITION_DEFAULT 500
15+
#define QR_DENSITY_MIN 100
16+
#define QR_DENSITY_MAX 600
17+
#define QR_DENSITY_DEFAULT 400
18+
#define QR_SHADE_MIN 30
19+
#define QR_SHADE_MAX 100
20+
#define QR_SHADE_DEFAULT 100
21+
#define QR_FPS_MIN 1
22+
#define QR_FPS_MAX 5
23+
#define QR_FPS_DEFAULT 4
1424

1525
esp_err_t settings_init(void);
1626
wallet_network_t settings_get_network(void);
@@ -21,6 +31,12 @@ uint8_t settings_get_ae_target(void);
2131
esp_err_t settings_set_ae_target(uint8_t level);
2232
uint16_t settings_get_focus_position(void);
2333
esp_err_t settings_set_focus_position(uint16_t position);
34+
uint16_t settings_get_qr_density(void);
35+
esp_err_t settings_set_qr_density(uint16_t chars_per_frame);
36+
uint8_t settings_get_qr_shade(void);
37+
esp_err_t settings_set_qr_shade(uint8_t shade);
38+
uint8_t settings_get_qr_fps(void);
39+
esp_err_t settings_set_qr_fps(uint8_t fps);
2440
bool settings_get_permissive_signing(void);
2541
esp_err_t settings_set_permissive_signing(bool permissive);
2642
bool settings_get_partial_signing(void);

main/pages/login/login_settings.c

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ static void destroy_brightness_page(void);
3030

3131
static void brightness_slider_cb(lv_event_t *e) {
3232
lv_obj_t *slider = lv_event_get_target(e);
33-
int32_t val = lv_slider_get_value(slider);
34-
bsp_display_brightness_set(val);
35-
lv_label_set_text_fmt(brightness_label, "%d%%", (int)val);
33+
bsp_display_brightness_set(lv_slider_get_value(slider));
3634
}
3735

3836
static void brightness_back_cb(lv_event_t *e) {
@@ -51,28 +49,19 @@ static void show_brightness_page(void) {
5149
ui_create_back_button(brightness_screen, brightness_back_cb);
5250
theme_create_page_title(brightness_screen, "Screen Brightness");
5351

54-
// Percentage label
5552
uint8_t cur = settings_get_brightness();
5653
brightness_label = lv_label_create(brightness_screen);
57-
lv_label_set_text_fmt(brightness_label, "%d%%", (int)cur);
54+
lv_label_set_text(brightness_label, "Brightness");
5855
lv_obj_set_style_text_font(brightness_label, theme_font_medium(), 0);
5956
lv_obj_set_style_text_color(brightness_label, primary_color(), 0);
60-
lv_obj_align(brightness_label, LV_ALIGN_CENTER, 0, -30);
57+
lv_obj_align(brightness_label, LV_ALIGN_CENTER, 0, -theme_min_touch_size());
6158

62-
// Slider
6359
brightness_slider = lv_slider_create(brightness_screen);
64-
lv_slider_set_range(brightness_slider, 1, 100);
60+
lv_slider_set_range(brightness_slider, BRIGHTNESS_MIN, 100);
6561
lv_slider_set_value(brightness_slider, cur, LV_ANIM_OFF);
6662
lv_obj_set_width(brightness_slider, LV_HOR_RES * 60 / 100);
67-
lv_obj_set_height(brightness_slider, 10);
68-
lv_obj_align(brightness_slider, LV_ALIGN_CENTER, 0, 20);
69-
70-
// Style: orange knob and indicator, dark track
71-
lv_obj_set_style_bg_color(brightness_slider, highlight_color(),
72-
LV_PART_INDICATOR);
73-
lv_obj_set_style_bg_color(brightness_slider, highlight_color(), LV_PART_KNOB);
74-
lv_obj_set_style_bg_color(brightness_slider, panel_color(), LV_PART_MAIN);
75-
lv_obj_set_style_pad_all(brightness_slider, 8, LV_PART_KNOB);
63+
lv_obj_align(brightness_slider, LV_ALIGN_CENTER, 0, theme_button_spacing());
64+
theme_apply_slider(brightness_slider);
7665

7766
lv_obj_add_event_cb(brightness_slider, brightness_slider_cb,
7867
LV_EVENT_VALUE_CHANGED, NULL);

main/qr/encoder.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,19 @@ static void qr_blit_region(lv_obj_t *qr_obj, const uint8_t *qr_buf, int x0,
6363
lv_obj_invalidate(qr_obj);
6464
}
6565

66+
void qr_set_light_color(lv_obj_t *qr_obj, lv_color_t color) {
67+
if (!qr_obj)
68+
return;
69+
70+
lv_draw_buf_t *draw_buf = lv_canvas_get_draw_buf(qr_obj);
71+
if (!draw_buf)
72+
return;
73+
74+
lv_canvas_set_palette(qr_obj, 0, lv_color_to_32(color, LV_OPA_COVER));
75+
lv_image_cache_drop(draw_buf);
76+
lv_obj_invalidate(qr_obj);
77+
}
78+
6679
static bool is_all_digits(const char *data, size_t len) {
6780
for (size_t i = 0; i < len; i++) {
6881
if (!isdigit((unsigned char)data[i])) {

main/qr/encoder.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,17 @@ lv_obj_t *qr_create_optimal(lv_obj_t *parent, int32_t size, const char *text);
6161
*/
6262
void qr_resize(lv_obj_t *qr_obj, int32_t size);
6363

64+
/**
65+
* @brief Override the light-module (background) color of a QR widget.
66+
*
67+
* The blit step resets the palette to pure white on every encode, so this
68+
* must be re-applied after each qr_update_optimal/qr_update_binary call.
69+
*
70+
* @param qr_obj QR widget (canvas)
71+
* @param color Color for the light modules
72+
*/
73+
void qr_set_light_color(lv_obj_t *qr_obj, lv_color_t color);
74+
6475
/**
6576
* @brief Encode text/binary into a module buffer without drawing.
6677
*

main/qr/scanner.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -403,12 +403,8 @@ static void settings_close_cb(lv_event_t *e) { destroy_settings_overlay(); }
403403

404404
static void style_settings_slider(lv_obj_t *slider) {
405405
lv_obj_set_width(slider, LV_PCT(90));
406-
lv_obj_set_height(slider, 20);
407-
lv_obj_set_style_bg_color(slider, highlight_color(), LV_PART_INDICATOR);
408-
lv_obj_set_style_bg_color(slider, highlight_color(), LV_PART_KNOB);
409-
lv_obj_set_style_bg_color(slider, panel_color(), LV_PART_MAIN);
410-
lv_obj_set_style_pad_all(slider, 8, LV_PART_KNOB);
411-
lv_obj_set_style_margin_bottom(slider, 20, 0);
406+
theme_apply_slider(slider);
407+
lv_obj_set_style_margin_ver(slider, theme_slider_knob_pad(), 0);
412408
}
413409

414410
static void create_settings_overlay(void) {

0 commit comments

Comments
 (0)