mirror of
https://github.com/ratspeak/ratdeck.git
synced 2026-05-15 03:45:06 +00:00
07025bfa23
- Migrate all screens to LVGL v8.4 widget system - Non-blocking radio TX (async endPacket via LoRaInterface) - Live TCP server switching with transient node cleanup - Fix UI freeze during radio transmit - Trackball long-press delete, deferred click with debounce - Pin microReticulum to 392363c, fix list_directory API - Fix CI build: portable include path, remove hardcoded local path
82 lines
2.7 KiB
C++
82 lines
2.7 KiB
C++
#include "LvTabBar.h"
|
|
#include "Theme.h"
|
|
#include <cstdio>
|
|
|
|
constexpr const char* LvTabBar::TAB_NAMES[TAB_COUNT];
|
|
|
|
static void tab_click_cb(lv_event_t* e) {
|
|
LvTabBar* bar = (LvTabBar*)lv_event_get_user_data(e);
|
|
lv_obj_t* target = lv_event_get_target(e);
|
|
for (int i = 0; i < LvTabBar::TAB_COUNT; i++) {
|
|
lv_obj_t* parent = lv_obj_get_parent(target);
|
|
if (target == lv_obj_get_child(bar->obj(), i) ||
|
|
(parent && parent == lv_obj_get_child(bar->obj(), i))) {
|
|
bar->setActiveTab(i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void LvTabBar::create(lv_obj_t* parent) {
|
|
_bar = lv_obj_create(parent);
|
|
lv_obj_set_size(_bar, Theme::SCREEN_W, Theme::TAB_BAR_H);
|
|
lv_obj_align(_bar, LV_ALIGN_BOTTOM_LEFT, 0, 0);
|
|
lv_obj_set_style_bg_color(_bar, lv_color_hex(Theme::BG), 0);
|
|
lv_obj_set_style_bg_opa(_bar, LV_OPA_COVER, 0);
|
|
lv_obj_set_style_border_color(_bar, lv_color_hex(Theme::BORDER), 0);
|
|
lv_obj_set_style_border_width(_bar, 1, 0);
|
|
lv_obj_set_style_border_side(_bar, LV_BORDER_SIDE_TOP, 0);
|
|
lv_obj_set_style_pad_all(_bar, 0, 0);
|
|
lv_obj_set_style_radius(_bar, 0, 0);
|
|
lv_obj_clear_flag(_bar, LV_OBJ_FLAG_SCROLLABLE);
|
|
lv_obj_set_layout(_bar, LV_LAYOUT_FLEX);
|
|
lv_obj_set_flex_flow(_bar, LV_FLEX_FLOW_ROW);
|
|
lv_obj_set_flex_align(_bar, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
|
|
|
const lv_font_t* font = &lv_font_montserrat_12;
|
|
|
|
for (int i = 0; i < TAB_COUNT; i++) {
|
|
_tabs[i] = lv_label_create(_bar);
|
|
lv_obj_set_style_text_font(_tabs[i], font, 0);
|
|
lv_label_set_text(_tabs[i], TAB_NAMES[i]);
|
|
lv_obj_add_flag(_tabs[i], LV_OBJ_FLAG_CLICKABLE);
|
|
lv_obj_add_event_cb(_tabs[i], tab_click_cb, LV_EVENT_CLICKED, this);
|
|
}
|
|
|
|
refreshTabs();
|
|
}
|
|
|
|
void LvTabBar::setActiveTab(int tab) {
|
|
if (tab < 0 || tab >= TAB_COUNT) return;
|
|
_activeTab = tab;
|
|
refreshTabs();
|
|
if (_tabCb) _tabCb(tab);
|
|
}
|
|
|
|
void LvTabBar::cycleTab(int direction) {
|
|
int next = (_activeTab + direction + TAB_COUNT) % TAB_COUNT;
|
|
setActiveTab(next);
|
|
}
|
|
|
|
void LvTabBar::setUnreadCount(int tab, int count) {
|
|
if (tab < 0 || tab >= TAB_COUNT) return;
|
|
_unread[tab] = count;
|
|
refreshTabs();
|
|
}
|
|
|
|
void LvTabBar::refreshTabs() {
|
|
for (int i = 0; i < TAB_COUNT; i++) {
|
|
bool active = (i == _activeTab);
|
|
lv_obj_set_style_text_color(_tabs[i],
|
|
lv_color_hex(active ? Theme::TAB_ACTIVE : Theme::TAB_INACTIVE), 0);
|
|
|
|
char buf[24];
|
|
if (_unread[i] > 0) {
|
|
snprintf(buf, sizeof(buf), "%s(%d)", TAB_NAMES[i], _unread[i]);
|
|
} else {
|
|
snprintf(buf, sizeof(buf), "%s", TAB_NAMES[i]);
|
|
}
|
|
lv_label_set_text(_tabs[i], buf);
|
|
}
|
|
}
|