init Files

This commit is contained in:
2024-12-09 19:47:18 +01:00
parent b55a8cd2bc
commit 528e862838
3471 changed files with 1105029 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
Simple File Explorer
--------------------
.. lv_example:: others/file_explorer/lv_example_file_explorer_1
:language: c
Control File Explorer
---------------------
.. lv_example:: others/file_explorer/lv_example_file_explorer_2
:language: c
Custom sort
-----------
.. lv_example:: others/file_explorer/lv_example_file_explorer_3
:language: c

View File

@@ -0,0 +1,40 @@
/**
* @file lv_example_file_explorer.h
*
*/
#ifndef LV_EX_FILE_EXPLORER_H
#define LV_EX_FILE_EXPLORER_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_example_file_explorer_1(void);
void lv_example_file_explorer_2(void);
void lv_example_file_explorer_3(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_EX_FILE_EXPLORER_H*/

View File

@@ -0,0 +1,73 @@
#include "../../lv_examples.h"
#if LV_USE_TABLE && LV_USE_FILE_EXPLORER && (LV_USE_FS_STDIO || LV_USE_FS_POSIX || LV_USE_FS_WIN32 || LV_USE_FS_FATFS) && LV_BUILD_EXAMPLES
#include <stdlib.h>
#include <string.h>
static void file_explorer_event_handler(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t * obj = lv_event_get_target(e);
if(code == LV_EVENT_VALUE_CHANGED) {
const char * cur_path = lv_file_explorer_get_current_path(obj);
const char * sel_fn = lv_file_explorer_get_selected_file_name(obj);
LV_LOG_USER("%s%s", cur_path, sel_fn);
}
}
void lv_example_file_explorer_1(void)
{
lv_obj_t * file_explorer = lv_file_explorer_create(lv_screen_active());
lv_file_explorer_set_sort(file_explorer, LV_EXPLORER_SORT_KIND);
#if LV_USE_FS_WIN32
lv_file_explorer_open_dir(file_explorer, "D:");
#if LV_FILE_EXPLORER_QUICK_ACCESS
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_HOME_DIR, "C:/Users/Public/Desktop");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_VIDEO_DIR, "C:/Users/Public/Videos");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_PICTURES_DIR, "C:/Users/Public/Pictures");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_MUSIC_DIR, "C:/Users/Public/Music");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_DOCS_DIR, "C:/Users/Public/Documents");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_FS_DIR, "D:");
#endif
#else
/* linux */
lv_file_explorer_open_dir(file_explorer, "A:/");
#if LV_FILE_EXPLORER_QUICK_ACCESS
char * envvar = "HOME";
char home_dir[LV_FS_MAX_PATH_LENGTH];
strcpy(home_dir, "A:");
/* get the user's home directory from the HOME environment variable*/
strcat(home_dir, getenv(envvar));
LV_LOG_USER("home_dir: %s\n", home_dir);
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_HOME_DIR, home_dir);
char video_dir[LV_FS_MAX_PATH_LENGTH];
strcpy(video_dir, home_dir);
strcat(video_dir, "/Videos");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_VIDEO_DIR, video_dir);
char picture_dir[LV_FS_MAX_PATH_LENGTH];
strcpy(picture_dir, home_dir);
strcat(picture_dir, "/Pictures");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_PICTURES_DIR, picture_dir);
char music_dir[LV_FS_MAX_PATH_LENGTH];
strcpy(music_dir, home_dir);
strcat(music_dir, "/Music");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_MUSIC_DIR, music_dir);
char document_dir[LV_FS_MAX_PATH_LENGTH];
strcpy(document_dir, home_dir);
strcat(document_dir, "/Documents");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_DOCS_DIR, document_dir);
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_FS_DIR, "A:/");
#endif
#endif
lv_obj_add_event_cb(file_explorer, file_explorer_event_handler, LV_EVENT_ALL, NULL);
}
#endif

View File

@@ -0,0 +1,132 @@
#include "../../lv_examples.h"
#if LV_USE_TABLE && LV_USE_DROPDOWN && LV_USE_FILE_EXPLORER && (LV_USE_FS_STDIO || LV_USE_FS_POSIX || LV_USE_FS_WIN32 || LV_USE_FS_FATFS) && LV_BUILD_EXAMPLES
#include <stdlib.h>
#include <string.h>
static void file_explorer_event_handler(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t * obj = lv_event_get_target(e);
if(code == LV_EVENT_VALUE_CHANGED) {
const char * cur_path = lv_file_explorer_get_current_path(obj);
const char * sel_fn = lv_file_explorer_get_selected_file_name(obj);
LV_LOG_USER("%s%s", cur_path, sel_fn);
}
}
static void btn_event_handler(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t * btn = lv_event_get_target(e);
lv_obj_t * file_explorer = lv_event_get_user_data(e);
if(code == LV_EVENT_VALUE_CHANGED) {
if(lv_obj_has_state(btn, LV_STATE_CHECKED))
lv_obj_add_flag(file_explorer, LV_OBJ_FLAG_HIDDEN);
else
lv_obj_remove_flag(file_explorer, LV_OBJ_FLAG_HIDDEN);
}
}
static void dd_event_handler(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t * dd = lv_event_get_target(e);
lv_obj_t * fe_quick_access_obj = lv_event_get_user_data(e);
if(code == LV_EVENT_VALUE_CHANGED) {
char buf[32];
lv_dropdown_get_selected_str(dd, buf, sizeof(buf));
if(strcmp(buf, "NONE") == 0) {
lv_file_explorer_set_sort(fe_quick_access_obj, LV_EXPLORER_SORT_NONE);
}
else if(strcmp(buf, "KIND") == 0) {
lv_file_explorer_set_sort(fe_quick_access_obj, LV_EXPLORER_SORT_KIND);
}
}
}
void lv_example_file_explorer_2(void)
{
lv_obj_t * file_explorer = lv_file_explorer_create(lv_screen_active());
#if LV_USE_FS_WIN32
lv_file_explorer_open_dir(file_explorer, "D:");
#if LV_FILE_EXPLORER_QUICK_ACCESS
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_HOME_DIR, "C:/Users/Public/Desktop");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_VIDEO_DIR, "C:/Users/Public/Videos");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_PICTURES_DIR, "C:/Users/Public/Pictures");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_MUSIC_DIR, "C:/Users/Public/Music");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_DOCS_DIR, "C:/Users/Public/Documents");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_FS_DIR, "D:");
#endif
#else
/* linux */
lv_file_explorer_open_dir(file_explorer, "A:/");
#if LV_FILE_EXPLORER_QUICK_ACCESS
char * envvar = "HOME";
char home_dir[LV_FS_MAX_PATH_LENGTH];
strcpy(home_dir, "A:");
/* get the user's home directory from the HOME environment variable*/
strcat(home_dir, getenv(envvar));
LV_LOG_USER("home_dir: %s\n", home_dir);
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_HOME_DIR, home_dir);
char video_dir[LV_FS_MAX_PATH_LENGTH];
strcpy(video_dir, home_dir);
strcat(video_dir, "/Videos");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_VIDEO_DIR, video_dir);
char picture_dir[LV_FS_MAX_PATH_LENGTH];
strcpy(picture_dir, home_dir);
strcat(picture_dir, "/Pictures");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_PICTURES_DIR, picture_dir);
char music_dir[LV_FS_MAX_PATH_LENGTH];
strcpy(music_dir, home_dir);
strcat(music_dir, "/Music");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_MUSIC_DIR, music_dir);
char document_dir[LV_FS_MAX_PATH_LENGTH];
strcpy(document_dir, home_dir);
strcat(document_dir, "/Documents");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_DOCS_DIR, document_dir);
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_FS_DIR, "A:/");
#endif
#endif
lv_obj_add_event_cb(file_explorer, file_explorer_event_handler, LV_EVENT_ALL, NULL);
/*Quick access status control button*/
lv_obj_t * fe_quick_access_obj = lv_file_explorer_get_quick_access_area(file_explorer);
lv_obj_t * fe_header_obj = lv_file_explorer_get_header(file_explorer);
lv_obj_t * btn = lv_button_create(fe_header_obj);
lv_obj_set_style_radius(btn, 2, 0);
lv_obj_set_style_pad_all(btn, 4, 0);
lv_obj_align(btn, LV_ALIGN_LEFT_MID, 0, 0);
lv_obj_add_flag(btn, LV_OBJ_FLAG_CHECKABLE);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_LIST);
lv_obj_center(label);
lv_obj_add_event_cb(btn, btn_event_handler, LV_EVENT_VALUE_CHANGED, fe_quick_access_obj);
/*Sort control*/
static const char * opts = "NONE\n"
"KIND";
lv_obj_t * dd = lv_dropdown_create(fe_header_obj);
lv_obj_set_style_radius(dd, 4, 0);
lv_obj_set_style_pad_all(dd, 0, 0);
lv_obj_set_size(dd, LV_PCT(30), LV_SIZE_CONTENT);
lv_dropdown_set_options_static(dd, opts);
lv_obj_align(dd, LV_ALIGN_RIGHT_MID, 0, 0);
lv_obj_add_event_cb(dd, dd_event_handler, LV_EVENT_VALUE_CHANGED, file_explorer);
}
#endif

View File

@@ -0,0 +1,116 @@
#include "../../lv_examples.h"
#if LV_USE_TABLE && LV_USE_FILE_EXPLORER && (LV_USE_FS_STDIO || LV_USE_FS_POSIX || LV_USE_FS_WIN32 || LV_USE_FS_FATFS) && LV_BUILD_EXAMPLES
#include <stdlib.h>
#include <string.h>
static void exch_table_item(lv_obj_t * tb, int16_t i, int16_t j)
{
const char * tmp;
tmp = lv_table_get_cell_value(tb, i, 0);
lv_table_set_cell_value(tb, 0, 2, tmp);
lv_table_set_cell_value(tb, i, 0, lv_table_get_cell_value(tb, j, 0));
lv_table_set_cell_value(tb, j, 0, lv_table_get_cell_value(tb, 0, 2));
tmp = lv_table_get_cell_value(tb, i, 1);
lv_table_set_cell_value(tb, 0, 2, tmp);
lv_table_set_cell_value(tb, i, 1, lv_table_get_cell_value(tb, j, 1));
lv_table_set_cell_value(tb, j, 1, lv_table_get_cell_value(tb, 0, 2));
}
/*Quick sort 3 way*/
static void sort_by_file_kind(lv_obj_t * tb, int16_t lo, int16_t hi)
{
if(lo >= hi) return;
int16_t lt = lo;
int16_t i = lo + 1;
int16_t gt = hi;
const char * v = lv_table_get_cell_value(tb, lo, 1);
while(i <= gt) {
if(strcmp(lv_table_get_cell_value(tb, i, 1), v) < 0)
exch_table_item(tb, lt++, i++);
else if(strcmp(lv_table_get_cell_value(tb, i, 1), v) > 0)
exch_table_item(tb, i, gt--);
else
i++;
}
sort_by_file_kind(tb, lo, lt - 1);
sort_by_file_kind(tb, gt + 1, hi);
}
static void file_explorer_event_handler(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t * obj = lv_event_get_target(e);
if(code == LV_EVENT_VALUE_CHANGED) {
const char * cur_path = lv_file_explorer_get_current_path(obj);
const char * sel_fn = lv_file_explorer_get_selected_file_name(obj);
LV_LOG_USER("%s%s", cur_path, sel_fn);
}
else if(code == LV_EVENT_READY) {
lv_obj_t * tb = lv_file_explorer_get_file_table(obj);
uint16_t sum = lv_table_get_row_count(tb);
sort_by_file_kind(tb, 0, (sum - 1));
}
}
void lv_example_file_explorer_3(void)
{
lv_obj_t * file_explorer = lv_file_explorer_create(lv_screen_active());
/*Before custom sort, please set the default sorting to NONE. The default is NONE.*/
lv_file_explorer_set_sort(file_explorer, LV_EXPLORER_SORT_NONE);
#if LV_USE_FS_WIN32
lv_file_explorer_open_dir(file_explorer, "D:");
#if LV_FILE_EXPLORER_QUICK_ACCESS
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_HOME_DIR, "C:/Users/Public/Desktop");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_VIDEO_DIR, "C:/Users/Public/Videos");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_PICTURES_DIR, "C:/Users/Public/Pictures");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_MUSIC_DIR, "C:/Users/Public/Music");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_DOCS_DIR, "C:/Users/Public/Documents");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_FS_DIR, "D:");
#endif
#else
/* linux */
lv_file_explorer_open_dir(file_explorer, "A:/");
#if LV_FILE_EXPLORER_QUICK_ACCESS
char * envvar = "HOME";
char home_dir[LV_FS_MAX_PATH_LENGTH];
strcpy(home_dir, "A:");
/* get the user's home directory from the HOME environment variable*/
strcat(home_dir, getenv(envvar));
LV_LOG_USER("home_dir: %s\n", home_dir);
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_HOME_DIR, home_dir);
char video_dir[LV_FS_MAX_PATH_LENGTH];
strcpy(video_dir, home_dir);
strcat(video_dir, "/Videos");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_VIDEO_DIR, video_dir);
char picture_dir[LV_FS_MAX_PATH_LENGTH];
strcpy(picture_dir, home_dir);
strcat(picture_dir, "/Pictures");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_PICTURES_DIR, picture_dir);
char music_dir[LV_FS_MAX_PATH_LENGTH];
strcpy(music_dir, home_dir);
strcat(music_dir, "/Music");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_MUSIC_DIR, music_dir);
char document_dir[LV_FS_MAX_PATH_LENGTH];
strcpy(document_dir, home_dir);
strcat(document_dir, "/Documents");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_DOCS_DIR, document_dir);
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_FS_DIR, "A:/");
#endif
#endif
lv_obj_add_event_cb(file_explorer, file_explorer_event_handler, LV_EVENT_ALL, NULL);
}
#endif

View File

@@ -0,0 +1,12 @@
Basic fragment usage
--------------------
.. lv_example:: others/fragment/lv_example_fragment_1
:language: c
Stack navigation example
------------------------
.. lv_example:: others/fragment/lv_example_fragment_2
:language: c

View File

@@ -0,0 +1,37 @@
/**
* @file lv_example_fragment.h
*/
#ifndef LV_EXAMPLE_FRAGMENT_H
#define LV_EXAMPLE_FRAGMENT_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_example_fragment_1(void);
void lv_example_fragment_2(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_EXAMPLE_fragment_H*/

View File

@@ -0,0 +1,59 @@
/**
* @file lv_example_fragment_1.c
* @brief Basic usage of obj fragment
*/
#include "../../lv_examples.h"
#if LV_USE_FRAGMENT && LV_BUILD_EXAMPLES
static void sample_fragment_ctor(lv_fragment_t * self, void * args);
static lv_obj_t * sample_fragment_create_obj(lv_fragment_t * self, lv_obj_t * parent);
static void sample_container_delete(lv_event_t * e);
static lv_obj_t * root = NULL;
struct sample_fragment_t {
lv_fragment_t base;
const char * name;
};
static const lv_fragment_class_t sample_cls = {
.constructor_cb = sample_fragment_ctor,
.create_obj_cb = sample_fragment_create_obj,
.instance_size = sizeof(struct sample_fragment_t),
};
void lv_example_fragment_1(void)
{
root = lv_obj_create(lv_screen_active());
lv_obj_set_size(root, LV_PCT(100), LV_PCT(100));
lv_fragment_manager_t * manager = lv_fragment_manager_create(NULL);
/* Clean up the fragment manager before objects in containers got deleted */
lv_obj_add_event_cb(root, sample_container_delete, LV_EVENT_DELETE, manager);
lv_fragment_t * fragment = lv_fragment_create(&sample_cls, "Fragment");
lv_fragment_manager_replace(manager, fragment, &root);
}
static void sample_fragment_ctor(lv_fragment_t * self, void * args)
{
((struct sample_fragment_t *) self)->name = args;
}
static lv_obj_t * sample_fragment_create_obj(lv_fragment_t * self, lv_obj_t * parent)
{
lv_obj_t * label = lv_label_create(parent);
lv_obj_set_style_bg_opa(label, LV_OPA_COVER, 0);;
lv_label_set_text_fmt(label, "Hello, %s!", ((struct sample_fragment_t *) self)->name);
return label;
}
static void sample_container_delete(lv_event_t * e)
{
lv_fragment_manager_t * manager = (lv_fragment_manager_t *) lv_event_get_user_data(e);
lv_fragment_manager_delete(manager);
}
#endif

View File

@@ -0,0 +1,126 @@
/**
* @file lv_example_fragment_2.c
* @brief Navigation stack using obj fragment
*/
#include "../../lv_examples.h"
#if LV_USE_FRAGMENT && LV_USE_WIN && LV_USE_GRID && LV_BUILD_EXAMPLES
static void sample_fragment_ctor(lv_fragment_t * self, void * args);
static lv_obj_t * sample_fragment_create_obj(lv_fragment_t * self, lv_obj_t * parent);
static void sample_push_click(lv_event_t * e);
static void sample_pop_click(lv_event_t * e);
static void sample_container_delete(lv_event_t * e);
static void sample_fragment_inc_click(lv_event_t * e);
typedef struct sample_fragment_t {
lv_fragment_t base;
lv_obj_t * label;
int depth;
int counter;
} sample_fragment_t;
static const lv_fragment_class_t sample_cls = {
.constructor_cb = sample_fragment_ctor,
.create_obj_cb = sample_fragment_create_obj,
.instance_size = sizeof(sample_fragment_t),
};
static lv_obj_t * container = NULL;
void lv_example_fragment_2(void)
{
lv_obj_t * root = lv_obj_create(lv_screen_active());
lv_obj_set_size(root, LV_PCT(100), LV_PCT(100));
lv_obj_set_layout(root, LV_LAYOUT_GRID);
static const int32_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
static const int32_t row_dsc[] = {LV_GRID_FR(1), LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
lv_obj_set_grid_dsc_array(root, col_dsc, row_dsc);
container = lv_obj_create(root);
lv_obj_remove_style_all(container);
lv_obj_set_grid_cell(container, LV_GRID_ALIGN_STRETCH, 0, 2, LV_GRID_ALIGN_STRETCH, 0, 1);
lv_obj_t * push_btn = lv_button_create(root);
lv_obj_t * push_label = lv_label_create(push_btn);
lv_label_set_text(push_label, "Push");
lv_obj_t * pop_btn = lv_button_create(root);
lv_obj_t * pop_label = lv_label_create(pop_btn);
lv_label_set_text(pop_label, "Pop");
lv_obj_set_grid_cell(push_btn, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_CENTER, 1, 1);
lv_obj_set_grid_cell(pop_btn, LV_GRID_ALIGN_END, 1, 1, LV_GRID_ALIGN_CENTER, 1, 1);
lv_fragment_manager_t * manager = lv_fragment_manager_create(NULL);
/* Clean up the fragment manager before objects in containers got deleted */
lv_obj_add_event_cb(root, sample_container_delete, LV_EVENT_DELETE, manager);
int depth = 0;
lv_fragment_t * fragment = lv_fragment_create(&sample_cls, &depth);
lv_fragment_manager_push(manager, fragment, &container);
lv_obj_add_event_cb(push_btn, sample_push_click, LV_EVENT_CLICKED, manager);
lv_obj_add_event_cb(pop_btn, sample_pop_click, LV_EVENT_CLICKED, manager);
}
static void sample_fragment_ctor(lv_fragment_t * self, void * args)
{
LV_UNUSED(args);
((sample_fragment_t *) self)->depth = *((int *) args);
((sample_fragment_t *) self)->counter = 0;
}
static lv_obj_t * sample_fragment_create_obj(lv_fragment_t * self, lv_obj_t * parent)
{
sample_fragment_t * fragment = (sample_fragment_t *) self;
lv_obj_t * content = lv_obj_create(parent);
lv_obj_remove_style_all(content);
lv_obj_set_style_bg_opa(content, LV_OPA_50, 0);
lv_obj_set_style_bg_color(content, lv_palette_main(LV_PALETTE_YELLOW), 0);
lv_obj_set_size(content, LV_PCT(100), LV_PCT(100));
lv_obj_set_flex_flow(content, LV_FLEX_FLOW_COLUMN);
lv_obj_t * depth = lv_label_create(content);
lv_label_set_text_fmt(depth, "Depth: %d", fragment->depth);
lv_obj_t * label = lv_label_create(content);
fragment->label = label;
lv_label_set_text_fmt(label, "The button has been pressed %d times", fragment->counter);
lv_obj_t * inc_btn = lv_button_create(content);
lv_obj_t * inc_label = lv_label_create(inc_btn);
lv_label_set_text(inc_label, "+1");
lv_obj_add_event_cb(inc_btn, sample_fragment_inc_click, LV_EVENT_CLICKED, fragment);
return content;
}
static void sample_push_click(lv_event_t * e)
{
lv_fragment_manager_t * manager = (lv_fragment_manager_t *) lv_event_get_user_data(e);
size_t stack_size = lv_fragment_manager_get_stack_size(manager);
lv_fragment_t * fragment = lv_fragment_create(&sample_cls, &stack_size);
lv_fragment_manager_push(manager, fragment, &container);
}
static void sample_pop_click(lv_event_t * e)
{
lv_fragment_manager_t * manager = (lv_fragment_manager_t *) lv_event_get_user_data(e);
lv_fragment_manager_pop(manager);
}
static void sample_container_delete(lv_event_t * e)
{
lv_fragment_manager_t * manager = (lv_fragment_manager_t *) lv_event_get_user_data(e);
lv_fragment_manager_delete(manager);
}
static void sample_fragment_inc_click(lv_event_t * e)
{
sample_fragment_t * fragment = (sample_fragment_t *) lv_event_get_user_data(e);
fragment->counter++;
lv_label_set_text_fmt(fragment->label, "The button has been pressed %d times", fragment->counter);
}
#endif

View File

@@ -0,0 +1,30 @@
Basic grid navigation
---------------------
.. lv_example:: others/gridnav/lv_example_gridnav_1
:language: c
Grid navigation on a list
-------------------------
.. lv_example:: others/gridnav/lv_example_gridnav_2
:language: c
Nested grid navigations
-----------------------
.. lv_example:: others/gridnav/lv_example_gridnav_3
:language: c
Simple navigation on a list widget
----------------------------------
.. lv_example:: others/gridnav/lv_example_gridnav_4
:language: c
Grid navigation for only one axis
---------------------------------
.. lv_example:: others/gridnav/lv_example_gridnav_5
:language: c

View File

@@ -0,0 +1,42 @@
/**
* @file lv_example_gridnav.h
*
*/
#ifndef LV_EXAMPLE_GRIDNAV_H
#define LV_EXAMPLE_GRIDNAV_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_example_gridnav_1(void);
void lv_example_gridnav_2(void);
void lv_example_gridnav_3(void);
void lv_example_gridnav_4(void);
void lv_example_gridnav_5(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_EXAMPLE_GRIDNAV_H*/

View File

@@ -0,0 +1,72 @@
#include "../../lv_examples.h"
#if LV_USE_GRIDNAV && LV_USE_FLEX && LV_BUILD_EXAMPLES
/**
* Demonstrate a a basic grid navigation
*/
void lv_example_gridnav_1(void)
{
/*It's assumed that the default group is set and
*there is a keyboard indev*/
lv_obj_t * cont1 = lv_obj_create(lv_screen_active());
lv_gridnav_add(cont1, LV_GRIDNAV_CTRL_NONE);
/*Use flex here, but works with grid or manually placed objects as well*/
lv_obj_set_flex_flow(cont1, LV_FLEX_FLOW_ROW_WRAP);
lv_obj_set_style_bg_color(cont1, lv_palette_lighten(LV_PALETTE_BLUE, 5), LV_STATE_FOCUSED);
lv_obj_set_size(cont1, lv_pct(50), lv_pct(100));
/*Only the container needs to be in a group*/
lv_group_add_obj(lv_group_get_default(), cont1);
lv_obj_t * label = lv_label_create(cont1);
lv_label_set_text_fmt(label, "No rollover");
uint32_t i;
for(i = 0; i < 10; i++) {
lv_obj_t * obj = lv_button_create(cont1);
lv_obj_set_size(obj, 70, LV_SIZE_CONTENT);
lv_obj_add_flag(obj, LV_OBJ_FLAG_CHECKABLE);
lv_group_remove_obj(obj); /*Not needed, we use the gridnav instead*/
label = lv_label_create(obj);
lv_label_set_text_fmt(label, "%"LV_PRIu32"", i);
lv_obj_center(label);
}
/* Create a second container with rollover grid nav mode.*/
lv_obj_t * cont2 = lv_obj_create(lv_screen_active());
lv_gridnav_add(cont2, LV_GRIDNAV_CTRL_ROLLOVER);
lv_obj_set_style_bg_color(cont2, lv_palette_lighten(LV_PALETTE_BLUE, 5), LV_STATE_FOCUSED);
lv_obj_set_size(cont2, lv_pct(50), lv_pct(100));
lv_obj_align(cont2, LV_ALIGN_RIGHT_MID, 0, 0);
label = lv_label_create(cont2);
lv_obj_set_width(label, lv_pct(100));
lv_label_set_text_fmt(label, "Rollover\nUse tab to focus the other container");
/*Only the container needs to be in a group*/
lv_group_add_obj(lv_group_get_default(), cont2);
/*Add and place some children manually*/
lv_obj_t * ta = lv_textarea_create(cont2);
lv_obj_set_size(ta, lv_pct(100), 80);
lv_obj_set_pos(ta, 0, 80);
lv_group_remove_obj(ta); /*Not needed, we use the gridnav instead*/
lv_obj_t * cb = lv_checkbox_create(cont2);
lv_obj_set_pos(cb, 0, 170);
lv_group_remove_obj(cb); /*Not needed, we use the gridnav instead*/
lv_obj_t * sw1 = lv_switch_create(cont2);
lv_obj_set_pos(sw1, 0, 200);
lv_group_remove_obj(sw1); /*Not needed, we use the gridnav instead*/
lv_obj_t * sw2 = lv_switch_create(cont2);
lv_obj_set_pos(sw2, lv_pct(50), 200);
lv_group_remove_obj(sw2); /*Not needed, we use the gridnav instead*/
}
#endif

View File

@@ -0,0 +1,43 @@
#include "../../lv_examples.h"
#if LV_USE_GRIDNAV && LV_USE_LIST && LV_BUILD_EXAMPLES
/**
* Grid navigation on a list
*/
void lv_example_gridnav_2(void)
{
/*It's assumed that the default group is set and
*there is a keyboard indev*/
lv_obj_t * list1 = lv_list_create(lv_screen_active());
lv_gridnav_add(list1, LV_GRIDNAV_CTRL_NONE);
lv_obj_set_size(list1, lv_pct(45), lv_pct(80));
lv_obj_align(list1, LV_ALIGN_LEFT_MID, 5, 0);
lv_obj_set_style_bg_color(list1, lv_palette_lighten(LV_PALETTE_BLUE, 5), LV_STATE_FOCUSED);
lv_group_add_obj(lv_group_get_default(), list1);
char buf[32];
uint32_t i;
for(i = 0; i < 15; i++) {
lv_snprintf(buf, sizeof(buf), "File %d", i + 1);
lv_obj_t * item = lv_list_add_button(list1, LV_SYMBOL_FILE, buf);
lv_obj_set_style_bg_opa(item, 0, 0);
lv_group_remove_obj(item); /*Not needed, we use the gridnav instead*/
}
lv_obj_t * list2 = lv_list_create(lv_screen_active());
lv_gridnav_add(list2, LV_GRIDNAV_CTRL_ROLLOVER);
lv_obj_set_size(list2, lv_pct(45), lv_pct(80));
lv_obj_align(list2, LV_ALIGN_RIGHT_MID, -5, 0);
lv_obj_set_style_bg_color(list2, lv_palette_lighten(LV_PALETTE_BLUE, 5), LV_STATE_FOCUSED);
lv_group_add_obj(lv_group_get_default(), list2);
for(i = 0; i < 15; i++) {
lv_snprintf(buf, sizeof(buf), "Folder %d", i + 1);
lv_obj_t * item = lv_list_add_button(list2, LV_SYMBOL_DIRECTORY, buf);
lv_obj_set_style_bg_opa(item, 0, 0);
lv_group_remove_obj(item);
}
}
#endif

View File

@@ -0,0 +1,97 @@
#include "../../lv_examples.h"
#if LV_USE_GRIDNAV && LV_USE_FLEX && LV_BUILD_EXAMPLES
static void cont_sub_event_cb(lv_event_t * e)
{
uint32_t k = lv_event_get_key(e);
lv_obj_t * obj = lv_event_get_target(e);
if(k == LV_KEY_ENTER) {
lv_group_focus_obj(obj);
}
else if(k == LV_KEY_ESC) {
lv_group_focus_next(lv_obj_get_group(obj));
}
}
/**
* Nested grid navigations
*/
void lv_example_gridnav_3(void)
{
/*It's assumed that the default group is set and
*there is a keyboard indev*/
lv_obj_t * cont_main = lv_obj_create(lv_screen_active());
lv_gridnav_add(cont_main, LV_GRIDNAV_CTRL_ROLLOVER | LV_GRIDNAV_CTRL_SCROLL_FIRST);
/*Only the container needs to be in a group*/
lv_group_add_obj(lv_group_get_default(), cont_main);
/*Use flex here, but works with grid or manually placed objects as well*/
lv_obj_set_flex_flow(cont_main, LV_FLEX_FLOW_ROW_WRAP);
lv_obj_set_style_bg_color(cont_main, lv_palette_lighten(LV_PALETTE_BLUE, 5), LV_STATE_FOCUSED);
lv_obj_set_size(cont_main, lv_pct(80), LV_SIZE_CONTENT);
lv_obj_t * btn;
lv_obj_t * label;
btn = lv_button_create(cont_main);
lv_group_remove_obj(btn);
label = lv_label_create(btn);
lv_label_set_text(label, "Button 1");
btn = lv_button_create(cont_main);
lv_group_remove_obj(btn);
label = lv_label_create(btn);
lv_label_set_text(label, "Button 2");
/*Create another container with long text to show how LV_GRIDNAV_CTRL_SCROLL_FIRST works*/
lv_obj_t * cont_sub1 = lv_obj_create(cont_main);
lv_obj_set_size(cont_sub1, lv_pct(100), 100);
label = lv_label_create(cont_sub1);
lv_obj_set_style_bg_color(cont_sub1, lv_palette_lighten(LV_PALETTE_RED, 5), LV_STATE_FOCUSED);
lv_obj_set_width(label, lv_pct(100));
lv_label_set_text(label,
"I'm a very long text which is makes my container scrollable. "
"As LV_GRIDNAV_FLAG_SCROLL_FIRST is enabled arrow will scroll me first "
"and a new objects will be focused only when an edge is reached with the scrolling.\n\n"
"This is only some placeholder text to be sure the parent will be scrollable. \n\n"
"Hello world!\n"
"Hello world!\n"
"Hello world!\n"
"Hello world!\n"
"Hello world!\n"
"Hello world!");
/*Create a third container that can be focused with ENTER and contains another grid nav*/
lv_obj_t * cont_sub2 = lv_obj_create(cont_main);
lv_gridnav_add(cont_sub2, LV_GRIDNAV_CTRL_ROLLOVER);
/*Only the container needs to be in a group*/
lv_group_add_obj(lv_group_get_default(), cont_sub2);
lv_obj_add_event_cb(cont_sub2, cont_sub_event_cb, LV_EVENT_KEY, NULL);
/*Use flex here, but works with grid or manually placed objects as well*/
lv_obj_set_flex_flow(cont_sub2, LV_FLEX_FLOW_ROW_WRAP);
lv_obj_set_style_bg_color(cont_sub2, lv_palette_lighten(LV_PALETTE_RED, 5), LV_STATE_FOCUSED);
lv_obj_set_size(cont_sub2, lv_pct(100), LV_SIZE_CONTENT);
label = lv_label_create(cont_sub2);
lv_label_set_text(label, "Use ENTER/ESC to focus/defocus this container");
lv_obj_set_width(label, lv_pct(100));
btn = lv_button_create(cont_sub2);
lv_group_remove_obj(btn);
label = lv_label_create(btn);
lv_label_set_text(label, "Button 3");
btn = lv_button_create(cont_sub2);
lv_group_remove_obj(btn);
label = lv_label_create(btn);
lv_label_set_text(label, "Button 4");
}
#endif

View File

@@ -0,0 +1,47 @@
#include "../../lv_examples.h"
#if LV_USE_GRIDNAV && LV_USE_FLEX && LV_BUILD_EXAMPLES
static void event_handler(lv_event_t * e)
{
lv_obj_t * obj = lv_event_get_target(e);
lv_obj_t * list = lv_obj_get_parent(obj);
LV_UNUSED(list); /*If logging is disabled*/
LV_LOG_USER("Clicked: %s", lv_list_get_button_text(list, obj));
}
/**
* Simple navigation on a list widget
*/
void lv_example_gridnav_4(void)
{
/*It's assumed that the default group is set and
*there is a keyboard indev*/
lv_obj_t * list = lv_list_create(lv_screen_active());
lv_gridnav_add(list, LV_GRIDNAV_CTRL_ROLLOVER);
lv_obj_align(list, LV_ALIGN_LEFT_MID, 10, 0);
lv_group_add_obj(lv_group_get_default(), list);
uint32_t i;
for(i = 0; i < 20; i++) {
char buf[32];
/*Add some separators too, they are not focusable by gridnav*/
if((i % 5) == 0) {
lv_snprintf(buf, sizeof(buf), "Section %d", i / 5 + 1);
lv_list_add_text(list, buf);
}
lv_snprintf(buf, sizeof(buf), "File %d", i + 1);
lv_obj_t * item = lv_list_add_button(list, LV_SYMBOL_FILE, buf);
lv_obj_add_event_cb(item, event_handler, LV_EVENT_CLICKED, NULL);
lv_group_remove_obj(item); /*The default group adds it automatically*/
}
lv_obj_t * btn = lv_button_create(lv_screen_active());
lv_obj_align(btn, LV_ALIGN_RIGHT_MID, -10, 0);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, "Button");
}
#endif

View File

@@ -0,0 +1,69 @@
#include "../../lv_examples.h"
#if LV_USE_GRIDNAV && LV_USE_FLEX && LV_BUILD_EXAMPLES
static const char * opts[] = {"0\n1\n2\n3\n4\n5", "0\n1\n2\n3\n4\n5\n6\n7\n8\n9", "s\nm\nh"};
static const int32_t opts_counts[] = {6, 10, 3};
static lv_obj_t * sliders[3];
static lv_obj_t * rollers[3];
static void slider_key_cb(lv_event_t * e)
{
uint8_t i = (uint32_t)(uintptr_t)lv_event_get_user_data(e);
lv_roller_set_selected(rollers[i], lv_slider_get_value(sliders[i]), LV_ANIM_ON);
}
static void roller_key_cb(lv_event_t * e)
{
uint8_t i = (uint32_t)(uintptr_t)lv_event_get_user_data(e);
lv_slider_set_value(sliders[i], lv_roller_get_selected(rollers[i]), LV_ANIM_ON);
}
/**
* Grid navigation for only one axis
*/
void lv_example_gridnav_5(void)
{
/*It's assumed that the default group is set and
*there is a keyboard indev*/
lv_group_t * group = lv_group_get_default();
lv_obj_t * cont;
cont = lv_obj_create(lv_screen_active());
lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(cont, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_size(cont, lv_pct(100), lv_pct(50));
lv_obj_align(cont, LV_ALIGN_TOP_MID, 0, 0);
/* only up/down keys will be used for grid navigation in this container. */
/* left/right will be sent to the sliders */
lv_gridnav_add(cont, LV_GRIDNAV_CTRL_VERTICAL_MOVE_ONLY);
lv_group_add_obj(group, cont);
for(uint32_t i = 0; i < 3; i++) {
lv_obj_t * slider = lv_slider_create(cont);
lv_slider_set_range(slider, 0, opts_counts[i] - 1);
lv_group_remove_obj(slider);
lv_obj_set_width(slider, lv_pct(85));
sliders[i] = slider;
lv_obj_add_event_cb(slider, slider_key_cb, LV_EVENT_KEY, (void *)(uintptr_t)i);
}
cont = lv_obj_create(lv_screen_active());
lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(cont, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_size(cont, lv_pct(100), lv_pct(50));
lv_obj_align(cont, LV_ALIGN_BOTTOM_MID, 0, 0);
/* only left/right keys will be used for grid navigation in this container. */
/* up/down will be sent to the rollers */
lv_gridnav_add(cont, LV_GRIDNAV_CTRL_HORIZONTAL_MOVE_ONLY);
lv_group_add_obj(group, cont);
for(uint32_t i = 0; i < 3; i++) {
lv_obj_t * roller = lv_roller_create(cont);
lv_roller_set_options(roller, opts[i], LV_ROLLER_MODE_INFINITE);
lv_obj_set_size(roller, lv_pct(30), lv_pct(100));
lv_group_remove_obj(roller);
rollers[i] = roller;
lv_obj_add_event_cb(roller, roller_key_cb, LV_EVENT_KEY, (void *)(uintptr_t)i);
}
}
#endif

View File

@@ -0,0 +1,12 @@
Pinyin IME 26 key input
-----------------------
.. lv_example:: others/ime/lv_example_ime_pinyin_1
:language: c
Pinyin IME 9 key input
----------------------
.. lv_example:: others/ime/lv_example_ime_pinyin_2
:language: c

View File

@@ -0,0 +1,39 @@
/**
* @file lv_example_ime_pinyin.h
*
*/
#ifndef LV_EX_IME_PINYIN_H
#define LV_EX_IME_PINYIN_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_example_ime_pinyin_1(void);
void lv_example_ime_pinyin_2(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_EX_IME_PINYIN_H*/

View File

@@ -0,0 +1,56 @@
#include "../../lv_examples.h"
#if LV_USE_LABEL && LV_USE_TEXTAREA && LV_FONT_SIMSUN_16_CJK && LV_USE_IME_PINYIN && LV_BUILD_EXAMPLES
static void ta_event_cb(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t * ta = lv_event_get_target(e);
lv_obj_t * kb = lv_event_get_user_data(e);
if(code == LV_EVENT_FOCUSED) {
if(lv_indev_get_type(lv_indev_active()) != LV_INDEV_TYPE_KEYPAD) {
lv_keyboard_set_textarea(kb, ta);
lv_obj_remove_flag(kb, LV_OBJ_FLAG_HIDDEN);
}
}
else if(code == LV_EVENT_CANCEL) {
lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);
lv_obj_remove_state(ta, LV_STATE_FOCUSED);
lv_indev_reset(NULL, ta); /*To forget the last clicked object to make it focusable again*/
}
}
void lv_example_ime_pinyin_1(void)
{
lv_obj_t * pinyin_ime = lv_ime_pinyin_create(lv_screen_active());
lv_obj_set_style_text_font(pinyin_ime, &lv_font_simsun_16_cjk, 0);
//lv_ime_pinyin_set_dict(pinyin_ime, your_dict); // Use a custom dictionary. If it is not set, the built-in dictionary will be used.
/* ta1 */
lv_obj_t * ta1 = lv_textarea_create(lv_screen_active());
lv_textarea_set_one_line(ta1, true);
lv_obj_set_style_text_font(ta1, &lv_font_simsun_16_cjk, 0);
lv_obj_align(ta1, LV_ALIGN_TOP_LEFT, 0, 0);
/*Create a keyboard and add it to ime_pinyin*/
lv_obj_t * kb = lv_keyboard_create(lv_screen_active());
lv_ime_pinyin_set_keyboard(pinyin_ime, kb);
lv_keyboard_set_textarea(kb, ta1);
lv_obj_add_event_cb(ta1, ta_event_cb, LV_EVENT_ALL, kb);
/*Get the cand_panel, and adjust its size and position*/
lv_obj_t * cand_panel = lv_ime_pinyin_get_cand_panel(pinyin_ime);
lv_obj_set_size(cand_panel, LV_PCT(100), LV_PCT(10));
lv_obj_align_to(cand_panel, kb, LV_ALIGN_OUT_TOP_MID, 0, 0);
/*Try using ime_pinyin to output the Chinese below in the ta1 above*/
lv_obj_t * cz_label = lv_label_create(lv_screen_active());
lv_label_set_text(cz_label,
"嵌入式系统Embedded System\n是一种嵌入机械或电气系统内部、具有专一功能和实时计算性能的计算机系统。");
lv_obj_set_style_text_font(cz_label, &lv_font_simsun_16_cjk, 0);
lv_obj_set_width(cz_label, 310);
lv_obj_align_to(cz_label, ta1, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
}
#endif

View File

@@ -0,0 +1,58 @@
#include "../../lv_examples.h"
#if LV_USE_LABEL && LV_USE_TEXTAREA && LV_FONT_SIMSUN_16_CJK && LV_USE_IME_PINYIN && LV_IME_PINYIN_USE_K9_MODE && LV_BUILD_EXAMPLES
static void ta_event_cb(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t * ta = lv_event_get_target(e);
lv_obj_t * kb = lv_event_get_user_data(e);
if(code == LV_EVENT_FOCUSED) {
if(lv_indev_get_type(lv_indev_active()) != LV_INDEV_TYPE_KEYPAD) {
lv_keyboard_set_textarea(kb, ta);
lv_obj_remove_flag(kb, LV_OBJ_FLAG_HIDDEN);
}
}
else if(code == LV_EVENT_READY) {
lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);
lv_obj_remove_state(ta, LV_STATE_FOCUSED);
lv_indev_reset(NULL, ta); /*To forget the last clicked object to make it focusable again*/
}
}
void lv_example_ime_pinyin_2(void)
{
lv_obj_t * pinyin_ime = lv_ime_pinyin_create(lv_screen_active());
lv_obj_set_style_text_font(pinyin_ime, &lv_font_simsun_16_cjk, 0);
//lv_ime_pinyin_set_dict(pinyin_ime, your_dict); // Use a custom dictionary. If it is not set, the built-in dictionary will be used.
/* ta1 */
lv_obj_t * ta1 = lv_textarea_create(lv_screen_active());
lv_textarea_set_one_line(ta1, true);
lv_obj_set_style_text_font(ta1, &lv_font_simsun_16_cjk, 0);
lv_obj_align(ta1, LV_ALIGN_TOP_LEFT, 0, 0);
/*Create a keyboard and add it to ime_pinyin*/
lv_obj_t * kb = lv_keyboard_create(lv_screen_active());
lv_keyboard_set_textarea(kb, ta1);
lv_ime_pinyin_set_keyboard(pinyin_ime, kb);
lv_ime_pinyin_set_mode(pinyin_ime,
LV_IME_PINYIN_MODE_K9); // Set to 9-key input mode. Default: 26-key input(k26) mode.
lv_obj_add_event_cb(ta1, ta_event_cb, LV_EVENT_ALL, kb);
/*Get the cand_panel, and adjust its size and position*/
lv_obj_t * cand_panel = lv_ime_pinyin_get_cand_panel(pinyin_ime);
lv_obj_set_size(cand_panel, LV_PCT(100), LV_PCT(10));
lv_obj_align_to(cand_panel, kb, LV_ALIGN_OUT_TOP_MID, 0, 0);
/*Try using ime_pinyin to output the Chinese below in the ta1 above*/
lv_obj_t * cz_label = lv_label_create(lv_screen_active());
lv_label_set_text(cz_label,
"嵌入式系统Embedded System\n是一种嵌入机械或电气系统内部、具有专一功能和实时计算性能的计算机系统。");
lv_obj_set_style_text_font(cz_label, &lv_font_simsun_16_cjk, 0);
lv_obj_set_width(cz_label, 310);
lv_obj_align_to(cz_label, ta1, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
}
#endif

View File

@@ -0,0 +1,6 @@
Use emojis in a text.
---------------------
.. lv_example:: others/imgfont/lv_example_imgfont_1
:language: c

View File

@@ -0,0 +1,38 @@
/**
* @file lv_example_imgfont.h
*
*/
#ifndef LV_EXAMPLE_IMGFONT_H
#define LV_EXAMPLE_IMGFONT_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_example_imgfont_1(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_EXAMPLE_IMGFONT_H*/

View File

@@ -0,0 +1,60 @@
#include "../../lv_examples.h"
#if LV_BUILD_EXAMPLES
#if LV_USE_IMGFONT
static const void * get_imgfont_path(const lv_font_t * font, uint32_t unicode, uint32_t unicode_next,
int32_t * offset_y, void * user_data)
{
LV_UNUSED(font);
LV_UNUSED(unicode_next);
LV_UNUSED(offset_y);
LV_UNUSED(user_data);
LV_IMAGE_DECLARE(emoji_F617);
if(unicode < 0xF000) return NULL;
if(unicode == 0xF617) {
return &emoji_F617;
}
else if(unicode == 0xF600) {
#if LV_USE_FFMPEG
return "lvgl/examples/assets/emoji/F600.png";
#else
return "A:lvgl/examples/assets/emoji/F600.png";
#endif
}
return NULL;
}
/**
* draw img in label or span obj
*/
void lv_example_imgfont_1(void)
{
lv_font_t * imgfont = lv_imgfont_create(80, get_imgfont_path, NULL);
if(imgfont == NULL) {
LV_LOG_ERROR("imgfont init error");
return;
}
imgfont->fallback = LV_FONT_DEFAULT;
lv_obj_t * label1 = lv_label_create(lv_screen_active());
lv_label_set_text(label1, "12\uF600\uF617AB");
lv_obj_set_style_text_font(label1, imgfont, LV_PART_MAIN);
lv_obj_center(label1);
}
#else
void lv_example_imgfont_1(void)
{
lv_obj_t * label = lv_label_create(lv_screen_active());
lv_label_set_text(label, "imgfont is not installed");
lv_obj_center(label);
}
#endif
#endif

View File

@@ -0,0 +1,45 @@
/**
* @file lv_example_others.h
*
*/
#ifndef LV_EXAMPLE_OTHERS_H
#define LV_EXAMPLE_OTHERS_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "file_explorer/lv_example_file_explorer.h"
#include "fragment/lv_example_fragment.h"
#include "gridnav/lv_example_gridnav.h"
#include "ime/lv_example_ime_pinyin.h"
#include "imgfont/lv_example_imgfont.h"
#include "monkey/lv_example_monkey.h"
#include "observer/lv_example_observer.h"
#include "snapshot/lv_example_snapshot.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_EXAMPLE_OTHERS_H*/

View File

@@ -0,0 +1,18 @@
Touchpad monkey example
-----------------------
.. lv_example:: others/monkey/lv_example_monkey_1
:language: c
Encoder monkey example
----------------------
.. lv_example:: others/monkey/lv_example_monkey_2
:language: c
Button monkey example
---------------------
.. lv_example:: others/monkey/lv_example_monkey_3
:language: c

View File

@@ -0,0 +1,40 @@
/**
* @file lv_example_monkey.h
*
*/
#ifndef LV_EXAMPLE_MONKEY_H
#define LV_EXAMPLE_MONKEY_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_example_monkey_1(void);
void lv_example_monkey_2(void);
void lv_example_monkey_3(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_EXAMPLE_MONKEY_H*/

View File

@@ -0,0 +1,18 @@
#include "../../lv_examples.h"
#if LV_USE_MONKEY && LV_BUILD_EXAMPLES
void lv_example_monkey_1(void)
{
/*Create pointer monkey test*/
lv_monkey_config_t config;
lv_monkey_config_init(&config);
config.type = LV_INDEV_TYPE_POINTER;
config.period_range.min = 10;
config.period_range.max = 100;
lv_monkey_t * monkey = lv_monkey_create(&config);
/*Start monkey test*/
lv_monkey_set_enable(monkey, true);
}
#endif

View File

@@ -0,0 +1,25 @@
#include "../../lv_examples.h"
#if LV_USE_MONKEY && LV_BUILD_EXAMPLES
void lv_example_monkey_2(void)
{
/*Create encoder monkey test*/
lv_monkey_config_t config;
lv_monkey_config_init(&config);
config.type = LV_INDEV_TYPE_ENCODER;
config.period_range.min = 50;
config.period_range.max = 500;
config.input_range.min = -5;
config.input_range.max = 5;
lv_monkey_t * monkey = lv_monkey_create(&config);
/*Set the default group*/
lv_group_t * group = lv_group_create();
lv_indev_set_group(lv_monkey_get_indev(monkey), group);
lv_group_set_default(group);
/*Start monkey test*/
lv_monkey_set_enable(monkey, true);
}
#endif

View File

@@ -0,0 +1,33 @@
#include "../../lv_examples.h"
#if LV_USE_MONKEY && LV_BUILD_EXAMPLES
void lv_example_monkey_3(void)
{
static lv_point_t btn_points[3];
int32_t hor_res = LV_HOR_RES;
/*Create button monkey test*/
lv_monkey_config_t config;
lv_monkey_config_init(&config);
config.type = LV_INDEV_TYPE_BUTTON;
config.period_range.min = 50;
config.period_range.max = 500;
config.input_range.min = 0;
config.input_range.max = sizeof(btn_points) / sizeof(lv_point_t) - 1;
lv_monkey_t * monkey = lv_monkey_create(&config);
/*Set the coordinates bound to the button*/
btn_points[0].x = hor_res / 4;
btn_points[0].y = 10;
btn_points[1].x = hor_res / 2;
btn_points[1].y = 10;
btn_points[2].x = hor_res * 3 / 4;
btn_points[2].y = 10;
lv_indev_set_button_points(lv_monkey_get_indev(monkey), btn_points);
/*Start monkey test*/
lv_monkey_set_enable(monkey, true);
}
#endif

View File

@@ -0,0 +1,38 @@
Bind a slider's value to a label
--------------------------------
.. lv_example:: others/observer/lv_example_observer_1
:language: c
Handling login and its states
-----------------------------
.. lv_example:: others/observer/lv_example_observer_2
:language: c
Set time with 12/24 mode and AM/PM
----------------------------------
.. lv_example:: others/observer/lv_example_observer_3
:language: c
Custom tab view with state management
-------------------------------------
.. lv_example:: others/observer/lv_example_observer_4
:language: c
Firmware update process
-----------------------
.. lv_example:: others/observer/lv_example_observer_5
:language: c
Modular style update on theme change
------------------------------------
.. lv_example:: others/observer/lv_example_observer_6
:language: c

View File

@@ -0,0 +1,43 @@
/**
* @file lv_example_observer.h
*
*/
#ifndef LV_EXAMPLE_OBSERVER_H
#define LV_EXAMPLE_OBSERVER_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_example_observer_1(void);
void lv_example_observer_2(void);
void lv_example_observer_3(void);
void lv_example_observer_4(void);
void lv_example_observer_5(void);
void lv_example_observer_6(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_EXAMPLE_OBSERVER_H*/

View File

@@ -0,0 +1,24 @@
#include "../../lv_examples.h"
#if LV_USE_OBSERVER && LV_USE_SLIDER && LV_USE_LABEL && LV_BUILD_EXAMPLES
static lv_subject_t temperature_subject;
/**
* A slider sends a message on value change and a label display's that value
*/
void lv_example_observer_1(void)
{
lv_subject_init_int(&temperature_subject, 28);
/*Create a slider in the center of the display*/
lv_obj_t * slider = lv_slider_create(lv_screen_active());
lv_obj_center(slider);
lv_slider_bind_value(slider, &temperature_subject);
/*Create a label below the slider*/
lv_obj_t * label = lv_label_create(lv_screen_active());
lv_obj_align(label, LV_ALIGN_CENTER, 0, 30);
lv_label_bind_text(label, &temperature_subject, "%d °C");
}
#endif

View File

@@ -0,0 +1,136 @@
#include "../../lv_examples.h"
#if LV_USE_OBSERVER && LV_USE_SLIDER && LV_USE_LABEL && LV_BUILD_EXAMPLES
/*This the only interface between the UI and the application*/
static lv_subject_t engine_subject;
static void app_init(void);
static void ui_init(void);
/**
* Simple PIN login screen to start an engine.
* The only interface between the UI and the application is a single "subject".
*/
void lv_example_observer_2(void)
{
lv_subject_init_int(&engine_subject, 0);
app_init();
ui_init();
}
/*--------------------------------------------------
* APPLICATION
*
* This part contains a demo application logic.
* It doesn't know anything about the internals of the UI
* and uses any the `engine_subject` as an interface.
* -------------------------------------------------*/
static void engine_state_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
{
LV_UNUSED(observer);
int32_t v = lv_subject_get_int(subject);
LV_UNUSED(v);
/*In a real application set/clear a pin here*/
LV_LOG_USER("Engine state: %" LV_PRId32, v);
}
static void app_init(void)
{
lv_subject_add_observer(&engine_subject, engine_state_observer_cb, NULL);
}
/*--------------------------------------------------
* USER INTERFACE
*
* This part contains only UI related code and data.
* In a project it would a separate file and the
* application couldn't see its internals
* -------------------------------------------------*/
typedef enum {
LOGGED_OUT,
LOGGED_IN,
AUTH_FAILED,
} auth_state_t;
static lv_subject_t auth_state_subject;
static void textarea_event_cb(lv_event_t * e)
{
lv_obj_t * ta = lv_event_get_target(e);
if(lv_strcmp(lv_textarea_get_text(ta), "hello") == 0) {
lv_subject_set_int(&auth_state_subject, LOGGED_IN);
}
else {
lv_subject_set_int(&auth_state_subject, AUTH_FAILED);
}
}
static void info_label_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
{
lv_obj_t * label = lv_observer_get_target(observer);
switch(lv_subject_get_int(subject)) {
case LOGGED_IN:
lv_label_set_text(label, "Login successful");
break;
case LOGGED_OUT:
lv_label_set_text(label, "Logged out");
break;
case AUTH_FAILED:
lv_label_set_text(label, "Login failed");
break;
}
}
static void log_out_click_event_cb(lv_event_t * e)
{
LV_UNUSED(e);
lv_subject_set_int(&auth_state_subject, LOGGED_OUT);
}
static void ui_init(void)
{
lv_subject_init_int(&auth_state_subject, LOGGED_OUT);
/*Create a slider in the center of the display*/
lv_obj_t * ta = lv_textarea_create(lv_screen_active());
lv_obj_set_pos(ta, 10, 10);
lv_obj_set_width(ta, 200);
lv_textarea_set_one_line(ta, true);
lv_textarea_set_password_mode(ta, true);
lv_textarea_set_placeholder_text(ta, "The password is: hello");
lv_obj_add_event_cb(ta, textarea_event_cb, LV_EVENT_READY, NULL);
lv_obj_bind_state_if_eq(ta, &auth_state_subject, LV_STATE_DISABLED, LOGGED_IN);
lv_obj_t * kb = lv_keyboard_create(lv_screen_active());
lv_keyboard_set_textarea(kb, ta);
lv_obj_t * btn;
lv_obj_t * label;
/*Create a log out button which will be active only when logged in*/
btn = lv_button_create(lv_screen_active());
lv_obj_set_pos(btn, 220, 10);
lv_obj_add_event_cb(btn, log_out_click_event_cb, LV_EVENT_CLICKED, NULL);
lv_obj_bind_state_if_not_eq(btn, &auth_state_subject, LV_STATE_DISABLED, LOGGED_IN);
label = lv_label_create(btn);
lv_label_set_text(label, "LOG OUT");
/*Create a label to show info*/
label = lv_label_create(lv_screen_active());
lv_obj_set_pos(label, 10, 60);
lv_subject_add_observer_obj(&auth_state_subject, info_label_observer_cb, label, NULL);
/*Create button which will be active only when logged in*/
btn = lv_button_create(lv_screen_active());
lv_obj_set_pos(btn, 10, 80);
lv_obj_add_flag(btn, LV_OBJ_FLAG_CHECKABLE);
lv_obj_bind_state_if_not_eq(btn, &auth_state_subject, LV_STATE_DISABLED, LOGGED_IN);
lv_button_bind_checked(btn, &engine_subject);
label = lv_label_create(btn);
lv_label_set_text(label, "START ENGINE");
}
#endif

View File

@@ -0,0 +1,158 @@
#include "../../lv_examples.h"
#if LV_USE_OBSERVER && LV_USE_SLIDER && LV_USE_LABEL && LV_USE_ROLLER && LV_USE_DROPDOWN && LV_FONT_MONTSERRAT_30 && LV_BUILD_EXAMPLES
static lv_subject_t hour_subject;
static lv_subject_t minute_subject;
static lv_subject_t format_subject;
static lv_subject_t am_pm_subject;
static lv_subject_t time_subject;
static lv_subject_t * time_group_array_subject[] = {&hour_subject, &minute_subject, &format_subject, &am_pm_subject};
const char * hour12_options = "01\n02\n03\n04\n05\n06\n07\n08\n09\n10\n11\n12";
const char * hour24_options =
"00\n01\n02\n03\n04\n05\n06\n07\n08\n09\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23";
const char * minute_options =
"00\n01\n02\n03\n04\n05\n06\n07\n08\n09\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n34\n35\n36\n37\n38\n39\n40\n41\n42\n43\n44\n45\n46\n47\n48\n49\n50\n51\n52\n53\n54\n55\n56\n57\n58\n59";
static void set_btn_clicked_event_cb(lv_event_t * e);
static void close_clicked_event_cb(lv_event_t * e);
static void hour_roller_options_update(lv_observer_t * observer, lv_subject_t * subject);
static void time_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
typedef enum {
TIME_FORMAT_12,
TIME_FORMAT_24,
} time_format_t;
typedef enum {
TIME_AM,
TIME_PM,
} time_am_pm_t;
/**
* Show how to handle a complex time setting with hour, minute, 12/24 hour mode, and AM/PM switch
* In a real application the time can be displayed on multiple screens and it's not trivial
* how and where to store the current values and how to get them.
* In this example the widgets to set the time are create/deleted dynamically,
* yet they always know what the current values are by using subjects.
*/
void lv_example_observer_3(void)
{
/*Initialize the subjects.
*The UI will update these and read the current values from here,
*however the application can update these values at any time and
*the widgets will be updated automatically. */
lv_subject_init_int(&hour_subject, 7);
lv_subject_init_int(&minute_subject, 45);
lv_subject_init_int(&format_subject, TIME_FORMAT_12);
lv_subject_init_int(&am_pm_subject, TIME_AM);
lv_subject_init_group(&time_subject, time_group_array_subject, 4);
/*Create the UI*/
lv_obj_t * time_label = lv_label_create(lv_screen_active());
lv_obj_set_style_text_font(time_label, &lv_font_montserrat_30, 0);
lv_subject_add_observer_obj(&time_subject, time_observer_cb, time_label, NULL);
lv_obj_set_pos(time_label, 24, 24);
lv_obj_t * set_btn = lv_button_create(lv_screen_active());
lv_obj_set_pos(set_btn, 180, 24);
lv_obj_add_event_cb(set_btn, set_btn_clicked_event_cb, LV_EVENT_CLICKED, NULL);
lv_obj_t * set_label = lv_label_create(set_btn);
lv_label_set_text(set_label, "Set");
/*Update some subjects to see if the UI is updated as well*/
lv_subject_set_int(&hour_subject, 9);
lv_subject_set_int(&minute_subject, 30);
lv_subject_set_int(&am_pm_subject, TIME_PM);
}
static void set_btn_clicked_event_cb(lv_event_t * e)
{
lv_obj_t * set_btn = lv_event_get_target(e);
lv_obj_add_state(set_btn, LV_STATE_DISABLED);
lv_obj_t * cont = lv_obj_create(lv_screen_active());
lv_obj_set_size(cont, lv_pct(100), LV_SIZE_CONTENT);
lv_obj_align(cont, LV_ALIGN_BOTTOM_MID, 0, 0);
lv_obj_t * hour_roller = lv_roller_create(cont);
lv_obj_add_flag(hour_roller, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK);
lv_subject_add_observer_obj(&format_subject, hour_roller_options_update, hour_roller, NULL);
lv_roller_bind_value(hour_roller, &hour_subject);
lv_obj_set_pos(hour_roller, 0, 0);
lv_obj_t * min_roller = lv_roller_create(cont);
lv_roller_set_options(min_roller, minute_options, LV_ROLLER_MODE_NORMAL);
lv_roller_bind_value(min_roller, &minute_subject);
lv_obj_set_pos(min_roller, 64, 0);
lv_obj_t * format_dropdown = lv_dropdown_create(cont);
lv_dropdown_set_options(format_dropdown, "12\n24");
lv_dropdown_bind_value(format_dropdown, &format_subject);
lv_obj_set_pos(format_dropdown, 128, 0);
lv_obj_set_width(format_dropdown, 80);
lv_obj_t * am_pm_dropdown = lv_dropdown_create(cont);
lv_dropdown_set_options(am_pm_dropdown, "am\npm");
lv_dropdown_bind_value(am_pm_dropdown, &am_pm_subject);
lv_obj_bind_state_if_eq(am_pm_dropdown, &format_subject, LV_STATE_DISABLED, TIME_FORMAT_24);
lv_obj_set_pos(am_pm_dropdown, 128, 48);
lv_obj_set_width(am_pm_dropdown, 80);
lv_obj_t * close_btn = lv_button_create(cont);
lv_obj_align(close_btn, LV_ALIGN_TOP_RIGHT, 0, 0);
/*Pass the set_btn as user_data to make it non-disabled on close*/
lv_obj_add_event_cb(close_btn, close_clicked_event_cb, LV_EVENT_CLICKED, set_btn);
lv_obj_t * close_label = lv_label_create(close_btn);
lv_label_set_text(close_label, LV_SYMBOL_CLOSE);
}
static void close_clicked_event_cb(lv_event_t * e)
{
lv_obj_t * set_btn = lv_event_get_user_data(e);
lv_obj_t * close_btn = lv_event_get_target(e);
lv_obj_t * cont = lv_obj_get_parent(close_btn);
lv_obj_remove_state(set_btn, LV_STATE_DISABLED);
lv_obj_delete(cont);
}
/*Watch all related subject to display the current time correctly*/
static void time_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
{
int32_t hour = lv_subject_get_int(lv_subject_get_group_element(subject, 0));
int32_t minute = lv_subject_get_int(lv_subject_get_group_element(subject, 1));
int32_t format = lv_subject_get_int(lv_subject_get_group_element(subject, 2));
int32_t am_pm = lv_subject_get_int(lv_subject_get_group_element(subject, 3));
lv_obj_t * label = lv_observer_get_target(observer);
if(format == TIME_FORMAT_24) {
lv_label_set_text_fmt(label, "%" LV_PRId32 ":%02" LV_PRId32, hour, minute);
}
else {
lv_label_set_text_fmt(label, "%"LV_PRId32":%02"LV_PRId32" %s", hour + 1, minute, am_pm == TIME_AM ? "am" : "pm");
}
}
/*Change the hour options on format change*/
static void hour_roller_options_update(lv_observer_t * observer, lv_subject_t * subject)
{
lv_obj_t * roller = lv_observer_get_target(observer);
int32_t prev_selected = lv_roller_get_selected(roller);
int32_t v = lv_subject_get_int(subject);
if(v == TIME_FORMAT_12) {
prev_selected--;
if(prev_selected > 12) prev_selected -= 12;
lv_roller_set_options(roller, hour12_options, LV_ROLLER_MODE_NORMAL);
}
else {
prev_selected++;
lv_roller_set_options(roller, hour24_options, LV_ROLLER_MODE_NORMAL);
}
lv_roller_set_selected(roller, prev_selected, LV_ANIM_OFF);
lv_obj_send_event(roller, LV_EVENT_VALUE_CHANGED, NULL);
}
#endif

View File

@@ -0,0 +1,205 @@
#include "../../lv_examples.h"
#if LV_USE_OBSERVER && LV_USE_SLIDER && LV_USE_LABEL && LV_USE_ROLLER && LV_USE_DROPDOWN && LV_FONT_MONTSERRAT_30 && LV_BUILD_EXAMPLES
static void cont_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
static void btn_create(lv_obj_t * parent, const char * text);
static void btn_click_event_cb(lv_event_t * e);
static void btn_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
static void indicator_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
static lv_subject_t current_tab_subject;
static lv_subject_t slider_subject[4];
static lv_subject_t dropdown_subject[3];
static lv_subject_t roller_subject[2];
void lv_example_observer_4(void)
{
lv_subject_init_int(&current_tab_subject, 0);
lv_subject_init_int(&slider_subject[0], 0);
lv_subject_init_int(&slider_subject[1], 0);
lv_subject_init_int(&slider_subject[2], 0);
lv_subject_init_int(&slider_subject[3], 0);
lv_subject_init_int(&dropdown_subject[0], 0);
lv_subject_init_int(&dropdown_subject[1], 0);
lv_subject_init_int(&dropdown_subject[2], 0);
lv_subject_init_int(&roller_subject[0], 0);
lv_subject_init_int(&roller_subject[1], 0);
lv_obj_t * main_cont = lv_obj_create(lv_screen_active());
lv_obj_remove_style_all(main_cont);
lv_obj_set_size(main_cont, lv_pct(100), lv_pct(100));
lv_obj_set_style_pad_all(main_cont, 0, 0);
lv_obj_set_flex_flow(main_cont, LV_FLEX_FLOW_COLUMN);
lv_obj_t * cont = lv_obj_create(main_cont);
lv_obj_remove_style_all(cont);
lv_obj_set_flex_grow(cont, 1);
lv_obj_set_style_pad_all(cont, 8, 0);
lv_obj_set_width(cont, lv_pct(100));
lv_subject_add_observer_obj(&current_tab_subject, cont_observer_cb, cont, NULL);
lv_obj_set_scroll_dir(cont, LV_DIR_VER);
lv_obj_t * footer = lv_obj_create(main_cont);
lv_obj_remove_style_all(footer);
lv_obj_set_style_pad_column(footer, 8, 0);
lv_obj_set_style_pad_all(footer, 8, 0);
lv_obj_set_flex_flow(footer, LV_FLEX_FLOW_ROW);
lv_obj_set_size(footer, lv_pct(100), 60);
lv_obj_align(footer, LV_ALIGN_BOTTOM_MID, 0, 0);
btn_create(footer, "First");
btn_create(footer, "Second");
btn_create(footer, "Third");
lv_obj_t * indicator = lv_obj_create(footer);
lv_obj_remove_style(indicator, NULL, 0);
lv_obj_set_style_bg_opa(indicator, LV_OPA_40, 0);
lv_subject_add_observer_obj(&current_tab_subject, indicator_observer_cb, indicator, NULL);
lv_obj_set_height(indicator, 10);
lv_obj_align(indicator, LV_ALIGN_BOTTOM_LEFT, 0, 0);
lv_obj_add_flag(indicator, LV_OBJ_FLAG_IGNORE_LAYOUT);
/*Be sure the indicator has the correct size*/
lv_obj_update_layout(indicator);
lv_subject_notify(&current_tab_subject);
}
static int32_t anim_get_x_cb(lv_anim_t * a)
{
return lv_obj_get_x_aligned(a->var);
}
static void anim_set_x_cb(void * obj, int32_t v)
{
lv_obj_set_x(obj, v);
}
static void cont_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
{
int32_t prev_v = lv_subject_get_previous_int(subject);
int32_t cur_v = lv_subject_get_int(subject);
lv_obj_t * cont = lv_observer_get_target(observer);
/*Animate out the previous content*/
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_duration(&a, 300);
lv_anim_set_path_cb(&a, lv_anim_path_ease_in_out);
lv_anim_set_exec_cb(&a, anim_set_x_cb);
lv_anim_set_get_value_cb(&a, anim_get_x_cb);
lv_anim_set_completed_cb(&a, lv_obj_delete_anim_completed_cb);
uint32_t i;
uint32_t delay = 0;
uint32_t child_cnt_prev = lv_obj_get_child_count(cont);
for(i = 0; i < child_cnt_prev; i++) {
lv_obj_t * child = lv_obj_get_child(cont, i);
lv_anim_set_var(&a, child);
if(prev_v < cur_v) {
lv_anim_set_values(&a, 0, -20);
}
else {
lv_anim_set_values(&a, 0, 20);
}
lv_anim_set_delay(&a, delay);
lv_anim_start(&a);
lv_obj_fade_out(child, 200, delay);
delay += 50;
}
/*Create the widgets according to the current value*/
if(cur_v == 0) {
for(i = 0; i < 4; i++) {
lv_obj_t * slider = lv_slider_create(cont);
lv_slider_bind_value(slider, &slider_subject[i]);
lv_obj_align(slider, LV_ALIGN_TOP_MID, 0, 10 + i * 30);
}
}
if(cur_v == 1) {
for(i = 0; i < 3; i++) {
lv_obj_t * dropdown = lv_dropdown_create(cont);
lv_dropdown_bind_value(dropdown, &dropdown_subject[i]);
lv_obj_align(dropdown, LV_ALIGN_TOP_MID, 0, i * 50);
}
}
if(cur_v == 2) {
for(i = 0; i < 2; i++) {
lv_obj_t * roller = lv_roller_create(cont);
lv_roller_bind_value(roller, &roller_subject[i]);
lv_obj_align(roller, LV_ALIGN_CENTER, - 80 + i * 160, 0);
}
}
/*Animate in the new widgets*/
lv_anim_set_completed_cb(&a, NULL);
for(i = child_cnt_prev; i < lv_obj_get_child_count(cont); i++) {
lv_obj_t * child = lv_obj_get_child(cont, i);
lv_anim_set_var(&a, child);
if(prev_v < cur_v) {
lv_anim_set_values(&a, 20, 0);
}
else {
lv_anim_set_values(&a, -20, -0);
}
lv_anim_set_delay(&a, delay);
lv_anim_start(&a);
lv_obj_fade_in(child, 200, delay);
delay += 50;
}
}
static void btn_create(lv_obj_t * parent, const char * text)
{
lv_obj_t * btn = lv_button_create(parent);
lv_obj_set_flex_grow(btn, 1);
lv_obj_set_height(btn, lv_pct(100));
lv_obj_set_style_radius(btn, 0, 0);
lv_subject_add_observer_obj(&current_tab_subject, btn_observer_cb, btn, NULL);
lv_obj_add_event_cb(btn, btn_click_event_cb, LV_EVENT_CLICKED, NULL);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, text);
lv_obj_center(label);
}
static void btn_click_event_cb(lv_event_t * e)
{
lv_obj_t * btn = lv_event_get_target(e);
uint32_t idx = lv_obj_get_index(btn);
lv_subject_set_int(&current_tab_subject, idx);
}
static void btn_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
{
int32_t prev_v = lv_subject_get_previous_int(subject);
int32_t cur_v = lv_subject_get_int(subject);
lv_obj_t * btn = lv_observer_get_target(observer);
int32_t idx = (int32_t)lv_obj_get_index(btn);
if(idx == prev_v) lv_obj_remove_state(btn, LV_STATE_CHECKED);
if(idx == cur_v) lv_obj_add_state(btn, LV_STATE_CHECKED);
}
static void indicator_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
{
int32_t cur_v = lv_subject_get_int(subject);
lv_obj_t * indicator = lv_observer_get_target(observer);
lv_obj_t * footer = lv_obj_get_parent(indicator);
lv_obj_t * btn_act = lv_obj_get_child(footer, cur_v);
lv_obj_set_width(indicator, lv_obj_get_width(btn_act));
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_exec_cb(&a, anim_set_x_cb);
lv_anim_set_duration(&a, 300);
lv_anim_set_path_cb(&a, lv_anim_path_ease_in_out);
lv_anim_set_var(&a, indicator);
lv_anim_set_values(&a, lv_obj_get_x(indicator), lv_obj_get_x(btn_act));
lv_anim_start(&a);
}
#endif

View File

@@ -0,0 +1,167 @@
#include "../../lv_examples.h"
#if LV_USE_OBSERVER && LV_USE_ARC && LV_USE_LABEL && LV_USE_BUTTON && LV_USE_SPINNER && LV_BUILD_EXAMPLES
typedef enum {
FW_UPDATE_STATE_IDLE,
FW_UPDATE_STATE_CONNECTING,
FW_UPDATE_STATE_CONNECTED,
FW_UPDATE_STATE_DOWNLOADING,
FW_UPDATE_STATE_CANCEL,
FW_UPDATE_STATE_READY,
} fw_update_state_t;
static void fw_upload_manager_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
static void fw_update_btn_clicked_event_cb(lv_event_t * e);
static void fw_update_close_event_cb(lv_event_t * e);
static void fw_update_win_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
static lv_subject_t fw_download_percent_subject;
static lv_subject_t fw_update_status_subject;
/**
* Show how to handle a complete firmware update process with observers.
* Normally it's hard to implement a firmware update process because in some cases
* - the App needs to was for the UI (wait for a button press)
* - the UI needs to wait for the App (connecting or downloading)
* With observers these complex mechanisms can be implemented a simple and clean way.
*/
void lv_example_observer_5(void)
{
lv_subject_init_int(&fw_download_percent_subject, 0);
lv_subject_init_int(&fw_update_status_subject, FW_UPDATE_STATE_IDLE);
lv_subject_add_observer(&fw_update_status_subject, fw_upload_manager_observer_cb, NULL);
/*Create start FW update button*/
lv_obj_t * btn = lv_button_create(lv_screen_active());
lv_obj_add_event_cb(btn, fw_update_btn_clicked_event_cb, LV_EVENT_CLICKED, NULL);
lv_obj_center(btn);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, "Firmware update");
}
static void fw_update_btn_clicked_event_cb(lv_event_t * e)
{
LV_UNUSED(e);
lv_obj_t * win = lv_win_create(lv_screen_active());
lv_obj_set_size(win, lv_pct(90), lv_pct(90));
lv_obj_set_height(lv_win_get_header(win), 40);
lv_obj_set_style_radius(win, 8, 0);
lv_obj_set_style_shadow_width(win, 24, 0);
lv_obj_set_style_shadow_offset_x(win, 2, 0);
lv_obj_set_style_shadow_offset_y(win, 3, 0);
lv_obj_set_style_shadow_color(win, lv_color_hex3(0x888), 0);
lv_win_add_title(win, "Firmware update");
lv_obj_t * btn = lv_win_add_button(win, LV_SYMBOL_CLOSE, 40);
lv_obj_add_event_cb(btn, fw_update_close_event_cb, LV_EVENT_CLICKED, NULL);
lv_obj_center(win);
lv_subject_set_int(&fw_update_status_subject, FW_UPDATE_STATE_IDLE);
lv_subject_add_observer_obj(&fw_update_status_subject, fw_update_win_observer_cb, win, NULL);
}
static void fw_update_close_event_cb(lv_event_t * e)
{
LV_UNUSED(e);
lv_subject_set_int(&fw_update_status_subject, FW_UPDATE_STATE_CANCEL);
}
static void restart_btn_click_event_cb(lv_event_t * e)
{
lv_obj_t * win = lv_event_get_user_data(e);
lv_obj_delete(win);
lv_subject_set_int(&fw_update_status_subject, FW_UPDATE_STATE_IDLE);
}
static void fw_update_win_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
{
lv_obj_t * win = lv_observer_get_target(observer);
lv_obj_t * cont = lv_win_get_content(win);
fw_update_state_t status = lv_subject_get_int(&fw_update_status_subject);
if(status == FW_UPDATE_STATE_IDLE) {
lv_obj_clean(cont);
lv_obj_t * spinner = lv_spinner_create(cont);
lv_obj_center(spinner);
lv_obj_set_size(spinner, 130, 130);
lv_obj_t * label = lv_label_create(cont);
lv_label_set_text(label, "Connecting");
lv_obj_center(label);
lv_subject_set_int(subject, FW_UPDATE_STATE_CONNECTING);
}
else if(status == FW_UPDATE_STATE_DOWNLOADING) {
lv_obj_clean(cont);
lv_obj_t * arc = lv_arc_create(cont);
lv_arc_bind_value(arc, &fw_download_percent_subject);
lv_obj_center(arc);
lv_obj_set_size(arc, 130, 130);
lv_obj_remove_flag(arc, LV_OBJ_FLAG_CLICKABLE);
lv_obj_t * label = lv_label_create(cont);
lv_label_bind_text(label, &fw_download_percent_subject, "%d %%");
lv_obj_center(label);
}
else if(status == FW_UPDATE_STATE_READY) {
lv_obj_clean(cont);
lv_obj_t * label = lv_label_create(cont);
lv_label_set_text(label, "Firmware update is ready");
lv_obj_align(label, LV_ALIGN_CENTER, 0, -20);
lv_obj_t * btn = lv_button_create(cont);
lv_obj_align(btn, LV_ALIGN_CENTER, 0, 20);
lv_obj_add_event_cb(btn, restart_btn_click_event_cb, LV_EVENT_CLICKED, win);
label = lv_label_create(btn);
lv_label_set_text(label, "Restart");
}
else if(status == FW_UPDATE_STATE_CANCEL) {
lv_obj_delete(win);
}
}
static void connect_timer_cb(lv_timer_t * t)
{
if(lv_subject_get_int(&fw_update_status_subject) != FW_UPDATE_STATE_CANCEL) {
lv_subject_set_int(&fw_update_status_subject, FW_UPDATE_STATE_CONNECTED);
}
lv_timer_delete(t);
}
static void download_timer_cb(lv_timer_t * t)
{
if(lv_subject_get_int(&fw_update_status_subject) == FW_UPDATE_STATE_CANCEL) {
lv_timer_delete(t);
return;
}
int32_t v = lv_subject_get_int(&fw_download_percent_subject);
if(v < 100) {
lv_subject_set_int(&fw_download_percent_subject, v + 1);
}
else {
lv_subject_set_int(&fw_update_status_subject, FW_UPDATE_STATE_READY);
lv_timer_delete(t);
}
}
/**
* Emulate connection and FW downloading by timers
*/
static void fw_upload_manager_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
{
LV_UNUSED(subject);
LV_UNUSED(observer);
fw_update_state_t state = lv_subject_get_int(&fw_update_status_subject);
if(state == FW_UPDATE_STATE_CONNECTING) {
lv_timer_create(connect_timer_cb, 2000, NULL);
}
else if(state == FW_UPDATE_STATE_CONNECTED) {
lv_subject_set_int(&fw_download_percent_subject, 0);
lv_subject_set_int(&fw_update_status_subject, FW_UPDATE_STATE_DOWNLOADING);
lv_timer_create(download_timer_cb, 50, NULL);
}
}
#endif

View File

@@ -0,0 +1,190 @@
#include "../../lv_examples.h"
#if LV_USE_OBSERVER && LV_USE_SLIDER && LV_USE_LABEL && LV_BUILD_EXAMPLES
typedef enum {
THEME_MODE_LIGHT,
THEME_MODE_DARK,
} theme_mode_t;
static lv_obj_t * my_panel_create(lv_obj_t * parent);
static lv_obj_t * my_button_create(lv_obj_t * parent, const char * text, lv_event_cb_t event_cb);
static void switch_theme_event_cb(lv_event_t * e);
static lv_subject_t theme_subject;
/**
* Change between light and dark mode
*/
void lv_example_observer_6(void)
{
lv_subject_init_int(&theme_subject, THEME_MODE_DARK);
lv_obj_t * panel1 = my_panel_create(lv_screen_active());
lv_obj_set_flex_flow(panel1, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(panel1, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_size(panel1, lv_pct(90), lv_pct(90));
lv_obj_center(panel1);
my_button_create(panel1, "Button 1", switch_theme_event_cb);
my_button_create(panel1, "Button 2", switch_theme_event_cb);
my_button_create(panel1, "Button 3", switch_theme_event_cb);
my_button_create(panel1, "Button 4", switch_theme_event_cb);
my_button_create(panel1, "Button 5", switch_theme_event_cb);
my_button_create(panel1, "Button 6", switch_theme_event_cb);
my_button_create(panel1, "Button 7", switch_theme_event_cb);
my_button_create(panel1, "Button 8", switch_theme_event_cb);
my_button_create(panel1, "Button 9", switch_theme_event_cb);
my_button_create(panel1, "Button 10", switch_theme_event_cb);
}
static void switch_theme_event_cb(lv_event_t * e)
{
LV_UNUSED(e);
if(lv_subject_get_int(&theme_subject) == THEME_MODE_LIGHT) lv_subject_set_int(&theme_subject, THEME_MODE_DARK);
else lv_subject_set_int(&theme_subject, THEME_MODE_LIGHT);
}
/*-----------------------------------------
* my_panel.c
*
* It would be a separate file with its own
* local types, data, and functions
*------------------------------------------*/
typedef struct {
lv_style_t style_main;
lv_style_t style_scrollbar;
} my_panel_styles_t;
static void my_panel_style_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
{
LV_UNUSED(subject);
LV_UNUSED(observer);
theme_mode_t m = lv_subject_get_int(&theme_subject);
my_panel_styles_t * styles = lv_observer_get_target(observer);
if(m == THEME_MODE_LIGHT) {
lv_style_set_bg_color(&styles->style_main, lv_color_hex3(0xfff));
lv_style_set_shadow_color(&styles->style_main, lv_color_hex3(0x888));
lv_style_set_text_color(&styles->style_main, lv_color_hex3(0x222));
lv_style_set_bg_color(&styles->style_scrollbar, lv_color_hex3(0x888));
}
if(m == THEME_MODE_DARK) {
lv_style_set_bg_color(&styles->style_main, lv_color_hex(0x040038));
lv_style_set_shadow_color(&styles->style_main, lv_color_hex3(0xaaa));
lv_style_set_text_color(&styles->style_main, lv_color_hex3(0xeee));
lv_style_set_bg_color(&styles->style_scrollbar, lv_color_hex3(0xaaa));
}
lv_obj_report_style_change(&styles->style_main);
lv_obj_report_style_change(&styles->style_scrollbar);
}
static lv_obj_t * my_panel_create(lv_obj_t * parent)
{
static bool inited = false;
static my_panel_styles_t styles;
if(!inited) {
inited = true;
lv_style_init(&styles.style_main);
lv_style_set_radius(&styles.style_main, 12);
lv_style_set_bg_opa(&styles.style_main, LV_OPA_COVER);
lv_style_set_shadow_width(&styles.style_main, 24);
lv_style_set_shadow_offset_x(&styles.style_main, 4);
lv_style_set_shadow_offset_y(&styles.style_main, 6);
lv_style_set_pad_all(&styles.style_main, 12);
lv_style_set_pad_gap(&styles.style_main, 16);
lv_style_init(&styles.style_scrollbar);
lv_style_set_width(&styles.style_scrollbar, 4);
lv_style_set_radius(&styles.style_scrollbar, 2);
lv_style_set_pad_right(&styles.style_scrollbar, 8);
lv_style_set_pad_ver(&styles.style_scrollbar, 8);
lv_style_set_bg_opa(&styles.style_scrollbar, LV_OPA_50);
lv_subject_add_observer_with_target(&theme_subject, my_panel_style_observer_cb, &styles, NULL);
}
lv_obj_t * panel = lv_obj_create(parent);
lv_obj_remove_style_all(panel);
lv_obj_add_style(panel, &styles.style_main, 0);
lv_obj_add_style(panel, &styles.style_scrollbar, LV_PART_SCROLLBAR);
return panel;
}
/*-----------------------------------------
* my_button.c
*
* It would be a separate file with its own
* local types, data, and functions
*------------------------------------------*/
typedef struct {
lv_style_t style_main;
lv_style_t style_pressed;
} my_button_styles_t;
static void my_button_style_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
{
LV_UNUSED(subject);
LV_UNUSED(observer);
theme_mode_t m = lv_subject_get_int(&theme_subject);
my_button_styles_t * styles = lv_observer_get_target(observer);
if(m == THEME_MODE_LIGHT) {
lv_style_set_bg_color(&styles->style_main, lv_color_hex(0x3379de));
lv_style_set_bg_grad_color(&styles->style_main, lv_color_hex(0xd249a5));
lv_style_set_shadow_color(&styles->style_main, lv_color_hex(0x3379de));
lv_style_set_text_color(&styles->style_main, lv_color_hex3(0xfff));
lv_style_set_color_filter_opa(&styles->style_pressed, LV_OPA_70);
}
if(m == THEME_MODE_DARK) {
lv_style_set_bg_color(&styles->style_main, lv_color_hex(0xde1382));
lv_style_set_bg_grad_color(&styles->style_main, lv_color_hex(0x4b0c72));
lv_style_set_shadow_color(&styles->style_main, lv_color_hex(0x4b0c72));
lv_style_set_text_color(&styles->style_main, lv_color_hex3(0xfff));
lv_style_set_color_filter_opa(&styles->style_pressed, LV_OPA_30);
}
lv_obj_report_style_change(&styles->style_main);
lv_obj_report_style_change(&styles->style_pressed);
}
static lv_obj_t * my_button_create(lv_obj_t * parent, const char * text, lv_event_cb_t event_cb)
{
static bool inited = false;
static my_button_styles_t styles;
if(!inited) {
inited = true;
lv_style_init(&styles.style_main);
lv_style_set_radius(&styles.style_main, LV_RADIUS_CIRCLE);
lv_style_set_bg_opa(&styles.style_main, LV_OPA_COVER);
lv_style_set_bg_grad_dir(&styles.style_main, LV_GRAD_DIR_HOR);
lv_style_set_shadow_width(&styles.style_main, 24);
lv_style_set_shadow_offset_y(&styles.style_main, 6);
lv_style_set_pad_hor(&styles.style_main, 32);
lv_style_set_pad_ver(&styles.style_main, 12);
lv_style_init(&styles.style_pressed);
lv_style_set_color_filter_dsc(&styles.style_pressed, &lv_color_filter_shade);
lv_subject_add_observer_with_target(&theme_subject, my_button_style_observer_cb, &styles, NULL);
}
lv_obj_t * btn = lv_button_create(parent);
lv_obj_remove_style_all(btn);
lv_obj_add_style(btn, &styles.style_main, 0);
lv_obj_add_style(btn, &styles.style_pressed, LV_STATE_PRESSED);
lv_obj_add_event_cb(btn, event_cb, LV_EVENT_CLICKED, NULL);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, text);
return btn;
}
#endif

View File

@@ -0,0 +1,7 @@
Simple snapshot example
-----------------------
.. lv_example:: others/snapshot/lv_example_snapshot_1
:language: c

View File

@@ -0,0 +1,38 @@
/**
* @file lv_example_snapshot.h
*
*/
#ifndef LV_EX_SNAPSHOT_H
#define LV_EX_SNAPSHOT_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_example_snapshot_1(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_EX_GET_STARTED_H*/

View File

@@ -0,0 +1,58 @@
#include "../../lv_examples.h"
#if LV_USE_SNAPSHOT && LV_BUILD_EXAMPLES
static void event_cb(lv_event_t * e)
{
lv_obj_t * snapshot_obj = lv_event_get_user_data(e);
lv_obj_t * img = lv_event_get_target(e);
if(snapshot_obj) {
lv_draw_buf_t * snapshot = (lv_draw_buf_t *)lv_image_get_src(snapshot_obj);
if(snapshot) {
lv_draw_buf_destroy(snapshot);
}
/*Update the snapshot, we know parent of object is the container.*/
snapshot = lv_snapshot_take(lv_obj_get_parent(img), LV_COLOR_FORMAT_ARGB8888);
if(snapshot == NULL)
return;
lv_image_set_src(snapshot_obj, snapshot);
}
}
void lv_example_snapshot_1(void)
{
LV_IMAGE_DECLARE(img_star);
lv_obj_t * root = lv_screen_active();
lv_obj_set_style_bg_color(root, lv_palette_main(LV_PALETTE_LIGHT_BLUE), 0);
/*Create an image object to show snapshot*/
lv_obj_t * snapshot_obj = lv_image_create(root);
lv_obj_set_style_bg_color(snapshot_obj, lv_palette_main(LV_PALETTE_PURPLE), 0);
lv_obj_set_style_bg_opa(snapshot_obj, LV_OPA_100, 0);
lv_image_set_scale(snapshot_obj, 128);
lv_image_set_rotation(snapshot_obj, 300);
/*Create the container and its children*/
lv_obj_t * container = lv_obj_create(root);
lv_obj_center(container);
lv_obj_set_size(container, 180, 180);
lv_obj_set_flex_flow(container, LV_FLEX_FLOW_ROW_WRAP);
lv_obj_set_flex_align(container, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_radius(container, 50, 0);
lv_obj_t * img;
int i;
for(i = 0; i < 4; i++) {
img = lv_image_create(container);
lv_image_set_src(img, &img_star);
lv_obj_set_style_bg_color(img, lv_color_black(), 0);
lv_obj_set_style_bg_opa(img, LV_OPA_COVER, 0);
// lv_obj_set_style_transform_scale(img, 400, LV_STATE_PRESSED);
lv_obj_add_flag(img, LV_OBJ_FLAG_CLICKABLE);
lv_obj_add_event_cb(img, event_cb, LV_EVENT_PRESSED, snapshot_obj);
lv_obj_add_event_cb(img, event_cb, LV_EVENT_RELEASED, snapshot_obj);
}
}
#endif