diff --git a/lv_app/lv_app.c b/lv_app/lv_app.c index d18bc2e17..e9bf07643 100644 --- a/lv_app/lv_app.c +++ b/lv_app/lv_app.c @@ -133,6 +133,11 @@ void lv_app_init(void) dsc = ll_ins_head(&app_dsc_ll); *dsc = lv_app_files_init(); #endif + +#if USE_LV_APP_WIFI != 0 + dsc = ll_ins_head(&app_dsc_ll); + *dsc = lv_app_wifi_init(); +#endif } /** diff --git a/lv_app/lv_app.h b/lv_app/lv_app.h index 81d0dd0e0..6eb8186a6 100644 --- a/lv_app/lv_app.h +++ b/lv_app/lv_app.h @@ -240,6 +240,7 @@ lv_app_style_t * lv_app_style_get(void); #include "lvgl/lv_appx/lv_app_sysmon.h" #include "lvgl/lv_appx/lv_app_terminal.h" #include "lvgl/lv_appx/lv_app_files.h" +#include "lvgl/lv_appx/lv_app_wifi.h" #endif /*LV_APP_ENABLE != 0*/ diff --git a/lv_app/lv_app_util/lv_app_kb.c b/lv_app/lv_app_util/lv_app_kb.c index 0eb843b8f..d3456f395 100644 --- a/lv_app/lv_app_util/lv_app_kb.c +++ b/lv_app/lv_app_util/lv_app_kb.c @@ -149,14 +149,13 @@ lv_obj_t * lv_app_kb_open(lv_obj_t * ta, lv_app_kb_mode_t mode, void (*close)(lv if(lv_obj_get_height(kb_ta) > cont_h - LV_DPI / 10) { lv_obj_set_height(kb_ta, cont_h - LV_DPI / 10); } -#if LV_APP_ANIM_LEVEL != 0 - lv_page_focus(lv_win_get_content(kb_win), kb_ta, true); -#else lv_page_focus(lv_win_get_page(kb_win), kb_ta, 0); -#endif } lv_ta_set_cursor_pos(kb_ta, LV_TA_CUR_LAST); + if(kb_mode & LV_APP_KB_MODE_CURSOR_MANAGE) { + lv_ta_set_cursor_show(kb_ta, true); + } return kb_btnm; @@ -182,7 +181,11 @@ void lv_app_kb_close(bool ok) lv_obj_set_size(kb_win, LV_HOR_RES, LV_VER_RES); kb_win = NULL; } - + + if(kb_mode & LV_APP_KB_MODE_CURSOR_MANAGE) { + lv_ta_set_cursor_show(kb_ta, false); + } + lv_obj_del(kb_btnm); kb_btnm = NULL; diff --git a/lv_app/lv_app_util/lv_app_kb.h b/lv_app/lv_app_util/lv_app_kb.h index bf0d48031..f3ade3af7 100644 --- a/lv_app/lv_app_util/lv_app_kb.h +++ b/lv_app/lv_app_util/lv_app_kb.h @@ -24,6 +24,7 @@ typedef enum LV_APP_KB_MODE_TXT = 0x01, LV_APP_KB_MODE_NUM = 0x02, LV_APP_KB_MODE_WIN_RESIZE = 0x04, + LV_APP_KB_MODE_CURSOR_MANAGE = 0x08, }lv_app_kb_mode_t; /********************** diff --git a/lv_appx/lv_app_terminal.c b/lv_appx/lv_app_terminal.c index 0e91e946a..f422ec6bc 100644 --- a/lv_appx/lv_app_terminal.c +++ b/lv_appx/lv_app_terminal.c @@ -32,6 +32,7 @@ * DEFINES *********************/ #define OBJ_PAD (LV_DPI / 12) +#define AUTO_CONNECT_TCP_DELAY 5000 /*Wait before TCS server connect when the WiFi connect is ready*/ /********************** * TYPEDEFS @@ -187,7 +188,7 @@ static void my_com_rec(lv_app_inst_t * app_send, lv_app_inst_t * app_rec, /*Insert the name of the sender application if it is not the last*/ if(app_data->last_sender != app_send) { - add_data(app_rec, "@", 1); + add_data(app_rec, "\n@", 2); add_data(app_rec, app_send->name, strlen(app_send->name)); add_data(app_rec, "\n", 1); } @@ -424,6 +425,8 @@ static void win_ta_kb_ok_action(lv_obj_t * ta) lv_app_com_send(app, app_data->com_type, ta_txt, ta_txt_len); lv_ta_set_text(ta, ""); + app_data->last_sender = NULL; /*Now the least data in the terminal is from this app*/ + } /** diff --git a/lv_appx/lv_app_wifi.c b/lv_appx/lv_app_wifi.c new file mode 100644 index 000000000..6b9fbc0dc --- /dev/null +++ b/lv_appx/lv_app_wifi.c @@ -0,0 +1,484 @@ +/** + * @file lv_app_wifi.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_app_wifi.h" +#if LV_APP_ENABLE != 0 && USE_LV_APP_WIFI != 0 + +#include "../lv_app/lv_app_util/lv_app_kb.h" +#include "hal/wifi/wifi.h" +#include "misc/os/ptask.h" +#include "hal/systick/systick.h" +#include "misc/comm/wifimng.h" +#include + +/********************* + * DEFINES + *********************/ +#define SSID_LIST_MAX_LENGTH 512 +#define WIFI_MONITOR_PERIOD 1000 /*ms*/ + +/********************** + * TYPEDEFS + **********************/ + +/*Application specific data for an instance of this application*/ +typedef struct +{ + char set_ssid[64]; + char set_pwd[64]; + char set_ip[32]; + char set_port[16]; +}my_app_data_t; + +/*Application specific data a window of this application*/ +typedef struct +{ + lv_obj_t * list; + lv_obj_t * title; + lv_obj_t * netw_ssid_ta; + lv_obj_t * netw_pwd_ta; + lv_obj_t * tcp_ip_ta; + lv_obj_t * tcp_port_ta; +}my_win_data_t; + +/*Application specific data for a shortcut of this application*/ +typedef struct +{ + lv_obj_t * label; +}my_sc_data_t; + +/********************** + * STATIC PROTOTYPES + **********************/ +static void my_app_run(lv_app_inst_t * app, void * conf); +static void my_app_close(lv_app_inst_t * app); +static void my_com_rec(lv_app_inst_t * app_send, lv_app_inst_t * app_rec, lv_app_com_type_t type , const void * data, uint32_t size); +static void my_sc_open(lv_app_inst_t * app, lv_obj_t * sc); +static void my_sc_close(lv_app_inst_t * app); +static void my_win_open(lv_app_inst_t * app, lv_obj_t * win); +static void my_win_close(lv_app_inst_t * app); + +static void wifi_state_monitor_task(void * param); + +static lv_action_res_t netw_list_rel_action(lv_obj_t * btn, lv_dispi_t * dispi); +static lv_action_res_t netw_con_rel_action(lv_obj_t * btn, lv_dispi_t* dispi); +static lv_action_res_t netw_ssid_rel_action( lv_obj_t * ta, lv_dispi_t* dispi); +static lv_action_res_t netw_pwd_rel_action( lv_obj_t * ta, lv_dispi_t* dispi); +static lv_action_res_t tcp_ip_rel_action( lv_obj_t * ta, lv_dispi_t* dispi); +static lv_action_res_t tcp_port_rel_action( lv_obj_t * ta, lv_dispi_t* dispi); +static lv_action_res_t wifi_ap_select_action( lv_obj_t * ddlist, lv_dispi_t* dispi); + +static void netw_ssid_kb_ok(lv_obj_t * ta); +static void netw_ssid_kb_close(lv_obj_t * ta); +static void netw_pwd_kb_ok(lv_obj_t * ta); +static void netw_pwd_kb_close(lv_obj_t * ta); +static void tcp_ip_kb_ok(lv_obj_t * ta); +static void tcp_ip_kb_close(lv_obj_t * ta); +static void tcp_port_kb_ok(lv_obj_t * ta); +static void tcp_port_kb_close(lv_obj_t * ta); + +static void list_cb(wifi_state_t state, const char * txt); +static void tcp_transf_cb(wifi_state_t state, const char * txt); + +static void win_title_refr(void); + +/********************** + * STATIC VARIABLES + **********************/ +static lv_app_dsc_t my_app_dsc = +{ + .name = "WiFi", + .mode = LV_APP_MODE_NONE, + .app_run = my_app_run, + .app_close = my_app_close, + .com_rec = my_com_rec, + .win_open = my_win_open, + .win_close = my_win_close, + .sc_open = my_sc_open, + .sc_close = my_sc_close, + .app_data_size = sizeof(my_app_data_t), + .sc_data_size = sizeof(my_sc_data_t), + .win_data_size = sizeof(my_win_data_t), +}; + +static char ssid_list[SSID_LIST_MAX_LENGTH]; +static lv_app_inst_t * app_act_com; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * Initialize the application + * @return pointer to the application descriptor of this application + */ +const lv_app_dsc_t * lv_app_wifi_init(void) +{ + strcpy(ssid_list, ""); + + wifimng_set_last_netw(LV_APP_WIFI_SSID_DEF, LV_APP_WIFI_PWD_DEF); + wifimng_set_last_tcp(LV_APP_WIFI_IP_DEF, LV_APP_WIFI_PORT_DEF); + + ptask_create(wifi_state_monitor_task, WIFI_MONITOR_PERIOD, PTASK_PRIO_LOW, NULL); + + return &my_app_dsc; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +/** + * Run an application according to 'app_dsc' + * @param app_dsc pointer to an application descriptor + * @param conf pointer to a lv_app_example_conf_t structure with configuration data or NULL if unused + * @return pointer to the opened application or NULL if any error occurred + */ +static void my_app_run(lv_app_inst_t * app, void * conf) +{ + /*Initialize the application*/ + my_app_data_t * adata = app->app_data; + strcpy(adata->set_ssid, LV_APP_WIFI_SSID_DEF); + strcpy(adata->set_pwd, LV_APP_WIFI_PWD_DEF); + strcpy(adata->set_ip, LV_APP_WIFI_IP_DEF); + strcpy(adata->set_port, LV_APP_WIFI_PORT_DEF); +} + +/** + * Close a running application. + * Close the Window and the Shortcut too if opened. + * Free all the allocated memory by this application. + * @param app pointer to an application + */ +static void my_app_close(lv_app_inst_t * app) +{ + /*No dynamically allocated data in 'my_app_data'*/ +} + +/** + * Read the data have been sent to this application + * @param app_send pointer to an application which sent the message + * @param app_rec pointer to an application which is receiving the message + * @param type type of data from 'lv_app_com_type_t' enum + * @param data pointer to the sent data + * @param size length of 'data' in bytes + */ +static void my_com_rec(lv_app_inst_t * app_send, lv_app_inst_t * app_rec, + lv_app_com_type_t type , const void * data, uint32_t size) +{ + if(type == LV_APP_COM_TYPE_CHAR) { /*data: string*/ + app_act_com = app_rec; + wifi_tcp_transf(data, size, tcp_transf_cb); + } +} + +/** + * Open a shortcut for an application + * @param app pointer to an application + * @param sc pointer to an object where the application + * can create content of the shortcut + */ +static void my_sc_open(lv_app_inst_t * app, lv_obj_t * sc) +{ + my_sc_data_t * sc_data = app->sc_data; + + sc_data->label = lv_label_create(sc, NULL); + lv_label_set_text(sc_data->label, "Empty"); + lv_obj_align(sc_data->label, NULL, LV_ALIGN_CENTER, 0, 0); +} + +/** + * Close the shortcut of an application + * @param app pointer to an application + */ +static void my_sc_close(lv_app_inst_t * app) +{ + /*No dynamically allocated data in 'my_sc_data'*/ +} + + +/** + * Open the application in a window + * @param app pointer to an application + * @param win pointer to a window object where + * the application can create content + */ +static void my_win_open(lv_app_inst_t * app, lv_obj_t * win) +{ + my_app_data_t * adata = app->app_data; + my_win_data_t * wdata = app->win_data; + + wdata->title = lv_label_create(win, NULL); + + wdata->list = lv_ddlist_create(win, NULL); + lv_obj_set_free_p(wdata->list, app); + lv_ddlist_set_options_str(wdata->list, ssid_list); + lv_ddlist_set_action(wdata->list, wifi_ap_select_action); + + lv_obj_t * list_btn = lv_btn_create(win, NULL); + lv_obj_set_free_p(list_btn, app); + lv_btn_set_rel_action(list_btn, netw_list_rel_action); + lv_obj_t * label = lv_label_create(list_btn, NULL); + lv_label_set_text(label, "List\nrefresh"); + + lv_obj_t * ta_cont = lv_cont_create(win, NULL); + lv_cont_set_fit(ta_cont, true, true); + lv_cont_set_layout(ta_cont, LV_CONT_LAYOUT_COL_L); + lv_obj_set_style(ta_cont, lv_style_get(LV_STYLE_TRANSP_TIGHT, NULL)); + + wdata->netw_ssid_ta = lv_ta_create(ta_cont, NULL); + lv_cont_set_fit(wdata->netw_ssid_ta, false, true); + lv_obj_set_free_p(wdata->netw_ssid_ta, app); + lv_page_set_rel_action(wdata->netw_ssid_ta, netw_ssid_rel_action); + lv_ta_set_text(wdata->netw_ssid_ta, adata->set_ssid); + lv_ta_set_cursor_show(wdata->netw_ssid_ta, false); + + wdata->netw_pwd_ta = lv_ta_create(ta_cont, wdata->netw_ssid_ta); + lv_page_set_rel_action(wdata->netw_pwd_ta, netw_pwd_rel_action); + lv_ta_set_text(wdata->netw_pwd_ta, adata->set_pwd); + + wdata->tcp_ip_ta = lv_ta_create(ta_cont, wdata->netw_ssid_ta); + lv_page_set_rel_action(wdata->tcp_ip_ta, tcp_ip_rel_action); + lv_ta_set_text(wdata->tcp_ip_ta, adata->set_ip); + + wdata->tcp_port_ta = lv_ta_create(ta_cont, wdata->netw_ssid_ta); + lv_page_set_rel_action(wdata->tcp_port_ta, tcp_port_rel_action); + lv_ta_set_text(wdata->tcp_port_ta, adata->set_port); + + + lv_obj_t * con_btn = lv_btn_create(win, NULL); + lv_obj_set_free_p(con_btn, app); + lv_btn_set_rel_action(con_btn, netw_con_rel_action); + label = lv_label_create(con_btn, NULL); + lv_label_set_text(label, "Connect"); + + + lv_cont_set_layout(lv_page_get_scrl(lv_win_get_page(win)), LV_CONT_LAYOUT_PRETTY); + + win_title_refr(); +} + + +/** + * Close the window of an application + * @param app pointer to an application + */ +static void my_win_close(lv_app_inst_t * app) +{ + +} + +/*-------------------- + * OTHER FUNCTIONS + ---------------------*/ + +static void wifi_state_monitor_task(void * param) +{ + static wifimng_state_t state_prev = WIFIMNG_STATE_WAIT; + wifimng_state_t state_act = wifimng_get_state(); + + if(state_prev != state_act && state_act == WIFIMNG_STATE_READY) { + lv_app_notice_add("WiFi connected to:\n%s\n%s:%s", + wifimng_get_last_ssid(), wifimng_get_last_ip(), wifimng_get_last_port()); + } + + + state_prev = state_act; +} + +static lv_action_res_t netw_list_rel_action(lv_obj_t * btn, lv_dispi_t* dispi) +{ + bool ret; + ret = wifi_netw_list(list_cb); + + if(ret != false) { + lv_app_notice_add("Listing WiFi networks"); + } else { + lv_app_notice_add("Cannot list networks\nWiFi was busy. Try again"); + + } + return LV_ACTION_RES_OK; +} + +static lv_action_res_t netw_con_rel_action(lv_obj_t * btn, lv_dispi_t* dispi) +{ + lv_app_inst_t * app = lv_obj_get_free_p(btn); + my_app_data_t * adata = app->app_data; + + wifimng_set_last_netw(adata->set_ssid, adata->set_pwd); + wifimng_set_last_tcp(adata->set_ip, adata->set_port); + wifimng_reconnect(); + lv_app_notice_add("Connecting to WiFi network\n%s, %s:%s", + adata->set_ssid, adata->set_ip, adata->set_port); + return LV_ACTION_RES_OK; +} + +static lv_action_res_t netw_ssid_rel_action( lv_obj_t * ta, lv_dispi_t* dispi) +{ + lv_app_kb_open(ta, LV_APP_KB_MODE_TXT | LV_APP_KB_MODE_WIN_RESIZE | LV_APP_KB_MODE_CURSOR_MANAGE, netw_ssid_kb_close ,netw_ssid_kb_ok); + return LV_ACTION_RES_OK; +} + +static lv_action_res_t netw_pwd_rel_action( lv_obj_t * ta, lv_dispi_t* dispi) +{ + lv_app_kb_open(ta, LV_APP_KB_MODE_TXT | LV_APP_KB_MODE_WIN_RESIZE | LV_APP_KB_MODE_CURSOR_MANAGE, netw_pwd_kb_close ,netw_pwd_kb_ok); + return LV_ACTION_RES_OK; +} + +static lv_action_res_t tcp_ip_rel_action( lv_obj_t * ta, lv_dispi_t* dispi) +{ + lv_app_kb_open(ta, LV_APP_KB_MODE_TXT | LV_APP_KB_MODE_WIN_RESIZE | LV_APP_KB_MODE_CURSOR_MANAGE, tcp_ip_kb_close ,tcp_ip_kb_ok); + return LV_ACTION_RES_OK; +} + +static lv_action_res_t tcp_port_rel_action( lv_obj_t * ta, lv_dispi_t* dispi) +{ + lv_app_kb_open(ta, LV_APP_KB_MODE_NUM | LV_APP_KB_MODE_WIN_RESIZE | LV_APP_KB_MODE_CURSOR_MANAGE, tcp_port_kb_close ,tcp_port_kb_ok); + return LV_ACTION_RES_OK; +} + +static lv_action_res_t wifi_ap_select_action( lv_obj_t * ddlist, lv_dispi_t* dispi) +{ + lv_app_inst_t * app = lv_obj_get_free_p(ddlist); + my_app_data_t * adata = app->app_data; + + char ssid[256]; + lv_ddlist_get_selected_str(ddlist, ssid); + + my_win_data_t * wdata = app->win_data; + lv_ta_set_text(wdata->netw_ssid_ta, ssid); + strcpy(adata->set_ssid, ssid); + + return LV_ACTION_RES_OK; +} + +static void netw_ssid_kb_ok(lv_obj_t * ta) +{ + lv_app_inst_t * app = lv_obj_get_free_p(ta); + my_app_data_t * adata = app->app_data; + strcpy(adata->set_ssid, lv_ta_get_txt(ta)); +} + +static void netw_ssid_kb_close(lv_obj_t * ta) +{ + lv_app_inst_t * app = lv_obj_get_free_p(ta); + my_app_data_t * adata = app->app_data; + lv_ta_set_text(ta, adata->set_ssid); +} + +static void netw_pwd_kb_ok(lv_obj_t * ta) +{ + lv_app_inst_t * app = lv_obj_get_free_p(ta); + my_app_data_t * adata = app->app_data; + strcpy(adata->set_pwd, lv_ta_get_txt(ta)); +} + +static void netw_pwd_kb_close(lv_obj_t * ta) +{ + lv_app_inst_t * app = lv_obj_get_free_p(ta); + my_app_data_t * adata = app->app_data; + lv_ta_set_text(ta, adata->set_pwd); +} + +static void tcp_ip_kb_ok(lv_obj_t * ta) +{ + lv_app_inst_t * app = lv_obj_get_free_p(ta); + my_app_data_t * adata = app->app_data; + strcpy(adata->set_ip, lv_ta_get_txt(ta)); +} + +static void tcp_ip_kb_close(lv_obj_t * ta) +{ + lv_app_inst_t * app = lv_obj_get_free_p(ta); + my_app_data_t * adata = app->app_data; + lv_ta_set_text(ta, adata->set_ip); +} + +static void tcp_port_kb_ok(lv_obj_t * ta) +{ + lv_app_inst_t * app = lv_obj_get_free_p(ta); + my_app_data_t * adata = app->app_data; + strcpy(adata->set_port, lv_ta_get_txt(ta)); +} + +static void tcp_port_kb_close(lv_obj_t * ta) +{ + lv_app_inst_t * app = lv_obj_get_free_p(ta); + my_app_data_t * adata = app->app_data; + lv_ta_set_text(ta, adata->set_port); +} + +static void list_cb(wifi_state_t state, const char * txt) +{ + if(state == WIFI_STATE_READY) { + if(txt[0] == '\0') { + lv_app_notice_add("WiFi network list ready"); + return; + } + if(strlen(ssid_list) + strlen(txt) + 4 < sizeof(ssid_list)) { + sprintf(ssid_list, "%s\n%s", ssid_list, txt); + } + + lv_app_inst_t * app = lv_app_get_next(NULL, &my_app_dsc); + while(app != NULL) { + if(app->win_data != NULL) { + my_win_data_t * wdata = app->win_data; + lv_ddlist_set_options_str(wdata->list, ssid_list); + + } + app = lv_app_get_next(app, &my_app_dsc); + } + } else if(state == WIFI_STATE_ERROR) { + lv_app_notice_add("WiFi network list error\n%s", txt); + } +} + +static void tcp_transf_cb(wifi_state_t state, const char * txt) +{ + if(state == WIFI_STATE_READY) { + uint16_t size = txt[0] + ((txt[1] << 8) & 0xFF00); + char buf[256]; + memcpy(buf, &txt[2], size); + buf[size] = '\0'; + lv_app_com_send(app_act_com, LV_APP_COM_TYPE_CHAR, &txt[2], size); + }else if(state == WIFI_STATE_ERROR) { + lv_app_notice_add("WiFi TCP transfer error\n%s", txt); + lv_app_notice_add("Reconnecting to WiFi..."); + wifimng_reconnect(); + } + + app_act_com = NULL; +} + + +static void win_title_refr(void) +{ + lv_app_inst_t * app; + app = lv_app_get_next(NULL, &my_app_dsc); + while(app != NULL) { + if(app->win != NULL) { + my_win_data_t * wdata = app->win_data; + + if(wifimng_get_state() != WIFIMNG_STATE_READY) lv_label_set_text(wdata->title, "Not connected"); + else { + char buf[256]; + sprintf(buf, "%s - %s:%s", wifimng_get_last_ssid(), wifimng_get_last_ip(), wifimng_get_last_port()); + lv_label_set_text(wdata->title, buf); + } + lv_obj_set_width(wdata->title, lv_win_get_width(app->win)); + } + app = lv_app_get_next(app, &my_app_dsc); + } +} + + +#endif /*LV_APP_ENABLE != 0 && USE_LV_APP_EXAMPLE != 0*/ diff --git a/lv_appx/lv_app_wifi.h b/lv_appx/lv_app_wifi.h new file mode 100644 index 000000000..2bbce1417 --- /dev/null +++ b/lv_appx/lv_app_wifi.h @@ -0,0 +1,39 @@ +/** + * @file lv_app_example.h + * + */ + +#ifndef LV_APP_WIFI_H +#define LV_APP_WIFI_H + +/********************* + * INCLUDES + *********************/ +#include "lvgl/lv_app/lv_app.h" + +#if LV_APP_ENABLE != 0 && USE_LV_APP_WIFI != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef struct +{ + +}lv_app_wifi_conf_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ +const lv_app_dsc_t * lv_app_wifi_init(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_APP_ENABLE != 0 && USE_LV_APP_EXAMPLE != 0*/ + +#endif /* LV_APP_EXAMPLE_H */ diff --git a/lv_obj/lv_style.c b/lv_obj/lv_style.c index e0ab30cbf..005747cdd 100644 --- a/lv_obj/lv_style.c +++ b/lv_obj/lv_style.c @@ -134,6 +134,7 @@ void lv_style_init (void) lv_style_btn_rel.hpad = LV_DPI / 4; lv_style_btn_rel.vpad = LV_DPI / 6; lv_style_btn_rel.opad = LV_DPI / 10; + lv_style_btn_rel.txt_align = LV_TXT_ALIGN_MID; /*Button pressed style*/ memcpy(&lv_style_btn_pr, &lv_style_btn_rel, sizeof(lv_style_t)); diff --git a/lv_objx/lv_ddlist.c b/lv_objx/lv_ddlist.c index 54ecb5507..5351c88e3 100644 --- a/lv_objx/lv_ddlist.c +++ b/lv_objx/lv_ddlist.c @@ -140,9 +140,9 @@ bool lv_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * param) *====================*/ /** - * Set the options in a drop down list + * Set the options in a drop down list from an array * @param ddlist pointer to drop down list object - * @param options an array of strings wit the text of the options. + * @param options an array of strings with the text of the options. * The lest element has to be "" (empty string) * E.g. const char * opts[] = {"apple", "banana", "orange", ""}; */ @@ -161,6 +161,18 @@ void lv_ddlist_set_options(lv_obj_t * ddlist, const char ** options) lv_ddlist_refr_size(ddlist, 0); } +/** + * Set the options in a drop down list from a string + * @param ddlist pointer to drop down list object + * @param options a string with '\n' separated options. E.g. "One\nTwo\nThree" + */ +void lv_ddlist_set_options_str(lv_obj_t * ddlist, const char * options) +{ + lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist); + lv_label_set_text(ext->opt_label, options); + lv_ddlist_refr_size(ddlist, 0); +} + /** * Set the selected option * @param ddlist pointer to drop down list object @@ -250,6 +262,31 @@ uint16_t lv_ddlist_get_selected(lv_obj_t * ddlist) return ext->sel_opt; } +/** + * Get the current selected option as a string + * @param ddlist pointer to ddlist object + * @param buf pointer to an array to store the string + */ +void lv_ddlist_get_selected_str(lv_obj_t * ddlist, char * buf) +{ + lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist); + + uint16_t i; + uint16_t line = 0; + const char * opt_txt = lv_label_get_text(ext->opt_label); + uint16_t txt_len = strlen(opt_txt); + + + for(i = 0; i < txt_len && line != ext->sel_opt; i++) { + if(opt_txt[i] == '\n') line ++; + } + + uint16_t c; + for(c = 0; opt_txt[i] != '\n' && i < txt_len; c++, i++) buf[c] = opt_txt[i]; + + buf[c] = '\0'; +} + /** * Get the auto size attribute. * @param ddlist pointer to a drop down list object diff --git a/lv_objx/lv_ddlist.h b/lv_objx/lv_ddlist.h index ad276bce7..49d0097c2 100644 --- a/lv_objx/lv_ddlist.h +++ b/lv_objx/lv_ddlist.h @@ -77,6 +77,7 @@ bool lv_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * param); */ void lv_ddlist_set_options(lv_obj_t * ddlist, const char ** options); +void lv_ddlist_set_options_str(lv_obj_t * ddlist, const char * options); /** * Set the selected option * @param ddlist pointer to drop down list object @@ -121,6 +122,7 @@ const char * lv_ddlist_get_options(lv_obj_t * ddlist); */ uint16_t lv_ddlist_get_selected(lv_obj_t * ddlist); +void lv_ddlist_get_selected_str(lv_obj_t * ddlist, char * buf); /** * Get the auto size attribute. * @param ddlist pointer to a drop down list object diff --git a/lv_objx/lv_ta.c b/lv_objx/lv_ta.c index 837d0f967..e553c3092 100644 --- a/lv_objx/lv_ta.c +++ b/lv_objx/lv_ta.c @@ -105,6 +105,7 @@ lv_obj_t * lv_ta_create(lv_obj_t * par, lv_obj_t * copy) lv_obj_set_design_f(ext->page.scrl, lv_ta_scrling_design); lv_ta_ext_t * copy_ext = lv_obj_get_ext(copy); ext->label = lv_label_create(new_ta, copy_ext->label); + ext->cursor_show = copy_ext->cursor_show; lv_page_glue_obj(ext->label, true); /*Refresh the style with new signal function*/