X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fgadgets.c;h=3431719caeb799898974860d5982cced01e4df71;hb=095207353ef58a65f5146e6ddc7eefb51bfe0f55;hp=a97fe3bd2b636e04b45a711f87c3a6b07f36518f;hpb=bf1e4db1ffa9a313b8d1b68e55633ace682fef96;p=rocksndiamonds.git diff --git a/src/libgame/gadgets.c b/src/libgame/gadgets.c index a97fe3bd..3431719c 100644 --- a/src/libgame/gadgets.c +++ b/src/libgame/gadgets.c @@ -681,6 +681,22 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) gi->y > gfx.vy ? REDRAW_DOOR_2 : REDRAW_DOOR_3); } +static int get_minimal_size_for_numeric_input(int minmax_value) +{ + int min_size = 1; /* value needs at least one digit */ + int i; + + /* add number of digits needed for absolute value */ + for (i = 10; i <= ABS(minmax_value); i *= 10) + min_size++; + + /* if min/max value is negative, add one digit for minus sign */ + if (minmax_value < 0) + min_size++; + + return min_size; +} + static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) { int tag = first_tag; @@ -760,6 +776,7 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) case GDI_NUMBER_VALUE: gi->textinput.number_value = va_arg(ap, long); sprintf(gi->textinput.value, "%d", gi->textinput.number_value); + strcpy(gi->textinput.last_value, gi->textinput.value); gi->textinput.cursor_position = strlen(gi->textinput.value); break; @@ -769,6 +786,7 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) { gi->textinput.number_value = gi->textinput.number_min; sprintf(gi->textinput.value, "%d", gi->textinput.number_value); + strcpy(gi->textinput.last_value, gi->textinput.value); } break; @@ -778,6 +796,7 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) { gi->textinput.number_value = gi->textinput.number_max; sprintf(gi->textinput.value, "%d", gi->textinput.number_value); + strcpy(gi->textinput.last_value, gi->textinput.value); } break; @@ -789,12 +808,15 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) max_textsize = MIN(gi->textinput.size, MAX_GADGET_TEXTSIZE - 1); strncpy(gi->textinput.value, va_arg(ap, char *), max_textsize); + strcpy(gi->textinput.last_value, gi->textinput.value); + gi->textinput.value[max_textsize] = '\0'; gi->textinput.cursor_position = strlen(gi->textinput.value); /* same tag also used for other gadget definitions */ strcpy(gi->textbutton.value, gi->textinput.value); strcpy(gi->textarea.value, gi->textinput.value); + strcpy(gi->textarea.last_value, gi->textinput.value); } break; @@ -805,10 +827,17 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) gi->textinput.size = max_textsize; gi->textinput.value[max_textsize] = '\0'; + strcpy(gi->textinput.last_value, gi->textinput.value); /* same tag also used for other gadget definitions */ - strcpy(gi->textbutton.value, gi->textinput.value); - gi->textbutton.size = gi->textinput.size; + + gi->textarea.size = max_textsize; + gi->textarea.value[max_textsize] = '\0'; + strcpy(gi->textarea.last_value, gi->textinput.value); + + gi->textbutton.size = max_textsize; + gi->textbutton.value[max_textsize] = '\0'; + gi->selectbox.size = gi->textinput.size; } break; @@ -985,6 +1014,19 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) int border_xsize = gi->border.xsize; int border_ysize = gi->border.ysize; + if (gi->type == GD_TYPE_TEXT_INPUT_NUMERIC) + { + int number_min = gi->textinput.number_min; + int number_max = gi->textinput.number_max; + int min_size_min = get_minimal_size_for_numeric_input(number_min); + int min_size_max = get_minimal_size_for_numeric_input(number_max); + int min_size = MAX(min_size_min, min_size_max); + + /* expand gadget text input size, if maximal value is too large */ + if (gi->textinput.size < min_size) + gi->textinput.size = min_size; + } + gi->width = 2 * border_xsize + (gi->textinput.size + 1) * font_width; gi->height = 2 * border_ysize + font_height; } @@ -1307,6 +1349,9 @@ boolean anyTextGadgetActive() void ClickOnGadget(struct GadgetInfo *gi, int button) { + if (!gi->mapped) + return; + /* simulate releasing mouse button over last gadget, if still pressed */ if (button_status) HandleGadgets(-1, -1, 0); @@ -1400,14 +1445,35 @@ boolean HandleGadgets(int mx, int my, int button) button != 0 && !motion_status && new_gi != last_gi) #endif { - CheckRangeOfNumericInputGadget(last_gi); /* in case of numeric gadget */ + struct GadgetInfo *gi = last_gi; + boolean gadget_changed = (gi->event_mask & GD_EVENT_TEXT_LEAVING); + + /* check if text gadget has changed its value */ + if (gi->type & GD_TYPE_TEXT_INPUT) + { + CheckRangeOfNumericInputGadget(gi); - DrawGadget(last_gi, DG_UNPRESSED, last_gi->direct_draw); + if (strcmp(gi->textinput.value, gi->textinput.last_value) != 0) + strcpy(gi->textinput.last_value, gi->textinput.value); + else + gadget_changed = FALSE; + } + + /* selectbox does not change its value when closed by clicking outside */ + if (gi->type & GD_TYPE_SELECTBOX) + gadget_changed = FALSE; - last_gi->event.type = GD_EVENT_TEXT_LEAVING; + DrawGadget(gi, DG_UNPRESSED, gi->direct_draw); - if (last_gi->event_mask & GD_EVENT_TEXT_LEAVING) - last_gi->callback_action(last_gi); + gi->event.type = GD_EVENT_TEXT_LEAVING; + +#if 1 + if (gadget_changed && !(gi->type & GD_TYPE_SELECTBOX)) + gi->callback_action(gi); +#else + if (gi->event_mask & GD_EVENT_TEXT_LEAVING) + gi->callback_action(gi); +#endif last_gi = NULL; @@ -1752,20 +1818,29 @@ boolean HandleGadgets(int mx, int my, int button) if (gadget_released_inside) { boolean deactivate_gadget = TRUE; + boolean gadget_changed = TRUE; if (gi->type & GD_TYPE_SELECTBOX) { #if 1 if (mouse_released_where_pressed || !gadget_released_inside_select_area) /* selectbox stays open */ + { deactivate_gadget = FALSE; + gadget_changed = FALSE; + } #else if (gadget_released_inside_select_line || gadget_released_off_borders) /* selectbox stays open */ + { deactivate_gadget = FALSE; + gadget_changed = FALSE; + } #endif - else + else if (gi->selectbox.index != gi->selectbox.current_index) gi->selectbox.index = gi->selectbox.current_index; + else + gadget_changed = FALSE; } if (deactivate_gadget && @@ -1776,8 +1851,15 @@ boolean HandleGadgets(int mx, int my, int button) gi->state = GD_BUTTON_UNPRESSED; gi->event.type = GD_EVENT_RELEASED; +#if 1 + if ((gi->event_mask & GD_EVENT_RELEASED) && gadget_changed) + { + gi->callback_action(gi); + } +#else if ((gi->event_mask & GD_EVENT_RELEASED) && deactivate_gadget) gi->callback_action(gi); +#endif } if (gadget_released_off_borders) @@ -1827,10 +1909,24 @@ boolean HandleGadgetsKeyInput(Key key) if (key == KSYM_Return) /* valid for both text input and selectbox */ { + boolean gadget_changed = (gi->event_mask & GD_EVENT_TEXT_RETURN); + if (gi->type & GD_TYPE_TEXT_INPUT) + { CheckRangeOfNumericInputGadget(gi); + + if (strcmp(gi->textinput.value, gi->textinput.last_value) != 0) + strcpy(gi->textinput.last_value, gi->textinput.value); + else + gadget_changed = FALSE; + } else if (gi->type & GD_TYPE_SELECTBOX) - gi->selectbox.index = gi->selectbox.current_index; + { + if (gi->selectbox.index != gi->selectbox.current_index) + gi->selectbox.index = gi->selectbox.current_index; + else + gadget_changed = FALSE; + } if (gi->type & GD_TYPE_TEXT_AREA) { @@ -1847,8 +1943,13 @@ boolean HandleGadgetsKeyInput(Key key) last_gi = NULL; } +#if 1 + if (gadget_changed) + gi->callback_action(gi); +#else if (gi->event_mask & GD_EVENT_TEXT_RETURN) gi->callback_action(gi); +#endif } else if (gi->type & GD_TYPE_TEXT_INPUT) /* only valid for text input */ {