implemnt scrollable menu field. Not yet tested
This commit is contained in:
		@@ -47,7 +47,9 @@ struct lcd_menu {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct menu_list {
 | 
					struct menu_list {
 | 
				
			||||||
 | 
						void (*update_display)(uint8_t row, const char *data);
 | 
				
			||||||
	const char **entry_names;
 | 
						const char **entry_names;
 | 
				
			||||||
 | 
						uint32_t entry_count;
 | 
				
			||||||
	uint32_t currently_selected;
 | 
						uint32_t currently_selected;
 | 
				
			||||||
	const menu_func_t *submenu_list;
 | 
						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_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__ */
 | 
					#endif /* __MENU_H__ */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,6 +20,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <reflow-controller/ui/menu.h>
 | 
					#include <reflow-controller/ui/menu.h>
 | 
				
			||||||
#include <stddef.h>
 | 
					#include <stddef.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void menu_handle(struct lcd_menu *menu, int16_t rotary_encoder_delta, enum button_state push_button)
 | 
					void menu_handle(struct lcd_menu *menu, int16_t rotary_encoder_delta, enum button_state push_button)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -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);
 | 
						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;
 | 
						uint8_t row_count;
 | 
				
			||||||
	(void)top_row;
 | 
						uint32_t mid_row;
 | 
				
			||||||
	(void)bottom_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--;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user