X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fgadgets.c;h=8601256cbf3ed1b2da04be5a9422d40f62bf6efd;hb=c5b6de1f19f2c87f70b208794375b284e035cb80;hp=ddc5ac6016e98877dade4bc05699ed682fc4ad05;hpb=2a357b702b5ceb9bf9173ac02f68cf42340b3158;p=rocksndiamonds.git diff --git a/src/libgame/gadgets.c b/src/libgame/gadgets.c index ddc5ac60..8601256c 100644 --- a/src/libgame/gadgets.c +++ b/src/libgame/gadgets.c @@ -552,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; } } @@ -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; @@ -985,6 +1001,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; } @@ -1282,6 +1311,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() || @@ -1308,13 +1353,19 @@ boolean HandleGadgets(int mx, int my, int button) 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; @@ -1349,9 +1400,34 @@ boolean HandleGadgets(int mx, int my, int button) last_mx = mx; last_my = my; + if (press_event && new_gi != last_gi) + { + pressed_mx = mx; + pressed_my = my; + } + + mouse_released_where_pressed = + (release_event && mx == pressed_mx && my == pressed_my); + + mouse_inside_select_line = insideSelectboxLine(new_gi, mx, my); + mouse_inside_select_area = insideSelectboxArea(new_gi, mx, my); + + gadget_pressed_off_borders = (press_event && new_gi != last_gi); + + 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 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 { CheckRangeOfNumericInputGadget(last_gi); /* in case of numeric gadget */ @@ -1363,6 +1439,9 @@ boolean HandleGadgets(int mx, int my, int button) last_gi->callback_action(last_gi); last_gi = NULL; + + if (gadget_pressed_inside_select_line) + new_gi = NULL; } gadget_pressed = @@ -1383,12 +1462,17 @@ boolean 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 { @@ -1411,12 +1495,23 @@ boolean 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; } @@ -1470,7 +1565,7 @@ boolean 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; @@ -1689,9 +1784,15 @@ boolean 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; }