/* values for DrawGadget() */
#define DG_UNPRESSED 0
#define DG_PRESSED 1
+
#define DG_BUFFERED 0
#define DG_DIRECT 1
{
struct GadgetInfo *gi = gadget_list_first_entry;
- while (gi)
+ while (gi != NULL)
{
printf("-XXX-1-> '%s': %s\n",
gi->info_text, (gi->mapped ? "mapped" : "not mapped"));
static struct GadgetInfo *getGadgetInfoFromMousePosition(int mx, int my)
{
- struct GadgetInfo *gi = gadget_list_first_entry;
+ struct GadgetInfo *gi;
- while (gi)
+ /* open selectboxes may overlap other active gadgets, so check them first */
+ for (gi = gadget_list_first_entry; gi != NULL; gi = gi->next)
{
if (gi->mapped && gi->active &&
- ((mx >= gi->x && mx < gi->x + gi->width &&
- my >= gi->y && my < gi->y + gi->height) ||
- (gi->type & GD_TYPE_SELECTBOX && gi->selectbox.open &&
- mx >= gi->selectbox.x && mx < gi->selectbox.x+gi->selectbox.width &&
- my >= gi->selectbox.y && my < gi->selectbox.y+gi->selectbox.height)))
- break;
+ gi->type & GD_TYPE_SELECTBOX && gi->selectbox.open &&
+ mx >= gi->selectbox.x && mx < gi->selectbox.x + gi->selectbox.width &&
+ my >= gi->selectbox.y && my < gi->selectbox.y + gi->selectbox.height)
+ return gi;
+ }
- gi = gi->next;
+ /* check all other gadgets */
+ for (gi = gadget_list_first_entry; gi != NULL; gi = gi->next)
+ {
+ if (gi->mapped && gi->active &&
+ mx >= gi->x && mx < gi->x + gi->width &&
+ my >= gi->y && my < gi->y + gi->height)
+ return gi;
}
- return gi;
+ return NULL;
}
static void default_callback_info(void *ptr)
gi->active = (boolean)va_arg(ap, int);
break;
+ case GDI_DIRECT_DRAW:
+ /* take care here: "boolean" is typedef'ed as "unsigned char",
+ which gets promoted to "int" */
+ gi->direct_draw = (boolean)va_arg(ap, int);
+ break;
+
case GDI_CHECKED:
/* take care here: "boolean" is typedef'ed as "unsigned char",
which gets promoted to "int" */
int border_xsize = gi->border.xsize;
int border_ysize = gi->border.ysize;
int button_size = gi->border.xsize_selectbutton;
+ int bottom_screen_border = gfx.sy + gfx.sysize - font_height;
Bitmap *src_bitmap;
int src_x, src_y;
gi->selectbox.x = gi->x;
gi->selectbox.y = gi->y + gi->height;
- if (gi->selectbox.y + gi->selectbox.height > gfx.real_sy + gfx.full_sysize)
+ if (gi->selectbox.y + gi->selectbox.height > bottom_screen_border)
gi->selectbox.y = gi->y - gi->selectbox.height;
if (gi->selectbox.y < 0)
- gi->selectbox.y = gfx.real_sy + gfx.full_sysize - gi->selectbox.height;
+ gi->selectbox.y = bottom_screen_border - gi->selectbox.height;
getFontCharSource(font_nr, FONT_ASCII_CURSOR, &src_bitmap, &src_x, &src_y);
src_x += font_width / 2;
void RedrawGadget(struct GadgetInfo *gi)
{
if (gi->mapped)
- DrawGadget(gi, gi->state, DG_DIRECT);
+ DrawGadget(gi, gi->state, gi->direct_draw);
}
struct GadgetInfo *CreateGadget(int first_tag, ...)
new_gadget->callback_info = default_callback_info;
new_gadget->callback_action = default_callback_action;
new_gadget->active = TRUE;
+ new_gadget->direct_draw = TRUE;
+
new_gadget->next = NULL;
va_start(ap, first_tag);
static boolean map_state[MAX_NUM_GADGETS];
int map_count = 0;
- while (gi)
+ while (gi != NULL)
{
if ((mode & MULTIMAP_PLAYFIELD &&
gi->x < gfx.sx + gfx.sxsize) ||
if (gadget_list_first_entry == NULL)
return;
+ /* simulated release of mouse button over last gadget */
+ if (mx == -1 && my == -1 && button == 0)
+ {
+ mx = last_mx;
+ my = last_my;
+ }
+
/* check which gadget is under the mouse pointer */
new_gi = getGadgetInfoFromMousePosition(mx, my);
gi->text.cursor_position = strlen(gi->text.value);
if (gi->text.cursor_position != old_cursor_position)
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ DrawGadget(gi, DG_PRESSED, gi->direct_draw);
}
else
{
/* if mouse button pressed outside text input gadget, deactivate it */
CheckRangeOfNumericInputGadget(gi);
- DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
+ DrawGadget(gi, DG_UNPRESSED, gi->direct_draw);
gi->event.type = GD_EVENT_TEXT_LEAVING;
/* 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.xsize) / getFontWidth(gi->font);
+ (my - gi->selectbox.y - gi->border.ysize) / getFontHeight(gi->font);
if (gi->selectbox.current_index < 0)
gi->selectbox.current_index = 0;
gi->selectbox.current_index = gi->selectbox.num_values - 1;
if (gi->selectbox.current_index != old_index)
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ DrawGadget(gi, DG_PRESSED, gi->direct_draw);
}
else
{
/* if mouse button pressed outside selectbox gadget, deactivate it */
- DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
+ DrawGadget(gi, DG_UNPRESSED, gi->direct_draw);
gi->event.type = GD_EVENT_TEXT_LEAVING;
(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);
+ (mx >= gi->selectbox.x && mx < gi->selectbox.x + gi->selectbox.width &&
+ my >= gi->selectbox.y && my < gi->selectbox.y + gi->selectbox.height);
}
else
{
if (button == 0 && !release_event)
gi = new_gi;
- if (gi)
+ if (gi != NULL)
{
int last_x = gi->event.x;
int last_y = gi->event.y;
/* if mouse moving 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.xsize) / getFontWidth(gi->font);
+ (my - gi->selectbox.y - gi->border.ysize) / getFontHeight(gi->font);
if (gi->selectbox.current_index < 0)
gi->selectbox.current_index = 0;
gi->selectbox.current_index = gi->selectbox.num_values - 1;
if (gi->selectbox.current_index != old_index)
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ DrawGadget(gi, DG_PRESSED, gi->direct_draw);
}
}
rgi != gi)
{
rgi->checked = FALSE;
- DrawGadget(rgi, DG_UNPRESSED, DG_DIRECT);
+ DrawGadget(rgi, DG_UNPRESSED, rgi->direct_draw);
}
rgi = rgi->next;
}
}
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ DrawGadget(gi, DG_PRESSED, gi->direct_draw);
gi->state = GD_BUTTON_PRESSED;
gi->event.type = GD_EVENT_PRESSED;
if (gi->type & GD_TYPE_BUTTON)
{
if (gadget_moving_inside && gi->state == GD_BUTTON_UNPRESSED)
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ DrawGadget(gi, DG_PRESSED, gi->direct_draw);
else if (gadget_moving_off_borders && gi->state == GD_BUTTON_PRESSED)
- DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
+ DrawGadget(gi, DG_UNPRESSED, gi->direct_draw);
}
else if (gi->type & GD_TYPE_SELECTBOX)
{
/* if mouse moving 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.xsize) / getFontWidth(gi->font);
+ (my - gi->selectbox.y - gi->border.ysize) / getFontHeight(gi->font);
if (gi->selectbox.current_index < 0)
gi->selectbox.current_index = 0;
gi->selectbox.current_index = gi->selectbox.num_values - 1;
if (gi->selectbox.current_index != old_index)
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ DrawGadget(gi, DG_PRESSED, gi->direct_draw);
}
else if (gi->type & GD_TYPE_SCROLLBAR)
{
changed_position = TRUE;
}
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ DrawGadget(gi, DG_PRESSED, gi->direct_draw);
}
gi->state = (gadget_moving_inside || gi->type & GD_TYPE_SCROLLBAR ?
if (deactivate_gadget &&
!(gi->type & GD_TYPE_TEXTINPUT)) /* text input stays open */
- DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
+ DrawGadget(gi, DG_UNPRESSED, gi->direct_draw);
gi->state = GD_BUTTON_UNPRESSED;
gi->event.type = GD_EVENT_RELEASED;
if (gadget_released_off_borders)
{
if (gi->type & GD_TYPE_SCROLLBAR)
- DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
+ DrawGadget(gi, DG_UNPRESSED, gi->direct_draw);
gi->event.type = GD_EVENT_RELEASED;
gi->event_mask & GD_EVENT_OFF_BORDERS)
gi->callback_action(gi);
}
+
+ /* handle gadgets unmapped/mapped between pressing and releasing */
+ if (release_event && !gadget_released && new_gi)
+ new_gi->state = GD_BUTTON_UNPRESSED;
}
void HandleGadgetsKeyInput(Key key)
else if (gi->type & GD_TYPE_SELECTBOX)
gi->selectbox.index = gi->selectbox.current_index;
- DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
+ DrawGadget(gi, DG_UNPRESSED, gi->direct_draw);
gi->event.type = GD_EVENT_TEXT_RETURN;
gi->text.value[cursor_pos] = letter;
gi->text.cursor_position++;
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ DrawGadget(gi, DG_PRESSED, gi->direct_draw);
}
else if (key == KSYM_Left && cursor_pos > 0)
{
gi->text.cursor_position--;
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ DrawGadget(gi, DG_PRESSED, gi->direct_draw);
}
else if (key == KSYM_Right && cursor_pos < text_length)
{
gi->text.cursor_position++;
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ DrawGadget(gi, DG_PRESSED, gi->direct_draw);
}
else if (key == KSYM_BackSpace && cursor_pos > 0)
{
strcpy(text, gi->text.value);
strcpy(&gi->text.value[cursor_pos - 1], &text[cursor_pos]);
gi->text.cursor_position--;
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ DrawGadget(gi, DG_PRESSED, gi->direct_draw);
}
else if (key == KSYM_Delete && cursor_pos < text_length)
{
strcpy(text, gi->text.value);
strcpy(&gi->text.value[cursor_pos], &text[cursor_pos + 1]);
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ DrawGadget(gi, DG_PRESSED, gi->direct_draw);
}
}
else if (gi->type & GD_TYPE_SELECTBOX) /* only valid for selectbox */
if (key == KSYM_Up && index > 0)
{
gi->selectbox.current_index--;
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ DrawGadget(gi, DG_PRESSED, gi->direct_draw);
}
else if (key == KSYM_Down && index < num_values - 1)
{
gi->selectbox.current_index++;
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ DrawGadget(gi, DG_PRESSED, gi->direct_draw);
}
}
}