Compare commits

..

No commits in common. "lvgl_9.1" and "main" have entirely different histories.

18 changed files with 322 additions and 267 deletions

View File

@ -3,30 +3,30 @@
#include "sleep_hal_esp32.h"
// -----------------------
// https://docs.lvgl.io/master/porting/display.html#two-buffers
// https://docs.lvgl.io/8.3/porting/display.html?highlight=lv_disp_draw_buf_init#buffering-modes
// With two buffers, the rendering and refreshing of the display become parallel operations
// Second buffer needs 15.360 bytes more memory in heap.
#define useTwoBuffersForlvgl
// Display flushing
static void my_disp_flush( lv_display_t *disp, const lv_area_t *area, uint8_t *px_map ) {
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
void my_disp_flush( lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p ){
uint32_t w = ( area->x2 - area->x1 + 1 );
uint32_t h = ( area->y2 - area->y1 + 1 );
tft.startWrite();
tft.setAddrWindow(area->x1, area->y1, w, h);
#ifdef useTwoBuffersForlvgl
tft.pushPixelsDMA((uint16_t*)px_map, w * h);
tft.pushPixelsDMA((uint16_t*)&color_p->full, w * h);
#else
tft.pushColors((uint16_t *)px_map, w * h, true);
tft.pushColors((uint16_t*)&color_p->full, w * h, true);
#endif
tft.endWrite();
lv_display_flush_ready(disp);
lv_disp_flush_ready( disp );
}
// Read the touchpad
static void my_touchpad_read(lv_indev_t *indev_driver, lv_indev_data_t *data) {
void my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data){
int16_t touchX;
int16_t touchY;
get_touchpoint(&touchX, &touchY);
@ -38,10 +38,10 @@ static void my_touchpad_read(lv_indev_t *indev_driver, lv_indev_data_t *data) {
}
if( !touched ){
data->state = LV_INDEV_STATE_RELEASED;
data->state = LV_INDEV_STATE_REL;
}
else{
data->state = LV_INDEV_STATE_PRESSED;
data->state = LV_INDEV_STATE_PR;
// Set the coordinates
data->point.x = SCR_WIDTH - touchX;
@ -56,40 +56,35 @@ static void my_touchpad_read(lv_indev_t *indev_driver, lv_indev_data_t *data) {
}
}
/*LVGL draw into this buffer, 1/10 screen size usually works well. The size is in bytes*/
#define DRAW_BUF_SIZE (SCR_WIDTH * SCR_HEIGHT / 10 * (LV_COLOR_DEPTH / 8))
static uint32_t my_tick_get_cb(void) {
return millis();
}
static lv_disp_draw_buf_t draw_buf;
void init_lvgl_HAL() {
// first init TFT
init_tft();
// new in lvgl 9
lv_tick_set_cb(my_tick_get_cb);
// https://github.com/lvgl/lvgl/blob/release/v9.0/docs/CHANGELOG.rst#display-api
// https://docs.lvgl.io/master/get-started/quick-overview.html#add-lvgl-into-your-project
lv_display_t *disp = lv_display_create(SCR_WIDTH, SCR_HEIGHT);
lv_display_set_flush_cb(disp, my_disp_flush);
// https://github.com/lvgl/lvgl/blob/release/v9.0/docs/CHANGELOG.rst#migration-guide
// lv_display_set_buffers(display, buf1, buf2, buf_size_byte, mode) is more or less the equivalent of lv_disp_draw_buf_init(&draw_buf_dsc, buf1, buf2, buf_size_px) from v8, however in v9 the buffer size is set in bytes.
#ifdef useTwoBuffersForlvgl
uint8_t *bufA = (uint8_t *) malloc(DRAW_BUF_SIZE);
uint8_t *bufB = (uint8_t *) malloc(DRAW_BUF_SIZE);
lv_display_set_buffers(disp, bufA, bufB, DRAW_BUF_SIZE, LV_DISPLAY_RENDER_MODE_PARTIAL);
lv_color_t * bufA = (lv_color_t *) malloc(sizeof(lv_color_t) * SCR_WIDTH * SCR_HEIGHT / 10);
lv_color_t * bufB = (lv_color_t *) malloc(sizeof(lv_color_t) * SCR_WIDTH * SCR_HEIGHT / 10);
lv_disp_draw_buf_init(&draw_buf, bufA, bufB, SCR_WIDTH * SCR_HEIGHT / 10);
#else
uint8_t *bufA = (uint8_t *) malloc(DRAW_BUF_SIZE);
lv_display_set_buffers(disp, bufA, NULL, DRAW_BUF_SIZE, LV_DISPLAY_RENDER_MODE_PARTIAL);
lv_color_t * bufA = (lv_color_t *) malloc(sizeof(lv_color_t) * SCR_WIDTH * SCR_HEIGHT / 10);
lv_disp_draw_buf_init(&draw_buf, bufA, NULL, SCR_WIDTH * SCR_HEIGHT / 10);
#endif
// Initialize the display driver --------------------------------------------------------------------------
static lv_disp_drv_t disp_drv;
lv_disp_drv_init( &disp_drv );
disp_drv.hor_res = SCR_WIDTH;
disp_drv.ver_res = SCR_HEIGHT;
disp_drv.flush_cb = my_disp_flush;
disp_drv.draw_buf = &draw_buf;
lv_disp_drv_register( &disp_drv );
// Initialize the touchscreen driver
// https://github.com/lvgl/lvgl/blob/release/v9.0/docs/CHANGELOG.rst#indev-api
static lv_indev_t * indev = lv_indev_create();
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
lv_indev_set_read_cb(indev, my_touchpad_read);
static lv_indev_drv_t indev_drv;
lv_indev_drv_init( &indev_drv );
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = my_touchpad_read;
lv_indev_drv_register( &indev_drv );
}

View File

@ -23,7 +23,7 @@ long HeapUsed()
#elif defined(__linux__)
long HeapUsed() {
// don't know how to get used heap size in linux
return 80000;
return 800000;
}
#endif

View File

@ -1,4 +1,44 @@
#include <stdlib.h>
#include <sys/time.h>
#include <lvgl.h>
#include <SDL2/SDL_thread.h>
#include "sdl/sdl.h"
#include "SDL2/SDL_events.h"
long long current_timestamp_hal_windowsLinux() {
struct timeval te;
gettimeofday(&te, NULL); // get current time
long long milliseconds = te.tv_sec*1000LL + te.tv_usec/1000; // calculate milliseconds
// printf("milliseconds: %lld\r\n", milliseconds);
return milliseconds;
}
/**
* A task to measure the elapsed time for LittlevGL
* @param data unused
* @return never return
*/
static int tick_thread(void * data)
{
(void)data;
long long lastTimestamp = current_timestamp_hal_windowsLinux();
long long newTimestamp = 0;
while(1) {
// we don't use this blackbox
// SDL_Delay(5); /*Sleep for 5 millisecond*/
// lv_tick_inc(5); /*Tell lvgl that 5 milliseconds were elapsed*/
newTimestamp = current_timestamp_hal_windowsLinux();
if ((newTimestamp - lastTimestamp) > 5) {
lv_tick_inc(newTimestamp - lastTimestamp);
lastTimestamp = newTimestamp;
}
}
return 0;
}
static lv_disp_draw_buf_t draw_buf;
void init_lvgl_HAL() {
// Workaround for sdl2 `-m32` crash
@ -7,33 +47,63 @@ void init_lvgl_HAL() {
setenv("DBUS_FATAL_WARNINGS", "0", 1);
#endif
// https://github.com/lvgl/lv_platformio/issues/59
// https://github.com/lvgl/lv_port_pc_eclipse/blob/master/main.c#L111
// https://github.com/lvgl/lv_port_pc_eclipse/blob/master/lv_conf.h#L832-L839
lv_group_set_default(lv_group_create());
#ifdef useTwoBuffersForlvgl
lv_color_t * bufA = (lv_color_t *) malloc(sizeof(lv_color_t) * SDL_HOR_RES * SDL_VER_RES / 10);
lv_color_t * bufB = (lv_color_t *) malloc(sizeof(lv_color_t) * SDL_HOR_RES * SDL_VER_RES / 10);
lv_disp_draw_buf_init(&draw_buf, bufA, bufB, SDL_HOR_RES * SDL_VER_RES / 10);
#else
lv_color_t * bufA = (lv_color_t *) malloc(sizeof(lv_color_t) * SDL_HOR_RES * SDL_VER_RES / 10);
lv_disp_draw_buf_init(&draw_buf, bufA, NULL, SDL_HOR_RES * SDL_VER_RES / 10);
#endif
lv_display_t * disp = lv_sdl_window_create(SDL_HOR_RES, SDL_VER_RES);
lv_display_set_default(disp);
// Initialize the display driver --------------------------------------------------------------------------
static lv_disp_drv_t disp_drv;
lv_disp_drv_init( &disp_drv );
disp_drv.hor_res = SDL_HOR_RES;
disp_drv.ver_res = SDL_VER_RES;
disp_drv.flush_cb = sdl_display_flush; /*Used when `LV_VDB_SIZE != 0` in lv_conf.h (buffered drawing)*/
disp_drv.draw_buf = &draw_buf;
//disp_drv.disp_fill = monitor_fill; /*Used when `LV_VDB_SIZE == 0` in lv_conf.h (unbuffered drawing)*/
//disp_drv.disp_map = monitor_map; /*Used when `LV_VDB_SIZE == 0` in lv_conf.h (unbuffered drawing)*/
lv_disp_drv_register( &disp_drv );
lv_indev_t * mouse = lv_sdl_mouse_create();
lv_indev_set_group(mouse, lv_group_get_default());
lv_indev_set_display(mouse, disp);
/* Add the mouse as input device
* Use the 'mouse' driver which reads the PC's mouse*/
static lv_indev_drv_t indev_drv_mouse;
lv_indev_drv_init( &indev_drv_mouse );
indev_drv_mouse.type = LV_INDEV_TYPE_POINTER;
indev_drv_mouse.read_cb = sdl_mouse_read; /*This function will be called periodically (by the library) to get the mouse position and state*/
lv_indev_drv_register( &indev_drv_mouse );
// LV_IMAGE_DECLARE(mouse_cursor_icon); /*Declare the image file.*/
// lv_obj_t * cursor_obj;
// cursor_obj = lv_image_create(lv_screen_active()); /*Create an image object for the cursor */
// lv_image_set_src(cursor_obj, &mouse_cursor_icon); /*Set the image source*/
// lv_indev_set_cursor(mouse, cursor_obj); /*Connect the image object to the driver*/
// /* Add the keyboard as input device
// * did not work */
// static lv_indev_drv_t indev_drv_keyboard;
// lv_indev_drv_init( &indev_drv_keyboard );
// indev_drv_keyboard.type = LV_INDEV_TYPE_KEYPAD;
// indev_drv_keyboard.read_cb = sdl_keyboard_read; /*This function will be called periodically (by the library) to get the keyboard events*/
// lv_indev_t *keyboard_device = lv_indev_drv_register( &indev_drv_keyboard );
// lv_group_t *group = lv_group_create();
// lv_indev_set_group(keyboard_device, group);
// lv_group_add_obj(group, lv_scr_act());
// lv_group_add_obj(group, tabview);
// lv_group_add_obj(group, lv_tabview_get_content(tabview));
// lv_group_add_obj(group, tabs);
//
// need to be in a loop
// printf("last key: %d\n",lv_indev_get_key(keyboard_device));
lv_indev_t * mousewheel = lv_sdl_mousewheel_create();
lv_indev_set_display(mousewheel, disp);
lv_indev_set_group(mousewheel, lv_group_get_default());
sdl_init();
lv_indev_t * keyboard = lv_sdl_keyboard_create();
lv_indev_set_display(keyboard, disp);
lv_indev_set_group(keyboard, lv_group_get_default());
// Get the SDL window via an event
SDL_Event aWindowIdFinder;
SDL_PollEvent(&aWindowIdFinder);
SDL_Window *mSimWindow = SDL_GetWindowFromID(aWindowIdFinder.window.windowID);
SDL_SetWindowTitle(mSimWindow, "OMOTE simulator");
lv_sdl_window_set_title(disp, "OMOTE simulator");
lv_sdl_window_set_zoom(disp, SDL_ZOOM);
/* Tick init.
* You have to call 'lv_tick_inc()' in periodically to inform lvgl about how much time were elapsed
* Create an SDL thread to do this*/
SDL_CreateThread(tick_thread, "tick", NULL);
}

View File

@ -16,7 +16,7 @@ default_envs = esp32
custom_screen_width = 240
custom_screen_heigth = 320
lib_deps =
lvgl/lvgl@^9.1.0
lvgl/lvgl@^8.3.11
build_flags =
;-- OMOTE -----------------------------------------------------------------
-D ENABLE_WIFI_AND_MQTT=1
@ -34,12 +34,14 @@ build_flags =
;-D OMOTE_LOG_LEVEL=OMOTE_LOG_LEVEL_VERBOSE
;-- lvgl ------------------------------------------------------------------
; lvgl variant 1:
; Don't use lv_conf.h. Tweak params via platfom.ini. See lv_conf_internal.h line 49. Don't change this line.
; Don't use lv_conf.h. Tweak params via platfom.ini. See lv_conf_internal.h line 31. Don't change this line.
-D LV_CONF_SKIP=1
; Set this in specific environments below. Will be different in Arduino and Windows/Linux
;-D LV_TICK_CUSTOM=1
; dynamic memory. Takes as much as it gets from heap (DRAM). Needs approx. 25%-30% more memory than static memory.
;-D LV_USE_STDLIB_MALLOC=1
;-D LV_MEM_CUSTOM=1
; Set this in specific environments below. 32 bit and 64 bit need differenz sizes.
;-D LV_USE_STDLIB_MALLOC=0
;-D LV_MEM_CUSTOM=0
;-D LV_MEM_SIZE="(32U * 1024U)"
; fonts and theme
-D LV_FONT_MONTSERRAT_10=1
@ -70,10 +72,8 @@ build_flags =
; ---------
; lvgl variant 2:
; or define where lv_conf.h is, relative to the `lvgl` folder
;-D LV_CONF_PATH=../../../../src/gui/lv_conf.h
;-D LV_CONF_PATH=../../../../src/gui_general_and_keys/lv_conf.h
; --- interesting lvgl debug infos (OSD)
; LV_USE_SYSMON needs to be set for LV_USE_PERF_MONITOR and LV_USE_MEM_MONITOR to work
;-D LV_USE_SYSMON=1
;-D LV_USE_PERF_MONITOR=1
;-D LV_USE_MEM_MONITOR=1
;-D LV_USE_REFR_DEBUG=1
@ -115,9 +115,11 @@ build_flags =
;-D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
;-D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
;-- lvgl arduino ----------------------------------------------------------
; use millis() from "Arduino.h" to tell the elapsed time in milliseconds
-D LV_TICK_CUSTOM=1
; static memory, will be allocated in static DRAM
-D LV_USE_STDLIB_MALLOC=0
-D LV_MEM_SIZE="(44U * 1024U)"
-D LV_MEM_CUSTOM=0
-D LV_MEM_SIZE="(32U * 1024U)"
;-- TFT_eSPI --------------------------------------------------------------
-D DISABLE_ALL_LIBRARY_WARNINGS=1
; The following lines replace the TFT_eSPI User_setup.h-file
@ -156,23 +158,30 @@ build_src_filter =
; use this if you are using Ubuntu or WSL2 (64 bit compiler)
[env:linux_64bit]
platform = native@^1.2.1
lib_deps =
${env.lib_deps}
;we need the master branch from github because of this commit https://github.com/lvgl/lv_drivers/commit/7b9dee11c93ad27e2591182457c1eba7677473be
lv_drivers=https://github.com/lvgl/lv_drivers
;lvgl/lv_drivers@^8.3.0
build_flags =
${env.build_flags}
;-- lvgl ------------------------------------------------------------------
; in lvgl 9, lv_drivers is not needed anymore
-D LV_USE_SDL=1
; 64 bit needs a lot more static memory
-D LV_USE_STDLIB_MALLOC=0
-D LV_MEM_SIZE="(88U * 1024U)"
;-- OMOTE -----------------------------------------------------------------
-D LV_MEM_CUSTOM=0
-D LV_MEM_SIZE="(64U * 1024U)"
;SDL2 from msys64
-l SDL2
; settings for lv_drivers
-D LV_LVGL_H_INCLUDE_SIMPLE
-D LV_DRV_NO_CONF
-D USE_SDL
-D SDL_INCLUDE_PATH="\"SDL2/SDL.h\""
-D SDL_HOR_RES=${env.custom_screen_width}
-D SDL_VER_RES=${env.custom_screen_heigth}
-D SDL_ZOOM=2
;-- hardware abstraction, needed to find hardwareLayer.h ------------------
-I hardware
-I hardware/windows_linux/lib/MQTT-C/include
;SDL2 from msys64
-l SDL2
build_src_filter =
+<*>
+<../hardware/windows_linux/*>
@ -192,14 +201,14 @@ extends = env:windows_64bit
build_unflags =
${env:windows_64bit.build_unflags}
;-- lvgl ------------------------------------------------------------------
-D LV_USE_STDLIB_MALLOC=0
-D LV_MEM_SIZE="(88U * 1024U)"
-D LV_MEM_CUSTOM=0
-D LV_MEM_SIZE="(64U * 1024U)"
build_flags =
${env:windows_64bit.build_flags}
;-- lvgl ------------------------------------------------------------------
; 32 bit needs exact the same lvgl memory as on ESP32
-D LV_MEM_CUSTOM=0
-D LV_MEM_SIZE="(44U * 1024U)"
-D LV_MEM_SIZE="(32U * 1024U)"
; Take care. If you have a 64 bit compiler, this setting will tell the compiler to cross compile to 32 bit.
; Compiling is successfull, but linker fails. So use this env only with a 32 bit compiler.
; Probably a custom linker script would be needed for cross compiling to work.

View File

@ -8,9 +8,7 @@
#include "scenes/scene__default.h"
lv_color_t color_primary = lv_color_hex(0x303030); // gray
lv_span_t* MemoryUsageSpanHeap = NULL;
lv_span_t* MemoryUsageSpanSeparator = NULL;
lv_span_t* MemoryUsageSpanLVGLmemory = NULL;
lv_obj_t* MemoryUsageLabel = NULL;
lv_obj_t* WifiLabel = NULL;
lv_obj_t* BluetoothLabel = NULL;
lv_obj_t* BattPercentageLabel = NULL;
@ -36,7 +34,7 @@ void guis_doTabCreationAfterSliding(int newTabID);
// callback when pageIndicator prev or next was clicked
void pageIndicator_navigate_event_cb(lv_event_t* e) {
lv_obj_t* target = (lv_obj_t*)lv_event_get_target(e);
lv_obj_t* target = lv_event_get_target(e);
int user_data = (intptr_t)(target->user_data);
if (user_data == 0) {
@ -54,8 +52,8 @@ void sceneLabel_or_pageIndicator_event_cb(lv_event_t* e) {
// callback for swipe down event to navigate to the scene selection page
void screen_gesture_event_cb(lv_event_t* e) {
lv_obj_t* screen = (lv_obj_t*)lv_event_get_current_target(e);
lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_active());
lv_obj_t* screen = lv_event_get_current_target(e);
lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act());
if (dir == LV_DIR_BOTTOM) {
omote_log_d("- Scene selection: swipe down received for navigating to scene selection page\r\n");
executeCommand(SCENE_SELECTION);
@ -71,7 +69,7 @@ void tabview_content_is_scrolling_event_cb(lv_event_t* e){
// screenwidth indicator ?? 2 small hidden buttons ??
int offset = SCR_WIDTH / 2 - 150 / 2 - 8 - 2*50 / 2 -4;
// get the object to which the event is sent
lv_obj_t* tabviewContent = (lv_obj_t*)lv_event_get_target(e);
lv_obj_t* tabviewContent = lv_event_get_target(e);
// Get the x coordinate of object and scroll panel accordingly
int16_t tabviewX = lv_obj_get_scroll_x(tabviewContent);
@ -107,18 +105,18 @@ static void tabview_animation_ready_cb(lv_anim_t* a) {
void tabview_tab_changed_event_cb(lv_event_t* e) {
if (lv_event_get_code(e) == LV_EVENT_VALUE_CHANGED) {
int newTabID = lv_tabview_get_tab_active((lv_obj_t*)lv_event_get_target(e));
int newTabID = lv_tabview_get_tab_act((lv_obj_t*)lv_event_get_target(e));
// Wait until the animation ended, then call "guis_doTabCreationAfterSliding(newTabID);"
// https://forum.lvgl.io/t/delete-a-tab-after-the-tabview-scroll-animation-is-complete/3155/4
lv_obj_t* myTabview = (lv_obj_t*)lv_event_get_target(e);
lv_obj_t* myTabview = lv_event_get_target(e);
lv_obj_t* tabContainer = lv_tabview_get_content(myTabview);
lv_anim_t* anim = lv_anim_get(tabContainer, NULL);
if(anim) {
// Swipe is not yet complete. User released the touch screen, an animation will bring it to the end.
// That's the normal (and only?) case for the tft touchscreen
newTabID_forLateTabCreation = newTabID;
lv_anim_set_completed_cb(anim, tabview_animation_ready_cb);
lv_anim_set_ready_cb(anim, tabview_animation_ready_cb);
} else {
// Swipe is complete, no additional animation is needed. Most likely only possible in simulator
omote_log_d("Change of tab detected, without animation at the end. Will directly do my job after sliding.\r\n");
@ -153,7 +151,7 @@ void init_gui(void) {
#endif
}
// Set the background color -------------------------------------------------------------------------------
lv_obj_set_style_bg_color(lv_screen_active(), lv_color_black(), LV_PART_MAIN);
lv_obj_set_style_bg_color(lv_scr_act(), lv_color_black(), LV_PART_MAIN);
// set default height and position of main widgets
setMainWidgetsHeightAndPosition();
// On startup, set current GUIname and GUIlist according to last state before going to sleep
@ -164,7 +162,7 @@ void init_gui(void) {
init_gui_status_bar();
// register callback for swipe down event to navigate to the scene selection page
lv_obj_add_event_cb(lv_screen_active(), screen_gesture_event_cb, LV_EVENT_GESTURE, NULL);
lv_obj_add_event_cb(lv_scr_act(), screen_gesture_event_cb, LV_EVENT_GESTURE, NULL);
}
@ -204,7 +202,7 @@ void showMemoryUsageBar(bool showBar) {
return;
if (showBar) {
// lv_obj_remove_flag(memoryUsageBar, LV_OBJ_FLAG_HIDDEN);
// lv_obj_clear_flag(memoryUsageBar, LV_OBJ_FLAG_HIDDEN);
lv_obj_set_size(memoryUsageBar, SCR_WIDTH, memoryUsageBarHeight);
lv_obj_align(memoryUsageBar, LV_ALIGN_TOP_MID, 0, memoryUsageBarTop);
lv_obj_set_size(statusbar, SCR_WIDTH, statusbarHeight);
@ -219,7 +217,7 @@ void showMemoryUsageBar(bool showBar) {
void init_gui_memoryUsage_bar() {
// Create a memory status text bar at the top -------------------------------------------------------------
memoryUsageBar = lv_button_create(lv_screen_active());
memoryUsageBar = lv_btn_create(lv_scr_act());
lv_obj_set_size(memoryUsageBar, SCR_WIDTH, memoryUsageBarHeight);
lv_obj_set_style_shadow_width(memoryUsageBar, 0, LV_PART_MAIN);
lv_obj_set_style_bg_color(memoryUsageBar, lv_color_black(), LV_PART_MAIN);
@ -230,21 +228,17 @@ void init_gui_memoryUsage_bar() {
lv_obj_set_style_pad_all(memoryUsageBar, 0, LV_PART_MAIN);
lv_obj_align(memoryUsageBar, LV_ALIGN_TOP_MID, 0, memoryUsageBarTop);
lv_obj_t * memoryUsageSpangroup = lv_spangroup_create(memoryUsageBar);
lv_obj_align(memoryUsageSpangroup, LV_ALIGN_TOP_LEFT, 0, labelsPositionTop);
lv_obj_set_style_text_font(memoryUsageSpangroup, &lv_font_montserrat_12, LV_PART_MAIN);
// label for heap usage
MemoryUsageSpanHeap = lv_spangroup_new_span(memoryUsageSpangroup);
// separator
MemoryUsageSpanSeparator = lv_spangroup_new_span(memoryUsageSpangroup);
// label for lvgl memory usage
MemoryUsageSpanLVGLmemory = lv_spangroup_new_span(memoryUsageSpangroup);
MemoryUsageLabel = lv_label_create(memoryUsageBar);
lv_label_set_text(MemoryUsageLabel, "");
lv_obj_align(MemoryUsageLabel, LV_ALIGN_TOP_LEFT, 0, labelsPositionTop);
lv_obj_set_style_text_font(MemoryUsageLabel, &lv_font_montserrat_12, LV_PART_MAIN);
lv_label_set_recolor(MemoryUsageLabel, true);
}
void init_gui_status_bar() {
// Create a status bar at the top -------------------------------------------------------------------------
statusbar = lv_button_create(lv_screen_active());
lv_obj_remove_flag(statusbar, LV_OBJ_FLAG_CLICKABLE);
statusbar = lv_btn_create(lv_scr_act());
lv_obj_clear_flag(statusbar, LV_OBJ_FLAG_CLICKABLE);
lv_obj_set_size(statusbar, SCR_WIDTH, statusbarHeight);
lv_obj_set_style_shadow_width(statusbar, 0, LV_PART_MAIN);
lv_obj_set_style_bg_color(statusbar, lv_color_black(), LV_PART_MAIN);
@ -341,19 +335,19 @@ void guis_doTabCreationForNavigateToLastActiveGUIofPreviousGUIlist() {
void setActiveTab(uint32_t index, lv_anim_enable_t anim_en, bool send_tab_changed_event) {
// unsigned long startTime = millis();
if (anim_en == LV_ANIM_ON) {
lv_tabview_set_active(tabview, index, LV_ANIM_ON);
lv_tabview_set_act(tabview, index, LV_ANIM_ON);
// startTime = millis();
// while (millis() - startTime < 1000) {
// lv_timer_handler();
// }
} else {
lv_tabview_set_active(tabview, index, LV_ANIM_OFF);
lv_tabview_set_act(tabview, index, LV_ANIM_OFF);
// lv_timer_handler();
// log_memory();
}
if (send_tab_changed_event) {
lv_obj_send_event(tabview, LV_EVENT_VALUE_CHANGED, NULL);
lv_event_send(tabview, LV_EVENT_VALUE_CHANGED, NULL);
}
}

View File

@ -4,9 +4,7 @@
#include "applicationInternal/gui/guiMemoryOptimizer.h"
// used by memoryUsage.cpp
extern lv_span_t* MemoryUsageSpanHeap;
extern lv_span_t* MemoryUsageSpanSeparator;
extern lv_span_t* MemoryUsageSpanLVGLmemory;
extern lv_obj_t* MemoryUsageLabel;
// used by guiStatusUpdate.cpp
extern lv_obj_t* BluetoothLabel;
extern lv_obj_t* BattPercentageLabel;

View File

@ -12,8 +12,10 @@ const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_GRADIENTL
0xfa, 0xf2, 0xea, 0xe2, 0xda, 0xd1, 0xc7, 0xbe, 0xb7, 0xae, 0xa6, 0x9e, 0x95, 0x8d, 0x84, 0x7d, 0x74, 0x6c, 0x62, 0x5a, 0x51, 0x48, 0x41, 0x38, 0x2f, 0x28, 0x1f, 0x17, 0x0f, 0x07,
};
const lv_image_dsc_t gradientLeft = {
.header.cf = LV_COLOR_FORMAT_A8,
const lv_img_dsc_t gradientLeft = {
.header.cf = LV_IMG_CF_ALPHA_8BIT,
.header.always_zero = 0,
.header.reserved = 0,
.header.w = 30,
.header.h = 1,
.data_size = 30,
@ -29,8 +31,10 @@ const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_GRADIENTR
0x07, 0x0f, 0x17, 0x1f, 0x28, 0x2f, 0x38, 0x41, 0x48, 0x51, 0x5a, 0x62, 0x6c, 0x74, 0x7d, 0x84, 0x8d, 0x95, 0x9e, 0xa6, 0xae, 0xb7, 0xbe, 0xc7, 0xd1, 0xda, 0xe2, 0xea, 0xf2, 0xfa,
};
const lv_image_dsc_t gradientRight = {
.header.cf = LV_COLOR_FORMAT_A8,
const lv_img_dsc_t gradientRight = {
.header.cf = LV_IMG_CF_ALPHA_8BIT,
.header.always_zero = 0,
.header.reserved = 0,
.header.w = 30,
.header.h = 1,
.data_size = 30,

View File

@ -114,7 +114,7 @@ void clear_tabview(lv_obj_t* tabview, t_gui_state *gui_state) {
lv_obj_remove_event_cb(tabview, tabview_tab_changed_event_cb);
lv_obj_remove_event_cb(tabview, tabview_content_is_scrolling_event_cb);
// delete tabview
lv_obj_delete(tabview);
lv_obj_del(tabview);
tabview = NULL;
}
@ -127,15 +127,15 @@ void clear_tabview(lv_obj_t* tabview, t_gui_state *gui_state) {
void clear_panel(lv_obj_t* panel, lv_obj_t* img1, lv_obj_t* img2) {
if (panel != NULL) {
lv_obj_delete(panel);
lv_obj_del(panel);
panel = NULL;
}
if (img1 != NULL) {
lv_obj_delete(img1);
lv_obj_del(img1);
img1 = NULL;
}
if (img2 != NULL) {
lv_obj_delete(img2);
lv_obj_del(img2);
img2 = NULL;
}
@ -143,9 +143,7 @@ void clear_panel(lv_obj_t* panel, lv_obj_t* img1, lv_obj_t* img2) {
lv_obj_t* create_tabview() {
// Setup a scrollable tabview for devices and settings ----------------------------------------------------
lv_obj_t* tabview = lv_tabview_create(lv_screen_active()); // Hide tab labels by setting their height to 0
lv_tabview_set_tab_bar_position(tabview, LV_DIR_TOP);
lv_tabview_set_tab_bar_size(tabview, 0);
lv_obj_t* tabview = lv_tabview_create(lv_scr_act(), LV_DIR_TOP, 0); // Hide tab labels by setting their height to 0
#ifdef drawRedBorderAroundMainWidgets
lv_obj_add_style(tabview, &style_red_border, LV_PART_MAIN);
#endif
@ -157,9 +155,9 @@ lv_obj_t* create_tabview() {
lv_obj_t* create_panel() {
// Create a page indicator at the bottom ------------------------------------------------------------------
lv_obj_t* panel = lv_obj_create(lv_screen_active());
lv_obj_remove_flag(panel, LV_OBJ_FLAG_CLICKABLE); // This indicator will not be clickable
lv_obj_remove_flag(panel, LV_OBJ_FLAG_SCROLLABLE); // This indicator will not be scrollable
lv_obj_t* panel = lv_obj_create(lv_scr_act());
lv_obj_clear_flag(panel, LV_OBJ_FLAG_CLICKABLE); // This indicator will not be clickable
lv_obj_clear_flag(panel, LV_OBJ_FLAG_SCROLLABLE); // This indicator will not be scrollable
lv_obj_set_size(panel, SCR_WIDTH, panelHeight);
lv_obj_set_flex_flow(panel, LV_FLEX_FLOW_ROW);
lv_obj_align(panel, LV_ALIGN_BOTTOM_MID, 0, 0);
@ -305,8 +303,8 @@ void doTabCreation_strategyMax3(lv_obj_t* tabview, t_gui_state *gui_state) {
}
}
LV_IMAGE_DECLARE(gradientLeft);
LV_IMAGE_DECLARE(gradientRight);
LV_IMG_DECLARE(gradientLeft);
LV_IMG_DECLARE(gradientRight);
void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv_obj_t* img2, t_gui_state *gui_state) {
omote_log_d(" Will fill panel with page indicators\r\n");
@ -322,7 +320,7 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv
}
// This small hidden button enables the page indicator to scroll further
lv_obj_t* btn = lv_button_create(panel);
lv_obj_t* btn = lv_btn_create(panel);
lv_obj_set_size(btn, 50, lv_pct(100));
lv_obj_set_style_shadow_width(btn, 0, LV_PART_MAIN);
lv_obj_set_style_opa(btn, LV_OPA_TRANSP, LV_PART_MAIN);
@ -340,8 +338,8 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv
3 4 -1 p p p b 1 <- last state, special case
*/
// first page indicator before the first tab
btn = lv_button_create(panel);
lv_obj_remove_flag(btn, LV_OBJ_FLAG_CLICKABLE);
btn = lv_btn_create(panel);
lv_obj_clear_flag(btn, LV_OBJ_FLAG_CLICKABLE);
lv_obj_set_size(btn, 150, lv_pct(100));
if (gui_state->gui_on_tab[0].gui_list_index == 0) {
lv_obj_set_style_bg_color(btn, lv_color_black(), LV_PART_MAIN);
@ -381,7 +379,7 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv
breadcrumpPosition = gui_state->gui_on_tab[i].gui_list_index +1;
// Create actual buttons for every tab
lv_obj_t* btn = lv_button_create(panel);
lv_obj_t* btn = lv_btn_create(panel);
if (i == gui_state->activeTabID) {
// only if this is the button for the currently active tab, make it clickable to get to scene selection gui
lv_obj_add_flag(btn, LV_OBJ_FLAG_CLICKABLE);
@ -470,8 +468,8 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv
}
// last page indicator after the last tab
btn = lv_button_create(panel);
lv_obj_remove_flag(btn, LV_OBJ_FLAG_CLICKABLE);
btn = lv_btn_create(panel);
lv_obj_clear_flag(btn, LV_OBJ_FLAG_CLICKABLE);
lv_obj_set_size(btn, 150, lv_pct(100));
// 4 at last position 4 at middle position only one tab available overall
if ((gui_state->gui_on_tab[2].gui_list_index == get_gui_list_active_withFallback()->size()-1) || (gui_state->gui_on_tab[1].gui_list_index == get_gui_list_active_withFallback()->size()-1) || (gui_state->gui_on_tab[1].gui_list_index == -1)) {
@ -481,14 +479,14 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv
}
// This small hidden button enables the page indicator to scroll further
btn = lv_button_create(panel);
btn = lv_btn_create(panel);
lv_obj_set_size(btn, 50, lv_pct(100));
lv_obj_set_style_shadow_width(btn, 0, LV_PART_MAIN);
lv_obj_set_style_opa(btn, LV_OPA_TRANSP, LV_PART_MAIN);
// creation of style was moved to init_gui(void)
// otherwise repeated calls of lv_style_init will lead to a memory leak of about 46 bytes each time
// https://docs.lvgl.io/master/overview/style.html?highlight=lv_style_t#initialize-styles-and-set-get-properties
// https://docs.lvgl.io/8.3/overview/style.html?highlight=lv_style_t#initialize-styles-and-set-get-properties
lv_obj_add_style(panel, &panel_style, 0);
#ifdef drawRedBorderAroundMainWidgets
lv_obj_add_style(panel, &style_red_border, LV_PART_MAIN);
@ -497,20 +495,18 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv
// Make the indicator fade out at the sides using gradient bitmaps
// Bitmaps are above the buttons and labels
// don't create it here
// img1 = lv_image_create(lv_screen_active());
lv_obj_set_size(img1, panelHeight, panelHeight); // stretch the 1-pixel high image to 30px
// img1 = lv_img_create(lv_scr_act());
lv_img_set_src(img1, &gradientLeft);
lv_obj_align(img1, LV_ALIGN_BOTTOM_LEFT, 0, 0);
lv_image_set_src(img1, &gradientLeft);
lv_image_set_inner_align(img1, LV_IMAGE_ALIGN_STRETCH);
lv_obj_set_size(img1, panelHeight, panelHeight); // stretch the 1-pixel high image to 30px
#ifdef drawRedBorderAroundMainWidgets
lv_obj_add_style(img1, &style_red_border, LV_PART_MAIN);
#endif
// don't create it here
// img2 = lv_image_create(lv_screen_active());
lv_obj_set_size(img2, panelHeight, panelHeight);
// img2 = lv_img_create(lv_scr_act());
lv_img_set_src(img2, &gradientRight);
lv_obj_align(img2, LV_ALIGN_BOTTOM_RIGHT, 0, 0);
lv_image_set_src(img2, &gradientRight);
lv_image_set_inner_align(img2, LV_IMAGE_ALIGN_STRETCH);
lv_obj_set_size(img2, panelHeight, panelHeight);
#ifdef drawRedBorderAroundMainWidgets
lv_obj_add_style(img2, &style_red_border, LV_PART_MAIN);
#endif
@ -595,12 +591,12 @@ void gui_memoryOptimizer_afterSliding(lv_obj_t** tabview, lv_obj_t** panel, lv_o
// only optional: delete and create the whole screen. Not necessary.
// Only used for a test. init_gui_status_bar() would need to be called again at a suitable place, because the status bar would also be deleted.
// lv_obj_t* oldscr = lv_screen_active();
// lv_obj_t* oldscr = lv_scr_act();
// // create new screen
// lv_obj_t* newscr = lv_obj_create(NULL);
// // load this new screen
// lv_screen_load(newscr);
// lv_obj_delete(oldscr);
// lv_scr_load(newscr);
// lv_obj_del(oldscr);
// 2. set gui_list_indices and the tab to be activated
setGUIlistIndicesToBeShown_afterSlide(&gui_state);
@ -696,15 +692,15 @@ void gui_memoryOptimizer_doContentCreation(lv_obj_t** tabview, lv_obj_t** panel,
// Create the panel for the page indicator. Panel itself takes about 2136 bytes for three tabs.
lv_obj_t* newPanel = create_panel();
*panel = newPanel;
*img1 = lv_image_create(lv_screen_active());
*img2 = lv_image_create(lv_screen_active());
*img1 = lv_img_create(lv_scr_act());
*img2 = lv_img_create(lv_scr_act());
fillPanelWithPageIndicator_strategyMax3(*panel, *img1, *img2, gui_state);
// now, as the correct tab is active, register again the events for the tabview
lv_obj_add_event_cb(*tabview, tabview_tab_changed_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
lv_obj_add_event_cb(lv_tabview_get_content(*tabview), tabview_content_is_scrolling_event_cb, LV_EVENT_SCROLL, NULL);
// Initialize scroll position of the page indicator
lv_obj_send_event(lv_tabview_get_content(*tabview), LV_EVENT_SCROLL, NULL);
lv_event_send(lv_tabview_get_content(*tabview), LV_EVENT_SCROLL, NULL);
// gui_memoryOptimizer_doContentCreation() is called as last step every time the 3 tabs are recreated.
// Save here the last_active_gui_list. If the used list changes in a future navigation, save the last_active_gui_list_index

View File

@ -5,7 +5,7 @@
bool showMemoryUsage = 0;
#if (LV_USE_STDLIB_MALLOC == 0)
#if LV_MEM_CUSTOM == 0
lv_mem_monitor_t mon;
#endif
@ -43,7 +43,7 @@ void doLogMemoryUsage() {
bool doESPHeapWarning = (freeSystemHeap < thresholdForESP32HeapFreeWarning);
bool doLVGLMemoryWarning = false;
#if (LV_USE_STDLIB_MALLOC == 0)
#if LV_MEM_CUSTOM == 0
int thresholdForLVGLmemoryFreeWarning = 20; // in percentage free
lv_mem_monitor(&mon);
doLVGLMemoryWarning = ((100 - mon.used_pct) < thresholdForLVGLmemoryFreeWarning);
@ -65,7 +65,7 @@ void doLogMemoryUsage() {
freeSystemHeap, float(freeSystemHeap) / systemHeapSize * 100,
maxAllocSystemHeap, minfreeSystemHeap);
#if (LV_USE_STDLIB_MALLOC == 0)
#if LV_MEM_CUSTOM == 0
if (doLVGLMemoryWarning) {
omote_log_w("WARNING: LVGL memory is getting low. You GUI might stop working. In that case, increase \"-D LV_MEM_SIZE\" in platformio.ini\r\n");
}
@ -82,69 +82,46 @@ void doLogMemoryUsage() {
#endif
if (showMemoryUsage) {
char bufferHeap[40];
char bufferLVGLmemory[40];
#ifdef SHOW_USED_MEMORY_INSTEAD_OF_FREE_IN_GUI
//sprintf(buffer, ESP32HeapWarnBegin.append("%lu/%lu (%.0f%%)").append(ESP32HeapWarnEnd).append(" / ").append(LVGLMemorWarnBegin).append("%lu/%lu (%d%%)").append(LVGLMemorWarnEnd).c_str(), systemHeapSize-freeSystemHeap, systemHeapSize, float(systemHeapSize-freeSystemHeap) / systemHeapSize * 100, mon.total_size - mon.free_size, mon.total_size, mon.used_pct);
sprintf(bufferHeap, std::string("").append("%lu/%lu (%.0f%%)\0").c_str(), systemHeapSize-freeSystemHeap, systemHeapSize, float(systemHeapSize-freeSystemHeap) / systemHeapSize * 100);
#if (LV_USE_STDLIB_MALLOC == 0)
sprintf(bufferLVGLmemory, std::string("").append("%lu/%lu (%d%%)\0").c_str(), mon.total_size - mon.free_size, mon.total_size, mon.used_pct);
char buffer[80];
std::string ESP32HeapWarnBegin = "#00ff00 "; // green
std::string ESP32HeapWarnEnd = "#";
std::string LVGLMemorWarnBegin = "#00ff00 "; // green
std::string LVGLMemorWarnEnd = "#";
if (doESPHeapWarning) {
ESP32HeapWarnBegin = "#ff0000 "; // red
ESP32HeapWarnEnd = "#";
}
if (doLVGLMemoryWarning) {
LVGLMemorWarnBegin = "#ff0000 "; // red
LVGLMemorWarnEnd = "#";
}
#if LV_MEM_CUSTOM != 0
#ifdef SHOW_USED_MEMORY_INSTEAD_OF_FREE_IN_GUI
sprintf(buffer, ESP32HeapWarnBegin.append("%lu/%lu (%.0f%%)").append(ESP32HeapWarnEnd).c_str() , systemHeapSize-freeSystemHeap, systemHeapSize, float(systemHeapSize-freeSystemHeap) / systemHeapSize * 100);
#else
sprintf(buffer, ESP32HeapWarnBegin.append("%lu/%lu (%.0f%%)").append(ESP32HeapWarnEnd).c_str() , freeSystemHeap, systemHeapSize, float(freeSystemHeap) / systemHeapSize * 100);
#endif
#else
//sprintf(buffer, ESP32HeapWarnBegin.append("%lu/%lu (%.0f%%)").append(ESP32HeapWarnEnd).append(" / ").append(LVGLMemorWarnBegin).append("%lu/%lu (%d%%)").append(LVGLMemorWarnEnd).c_str(), freeSystemHeap, systemHeapSize, float(freeSystemHeap) / systemHeapSize * 100, mon.free_size, mon.total_size, 100-mon.used_pct);
sprintf(bufferHeap, std::string("").append("%lu/%lu (%.0f%%)\0").c_str(), freeSystemHeap, systemHeapSize, float(freeSystemHeap) / systemHeapSize * 100);
#if (LV_USE_STDLIB_MALLOC == 0)
sprintf(bufferLVGLmemory, std::string("").append("%lu/%lu (%d%%)\0").c_str(), mon.free_size, mon.total_size, 100-mon.used_pct);
#ifdef SHOW_USED_MEMORY_INSTEAD_OF_FREE_IN_GUI
sprintf(buffer, ESP32HeapWarnBegin.append("%lu/%lu (%.0f%%)").append(ESP32HeapWarnEnd).append(" / ").append(LVGLMemorWarnBegin).append("%lu/%lu (%d%%)").append(LVGLMemorWarnEnd).c_str(), systemHeapSize-freeSystemHeap, systemHeapSize, float(systemHeapSize-freeSystemHeap) / systemHeapSize * 100, mon.total_size - mon.free_size, mon.total_size, mon.used_pct);
#else
sprintf(buffer, ESP32HeapWarnBegin.append("%lu/%lu (%.0f%%)").append(ESP32HeapWarnEnd).append(" / ").append(LVGLMemorWarnBegin).append("%lu/%lu (%d%%)").append(LVGLMemorWarnEnd).c_str(), freeSystemHeap, systemHeapSize, float(freeSystemHeap) / systemHeapSize * 100, mon.free_size, mon.total_size, 100-mon.used_pct);
#endif
#endif
// convert "." to ","
for (int i=0; i<strlen(bufferHeap); i++) {
if (bufferHeap[i] == '.') {
bufferHeap[i] = ',';
for (int i=0; i<strlen(buffer); i++) {
if (buffer[i] == '.') {
buffer[i] = ',';
}
}
for (int i=0; i<strlen(bufferLVGLmemory); i++) {
if (bufferLVGLmemory[i] == '.') {
bufferLVGLmemory[i] = ',';
}
if (MemoryUsageLabel != NULL) {
omote_log_v("inside doLogMemoryUsage: will do GUI log %s\r\n", buffer);
lv_label_set_text(MemoryUsageLabel, buffer);
}
// set text and color of heap used
if (MemoryUsageSpanHeap != NULL) {
lv_span_set_text(MemoryUsageSpanHeap, bufferHeap);
if (doESPHeapWarning) {
lv_style_set_text_color(&MemoryUsageSpanHeap->style, lv_palette_main(LV_PALETTE_RED));
} else {
lv_style_set_text_color(&MemoryUsageSpanHeap->style, lv_palette_main(LV_PALETTE_GREEN));
}
}
// only if LVGL's built in implementation of memory management is used
#if (LV_USE_STDLIB_MALLOC == 0)
// first the separator
if (MemoryUsageSpanSeparator != NULL) {
lv_span_set_text(MemoryUsageSpanSeparator, " / ");
}
// set text and color of LVGL memory used
if (MemoryUsageSpanLVGLmemory != NULL) {
lv_span_set_text(MemoryUsageSpanLVGLmemory, bufferLVGLmemory);
if (doLVGLMemoryWarning) {
lv_style_set_text_color(&MemoryUsageSpanLVGLmemory->style, lv_palette_main(LV_PALETTE_RED));
} else {
lv_style_set_text_color(&MemoryUsageSpanLVGLmemory->style, lv_palette_main(LV_PALETTE_GREEN));
}
}
#endif
} else {
// we don't show memory usage, so clear text
if (MemoryUsageSpanHeap != NULL) {
lv_span_set_text(MemoryUsageSpanHeap, "");
}
if (MemoryUsageSpanLVGLmemory != NULL) {
lv_span_set_text(MemoryUsageSpanLVGLmemory, "");
if (MemoryUsageLabel != NULL) {
lv_label_set_text(MemoryUsageLabel, "");
}
}
}

View File

@ -9,9 +9,9 @@
#include "devices/mediaPlayer/device_appleTV/device_appleTV.h"
// LVGL declarations
LV_IMAGE_DECLARE(appleTvIcon);
LV_IMAGE_DECLARE(appleDisplayIcon);
LV_IMAGE_DECLARE(appleBackIcon);
LV_IMG_DECLARE(appleTvIcon);
LV_IMG_DECLARE(appleDisplayIcon);
LV_IMG_DECLARE(appleBackIcon);
// Apple Key Event handler
static void appleKey_event_cb(lv_event_t* e) {
@ -25,34 +25,34 @@ void create_tab_content_appleTV(lv_obj_t* tab) {
// Add content to the Apple TV tab
// Add a nice apple tv logo
lv_obj_t* appleImg = lv_image_create(tab);
lv_image_set_src(appleImg, &appleTvIcon);
lv_obj_t* appleImg = lv_img_create(tab);
lv_img_set_src(appleImg, &appleTvIcon);
lv_obj_align(appleImg, LV_ALIGN_CENTER, 0, -60);
// create two buttons and add their icons accordingly
lv_obj_t* button = lv_button_create(tab);
lv_obj_t* button = lv_btn_create(tab);
lv_obj_align(button, LV_ALIGN_BOTTOM_LEFT, 10, 0);
lv_obj_set_size(button, 60, 60);
lv_obj_set_style_radius(button, 30, LV_PART_MAIN);
lv_obj_set_style_bg_color(button, color_primary, LV_PART_MAIN);
lv_obj_add_event_cb(button, appleKey_event_cb, LV_EVENT_CLICKED, (void*)1);
appleImg = lv_image_create(button);
lv_image_set_src(appleImg, &appleBackIcon);
lv_obj_set_style_image_recolor(appleImg, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_image_recolor_opa(appleImg, LV_OPA_COVER, LV_PART_MAIN);
appleImg = lv_img_create(button);
lv_img_set_src(appleImg, &appleBackIcon);
lv_obj_set_style_img_recolor(appleImg, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_img_recolor_opa(appleImg, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_align(appleImg, LV_ALIGN_CENTER, -3, 0);
button = lv_button_create(tab);
button = lv_btn_create(tab);
lv_obj_align(button, LV_ALIGN_BOTTOM_RIGHT, -10, 0);
lv_obj_set_size(button, 60, 60);
lv_obj_set_style_radius(button, 30, LV_PART_MAIN);
lv_obj_set_style_bg_color(button, color_primary, LV_PART_MAIN);
lv_obj_add_event_cb(button, appleKey_event_cb, LV_EVENT_CLICKED, (void*)2);
appleImg = lv_image_create(button);
lv_image_set_src(appleImg, &appleDisplayIcon);
lv_obj_set_style_image_recolor(appleImg, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_image_recolor_opa(appleImg, LV_OPA_COVER, LV_PART_MAIN);
appleImg = lv_img_create(button);
lv_img_set_src(appleImg, &appleDisplayIcon);
lv_obj_set_style_img_recolor(appleImg, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_img_recolor_opa(appleImg, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_align(appleImg, LV_ALIGN_CENTER, 0, 0);
}

View File

@ -54,11 +54,13 @@ const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t appleTvIcon_map[]
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x73, 0xf8, 0xc5, 0xba, 0xd6, 0xd7, 0xbd, 0xf0, 0x83, 0xa3, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x4a, 0xf3, 0x9c, 0xf8, 0xc5, 0x59, 0xce, 0x55, 0xad, 0x08, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, 0x73, 0x76, 0xb5, 0x39, 0xce, 0x7a, 0xd6, 0x39, 0xce, 0xd7, 0xbd, 0xd3, 0x9c, 0xec, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x4a, 0x0c, 0x63, 0x0c, 0x63, 0x0c, 0x63, 0x0c, 0x63, 0x0c, 0x63, 0x0c, 0x63, 0x0c, 0x63, 0x49, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const lv_image_dsc_t appleTvIcon = {
.header.cf = LV_COLOR_FORMAT_NATIVE,
const lv_img_dsc_t appleTvIcon = {
.header.cf = LV_IMG_CF_TRUE_COLOR,
.header.always_zero = 0,
.header.reserved = 0,
.header.w = 91,
.header.h = 42,
.data_size = 3822 * LV_COLOR_DEPTH / 8,
.data_size = 3822 * LV_COLOR_SIZE / 8,
.data = appleTvIcon_map,
};
@ -90,8 +92,10 @@ const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t appleDisplayIcon_m
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xd3, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdb, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
const lv_image_dsc_t appleDisplayIcon = {
.header.cf = LV_COLOR_FORMAT_A8,
const lv_img_dsc_t appleDisplayIcon = {
.header.cf = LV_IMG_CF_ALPHA_8BIT,
.header.always_zero = 0,
.header.reserved = 0,
.header.w = 25,
.header.h = 20,
.data_size = 500,
@ -131,8 +135,10 @@ const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_APPLEBACK
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0x18,
};
const lv_image_dsc_t appleBackIcon = {
.header.cf = LV_COLOR_FORMAT_A8,
const lv_img_dsc_t appleBackIcon = {
.header.cf = LV_IMG_CF_ALPHA_8BIT,
.header.always_zero = 0,
.header.reserved = 0,
.header.w = 13,
.header.h = 25,
.data_size = 325,

View File

@ -10,7 +10,7 @@
#include "scenes/scene__default.h"
// LVGL declarations
LV_IMAGE_DECLARE(lightbulb);
LV_IMG_DECLARE(lightbulb);
static lv_obj_t* lightToggleA;
static lv_obj_t* lightToggleB;
@ -31,7 +31,7 @@ std::map<char, uint16_t> key_commands_long_smarthome = {};
// Smart Home Toggle Event handler
static void smartHomeToggle_event_cb(lv_event_t* e){
std::string payload;
if (lv_obj_has_state((lv_obj_t*)lv_event_get_target(e), LV_STATE_CHECKED)) payload = "true";
if (lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED)) payload = "true";
else payload = "false";
// Publish an MQTT message based on the event user data
#if (ENABLE_WIFI_AND_MQTT == 1)
@ -43,7 +43,7 @@ static void smartHomeToggle_event_cb(lv_event_t* e){
// Smart Home Slider Event handler
static void smartHomeSlider_event_cb(lv_event_t* e){
lv_obj_t* slider = (lv_obj_t*)lv_event_get_target(e);
lv_obj_t* slider = lv_event_get_target(e);
char payload[8];
sprintf(payload, "%.2f", float(lv_slider_get_value(slider)));
std::string payload_str(payload);
@ -71,10 +71,10 @@ void create_tab_content_smarthome(lv_obj_t* tab) {
lv_obj_set_style_bg_color(menuBox, color_primary, LV_PART_MAIN);
lv_obj_set_style_border_width(menuBox, 0, LV_PART_MAIN);
lv_obj_t* bulbIcon = lv_image_create(menuBox);
lv_image_set_src(bulbIcon, &lightbulb);
lv_obj_set_style_image_recolor(bulbIcon, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_image_recolor_opa(bulbIcon, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_t* bulbIcon = lv_img_create(menuBox);
lv_img_set_src(bulbIcon, &lightbulb);
lv_obj_set_style_img_recolor(bulbIcon, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_img_recolor_opa(bulbIcon, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_align(bulbIcon, LV_ALIGN_TOP_LEFT, 0, 0);
menuLabel = lv_label_create(menuBox);
@ -84,7 +84,7 @@ void create_tab_content_smarthome(lv_obj_t* tab) {
if (lightToggleAstate) {
lv_obj_add_state(lightToggleA, LV_STATE_CHECKED);
} else {
// lv_obj_remove_state(lightToggleA, LV_STATE_CHECKED);
// lv_obj_clear_state(lightToggleA, LV_STATE_CHECKED);
}
lv_obj_set_size(lightToggleA, 40, 22);
lv_obj_align(lightToggleA, LV_ALIGN_TOP_RIGHT, 0, 0);
@ -111,10 +111,10 @@ void create_tab_content_smarthome(lv_obj_t* tab) {
lv_obj_set_style_bg_color(menuBox, color_primary, LV_PART_MAIN);
lv_obj_set_style_border_width(menuBox, 0, LV_PART_MAIN);
bulbIcon = lv_image_create(menuBox);
lv_image_set_src(bulbIcon, &lightbulb);
lv_obj_set_style_image_recolor(bulbIcon, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_image_recolor_opa(bulbIcon, LV_OPA_COVER, LV_PART_MAIN);
bulbIcon = lv_img_create(menuBox);
lv_img_set_src(bulbIcon, &lightbulb);
lv_obj_set_style_img_recolor(bulbIcon, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_img_recolor_opa(bulbIcon, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_align(bulbIcon, LV_ALIGN_TOP_LEFT, 0, 0);
menuLabel = lv_label_create(menuBox);
@ -124,7 +124,7 @@ void create_tab_content_smarthome(lv_obj_t* tab) {
if (lightToggleBstate) {
lv_obj_add_state(lightToggleB, LV_STATE_CHECKED);
} else {
// lv_obj_remove_state(lightToggleB, LV_STATE_CHECKED);
// lv_obj_clear_state(lightToggleB, LV_STATE_CHECKED);
}
lv_obj_set_size(lightToggleB, 40, 22);
lv_obj_align(lightToggleB, LV_ALIGN_TOP_RIGHT, 0, 0);

View File

@ -31,8 +31,10 @@ const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_LIGHTBULB
0x00, 0x00, 0x00, 0x01, 0x21, 0x22, 0x22, 0x21, 0x01, 0x00, 0x00, 0x00,
};
const lv_image_dsc_t lightbulb = {
.header.cf = LV_COLOR_FORMAT_A8,
const lv_img_dsc_t lightbulb = {
.header.cf = LV_IMG_CF_ALPHA_8BIT,
.header.always_zero = 0,
.header.reserved = 0,
.header.w = 12,
.header.h = 20,
.data_size = 240,

View File

@ -89,7 +89,7 @@ void showNewIRmessage(std::string message) {
// IR receiver on Switch Event handler
static void IRReceiverOnSetting_event_cb(lv_event_t* e){
set_irReceiverEnabled(lv_obj_has_state((lv_obj_t*)lv_event_get_target(e), LV_STATE_CHECKED));
set_irReceiverEnabled(lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED));
if (get_irReceiverEnabled()) {
omote_log_d("will turn on IR receiver\r\n");
start_infraredReceiver();

View File

@ -13,8 +13,8 @@
// Virtual Keypad Event handler
static void virtualKeypad_event_cb(lv_event_t* e) {
lv_obj_t* target = (lv_obj_t*)lv_event_get_target(e);
lv_obj_t* cont = (lv_obj_t*)lv_event_get_current_target(e);
lv_obj_t* target = lv_event_get_target(e);
lv_obj_t* cont = lv_event_get_current_target(e);
if (target == cont) return; // stop if container was clicked
int user_data = (intptr_t)(target->user_data);
@ -38,8 +38,8 @@ void create_tab_content_numpad(lv_obj_t* tab) {
// Configure number button grid
// A variable declared static inside a function is visible only inside that function, exists only once (not created/destroyed for each call) and is permanent. It is in a sense a private global variable.
static int32_t col_dsc[] = { LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST }; // equal x distribution
static int32_t row_dsc[] = { 52, 52, 52, 52, LV_GRID_TEMPLATE_LAST }; // manual y distribution to compress the grid a bit
static lv_coord_t col_dsc[] = { LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST }; // equal x distribution
static lv_coord_t row_dsc[] = { 52, 52, 52, 52, LV_GRID_TEMPLATE_LAST }; // manual y distribution to compress the grid a bit
// Create a container with grid for tab
lv_obj_set_style_pad_all(tab, 0, LV_PART_MAIN);
@ -63,7 +63,7 @@ void create_tab_content_numpad(lv_obj_t* tab) {
uint8_t row = i / 3;
// Create the button object
if ((row == 3) && ((col == 0) || (col == 2))) continue; // Do not create a complete fourth row, only a 0 button
obj = lv_button_create(cont);
obj = lv_btn_create(cont);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, col, 1, LV_GRID_ALIGN_STRETCH, row, 1);
lv_obj_set_style_bg_color(obj, color_primary, LV_PART_MAIN);
lv_obj_set_style_radius(obj, 14, LV_PART_MAIN);

View File

@ -103,7 +103,7 @@ void create_tab_content_sceneSelection(lv_obj_t* tab) {
scene_list scenes = get_scenes_on_sceneSelectionGUI();
if ((scenes != NULL) && (scenes->size() > 0)) {
for (int i=0; i<scenes->size(); i++) {
lv_obj_t* button = lv_button_create(tab);
lv_obj_t* button = lv_btn_create(tab);
lv_obj_set_size(button, lv_pct(100), 42);
lv_obj_set_style_radius(button, 30, LV_PART_MAIN);
lv_obj_set_style_bg_color(button, color_primary, LV_PART_MAIN);

View File

@ -7,8 +7,8 @@
#include "guis/gui_settings.h"
// LVGL declarations
LV_IMAGE_DECLARE(high_brightness);
LV_IMAGE_DECLARE(low_brightness);
LV_IMG_DECLARE(high_brightness);
LV_IMG_DECLARE(low_brightness);
lv_obj_t* objBattSettingsVoltage;
lv_obj_t* objBattSettingsPercentage;
@ -16,7 +16,7 @@ lv_obj_t* objBattSettingsPercentage;
// Slider Event handler
static void bl_slider_event_cb(lv_event_t* e){
lv_obj_t* slider = (lv_obj_t*)lv_event_get_target(e);
lv_obj_t* slider = lv_event_get_target(e);
int32_t slider_value = lv_slider_get_value(slider);
if (slider_value < 60) {slider_value = 60;}
if (slider_value > 255) {slider_value = 255;}
@ -25,12 +25,12 @@ static void bl_slider_event_cb(lv_event_t* e){
// Wakeup by IMU Switch Event handler
static void WakeEnableSetting_event_cb(lv_event_t* e){
set_wakeupByIMUEnabled(lv_obj_has_state((lv_obj_t*)lv_event_get_target(e), LV_STATE_CHECKED));
set_wakeupByIMUEnabled(lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED));
}
// timout event handler
static void timout_event_cb(lv_event_t* e){
lv_obj_t* drop = (lv_obj_t*)lv_event_get_target(e);
lv_obj_t* drop = lv_event_get_target(e);
uint16_t selected = lv_dropdown_get_selected(drop);
switch (selected) {
case 0: {set_sleepTimeout( 10000); break;}
@ -49,7 +49,7 @@ static void timout_event_cb(lv_event_t* e){
// show memory usage event handler
static void showMemoryUsage_event_cb(lv_event_t* e) {
setShowMemoryUsage(lv_obj_has_state((lv_obj_t*)lv_event_get_target(e), LV_STATE_CHECKED));
setShowMemoryUsage(lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED));
}
void create_tab_content_settings(lv_obj_t* tab) {
@ -69,10 +69,10 @@ void create_tab_content_settings(lv_obj_t* tab) {
lv_obj_set_style_bg_color(menuBox, color_primary, LV_PART_MAIN);
lv_obj_set_style_border_width(menuBox, 0, LV_PART_MAIN);
lv_obj_t* brightnessIcon = lv_image_create(menuBox);
lv_image_set_src(brightnessIcon, &low_brightness);
lv_obj_set_style_image_recolor(brightnessIcon, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_image_recolor_opa(brightnessIcon, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_t* brightnessIcon = lv_img_create(menuBox);
lv_img_set_src(brightnessIcon, &low_brightness);
lv_obj_set_style_img_recolor(brightnessIcon, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_img_recolor_opa(brightnessIcon, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_align(brightnessIcon, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_t* slider = lv_slider_create(menuBox);
lv_slider_set_range(slider, 60, 255);
@ -82,10 +82,10 @@ void create_tab_content_settings(lv_obj_t* tab) {
lv_slider_set_value(slider, get_backlightBrightness(), LV_ANIM_OFF);
lv_obj_set_size(slider, lv_pct(66), 10);
lv_obj_align(slider, LV_ALIGN_TOP_MID, 0, 3);
brightnessIcon = lv_image_create(menuBox);
lv_image_set_src(brightnessIcon, &high_brightness);
lv_obj_set_style_image_recolor(brightnessIcon, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_image_recolor_opa(brightnessIcon, LV_OPA_COVER, LV_PART_MAIN);
brightnessIcon = lv_img_create(menuBox);
lv_img_set_src(brightnessIcon, &high_brightness);
lv_obj_set_style_img_recolor(brightnessIcon, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_img_recolor_opa(brightnessIcon, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_align(brightnessIcon, LV_ALIGN_TOP_RIGHT, 0, -1);
lv_obj_add_event_cb(slider, bl_slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
@ -100,7 +100,7 @@ void create_tab_content_settings(lv_obj_t* tab) {
if (get_wakeupByIMUEnabled()) {
lv_obj_add_state(wakeToggle, LV_STATE_CHECKED);
} else {
// lv_obj_remove_state(wakeToggle, LV_STATE_CHECKED);
// lv_obj_clear_state(wakeToggle, LV_STATE_CHECKED);
}
menuLabel = lv_label_create(menuBox);
@ -193,7 +193,7 @@ void create_tab_content_settings(lv_obj_t* tab) {
if (getShowMemoryUsage()) {
lv_obj_add_state(memoryUsageToggle, LV_STATE_CHECKED);
} else {
// lv_obj_remove_state(memoryUsageToggle, LV_STATE_CHECKED);
// lv_obj_clear_state(memoryUsageToggle, LV_STATE_CHECKED);
}
}

View File

@ -29,8 +29,10 @@ const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_HIGH_BRIG
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
const lv_image_dsc_t high_brightness = {
.header.cf = LV_COLOR_FORMAT_A8,
const lv_img_dsc_t high_brightness = {
.header.cf = LV_IMG_CF_ALPHA_8BIT,
.header.always_zero = 0,
.header.reserved = 0,
.header.w = 18,
.header.h = 18,
.data_size = 324,
@ -61,8 +63,10 @@ const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_LOW_BRIGH
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
const lv_image_dsc_t low_brightness = {
.header.cf = LV_COLOR_FORMAT_A8,
const lv_img_dsc_t low_brightness = {
.header.cf = LV_IMG_CF_ALPHA_8BIT,
.header.always_zero = 0,
.header.reserved = 0,
.header.w = 16,
.header.h = 16,
.data_size = 256,