mirror of
https://github.com/libretro/RetroArch
synced 2025-03-30 07:20:36 +00:00
Add experimental RGUI keyboard search feature.
Type '/' to start search, then type search string (case sensitive for now due to strcasestr being GNU ext). When done, type return.
This commit is contained in:
parent
40861aa17d
commit
84c93ef94a
1
driver.h
1
driver.h
@ -492,6 +492,7 @@ typedef struct driver
|
||||
#endif
|
||||
bool stdin_claimed;
|
||||
bool block_hotkey;
|
||||
bool block_input;
|
||||
bool nonblock_state;
|
||||
|
||||
// Opaque handles to currently running window.
|
||||
|
24
file_list.c
24
file_list.c
@ -26,11 +26,9 @@ struct item_file
|
||||
size_t directory_ptr;
|
||||
};
|
||||
|
||||
void file_list_push(void *userdata,
|
||||
void file_list_push(file_list_t *list,
|
||||
const char *path, unsigned type, size_t directory_ptr)
|
||||
{
|
||||
file_list_t *list = (file_list_t*)userdata;
|
||||
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
@ -120,3 +118,23 @@ void file_list_get_last(const file_list_t *list,
|
||||
if (list->size)
|
||||
file_list_get_at_offset(list, list->size - 1, path, file_type);
|
||||
}
|
||||
|
||||
bool file_list_search(const file_list_t *list, const char *needle, size_t *index)
|
||||
{
|
||||
size_t i;
|
||||
const char *alt;
|
||||
for (i = 0; i < list->size; i++)
|
||||
{
|
||||
file_list_get_alt_at_offset(list, i, &alt);
|
||||
if (!alt)
|
||||
continue;
|
||||
if (strstr(alt, needle))
|
||||
{
|
||||
*index = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "boolean.h"
|
||||
|
||||
struct item_file;
|
||||
typedef struct file_list
|
||||
{
|
||||
@ -32,7 +34,7 @@ typedef struct file_list
|
||||
|
||||
void file_list_free(file_list_t *list);
|
||||
|
||||
void file_list_push(void *userdata, const char *path,
|
||||
void file_list_push(file_list_t *userdata, const char *path,
|
||||
unsigned type, size_t current_directory_ptr);
|
||||
void file_list_pop(file_list_t *list, size_t *directory_ptr);
|
||||
void file_list_clear(file_list_t *list);
|
||||
@ -50,6 +52,8 @@ void file_list_get_alt_at_offset(const file_list_t *list, size_t index,
|
||||
|
||||
void file_list_sort_on_alt(file_list_t *list);
|
||||
|
||||
bool file_list_search(const file_list_t *list, const char *needle, size_t *index);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -510,6 +510,13 @@ static void rgui_render(void *data)
|
||||
|
||||
rgui_render_messagebox(rgui, message_queue);
|
||||
#endif
|
||||
|
||||
if (rgui->display_keyboard)
|
||||
{
|
||||
char msg[1024];
|
||||
snprintf(msg, sizeof(msg), "Search: %s", rgui->keyboard.buffer ? rgui->keyboard.buffer : "");
|
||||
rgui_render_messagebox(rgui, msg);
|
||||
}
|
||||
}
|
||||
|
||||
static void *rgui_init(void)
|
||||
|
@ -426,6 +426,8 @@ void menu_free(void)
|
||||
rom_history_free(rgui->history);
|
||||
core_info_list_free(rgui->core_info);
|
||||
|
||||
menu_keyboard_state_clear(&rgui->keyboard);
|
||||
|
||||
free(rgui);
|
||||
}
|
||||
|
||||
@ -1382,6 +1384,7 @@ bool menu_iterate(void)
|
||||
rgui->old_input_state |= 1ULL << RARCH_MENU_TOGGLE;
|
||||
}
|
||||
|
||||
rarch_check_block_hotkey();
|
||||
rarch_input_poll();
|
||||
#ifdef HAVE_OVERLAY
|
||||
rarch_check_overlay();
|
||||
@ -1423,6 +1426,9 @@ bool menu_iterate(void)
|
||||
rgui->delay_count++;
|
||||
rgui->old_input_state = input_state;
|
||||
|
||||
if (driver.block_input)
|
||||
rgui->trigger_state = 0;
|
||||
|
||||
action = RGUI_ACTION_NOOP;
|
||||
|
||||
// don't run anything first frame, only capture held inputs for old_input_state
|
||||
@ -1718,13 +1724,69 @@ bool menu_poll_find_trigger(struct rgui_bind_state *state, struct rgui_bind_stat
|
||||
return false;
|
||||
}
|
||||
|
||||
bool menu_keyboard_state_event(struct rgui_keyboard_state *state,
|
||||
bool down, enum retro_key key, uint32_t character)
|
||||
{
|
||||
// Treat extended chars as ? as we cannot support printable characters for unicode stuff.
|
||||
char c = character >= 128 ? '?' : character;
|
||||
if (c == '\r' || c == '\n')
|
||||
return true;
|
||||
|
||||
if (c == '\b')
|
||||
{
|
||||
if (state->ptr)
|
||||
{
|
||||
memmove(state->buffer + state->ptr - 1, state->buffer + state->ptr,
|
||||
state->size - state->ptr + 1);
|
||||
state->ptr--;
|
||||
state->size--;
|
||||
}
|
||||
}
|
||||
// Handle left/right here when suitable
|
||||
else if (isprint(c))
|
||||
{
|
||||
char *newbuf = (char*)realloc(state->buffer, state->size + 2);
|
||||
if (!newbuf)
|
||||
return false;
|
||||
|
||||
memmove(newbuf + state->ptr + 1, newbuf + state->ptr, state->size - state->ptr + 1);
|
||||
newbuf[state->ptr] = c;
|
||||
state->ptr++;
|
||||
state->size++;
|
||||
newbuf[state->size] = '\0';
|
||||
|
||||
state->buffer = newbuf;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void menu_keyboard_state_clear(struct rgui_keyboard_state *state)
|
||||
{
|
||||
free(state->buffer);
|
||||
memset(state, 0, sizeof(*state));
|
||||
}
|
||||
|
||||
void menu_key_event(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers)
|
||||
{
|
||||
// TODO: Do something with this. Stub for now.
|
||||
(void)down;
|
||||
(void)keycode;
|
||||
(void)character;
|
||||
(void)key_modifiers;
|
||||
|
||||
if (!driver.block_input && character == '/')
|
||||
{
|
||||
driver.block_input = true;
|
||||
rgui->display_keyboard = true;
|
||||
menu_keyboard_state_clear(&rgui->keyboard);
|
||||
return;
|
||||
}
|
||||
|
||||
if (driver.block_input && menu_keyboard_state_event(&rgui->keyboard, down, keycode, character) && rgui->keyboard.buffer)
|
||||
{
|
||||
file_list_search(rgui->selection_buf, rgui->keyboard.buffer, &rgui->selection_ptr);
|
||||
menu_keyboard_state_clear(&rgui->keyboard);
|
||||
driver.block_input = false;
|
||||
rgui->display_keyboard = false;
|
||||
rgui->old_input_state = -1ull; // Avoid triggering states on pressing return.
|
||||
}
|
||||
}
|
||||
|
||||
static inline int menu_list_get_first_char(file_list_t *buf, unsigned offset)
|
||||
|
@ -242,6 +242,17 @@ void menu_poll_bind_get_rested_axes(struct rgui_bind_state *state);
|
||||
void menu_poll_bind_state(struct rgui_bind_state *state);
|
||||
bool menu_poll_find_trigger(struct rgui_bind_state *state, struct rgui_bind_state *new_state);
|
||||
|
||||
struct rgui_keyboard_state
|
||||
{
|
||||
char *buffer;
|
||||
size_t ptr;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
void menu_keyboard_state_clear(struct rgui_keyboard_state *state);
|
||||
bool menu_keyboard_state_event(struct rgui_keyboard_state *state,
|
||||
bool down, enum retro_key key, uint32_t character);
|
||||
|
||||
#ifdef GEKKO
|
||||
enum
|
||||
{
|
||||
@ -324,6 +335,8 @@ typedef struct
|
||||
rarch_time_t last_time; // Used to throttle RGUI in case VSync is broken.
|
||||
|
||||
struct rgui_bind_state binds;
|
||||
struct rgui_keyboard_state keyboard;
|
||||
bool display_keyboard;
|
||||
} rgui_handle_t;
|
||||
|
||||
extern rgui_handle_t *rgui;
|
||||
|
@ -678,6 +678,7 @@ void rarch_init_msg_queue(void);
|
||||
void rarch_deinit_msg_queue(void);
|
||||
void rarch_input_poll(void);
|
||||
void rarch_check_overlay(void);
|
||||
void rarch_check_block_hotkey(void);
|
||||
void rarch_init_rewind(void);
|
||||
void rarch_deinit_rewind(void);
|
||||
void rarch_set_fullscreen(bool fullscreen);
|
||||
|
10
retroarch.c
10
retroarch.c
@ -2690,17 +2690,17 @@ static void check_netplay_flip(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void check_block_hotkey(void)
|
||||
void rarch_check_block_hotkey(void)
|
||||
{
|
||||
driver.block_hotkey = false;
|
||||
driver.block_hotkey = driver.block_input;
|
||||
|
||||
// If we haven't bound anything to this,
|
||||
// always allow hotkeys.
|
||||
static const struct retro_keybind *bind = &g_settings.input.binds[0][RARCH_ENABLE_HOTKEY];
|
||||
if (bind->key == RETROK_UNKNOWN && bind->joykey == NO_BTN && bind->joyaxis == AXIS_NONE)
|
||||
if (!driver.block_hotkey && bind->key == RETROK_UNKNOWN && bind->joykey == NO_BTN && bind->joyaxis == AXIS_NONE)
|
||||
return;
|
||||
|
||||
driver.block_hotkey = !input_key_pressed_func(RARCH_ENABLE_HOTKEY);
|
||||
driver.block_hotkey = driver.block_input || !input_key_pressed_func(RARCH_ENABLE_HOTKEY);
|
||||
}
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
@ -2743,7 +2743,7 @@ static void check_grab_mouse_toggle(void)
|
||||
|
||||
static void do_state_checks(void)
|
||||
{
|
||||
check_block_hotkey();
|
||||
rarch_check_block_hotkey();
|
||||
|
||||
#if defined(HAVE_SCREENSHOTS) && !defined(_XBOX)
|
||||
check_screenshot();
|
||||
|
Loading…
x
Reference in New Issue
Block a user