implemnt scrollable menu field. Not yet tested
This commit is contained in:
		@@ -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--;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user