From 99171e87a70452395b56cce713a951c1c2964370 Mon Sep 17 00:00:00 2001 From: Manuel <71137295+mverch67@users.noreply.github.com> Date: Sat, 29 Mar 2025 19:56:49 +0100 Subject: [PATCH] feat: node list <-> map navigation (#109) * allow full size boot logo * node list <-> map navigation --- generated/ui_320x240/ui.c | 2 +- include/graphics/map/MapPanel.h | 1 + include/graphics/view/TFT/TFTView_320x240.h | 1 + include/lv_conf.h | 2 +- source/graphics/TFT/TFTView_320x240.cpp | 37 +++++++++++++++++++-- source/graphics/map/MapPanel.cpp | 6 ++++ studio/320x240/TFT320x240.eez-project | 2 +- 7 files changed, 46 insertions(+), 5 deletions(-) diff --git a/generated/ui_320x240/ui.c b/generated/ui_320x240/ui.c index 700f885..9560ea6 100644 --- a/generated/ui_320x240/ui.c +++ b/generated/ui_320x240/ui.c @@ -23,7 +23,7 @@ static const void *getLvglImageByName(const char *name) { void loadScreen(enum ScreensEnum screenId) { currentScreen = screenId - 1; lv_obj_t *screen = getLvglObjectFromIndex(currentScreen); - lv_screen_load_anim(screen, LV_SCR_LOAD_ANIM_FADE_IN, 200, 0, false); + lv_screen_load_anim(screen, LV_SCR_LOAD_ANIM_NONE, 200, 0, false); } void ui_init_boot() { diff --git a/include/graphics/map/MapPanel.h b/include/graphics/map/MapPanel.h index 94c62c3..f7a7239 100644 --- a/include/graphics/map/MapPanel.h +++ b/include/graphics/map/MapPanel.h @@ -38,6 +38,7 @@ class MapPanel void getHomeLocation(float &lat, float &lon) const; // set new home position void setHomeLocation(float lat, float lon); + void setScrolledPosition(float lat, float lon); void setGpsPosition(float lat, float lon); bool scroll(int16_t deltaX, int16_t deltaY, uint16_t fraction = 3); // -1, 0, +1, 1/3 void moveHome(bool zoomDefault = true); diff --git a/include/graphics/view/TFT/TFTView_320x240.h b/include/graphics/view/TFT/TFTView_320x240.h index 83fb777..f45dc7b 100644 --- a/include/graphics/view/TFT/TFTView_320x240.h +++ b/include/graphics/view/TFT/TFTView_320x240.h @@ -366,6 +366,7 @@ class TFTView_320x240 : public MeshtasticView static void ui_event_mapBrightnessSlider(lv_event_t *e); static void ui_event_mapContrastSlider(lv_event_t *e); static void ui_event_mapNodeButton(lv_event_t *e); + static void ui_event_positionButton(lv_event_t *e); // animations static void ui_anim_node_panel_cb(void *var, int32_t v); diff --git a/include/lv_conf.h b/include/lv_conf.h index ba1d635..38a5441 100644 --- a/include/lv_conf.h +++ b/include/lv_conf.h @@ -299,7 +299,7 @@ *LV_LOG_LEVEL_USER Only logs added by the user *LV_LOG_LEVEL_NONE Do not log anything*/ - #define LV_LOG_LEVEL LV_LOG_LEVEL_WARN + #define LV_LOG_LEVEL LV_LOG_LEVEL_ERROR /*1: Print the log with 'printf'; *0: User need to register a callback with `lv_log_register_print_cb()`*/ diff --git a/source/graphics/TFT/TFTView_320x240.cpp b/source/graphics/TFT/TFTView_320x240.cpp index 0740eba..6c4d253 100644 --- a/source/graphics/TFT/TFTView_320x240.cpp +++ b/source/graphics/TFT/TFTView_320x240.cpp @@ -170,7 +170,14 @@ void TFTView_320x240::init(IClientBase *client) ui_init_boot(); FileLoader::init(&fileSystem); FileLoader::loadBootImage(objects.boot_logo); - lv_label_set_text(objects.firmware_label, firmware_version); + // if boot logo is too big remove the label and center the image + lv_obj_update_layout(objects.boot_logo); + if (lv_obj_get_height(objects.boot_logo) > lv_display_get_vertical_resolution(displaydriver->getDisplay()) / 2) { + lv_obj_set_pos(objects.boot_logo, 0, 0); + lv_obj_add_flag(objects.firmware_label, LV_OBJ_FLAG_HIDDEN); + } else { + lv_label_set_text(objects.firmware_label, firmware_version); + } time(&lastrun60); time(&lastrun10); @@ -2163,6 +2170,23 @@ void TFTView_320x240::ui_event_mapNodeButton(lv_event_t *e) lv_obj_t *panel = THIS->nodes[nodeNum]; THIS->ui_set_active(objects.nodes_button, objects.nodes_panel, objects.top_nodes_panel); lv_obj_scroll_to_view(panel, LV_ANIM_ON); + if (panel != currentPanel) + ui_event_NodeButton(e); +} + +void TFTView_320x240::ui_event_positionButton(lv_event_t *e) +{ + // navigate to position in map + lv_obj_t *p = (lv_obj_t *)e->user_data; + int32_t lat = (long)p->LV_OBJ_IDX(node_pos1_idx)->user_data; + int32_t lon = (long)p->LV_OBJ_IDX(node_pos2_idx)->user_data; + if (lat && lon) { + THIS->ui_set_active(objects.map_button, objects.map_panel, objects.top_map_panel); + if (!THIS->map) { + THIS->loadMap(); + } + THIS->map->setScrolledPosition(lat * 1e-7, lon * 1e-7); + } } void TFTView_320x240::ui_screen_event_cb(lv_event_t *e) @@ -2293,6 +2317,8 @@ void TFTView_320x240::loadMap(void) map = new MapPanel(objects.raw_map_panel); #endif map->setHomeLocationImage(objects.home_location_image); + lv_obj_add_flag(objects.home_location_image, LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_event_cb(objects.home_location_image, ui_event_mapNodeButton, LV_EVENT_CLICKED, (void *)ownNode); // center map to GPS > home > other nodes > default location if (db.config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT) { @@ -2368,6 +2394,7 @@ void TFTView_320x240::loadMap(void) float lat = 1e-7 * (long)p->LV_OBJ_IDX(node_pos1_idx)->user_data; float lon = 1e-7 * (long)p->LV_OBJ_IDX(node_pos2_idx)->user_data; map->add(it.first, lat, lon, drawObjectCB); + lv_obj_add_flag(it.second, LV_OBJ_FLAG_CLICKABLE); lv_obj_add_event_cb(it.second, ui_event_mapNodeButton, LV_EVENT_CLICKED, (void *)it.first); } } @@ -2461,10 +2488,15 @@ void TFTView_320x240::addOrUpdateMap(uint32_t nodeNum, int32_t lat, int32_t lon) lv_obj_t *p = nodes[nodeNum]; lv_label_set_text_fmt(lbl, "%s", lv_label_get_text(p->LV_OBJ_IDX(node_lbs_idx))); + // position label callback + lv_obj_add_flag(p->LV_OBJ_IDX(node_pos1_idx), LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_event_cb(p->LV_OBJ_IDX(node_pos1_idx), ui_event_positionButton, LV_EVENT_CLICKED, (void *)p); + nodeObjects[nodeNum] = img; if (map) { map->add(nodeNum, lat * 1e-7, lon * 1e-7, drawObjectCB); - lv_obj_add_event_cb(img, ui_event_mapNodeButton, LV_EVENT_CLICKED, (void *)p); + lv_obj_add_flag(img, LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_event_cb(img, ui_event_mapNodeButton, LV_EVENT_CLICKED, (void *)nodeNum); updateLocationMap(map->getObjectsOnMap()); } } else { @@ -2485,6 +2517,7 @@ void TFTView_320x240::removeFromMap(uint32_t nodeNum) updateLocationMap(map->getObjectsOnMap()); } nodeObjects.erase(nodeNum); + lv_obj_remove_event_cb(img, ui_event_mapNodeButton); lv_obj_delete(img); } diff --git a/source/graphics/map/MapPanel.cpp b/source/graphics/map/MapPanel.cpp index 7115c9d..56702a0 100644 --- a/source/graphics/map/MapPanel.cpp +++ b/source/graphics/map/MapPanel.cpp @@ -191,6 +191,12 @@ void MapPanel::setHomeLocation(float lat, float lon) center(); } +void MapPanel::setScrolledPosition(float lat, float lon) +{ + scrolled = GeoPoint(lat, lon, MapTileSettings::getZoomLevel()); + center(); +} + void MapPanel::setGpsPosition(float lat, float lon) { current = GeoPoint(lat, lon, MapTileSettings::getZoomLevel()); diff --git a/studio/320x240/TFT320x240.eez-project b/studio/320x240/TFT320x240.eez-project index 8044b4f..abd69de 100644 --- a/studio/320x240/TFT320x240.eez-project +++ b/studio/320x240/TFT320x240.eez-project @@ -85,7 +85,7 @@ { "objID": "6cd0436e-d32a-4b33-ca3e-8969abed1c80", "fileName": "ui.c", - "template": "#include \"ui.h\"\n#include \"images.h\"\n#include \n\nstatic int16_t currentScreen = -1;\n\nstatic lv_obj_t *getLvglObjectFromIndex(int32_t index) {\n if (index == -1) {\n return 0;\n }\n return ((lv_obj_t **)&objects)[index];\n}\n\nstatic const void *getLvglImageByName(const char *name) {\n for (size_t imageIndex = 0; imageIndex < sizeof(images) / sizeof(ext_img_desc_t); imageIndex++) {\n if (strcmp(images[imageIndex].name, name) == 0) {\n return images[imageIndex].img_dsc;\n }\n }\n return 0;\n}\n\nvoid loadScreen(enum ScreensEnum screenId) {\n currentScreen = screenId - 1;\n lv_obj_t *screen = getLvglObjectFromIndex(currentScreen);\n lv_screen_load_anim(screen, LV_SCR_LOAD_ANIM_FADE_IN, 200, 0, false);\n}\n\nvoid ui_init_boot() {\n lv_disp_t *dispp = lv_disp_get_default();\n lv_theme_t *theme = lv_theme_default_init(dispp, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED), false, LV_FONT_DEFAULT);\n lv_disp_set_theme(dispp, theme);\n \n create_screen_boot_screen();\n create_screen_blank_screen();\n loadScreen(SCREEN_ID_BOOT_SCREEN);\n}\n\nvoid ui_init() {\n //create_screens();\n create_screen_main_screen();\n create_screen_lock_screen();\n create_screen_calibration_screen();\n create_tabview_settings();\n}\n\nvoid ui_tick() {\n tick_screen(currentScreen);\n}\n" + "template": "#include \"ui.h\"\n#include \"images.h\"\n#include \n\nstatic int16_t currentScreen = -1;\n\nstatic lv_obj_t *getLvglObjectFromIndex(int32_t index) {\n if (index == -1) {\n return 0;\n }\n return ((lv_obj_t **)&objects)[index];\n}\n\nstatic const void *getLvglImageByName(const char *name) {\n for (size_t imageIndex = 0; imageIndex < sizeof(images) / sizeof(ext_img_desc_t); imageIndex++) {\n if (strcmp(images[imageIndex].name, name) == 0) {\n return images[imageIndex].img_dsc;\n }\n }\n return 0;\n}\n\nvoid loadScreen(enum ScreensEnum screenId) {\n currentScreen = screenId - 1;\n lv_obj_t *screen = getLvglObjectFromIndex(currentScreen);\n lv_screen_load_anim(screen, LV_SCR_LOAD_ANIM_NONE, 200, 0, false);\n}\n\nvoid ui_init_boot() {\n lv_disp_t *dispp = lv_disp_get_default();\n lv_theme_t *theme = lv_theme_default_init(dispp, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED), false, LV_FONT_DEFAULT);\n lv_disp_set_theme(dispp, theme);\n \n create_screen_boot_screen();\n create_screen_blank_screen();\n loadScreen(SCREEN_ID_BOOT_SCREEN);\n}\n\nvoid ui_init() {\n //create_screens();\n create_screen_main_screen();\n create_screen_lock_screen();\n create_screen_calibration_screen();\n create_tabview_settings();\n}\n\nvoid ui_tick() {\n tick_screen(currentScreen);\n}\n" } ], "destinationFolder": "../../generated/ui_320x240",