ui-new: частота в настройках радио правится по разрядам (МГц шагом 1, кГц по символам)
This commit is contained in:
1 parent
24e2e48e1d
commit
e59a5f1759
2 files changed
+71
-10
No files matched your search
@@ -60,11 +60,14 @@ git merge upstream/main # правки для upstream отправляю
|
||||
|
||||
### Интерфейс (companion_radio / ui-new)
|
||||
|
||||
- **Настройка радио прямо с устройства** — страница RADIO, длинное нажатие: частота
|
||||
(шаг 25 кГц), ширина полосы, SF, CR и мощность передатчика. Значения применяются к радио
|
||||
сразу, в память пишутся по пункту `Save & exit`; через 5 минут простоя меню закрывается
|
||||
без сохранения и экран гаснет, а пока меню открыто — входящие сообщения не всплывают
|
||||
поверх него.
|
||||
- **Настройка радио прямо с устройства** — страница RADIO, длинное нажатие: частота,
|
||||
ширина полосы, SF, CR и мощность передатчика. Частота правится **по разрядам** (как в
|
||||
PosadMesh): целые МГц меняются шагом 1 МГц, а килогерцы — по символам (сотни, десятки,
|
||||
единицы). Короткое и двойное нажатие меняют активный разряд на ±1, длинное — переводит
|
||||
на следующий разряд, а после единиц кГц возвращает к списку; активный разряд показан
|
||||
инверсией. Значения применяются к радио сразу, в память пишутся по пункту `Save & exit`;
|
||||
через 5 минут простоя меню закрывается без сохранения и экран гаснет, а пока меню открыто —
|
||||
входящие сообщения не всплывают поверх него.
|
||||
- **Меню уведомлений** (длинное нажатие на первом экране): `Popups`, `Wake screen`
|
||||
(запретить автовключение дисплея по входящему сообщению; по кнопке экран работает),
|
||||
`Alerts` (звук+вибрация / только звук / только вибрация / выключено), `Channels`
|
||||
|
||||
@@ -41,7 +41,9 @@
|
||||
#ifndef UI_RADIO_FREQ_MAX
|
||||
#define UI_RADIO_FREQ_MAX 960.0f
|
||||
#endif
|
||||
#define UI_RADIO_FREQ_STEP_KHZ 25 // шаг перестройки частоты
|
||||
// Частота правится по разрядам, как в PosadMesh: целые МГц меняются шагом 1 МГц,
|
||||
// а килогерцы — по символам (сотни, десятки, единицы). Разряд 0 — МГц, 1..3 — кГц.
|
||||
#define UI_RADIO_FREQ_KHZ_DIGITS 3
|
||||
#define UI_RADIO_MENU_TIMEOUT_MILLIS 300000UL // 5 минут простоя — выйти из меню без сохранения
|
||||
#define NOTIFY_MAIN_ROWS 7 // строк в меню уведомлений
|
||||
|
||||
@@ -163,6 +165,7 @@ class HomeScreen : public UIScreen {
|
||||
bool _radio_edit;
|
||||
bool _radio_val_edit;
|
||||
uint8_t _radio_sel;
|
||||
uint8_t _radio_fq_pos; // активный разряд частоты: 0 — МГц, 1..3 — сотни/десятки/единицы кГц
|
||||
unsigned long _radio_last_activity; // для автовыхода из меню по простою
|
||||
|
||||
void radioEditEnter() {
|
||||
@@ -170,6 +173,7 @@ class HomeScreen : public UIScreen {
|
||||
_radio_edit = true;
|
||||
_radio_val_edit = false;
|
||||
_radio_sel = ROW_FQ;
|
||||
_radio_fq_pos = 0;
|
||||
_radio_last_activity = millis();
|
||||
}
|
||||
void radioEditLeave(bool save) {
|
||||
@@ -339,7 +343,7 @@ class HomeScreen : public UIScreen {
|
||||
public:
|
||||
HomeScreen(UITask* task, mesh::RTCClock* rtc, SensorManager* sensors, NodePrefs* node_prefs)
|
||||
: _task(task), _rtc(rtc), _sensors(sensors), _node_prefs(node_prefs), _page(0),
|
||||
_shutdown_init(false), _radio_edit(false), _radio_val_edit(false), _radio_sel(0),
|
||||
_shutdown_init(false), _radio_edit(false), _radio_val_edit(false), _radio_sel(0), _radio_fq_pos(0),
|
||||
_radio_last_activity(0), _theme_edit(false), _theme_sel(0), _theme_last_activity(0),
|
||||
_notify_screen(NOTIFY_OFF), _notify_sel(0), _notify_val_edit(false), _notify_last_activity(0),
|
||||
sensors_lpp(200) { }
|
||||
@@ -655,10 +659,16 @@ public:
|
||||
}
|
||||
if (c == KEY_ENTER) {
|
||||
if (_radio_val_edit) {
|
||||
_radio_val_edit = false; // назад к списку
|
||||
// у частоты долгое нажатие перебирает разряды, на последнем — возврат к списку
|
||||
if (_radio_sel == ROW_FQ && _radio_fq_pos < UI_RADIO_FREQ_KHZ_DIGITS) {
|
||||
_radio_fq_pos++;
|
||||
} else {
|
||||
_radio_val_edit = false; // назад к списку
|
||||
}
|
||||
} else if (_radio_sel == ROW_SAVE) {
|
||||
radioEditLeave(true); // сохранить в память и выйти
|
||||
} else {
|
||||
_radio_fq_pos = 0;
|
||||
_radio_val_edit = true; // править значение
|
||||
}
|
||||
return true;
|
||||
@@ -773,7 +783,16 @@ public:
|
||||
void HomeScreen::radioValueStep(int8_t dir) {
|
||||
switch (_radio_sel) {
|
||||
case ROW_FQ: {
|
||||
int32_t khz = (int32_t)(_node_prefs->freq * 1000.0f + 0.5f) + dir * UI_RADIO_FREQ_STEP_KHZ;
|
||||
// разрядное редактирование: целые МГц (±1 МГц), килогерцы — по символам
|
||||
int32_t khz = (int32_t)(_node_prefs->freq * 1000.0f + 0.5f);
|
||||
if (_radio_fq_pos == 0) {
|
||||
khz += dir * 1000;
|
||||
} else {
|
||||
int step = 1;
|
||||
for (uint8_t i = _radio_fq_pos; i < UI_RADIO_FREQ_KHZ_DIGITS; i++) step *= 10; // 100, 10, 1
|
||||
int digit = (khz / step) % 10;
|
||||
khz += ((digit + dir + 10) % 10 - digit) * step; // по кругу: 9 + 1 -> 0, 0 - 1 -> 9
|
||||
}
|
||||
int32_t lo = (int32_t)(UI_RADIO_FREQ_MIN * 1000.0f), hi = (int32_t)(UI_RADIO_FREQ_MAX * 1000.0f);
|
||||
if (khz < lo) khz = lo;
|
||||
if (khz > hi) khz = hi;
|
||||
@@ -846,8 +865,47 @@ void HomeScreen::renderRadioEditor(DisplayDriver& display) {
|
||||
char head[32];
|
||||
|
||||
if (_radio_val_edit) { // фаза правки значения
|
||||
if (_radio_sel == ROW_FQ) {
|
||||
// частота правится по разрядам: активный разряд инвертируем, чтобы было видно,
|
||||
// что именно меняется (целые МГц или один из разрядов кГц)
|
||||
int32_t khz = (int32_t)(_node_prefs->freq * 1000.0f + 0.5f);
|
||||
int mhz = khz / 1000, rem = khz % 1000;
|
||||
snprintf(buf, sizeof(buf), "%d.%03d", mhz, rem);
|
||||
|
||||
snprintf(head, sizeof(head), "FQ %.0f-%.0f MHz", UI_RADIO_FREQ_MIN, UI_RADIO_FREQ_MAX);
|
||||
display.setColor(UIColor::secondary_txt);
|
||||
display.setTextSize(1);
|
||||
display.drawTextLeftAlign(0, 2, head);
|
||||
|
||||
display.setColor(UIColor::warning_txt);
|
||||
display.setTextSize(2);
|
||||
int w = display.getTextWidth(buf);
|
||||
int x = (display.width() - w) / 2;
|
||||
const int y = 20;
|
||||
display.drawTextLeftAlign(x, y, buf);
|
||||
|
||||
char mhz_txt[8];
|
||||
snprintf(mhz_txt, sizeof(mhz_txt), "%d", mhz);
|
||||
int sel_len = _radio_fq_pos == 0 ? (int)strlen(mhz_txt) : 1;
|
||||
int sel_start = _radio_fq_pos == 0 ? 0 : (int)strlen(mhz_txt) + _radio_fq_pos; // +1 — точка
|
||||
char sel[10];
|
||||
if (sel_len > (int)sizeof(sel) - 1) sel_len = (int)sizeof(sel) - 1;
|
||||
memcpy(sel, buf + sel_start, sel_len);
|
||||
sel[sel_len] = 0;
|
||||
|
||||
const int char_w = 6 * 2; // шрифт моноширинный: 6 px на символ при размере 2
|
||||
display.setColor(UIColor::primary_txt);
|
||||
display.fillRect(x + sel_start * char_w - 1, y - 2, sel_len * char_w + 2, 20);
|
||||
display.setColor(UIColor::window_bkg);
|
||||
display.drawTextLeftAlign(x + sel_start * char_w, y, sel);
|
||||
|
||||
display.setColor(UIColor::secondary_txt);
|
||||
display.setTextSize(1);
|
||||
display.drawTextCentered(display.width() / 2, 64 - 10, "clk+ dbl- hold=next");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (_radio_sel) {
|
||||
case ROW_FQ: snprintf(head, sizeof(head), "FQ %.0f-%.0f MHz", UI_RADIO_FREQ_MIN, UI_RADIO_FREQ_MAX); break;
|
||||
case ROW_BW: strcpy(head, "BW 7.8-500 kHz"); break;
|
||||
case ROW_SF: strcpy(head, "SF 5-12"); break;
|
||||
case ROW_CR: strcpy(head, "CR 5-8"); break;
|
||||
|
||||
Reference in new issue
Block a user