X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Flibgame%2Fgadgets.c;h=a97fe3bd2b636e04b45a711f87c3a6b07f36518f;hb=564a563aee2c9fdb37116d41342b36eda63c1f6a;hp=55174eef8b749c09812f870cd7d2059d33f11205;hpb=274935f49f49068998ad7b4ed9d93892aedfc6aa;p=rocksndiamonds.git diff --git a/src/libgame/gadgets.c b/src/libgame/gadgets.c index 55174eef..a97fe3bd 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, @@ -1400,6 +1282,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() || @@ -1420,19 +1318,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 +1349,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,64 +1371,37 @@ 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); + gadget_pressed_off_borders = (press_event && new_gi != last_gi); - last_gi = NULL; - } + 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)); - /* special treatment for leaving text area gadgets */ - if (anyTextAreaGadgetActive() && + /* 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) +#endif { - /* if mouse button pressed outside text input 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; - } + CheckRangeOfNumericInputGadget(last_gi); /* in case of numeric gadget */ - /* special treatment for leaving selectbox gadgets */ - if (anySelectboxGadgetActive() && - 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; @@ -1533,125 +1410,11 @@ void HandleGadgets(int mx, int my, int button) 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; - - 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 - { - /* 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; - } - } - - /* 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); - - 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); - - setTextAreaCursorXY(gi, x, y); - -#if 0 - printf("::: %d -----> %d\n", - old_cursor_position, - gi->textarea.cursor_position); -#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; - } + if (gadget_pressed_inside_select_line) + new_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; - } - } - -#endif - gadget_pressed = (button != 0 && last_gi == NULL && new_gi != NULL && press_event); gadget_pressed_repeated = @@ -1670,12 +1433,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 +1466,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 +1536,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 +1568,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 +1657,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 +1675,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; @@ -1991,9 +1755,15 @@ void HandleGadgets(int mx, int my, int button) if (gi->type & GD_TYPE_SELECTBOX) { +#if 1 + if (mouse_released_where_pressed || + !gadget_released_inside_select_area) /* selectbox stays open */ + deactivate_gadget = 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; +#endif else gi->selectbox.index = gi->selectbox.current_index; } @@ -2025,6 +1795,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 +1808,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,7 +1823,7 @@ 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 */ { @@ -2143,10 +1908,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 +1975,6 @@ void HandleGadgetsKeyInput(Key key) DrawGadget(gi, DG_PRESSED, gi->direct_draw); } } + + return TRUE; }