static struct GadgetInfo *gadget_list_first_entry = NULL;
static struct GadgetInfo *gadget_list_last_entry = NULL;
+static struct GadgetInfo *last_info_gi = NULL;
static int next_free_gadget_id = 1;
static boolean gadget_id_wrapped = FALSE;
static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct)
{
+ struct GadgetDesign *gd;
int state = (pressed ? GD_BUTTON_PRESSED : GD_BUTTON_UNPRESSED);
- struct GadgetDesign *gd = (!gi->active ? &gi->alt_design[state] :
- gi->checked ? &gi->alt_design[state] :
- &gi->design[state]);
boolean redraw_selectbox = FALSE;
+ if (gi == NULL)
+ return;
+
+ gd = (!gi->active ? &gi->alt_design[state] :
+ gi->checked ? &gi->alt_design[state] : &gi->design[state]);
+
switch (gi->type)
{
case GD_TYPE_NORMAL_BUTTON:
{
int tag = first_tag;
+ if (gi == NULL)
+ return;
+
while (tag != GDI_END)
{
switch(tag)
void RedrawGadget(struct GadgetInfo *gi)
{
+ if (gi == NULL)
+ return;
+
if (gi->mapped)
DrawGadget(gi, gi->state, gi->direct_draw);
}
{
struct GadgetInfo *gi_previous = gadget_list_first_entry;
+ /* prevent "last_info_gi" from pointing to memory that will be freed */
+ if (last_info_gi == gi)
+ last_info_gi = NULL;
+
while (gi_previous != NULL && gi_previous->next != gi)
gi_previous = gi_previous->next;
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;
+ static boolean keep_selectbox_open = FALSE;
int scrollbar_mouse_pos = 0;
struct GadgetInfo *new_gi, *gi;
boolean press_event;
{
CheckRangeOfNumericInputGadget(gi);
- if (strcmp(gi->textinput.value, gi->textinput.last_value) != 0)
+ if (!strEqual(gi->textinput.last_value, gi->textinput.value))
strcpy(gi->textinput.last_value, gi->textinput.value);
else
gadget_changed = FALSE;
gadget_released_inside_select_area = FALSE;
}
+ /* setting state for handling over-large selectbox */
+ if (keep_selectbox_open && (press_event || !mouse_inside_select_line))
+ keep_selectbox_open = FALSE;
+
/* if new gadget pressed, store this gadget */
if (gadget_pressed)
last_gi = new_gi;
if (gadget_released)
{
if (gi->type & GD_TYPE_SELECTBOX &&
- (mouse_released_where_pressed ||
- !gadget_released_inside_select_area)) /* selectbox stays open */
+ (keep_selectbox_open ||
+ mouse_released_where_pressed ||
+ !gadget_released_inside_select_area)) /* selectbox stays open */
{
gi->selectbox.stay_open = TRUE;
pressed_mx = 0;
if (gi->textarea.cursor_position != old_cursor_position)
DrawGadget(gi, DG_PRESSED, gi->direct_draw);
}
- else if (gi->type & GD_TYPE_SELECTBOX && gi->selectbox.open)
+ else if (gi->type & GD_TYPE_SELECTBOX && gi->selectbox.open &&
+ !keep_selectbox_open)
{
int old_index = gi->selectbox.current_index;
return TRUE;
}
}
+ else if (gi->type & GD_TYPE_SELECTBOX)
+ {
+ /* keep selectbox open in case of over-large selectbox */
+ keep_selectbox_open = (mouse_inside_select_line &&
+ mouse_inside_select_area);
+ }
DrawGadget(gi, DG_PRESSED, gi->direct_draw);
else if (gadget_moving_off_borders && gi->state == GD_BUTTON_PRESSED)
DrawGadget(gi, DG_UNPRESSED, gi->direct_draw);
}
- else if (gi->type & GD_TYPE_SELECTBOX)
+ else if (gi->type & GD_TYPE_SELECTBOX && !keep_selectbox_open)
{
int old_index = gi->selectbox.current_index;
if (gi->type & GD_TYPE_SELECTBOX)
{
- if (mouse_released_where_pressed ||
+ if (keep_selectbox_open ||
+ mouse_released_where_pressed ||
!gadget_released_inside_select_area) /* selectbox stays open */
{
deactivate_gadget = FALSE;
{
CheckRangeOfNumericInputGadget(gi);
- if (strcmp(gi->textinput.value, gi->textinput.last_value) != 0)
+ if (!strEqual(gi->textinput.last_value, gi->textinput.value))
strcpy(gi->textinput.last_value, gi->textinput.value);
else
gadget_changed = FALSE;