changed handling of deactivated gadgets (undefined bitmap or off-screen)
[rocksndiamonds.git] / src / libgame / gadgets.c
index b21ecdca09607e9afb25eb4dec7f1fb8ad302e19..ce939a75de69cbad9d507d3a0a34f6c8cc1a422d 100644 (file)
@@ -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' &&                                                     \
@@ -220,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] :
@@ -244,9 +242,16 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct)
        int deco_width  = MIN(gi->deco.width,  gi->width  - deco_x);
        int deco_height = MIN(gi->deco.height, gi->height - deco_y);
 
-       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);
+       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;
@@ -770,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)
@@ -994,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;
@@ -1086,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 */
 
@@ -1252,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)
@@ -1340,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;
@@ -1356,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;
@@ -2061,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))