diff --git a/Core/Inc/keypad_screen.h b/Core/Inc/keypad_screen.h new file mode 100644 index 0000000..b07381f --- /dev/null +++ b/Core/Inc/keypad_screen.h @@ -0,0 +1,27 @@ +/* + * keypad_screen.h + * + * Created on: Aug 11, 2023 + * Author: leo + */ + +#ifndef INC_KEYPAD_SCREEN_H_ +#define INC_KEYPAD_SCREEN_H_ + +#include + +#include "lvgl.h" + +typedef struct keypad_data keypad_data; + +typedef void (*keypad_on_result_cb)(keypad_data* data); + +struct keypad_data { + lv_obj_t* parent; + keypad_on_result_cb cb; + uint32_t value; + void* user_data; +}; + +void Keypad_screen_launch(keypad_data* data); +#endif \ No newline at end of file diff --git a/Core/Src/PSE_unit_edit_screen.c b/Core/Src/PSE_unit_edit_screen.c index d78fc17..70522ee 100644 --- a/Core/Src/PSE_unit_edit_screen.c +++ b/Core/Src/PSE_unit_edit_screen.c @@ -12,9 +12,11 @@ #include "PSE_unit_edit_screen.h" #include "PSE_unit.h" +#include "keypad_screen.h" #include "lvgl.h" static lv_obj_t* parent_screen; +static lv_obj_t* this_screen; static void back_button_handler(lv_event_t * e){ lv_event_code_t code = lv_event_get_code(e); @@ -30,32 +32,76 @@ static void back_button_handler(lv_event_t * e){ static lv_coord_t widg_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST}; static lv_coord_t widg_row_dsc[] = {LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST}; +static keypad_data kp_data; + +lv_obj_t* flow_widget_label; +static void update_flow(keypad_data* data){ + pse_unit* unit = data->user_data; + unit->flow = data->value; + lv_label_set_text_fmt(flow_widget_label, "Debit : \n%d.%d\nmL/mn", unit->flow / 1000, unit->flow % 1000); +} +static void flow_edit_handler(lv_event_t* e){ + lv_event_code_t code = lv_event_get_code(e); + + if(code == LV_EVENT_CLICKED) { + pse_unit* unit = lv_event_get_user_data(e); + kp_data = (keypad_data){ + .parent = this_screen, + .cb = update_flow, + .user_data = unit, + }; + Keypad_screen_launch(&kp_data); + } +} + static lv_obj_t* flow_widget(lv_obj_t* parent, pse_unit* unit){ // The main container lv_obj_t* cont = lv_obj_create(parent); lv_obj_set_size(cont, lv_pct(24), lv_pct(100)); lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN); - // lv_obj_add_event_cb(cont, unit_widget_clicked_handler, LV_EVENT_ALL, pse_unit); + lv_obj_add_event_cb(cont, flow_edit_handler, LV_EVENT_ALL, unit); // flow setting lv_obj_t* flow = lv_label_create(cont); lv_obj_set_width(flow, lv_pct(100)); lv_obj_set_flex_grow(flow, 1); lv_label_set_text_fmt(flow, "Debit : \n%d.%d\nmL/mn", unit->flow / 1000, unit->flow % 1000); + flow_widget_label = flow; return cont; } + +lv_obj_t* volume_widget_label; +static void update_volume(keypad_data* data){ + pse_unit* unit = data->user_data; + unit->set_volume = data->value; + lv_label_set_text_fmt(volume_widget_label, "Volume : \n%d.%d\nmL", unit->set_volume / 1000, unit->set_volume % 1000); +} +static void volume_edit_handler(lv_event_t* e){ + lv_event_code_t code = lv_event_get_code(e); + + if(code == LV_EVENT_CLICKED) { + pse_unit* unit = lv_event_get_user_data(e); + kp_data = (keypad_data){ + .parent = this_screen, + .cb = update_volume, + .user_data = unit, + }; + Keypad_screen_launch(&kp_data); + } +} static lv_obj_t* volume_widget(lv_obj_t* parent, pse_unit* unit){ // The main container lv_obj_t* cont = lv_obj_create(parent); lv_obj_set_size(cont, lv_pct(24), lv_pct(100)); lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN); - // lv_obj_add_event_cb(cont, unit_widget_clicked_handler, LV_EVENT_ALL, pse_unit); + lv_obj_add_event_cb(cont, volume_edit_handler, LV_EVENT_ALL, unit); // volume setting lv_obj_t* vol = lv_label_create(cont); lv_obj_set_width(vol, lv_pct(100)); lv_obj_set_flex_grow(vol, 1); lv_label_set_text_fmt(vol, "Volume : \n%d.%d\nmL", unit->set_volume / 1000, unit->set_volume % 1000); + volume_widget_label = vol; return cont; } static lv_obj_t* syringe_widget(lv_obj_t* parent, pse_unit* unit){ @@ -108,6 +154,7 @@ void PSE_unit_edit_screen_Gen(lv_obj_t* parent, pse_unit* unit){ parent_screen = parent; // Create a new screen lv_obj_t* scr = lv_obj_create(NULL); + this_screen = scr; // create the top menu on the top 20% lv_obj_t* top_menu = lv_obj_create(scr); diff --git a/Core/Src/keypad_screen.c b/Core/Src/keypad_screen.c new file mode 100644 index 0000000..d40767b --- /dev/null +++ b/Core/Src/keypad_screen.c @@ -0,0 +1,110 @@ +/* + * keypad_screen.c + * + * Created on: Aug 11, 2023 + * Author: leo + */ + +#include "keypad_screen.h" + +#include +#include + +#include "lvgl.h" + +static keypad_data* kp_data; +static uint32_t value; +lv_obj_t* value_readout; + +static const char * btnm_map[] = {"7", "8", "9", "\n", "4", "5", "6", "\n", "1", "2", "3", "\n", "X", "0", LV_SYMBOL_BACKSPACE, NULL}; + +static void back_button_handler(lv_event_t * e){ + lv_event_code_t code = lv_event_get_code(e); + + if(code == LV_EVENT_CLICKED) { + lv_obj_t* curr_scr = lv_scr_act(); + lv_scr_load(kp_data->parent); + lv_obj_del(curr_scr); + } +} + +static void ok_button_handler(lv_event_t * e){ + lv_event_code_t code = lv_event_get_code(e); + + if(code == LV_EVENT_CLICKED) { + kp_data->value = value; + lv_obj_t* curr_scr = lv_scr_act(); + lv_scr_load(kp_data->parent); + lv_obj_del(curr_scr); + kp_data->cb(kp_data); + } +} + +static void keypress_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) { + uint32_t id = lv_btnmatrix_get_selected_btn(obj); + const char * txt = lv_btnmatrix_get_btn_text(obj, id); + + if(txt[0] >= 48 && txt[0] <= 57){ // number + uint8_t digit = txt[0] - 48; + value *= 10; + value += digit; + } + else if(txt[0] == 'X') value = 0; + else value /= 10; + + lv_label_set_text_fmt(value_readout, "%02d.%03d", value/1000, value%1000); + } +} + +void Keypad_screen_launch(keypad_data* data){ + kp_data = data; + value = 0; + + // main screen + lv_obj_t* scr = lv_obj_create(NULL); + + // create the top menu on the top 20% + lv_obj_t* top_menu = lv_obj_create(scr); + lv_obj_set_align(top_menu, LV_ALIGN_TOP_LEFT); + lv_obj_set_size(top_menu, lv_pct(100), lv_pct(20)); + lv_obj_set_style_pad_all(top_menu, 5, 0); + + // add a back button + lv_obj_t* back_button = lv_btn_create(top_menu); + lv_obj_set_size(back_button, lv_pct(10), lv_pct(100)); + lv_obj_set_align(back_button, LV_ALIGN_TOP_LEFT); + lv_obj_add_event_cb(back_button, back_button_handler, LV_EVENT_ALL, NULL); + + // add the back label + lv_obj_t* back_label = lv_label_create(back_button); + lv_label_set_text(back_label, LV_SYMBOL_LEFT); + lv_obj_center(back_label); + + // add a readout of the set value + value_readout = lv_label_create(top_menu); + lv_label_set_text_fmt(value_readout, "%02d.%03d", value/1000, value%1000); + lv_obj_center(value_readout); + + // add a validation button + lv_obj_t* ok_button = lv_btn_create(top_menu); + lv_obj_set_size(ok_button, lv_pct(10), lv_pct(100)); + lv_obj_set_align(ok_button, LV_ALIGN_TOP_RIGHT); + lv_obj_add_event_cb(ok_button, ok_button_handler, LV_EVENT_ALL, NULL); + + // add the ok label + lv_obj_t* ok_label = lv_label_create(ok_button); + lv_label_set_text(ok_label, LV_SYMBOL_OK); + lv_obj_center(ok_label); + + lv_obj_t * btnm1 = lv_btnmatrix_create(scr); + lv_btnmatrix_set_map(btnm1, btnm_map); + lv_obj_align_to(btnm1, top_menu, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0); + lv_obj_set_size(btnm1, lv_pct(100), lv_pct(80)); + lv_obj_add_event_cb(btnm1, keypress_handler, LV_EVENT_ALL, NULL); + + lv_scr_load(scr); +} diff --git a/Drivers/lv_conf.h b/Drivers/lv_conf.h index 0e10466..f85ac54 100644 --- a/Drivers/lv_conf.h +++ b/Drivers/lv_conf.h @@ -49,7 +49,7 @@ #define LV_MEM_CUSTOM 0 #if LV_MEM_CUSTOM == 0 /*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/ - #define LV_MEM_SIZE (32U * 1024U) /*[bytes]*/ + #define LV_MEM_SIZE (64U * 1024U) /*[bytes]*/ /*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/ #define LV_MEM_ADR 0 /*0: unused*/