Wheel side setting: rotate the display 180° for left-handed use

Hardware mirror in the ST7789 (rotation 3 <-> rotation 1); the 35-px
window offset is the same both ways. Stored in settings v3.
This commit is contained in:
Juli committed 2026-09-17 15:52:56 +02:00
1 parent 836e815f30
commit 33089b95ab
7 files changed
+28 -2

No files matched your search

+2
View File
@@ -72,6 +72,8 @@ Entries:
* **Theme** — the look of the menu, boot page and pop-ups, applied as you
cycle: *Phosphor* (green), *Pink*, *Amber*, *Ice*, and *Terminal* (green with
an 8×16 pixel font). The camera caption keeps its own neutral style.
* **Wheel side** — *Right* (as built) or *Left*: rotates the picture 180° so
you can turn the unit round and keep the knob under your left hand.
* **Forget a favourite**, **Wi-Fi setup** (reboots into the hotspot), **Power
off**, the board name with its IP, and the power source.
+11
View File
@@ -97,3 +97,14 @@ void display_off(void)
display_set_backlight(0);
if (panel) esp_lcd_panel_disp_on_off(panel, false);
}
void display_set_flipped(bool flipped)
{
if (!panel) return;
// Rotation 3 (MV|MY) is the stock orientation; rotation 1 (MV|MX) is its 180° twin.
// The 170-px window is centred in the 240-column RAM, so the 35-px gap is the same both ways.
lvgl_port_lock(0);
esp_lcd_panel_mirror(panel, flipped, !flipped);
lv_obj_invalidate(lv_screen_active());
lvgl_port_unlock();
}
+3
View File
@@ -1,4 +1,5 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#define LCD_H_RES 320
@@ -10,3 +11,5 @@ void display_init(void);
void display_set_backlight(uint8_t percent);
// Panel sleep-in (used before powering down).
void display_off(void);
// 180° rotation so the knob can sit on the left; redraws the current screen.
void display_set_flipped(bool flipped);
+1
View File
@@ -38,6 +38,7 @@ void app_main(void)
leds_set_mode(LED_BREATHE, 0x404040);
display_init();
display_set_flipped(settings.flip);
ui_init();
ui_set_theme(settings.theme);
ui_status("insecam widget", "starting");
+7 -1
View File
@@ -20,7 +20,7 @@ static const char *TAG = "menu";
typedef enum { VIEW_TOP, VIEW_FAV_PLAY, VIEW_FAV_SAVE, VIEW_FAV_FORGET } view_t;
enum { ROW_FAV_TOGGLE, ROW_FAVS, ROW_SOURCE, ROW_PROVIDER, ROW_INTERVAL, ROW_LISTING, ROW_LCD, ROW_RING,
ROW_CAPTION, ROW_THEME, ROW_FORGET, ROW_WIFI, ROW_POWER, ROW_IP, ROW_BATTERY, ROW_CLOSE, TOP_ROWS };
ROW_CAPTION, ROW_THEME, ROW_FLIP, ROW_FORGET, ROW_WIFI, ROW_POWER, ROW_IP, ROW_BATTERY, ROW_CLOSE, TOP_ROWS };
static ui_menu_row_t rows[TOP_ROWS > FAV_SLOTS + 1 ? TOP_ROWS : FAV_SLOTS + 1];
static char values[TOP_ROWS][20];
@@ -54,6 +54,7 @@ static int build_top(const cam_info_t *current, int fav_slot)
rows[ROW_RING] = (ui_menu_row_t){"Ring brightness", values[ROW_RING], false};
rows[ROW_CAPTION] = (ui_menu_row_t){"Caption", settings.caption ? "Shown" : "Hidden", false};
rows[ROW_THEME] = (ui_menu_row_t){"Theme", ui_theme_name(settings.theme), false};
rows[ROW_FLIP] = (ui_menu_row_t){"Wheel side", settings.flip ? "Left" : "Right", false};
rows[ROW_FORGET] = (ui_menu_row_t){"Forget a favourite", NULL, fav_count() == 0};
rows[ROW_WIFI] = (ui_menu_row_t){"Wi-Fi setup", NULL, false};
rows[ROW_POWER] = (ui_menu_row_t){"Power off", "knob wakes", false};
@@ -191,6 +192,11 @@ menu_result_t menu_run(const cam_info_t *current, int *fav_slot_out)
ui_set_theme(settings.theme);
settings_save();
break;
case ROW_FLIP:
settings.flip = !settings.flip;
display_set_flipped(settings.flip);
settings_save();
break;
case ROW_LISTING:
settings.listing = (settings.listing + 1) % 3;
settings_save();
+2
View File
@@ -46,6 +46,8 @@ void settings_init(void)
if (nvs_get_blob(nvs, "settings", &stored, &len) == ESP_OK && len >= 7 && len <= sizeof stored) {
memcpy(&settings, &stored, len);
if (len <= offsetof(settings_t, provider)) settings.provider = PROVIDER_PREF_MIXED; // pre-provider blob
if (settings.version < 3) settings.flip = 0; // field lived in padding before v3
settings.flip = settings.flip ? 1 : 0;
settings.version = SETTINGS_VERSION;
if (settings.interval_s < 5 || settings.interval_s > 300) settings.interval_s = CONFIG_WIDGET_INTERVAL_S;
if (settings.lcd_brightness > 100) settings.lcd_brightness = 100;
+2 -1
View File
@@ -18,8 +18,9 @@ typedef struct {
uint8_t provider; // provider_pref_t (appended; older blobs load with the default)
uint8_t version; // SETTINGS_VERSION; lets us tell a pre-provider blob apart
uint8_t theme; // ui theme index
uint8_t flip; // 1 = screen rotated 180° (knob on the left)
} settings_t;
#define SETTINGS_VERSION 2
#define SETTINGS_VERSION 3
extern settings_t settings;