From f6228c19a9cb6593cd3af01cc595f5cd9d3ddd1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martti=20Rannanj=C3=A4rvi?= Date: Fri, 2 Jan 2026 08:17:09 +0200 Subject: [PATCH 1/7] console: Add keypress command --- src/console/console.c | 15 +++++++++++++++ src/console/console.h | 3 +++ src/console/console_cmd.c | 18 ++++++++++++++++++ src/console/console_type.h | 2 ++ 4 files changed, 38 insertions(+) diff --git a/src/console/console.c b/src/console/console.c index 949463cb2..b225a0ac3 100644 --- a/src/console/console.c +++ b/src/console/console.c @@ -359,6 +359,7 @@ void console_tick(game_state *gs) { con->y_pos = 0; } } + console_release_keypress(); } void console_add_cmd(const char *name, command_func func, const char *doc) { @@ -372,6 +373,20 @@ void console_remove_cmd(const char *name) { hashmap_del_str(&con->cmds, name); } +void console_release_keypress(void) { + if(con->keypress_time > 0) { + con->keypress_time--; + return; + } + if(con->keypress_scancode != SDL_SCANCODE_UNKNOWN) { + Uint8 *state = (Uint8 *)SDL_GetKeyboardState(NULL); + state[con->keypress_scancode] = 0; + + con->keypress_time = 0; + con->keypress_scancode = SDL_SCANCODE_UNKNOWN; + } +} + bool console_window_is_open(void) { return con->is_open; } diff --git a/src/console/console.h b/src/console/console.h index aab40c397..1acabcc4b 100644 --- a/src/console/console.h +++ b/src/console/console.h @@ -16,6 +16,9 @@ void console_tick(game_state *gs); void console_add_cmd(const char *name, command_func func, const char *doc); void console_remove_cmd(const char *name); +// Potentially release a key that has been pressed by the keypress command. +void console_release_keypress(void); + void console_output_add(const char *text); void console_output_addline(const char *text); diff --git a/src/console/console_cmd.c b/src/console/console_cmd.c index bb17b0285..69f63aa0b 100644 --- a/src/console/console_cmd.c +++ b/src/console/console_cmd.c @@ -273,6 +273,23 @@ int console_cmd_god(game_state *gs, int argc, char **argv) { return 0; } +int console_keypress(game_state *gs, int argc, char **argv) { + SDL_Event sdlevent; + memset(&sdlevent, 0, sizeof(sdlevent)); + sdlevent.type = SDL_KEYDOWN; + sdlevent.key.keysym.sym = SDLK_DOWN; + sdlevent.key.keysym.scancode = SDL_SCANCODE_DOWN; + SDL_PushEvent(&sdlevent); + + Uint8 *state = (Uint8 *)SDL_GetKeyboardState(NULL); + state[SDL_SCANCODE_DOWN] = 1; + + con->keypress_time = 20; + con->keypress_scancode = SDL_SCANCODE_DOWN; + + return 0; +} + int console_kreissack(game_state *gs, int argc, char **argv) { game_player *p1 = game_state_get_player(gs, 0); p1->sp_wins = (2046 ^ (2 << p1->pilot->pilot_id)); @@ -472,6 +489,7 @@ void console_init_cmd(void) { console_add_cmd("stun", &console_cmd_stun, "Stun the other player"); console_add_cmd("rein", &console_cmd_rein, "R-E-I-N!"); console_add_cmd("god", &console_cmd_god, "Enable god mode"); + console_add_cmd("keypress", &console_keypress, "Push a keypress into the input queue"); console_add_cmd("kreissack", &console_kreissack, "Fight Kreissack"); console_add_cmd("ez-destruct", &console_cmd_ez_destruct, "Punch = destruction, kick = scrap"); console_add_cmd("warp", &console_toggle_warp, "Toggle warp speed"); diff --git a/src/console/console_type.h b/src/console/console_type.h index 38c814756..ff0e9872c 100644 --- a/src/console/console_type.h +++ b/src/console/console_type.h @@ -24,6 +24,8 @@ typedef struct console { int y_pos; hashmap cmds; // string -> command text *text; + int keypress_time; + int keypress_scancode; } console; typedef struct command { From 2f888fc7ee0d957df053b75f2855d1924d3d1aeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martti=20Rannanj=C3=A4rvi?= Date: Sat, 3 Jan 2026 22:38:51 +0200 Subject: [PATCH 2/7] WIP --- src/game/gui/component.c | 7 +++++++ src/game/gui/component.h | 7 +++++-- src/game/gui/sizer.c | 7 +++++++ src/game/gui/sizer.h | 2 ++ src/game/gui/spritebutton.c | 10 ++++++++++ src/game/gui/spritebutton.h | 1 + src/game/gui/widget.c | 7 +++++++ src/game/gui/widget.h | 2 ++ 8 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/game/gui/component.c b/src/game/gui/component.c index 25f7e0549..16808b513 100644 --- a/src/game/gui/component.c +++ b/src/game/gui/component.c @@ -116,6 +116,13 @@ component *component_find(component *c, int id) { return c->find(c, id); } +component *component_find_text(component *c, const char *text) { + if(c->find_text != NULL) { + return c->find_text(c, text); + } + return NULL; +} + void component_set_obj(component *c, void *obj) { c->obj = obj; } diff --git a/src/game/gui/component.h b/src/game/gui/component.h index a8924db9a..7d1b4ff35 100644 --- a/src/game/gui/component.h +++ b/src/game/gui/component.h @@ -25,6 +25,7 @@ typedef void (*component_tick_cb)(component *c); typedef void (*component_free_cb)(component *c); typedef void (*component_init_cb)(component *c, const gui_theme *theme); typedef component *(*component_find_cb)(component *c, int id); +typedef component *(*component_find_text_cb)(component *c, const char *text); /*! \brief Basic GUI object * @@ -70,8 +71,9 @@ struct component { component_tick_cb tick; ///< Tick function callback. This is called periodically. component_free_cb free; ///< Free function callback. Any component callbacks should be done here. component_find_cb find; ///< Should only be set by widget and sizer. Used to look up widgets by ID. - component_init_cb init; ///< Initialization function callback. This is called right before layout function. This - ///< should be used to prerender elements, decide size hints, etc. + component_find_text_cb find_text; ///< ... + component_init_cb init; ///< Initialization function callback. This is called right before layout function. This + ///< should be used to prerender elements, decide size hints, etc. component *parent; ///< Parent component. For widgets, usually a sizer. NULL for root component. }; @@ -121,5 +123,6 @@ void component_set_init_cb(component *c, component_init_cb cb); void component_set_tick_cb(component *c, component_tick_cb cb); void component_set_free_cb(component *c, component_free_cb cb); void component_set_find_cb(component *c, component_find_cb cb); +void component_set_find_text_cb(component *c, component_find_cb cb); #endif // COMPONENT_H diff --git a/src/game/gui/sizer.c b/src/game/gui/sizer.c index 0fa0a680a..29e2df0d8 100644 --- a/src/game/gui/sizer.c +++ b/src/game/gui/sizer.c @@ -17,6 +17,7 @@ typedef struct sizer { sizer_tick_cb tick; sizer_free_cb free; sizer_find_cb find; + sizer_find_text_cb find_text; sizer_init_cb init; } sizer; @@ -109,6 +110,12 @@ void sizer_set_find_cb(component *c, sizer_find_cb cb) { local->find = cb; } +void sizer_set_find_text_cb(component *c, sizer_find_text_cb cb) { + assert(c->header == SIZER_MAGIC); + sizer *local = component_get_obj(c); + local->find_text = cb; +} + void sizer_set_init_cb(component *c, sizer_init_cb cb) { assert(c->header == SIZER_MAGIC); sizer *local = component_get_obj(c); diff --git a/src/game/gui/sizer.h b/src/game/gui/sizer.h index 5f45e65d6..6cdcf10fe 100644 --- a/src/game/gui/sizer.h +++ b/src/game/gui/sizer.h @@ -12,6 +12,7 @@ typedef void (*sizer_tick_cb)(component *c); typedef void (*sizer_init_cb)(component *c, const gui_theme *theme); typedef void (*sizer_free_cb)(component *c); typedef component *(*sizer_find_cb)(component *c, int id); +typedef component *(*sizer_find_text_cb)(component *c, const char *text); typedef struct sizer sizer; @@ -36,6 +37,7 @@ void sizer_set_tick_cb(component *c, sizer_tick_cb cb); void sizer_set_free_cb(component *c, sizer_free_cb cb); void sizer_set_init_cb(component *c, sizer_init_cb cb); void sizer_set_find_cb(component *c, sizer_find_cb cb); +void sizer_set_find_text_cb(component *c, sizer_find_text_cb cb); void sizer_attach(component *c, component *nc); diff --git a/src/game/gui/spritebutton.c b/src/game/gui/spritebutton.c index d1252d1ef..0271dccb6 100644 --- a/src/game/gui/spritebutton.c +++ b/src/game/gui/spritebutton.c @@ -25,6 +25,7 @@ typedef struct spritebutton { spritebutton_click_cb click_cb; spritebutton_tick_cb tick_cb; spritebutton_focus_cb focus_cb; + spritebutton_find_text_cb find_text_cb; bool free_userdata; void *userdata; } spritebutton; @@ -71,6 +72,14 @@ static void spritebutton_tick(component *c) { } } +static component *spritebutton_find_text(component *c, const char *text) { + spritebutton *b = widget_get_obj(c); + if(strcmp(text_c(b->text), text) == 0) { + return c; + } + return NULL; +} + static void spritebutton_focus(component *c, bool focused) { spritebutton *b = widget_get_obj(c); if(b->focus_cb) { @@ -139,6 +148,7 @@ component *spritebutton_create(const char *text, const surface *img, bool disabl widget_set_tick_cb(c, spritebutton_tick); widget_set_free_cb(c, spritebutton_free); widget_set_layout_cb(c, spritebutton_layout); + widget_set_find_text_cb(c, spritebutton_find_text); return c; } diff --git a/src/game/gui/spritebutton.h b/src/game/gui/spritebutton.h index 96093db73..d00d55f8e 100644 --- a/src/game/gui/spritebutton.h +++ b/src/game/gui/spritebutton.h @@ -8,6 +8,7 @@ typedef void (*spritebutton_click_cb)(component *c, void *userdata); typedef void (*spritebutton_tick_cb)(component *c, void *userdata); typedef void (*spritebutton_focus_cb)(component *c, bool focused, void *userdata); +typedef component *(*spritebutton_find_text_cb)(component *c, const char *text); component *spritebutton_create(const char *text, const surface *img, bool disabled, spritebutton_click_cb cb, void *userdata); diff --git a/src/game/gui/widget.c b/src/game/gui/widget.c index 319b7be9e..de850f739 100644 --- a/src/game/gui/widget.c +++ b/src/game/gui/widget.c @@ -12,6 +12,7 @@ typedef struct widget { widget_event_cb event; widget_action_cb action; widget_focus_cb focus; + widget_find_text_cb find_text; widget_layout_cb layout; widget_tick_cb tick; widget_init_cb init; @@ -66,6 +67,12 @@ void widget_set_focus_cb(component *c, widget_focus_cb cb) { local->focus = cb; } +void widget_set_find_text_cb(component *c, widget_find_text_cb cb) { + assert(c->header == WIDGET_MAGIC); + widget *local = component_get_obj(c); + local->find_text = cb; +} + void widget_set_layout_cb(component *c, widget_layout_cb cb) { assert(c->header == WIDGET_MAGIC); widget *local = component_get_obj(c); diff --git a/src/game/gui/widget.h b/src/game/gui/widget.h index d745aa2fe..850f4d518 100644 --- a/src/game/gui/widget.h +++ b/src/game/gui/widget.h @@ -6,6 +6,7 @@ typedef void (*widget_render_cb)(component *c); typedef int (*widget_event_cb)(component *c, SDL_Event *event); typedef int (*widget_action_cb)(component *c, int action); +typedef component *(*widget_find_text_cb)(component *c, const char *text); typedef void (*widget_focus_cb)(component *c, bool focused); typedef void (*widget_layout_cb)(component *c, int x, int y, int w, int h); typedef void (*widget_tick_cb)(component *c); @@ -23,6 +24,7 @@ int widget_get_id(const component *c); void widget_set_render_cb(component *c, widget_render_cb cb); void widget_set_event_cb(component *c, widget_event_cb cb); void widget_set_action_cb(component *c, widget_action_cb cb); +void widget_set_find_text_cb(component *c, widget_find_text_cb cb); void widget_set_focus_cb(component *c, widget_focus_cb cb); void widget_set_layout_cb(component *c, widget_layout_cb cb); void widget_set_tick_cb(component *c, widget_tick_cb cb); From 804a318536da862e685873316b01cfc4c9c30c5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martti=20Rannanj=C3=A4rvi?= Date: Sun, 4 Jan 2026 05:49:26 +0200 Subject: [PATCH 3/7] WIP2 --- src/console/console_cmd.c | 14 ++++++++++++++ src/game/gui/component.h | 3 ++- src/game/scenes/mechlab.c | 5 +++++ src/game/scenes/mechlab.h | 3 +++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/console/console_cmd.c b/src/console/console_cmd.c index 69f63aa0b..cdf68edb8 100644 --- a/src/console/console_cmd.c +++ b/src/console/console_cmd.c @@ -3,6 +3,7 @@ #include "console/console_type.h" #include "formats/error.h" #include "formats/rec_assertion.h" +#include "game/gui/component.h" #include "game/scenes/arena.h" #include "game/scenes/mechlab.h" #include "resources/ids.h" @@ -273,6 +274,18 @@ int console_cmd_god(game_state *gs, int argc, char **argv) { return 0; } +int console_find_by_text(game_state *gs, int argc, char **argv) { + scene *sc = game_state_get_scene(gs); + if(sc->id != SCENE_MECHLAB) { + log_debug("Wrong scene for find_by_text"); + return 1; + } + gui_frame *frame = mechlab_get_frame(game_state_get_scene(gs)); + component_find_text(gui_frame_get_root(frame), "NEW"); + + return 0; +} + int console_keypress(game_state *gs, int argc, char **argv) { SDL_Event sdlevent; memset(&sdlevent, 0, sizeof(sdlevent)); @@ -490,6 +503,7 @@ void console_init_cmd(void) { console_add_cmd("rein", &console_cmd_rein, "R-E-I-N!"); console_add_cmd("god", &console_cmd_god, "Enable god mode"); console_add_cmd("keypress", &console_keypress, "Push a keypress into the input queue"); + console_add_cmd("find_by_text", &console_find_by_text, "Move the hand to this button"); console_add_cmd("kreissack", &console_kreissack, "Fight Kreissack"); console_add_cmd("ez-destruct", &console_cmd_ez_destruct, "Punch = destruction, kick = scrap"); console_add_cmd("warp", &console_toggle_warp, "Toggle warp speed"); diff --git a/src/game/gui/component.h b/src/game/gui/component.h index 7d1b4ff35..98ccd0a08 100644 --- a/src/game/gui/component.h +++ b/src/game/gui/component.h @@ -108,8 +108,9 @@ void component_set_help_text(component *c, const char *text); void component_set_theme(component *c, const gui_theme *theme); const gui_theme *component_get_theme(component *c); -// ID lookup stuff +// lookup stuff component *component_find(component *c, int id); +component *component_find_text(component *c, const char *text); // Basic component callbacks void component_set_obj(component *c, void *obj); diff --git a/src/game/scenes/mechlab.c b/src/game/scenes/mechlab.c index 477a5bba3..9a9cd09e4 100644 --- a/src/game/scenes/mechlab.c +++ b/src/game/scenes/mechlab.c @@ -587,6 +587,11 @@ void mechlab_input_tick(scene *scene) { controller_free_chain(p1); } +gui_frame *mechlab_get_frame(scene *scene) { + mechlab_local *local = scene_get_userdata(scene); + return local->frame; +} + // Init mechlab int mechlab_create(scene *scene) { // Alloc diff --git a/src/game/scenes/mechlab.h b/src/game/scenes/mechlab.h index a54022814..c38144e26 100644 --- a/src/game/scenes/mechlab.h +++ b/src/game/scenes/mechlab.h @@ -3,6 +3,7 @@ #include "formats/chr.h" #include "game/gui/component.h" +#include "game/gui/gui_frame.h" #include "game/protos/scene.h" #define MECHLAB_DARK_GREEN 165 @@ -41,4 +42,6 @@ void mechlab_spin_har(scene *scene, bool to_spin_or_not_to_spin); sd_chr_enemy *mechlab_next_opponent(scene *scene); +gui_frame *mechlab_get_frame(scene *scene); + #endif // MECHLAB_H From b765d3c4a9831a37b888bcc0cfb5833ff9d214b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martti=20Rannanj=C3=A4rvi?= Date: Sun, 4 Jan 2026 06:06:09 +0200 Subject: [PATCH 4/7] WIP3 --- src/console/console_cmd.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/console/console_cmd.c b/src/console/console_cmd.c index cdf68edb8..f2f9256fb 100644 --- a/src/console/console_cmd.c +++ b/src/console/console_cmd.c @@ -281,7 +281,12 @@ int console_find_by_text(game_state *gs, int argc, char **argv) { return 1; } gui_frame *frame = mechlab_get_frame(game_state_get_scene(gs)); - component_find_text(gui_frame_get_root(frame), "NEW"); + component *c = component_find_text(gui_frame_get_root(frame), "NEW"); + if(c == NULL) { + log_debug("Could not find the component"); + return 1; + } + component_action(c, ACT_PUNCH); return 0; } From 9b104255d3770aa90080b9db0aa1866db2836da8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martti=20Rannanj=C3=A4rvi?= Date: Sun, 4 Jan 2026 08:18:30 +0200 Subject: [PATCH 5/7] WIP4 --- src/game/gui/component.c | 4 ++++ src/game/gui/component.h | 2 +- src/game/gui/menu.c | 9 +++++++++ src/game/gui/sizer.c | 26 ++++++++++++++++++++++++++ 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/game/gui/component.c b/src/game/gui/component.c index 16808b513..0805f8b00 100644 --- a/src/game/gui/component.c +++ b/src/game/gui/component.c @@ -169,6 +169,10 @@ void component_set_find_cb(component *c, component_find_cb cb) { c->find = cb; } +void component_set_find_text_cb(component *c, component_find_text_cb cb) { + c->find_text = cb; +} + void component_set_init_cb(component *c, component_init_cb cb) { c->init = cb; } diff --git a/src/game/gui/component.h b/src/game/gui/component.h index 98ccd0a08..0d6c99ab2 100644 --- a/src/game/gui/component.h +++ b/src/game/gui/component.h @@ -124,6 +124,6 @@ void component_set_init_cb(component *c, component_init_cb cb); void component_set_tick_cb(component *c, component_tick_cb cb); void component_set_free_cb(component *c, component_free_cb cb); void component_set_find_cb(component *c, component_find_cb cb); -void component_set_find_text_cb(component *c, component_find_cb cb); +void component_set_find_text_cb(component *c, component_find_text_cb cb); #endif // COMPONENT_H diff --git a/src/game/gui/menu.c b/src/game/gui/menu.c index a13206537..5af848b87 100644 --- a/src/game/gui/menu.c +++ b/src/game/gui/menu.c @@ -430,6 +430,14 @@ static component *menu_find(component *c, int id) { return NULL; } +static component *menu_find_text(component *c, const char *text) { + menu *m = sizer_get_obj(c); + if(m->submenu) { + return component_find_text(m->submenu, text); + } + return NULL; +} + void menu_set_margin_top(component *c, int margin) { menu *m = sizer_get_obj(c); m->margin_top = margin; @@ -467,6 +475,7 @@ component *menu_create(void) { sizer_set_layout_cb(c, menu_layout); sizer_set_free_cb(c, menu_free); sizer_set_find_cb(c, menu_find); + sizer_set_find_text_cb(c, menu_find_text); return c; } diff --git a/src/game/gui/sizer.c b/src/game/gui/sizer.c index 29e2df0d8..c584744d9 100644 --- a/src/game/gui/sizer.c +++ b/src/game/gui/sizer.c @@ -250,6 +250,31 @@ static component *sizer_find(component *c, int id) { return NULL; } +static component *sizer_find_text(component *c, const char *text) { + assert(c->header == SIZER_MAGIC); + sizer *local = component_get_obj(c); + + iterator it; + component **tmp; + vector_iter_begin(&local->objs, &it); + foreach(it, tmp) { + // Find out if the component is what we're looking for. + // If it is, return pointer. + component *out = component_find_text(*tmp, text); + if(out != NULL) { + return out; + } + } + + // If find callback is set, try to use it. + if(local->find_text) { + return local->find_text(c, text); + } + + // If requested ID was not found in any of the internal components/widgets, return NULL. + return NULL; +} + component *sizer_create(void) { component *c = component_create(SIZER_MAGIC); @@ -264,6 +289,7 @@ component *sizer_create(void) { component_set_layout_cb(c, sizer_layout); component_set_free_cb(c, sizer_free); component_set_find_cb(c, sizer_find); + component_set_find_text_cb(c, sizer_find_text); component_set_init_cb(c, sizer_init); return c; From 8e9b6d1e1aa83e7a5bb8bf4971b2a6dba6c89c25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martti=20Rannanj=C3=A4rvi?= Date: Sun, 4 Jan 2026 08:31:42 +0200 Subject: [PATCH 6/7] WIP5 --- src/console/console_cmd.c | 1 + src/game/gui/component.c | 3 +++ src/game/gui/gui_frame.c | 7 +++++++ src/game/gui/gui_frame.h | 1 + 4 files changed, 12 insertions(+) diff --git a/src/console/console_cmd.c b/src/console/console_cmd.c index f2f9256fb..dd3a7d55b 100644 --- a/src/console/console_cmd.c +++ b/src/console/console_cmd.c @@ -4,6 +4,7 @@ #include "formats/error.h" #include "formats/rec_assertion.h" #include "game/gui/component.h" +#include "game/gui/sizer.h" #include "game/scenes/arena.h" #include "game/scenes/mechlab.h" #include "resources/ids.h" diff --git a/src/game/gui/component.c b/src/game/gui/component.c index 0805f8b00..f26bec51d 100644 --- a/src/game/gui/component.c +++ b/src/game/gui/component.c @@ -117,9 +117,12 @@ component *component_find(component *c, int id) { } component *component_find_text(component *c, const char *text) { + log_debug("component_find_text"); if(c->find_text != NULL) { + log_debug("component_find_text: callback found"); return c->find_text(c, text); } + log_debug("component_find_text: NULL"); return NULL; } diff --git a/src/game/gui/gui_frame.c b/src/game/gui/gui_frame.c index 1f725f8f3..a90e075f2 100644 --- a/src/game/gui/gui_frame.c +++ b/src/game/gui/gui_frame.c @@ -47,6 +47,13 @@ component *gui_frame_find(gui_frame *frame, int id) { return NULL; } +component *gui_frame_find_text(gui_frame *frame, const char *text) { + if(frame->root_node) { + return component_find_text(frame->root_node, text); + } + return NULL; +} + component *gui_frame_get_root(const gui_frame *frame) { return frame->root_node; } diff --git a/src/game/gui/gui_frame.h b/src/game/gui/gui_frame.h index d75352054..b09a14253 100644 --- a/src/game/gui/gui_frame.h +++ b/src/game/gui/gui_frame.h @@ -12,6 +12,7 @@ component *gui_frame_get_root(const gui_frame *frame); void gui_frame_free(gui_frame *frame); component *gui_frame_find(gui_frame *frame, int id); +component *gui_frame_find_text(gui_frame *frame, const char *text); void gui_frame_get_measurements(const gui_frame *frame, int *x, int *y, int *w, int *h); From fd5da6270aad2343568ac5ca2d39255c71a9eb24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martti=20Rannanj=C3=A4rvi?= Date: Sun, 4 Jan 2026 10:01:49 +0200 Subject: [PATCH 7/7] WIP6 --- src/console/console_cmd.c | 3 +- src/game/gui/gui_frame.c | 2 ++ src/game/gui/menu.c | 3 ++ src/game/gui/spritebutton.c | 2 ++ src/game/gui/trn_menu.c | 42 ++++++++++++++++++++++++ src/game/gui/trn_menu.h | 1 + src/game/gui/widget.c | 11 +++++++ src/game/gui/widget.h | 2 ++ src/game/scenes/mechlab/button_details.c | 8 +++-- src/game/scenes/mechlab/lab_menu_main.c | 1 + 10 files changed, 72 insertions(+), 3 deletions(-) diff --git a/src/console/console_cmd.c b/src/console/console_cmd.c index dd3a7d55b..55235f040 100644 --- a/src/console/console_cmd.c +++ b/src/console/console_cmd.c @@ -282,7 +282,8 @@ int console_find_by_text(game_state *gs, int argc, char **argv) { return 1; } gui_frame *frame = mechlab_get_frame(game_state_get_scene(gs)); - component *c = component_find_text(gui_frame_get_root(frame), "NEW"); + // component *c = component_find_text(gui_frame_get_root(frame), "NEW"); + component *c = gui_frame_find_text(frame, "NEW"); if(c == NULL) { log_debug("Could not find the component"); return 1; diff --git a/src/game/gui/gui_frame.c b/src/game/gui/gui_frame.c index a90e075f2..aa05b2982 100644 --- a/src/game/gui/gui_frame.c +++ b/src/game/gui/gui_frame.c @@ -1,5 +1,6 @@ #include "game/gui/gui_frame.h" #include "utils/allocator.h" +#include "utils/log.h" typedef struct gui_frame { int x; @@ -48,6 +49,7 @@ component *gui_frame_find(gui_frame *frame, int id) { } component *gui_frame_find_text(gui_frame *frame, const char *text) { + log_debug("gui_frame_find_text"); if(frame->root_node) { return component_find_text(frame->root_node, text); } diff --git a/src/game/gui/menu.c b/src/game/gui/menu.c index 5af848b87..76152a399 100644 --- a/src/game/gui/menu.c +++ b/src/game/gui/menu.c @@ -431,10 +431,13 @@ static component *menu_find(component *c, int id) { } static component *menu_find_text(component *c, const char *text) { + log_debug("menu_find_text"); menu *m = sizer_get_obj(c); if(m->submenu) { + log_debug("menu_find_text: calling for submenu"); return component_find_text(m->submenu, text); } + log_debug("menu_find_text: returning NULL"); return NULL; } diff --git a/src/game/gui/spritebutton.c b/src/game/gui/spritebutton.c index 0271dccb6..c1c05cffe 100644 --- a/src/game/gui/spritebutton.c +++ b/src/game/gui/spritebutton.c @@ -73,6 +73,7 @@ static void spritebutton_tick(component *c) { } static component *spritebutton_find_text(component *c, const char *text) { + log_debug("spritebutton_find_text"); spritebutton *b = widget_get_obj(c); if(strcmp(text_c(b->text), text) == 0) { return c; @@ -148,6 +149,7 @@ component *spritebutton_create(const char *text, const surface *img, bool disabl widget_set_tick_cb(c, spritebutton_tick); widget_set_free_cb(c, spritebutton_free); widget_set_layout_cb(c, spritebutton_layout); + log_debug("widget_set_find_text_cb(c, spritebutton_find_text): %s", text_c(b->text)); widget_set_find_text_cb(c, spritebutton_find_text); return c; } diff --git a/src/game/gui/trn_menu.c b/src/game/gui/trn_menu.c index 40767ffdc..a77a6a711 100644 --- a/src/game/gui/trn_menu.c +++ b/src/game/gui/trn_menu.c @@ -1,5 +1,6 @@ #include "game/gui/trn_menu.h" #include "game/gui/sizer.h" +#include "game/gui/widget.h" #include "utils/allocator.h" #include "utils/log.h" #include "utils/vector.h" @@ -420,6 +421,46 @@ int trnmenu_is_finished(const component *c) { return m->finished; } +static component *trnmenu_find_text(component *c, const char *text) { + log_debug("trnmenu_find_text"); + + iterator it; + component **tmp; + sizer_begin_iterator(c, &it); + + foreach(it, tmp) { + component *t = *tmp; + // log_debug("trnmenu_find_text: iterating %p", t); + + // if(!component_is_selectable(t)) { + // continue; + //} + // widget *w = component_get_obj(t); + // component_get_obj(t); + + component *found = widget_find_text(t, text); + if(found != NULL) { + log_debug("trnmenu_find_text: found %p", t); + return found; + } else { + log_debug("trnmenu_find_text: found was NULL on %p", t); + } + } + log_debug("trnmenu_find_text: checking submenu"); + + trnmenu *m = sizer_get_obj(c); + if(m->submenu != NULL) { + log_debug("trnmenu_find_text: submenu is non-NULL"); + component *found = component_find_text(m->submenu, text); + if(found != NULL) { + return found; + } + } else { + log_debug("trnmenu_find_text: submenu is NULL"); + } + return NULL; +} + void trnmenu_set_submenu(component *c, component *submenu) { trnmenu *m = sizer_get_obj(c); if(m->submenu) { @@ -480,6 +521,7 @@ component *trnmenu_create(surface *button_sheet, int sheet_x, int sheet_y, bool sizer_set_event_cb(c, trnmenu_event); sizer_set_tick_cb(c, trnmenu_tick); sizer_set_free_cb(c, trnmenu_free); + sizer_set_find_text_cb(c, trnmenu_find_text); return c; } diff --git a/src/game/gui/trn_menu.h b/src/game/gui/trn_menu.h index 5ff0767ad..fd3dbaa86 100644 --- a/src/game/gui/trn_menu.h +++ b/src/game/gui/trn_menu.h @@ -11,6 +11,7 @@ typedef void (*trnmenu_tick_cb)(component *c); typedef void (*trnmenu_free_cb)(component *c); typedef void (*trnmenu_submenu_init_cb)(component *menu, component *submenu); typedef void (*trnmenu_submenu_done_cb)(component *menu, component *submenu); +typedef component *(*trnmenu_find_text_cb)(component *menu, const char *text); component *trnmenu_create(surface *button_sheet, int sheet_x, int sheet_y, bool return_hand); void trnmenu_attach(component *menu, component *c); diff --git a/src/game/gui/widget.c b/src/game/gui/widget.c index de850f739..4c01d3521 100644 --- a/src/game/gui/widget.c +++ b/src/game/gui/widget.c @@ -68,6 +68,7 @@ void widget_set_focus_cb(component *c, widget_focus_cb cb) { } void widget_set_find_text_cb(component *c, widget_find_text_cb cb) { + log_debug("widget_set_find_text_cb %p", c); assert(c->header == WIDGET_MAGIC); widget *local = component_get_obj(c); local->find_text = cb; @@ -172,6 +173,16 @@ static component *widget_find(component *c, int id) { return NULL; } +component *widget_find_text(component *c, const char *text) { + widget *w = component_get_obj(c); + log_debug("widget_find_text(%p): %p", c, w); + component *ret = NULL; + if(w->find_text != NULL) { + ret = w->find_text(c, text); + } + return ret; +} + component *widget_create(void) { component *c = component_create(WIDGET_MAGIC); c->supports_disable = 1; diff --git a/src/game/gui/widget.h b/src/game/gui/widget.h index 850f4d518..5ab896aed 100644 --- a/src/game/gui/widget.h +++ b/src/game/gui/widget.h @@ -21,6 +21,8 @@ void *widget_get_obj(const component *c); void widget_set_id(component *c, int id); int widget_get_id(const component *c); +component *widget_find_text(component *c, const char *text); + void widget_set_render_cb(component *c, widget_render_cb cb); void widget_set_event_cb(component *c, widget_event_cb cb); void widget_set_action_cb(component *c, widget_action_cb cb); diff --git a/src/game/scenes/mechlab/button_details.c b/src/game/scenes/mechlab/button_details.c index e4c92ee70..1a288fe6b 100644 --- a/src/game/scenes/mechlab/button_details.c +++ b/src/game/scenes/mechlab/button_details.c @@ -1,9 +1,13 @@ #include "game/scenes/mechlab/button_details.h" +#include "utils/log.h" component *sprite_button_from_details(const button_details *details, const char *text, const surface *img, void *userdata) { - component *b = - spritebutton_create(text != NULL ? text : details->text, img, details->disabled, details->cb, userdata); + text = text != NULL ? text : details->text; + + log_debug("sprite_button_from_details(%s)", text); + + component *b = spritebutton_create(text, img, details->disabled, details->cb, userdata); spritebutton_set_vertical_align(b, details->valign); spritebutton_set_horizontal_align(b, details->halign); spritebutton_set_text_direction(b, details->dir); diff --git a/src/game/scenes/mechlab/lab_menu_main.c b/src/game/scenes/mechlab/lab_menu_main.c index df763341e..52757fe30 100644 --- a/src/game/scenes/mechlab/lab_menu_main.c +++ b/src/game/scenes/mechlab/lab_menu_main.c @@ -5,6 +5,7 @@ #include "game/gui/sizer.h" #include "game/gui/spritebutton.h" #include "game/gui/trn_menu.h" +#include "game/gui/widget.h" #include "game/scenes/mechlab.h" #include "game/scenes/mechlab/button_details.h" #include "game/scenes/mechlab/lab_menu_customize.h"