X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fgadgets.c;h=ce939a75de69cbad9d507d3a0a34f6c8cc1a422d;hb=3370541656df96651eabc2723332e93964c28737;hp=6200c9dc3da22291d19e086f1c5acdf99685e4d4;hpb=b4e74fe434deee25bf99f6d44376d6ae06b7c832;p=rocksndiamonds.git diff --git a/src/libgame/gadgets.c b/src/libgame/gadgets.c index 6200c9dc..ce939a75 100644 --- a/src/libgame/gadgets.c +++ b/src/libgame/gadgets.c @@ -24,8 +24,6 @@ #define DG_BUFFERED 0 #define DG_DIRECT 1 -#define GADGET_DEACTIVATED(g) ((g)->x < 0 || (g)->y < 0) - #define OPTION_TEXT_SELECTABLE(g, t) \ (t[0] != g->selectbox.char_unselectable && \ t[0] != '\0' && \ @@ -96,6 +94,16 @@ static struct GadgetInfo *getGadgetInfoFromMousePosition(int mx, int my, boolean check_horizontal = (IS_WHEEL_BUTTON_HORIZONTAL(button) || GetKeyModState() & KMOD_Shift); + /* check for the first active scrollbar directly under the mouse pointer */ + for (gi = gadget_list_first_entry; gi != NULL; gi = gi->next) + { + if (gi->mapped && gi->active && + (gi->type & GD_TYPE_SCROLLBAR) && + mx >= gi->x && mx < gi->x + gi->width && + my >= gi->y && my < gi->y + gi->height) + return gi; + } + /* check for the first active scrollbar with matching mouse wheel area */ for (gi = gadget_list_first_entry; gi != NULL; gi = gi->next) { @@ -210,7 +218,7 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) int state = (pressed ? GD_BUTTON_PRESSED : GD_BUTTON_UNPRESSED); boolean redraw_selectbox = FALSE; - if (gi == NULL) + if (gi == NULL || gi->deactivated) return; gd = (!gi->active ? &gi->alt_design[state] : @@ -221,15 +229,31 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) case GD_TYPE_NORMAL_BUTTON: case GD_TYPE_CHECK_BUTTON: case GD_TYPE_RADIO_BUTTON: + BlitBitmapOnBackground(gd->bitmap, drawto, gd->x, gd->y, gi->width, gi->height, gi->x, gi->y); + if (gi->deco.design.bitmap) - BlitBitmap(gi->deco.design.bitmap, drawto, - gi->deco.design.x, gi->deco.design.y, - gi->deco.width, gi->deco.height, - gi->x + gi->deco.x + (pressed ? gi->deco.xshift : 0), - gi->y + gi->deco.y + (pressed ? gi->deco.yshift : 0)); + { + // make sure that decoration does not overlap gadget border + int deco_x = gi->deco.x + (pressed ? gi->deco.xshift : 0); + int deco_y = gi->deco.y + (pressed ? gi->deco.yshift : 0); + int deco_width = MIN(gi->deco.width, gi->width - deco_x); + int deco_height = MIN(gi->deco.height, gi->height - deco_y); + + if (gi->deco.masked) + BlitBitmapMasked(gi->deco.design.bitmap, drawto, + gi->deco.design.x, gi->deco.design.y, + deco_width, deco_height, + gi->x + deco_x, gi->y + deco_y); + else + BlitBitmap(gi->deco.design.bitmap, drawto, + gi->deco.design.x, gi->deco.design.y, + deco_width, deco_height, + gi->x + deco_x, gi->y + deco_y); + } + break; case GD_TYPE_TEXT_BUTTON: @@ -751,7 +775,7 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) { int tag = first_tag; - if (gi == NULL) + if (gi == NULL || gi->deactivated) return; while (tag != GDI_END) @@ -975,6 +999,10 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) gi->deco.yshift = va_arg(ap, int); break; + case GDI_DECORATION_MASKED: + gi->deco.masked = (boolean)va_arg(ap, int); + break; + case GDI_EVENT_MASK: gi->event_mask = va_arg(ap, unsigned int); break; @@ -1067,11 +1095,17 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) tag = va_arg(ap, int); /* read next tag */ } - /* check if gadget is complete */ + gi->deactivated = FALSE; + + /* check if gadget has undefined bitmaps */ if (gi->type != GD_TYPE_DRAWING_AREA && - (!gi->design[GD_BUTTON_UNPRESSED].bitmap || - !gi->design[GD_BUTTON_PRESSED].bitmap)) - Error(ERR_EXIT, "gadget incomplete (missing Bitmap)"); + (gi->design[GD_BUTTON_UNPRESSED].bitmap == NULL || + gi->design[GD_BUTTON_PRESSED].bitmap == NULL)) + gi->deactivated = TRUE; + + /* check if gadget is placed off-screen */ + if (gi->x < 0 || gi->y < 0) + gi->deactivated = TRUE; /* adjust gadget values in relation to other gadget values */ @@ -1233,7 +1267,7 @@ void ModifyGadget(struct GadgetInfo *gi, int first_tag, ...) void RedrawGadget(struct GadgetInfo *gi) { - if (gi == NULL) + if (gi == NULL || gi->deactivated) return; if (gi->mapped) @@ -1321,7 +1355,7 @@ static struct GadgetInfo *last_gi = NULL; static void MapGadgetExt(struct GadgetInfo *gi, boolean redraw) { - if (gi == NULL || gi->mapped || GADGET_DEACTIVATED(gi)) + if (gi == NULL || gi->deactivated || gi->mapped) return; gi->mapped = TRUE; @@ -1337,7 +1371,7 @@ void MapGadget(struct GadgetInfo *gi) void UnmapGadget(struct GadgetInfo *gi) { - if (gi == NULL || !gi->mapped) + if (gi == NULL || gi->deactivated || !gi->mapped) return; gi->mapped = FALSE; @@ -1779,7 +1813,7 @@ boolean HandleGadgets(int mx, int my, int button) { boolean scroll_single_step = ((GetKeyModState() & KMOD_Alt) != 0); - item_steps = (scroll_single_step ? 1 : DEFAULT_WHEEL_STEPS); + item_steps = (scroll_single_step ? 1 : wheel_steps); item_direction = (button == MB_WHEEL_UP || button == MB_WHEEL_LEFT ? -1 : +1); } @@ -2042,7 +2076,7 @@ boolean HandleGadgetsKeyInput(Key key) { struct GadgetInfo *gi = last_gi; - if (gi == NULL || !gi->mapped || + if (gi == NULL || gi->deactivated || !gi->mapped || !(gi->type & GD_TYPE_TEXT_INPUT || gi->type & GD_TYPE_TEXT_AREA || gi->type & GD_TYPE_SELECTBOX))