X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fgadgets.c;h=5ac104c8a254688839d0f1111ce3f17efa951fc0;hb=494b886d5c5041013ea361a12a07d7cd87551d52;hp=3431719caeb799898974860d5982cced01e4df71;hpb=5a2237add0a19d1559c0fe20c3f27651a71adf6c;p=rocksndiamonds.git diff --git a/src/libgame/gadgets.c b/src/libgame/gadgets.c index 3431719c..5ac104c8 100644 --- a/src/libgame/gadgets.c +++ b/src/libgame/gadgets.c @@ -744,11 +744,11 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) break; case GDI_TYPE: - gi->type = va_arg(ap, unsigned long); + gi->type = va_arg(ap, unsigned int); break; case GDI_STATE: - gi->state = va_arg(ap, unsigned long); + gi->state = va_arg(ap, unsigned int); break; case GDI_ACTIVE: @@ -770,18 +770,18 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) break; case GDI_RADIO_NR: - gi->radio_nr = va_arg(ap, unsigned long); + gi->radio_nr = va_arg(ap, unsigned int); break; case GDI_NUMBER_VALUE: - gi->textinput.number_value = va_arg(ap, long); + gi->textinput.number_value = va_arg(ap, int); sprintf(gi->textinput.value, "%d", gi->textinput.number_value); strcpy(gi->textinput.last_value, gi->textinput.value); gi->textinput.cursor_position = strlen(gi->textinput.value); break; case GDI_NUMBER_MIN: - gi->textinput.number_min = va_arg(ap, long); + gi->textinput.number_min = va_arg(ap, int); if (gi->textinput.number_value < gi->textinput.number_min) { gi->textinput.number_value = gi->textinput.number_min; @@ -791,7 +791,7 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) break; case GDI_NUMBER_MAX: - gi->textinput.number_max = va_arg(ap, long); + gi->textinput.number_max = va_arg(ap, int); if (gi->textinput.number_value > gi->textinput.number_max) { gi->textinput.number_value = gi->textinput.number_max; @@ -919,7 +919,7 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) break; case GDI_EVENT_MASK: - gi->event_mask = va_arg(ap, unsigned long); + gi->event_mask = va_arg(ap, unsigned int); break; case GDI_AREA_SIZE: @@ -1068,7 +1068,11 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) getFontCharSource(font_nr, FONT_ASCII_CURSOR, &src_bitmap, &src_x, &src_y); src_x += font_width / 2; src_y += font_height / 2; - gi->selectbox.inverse_color = GetPixel(src_bitmap, src_x, src_y); + + /* there may be esoteric cases with missing or too small font bitmap */ + if (src_bitmap != NULL && + src_x < src_bitmap->width && src_y < src_bitmap->height) + gi->selectbox.inverse_color = GetPixel(src_bitmap, src_x, src_y); /* always start with closed selectbox */ gi->selectbox.open = FALSE; @@ -1101,16 +1105,23 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) if (gi->type & GD_TYPE_SCROLLBAR) { struct GadgetScrollbar *gs = &gi->scrollbar; + int scrollbar_size_cmp; if (gi->width == 0 || gi->height == 0 || gs->items_max == 0 || gs->items_visible == 0) Error(ERR_EXIT, "scrollbar gadget incomplete (missing tags)"); /* calculate internal scrollbar values */ + gs->size_min = (gi->type == GD_TYPE_SCROLLBAR_VERTICAL ? + gi->width : gi->height); gs->size_max = (gi->type == GD_TYPE_SCROLLBAR_VERTICAL ? gi->height : gi->width); - gs->size = gs->size_max * gs->items_visible / gs->items_max; - gs->position = gs->size_max * gs->item_position / gs->items_max; + + scrollbar_size_cmp = gs->size_max * gs->items_visible / gs->items_max; + gs->size = MAX(scrollbar_size_cmp, gs->size_min); + gs->size_max_cmp = (gs->size_max - (gs->size - scrollbar_size_cmp)); + + gs->position = gs->size_max_cmp * gs->item_position / gs->items_max; gs->position_max = gs->size_max - gs->size; gs->correction = gs->size_max / gs->items_max / 2; @@ -1309,21 +1320,33 @@ void RemapAllGadgets() MultiMapGadgets(MULTIMAP_ALL | MULTIMAP_REMAP); } -static boolean anyTextInputGadgetActive() +boolean anyTextInputGadgetActive() { return (last_gi && (last_gi->type & GD_TYPE_TEXT_INPUT) && last_gi->mapped); } -static boolean anyTextAreaGadgetActive() +boolean anyTextAreaGadgetActive() { return (last_gi && (last_gi->type & GD_TYPE_TEXT_AREA) && last_gi->mapped); } -static boolean anySelectboxGadgetActive() +boolean anySelectboxGadgetActive() { return (last_gi && (last_gi->type & GD_TYPE_SELECTBOX) && last_gi->mapped); } +boolean anyScrollbarGadgetActive() +{ + return (last_gi && (last_gi->type & GD_TYPE_SCROLLBAR) && last_gi->mapped); +} + +boolean anyTextGadgetActive() +{ + return (anyTextInputGadgetActive() || + anyTextAreaGadgetActive() || + anySelectboxGadgetActive()); +} + static boolean insideSelectboxLine(struct GadgetInfo *gi, int mx, int my) { return(gi != NULL && @@ -1340,13 +1363,6 @@ static boolean insideSelectboxArea(struct GadgetInfo *gi, int mx, int my) my >= gi->selectbox.y && my < gi->selectbox.y + gi->selectbox.height); } -boolean anyTextGadgetActive() -{ - return (anyTextInputGadgetActive() || - anyTextAreaGadgetActive() || - anySelectboxGadgetActive()); -} - void ClickOnGadget(struct GadgetInfo *gi, int button) { if (!gi->mapped) @@ -1701,7 +1717,7 @@ boolean HandleGadgets(int mx, int my, int button) if (gs->item_position < 0) gs->item_position = 0; - if (gs->item_position > gs->items_max - gs->items_visible) + else if (gs->item_position > gs->items_max - gs->items_visible) gs->item_position = gs->items_max - gs->items_visible; if (old_item_position != gs->item_position) @@ -1783,13 +1799,22 @@ boolean HandleGadgets(int mx, int my, int button) gs->position = scrollbar_mouse_pos - gs->drag_position; - if (gs->position < 0) + /* make sure to always precisely reach end positions when dragging */ + if (gs->position <= 0) + { gs->position = 0; - if (gs->position > gs->position_max) + gs->item_position = 0; + } + else if (gs->position >= gs->position_max) + { gs->position = gs->position_max; - - gs->item_position = - gs->items_max * (gs->position + gs->correction) / gs->size_max; + gs->item_position = gs->items_max - gs->items_visible; + } + else + { + gs->item_position = + gs->items_max * (gs->position + gs->correction) / gs->size_max_cmp; + } if (gs->item_position < 0) gs->item_position = 0;