implemnt scrollable menu field. Not yet tested

This commit is contained in:
Mario Hüttel 2020-06-09 22:43:00 +02:00
parent 3c3715effa
commit 7db5f02067
2 changed files with 96 additions and 7 deletions

View File

@ -47,7 +47,9 @@ struct lcd_menu {
};
struct menu_list {
void (*update_display)(uint8_t row, const char *data);
const char **entry_names;
uint32_t entry_count;
uint32_t currently_selected;
const menu_func_t *submenu_list;
};
@ -62,6 +64,12 @@ void menu_entry_enter(struct lcd_menu *menu, menu_func_t parent_func, bool handl
void menu_override_lcd_output(struct lcd_menu *menu, uint8_t row_num, const char *text);
void menu_list_display(struct menu_list *list, uint8_t top_row, uint8_t bottom_row);
void menu_list_display(struct menu_list *list, uint32_t top_row, uint32_t bottom_row);
void menu_list_compute_count(struct menu_list *list);
void menu_list_scroll_down(struct menu_list *list);
void menu_list_scroll_up(struct menu_list *list);
#endif /* __MENU_H__ */

View File

@ -20,6 +20,7 @@
#include <reflow-controller/ui/menu.h>
#include <stddef.h>
#include <stdio.h>
void menu_handle(struct lcd_menu *menu, int16_t rotary_encoder_delta, enum button_state push_button)
{
@ -38,9 +39,9 @@ void menu_handle(struct lcd_menu *menu, int16_t rotary_encoder_delta, enum butto
if (menu->active_entry_type == MENU_ENTRY_FIRST_ENTER) {
menu->active_entry(menu, menu->active_entry_type, menu->init_parent);
menu->active_entry(menu, menu->active_entry_type, menu->init_parent);
} else {
menu->active_entry(menu, menu->active_entry_type, NULL);
menu->active_entry(menu, menu->active_entry_type, NULL);
}
if (menu->active_entry_type != MENU_ENTRY_CONTINUE && tmp == menu->active_entry) {
@ -95,9 +96,89 @@ void menu_override_lcd_output(struct lcd_menu *menu, uint8_t row_num, const char
menu->update_display(row_num, text);
}
void menu_list_display(struct menu_list *list, uint8_t top_row, uint8_t bottom_row)
void menu_list_display(struct menu_list *list, uint32_t top_row, uint32_t bottom_row)
{
(void)list;
(void)top_row;
(void)bottom_row;
uint8_t row_count;
uint32_t mid_row;
uint32_t count_above_mid;
uint32_t count_below_mid;
uint32_t start_index;
uint32_t current_row;
uint32_t current_idx;
char workbuff[64];
if (!list || !list->update_display)
return;
if (bottom_row < top_row)
return;
if (list->entry_count == 0) {
for (current_row = top_row; current_row <= bottom_row; current_row++) {
list->update_display((uint8_t)current_row, "");
}
return;
}
/* Calculate list parameters */
row_count = top_row - bottom_row + 1;
mid_row = (top_row + bottom_row) / 2;
count_above_mid = mid_row - top_row;
count_below_mid = bottom_row - mid_row;
/* Check if there are more elements above the and below the currently selected one that can be displayed. in this case position
* active entry in center
*/
if (list->currently_selected > count_above_mid && (list->entry_count - list->currently_selected - 1) > count_below_mid) {
start_index = list->currently_selected - count_above_mid;
} else if (list->currently_selected < count_above_mid) {
start_index = 0;
} else if ((list->entry_count - list->currently_selected - 1) < count_below_mid) {
if (list->entry_count < row_count) {
start_index = 0;
}
start_index = list->entry_count - row_count;
} else {
start_index = 0;
}
for (current_row = top_row, current_idx = start_index; current_row <= bottom_row; current_row++, current_idx++) {
if (current_idx >= list->entry_count)
break;
snprintf(workbuff, sizeof(workbuff), "%c%s", (current_idx == list->currently_selected ? '>' : ' '), list->entry_names[current_idx]);
workbuff[sizeof(workbuff)-1] = 0;
list->update_display((uint8_t)current_row, workbuff);
}
}
void menu_list_compute_count(struct menu_list *list)
{
uint32_t count = 0;
if (!list)
return;
for (count = 0; list->entry_names[count] != NULL; count++);
list->entry_count = count;
}
void menu_list_scroll_down(struct menu_list *list)
{
if (!list)
return;
if (list->currently_selected < list->entry_count - 1) {
list->currently_selected++;
}
}
void menu_list_scroll_up(struct menu_list *list)
{
if (!list)
return;
if (list->currently_selected > 0)
list->currently_selected--;
}