static int action_toggle_scroll(unsigned type, const char *label, unsigned action) { unsigned scroll_speed = 0, fast_scroll_speed = 0; menu_handle_t *menu = menu_driver_resolve(); if (!menu) return -1; scroll_speed = (max(menu->navigation.scroll.acceleration, 2) - 2) / 4 + 1; fast_scroll_speed = 4 + 4 * scroll_speed; switch (action) { case MENU_ACTION_LEFT: if (menu->navigation.selection_ptr > fast_scroll_speed) menu_navigation_set(&menu->navigation, menu->navigation.selection_ptr - fast_scroll_speed, true); else menu_navigation_clear(&menu->navigation, false); break; case MENU_ACTION_RIGHT: if (menu->navigation.selection_ptr + fast_scroll_speed < (menu_list_get_size(menu->menu_list))) menu_navigation_set(&menu->navigation, menu->navigation.selection_ptr + fast_scroll_speed, true); else { if ((menu_list_get_size(menu->menu_list) > 0)) menu_navigation_set_last(&menu->navigation); } break; } return 0; }
static void glui_navigation_set(void *data, bool scroll) { glui_handle_t *glui = NULL; menu_handle_t *menu = (menu_handle_t*)data; if (!menu) return; glui = (glui_handle_t*)menu->userdata; if (!glui) return; if (!scroll) return; if (driver.menu->selection_ptr < glui->term_height/2) driver.menu->begin = 0; else if (driver.menu->selection_ptr >= glui->term_height/2 && driver.menu->selection_ptr < menu_list_get_size(driver.menu->menu_list) - glui->term_height/2) driver.menu->begin = driver.menu->selection_ptr - glui->term_height/2; else if (driver.menu->selection_ptr >= menu_list_get_size(driver.menu->menu_list) - glui->term_height/2) driver.menu->begin = menu_list_get_size(driver.menu->menu_list) - glui->term_height; }
/** * menu_navigation_increment: * * Increment the navigation pointer. **/ void menu_navigation_increment(menu_navigation_t *nav, unsigned scroll_speed) { settings_t *settings = config_get_ptr(); menu_list_t *menu_list = menu_list_get_ptr(); if (!nav) return; if (nav->selection_ptr + scroll_speed < (menu_list_get_size(menu_list))) { menu_navigation_set(nav, nav->selection_ptr + scroll_speed, true); menu_driver_navigation_increment(); } else { if (settings->menu.navigation.wraparound.vertical_enable) menu_navigation_clear(nav, false); else { if ((menu_list_get_size(menu_list) > 0)) { menu_navigation_set_last(nav); menu_driver_navigation_increment(); } } } }
/** * Before a refresh, we could have deleted a * file on disk, causing selection_ptr to * suddendly be out of range. * * Ensure it doesn't overflow. **/ static void menu_entries_refresh(file_list_t *list) { menu_handle_t *menu = menu_driver_get_ptr(); if (!menu) return; if (!list) return; if (menu->navigation.selection_ptr >= menu_list_get_size(menu->menu_list) && menu_list_get_size(menu->menu_list)) menu_navigation_set(&menu->navigation, menu_list_get_size(menu->menu_list) - 1, true); else if (!menu_list_get_size(menu->menu_list)) menu_navigation_clear(&menu->navigation, true); }
static int mouse_post_iterate(menu_file_list_cbs_t *cbs, const char *path, const char *label, unsigned type, unsigned action) { if (!driver.menu->mouse.enable) return 0; if (driver.menu->mouse.ptr <= menu_list_get_size(driver.menu->menu_list)-1) menu_navigation_set(driver.menu, driver.menu->mouse.ptr, false); if (driver.menu->mouse.left) { if (!driver.menu->mouse.oldleft) { driver.menu->mouse.oldleft = true; if (cbs && cbs->action_ok) return cbs->action_ok(path, label, type, driver.menu->selection_ptr); } } else driver.menu->mouse.oldleft = false; if (driver.menu->mouse.right) { if (!driver.menu->mouse.oldright) { driver.menu->mouse.oldright = true; menu_list_pop_stack(driver.menu->menu_list); } } else driver.menu->mouse.oldright = false; return 0; }
static int archive_open(void) { char cat_path[PATH_MAX_LENGTH]; const char *menu_path = NULL; const char *menu_label = NULL; const char* path = NULL; unsigned int type = 0; menu_handle_t *menu = menu_driver_get_ptr(); if (!menu) return -1; menu_list_pop_stack(menu->menu_list); menu_list_get_last_stack(menu->menu_list, &menu_path, &menu_label, NULL); if (menu_list_get_size(menu->menu_list) == 0) return 0; menu_list_get_at_offset(menu->menu_list->selection_buf, menu->navigation.selection_ptr, &path, NULL, &type); fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path)); menu_list_push_stack_refresh( menu->menu_list, cat_path, menu_label, type, menu->navigation.selection_ptr); return 0; }
void menu_navigation_set_last(menu_handle_t *menu) { menu->selection_ptr = menu_list_get_size(driver.menu->menu_list) - 1; if (driver.menu_ctx && driver.menu_ctx->navigation_set_last) driver.menu_ctx->navigation_set_last(menu); }
static int menu_archive_open(void) { char cat_path[PATH_MAX]; const char *menu_path = NULL; const char *menu_label = NULL; const char* path = NULL; unsigned int type = 0; menu_list_pop_stack(driver.menu->menu_list); menu_list_get_last_stack(driver.menu->menu_list, &menu_path, &menu_label, NULL); if (menu_list_get_size(driver.menu->menu_list) == 0) return 0; menu_list_get_at_offset(driver.menu->menu_list->selection_buf, driver.menu->selection_ptr, &path, NULL, &type); fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path)); menu_list_push_stack_refresh( driver.menu->menu_list, cat_path, menu_label, type, driver.menu->selection_ptr); return 0; }
static int action_bind_up_or_down_generic(unsigned type, const char *label, unsigned action) { unsigned scroll_speed = 0; menu_handle_t *menu = menu_driver_resolve(); if (!menu) return -1; scroll_speed = (max(menu->navigation.scroll.acceleration, 2) - 2) / 4 + 1; if (menu_list_get_size(menu->menu_list) <= 0) return 0; switch (action) { case MENU_ACTION_UP: if (menu->navigation.selection_ptr >= scroll_speed) menu_navigation_set(&menu->navigation, menu->navigation.selection_ptr - scroll_speed, true); else { if (g_settings.menu.navigation.wraparound.vertical_enable) menu_navigation_set(&menu->navigation, menu_list_get_size(menu->menu_list) - 1, true); else menu_navigation_set(&menu->navigation, 0, true); } break; case MENU_ACTION_DOWN: if (menu->navigation.selection_ptr + scroll_speed < (menu_list_get_size(menu->menu_list))) menu_navigation_set(&menu->navigation, menu->navigation.selection_ptr + scroll_speed, true); else { if (g_settings.menu.navigation.wraparound.vertical_enable) menu_navigation_clear(&menu->navigation, false); else menu_navigation_set(&menu->navigation, menu_list_get_size(menu->menu_list) - 1, true); } break; } return 0; }
// Returns the last index + 1 of the menu entry list size_t menu_entries_get_end(void) { menu_list_t *menu_list = menu_list_get_ptr(); if (!menu_list) return 0; return menu_list_get_size(menu_list); }
/** * Before a refresh, we could have deleted a * file on disk, causing selection_ptr to * suddendly be out of range. * * Ensure it doesn't overflow. **/ void menu_list_refresh(file_list_t *list) { menu_navigation_t *nav = menu_navigation_get_ptr(); menu_list_t *menu_list = menu_list_get_ptr(); if (!nav || !menu_list || !list) return; nav->scroll.indices.size = 0; menu_list_build_scroll_indices(list); if (nav->selection_ptr >= menu_list_get_size(menu_list) && menu_list_get_size(menu_list)) menu_navigation_set(nav, menu_list_get_size(menu_list) - 1, true); else if (!menu_list_get_size(menu_list)) menu_navigation_clear(nav, true); }
/** * menu_navigation_set_last: * * Sets navigation pointer to last index. **/ void menu_navigation_set_last(menu_navigation_t *nav) { menu_list_t *menu_list = menu_list_get_ptr(); if (!menu_list || !nav) return; nav->selection_ptr = menu_list_get_size(menu_list) - 1; menu_driver_navigation_set_last(); }
static int archive_load(void) { int ret = 0; menu_displaylist_info_t info = {0}; const char *menu_path = NULL; const char *menu_label = NULL; const char* path = NULL; size_t entry_idx = 0; settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); size_t selected = menu_navigation_get_current_selection(); menu_handle_t *menu = menu_driver_get_ptr(); menu_list_t *menu_list = menu_list_get_ptr(); if (!menu || !menu_list) return -1; menu_list_pop_stack(menu_list); menu_list_get_last_stack(menu_list, &menu_path, &menu_label, NULL, NULL); if (menu_list_get_size(menu_list) == 0) return 0; menu_list_get_at_offset(menu_list->selection_buf, selected, &path, NULL, NULL, &entry_idx); ret = rarch_defer_core(global->core_info, menu_path, path, menu_label, menu->deferred_path, sizeof(menu->deferred_path)); fill_pathname_join(detect_content_path, menu_path, path, sizeof(detect_content_path)); switch (ret) { case -1: event_command(EVENT_CMD_LOAD_CORE); menu_common_load_content(false, CORE_TYPE_PLAIN); break; case 0: info.list = menu_list->menu_stack; info.type = 0; info.directory_ptr = selected; strlcpy(info.path, settings->libretro_directory, sizeof(info.path)); strlcpy(info.label, menu_hash_to_str(MENU_LABEL_DEFERRED_CORE_LIST), sizeof(info.label)); ret = menu_displaylist_push_list(&info, DISPLAYLIST_GENERIC); break; } return ret; }
static int action_right_scroll(unsigned type, const char *label, bool wraparound) { unsigned scroll_speed = 0, fast_scroll_speed = 0; menu_list_t *menu_list = menu_list_get_ptr(); menu_navigation_t *nav = menu_navigation_get_ptr(); if (!nav || !menu_list) return -1; scroll_speed = (max(nav->scroll.acceleration, 2) - 2) / 4 + 1; fast_scroll_speed = 4 + 4 * scroll_speed; if (nav->selection_ptr + fast_scroll_speed < (menu_list_get_size(menu_list))) menu_navigation_set(nav, nav->selection_ptr + fast_scroll_speed, true); else { if ((menu_list_get_size(menu_list) > 0)) menu_navigation_set_last(nav); } return 0; }
int menu_entry_get_current_id(bool use_representation) { size_t i; menu_list_t *menu_list = menu_list_get_ptr(); size_t end = menu_list_get_size(menu_list); for (i = 0; i < end; i++) { menu_entry_t entry = {{0}}; menu_entry_get(&entry, i, NULL, use_representation); if (menu_entry_is_currently_selected(entry.idx)) return i; } return -1; }
static int archive_load(void) { int ret; const char *menu_path = NULL; const char *menu_label = NULL; const char* path = NULL; unsigned int type = 0; menu_handle_t *menu = menu_driver_get_ptr(); settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); if (!menu) return -1; menu_list_pop_stack(menu->menu_list); menu_list_get_last_stack(menu->menu_list, &menu_path, &menu_label, NULL); if (menu_list_get_size(menu->menu_list) == 0) return 0; menu_list_get_at_offset(menu->menu_list->selection_buf, menu->navigation.selection_ptr, &path, NULL, &type); ret = rarch_defer_core(global->core_info, menu_path, path, menu_label, menu->deferred_path, sizeof(menu->deferred_path)); switch (ret) { case -1: event_command(EVENT_CMD_LOAD_CORE); menu_entries_common_load_content(false); break; case 0: menu_list_push_stack_refresh( menu->menu_list, settings->libretro_directory, "deferred_core_list", 0, menu->navigation.selection_ptr); break; } return 0; }
static int action_bind_down_generic(unsigned type, const char *label) { size_t scroll_accel = 0; unsigned scroll_speed = 0; menu_list_t *menu_list = menu_list_get_ptr(); if (!menu_list) return -1; if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SCROLL_ACCEL, &scroll_accel)) return -1; scroll_speed = (max(scroll_accel, 2) - 2) / 4 + 1; if (menu_list_get_size(menu_list) <= 0) return 0; menu_navigation_ctl(MENU_NAVIGATION_CTL_INCREMENT, &scroll_speed); return 0; }
static int menu_archive_load(void) { int ret; const char *menu_path = NULL; const char *menu_label = NULL; const char* path = NULL; unsigned int type = 0; menu_list_pop_stack(driver.menu->menu_list); menu_list_get_last_stack(driver.menu->menu_list, &menu_path, &menu_label, NULL); if (menu_list_get_size(driver.menu->menu_list) == 0) return 0; menu_list_get_at_offset(driver.menu->menu_list->selection_buf, driver.menu->selection_ptr, &path, NULL, &type); ret = rarch_defer_core(g_extern.core_info, menu_path, path, driver.menu->deferred_path, sizeof(driver.menu->deferred_path)); switch (ret) { case -1: rarch_main_command(RARCH_CMD_LOAD_CORE); menu_common_load_content(); break; case 0: menu_list_push_stack_refresh( driver.menu->menu_list, g_settings.libretro_directory, "deferred_core_list", 0, driver.menu->selection_ptr); break; } return 0; }
static int archive_open(void) { char cat_path[PATH_MAX_LENGTH] = {0}; menu_displaylist_info_t info = {0}; const char *menu_path = NULL; const char *menu_label = NULL; const char* path = NULL; unsigned int type = 0; size_t entry_idx = 0; menu_navigation_t *nav = menu_navigation_get_ptr(); menu_list_t *menu_list = menu_list_get_ptr(); if (!menu_list || !nav) return -1; menu_list_pop_stack(menu_list); menu_list_get_last_stack(menu_list, &menu_path, &menu_label, NULL, NULL); if (menu_list_get_size(menu_list) == 0) return 0; menu_list_get_at_offset(menu_list->selection_buf, nav->selection_ptr, &path, NULL, &type, &entry_idx); fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path)); fill_pathname_join(detect_content_path, menu_path, path, sizeof(detect_content_path)); info.list = menu_list->menu_stack; info.type = type; info.directory_ptr = nav->selection_ptr; strlcpy(info.path, cat_path, sizeof(info.path)); strlcpy(info.label, menu_label, sizeof(info.label)); return menu_displaylist_push_list(&info, DISPLAYLIST_GENERIC); }
/** * menu_navigation_decrement: * * Decrement the navigation pointer. **/ void menu_navigation_decrement(menu_navigation_t *nav, unsigned scroll_speed) { menu_list_t *menu_list = menu_list_get_ptr(); settings_t *settings = config_get_ptr(); if (!nav) return; if (nav->selection_ptr >= scroll_speed) menu_navigation_set(nav, nav->selection_ptr - scroll_speed, true); else { if (settings->menu.navigation.wraparound.vertical_enable) menu_navigation_set(nav, menu_list_get_size(menu_list) - 1, true); else menu_navigation_set(nav, 0, true); } menu_driver_navigation_decrement(); }
static int menu_input_pointer_post_iterate(menu_file_list_cbs_t *cbs, menu_entry_t *entry, unsigned action) { unsigned header_height; size_t selection; int ret = 0; menu_list_t *menu_list = menu_list_get_ptr(); menu_input_t *menu_input = menu_input_get_ptr(); settings_t *settings = config_get_ptr(); if (!menu_input) return -1; if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection)) return -1; menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height); if (!settings->menu.pointer.enable #ifdef HAVE_OVERLAY || (settings->input.overlay_enable && input_overlay_is_alive()) #endif ) return 0; if (menu_input->pointer.pressed[0]) { int16_t pointer_x = menu_input_pointer_state(MENU_POINTER_X_AXIS); int16_t pointer_y = menu_input_pointer_state(MENU_POINTER_Y_AXIS); if (!menu_input->pointer.oldpressed[0]) { menu_input->pointer.accel = 0; menu_input->pointer.accel0 = 0; menu_input->pointer.accel1 = 0; menu_input->pointer.start_x = pointer_x; menu_input->pointer.start_y = pointer_y; menu_input->pointer.old_x = pointer_x; menu_input->pointer.old_y = pointer_y; menu_input->pointer.oldpressed[0] = true; } else if (abs(pointer_x - menu_input->pointer.start_x) > 3 || abs(pointer_y - menu_input->pointer.start_y) > 3) { float s, delta_time; menu_input->pointer.dragging = true; menu_input->pointer.dx = pointer_x - menu_input->pointer.old_x; menu_input->pointer.dy = pointer_y - menu_input->pointer.old_y; menu_input->pointer.old_x = pointer_x; menu_input->pointer.old_y = pointer_y; menu_animation_ctl(MENU_ANIMATION_CTL_DELTA_TIME, &delta_time); s = menu_input->pointer.dy / delta_time * 1000000.0; menu_input->pointer.accel = (menu_input->pointer.accel0 + menu_input->pointer.accel1 + s) / 3; menu_input->pointer.accel0 = menu_input->pointer.accel1; menu_input->pointer.accel1 = menu_input->pointer.accel; } } else { if (menu_input->pointer.oldpressed[0]) { if (!menu_input->pointer.dragging) { if ((unsigned)menu_input->pointer.start_y < header_height) { menu_list_pop_stack(menu_list, &selection); menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &selection); } else if (menu_input->pointer.ptr <= menu_list_get_size(menu_list)-1) { menu_input->pointer.oldpressed[0] = false; ret = pointer_tap(cbs, entry, action); } } menu_input->pointer.oldpressed[0] = false; menu_input->pointer.start_x = 0; menu_input->pointer.start_y = 0; menu_input->pointer.old_x = 0; menu_input->pointer.old_y = 0; menu_input->pointer.dx = 0; menu_input->pointer.dy = 0; menu_input->pointer.dragging = false; } } if (menu_input->pointer.back) { if (!menu_input->pointer.oldback) { menu_input->pointer.oldback = true; menu_list_pop_stack(menu_list, &selection); menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &selection); } } menu_input->pointer.oldback = menu_input->pointer.back; return ret; }
static int menu_input_pointer_post_iterate(menu_file_list_cbs_t *cbs, const char *path, const char *label, unsigned type, unsigned action) { menu_handle_t *menu = menu_driver_get_ptr(); settings_t *settings = config_get_ptr(); driver_t *driver = driver_get_ptr(); if (!menu) return -1; if (!settings->menu.pointer.enable #ifdef HAVE_OVERLAY || (settings->input.overlay_enable && driver && driver->overlay) #endif ) return 0; #if defined(HAVE_XMB) if (driver->menu_ctx == &menu_ctx_xmb) return 0; #endif if (menu->pointer.pressed[0]) { if (menu->pointer.oldpressed[0]) { if (menu->mouse.ptr <= menu_list_get_size(menu->menu_list)-1) menu_navigation_set(&menu->navigation, menu->mouse.ptr, false); } else menu->pointer.oldpressed[0] = true; } else { if (menu->pointer.oldpressed[0]) { rarch_setting_t *setting = NULL; menu->pointer.oldpressed[0] = false; setting = (rarch_setting_t*)setting_find_setting (menu->list_settings, menu->menu_list->selection_buf->list[menu->navigation.selection_ptr].label); if (menu->mouse.ptr == menu->navigation.selection_ptr && !menu->pointer.cancel && cbs && cbs->action_toggle && setting && (setting->type == ST_BOOL || setting->type == ST_UINT || setting->type == ST_FLOAT || setting->type == ST_STRING)) return cbs->action_toggle(type, label, MENU_ACTION_RIGHT, true); if (menu->mouse.ptr == menu->navigation.selection_ptr && !menu->pointer.cancel && cbs && cbs->action_ok) return cbs->action_ok(path, label, type, menu->navigation.selection_ptr); else if (menu->mouse.ptr <= menu_list_get_size(menu->menu_list) - 1) menu_navigation_set(&menu->navigation, menu->mouse.ptr, false); } } if (menu->pointer.back) { if (!menu->pointer.oldback) { menu->pointer.oldback = true; menu_list_pop_stack(menu->menu_list); } } menu->pointer.oldback = menu->pointer.back; return 0; }
static int menu_input_mouse_post_iterate(menu_file_list_cbs_t *cbs, const char *path, const char *label, unsigned type, unsigned action) { driver_t *driver = driver_get_ptr(); menu_handle_t *menu = menu_driver_get_ptr(); settings_t *settings = config_get_ptr(); if (!menu) return -1; if (!settings->menu.mouse.enable #ifdef HAVE_OVERLAY || (settings->input.overlay_enable && driver && driver->overlay) #endif ) { menu->mouse.wheeldown = false; menu->mouse.wheelup = false; menu->mouse.oldleft = false; menu->mouse.oldright = false; return 0; } if (menu->mouse.left) { if (!menu->mouse.oldleft) { rarch_setting_t *setting = (rarch_setting_t*)setting_find_setting (menu->list_settings, menu->menu_list->selection_buf->list[menu->navigation.selection_ptr].label); menu->mouse.oldleft = true; #if 0 RARCH_LOG("action OK: %d\n", cbs && cbs->action_ok); RARCH_LOG("action toggle: %d\n", cbs && cbs->action_toggle); if (setting && setting->type) RARCH_LOG("action type: %d\n", setting->type); #endif if (menu->mouse.ptr == menu->navigation.selection_ptr && cbs && cbs->action_toggle && setting && (setting->type == ST_BOOL || setting->type == ST_UINT || setting->type == ST_FLOAT || setting->type == ST_STRING)) return cbs->action_toggle(type, label, MENU_ACTION_RIGHT, true); if (menu->mouse.ptr == menu->navigation.selection_ptr && cbs && cbs->action_ok) return cbs->action_ok(path, label, type, menu->navigation.selection_ptr); else if (menu->mouse.ptr <= menu_list_get_size(menu->menu_list)-1) menu_navigation_set(&menu->navigation, menu->mouse.ptr, false); } } else menu->mouse.oldleft = false; if (menu->mouse.right) { if (!menu->mouse.oldright) { menu->mouse.oldright = true; menu_list_pop_stack(menu->menu_list); } } else menu->mouse.oldright = false; if (menu->mouse.wheeldown) menu_navigation_increment(&menu->navigation, 1); if (menu->mouse.wheelup) menu_navigation_decrement(&menu->navigation, 1); return 0; }
static int action_iterate_main(const char *label, unsigned action) { menu_entry_t entry; static bool did_messagebox = false; char msg[PATH_MAX_LENGTH] = {0}; enum action_iterate_type iterate_type; size_t selected; size_t *pop_selected = NULL; bool do_messagebox = false; bool do_pop_stack = false; bool do_post_iterate = false; bool do_render = false; int ret = 0; menu_handle_t *menu = menu_driver_get_ptr(); menu_navigation_t *nav = menu_navigation_get_ptr(); menu_display_t *disp = menu_display_get_ptr(); menu_list_t *menu_list = menu_list_get_ptr(); uint32_t hash = menu_hash_calculate(label); if (!menu || !menu_list) return 0; iterate_type = action_iterate_type(hash); switch (iterate_type) { case ITERATE_TYPE_HELP: ret = action_iterate_help(msg, sizeof(msg), label); pop_selected = NULL; do_messagebox = true; do_pop_stack = true; do_post_iterate = true; if (ret == 1) action = MENU_ACTION_OK; break; case ITERATE_TYPE_BIND: if (menu_input_bind_iterate()) menu_list_pop_stack(menu_list); break; case ITERATE_TYPE_VIEWPORT: ret = action_iterate_menu_viewport(msg, sizeof(msg), label, action, hash); break; case ITERATE_TYPE_INFO: ret = action_iterate_info(msg, sizeof(msg), label); pop_selected = &nav->selection_ptr; do_messagebox = true; do_pop_stack = true; do_post_iterate = true; break; case ITERATE_TYPE_MESSAGE: strlcpy(msg, disp->message_contents, sizeof(msg)); pop_selected = &nav->selection_ptr; do_messagebox = true; do_pop_stack = true; break; case ITERATE_TYPE_DEFAULT: selected = menu_navigation_get_current_selection(); /* FIXME: selected > selection_buf->list->size, i don't know why. */ selected = max(min(selected, menu_list_get_size(menu_list)-1), 0); menu_entry_get(&entry, selected, NULL, false); ret = menu_entry_action(&entry, selected, (enum menu_action)action); if (ret) return ret; do_post_iterate = true; do_render = true; /* Have to defer it so we let settings refresh. */ if (menu->push_help_screen) { menu_displaylist_info_t info = {0}; info.list = menu_list->menu_stack; strlcpy(info.label, menu_hash_to_str(MENU_LABEL_HELP), sizeof(info.label)); menu_displaylist_push_list(&info, DISPLAYLIST_HELP); } break; } did_messagebox = did_messagebox != do_messagebox; if (did_messagebox) menu_display_fb_set_dirty(); if (do_messagebox) menu_driver_render_messagebox(msg); if (do_pop_stack && action == MENU_ACTION_OK) menu_list_pop(menu_list->menu_stack, pop_selected); if (do_post_iterate) menu_input_post_iterate(&ret, action); if (do_render) menu_driver_render(); return ret; }
/** * menu_iterate: * @input : input sample for this frame * @old_input : input sample of the previous frame * @trigger_input : difference' input sample - difference * between 'input' and 'old_input' * * Runs RetroArch menu for one frame. * * Returns: 0 on success, -1 if we need to quit out of the loop. **/ int menu_iterate(bool render_this_frame, unsigned action) { menu_entry_t entry; enum action_iterate_type iterate_type; size_t selected; const char *label = NULL; int ret = 0; uint32_t hash = 0; menu_handle_t *menu = menu_driver_get_ptr(); menu_navigation_t *nav = menu_navigation_get_ptr(); menu_display_t *disp = menu_display_get_ptr(); menu_list_t *menu_list = menu_list_get_ptr(); if (render_this_frame) menu_animation_update_time(); menu_list_get_last_stack(menu_list, NULL, &label, NULL, NULL); if (!menu || !menu_list) return 0; menu->state.fb_is_dirty = false; menu->state.do_messagebox = false; menu->state.do_render = false; menu->state.do_pop_stack = false; menu->state.do_post_iterate = false; menu->state.pop_selected = NULL; menu->state.msg[0] = '\0'; hash = menu_hash_calculate(label); iterate_type = action_iterate_type(hash); if (action != MENU_ACTION_NOOP || menu_entries_needs_refresh() || menu_display_update_pending()) { if (render_this_frame) menu->state.fb_is_dirty = true; } switch (iterate_type) { case ITERATE_TYPE_HELP: ret = action_iterate_help(menu->state.msg, sizeof(menu->state.msg), label); if (render_this_frame) menu->state.do_render = true; menu->state.pop_selected = NULL; menu->state.do_messagebox = true; menu->state.do_pop_stack = true; menu->state.do_post_iterate = true; if (ret == 1) action = MENU_ACTION_OK; break; case ITERATE_TYPE_BIND: if (menu_input_bind_iterate(menu->state.msg, sizeof(menu->state.msg))) menu_list_pop_stack(menu_list, &nav->selection_ptr); else menu->state.do_messagebox = true; if (render_this_frame) menu->state.do_render = true; break; case ITERATE_TYPE_VIEWPORT: ret = action_iterate_menu_viewport(menu->state.msg, sizeof(menu->state.msg), label, action, hash); if (render_this_frame) menu->state.do_render = true; menu->state.do_messagebox = true; break; case ITERATE_TYPE_INFO: ret = action_iterate_info(menu->state.msg, sizeof(menu->state.msg), label); menu->state.pop_selected = &nav->selection_ptr; if (render_this_frame) menu->state.do_render = true; menu->state.do_messagebox = true; menu->state.do_pop_stack = true; menu->state.do_post_iterate = true; break; case ITERATE_TYPE_MESSAGE: strlcpy(menu->state.msg, disp->message_contents, sizeof(menu->state.msg)); menu->state.pop_selected = &nav->selection_ptr; menu->state.do_messagebox = true; menu->state.do_pop_stack = true; break; case ITERATE_TYPE_DEFAULT: selected = menu_navigation_get_selection(nav); /* FIXME: selected > selection_buf->list->size, i don't know why. */ selected = max(min(selected, menu_list_get_size(menu_list)-1), 0); menu_entry_get(&entry, selected, NULL, false); ret = menu_entry_action(&entry, selected, (enum menu_action)action); if (ret) goto end; menu->state.do_post_iterate = true; if (render_this_frame) menu->state.do_render = true; /* Have to defer it so we let settings refresh. */ if (menu->push_help_screen) { menu_displaylist_info_t info = {0}; info.list = menu_list->menu_stack; strlcpy(info.label, menu_hash_to_str(MENU_LABEL_HELP), sizeof(info.label)); menu_displaylist_push_list(&info, DISPLAYLIST_HELP); } break; } if (menu->state.do_pop_stack && action == MENU_ACTION_OK) menu_list_pop_stack(menu_list, menu->state.pop_selected); if (menu->state.do_post_iterate) menu_input_post_iterate(&ret, action); end: if (ret) return -1; return 0; }
static int menu_input_pointer_post_iterate(menu_file_list_cbs_t *cbs, menu_entry_t *entry, unsigned action) { int ret = 0; menu_handle_t *menu = menu_driver_get_ptr(); driver_t *driver = driver_get_ptr(); settings_t *settings = config_get_ptr(); if (!menu) return -1; if (!settings->menu.pointer.enable #ifdef HAVE_OVERLAY || (settings->input.overlay_enable && driver && driver->overlay) #endif ) return 0; if (menu->pointer.pressed[0]) { if (!menu->pointer.oldpressed[0]) { menu->pointer.start_x = menu->pointer.x; menu->pointer.start_y = menu->pointer.y; menu->pointer.old_x = menu->pointer.x; menu->pointer.old_y = menu->pointer.y; menu->pointer.oldpressed[0] = true; } else if (menu->pointer.x != menu->pointer.start_x && menu->pointer.y != menu->pointer.start_y) { menu->pointer.dragging = true; menu->pointer.dx = menu->pointer.x - menu->pointer.old_x; menu->pointer.dy = menu->pointer.y - menu->pointer.old_y; menu->pointer.old_x = menu->pointer.x; menu->pointer.old_y = menu->pointer.y; } } else { if (menu->pointer.oldpressed[0]) { if (!menu->pointer.dragging) { if (menu->pointer.start_y < menu->header_height) { menu_list_pop_stack(menu->menu_list); } else if (menu->pointer.ptr <= menu_list_get_size(menu->menu_list)-1) { menu->pointer.oldpressed[0] = false; ret = pointer_tap(cbs, entry, action); } } menu->pointer.oldpressed[0] = false; menu->pointer.start_x = 0; menu->pointer.start_y = 0; menu->pointer.old_x = 0; menu->pointer.old_y = 0; menu->pointer.dx = 0; menu->pointer.dy = 0; menu->pointer.dragging = false; } } if (menu->pointer.back) { if (!menu->pointer.oldback) { menu->pointer.oldback = true; menu_list_pop_stack(menu->menu_list); } } menu->pointer.oldback = menu->pointer.back; return ret; }
static int menu_input_pointer_post_iterate(menu_file_list_cbs_t *cbs, menu_entry_t *entry, unsigned action) { int ret = 0; menu_display_t *disp = menu_display_get_ptr(); menu_navigation_t *nav = menu_navigation_get_ptr(); menu_list_t *menu_list = menu_list_get_ptr(); menu_input_t *menu_input = menu_input_get_ptr(); settings_t *settings = config_get_ptr(); if (!menu_input) return -1; if (!settings->menu.pointer.enable #ifdef HAVE_OVERLAY || (settings->input.overlay_enable && input_overlay_is_alive()) #endif ) return 0; if (menu_input->pointer.pressed[0]) { if (!menu_input->pointer.oldpressed[0]) { menu_input->pointer.accel = 0; menu_input->pointer.accel0 = 0; menu_input->pointer.accel1 = 0; menu_input->pointer.start_x = menu_input->pointer.x; menu_input->pointer.start_y = menu_input->pointer.y; menu_input->pointer.old_x = menu_input->pointer.x; menu_input->pointer.old_y = menu_input->pointer.y; menu_input->pointer.oldpressed[0] = true; } else if (abs(menu_input->pointer.x - menu_input->pointer.start_x) > 3 || abs(menu_input->pointer.y - menu_input->pointer.start_y) > 3) { float s; menu_input->pointer.dragging = true; menu_input->pointer.dx = menu_input->pointer.x - menu_input->pointer.old_x; menu_input->pointer.dy = menu_input->pointer.y - menu_input->pointer.old_y; menu_input->pointer.old_x = menu_input->pointer.x; menu_input->pointer.old_y = menu_input->pointer.y; s = menu_input->pointer.dy / menu_animation_get_delta_time(disp->animation) * 1000000.0; menu_input->pointer.accel = (menu_input->pointer.accel0 + menu_input->pointer.accel1 + s) / 3; menu_input->pointer.accel0 = menu_input->pointer.accel1; menu_input->pointer.accel1 = menu_input->pointer.accel; } } else { if (menu_input->pointer.oldpressed[0]) { if (!menu_input->pointer.dragging) { if ((unsigned)menu_input->pointer.start_y < disp->header_height) menu_list_pop_stack(menu_list, &nav->selection_ptr); else if (menu_input->pointer.ptr <= menu_list_get_size(menu_list)-1) { menu_input->pointer.oldpressed[0] = false; ret = pointer_tap(cbs, entry, action); } } menu_input->pointer.oldpressed[0] = false; menu_input->pointer.start_x = 0; menu_input->pointer.start_y = 0; menu_input->pointer.old_x = 0; menu_input->pointer.old_y = 0; menu_input->pointer.dx = 0; menu_input->pointer.dy = 0; menu_input->pointer.dragging = false; } } if (menu_input->pointer.back) { if (!menu_input->pointer.oldback) { menu_input->pointer.oldback = true; menu_list_pop_stack(menu_list, &nav->selection_ptr); } } menu_input->pointer.oldback = menu_input->pointer.back; return ret; }
static void rmenu_xui_render(void) { size_t begin, end; char title[256]; const char *dir = NULL; const char *label = NULL; unsigned menu_type = 0; if (!driver.menu || driver.menu->need_refresh && g_extern.is_menu && !driver.menu->msg_force) return; begin = driver.menu->selection_ptr; end = menu_list_get_size(driver.menu->menu_list); rmenu_xui_render_background(); menu_list_get_last_stack(driver.menu->menu_list, &dir, &label, &menu_type); get_title(label, dir, menu_type, title, sizeof(title)); mbstowcs(strw_buffer, title, sizeof(strw_buffer) / sizeof(wchar_t)); XuiTextElementSetText(m_menutitle, strw_buffer); char title_buf[256]; menu_ticker_line(title_buf, RXUI_TERM_WIDTH - 3, g_extern.frame_count / 15, title, true); blit_line(RXUI_TERM_START_X + 15, 15, title_buf, true); char title_msg[64]; const char *core_name = g_extern.menu.info.library_name; if (!core_name) core_name = g_extern.system.info.library_name; if (!core_name) core_name = "No Core"; const char *core_version = g_extern.menu.info.library_version; if (!core_version) core_version = g_extern.system.info.library_version; if (!core_version) core_version = ""; snprintf(title_msg, sizeof(title_msg), "%s - %s %s", PACKAGE_VERSION, core_name, core_version); blit_line(RXUI_TERM_START_X + 15, (RXUI_TERM_HEIGHT * FONT_HEIGHT_STRIDE) + RXUI_TERM_START_Y + 2, title_msg, true); unsigned x, y; size_t i; x = RXUI_TERM_START_X; y = RXUI_TERM_START_Y; for (i = begin; i < end; i++/*, y += FONT_HEIGHT_STRIDE */) { char message[PATH_MAX], type_str[PATH_MAX], entry_title_buf[PATH_MAX], type_str_buf[PATH_MAX], path_buf[PATH_MAX]; const char *path = NULL, *entry_label = NULL; unsigned type = 0, w = 0; bool selected = false; menu_list_get_at_offset(driver.menu->menu_list->selection_buf, i, &path, &entry_label, &type); disp_set_label(driver.menu->menu_list->selection_buf, &w, type, i, label, type_str, sizeof(type_str), entry_label, path, path_buf, sizeof(path_buf)); selected = (i == driver.menu->selection_ptr); #if 0 if ((type == MENU_FILE_PLAIN || type == MENU_FILE_DIRECTORY)) menu_ticker_line(entry_title_buf, RXUI_TERM_WIDTH - (w + 1 + 2), g_extern.frame_count / 15, path, selected); else menu_ticker_line(type_str_buf, w, g_extern.frame_count / 15, type_str, selected); #endif snprintf(message, sizeof(message), "%s : %s", entry_title_buf, type_str_buf); wchar_t msg_w[256]; mbstowcs(msg_w, message, sizeof(msg_w) / sizeof(wchar_t)); XuiListSetText(m_menulist, i, msg_w); blit_line(x, y, message, i); } if (driver.menu->keyboard.display) { char msg[1024]; const char *str = *driver.menu->keyboard.buffer; if (!str) str = ""; snprintf(msg, sizeof(msg), "%s\n%s", driver.menu->keyboard.label, str); rmenu_xui_render_messagebox(msg); } }
static void rmenu_render(void) { size_t begin, end, i, j; struct font_params font_parms; char title[256], title_buf[256]; char title_msg[64]; const char *dir = NULL; const char *label = NULL; const char *core_name = NULL; const char *core_version = NULL; unsigned menu_type = 0; menu_handle_t *menu = menu_driver_get_ptr(); global_t *global = global_get_ptr(); runloop_t *runloop = rarch_main_get_ptr(); if (!menu) return; if (!render_normal) { render_normal = true; return; } if (menu->need_refresh && runloop->is_menu && !menu->msg_force) return; runloop->frames.video.current.menu.animation.is_active = false; runloop->frames.video.current.menu.label.is_updated = false; runloop->frames.video.current.menu.framebuf.dirty = false; if (!menu->menu_list->selection_buf) return; begin = (menu->navigation.selection_ptr >= (ENTRIES_HEIGHT / 2)) ? (menu->navigation.selection_ptr - (ENTRIES_HEIGHT / 2)) : 0; end = ((menu->navigation.selection_ptr + ENTRIES_HEIGHT) <= menu_list_get_size(menu->menu_list)) ? menu->navigation.selection_ptr + ENTRIES_HEIGHT : menu_list_get_size(menu->menu_list); if (menu_list_get_size(menu->menu_list) <= ENTRIES_HEIGHT) begin = 0; if (end - begin > ENTRIES_HEIGHT) end = begin + ENTRIES_HEIGHT; rmenu_render_background(); menu_list_get_last_stack(menu->menu_list, &dir, &label, &menu_type); get_title(label, dir, menu_type, title, sizeof(title)); menu_animation_ticker_line(title_buf, RMENU_TERM_WIDTH, runloop->frames.video.count / 15, title, true); font_parms.x = POSITION_EDGE_MIN + POSITION_OFFSET; font_parms.y = POSITION_EDGE_MIN + POSITION_RENDER_OFFSET - (POSITION_OFFSET*2); font_parms.scale = FONT_SIZE_NORMAL; font_parms.color = WHITE; video_driver_set_osd_msg(title_buf, &font_parms, NULL); core_name = global->menu.info.library_name; if (!core_name) core_name = global->system.info.library_name; if (!core_name) core_name = "No Core"; core_version = global->menu.info.library_version; if (!core_version) core_version = global->system.info.library_version; if (!core_version) core_version = ""; font_parms.x = POSITION_EDGE_MIN + POSITION_OFFSET; font_parms.y = POSITION_EDGE_MAX - (POSITION_OFFSET*2); font_parms.scale = FONT_SIZE_NORMAL; font_parms.color = WHITE; snprintf(title_msg, sizeof(title_msg), "%s - %s %s", PACKAGE_VERSION, core_name, core_version); video_driver_set_osd_msg(title_msg, &font_parms, NULL); j = 0; for (i = begin; i < end; i++, j++) { char message[PATH_MAX_LENGTH], type_str[PATH_MAX_LENGTH], entry_title_buf[PATH_MAX_LENGTH], type_str_buf[PATH_MAX_LENGTH], path_buf[PATH_MAX_LENGTH]; const char *path = NULL, *entry_label = NULL; unsigned type = 0, w = 0; bool selected = false; menu_file_list_cbs_t *cbs = NULL; menu_list_get_at_offset(menu->menu_list->selection_buf, i, &path, &entry_label, &type); cbs = (menu_file_list_cbs_t*) menu_list_get_actiondata_at_offset(menu->menu_list->selection_buf, i); if (cbs && cbs->action_get_representation) cbs->action_get_representation(menu->menu_list->selection_buf, &w, type, i, label, type_str, sizeof(type_str), entry_label, path, path_buf, sizeof(path_buf)); selected = (i == menu->navigation.selection_ptr); menu_animation_ticker_line(entry_title_buf, RMENU_TERM_WIDTH - (w + 1 + 2), runloop->frames.video.count / 15, path, selected); menu_animation_ticker_line(type_str_buf, w, runloop->frames.video.count / 15, type_str, selected); snprintf(message, sizeof(message), "%c %s", selected ? '>' : ' ', entry_title_buf); #if 0 blit_line(x, y, message, selected); #endif font_parms.x = POSITION_EDGE_MIN + POSITION_OFFSET; font_parms.y = POSITION_EDGE_MIN + POSITION_RENDER_OFFSET + (POSITION_OFFSET * j); font_parms.scale = FONT_SIZE_NORMAL; font_parms.color = WHITE; video_driver_set_osd_msg(message, &font_parms, NULL); font_parms.x = POSITION_EDGE_CENTER + POSITION_OFFSET; video_driver_set_osd_msg(type_str_buf, &font_parms, NULL); } }
static int menu_input_mouse_post_iterate(uint64_t *input_mouse, menu_file_list_cbs_t *cbs, unsigned action) { settings_t *settings = config_get_ptr(); menu_display_t *disp = menu_display_get_ptr(); menu_input_t *menu_input = menu_input_get_ptr(); menu_list_t *menu_list = menu_list_get_ptr(); menu_navigation_t *nav = menu_navigation_get_ptr(); *input_mouse = MOUSE_ACTION_NONE; if (!settings->menu.mouse.enable #ifdef HAVE_OVERLAY || (settings->input.overlay_enable && input_overlay_is_alive()) #endif ) { menu_input->mouse.wheeldown = false; menu_input->mouse.wheelup = false; menu_input->mouse.oldleft = false; menu_input->mouse.oldright = false; return 0; } if (menu_input->mouse.left) { if (!menu_input->mouse.oldleft) { BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L); menu_input->mouse.oldleft = true; if ((unsigned)menu_input->mouse.y < disp->header_height) { menu_list_pop_stack(menu_list, &nav->selection_ptr); return 0; } if ( (menu_input->mouse.ptr == nav->selection_ptr) && cbs && cbs->action_select ) { BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L_TOGGLE); } else if (menu_input->mouse.ptr <= menu_list_get_size(menu_list)-1) { BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L_SET_NAVIGATION); } } } else menu_input->mouse.oldleft = false; if (menu_input->mouse.right) { if (!menu_input->mouse.oldright) { menu_input->mouse.oldright = true; BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_R); } } else menu_input->mouse.oldright = false; if (menu_input->mouse.wheeldown) { BIT64_SET(*input_mouse, MOUSE_ACTION_WHEEL_DOWN); } if (menu_input->mouse.wheelup) { BIT64_SET(*input_mouse, MOUSE_ACTION_WHEEL_UP); } return 0; }