X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fgadgets.c;h=3431719caeb799898974860d5982cced01e4df71;hb=5a2237add0a19d1559c0fe20c3f27651a71adf6c;hp=55174eef8b749c09812f870cd7d2059d33f11205;hpb=274935f49f49068998ad7b4ed9d93892aedfc6aa;p=rocksndiamonds.git diff --git a/src/libgame/gadgets.c b/src/libgame/gadgets.c index 55174eef..3431719c 100644 --- a/src/libgame/gadgets.c +++ b/src/libgame/gadgets.c @@ -105,8 +105,6 @@ static struct GadgetInfo *getGadgetInfoFromMousePosition(int mx, int my) return NULL; } -#if 1 - static void setTextAreaCursorExt(struct GadgetInfo *gi, boolean set_cursor_pos) { char *text = gi->textarea.value; @@ -147,15 +145,6 @@ static void setTextAreaCursorExt(struct GadgetInfo *gi, boolean set_cursor_pos) pos++; } - if (y >= area_ysize) - { - x = area_xsize - 1; - } - -#if 0 - printf("::: %d, %d [%d]\n", cursor_x, cursor_y, cursor_position); -#endif - gi->textarea.cursor_x = x; gi->textarea.cursor_y = y; gi->textarea.cursor_x_preferred = x; @@ -177,98 +166,6 @@ static void setTextAreaCursorPosition(struct GadgetInfo *gi, int pos) setTextAreaCursorExt(gi, FALSE); } -#else - -static void setTextAreaCursorPosition(struct GadgetInfo *gi, int x, int y) -{ - char *text = gi->textarea.value; - int area_xsize = gi->textarea.xsize; - int area_ysize = gi->textarea.ysize; - int cursor_x = 0; - int cursor_y = 0; - int cursor_position = 0; - - while (*text && cursor_y < area_ysize) - { - char buffer[MAX_OUTPUT_LINESIZE + 1]; - int i; - - for (i=0; i < area_xsize && *text && *text != '\n'; i++) - buffer[i] = *text++; - buffer[i] = '\0'; - -#if 1 - if (i == 0 && *text == '\n') - { - text++; - cursor_position++; - } -#endif - - if (x == -1 && y == -1) /* get x/y from cursor position */ - { - if (cursor_position + i >= gi->textarea.cursor_position) - { -#if 0 - printf("::: cursor: %d + %d >= %d\n", cursor_position, i, - gi->textarea.cursor_position); -#endif - - cursor_x = gi->textarea.cursor_position - cursor_position; - cursor_position = gi->textarea.cursor_position; - - break; - } - } - - if (cursor_y == y || !*text) /* correct y position found */ - { - cursor_x = MIN(i, x); - cursor_position += cursor_x; - - break; - } - else - cursor_position += i; - -#if 0 - if (*text == '\n') - { - text++; - cursor_position++; - - if (i == area_xsize) - cursor_y++; - } -#endif - - cursor_y++; - } - - if (cursor_x >= area_xsize) - { - cursor_x = 0; - cursor_y++; - } - - if (cursor_y >= area_ysize) - { - cursor_x = area_xsize - 1; - cursor_y = area_ysize - 1; - } - -#if 0 - printf("::: %d, %d [%d]\n", cursor_x, cursor_y, cursor_position); -#endif - - gi->textarea.cursor_x = cursor_x; - gi->textarea.cursor_y = cursor_y; - gi->textarea.cursor_x_preferred = cursor_x; - gi->textarea.cursor_position = cursor_position; -} - -#endif - static void default_callback_info(void *ptr) { return; @@ -378,11 +275,6 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) cursor_string[0] = (cursor_letter != '\0' ? cursor_letter : ' '); cursor_string[1] = '\0'; -#if 0 - if (pressed) - printf("::: PRESSED!\n"); -#endif - /* draw cursor, if active */ if (pressed) DrawTextExt(drawto, @@ -466,21 +358,14 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) /* gadget text value */ DrawTextToTextArea(gi->x + border_x, gi->y + border_y, - gi->textarea.value, font_nr, - gi->textarea.xsize, gi->textarea.ysize); + gi->textarea.value, font_nr, gi->textarea.xsize, + gi->textarea.xsize, gi->textarea.ysize, + BLIT_ON_BACKGROUND); cursor_letter = gi->textarea.value[gi->textarea.cursor_position]; cursor_string[0] = (cursor_letter != '\0' ? cursor_letter : ' '); cursor_string[1] = '\0'; -#if 0 - printf("::: '%s' [%d, %d] [%d] [%d -> '%s']\n", - gi->textarea.value, - gi->textarea.cursor_x, gi->textarea.cursor_y, - gi->textarea.cursor_position, - pressed, cursor_string); -#endif - /* draw cursor, if active */ if (pressed) DrawTextExt(drawto, @@ -635,7 +520,10 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) /* selectbox text values */ for (i=0; i < gi->selectbox.num_values; i++) { - int mask_mode; + int mask_mode = BLIT_MASKED; + + strncpy(text, gi->selectbox.options[i].text, gi->selectbox.size); + text[gi->selectbox.size] = '\0'; if (i == gi->selectbox.current_index) { @@ -645,17 +533,11 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) gi->selectbox.width - 2 * border_x, font_height, gi->selectbox.inverse_color); - strncpy(text, gi->selectbox.options[i].text, gi->selectbox.size); - text[1 + gi->selectbox.size] = '\0'; - - mask_mode = BLIT_INVERSE; - } - else - { - strncpy(text, gi->selectbox.options[i].text, gi->selectbox.size); + /* prevent use of cursor graphic by drawing at least two chars */ + strcat(text, " "); text[gi->selectbox.size] = '\0'; - mask_mode = BLIT_MASKED; + mask_mode = BLIT_INVERSE; } DrawTextExt(drawto, @@ -670,15 +552,15 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) { gi->selectbox.open = FALSE; - /* redraw closed selectbox */ - DrawGadget(gi, FALSE, FALSE); - /* restore background under selectbox */ BlitBitmap(gfx.field_save_buffer, drawto, gi->selectbox.x, gi->selectbox.y, gi->selectbox.width, gi->selectbox.height, gi->selectbox.x, gi->selectbox.y); + /* redraw closed selectbox */ + DrawGadget(gi, FALSE, FALSE); + redraw_selectbox = TRUE; } } @@ -707,7 +589,7 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) xpos, ypos); /* middle part of gadget */ - for (i=0; ibitmap, drawto, gd->x, gd->y + gi->border.ysize, gi->width, design_body, @@ -754,7 +636,7 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) xpos, ypos); /* middle part of gadget */ - for (i=0; ibitmap, drawto, gd->x + gi->border.xsize, gd->y, design_body, gi->height, @@ -799,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; @@ -878,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; @@ -887,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; @@ -896,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; @@ -907,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; @@ -923,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; @@ -1103,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; } @@ -1400,6 +1324,22 @@ static boolean anySelectboxGadgetActive() return (last_gi && (last_gi->type & GD_TYPE_SELECTBOX) && last_gi->mapped); } +static boolean insideSelectboxLine(struct GadgetInfo *gi, int mx, int my) +{ + return(gi != NULL && + gi->type & GD_TYPE_SELECTBOX && + mx >= gi->x && mx < gi->x + gi->width && + my >= gi->y && my < gi->y + gi->height); +} + +static boolean insideSelectboxArea(struct GadgetInfo *gi, int mx, int my) +{ + return(gi != NULL && + gi->type & GD_TYPE_SELECTBOX && + mx >= gi->selectbox.x && mx < gi->selectbox.x + gi->selectbox.width && + my >= gi->selectbox.y && my < gi->selectbox.y + gi->selectbox.height); +} + boolean anyTextGadgetActive() { return (anyTextInputGadgetActive() || @@ -1409,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); @@ -1420,19 +1363,25 @@ void ClickOnGadget(struct GadgetInfo *gi, int button) HandleGadgets(gi->x, gi->y, 0); } -void HandleGadgets(int mx, int my, int button) +boolean HandleGadgets(int mx, int my, int button) { static struct GadgetInfo *last_info_gi = NULL; static unsigned long pressed_delay = 0; static int last_button = 0; static int last_mx = 0, last_my = 0; + static int pressed_mx = 0, pressed_my = 0; int scrollbar_mouse_pos = 0; struct GadgetInfo *new_gi, *gi; boolean press_event; boolean release_event; boolean mouse_moving; + boolean mouse_inside_select_line; + boolean mouse_inside_select_area; + boolean mouse_released_where_pressed; boolean gadget_pressed; boolean gadget_pressed_repeated; + boolean gadget_pressed_off_borders; + boolean gadget_pressed_inside_select_line; boolean gadget_moving; boolean gadget_moving_inside; boolean gadget_moving_off_borders; @@ -1445,7 +1394,7 @@ void HandleGadgets(int mx, int my, int button) /* check if there are any gadgets defined */ if (gadget_list_first_entry == NULL) - return; + return FALSE; /* simulated release of mouse button over last gadget */ if (mx == -1 && my == -1 && button == 0) @@ -1467,191 +1416,71 @@ void HandleGadgets(int mx, int my, int button) last_mx = mx; last_my = my; -#if 1 - -#if 1 - - /* if mouse button pressed outside text or selectbox gadget, deactivate it */ - if (anyTextGadgetActive() && - button != 0 && !motion_status && new_gi != last_gi) + if (press_event && new_gi != last_gi) { - CheckRangeOfNumericInputGadget(last_gi); /* in case of numeric gadget */ - - DrawGadget(last_gi, DG_UNPRESSED, last_gi->direct_draw); - - last_gi->event.type = GD_EVENT_TEXT_LEAVING; - - if (last_gi->event_mask & GD_EVENT_TEXT_LEAVING) - last_gi->callback_action(last_gi); - - last_gi = NULL; + pressed_mx = mx; + pressed_my = my; } -#else - - /* special treatment for leaving text and number input gadgets */ - if (anyTextInputGadgetActive() && - button != 0 && !motion_status && new_gi != last_gi) - { - /* if mouse button pressed outside text input gadget, deactivate it */ - CheckRangeOfNumericInputGadget(last_gi); - DrawGadget(last_gi, DG_UNPRESSED, last_gi->direct_draw); + mouse_released_where_pressed = + (release_event && mx == pressed_mx && my == pressed_my); - last_gi->event.type = GD_EVENT_TEXT_LEAVING; + mouse_inside_select_line = insideSelectboxLine(new_gi, mx, my); + mouse_inside_select_area = insideSelectboxArea(new_gi, mx, my); - if (last_gi->event_mask & GD_EVENT_TEXT_LEAVING) - last_gi->callback_action(last_gi); - - last_gi = NULL; - } - - /* special treatment for leaving text area gadgets */ - if (anyTextAreaGadgetActive() && - button != 0 && !motion_status && new_gi != last_gi) - { - /* if mouse button pressed outside text input gadget, deactivate it */ - DrawGadget(last_gi, DG_UNPRESSED, last_gi->direct_draw); + gadget_pressed_off_borders = (press_event && new_gi != last_gi); - last_gi->event.type = GD_EVENT_TEXT_LEAVING; + gadget_pressed_inside_select_line = + (press_event && new_gi != NULL && + new_gi->type & GD_TYPE_SELECTBOX && new_gi->selectbox.open && + insideSelectboxLine(new_gi, mx, my)); - if (last_gi->event_mask & GD_EVENT_TEXT_LEAVING) - last_gi->callback_action(last_gi); - - last_gi = NULL; - } - - /* special treatment for leaving selectbox gadgets */ - if (anySelectboxGadgetActive() && + /* if mouse button pressed outside text or selectbox gadget, deactivate it */ +#if 1 + if (anyTextGadgetActive() && + (gadget_pressed_off_borders || + (gadget_pressed_inside_select_line && !mouse_inside_select_area))) +#else + if (anyTextGadgetActive() && button != 0 && !motion_status && new_gi != last_gi) - { - /* if mouse button pressed outside selectbox gadget, deactivate it */ - DrawGadget(last_gi, DG_UNPRESSED, last_gi->direct_draw); - - last_gi->event.type = GD_EVENT_TEXT_LEAVING; - - if (last_gi->event_mask & GD_EVENT_TEXT_LEAVING) - last_gi->callback_action(last_gi); - - last_gi = NULL; - } - #endif - -#else - - /* special treatment for text and number input gadgets */ - if (anyTextInputGadgetActive() && button != 0 && !motion_status) { struct GadgetInfo *gi = last_gi; + boolean gadget_changed = (gi->event_mask & GD_EVENT_TEXT_LEAVING); - if (new_gi == last_gi) - { - int old_cursor_position = gi->textinput.cursor_position; - - /* if mouse button pressed inside activated text gadget, set cursor */ - gi->textinput.cursor_position = - (mx - gi->x - gi->border.xsize) / getFontWidth(gi->font); - - if (gi->textinput.cursor_position < 0) - gi->textinput.cursor_position = 0; - else if (gi->textinput.cursor_position > strlen(gi->textinput.value)) - gi->textinput.cursor_position = strlen(gi->textinput.value); - - if (gi->textinput.cursor_position != old_cursor_position) - DrawGadget(gi, DG_PRESSED, gi->direct_draw); - } - else + /* check if text gadget has changed its value */ + if (gi->type & GD_TYPE_TEXT_INPUT) { - /* if mouse button pressed outside text input gadget, deactivate it */ CheckRangeOfNumericInputGadget(gi); - DrawGadget(gi, DG_UNPRESSED, gi->direct_draw); - - gi->event.type = GD_EVENT_TEXT_LEAVING; - if (gi->event_mask & GD_EVENT_TEXT_LEAVING) - gi->callback_action(gi); - - last_gi = NULL; + if (strcmp(gi->textinput.value, gi->textinput.last_value) != 0) + strcpy(gi->textinput.last_value, gi->textinput.value); + else + gadget_changed = FALSE; } - } - /* special treatment for text area gadgets */ - if (anyTextAreaGadgetActive() && button != 0 && !motion_status) - { - struct GadgetInfo *gi = last_gi; - - if (new_gi == last_gi) - { - int old_cursor_position = gi->textarea.cursor_position; - int x = (mx - gi->x - gi->border.xsize) / getFontWidth(gi->font); - int y = (my - gi->y - gi->border.ysize) / getFontHeight(gi->font); + /* selectbox does not change its value when closed by clicking outside */ + if (gi->type & GD_TYPE_SELECTBOX) + gadget_changed = FALSE; - x = (x < 0 ? 0 : x >= gi->textarea.xsize ? gi->textarea.xsize - 1 : x); - y = (y < 0 ? 0 : y >= gi->textarea.ysize ? gi->textarea.ysize - 1 : y); + DrawGadget(gi, DG_UNPRESSED, gi->direct_draw); - setTextAreaCursorXY(gi, x, y); + gi->event.type = GD_EVENT_TEXT_LEAVING; -#if 0 - printf("::: %d -----> %d\n", - old_cursor_position, - gi->textarea.cursor_position); +#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 - if (gi->textarea.cursor_position != old_cursor_position) - DrawGadget(gi, DG_PRESSED, gi->direct_draw); - } - else - { - /* if mouse button pressed outside text input gadget, deactivate it */ - DrawGadget(gi, DG_UNPRESSED, gi->direct_draw); - - gi->event.type = GD_EVENT_TEXT_LEAVING; - - if (gi->event_mask & GD_EVENT_TEXT_LEAVING) - gi->callback_action(gi); - - last_gi = NULL; - } - } - - /* special treatment for selectbox gadgets */ - if (anySelectboxGadgetActive() && button != 0 && !motion_status) - { - struct GadgetInfo *gi = last_gi; - - if (new_gi == last_gi) - { - int old_index = gi->selectbox.current_index; - - /* if mouse button pressed inside activated selectbox, select value */ - if (my >= gi->selectbox.y && my < gi->selectbox.y + gi->selectbox.height) - gi->selectbox.current_index = - (my - gi->selectbox.y - gi->border.ysize) / getFontHeight(gi->font); - - if (gi->selectbox.current_index < 0) - gi->selectbox.current_index = 0; - else if (gi->selectbox.current_index > gi->selectbox.num_values - 1) - gi->selectbox.current_index = gi->selectbox.num_values - 1; - - if (gi->selectbox.current_index != old_index) - DrawGadget(gi, DG_PRESSED, gi->direct_draw); - } - else - { - /* if mouse button pressed outside selectbox gadget, deactivate it */ - DrawGadget(gi, DG_UNPRESSED, gi->direct_draw); - - gi->event.type = GD_EVENT_TEXT_LEAVING; - - if (gi->event_mask & GD_EVENT_TEXT_LEAVING) - gi->callback_action(gi); + last_gi = NULL; - last_gi = NULL; - } + if (gadget_pressed_inside_select_line) + new_gi = NULL; } -#endif - gadget_pressed = (button != 0 && last_gi == NULL && new_gi != NULL && press_event); gadget_pressed_repeated = @@ -1670,12 +1499,17 @@ void HandleGadgets(int mx, int my, int button) { struct GadgetInfo *gi = last_gi; +#if 1 + gadget_released_inside_select_line = insideSelectboxLine(gi, mx, my); + gadget_released_inside_select_area = insideSelectboxArea(gi, mx, my); +#else gadget_released_inside_select_line = (mx >= gi->x && mx < gi->x + gi->width && my >= gi->y && my < gi->y + gi->height); gadget_released_inside_select_area = (mx >= gi->selectbox.x && mx < gi->selectbox.x + gi->selectbox.width && my >= gi->selectbox.y && my < gi->selectbox.y + gi->selectbox.height); +#endif } else { @@ -1698,12 +1532,23 @@ void HandleGadgets(int mx, int my, int button) /* if mouse button released, no gadget needs to be handled anymore */ if (gadget_released) { - if (last_gi->type & GD_TYPE_SELECTBOX && +#if 1 + if (gi->type & GD_TYPE_SELECTBOX && + (mouse_released_where_pressed || + !gadget_released_inside_select_area)) /* selectbox stays open */ + { + gi->selectbox.stay_open = TRUE; + pressed_mx = 0; + pressed_my = 0; + } +#else + if (gi->type & GD_TYPE_SELECTBOX && (gadget_released_inside_select_line || gadget_released_off_borders)) /* selectbox stays open */ gi->selectbox.stay_open = TRUE; - else if (!(last_gi->type & GD_TYPE_TEXT_INPUT || - last_gi->type & GD_TYPE_TEXT_AREA)) /* text input stays open */ +#endif + else if (!(gi->type & GD_TYPE_TEXT_INPUT || + gi->type & GD_TYPE_TEXT_AREA)) /* text input stays open */ last_gi = NULL; } @@ -1757,7 +1602,7 @@ void HandleGadgets(int mx, int my, int button) if (gi->textarea.cursor_position != old_cursor_position) DrawGadget(gi, DG_PRESSED, gi->direct_draw); } - else if (gi->type & GD_TYPE_SELECTBOX) + else if (gi->type & GD_TYPE_SELECTBOX && gi->selectbox.open) { int old_index = gi->selectbox.current_index; @@ -1789,15 +1634,6 @@ void HandleGadgets(int mx, int my, int button) { last_info_gi->event.type = GD_EVENT_INFO_LEAVING; last_info_gi->callback_info(last_info_gi); - -#if 0 - default_callback_info(NULL); - - printf("It seems that we are leaving gadget [%s]!\n", - (last_info_gi != NULL && - last_info_gi->info_text != NULL ? - last_info_gi->info_text : "")); -#endif } last_info_gi = new_gi; @@ -1887,11 +1723,10 @@ void HandleGadgets(int mx, int my, int button) /* don't handle this scrollbar anymore while mouse button pressed */ last_gi = NULL; - return; + return TRUE; } } - /* !!! bad for TEXT_INPUT ... !!! */ DrawGadget(gi, DG_PRESSED, gi->direct_draw); gi->state = GD_BUTTON_PRESSED; @@ -1906,11 +1741,6 @@ void HandleGadgets(int mx, int my, int button) gi->callback_action(gi); } -#if 0 - if (!mouse_moving) - printf("::: PRESSED...?\n"); -#endif - if (gadget_pressed_repeated) { gi->event.type = GD_EVENT_PRESSED; @@ -1988,14 +1818,29 @@ void 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 */ + gadget_released_off_borders) /* selectbox stays open */ + { deactivate_gadget = FALSE; - else + gadget_changed = FALSE; + } +#endif + else if (gi->selectbox.index != gi->selectbox.current_index) gi->selectbox.index = gi->selectbox.current_index; + else + gadget_changed = FALSE; } if (deactivate_gadget && @@ -2006,8 +1851,15 @@ void 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) @@ -2025,6 +1877,9 @@ void HandleGadgets(int mx, int my, int button) /* handle gadgets unmapped/mapped between pressing and releasing */ if (release_event && !gadget_released && new_gi) new_gi->state = GD_BUTTON_UNPRESSED; + + return (gadget_pressed || gadget_pressed_repeated || + gadget_released || gadget_moving); } static void insertCharIntoTextArea(struct GadgetInfo *gi, char c) @@ -2035,22 +1890,14 @@ static void insertCharIntoTextArea(struct GadgetInfo *gi, char c) if (strlen(gi->textarea.value) == MAX_GADGET_TEXTSIZE) /* no space left */ return; -#if 0 - printf("::: '%s' + '%c'", gi->textarea.value, c); -#endif - strcpy(text, gi->textarea.value); strcpy(&gi->textarea.value[cursor_position + 1], &text[cursor_position]); gi->textarea.value[cursor_position] = c; -#if 0 - printf(" => '%s'\n", gi->textarea.value); -#endif - setTextAreaCursorPosition(gi, gi->textarea.cursor_position + 1); } -void HandleGadgetsKeyInput(Key key) +boolean HandleGadgetsKeyInput(Key key) { struct GadgetInfo *gi = last_gi; @@ -2058,14 +1905,28 @@ void HandleGadgetsKeyInput(Key key) !(gi->type & GD_TYPE_TEXT_INPUT || gi->type & GD_TYPE_TEXT_AREA || gi->type & GD_TYPE_SELECTBOX)) - return; + return FALSE; 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) { @@ -2082,8 +1943,13 @@ void 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 */ { @@ -2143,10 +2009,6 @@ void HandleGadgetsKeyInput(Key key) char letter = getCharFromKey(key); boolean legal_letter = (letter != 0); -#if 0 - printf("::: KEY: %x!\n", key); -#endif - if (legal_letter) { insertCharIntoTextArea(gi, letter); @@ -2214,4 +2076,6 @@ void HandleGadgetsKeyInput(Key key) DrawGadget(gi, DG_PRESSED, gi->direct_draw); } } + + return TRUE; }