X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fgadgets.c;h=937f7a3a22bd5e8c9b00bbe058d065ed8b0c5b1c;hb=874229af6e5963fad61c9929a481cd99bebeac48;hp=ce939a75de69cbad9d507d3a0a34f6c8cc1a422d;hpb=3370541656df96651eabc2723332e93964c28737;p=rocksndiamonds.git diff --git a/src/libgame/gadgets.c b/src/libgame/gadgets.c index ce939a75..937f7a3a 100644 --- a/src/libgame/gadgets.c +++ b/src/libgame/gadgets.c @@ -13,6 +13,7 @@ #include #include "gadgets.h" +#include "image.h" #include "text.h" #include "misc.h" @@ -59,7 +60,7 @@ static struct GadgetInfo *getGadgetInfoFromGadgetID(int id) return gi; } -static int getNewGadgetID() +static int getNewGadgetID(void) { int id = next_free_gadget_id++; @@ -212,6 +213,12 @@ static void default_callback_action(void *ptr) return; } +static void DoGadgetCallbackAction(struct GadgetInfo *gi, boolean changed) +{ + if (changed || gi->callback_action_always) + gi->callback_action(gi); +} + static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) { struct GadgetDesign *gd; @@ -782,6 +789,10 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) { switch(tag) { + case GDI_IMAGE_ID: + gi->image_id = va_arg(ap, int); + break; + case GDI_CUSTOM_ID: gi->custom_id = va_arg(ap, int); break; @@ -836,6 +847,10 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) gi->direct_draw = (boolean)va_arg(ap, int); break; + case GDI_CALLBACK_ACTION_ALWAYS: + gi->callback_action_always = (boolean)va_arg(ap, int); + break; + case GDI_CHECKED: gi->checked = (boolean)va_arg(ap, int); break; @@ -1281,6 +1296,7 @@ struct GadgetInfo *CreateGadget(int first_tag, ...) /* always start with reliable default values */ new_gadget->id = getNewGadgetID(); + new_gadget->image_id = -1; new_gadget->callback_info = default_callback_info; new_gadget->callback_action = default_callback_action; new_gadget->active = TRUE; @@ -1426,37 +1442,37 @@ static void MultiMapGadgets(int mode) } } -void UnmapAllGadgets() +void UnmapAllGadgets(void) { MultiMapGadgets(MULTIMAP_ALL | MULTIMAP_UNMAP); } -void RemapAllGadgets() +void RemapAllGadgets(void) { MultiMapGadgets(MULTIMAP_ALL | MULTIMAP_REMAP); } -boolean anyTextInputGadgetActive() +boolean anyTextInputGadgetActive(void) { return (last_gi && (last_gi->type & GD_TYPE_TEXT_INPUT) && last_gi->mapped); } -boolean anyTextAreaGadgetActive() +boolean anyTextAreaGadgetActive(void) { return (last_gi && (last_gi->type & GD_TYPE_TEXT_AREA) && last_gi->mapped); } -boolean anySelectboxGadgetActive() +boolean anySelectboxGadgetActive(void) { return (last_gi && (last_gi->type & GD_TYPE_SELECTBOX) && last_gi->mapped); } -boolean anyScrollbarGadgetActive() +boolean anyScrollbarGadgetActive(void) { return (last_gi && (last_gi->type & GD_TYPE_SCROLLBAR) && last_gi->mapped); } -boolean anyTextGadgetActive() +boolean anyTextGadgetActive(void) { return (anyTextInputGadgetActive() || anyTextAreaGadgetActive() || @@ -1481,18 +1497,25 @@ static boolean insideSelectboxArea(struct GadgetInfo *gi, int mx, int my) void ClickOnGadget(struct GadgetInfo *gi, int button) { - if (!gi->mapped) + if (gi == NULL || gi->deactivated || !gi->mapped) return; /* simulate releasing mouse button over last gadget, if still pressed */ if (button_status) HandleGadgets(-1, -1, 0); + int x = gi->x; + int y = gi->y; + + /* set cursor position to the end of the text for text input gadgets */ + if (gi->type & GD_TYPE_TEXT_INPUT) + x = gi->x + gi->width - 1; + /* simulate pressing mouse button over specified gadget */ - HandleGadgets(gi->x, gi->y, button); + HandleGadgets(x, y, button); /* simulate releasing mouse button over specified gadget */ - HandleGadgets(gi->x, gi->y, 0); + HandleGadgets(x, y, 0); } boolean HandleGadgets(int mx, int my, int button) @@ -1598,13 +1621,15 @@ boolean HandleGadgets(int mx, int my, int button) gi->event.type = GD_EVENT_TEXT_LEAVING; - if (gadget_changed && !(gi->type & GD_TYPE_SELECTBOX)) - gi->callback_action(gi); + if (!(gi->type & GD_TYPE_SELECTBOX)) + DoGadgetCallbackAction(gi, gadget_changed); last_gi = NULL; if (gadget_pressed_inside_select_line) new_gi = NULL; + + StopTextInput(); } gadget_pressed = @@ -1679,16 +1704,20 @@ boolean HandleGadgets(int mx, int my, int button) { int last_x = gi->event.x; int last_y = gi->event.y; + int last_mx = gi->event.mx; + int last_my = gi->event.my; - gi->event.x = mx - gi->x; - gi->event.y = my - gi->y; + gi->event.x = gi->event.mx = mx - gi->x; + gi->event.y = gi->event.my = my - gi->y; if (gi->type == GD_TYPE_DRAWING_AREA) { gi->event.x /= gi->drawing.item_xsize; gi->event.y /= gi->drawing.item_ysize; - if (last_x != gi->event.x || last_y != gi->event.y) + if (last_x != gi->event.x || last_y != gi->event.y || + ((last_mx != gi->event.mx || last_my != gi->event.my) && + gi->event_mask & GD_EVENT_PIXEL_PRECISE)) changed_position = TRUE; } else if (gi->type & GD_TYPE_TEXT_INPUT && button != 0 && !motion_status) @@ -1706,6 +1735,9 @@ boolean HandleGadgets(int mx, int my, int button) if (gi->textinput.cursor_position != old_cursor_position) DrawGadget(gi, DG_PRESSED, gi->direct_draw); + + if (press_event) + StartTextInput(gi->x, gi->y, gi->width, gi->height); } else if (gi->type & GD_TYPE_TEXT_AREA && button != 0 && !motion_status) { @@ -1720,6 +1752,9 @@ boolean HandleGadgets(int mx, int my, int button) if (gi->textarea.cursor_position != old_cursor_position) DrawGadget(gi, DG_PRESSED, gi->direct_draw); + + if (press_event) + StartTextInput(gi->x, gi->y, gi->width, gi->height); } else if (gi->type & GD_TYPE_SELECTBOX && gi->selectbox.open && !keep_selectbox_open) @@ -1750,7 +1785,7 @@ boolean HandleGadgets(int mx, int my, int button) new_gi->event.type = GD_EVENT_INFO_ENTERING; new_gi->callback_info(new_gi); } - else if (last_info_gi != NULL) + else if (last_info_gi != NULL && last_info_gi->mapped) { last_info_gi->event.type = GD_EVENT_INFO_LEAVING; last_info_gi->callback_info(last_info_gi); @@ -1840,8 +1875,8 @@ boolean HandleGadgets(int mx, int my, int button) gi->event.type = GD_EVENT_MOVING; gi->event.off_borders = FALSE; - if (gi->event_mask & GD_EVENT_MOVING && changed_position) - gi->callback_action(gi); + if (gi->event_mask & GD_EVENT_MOVING) + DoGadgetCallbackAction(gi, changed_position); return TRUE; } @@ -1996,9 +2031,9 @@ boolean HandleGadgets(int mx, int my, int button) gi->event.type = GD_EVENT_MOVING; gi->event.off_borders = gadget_moving_off_borders; - if (gi->event_mask & GD_EVENT_MOVING && changed_position && + if (gi->event_mask & GD_EVENT_MOVING && (gadget_moving_inside || gi->event_mask & GD_EVENT_OFF_BORDERS)) - gi->callback_action(gi); + DoGadgetCallbackAction(gi, changed_position); } if (gadget_released_inside) @@ -2030,10 +2065,8 @@ boolean HandleGadgets(int mx, int my, int button) gi->state = GD_BUTTON_UNPRESSED; gi->event.type = GD_EVENT_RELEASED; - if ((gi->event_mask & GD_EVENT_RELEASED) && gadget_changed) - { - gi->callback_action(gi); - } + if ((gi->event_mask & GD_EVENT_RELEASED)) + DoGadgetCallbackAction(gi, gadget_changed); } if (gadget_released_off_borders) @@ -2082,7 +2115,11 @@ boolean HandleGadgetsKeyInput(Key key) gi->type & GD_TYPE_SELECTBOX)) return FALSE; - if (key == KSYM_Return) /* valid for both text input and selectbox */ + if (key == KSYM_Escape) + { + StopTextInput(); + } + else if (key == KSYM_Return) /* valid for both text input and selectbox */ { boolean gadget_changed = ((gi->event_mask & GD_EVENT_TEXT_RETURN) != 0); @@ -2094,6 +2131,8 @@ boolean HandleGadgetsKeyInput(Key key) strcpy(gi->textinput.last_value, gi->textinput.value); else gadget_changed = FALSE; + + StopTextInput(); } else if (gi->type & GD_TYPE_SELECTBOX) { @@ -2118,8 +2157,7 @@ boolean HandleGadgetsKeyInput(Key key) last_gi = NULL; } - if (gadget_changed) - gi->callback_action(gi); + DoGadgetCallbackAction(gi, gadget_changed); } else if (gi->type & GD_TYPE_TEXT_INPUT) /* only valid for text input */ { @@ -2249,3 +2287,43 @@ boolean HandleGadgetsKeyInput(Key key) return TRUE; } + +void DumpGadgetIdentifiers(void) +{ + struct GadgetInfo *gi; + + Print("Gadgets on current screen:\n"); + + for (gi = gadget_list_first_entry; gi != NULL; gi = gi->next) + { + if (gi->mapped && gi->image_id != -1) + { + char *token = getTokenFromImageID(gi->image_id); + char *prefix = "gfx."; + + if (strPrefix(token, prefix)) + token = &token[strlen(prefix)]; + + Print("- '%s'\n", token); + } + } + + Print("Done.\n"); +} + +boolean DoGadgetAction(int image_id) +{ + struct GadgetInfo *gi; + + for (gi = gadget_list_first_entry; gi != NULL; gi = gi->next) + { + if (gi->mapped && gi->image_id == image_id) + { + gi->callback_action(gi); + + return TRUE; + } + } + + return FALSE; +}