{
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;
}
}
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;
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;
}
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() ||
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;
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 */
last_gi->callback_action(last_gi);
last_gi = NULL;
+
+ if (gadget_pressed_inside_select_line)
+ new_gi = NULL;
}
gadget_pressed =
{
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
{
/* 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;
}
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;
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;
}