diff --git a/menu/drivers/materialui.c b/menu/drivers/materialui.c index 11bad4f89d..b01bb0f89b 100644 --- a/menu/drivers/materialui.c +++ b/menu/drivers/materialui.c @@ -1954,31 +1954,60 @@ static void materialui_compute_entries_box(materialui_handle_t* mui, int width, /* Compute the scroll value depending on the highlighted entry */ static float materialui_get_scroll(materialui_handle_t *mui) { - unsigned i, width, height = 0; - float half, sum = 0; - size_t selection = menu_navigation_get_selection(); - file_list_t *list = menu_entries_get_selection_buf_ptr(0); + file_list_t *list = menu_entries_get_selection_buf_ptr(0); + materialui_node_t *node = NULL; + size_t selection = menu_navigation_get_selection(); + unsigned header_height = menu_display_get_header_height(); + unsigned width = 0; + unsigned height = 0; + float view_centre = 0.0f; + float selection_centre = 0.0f; + size_t i; - if (!mui) + if (!mui || !list) return 0; + /* Get current window size */ video_driver_get_size(&width, &height); - half = height / 2; + /* Get the vertical midpoint of the actual + * list view - i.e. account for header + + * navigation bar */ + view_centre = + (float)(height - header_height - mui->nav_bar_layout_height) / 2.0f; + /* Get the vertical midpoint of the currently + * selected entry */ + + /* > Account for entries *before* current selection */ for (i = 0; i < selection; i++) { - materialui_node_t *node = (materialui_node_t*) - file_list_get_userdata_at_offset(list, i); + node = (materialui_node_t*)file_list_get_userdata_at_offset(list, i); - if (node) - sum += node->entry_height; + /* If this ever happens, the scroll position + * will be entirely wrong... */ + if (!node) + continue; + + selection_centre += node->entry_height; } - if (sum < half) - return 0; + /* > Account for current selection */ + node = (materialui_node_t*)file_list_get_userdata_at_offset(list, selection); + if (node) + selection_centre += node->entry_height / 2.0f; - return sum - half; + /* If selected entry is near the beginning of the list + * (such that it fits within the first half of the + * list view when the list is rendered from the start), + * scroll position can be reset to zero */ + if (selection_centre < view_centre) + return 0.0f; + + /* ...Otherwise, set the scroll position such that the + * centre of the selected item is at the centre of the + * list view */ + return selection_centre - view_centre; } static void materialui_layout(