Initial commit: TXW82x FPV v2.7.0.7-42229 SDK + project sources

This commit is contained in:
2026-07-06 11:30:13 +08:00
commit e76462eeb7
3451 changed files with 1415300 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,84 @@
#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);
uint16_t path_len = strlen(cur_path);
uint16_t fn_len = strlen(sel_fn);
if((path_len + fn_len) <= LV_FILE_EXPLORER_PATH_MAX_LEN) {
char file_info[LV_FILE_EXPLORER_PATH_MAX_LEN];
strcpy(file_info, cur_path);
strcat(file_info, sel_fn);
LV_LOG_USER("%s", file_info);
}
else 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_scr_act());
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 enviroment 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,47 @@
import fs_driver
import os
LV_FILE_EXPLORER_QUICK_ACCESS = True
LV_USE_FS_WIN32 = False
LV_FILE_EXPLORER_PATH_MAX_LEN = 128
def file_explorer_event_handler(e) :
code = e.get_code()
obj = e.get_target()
if code == lv.EVENT.VALUE_CHANGED:
cur_path = obj.explorer_get_current_path()
sel_fn = obj.explorer_get_selected_file_name()
# print("cur_path: " + str(cur_path), " sel_fn: " + str(sel_fn))
print(str(cur_path) + str(sel_fn))
file_explorer = lv.file_explorer(lv.scr_act())
file_explorer.explorer_set_sort(lv.EXPLORER_SORT.KIND)
if LV_USE_FS_WIN32 :
file_explorer.explorer_open_dir("D:")
if LV_FILE_EXPLORER_QUICK_ACCESS :
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.HOME_DIR, "C:/Users/Public/Desktop")
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.VIDEO_DIR, "C:/Users/Public/Videos")
file_explorer.explorer_set_quick_access_path(lv.EXPLORER_PICTURES_DIR, "C:/Users/Public/Pictures");
file_explorer.explorer_set_quick_access_path(lv.EXPLORER_MUSIC_DIR, "C:/Users/Public/Music");
file_explorer.explorer_set_quick_access_path(lv.EXPLORER_DOCS_DIR, "C:/Users/Public/Documents");
file_explorer.explorer_set_quick_access_path(lv.EXPLORER_FS_DIR, "D:");
# linux
file_explorer.explorer_open_dir("A:/")
if LV_FILE_EXPLORER_QUICK_ACCESS :
home_dir = "A:" + os.getenv('HOME')
print("quick access: " + home_dir)
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.HOME_DIR, home_dir)
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.VIDEO_DIR, home_dir + "/Videos")
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.PICTURES_DIR, home_dir + "/Pictures")
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.MUSIC_DIR, home_dir + "/Music")
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.DOCS_DIR, home_dir + "/Documents")
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.FS_DIR, "A:/")
file_explorer.add_event_cb(file_explorer_event_handler, lv.EVENT.ALL, None)

View File

@@ -0,0 +1,143 @@
#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);
uint16_t path_len = strlen(cur_path);
uint16_t fn_len = strlen(sel_fn);
if((path_len + fn_len) <= LV_FILE_EXPLORER_PATH_MAX_LEN) {
char file_info[LV_FILE_EXPLORER_PATH_MAX_LEN];
strcpy(file_info, cur_path);
strcat(file_info, sel_fn);
LV_LOG_USER("%s", file_info);
}
else 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_clear_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_scr_act());
#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 enviroment 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_btn_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_align_to(dd, btn, LV_ALIGN_OUT_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,102 @@
import fs_driver
import os
LV_FILE_EXPLORER_QUICK_ACCESS = True
LV_USE_FS_WIN32 = False
LV_FILE_EXPLORER_PATH_MAX_LEN = 128
def file_explorer_event_handler(e):
code = e.get_code()
obj = e.get_target()
if code == lv.EVENT.VALUE_CHANGED:
cur_path = obj.explorer_get_current_path()
sel_fn = obj.explorer_get_selected_file_name()
print(str(cur_path) + str(sel_fn))
def btn_event_handler(e,fe_quick_access_obj):
code = e.get_code()
btn = e.get_target()
# lv_obj_t * file_explorer = lv_event_get_user_data(e);
if code == lv.EVENT.VALUE_CHANGED :
if btn.has_state(lv.STATE.CHECKED) :
fe_quick_access_obj.add_flag(lv.obj.FLAG.HIDDEN)
else :
fe_quick_access_obj.clear_flag(lv.obj.FLAG.HIDDEN)
def dd_event_handler(e, file_explorer):
code = e.get_code()
dd = e.get_target()
# fe_quick_access_obj = lv_event_get_user_data(e);
if code == lv.EVENT.VALUE_CHANGED :
buf = bytearray(32)
lv.dropdown.get_selected_str(dd,buf,len(buf))
if buf[:4] == b"NONE":
# print("set sort to NONE")
file_explorer.explorer_set_sort(lv.EXPLORER_SORT.NONE)
elif buf[:4] == b"KIND" :
# print("set sort to KIND")
file_explorer.explorer_set_sort(lv.EXPLORER_SORT.KIND)
file_explorer = lv.file_explorer(lv.scr_act())
if LV_USE_FS_WIN32 :
file_explorer.explorer_open_dir("D:")
if LV_FILE_EXPLORER_QUICK_ACCESS :
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.HOME_DIR, "C:/Users/Public/Desktop")
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.VIDEO_DIR, "C:/Users/Public/Videos")
file_explorer.explorer_set_quick_access_path(lv.EXPLORER_PICTURES_DIR, "C:/Users/Public/Pictures");
file_explorer.explorer_set_quick_access_path(lv.EXPLORER_MUSIC_DIR, "C:/Users/Public/Music");
file_explorer.explorer_set_quick_access_path(lv.EXPLORER_DOCS_DIR, "C:/Users/Public/Documents");
file_explorer.explorer_set_quick_access_path(lv.EXPLORER_FS_DIR, "D:");
# linux
file_explorer.explorer_open_dir("A:/")
if LV_FILE_EXPLORER_QUICK_ACCESS :
home_dir = "A:" + os.getenv('HOME')
print("quick access: " + home_dir)
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.HOME_DIR, home_dir)
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.VIDEO_DIR, home_dir + "/Videos")
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.PICTURES_DIR, home_dir + "/Pictures")
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.MUSIC_DIR, home_dir + "/Music")
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.DOCS_DIR, home_dir + "/Documents")
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.FS_DIR, "A:/")
file_explorer.add_event_cb(file_explorer_event_handler, lv.EVENT.ALL, None)
# Quick access status control button
fe_quick_access_obj = file_explorer.explorer_get_quick_access_area()
fe_header_obj = file_explorer.explorer_get_header()
btn = lv.btn(fe_header_obj)
btn.set_style_radius(2, 0)
btn.set_style_pad_all(4, 0)
btn.align(lv.ALIGN.LEFT_MID, 0, 0)
btn.add_flag(lv.obj.FLAG.CHECKABLE)
label = lv.label(btn)
label.set_text(lv.SYMBOL.LIST)
label.center()
btn.add_event_cb(lambda evt: btn_event_handler(evt,fe_quick_access_obj), lv.EVENT.VALUE_CHANGED, None)
#btn.add_event_cb(lambda evt: btn_event_handler(evt,file_explorer), lv.EVENT.VALUE_CHANGED, None)
# Sort control
opts = "NONE\nKIND"
dd = lv.dropdown(fe_header_obj)
dd.set_style_radius(4, 0)
dd.set_style_pad_all(0, 0)
dd.set_size(lv.pct(30), lv.SIZE_CONTENT)
dd.set_options_static(opts)
dd.align(lv.ALIGN.RIGHT_MID, 0, 0)
# lv_obj_align_to(dd, btn, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
dd.add_event_cb(lambda evt: dd_event_handler(evt,file_explorer), lv.EVENT.VALUE_CHANGED, None)
#dd.add_event_cb(lambda evt: dd_event_handler(evt,fe_quick_access_obj), lv.EVENT.VALUE_CHANGED, None)

View File

@@ -0,0 +1,128 @@
#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);
uint16_t path_len = strlen(cur_path);
uint16_t fn_len = strlen(sel_fn);
if((path_len + fn_len) <= LV_FILE_EXPLORER_PATH_MAX_LEN) {
char file_info[LV_FILE_EXPLORER_PATH_MAX_LEN];
strcpy(file_info, cur_path);
strcat(file_info, sel_fn);
LV_LOG_USER("%s", file_info);
}
else 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_cnt(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_scr_act());
/*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 enviroment 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,89 @@
import fs_driver
import os
LV_FILE_EXPLORER_QUICK_ACCESS = True
LV_USE_FS_WIN32 = False
LV_FILE_EXPLORER_PATH_MAX_LEN = 128
def exch_table_item(tb, i, j):
tmp = tb.get_cell_value(i, 0)
tb.set_cell_value(0, 2, tmp)
tb.set_cell_value(i, 0, tb.get_cell_value(j, 0))
tb.set_cell_value(j, 0, tb.get_cell_value(0, 2))
tmp = tb.get_cell_value(i, 1)
tb.set_cell_value(0, 2, tmp)
tb.set_cell_value(i, 1, tb.get_cell_value(j, 1))
tb.set_cell_value(j, 1, tb.get_cell_value(0, 2))
# Quick sort 3 way
def sort_by_file_kind(tb, lo, hi) :
if lo >= hi:
return;
lt = lo
i = lo + 1
gt = hi
v = tb.get_cell_value(lo, 1)
while i <= gt :
if tb.get_cell_value(i, 1) < v :
lt += 1
i += 1
exch_table_item(tb, lt, i)
elif tb.get_cell_value(i, 1) > v:
gt -= 1
exch_table_item(tb, i, gt)
else :
i += 1
sort_by_file_kind(tb, lo, lt - 1);
sort_by_file_kind(tb, gt + 1, hi);
def file_explorer_event_handler(e) :
code = e.get_code()
obj = e.get_target()
if code == lv.EVENT.VALUE_CHANGED:
cur_path = obj.explorer_get_current_path()
sel_fn = obj.explorer_get_selected_file_name()
print(str(cur_path) + str(sel_fn))
elif code == lv.EVENT.READY :
tb = obj.explorer_get_file_table()
sum = tb.get_row_cnt()
# print("sum: ",sum)
sort_by_file_kind(tb, 0, (sum - 1));
file_explorer = lv.file_explorer(lv.scr_act())
# Before custom sort, please set the default sorting to NONE. The default is NONE.
file_explorer.explorer_set_sort(lv.EXPLORER_SORT.NONE)
file_explorer = lv.file_explorer(lv.scr_act())
if LV_USE_FS_WIN32 :
file_explorer.explorer_open_dir("D:")
if LV_FILE_EXPLORER_QUICK_ACCESS :
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.HOME_DIR, "C:/Users/Public/Desktop")
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.VIDEO_DIR, "C:/Users/Public/Videos")
file_explorer.explorer_set_quick_access_path(lv.EXPLORER_PICTURES_DIR, "C:/Users/Public/Pictures");
file_explorer.explorer_set_quick_access_path(lv.EXPLORER_MUSIC_DIR, "C:/Users/Public/Music");
file_explorer.explorer_set_quick_access_path(lv.EXPLORER_DOCS_DIR, "C:/Users/Public/Documents");
file_explorer.explorer_set_quick_access_path(lv.EXPLORER_FS_DIR, "D:");
# linux
file_explorer.explorer_open_dir("A:/")
if LV_FILE_EXPLORER_QUICK_ACCESS :
home_dir = "A:" + os.getenv('HOME')
print("quick access: " + home_dir)
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.HOME_DIR, home_dir)
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.VIDEO_DIR, home_dir + "/Videos")
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.PICTURES_DIR, home_dir + "/Pictures")
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.MUSIC_DIR, home_dir + "/Music")
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.DOCS_DIR, home_dir + "/Documents")
file_explorer.explorer_set_quick_access_path(lv.EXPLORER.FS_DIR, "A:/")
file_explorer.add_event_cb(file_explorer_event_handler, lv.EVENT.ALL, None)

View File

@@ -0,0 +1,16 @@
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,60 @@
/**
* @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_del(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_scr_act());
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_del, 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_del(lv_event_t * e)
{
lv_fragment_manager_t * manager = (lv_fragment_manager_t *) lv_event_get_user_data(e);
lv_fragment_manager_del(manager);
}
#endif

View File

@@ -0,0 +1,127 @@
/**
* @file lv_example_fragment_2.c
* @brief Navigation stack using obj fragment
*/
#include "../../lv_examples.h"
#if LV_USE_FRAGMENT && LV_USE_WIN && 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_del(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_scr_act());
lv_obj_set_size(root, LV_PCT(100), LV_PCT(100));
lv_obj_set_layout(root, LV_LAYOUT_GRID);
static const lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
static const lv_coord_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_btn_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_btn_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_del, 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_btn_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_del(lv_event_t * e)
{
lv_fragment_manager_t * manager = (lv_fragment_manager_t *) lv_event_get_user_data(e);
lv_fragment_manager_del(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,24 @@
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

View File

@@ -0,0 +1,41 @@
/**
* @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);
/**********************
* 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_scr_act());
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_btn_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*/
lv_obj_t * 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_scr_act());
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,63 @@
#
# Demonstrate a a basic grid navigation
#
# It's assumed that the default group is set and
# there is a keyboard indev
cont1 = lv.obj(lv.scr_act())
lv.gridnav_add(cont1, lv.GRIDNAV_CTRL.NONE)
# Use flex here, but works with grid or manually placed objects as well
cont1.set_flex_flow(lv.FLEX_FLOW.ROW_WRAP)
cont1.set_style_bg_color(lv.palette_lighten(lv.PALETTE.BLUE, 5), lv.STATE.FOCUSED)
cont1.set_size(lv.pct(50), lv.pct(100))
# Only the container needs to be in a group
lv.group_get_default().add_obj(cont1)
label = lv.label(cont1)
label.set_text("No rollover")
for i in range(10):
obj = lv.btn(cont1)
obj.set_size(70, lv.SIZE_CONTENT)
obj.add_flag(lv.obj.FLAG.CHECKABLE)
lv.group_remove_obj(obj) # Not needed, we use the gridnav instead
label = lv.label(obj)
label.set_text("{:d}".format(i))
label.center()
# Create a second container with rollover grid nav mode.
cont2 = lv.obj(lv.scr_act())
lv.gridnav_add(cont2,lv.GRIDNAV_CTRL.ROLLOVER)
cont2.set_style_bg_color(lv.palette_lighten(lv.PALETTE.BLUE, 5), lv.STATE.FOCUSED)
cont2.set_size(lv.pct(50), lv.pct(100))
cont2.align(lv.ALIGN.RIGHT_MID, 0, 0)
label = lv.label(cont2)
label.set_width(lv.pct(100))
label.set_text("Rollover\nUse tab to focus the other container")
# Only the container needs to be in a group
lv.group_get_default().add_obj(cont2)
# Add and place some children manually
ta = lv.textarea(cont2)
ta.set_size(lv.pct(100), 80)
ta.set_pos(0, 80);
lv.group_remove_obj(ta) # Not needed, we use the gridnav instead
cb = lv.checkbox(cont2)
cb.set_pos(0, 170)
lv.group_remove_obj(cb) # Not needed, we use the gridnav instead
sw1 = lv.switch(cont2)
sw1.set_pos(0, 200);
lv.group_remove_obj(sw1) # Not needed, we use the gridnav instead
sw2 = lv.switch(cont2)
sw2.set_pos(lv.pct(50), 200)
lv.group_remove_obj(sw2) # Not needed, we use the gridnav instead

View File

@@ -0,0 +1,44 @@
#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_scr_act());
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_btn(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_scr_act());
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_btn(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,32 @@
#
# Grid navigation on a list
#
# It's assumed that the default group is set and
# there is a keyboard indev
list1 = lv.list(lv.scr_act())
lv.gridnav_add(list1, lv.GRIDNAV_CTRL.NONE)
list1.set_size(lv.pct(45), lv.pct(80))
list1.align(lv.ALIGN.LEFT_MID, 5, 0)
list1.set_style_bg_color(lv.palette_lighten(lv.PALETTE.BLUE, 5), lv.STATE.FOCUSED)
lv.group_get_default().add_obj(list1)
for i in range(15):
item_text = "File {:d}".format(i)
item = list1.add_btn(lv.SYMBOL.FILE, item_text)
item.set_style_bg_opa(0, 0)
lv.group_remove_obj(item) # Not needed, we use the gridnav instead
list2 = lv.list(lv.scr_act())
lv.gridnav_add(list2, lv.GRIDNAV_CTRL.ROLLOVER)
list2.set_size(lv.pct(45), lv.pct(80))
list2.align(lv.ALIGN.RIGHT_MID, -5, 0)
list2.set_style_bg_color(lv.palette_lighten(lv.PALETTE.BLUE, 5), lv.STATE.FOCUSED)
lv.group_get_default().add_obj(list2)
for i in range(15):
item_text = "Folder {:d}".format(i)
item = list2.add_btn(lv.SYMBOL.DIRECTORY, item_text)
item.set_style_bg_opa(0, 0)
lv.group_remove_obj(item)

View File

@@ -0,0 +1,101 @@
#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_current_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_scr_act());
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_btn_create(cont_main);
lv_group_remove_obj(btn);
label = lv_label_create(btn);
lv_label_set_text(label, "Button 1");
btn = lv_btn_create(cont_main);
lv_group_remove_obj(btn);
label = lv_label_create(btn);
lv_label_set_text(label, "Button 2");
/*Create an other 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 an other 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_btn_create(cont_sub2);
lv_group_remove_obj(btn);
label = lv_label_create(btn);
lv_label_set_text(label, "Button 3");
btn = lv_btn_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,84 @@
def cont_sub_event_cb(e):
k = e.get_key()
obj = e.get_current_target()
if k == lv.KEY.ENTER:
lv.group_focus_obj(obj)
elif k == lv.KEY.ESC:
obj.get_group().focus_next()
#
# Nested grid navigations
#
# It's assumed that the default group is set and
# there is a keyboard indev*/
cont_main = lv.obj(lv.scr_act())
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_get_default().add_obj(cont_main)
# Use flex here, but works with grid or manually placed objects as well
cont_main.set_flex_flow(lv.FLEX_FLOW.ROW_WRAP)
cont_main.set_style_bg_color(lv.palette_lighten(lv.PALETTE.BLUE, 5), lv.STATE.FOCUSED)
cont_main.set_size(lv.pct(80), lv.SIZE_CONTENT)
btn = lv.btn(cont_main)
lv.group_remove_obj(btn)
label = lv.label(btn)
label.set_text("Button 1")
btn = lv.btn(cont_main)
lv.group_remove_obj(btn)
label = lv.label(btn)
label.set_text("Button 2");
# Create an other container with long text to show how LV_GRIDNAV_CTRL_SCROLL_FIRST works
cont_sub1 = lv.obj(cont_main)
cont_sub1.set_size(lv.pct(100), 100)
label = lv.label(cont_sub1)
cont_sub1.set_style_bg_color(lv.palette_lighten(lv.PALETTE.RED, 5), lv.STATE.FOCUSED)
label.set_width(lv.pct(100));
label.set_text(
"""I'm a very long text which makes my container scrollable.
As LV_GRIDNAV_FLAG_SCROLL_FIRST is enabled arrows will scroll me first
and a new objects will be focused only when an edge is reached with the scrolling.\n
This is only some placeholder text to be sure the parent will be scrollable. \n
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
""")
# Create a third container that can be focused with ENTER and contains an other grid nav
cont_sub2 = lv.obj(cont_main)
lv.gridnav_add(cont_sub2, lv.GRIDNAV_CTRL.ROLLOVER)
#Only the container needs to be in a group
lv.group_get_default().add_obj(cont_sub2)
cont_sub2.add_event_cb(cont_sub_event_cb, lv.EVENT.KEY, None)
# Use flex here, but works with grid or manually placed objects as well
cont_sub2.set_flex_flow(lv.FLEX_FLOW.ROW_WRAP)
cont_sub2.set_style_bg_color(lv.palette_lighten(lv.PALETTE.RED, 5), lv.STATE.FOCUSED)
cont_sub2.set_size(lv.pct(100), lv.SIZE_CONTENT)
label = lv.label(cont_sub2)
label.set_text("Use ENTER/ESC to focus/defocus this container")
label.set_width(lv.pct(100))
btn = lv.btn(cont_sub2)
lv.group_remove_obj(btn)
label = lv.label(btn)
label.set_text("Button 3")
btn = lv.btn(cont_sub2)
lv.group_remove_obj(btn)
label = lv.label(btn)
label.set_text("Button 4")

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_LOG_USER("Clicked: %s", lv_list_get_btn_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_scr_act());
lv_gridnav_add(list, LV_GRIDNAV_CTRL_ROLLOVER);
lv_obj_align(list, LV_ALIGN_LEFT_MID, 0, 10);
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_btn(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_btn_create(lv_scr_act());
lv_obj_align(btn, LV_ALIGN_RIGHT_MID, 0, -10);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, "Button");
}
#endif

View File

@@ -0,0 +1,36 @@
def event_handler(e):
obj = e.get_target()
list = obj.get_parent()
print("Clicked: " + list.get_btn_text(obj))
#
# Simple navigation on a list widget
#
# It's assumed that the default group is set and
# there is a keyboard indev
list = lv.list(lv.scr_act())
lv.gridnav_add(list, lv.GRIDNAV_CTRL.ROLLOVER)
list.align(lv.ALIGN.LEFT_MID, 0, 10)
lv.group_get_default().add_obj(list)
for i in range(20):
# Add some separators too, they are not focusable by gridnav
if i % 5 == 0:
txt = "Section {:d}".format(i // 5 + 1)
# lv_snprintf(buf, sizeof(buf), "Section %d", i / 5 + 1);
list.add_text(txt)
txt = "File {:d}".format(i + 1)
#lv_snprintf(buf, sizeof(buf), "File %d", i + 1);
item = list.add_btn(lv.SYMBOL.FILE, txt)
item.add_event_cb(event_handler, lv.EVENT.CLICKED, None)
lv.group_remove_obj(item) # The default group adds it automatically
btn = lv.btn(lv.scr_act())
btn.align(lv.ALIGN.RIGHT_MID, 0, -10)
label = lv.label(btn)
label.set_text("Button")

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_get_act()) != LV_INDEV_TYPE_KEYPAD) {
lv_keyboard_set_textarea(kb, ta);
lv_obj_clear_flag(kb, LV_OBJ_FLAG_HIDDEN);
}
}
else if(code == LV_EVENT_CANCEL) {
lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);
lv_obj_clear_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_scr_act());
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_scr_act());
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_scr_act());
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_scr_act());
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,50 @@
import fs_driver
def ta_event_cb(e,kb):
code = e.get_code()
ta = e.get_target()
if code == lv.EVENT.FOCUSED:
if lv.indev_get_act() != None and lv.indev_get_act().get_type() != lv.INDEV_TYPE.KEYPAD :
kb.set_textarea(ta)
kb.clear_flag(lv.obj.FLAG.HIDDEN)
elif code == lv.EVENT.CANCEL:
kb.add_flag(lv.obj.FLAG.HIDDEN)
ta.clear_state(ta, LV_STATE_FOCUSED);
lv.indev_reset(None, ta) # To forget the last clicked object to make it focusable again
fs_drv = lv.fs_drv_t()
fs_driver.fs_register(fs_drv, 'S')
font_simsun_16_cjk = lv.font_load("S:../../assets/font/lv_font_simsun_16_cjk.fnt")
if font_simsun_16_cjk == None:
print("Error when loading chinese font")
pinyin_ime = lv.ime_pinyin(lv.scr_act())
pinyin_ime.set_style_text_font(font_simsun_16_cjk, 0)
# pinyin_ime.pinyin_set_dict(your_dict) # Use a custom dictionary. If it is not set, the built-in dictionary will be used.
# ta1
ta1 = lv.textarea(lv.scr_act())
ta1.set_one_line(True)
ta1.set_style_text_font(font_simsun_16_cjk, 0)
ta1.align(lv.ALIGN.TOP_LEFT, 0, 0)
# Create a keyboard and add it to ime_pinyin
kb = lv.keyboard(lv.scr_act())
pinyin_ime.pinyin_set_keyboard(kb)
kb.set_textarea(ta1)
ta1.add_event_cb(lambda evt: ta_event_cb(evt,kb), lv.EVENT.ALL, None)
# Get the cand_panel, and adjust its size and position
cand_panel = pinyin_ime.pinyin_get_cand_panel()
cand_panel.set_size(lv.pct(100), lv.pct(10))
cand_panel.align_to(kb, lv.ALIGN.OUT_TOP_MID, 0, 0)
# Try using ime_pinyin to output the Chinese below in the ta1 above
cz_label = lv.label(lv.scr_act())
cz_label.set_text("嵌入式系统Embedded System\n是一种嵌入机械或电气系统内部、具有专一功能和实时计算性能的计算机系统。")
cz_label.set_style_text_font(font_simsun_16_cjk, 0)
cz_label.set_width(310)
cz_label.align_to(ta1, lv.ALIGN.OUT_BOTTOM_LEFT, 0, 0)

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_get_act()) != LV_INDEV_TYPE_KEYPAD) {
lv_keyboard_set_textarea(kb, ta);
lv_obj_clear_flag(kb, LV_OBJ_FLAG_HIDDEN);
}
}
else if(code == LV_EVENT_READY) {
lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);
lv_obj_clear_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_scr_act());
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_scr_act());
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_scr_act());
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_scr_act());
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,52 @@
import fs_driver
def ta_event_cb(e,kb):
code = e.get_code()
ta = e.get_target()
if code == lv.EVENT.FOCUSED:
if lv.indev_get_act() != None and lv.indev_get_act().get_type() != lv.INDEV_TYPE.KEYPAD :
kb.set_textarea(ta)
kb.clear_flag(lv.obj.FLAG.HIDDEN)
elif code == lv.EVENT.READY:
kb.add_flag(lv.obj.FLAG.HIDDEN)
ta.clear_state(ta, LV_STATE_FOCUSED);
lv.indev_reset(None, ta) # To forget the last clicked object to make it focusable again
fs_drv = lv.fs_drv_t()
fs_driver.fs_register(fs_drv, 'S')
font_simsun_16_cjk = lv.font_load("S:../../assets/font/lv_font_simsun_16_cjk.fnt")
if font_simsun_16_cjk == None:
print("Error when loading chinese font")
pinyin_ime = lv.ime_pinyin(lv.scr_act())
pinyin_ime.set_style_text_font(font_simsun_16_cjk, 0)
# pinyin_ime.pinyin_set_dict(your_dict) # Use a custom dictionary. If it is not set, the built-in dictionary will be used.
# ta1
ta1 = lv.textarea(lv.scr_act())
ta1.set_one_line(True)
ta1.set_style_text_font(font_simsun_16_cjk, 0)
ta1.align(lv.ALIGN.TOP_LEFT, 0, 0)
# Create a keyboard and add it to ime_pinyin
kb = lv.keyboard(lv.scr_act())
kb.set_textarea(ta1)
pinyin_ime.pinyin_set_keyboard(kb)
pinyin_ime.pinyin_set_mode(lv.ime_pinyin.PINYIN_MODE.K9) # Set to 9-key input mode. Default: 26-key input(k26) mode.
ta1.add_event_cb(lambda evt: ta_event_cb(evt,kb), lv.EVENT.ALL, None)
# Get the cand_panel, and adjust its size and position
cand_panel = pinyin_ime.pinyin_get_cand_panel()
cand_panel.set_size(lv.pct(100), lv.pct(10))
cand_panel.align_to(kb, lv.ALIGN.OUT_TOP_MID, 0, 0)
# Try using ime_pinyin to output the Chinese below in the ta1 above
cz_label = lv.label(lv.scr_act())
cz_label.set_text("嵌入式系统Embedded System\n是一种嵌入机械或电气系统内部、具有专一功能和实时计算性能的计算机系统。")
cz_label.set_style_text_font(font_simsun_16_cjk, 0)
cz_label.set_width(310)
cz_label.align_to(ta1, lv.ALIGN.OUT_BOTTOM_LEFT, 0, 0)

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,63 @@
#include "../../lv_examples.h"
#include <stdio.h>
#if LV_BUILD_EXAMPLES
#if LV_USE_IMGFONT
LV_IMG_DECLARE(emoji_F617)
static bool get_imgfont_path(const lv_font_t * font, void * img_src,
uint16_t len, uint32_t unicode, uint32_t unicode_next,
lv_coord_t * offset_y, void * user_data)
{
LV_UNUSED(font);
LV_UNUSED(unicode_next);
LV_UNUSED(offset_y);
LV_UNUSED(user_data);
LV_ASSERT_NULL(img_src);
if(unicode < 0xF000) return false;
if(unicode == 0xF617) {
memcpy(img_src, &emoji_F617, sizeof(lv_img_dsc_t));
}
else {
char * path = (char *)img_src;
#if LV_USE_FFMPEG
lv_snprintf(path, len, "%s/%04X.png", "lvgl/examples/assets/emoji", unicode);
#elif LV_USE_PNG
lv_snprintf(path, len, "%s/%04X.png", "A:lvgl/examples/assets/emoji", unicode);
#endif
}
return true;
}
/**
* 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_scr_act());
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_scr_act());
lv_label_set_text(label, "imgfont is not installed");
lv_obj_center(label);
}
#endif
#endif

View File

@@ -0,0 +1,41 @@
import fs_driver
import sys
# set LV_USE_FFMPEG to True if it is enabled in lv_conf.h
LV_USE_FFMPEG = True
LV_FONT_DEFAULT = lv.font_montserrat_14
fs_drv = lv.fs_drv_t()
fs_driver.fs_register(fs_drv, 'A')
# get the directory in which the script is running
try:
script_path = __file__[:__file__.rfind('/')] if __file__.find('/') >= 0 else '.'
except NameError:
script_path = ''
def get_imgfont_path(font, img_src, length, unicode, unicode_next, offset_y, user_data) :
if unicode < 0xf600:
return
if LV_USE_FFMPEG:
path = bytes(script_path + "/../../assets/emoji/{:04X}.png".format(unicode) + "\0","ascii")
else:
path = bytes("A:"+ script_path + "/../../assets/emoji/{:04X}.png".format(unicode) + "\0","ascii")
# print("image path: ",path)
img_src.__dereference__(length)[0:len(path)] = path
return True
#
# draw img in label or span obj
#
imgfont = lv.imgfont_create(80, get_imgfont_path, None)
if imgfont == None:
print("imgfont init error")
sys.exit(1)
imgfont.fallback = LV_FONT_DEFAULT
label1 = lv.label(lv.scr_act())
label1.set_text("12\uF600\uF617AB")
label1.set_style_text_font(imgfont, lv.PART.MAIN)
label1.center()

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 "msg/lv_example_msg.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];
lv_coord_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,20 @@
Slider to label messaging
"""""""""""""""""""""""""
.. lv_example:: others/msg/lv_example_msg_1
:language: c
Handling login and its states
"""""""""""""""""""""""""""""
.. lv_example:: others/msg/lv_example_msg_2
:language: c
Setting the same value from many sources
""""""""""""""""""""""""""""""""""""""""
.. lv_example:: others/msg/lv_example_msg_3
:language: c

View File

@@ -0,0 +1,40 @@
/**
* @file lv_example_msg.h
*
*/
#ifndef LV_EXAMPLE_MSG_H
#define LV_EXAMPLE_MSG_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_example_msg_1(void);
void lv_example_msg_2(void);
void lv_example_msg_3(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_EXAMPLE_MSG_H*/

View File

@@ -0,0 +1,49 @@
#include "../../lv_examples.h"
#if LV_USE_MSG && LV_USE_SLIDER && LV_USE_LABEL && LV_BUILD_EXAMPLES
/*Define a message ID*/
#define MSG_NEW_TEMPERATURE 1
static void slider_event_cb(lv_event_t * e);
static void label_event_cb(lv_event_t * e);
/**
* A slider sends a message on value change and a label display's that value
*/
void lv_example_msg_1(void)
{
/*Create a slider in the center of the display*/
lv_obj_t * slider = lv_slider_create(lv_scr_act());
lv_obj_center(slider);
lv_obj_add_event_cb(slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
/*Create a label below the slider*/
lv_obj_t * label = lv_label_create(lv_scr_act());
lv_obj_add_event_cb(label, label_event_cb, LV_EVENT_MSG_RECEIVED, NULL);
lv_label_set_text(label, "0%");
lv_obj_align(label, LV_ALIGN_CENTER, 0, 30);
/*Subscribe the label to a message. Also use the user_data to set a format string here.*/
lv_msg_subscribe_obj(MSG_NEW_TEMPERATURE, label, "%d °C");
}
static void slider_event_cb(lv_event_t * e)
{
/*Notify all subscribers (only the label now) that the slider value has been changed*/
lv_obj_t * slider = lv_event_get_target(e);
int32_t v = lv_slider_get_value(slider);
lv_msg_send(MSG_NEW_TEMPERATURE, &v);
}
static void label_event_cb(lv_event_t * e)
{
lv_obj_t * label = lv_event_get_target(e);
lv_msg_t * m = lv_event_get_msg(e);
const char * fmt = lv_msg_get_user_data(m);
const int32_t * v = lv_msg_get_payload(m);
lv_label_set_text_fmt(label, fmt, *v);
}
#endif

View File

@@ -0,0 +1,39 @@
# Define a message ID
MSG_NEW_TEMPERATURE = const(1)
# Define the object that will be sent as msg payload
class Temperature:
def __init__(self, value):
self.value = value
def __repr__(self):
return f"{self.value} °C"
def slider_event_cb(e):
slider = e.get_target()
v = slider.get_value()
# Notify all subscribers (only the label now) that the slider value has been changed
lv.msg_send(MSG_NEW_TEMPERATURE, Temperature(v))
def label_event_cb(e):
label = e.get_target()
msg = e.get_msg()
# Respond only to MSG_NEW_TEMPERATURE message
if msg.get_id() == MSG_NEW_TEMPERATURE:
payload = msg.get_payload()
temprature = payload.__cast__()
label.set_text(str(temprature))
# Create a slider in the center of the display
slider = lv.slider(lv.scr_act())
slider.center()
slider.add_event_cb(slider_event_cb, lv.EVENT.VALUE_CHANGED, None)
# Create a label below the slider
label = lv.label(lv.scr_act())
label.add_event_cb(label_event_cb, lv.EVENT.MSG_RECEIVED, None)
label.set_text("0%")
label.align(lv.ALIGN.CENTER, 0, 30)
# Subscribe the label to a message
lv.msg_subscribe_obj(MSG_NEW_TEMPERATURE, label, None)

View File

@@ -0,0 +1,170 @@
#include "../../lv_examples.h"
#if LV_USE_MSG && LV_USE_SLIDER && LV_USE_LABEL && LV_BUILD_EXAMPLES
/*Define a message ID*/
#define MSG_LOGIN_ATTEMPT 1
#define MSG_LOG_OUT 2
#define MSG_LOGIN_ERROR 3
#define MSG_LOGIN_OK 4
static void auth_manager(lv_msg_t * m);
static void textarea_event_cb(lv_event_t * e);
static void log_out_event_cb(lv_event_t * e);
static void start_engine_msg_event_cb(lv_event_t * e);
static void info_label_msg_event_cb(lv_event_t * e);
/**
* Simple PIN login screen.
* No global variables are used, all state changes are communicated via messages.
*/
void lv_example_msg_2(void)
{
lv_msg_subscribe(MSG_LOGIN_ATTEMPT, auth_manager, "hello");
/*Create a slider in the center of the display*/
lv_obj_t * ta = lv_textarea_create(lv_scr_act());
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_ALL, NULL);
lv_msg_subscribe_obj(MSG_LOGIN_ERROR, ta, NULL);
lv_msg_subscribe_obj(MSG_LOGIN_OK, ta, NULL);
lv_msg_subscribe_obj(MSG_LOG_OUT, ta, NULL);
lv_obj_t * kb = lv_keyboard_create(lv_scr_act());
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_btn_create(lv_scr_act());
lv_obj_set_pos(btn, 240, 10);
lv_obj_add_event_cb(btn, log_out_event_cb, LV_EVENT_ALL, NULL);
lv_msg_subscribe_obj(MSG_LOGIN_OK, btn, NULL);
lv_msg_subscribe_obj(MSG_LOG_OUT, btn, NULL);
label = lv_label_create(btn);
lv_label_set_text(label, "LOG OUT");
/*Create a label to show info*/
label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "");
lv_obj_add_event_cb(label, info_label_msg_event_cb, LV_EVENT_MSG_RECEIVED, NULL);
lv_obj_set_pos(label, 10, 60);
lv_msg_subscribe_obj(MSG_LOGIN_ERROR, label, NULL);
lv_msg_subscribe_obj(MSG_LOGIN_OK, label, NULL);
lv_msg_subscribe_obj(MSG_LOG_OUT, label, NULL);
/*Create button which will be active only when logged in*/
btn = lv_btn_create(lv_scr_act());
lv_obj_set_pos(btn, 10, 80);
lv_obj_add_event_cb(btn, start_engine_msg_event_cb, LV_EVENT_MSG_RECEIVED, NULL);
lv_obj_add_flag(btn, LV_OBJ_FLAG_CHECKABLE);
lv_msg_subscribe_obj(MSG_LOGIN_OK, btn, NULL);
lv_msg_subscribe_obj(MSG_LOG_OUT, btn, NULL);
label = lv_label_create(btn);
lv_label_set_text(label, "START ENGINE");
lv_msg_send(MSG_LOG_OUT, NULL);
}
static void auth_manager(lv_msg_t * m)
{
const char * pin_act = lv_msg_get_payload(m);
const char * pin_expexted = lv_msg_get_user_data(m);
if(strcmp(pin_act, pin_expexted) == 0) {
lv_msg_send(MSG_LOGIN_OK, NULL);
}
else {
lv_msg_send(MSG_LOGIN_ERROR, "Incorrect PIN");
}
}
static void textarea_event_cb(lv_event_t * e)
{
lv_obj_t * ta = lv_event_get_target(e);
lv_event_code_t code = lv_event_get_code(e);
if(code == LV_EVENT_READY) {
lv_msg_send(MSG_LOGIN_ATTEMPT, lv_textarea_get_text(ta));
}
else if(code == LV_EVENT_MSG_RECEIVED) {
lv_msg_t * m = lv_event_get_msg(e);
switch(lv_msg_get_id(m)) {
case MSG_LOGIN_ERROR:
/*If there was an error, clean the text area*/
if(strlen(lv_msg_get_payload(m))) lv_textarea_set_text(ta, "");
break;
case MSG_LOGIN_OK:
lv_obj_add_state(ta, LV_STATE_DISABLED);
lv_obj_clear_state(ta, LV_STATE_FOCUSED | LV_STATE_FOCUS_KEY);
break;
case MSG_LOG_OUT:
lv_textarea_set_text(ta, "");
lv_obj_clear_state(ta, LV_STATE_DISABLED);
break;
}
}
}
static void log_out_event_cb(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e);
if(code == LV_EVENT_CLICKED) {
lv_msg_send(MSG_LOG_OUT, NULL);
}
else if(code == LV_EVENT_MSG_RECEIVED) {
lv_msg_t * m = lv_event_get_msg(e);
lv_obj_t * btn = lv_event_get_target(e);
switch(lv_msg_get_id(m)) {
case MSG_LOGIN_OK:
lv_obj_clear_state(btn, LV_STATE_DISABLED);
break;
case MSG_LOG_OUT:
lv_obj_add_state(btn, LV_STATE_DISABLED);
break;
}
}
}
static void start_engine_msg_event_cb(lv_event_t * e)
{
lv_msg_t * m = lv_event_get_msg(e);
lv_obj_t * btn = lv_event_get_target(e);
switch(lv_msg_get_id(m)) {
case MSG_LOGIN_OK:
lv_obj_clear_state(btn, LV_STATE_DISABLED);
break;
case MSG_LOG_OUT:
lv_obj_add_state(btn, LV_STATE_DISABLED);
break;
}
}
static void info_label_msg_event_cb(lv_event_t * e)
{
lv_obj_t * label = lv_event_get_target(e);
lv_msg_t * m = lv_event_get_msg(e);
switch(lv_msg_get_id(m)) {
case MSG_LOGIN_ERROR:
lv_label_set_text(label, lv_msg_get_payload(m));
lv_obj_set_style_text_color(label, lv_palette_main(LV_PALETTE_RED), 0);
break;
case MSG_LOGIN_OK:
lv_label_set_text(label, "Login successful");
lv_obj_set_style_text_color(label, lv_palette_main(LV_PALETTE_GREEN), 0);
break;
case MSG_LOG_OUT:
lv_label_set_text(label, "Logged out");
lv_obj_set_style_text_color(label, lv_palette_main(LV_PALETTE_GREY), 0);
break;
default:
break;
}
}
#endif

View File

@@ -0,0 +1,142 @@
from micropython import const
# Define a message ID
MSG_LOGIN_ATTEMPT = const(1)
MSG_LOG_OUT = const(2)
MSG_LOGIN_ERROR = const(3)
MSG_LOGIN_OK = const(4)
# Define the object that will be sent as msg payload
class Message:
def __init__(self, value):
self.value = value
def message(self):
return self.value
def auth_manager(m,passwd):
payload = m.get_payload()
pin_act = payload.__cast__().message()
# print("pin act: ",pin_act,end="")
# print(", pin axpected: ",passwd)
pin_expected = passwd
if pin_act == pin_expected:
lv.msg_send(MSG_LOGIN_OK, None)
else:
lv.msg_send(MSG_LOGIN_ERROR, Message("Incorrect PIN"))
def textarea_event_cb(e):
ta = e.get_target()
code = e.get_code()
if code == lv.EVENT.READY:
passwd = Message(ta.get_text())
lv.msg_send(MSG_LOGIN_ATTEMPT, passwd)
elif code == lv.EVENT.MSG_RECEIVED:
m = e.get_msg()
id = m.get_id()
if id == MSG_LOGIN_ERROR:
# If there was an error, clean the text area
msg = m.get_payload().__cast__()
if len(msg.message()):
ta.set_text("")
elif id == MSG_LOGIN_OK:
ta.add_state(lv.STATE.DISABLED)
ta.clear_state(lv.STATE.FOCUSED | lv.STATE.FOCUS_KEY)
elif id == MSG_LOG_OUT:
ta.set_text("");
ta.clear_state(lv.STATE.DISABLED)
def log_out_event_cb(e):
code = e.get_code()
if code == lv.EVENT.CLICKED:
lv.msg_send(MSG_LOG_OUT, None)
elif code == lv.EVENT.MSG_RECEIVED:
m = e.get_msg()
btn = e.get_target()
id = m.get_id()
if id == MSG_LOGIN_OK:
btn.clear_state(lv.STATE.DISABLED)
elif id == MSG_LOG_OUT:
btn.add_state(lv.STATE.DISABLED)
def start_engine_msg_event_cb(e):
m = e.get_msg()
btn = e.get_target()
id = m.get_id()
if id == MSG_LOGIN_OK:
btn.clear_state(lv.STATE.DISABLED)
elif id == MSG_LOG_OUT:
btn.add_state(lv.STATE.DISABLED)
def info_label_msg_event_cb(e):
label = e.get_target()
m = e.get_msg()
id = m.get_id()
if id == MSG_LOGIN_ERROR:
payload = m.get_payload()
label.set_text(payload.__cast__().message())
label.set_style_text_color(lv.palette_main(lv.PALETTE.RED), 0)
elif id == MSG_LOGIN_OK:
label.set_text("Login successful")
label.set_style_text_color(lv.palette_main(lv.PALETTE.GREEN), 0)
elif id == MSG_LOG_OUT:
label.set_text("Logged out")
label.set_style_text_color(lv.palette_main(lv.PALETTE.GREY), 0)
def register_auth(msg_id,auth_msg):
lv.msg_subscribe(MSG_LOGIN_ATTEMPT, lambda m: auth_msg(m,"hello"), None)
#
# Simple PIN login screen.
# No global variables are used, all state changes are communicated via messages.
register_auth(MSG_LOGIN_ATTEMPT,auth_manager)
# lv.msg_subscribe_obj(MSG_LOGIN_ATTEMPT, auth_manager, "Hello")
# Create a slider in the center of the display
ta = lv.textarea(lv.scr_act())
ta.set_pos(10, 10)
ta.set_width(200)
ta.set_one_line(True)
ta.set_password_mode(True)
ta.set_placeholder_text("The password is: hello")
ta.add_event_cb(textarea_event_cb, lv.EVENT.ALL, None)
lv.msg_subscribe_obj(MSG_LOGIN_ERROR, ta, None)
lv.msg_subscribe_obj(MSG_LOGIN_OK, ta, None)
lv.msg_subscribe_obj(MSG_LOG_OUT, ta, None)
kb = lv.keyboard(lv.scr_act())
kb.set_textarea(ta)
# Create a log out button which will be active only when logged in
btn = lv.btn(lv.scr_act())
btn.set_pos(240, 10)
btn.add_event_cb(log_out_event_cb, lv.EVENT.ALL, None)
lv.msg_subscribe_obj(MSG_LOGIN_OK, btn, None)
lv.msg_subscribe_obj(MSG_LOG_OUT, btn, None)
label = lv.label(btn);
label.set_text("LOG OUT")
# Create a label to show info
label = lv.label(lv.scr_act());
label.set_text("")
label.add_event_cb(info_label_msg_event_cb, lv.EVENT.MSG_RECEIVED, None)
label.set_pos(10, 60)
lv.msg_subscribe_obj(MSG_LOGIN_ERROR, label, None)
lv.msg_subscribe_obj(MSG_LOGIN_OK, label, None)
lv.msg_subscribe_obj(MSG_LOG_OUT, label, None)
#Create button which will be active only when logged in
btn = lv.btn(lv.scr_act())
btn.set_pos(10, 80)
btn.add_event_cb(start_engine_msg_event_cb, lv.EVENT.MSG_RECEIVED, None)
btn.add_flag(lv.obj.FLAG.CHECKABLE)
lv.msg_subscribe_obj(MSG_LOGIN_OK, btn, None)
lv.msg_subscribe_obj(MSG_LOG_OUT, btn, None)
label = lv.label(btn)
label.set_text("START ENGINE")
lv.msg_send(MSG_LOG_OUT, None)

View File

@@ -0,0 +1,112 @@
#include "../../lv_examples.h"
#if LV_USE_MSG && LV_USE_SLIDER && LV_USE_LABEL && LV_BUILD_EXAMPLES
static int32_t limit_value(int32_t v);
static void btn_event_cb(lv_event_t * e);
static void label_event_cb(lv_event_t * e);
static void slider_event_cb(lv_event_t * e);
static int32_t power_value;
/**
* Show how an increment button, a decrement button, as slider can set a value
* and a label display it.
* The current value (i.e. the system's state) is stored only in one static variable in a function
* and no global variables are required.
*/
void lv_example_msg_3(void)
{
lv_obj_t * panel = lv_obj_create(lv_scr_act());
lv_obj_set_size(panel, 250, LV_SIZE_CONTENT);
lv_obj_center(panel);
lv_obj_set_flex_flow(panel, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(panel, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START);
lv_obj_t * btn;
lv_obj_t * label;
/*Up button*/
btn = lv_btn_create(panel);
lv_obj_set_flex_grow(btn, 1);
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_ALL, NULL);
label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_LEFT);
lv_obj_center(label);
/*Current value*/
label = lv_label_create(panel);
lv_obj_set_flex_grow(label, 2);
lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0);
lv_label_set_text(label, "?");
lv_msg_subscribe_obj((lv_msg_id_t)&power_value, label, NULL);
lv_obj_add_event_cb(label, label_event_cb, LV_EVENT_MSG_RECEIVED, NULL);
/*Down button*/
btn = lv_btn_create(panel);
lv_obj_set_flex_grow(btn, 1);
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_ALL, NULL);
label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_RIGHT);
lv_obj_center(label);
/*Slider*/
lv_obj_t * slider = lv_slider_create(panel);
lv_obj_set_flex_grow(slider, 1);
lv_obj_add_flag(slider, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK);
lv_msg_subscribe_obj((lv_msg_id_t)&power_value, slider, NULL);
lv_obj_add_event_cb(slider, slider_event_cb, LV_EVENT_ALL, NULL);
power_value = 30;
lv_msg_update_value(&power_value);
}
static int32_t limit_value(int32_t v)
{
return LV_CLAMP(30, v, 80);
}
static void btn_event_cb(lv_event_t * e)
{
lv_obj_t * btn = lv_event_get_target(e);
lv_event_code_t code = lv_event_get_code(e);
if(code == LV_EVENT_CLICKED || code == LV_EVENT_LONG_PRESSED_REPEAT) {
if(lv_obj_get_index(btn) == 0) { /*First object is the dec. button*/
power_value = limit_value(power_value - 1);
lv_msg_update_value(&power_value);
}
else {
power_value = limit_value(power_value + 1);
lv_msg_update_value(&power_value);
}
}
}
static void label_event_cb(lv_event_t * e)
{
lv_obj_t * label = lv_event_get_target(e);
lv_event_code_t code = lv_event_get_code(e);
if(code == LV_EVENT_MSG_RECEIVED) {
lv_msg_t * m = lv_event_get_msg(e);
const int32_t * v = lv_msg_get_payload(m);
lv_label_set_text_fmt(label, "%"LV_PRId32" %%", *v);
}
}
static void slider_event_cb(lv_event_t * e)
{
lv_obj_t * slider = lv_event_get_target(e);
lv_event_code_t code = lv_event_get_code(e);
if(code == LV_EVENT_VALUE_CHANGED) {
power_value = limit_value(lv_slider_get_value(slider));
lv_msg_update_value(&power_value);
}
else if(code == LV_EVENT_MSG_RECEIVED) {
lv_msg_t * m = lv_event_get_msg(e);
const int32_t * v = lv_msg_get_payload(m);
lv_slider_set_value(slider, *v, LV_ANIM_OFF);
}
}
#endif

View File

@@ -0,0 +1,122 @@
# Define a message ID
MSG_INC = 1
MSG_DEC = 2
MSG_SET = 3
MSG_UPDATE = 4
MSG_UPDATE_REQUEST = 5
# Define the object that will be sent as msg payload
class NewValue:
def __init__(self, value):
self.value = value
def __repr__(self):
return f"{self.value} %"
class LV_Example_Msg_2:
def __init__(self):
self.value = 10
lv.msg_subscribe(MSG_INC, self.value_handler, None)
lv.msg_subscribe(MSG_DEC, self.value_handler, None)
lv.msg_subscribe(MSG_SET, self.value_handler, None)
lv.msg_subscribe(MSG_UPDATE, self.value_handler, None)
lv.msg_subscribe(MSG_UPDATE_REQUEST, self.value_handler, None)
panel = lv.obj(lv.scr_act())
panel.set_size(250, lv.SIZE_CONTENT)
panel.center()
panel.set_flex_flow(lv.FLEX_FLOW.ROW)
panel.set_flex_align(lv.FLEX_ALIGN.SPACE_BETWEEN, lv.FLEX_ALIGN.CENTER, lv.FLEX_ALIGN.START)
# Up button
btn = lv.btn(panel)
btn.set_flex_grow(1)
btn.add_event_cb(self.btn_event_cb, lv.EVENT.ALL, None)
label = lv.label(btn)
label.set_text(lv.SYMBOL.LEFT)
label.center()
# Current value
label = lv.label(panel)
label.set_flex_grow(2)
label.set_style_text_align(lv.TEXT_ALIGN.CENTER, 0)
label.set_text("?")
lv.msg_subscribe_obj(MSG_UPDATE, label, None)
label.add_event_cb(self.label_event_cb, lv.EVENT.MSG_RECEIVED, None)
# Down button
btn = lv.btn(panel)
btn.set_flex_grow(1)
btn.add_event_cb(self.btn_event_cb, lv.EVENT.ALL, None)
label = lv.label(btn)
label.set_text(lv.SYMBOL.RIGHT)
label.center()
# Slider
slider = lv.slider(panel)
slider.set_flex_grow(1)
slider.add_flag(lv.OBJ_FLAG_FLEX_IN_NEW_TRACK)
slider.add_event_cb(self.slider_event_cb, lv.EVENT.ALL, None)
lv.msg_subscribe_obj(MSG_UPDATE, slider, None)
# As there are new UI elements that don't know the system's state
# send an UPDATE REQUEST message which will trigger an UPDATE message with the current value
lv.msg_send(MSG_UPDATE_REQUEST, None)
def value_handler(self,m):
old_value = self.value
id = m.get_id()
if id == MSG_INC:
if self.value < 100:
self.value +=1
elif id == MSG_DEC:
if self.value > 0:
self.value -=1
elif id == MSG_SET:
payload = m.get_payload()
new_value=payload.__cast__()
self.value = new_value.value
# print("value_handler: new value: {:d}".format(new_value.value))
elif id == MSG_UPDATE_REQUEST:
lv.msg_send(MSG_UPDATE, NewValue(self.value))
if self.value != old_value:
lv.msg_send(MSG_UPDATE, NewValue(self.value));
def btn_event_cb(self,e):
btn = e.get_target()
code = e.get_code()
if code == lv.EVENT.CLICKED or code == lv.EVENT.LONG_PRESSED_REPEAT:
if btn.get_index() == 0: # rst object is the dec. button
lv.msg_send(MSG_DEC, None)
else :
lv.msg_send(MSG_INC, None)
def label_event_cb(self,e):
label = e.get_target()
code = e.get_code()
if code == lv.EVENT.MSG_RECEIVED:
m = e.get_msg()
if m.get_id() == MSG_UPDATE:
payload = m.get_payload()
value=payload.__cast__()
# print("label_event_cb: " + str(value))
label.set_text(str(value))
def slider_event_cb(self,e):
slider = e.get_target()
code = e.get_code()
if code == lv.EVENT.VALUE_CHANGED:
v = slider.get_value()
# print("slider_event_cb: {:d}".format(v))
lv.msg_send(MSG_SET, NewValue(v))
elif code == lv.EVENT.MSG_RECEIVED:
m = e.get_msg()
if m.get_id() == MSG_UPDATE:
v = m.get_payload()
value = v.__cast__()
slider.set_value(value.value, lv.ANIM.OFF)
lv_example_msg_2 = LV_Example_Msg_2()

View File

@@ -0,0 +1,8 @@
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_img_dsc_t * snapshot = (void *)lv_img_get_src(snapshot_obj);
if(snapshot) {
lv_snapshot_free(snapshot);
}
/*Update the snapshot, we know parent of object is the container.*/
snapshot = lv_snapshot_take(img->parent, LV_IMG_CF_TRUE_COLOR_ALPHA);
if(snapshot == NULL)
return;
lv_img_set_src(snapshot_obj, snapshot);
}
}
void lv_example_snapshot_1(void)
{
LV_IMG_DECLARE(img_star);
lv_obj_t * root = lv_scr_act();
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_img_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_img_set_zoom(snapshot_obj, 128);
lv_img_set_angle(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_img_create(container);
lv_img_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_zoom(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

View File

@@ -0,0 +1,65 @@
import gc
import lvgl as lv
# Measure memory usage
gc.enable()
gc.collect()
mem_free = gc.mem_free()
label = lv.label(lv.scr_act())
label.align(lv.ALIGN.BOTTOM_MID, 0, -10)
label.set_text(" memory free:" + str(mem_free/1024) + " kB")
# Create an image from the png file
try:
with open('../../assets/img_star.png','rb') as f:
png_data = f.read()
except:
print("Could not find star.png")
sys.exit()
img_star = lv.img_dsc_t({
'data_size': len(png_data),
'data': png_data
})
def event_cb(e, snapshot_obj):
img = e.get_target()
if snapshot_obj:
# no need to free the old source for snapshot_obj, gc will free it for us.
# take a new snapshot, overwrite the old one
dsc = lv.snapshot_take(img.get_parent(), lv.img.CF.TRUE_COLOR_ALPHA)
snapshot_obj.set_src(dsc)
gc.collect()
mem_used = mem_free - gc.mem_free()
label.set_text("memory used:" + str(mem_used/1024) + " kB")
root = lv.scr_act()
root.set_style_bg_color(lv.palette_main(lv.PALETTE.LIGHT_BLUE), 0)
# Create an image object to show snapshot
snapshot_obj = lv.img(root)
snapshot_obj.set_style_bg_color(lv.palette_main(lv.PALETTE.PURPLE), 0)
snapshot_obj.set_style_bg_opa(lv.OPA.COVER, 0)
snapshot_obj.set_zoom(128)
# Create the container and its children
container = lv.obj(root)
container.align(lv.ALIGN.CENTER, 0, 0)
container.set_size(180, 180)
container.set_flex_flow(lv.FLEX_FLOW.ROW_WRAP)
container.set_flex_align(lv.FLEX_ALIGN.SPACE_EVENLY, lv.FLEX_ALIGN.CENTER, lv.FLEX_ALIGN.CENTER)
container.set_style_radius(50, 0)
for i in range(4):
img = lv.img(container)
img.set_src(img_star)
img.set_style_bg_color(lv.palette_main(lv.PALETTE.GREY), 0)
img.set_style_bg_opa(lv.OPA.COVER, 0)
img.set_style_transform_zoom(400, lv.STATE.PRESSED)
img.add_flag(img.FLAG.CLICKABLE)
img.add_event_cb(lambda e: event_cb(e, snapshot_obj), lv.EVENT.PRESSED, None)
img.add_event_cb(lambda e: event_cb(e, snapshot_obj), lv.EVENT.RELEASED, None)