implemnt scrollable menu field. Not yet tested
This commit is contained in:
parent
3c3715effa
commit
7db5f02067
@ -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__ */
|
||||
|
@ -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--;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user