+
+/* ---------- new screen button stuff -------------------------------------- */
+
+/* graphic position and size values for buttons and scrollbars */
+#define SC_SCROLLBUTTON_XSIZE 32
+#define SC_SCROLLBUTTON_YSIZE 32
+
+#define SC_SCROLL_UP_XPOS (SXSIZE - SC_SCROLLBUTTON_XSIZE)
+#define SC_SCROLL_UP_YPOS SC_SCROLLBUTTON_YSIZE
+#define SC_SCROLL_DOWN_XPOS SC_SCROLL_UP_XPOS
+#define SC_SCROLL_DOWN_YPOS (SYSIZE - SC_SCROLLBUTTON_YSIZE)
+#define SC_SCROLL_VERTICAL_XPOS SC_SCROLL_UP_XPOS
+#define SC_SCROLL_VERTICAL_YPOS (SC_SCROLL_UP_YPOS + SC_SCROLLBUTTON_YSIZE)
+#define SC_SCROLL_VERTICAL_XSIZE SC_SCROLLBUTTON_XSIZE
+#define SC_SCROLL_VERTICAL_YSIZE (SYSIZE - 3 * SC_SCROLLBUTTON_YSIZE)
+
+#define SC_BORDER_SIZE 14
+
+static struct
+{
+ int gfx_unpressed, gfx_pressed;
+ int x, y;
+ int gadget_id;
+ char *infotext;
+} scrollbutton_info[NUM_SCREEN_SCROLLBUTTONS] =
+{
+ {
+ IMG_ARROW_BLUE_UP, IMG_ARROW_RED_UP,
+ SC_SCROLL_UP_XPOS, SC_SCROLL_UP_YPOS,
+ SCREEN_CTRL_ID_SCROLL_UP,
+ "scroll up"
+ },
+ {
+ IMG_ARROW_BLUE_DOWN, IMG_ARROW_RED_DOWN,
+ SC_SCROLL_DOWN_XPOS, SC_SCROLL_DOWN_YPOS,
+ SCREEN_CTRL_ID_SCROLL_DOWN,
+ "scroll down"
+ }
+};
+
+static struct
+{
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ Bitmap **gfx_unpressed, **gfx_pressed;
+#else
+ int gfx_unpressed, gfx_pressed;
+#endif
+ int x, y;
+ int width, height;
+ int type;
+ int gadget_id;
+ char *infotext;
+} scrollbar_info[NUM_SCREEN_SCROLLBARS] =
+{
+ {
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ &scrollbar_bitmap[0], &scrollbar_bitmap[1],
+#else
+ IMG_SCROLLBAR_BLUE, IMG_SCROLLBAR_RED,
+#endif
+ SX + SC_SCROLL_VERTICAL_XPOS, SY + SC_SCROLL_VERTICAL_YPOS,
+ SC_SCROLL_VERTICAL_XSIZE, SC_SCROLL_VERTICAL_YSIZE,
+ GD_TYPE_SCROLLBAR_VERTICAL,
+ SCREEN_CTRL_ID_SCROLL_VERTICAL,
+ "scroll level series vertically"
+ }
+};
+
+static void CreateScreenScrollbuttons()
+{
+ struct GadgetInfo *gi;
+ unsigned long event_mask;
+ int i;
+
+ for (i=0; i<NUM_SCREEN_SCROLLBUTTONS; i++)
+ {
+ Bitmap *gd_bitmap_unpressed, *gd_bitmap_pressed;
+ int gfx_unpressed, gfx_pressed;
+ int x, y, width, height;
+ int gd_x1, gd_x2, gd_y1, gd_y2;
+ int id = scrollbutton_info[i].gadget_id;
+
+ x = scrollbutton_info[i].x;
+ y = scrollbutton_info[i].y;
+
+ event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED;
+
+ x += SX;
+ y += SY;
+ width = SC_SCROLLBUTTON_XSIZE;
+ height = SC_SCROLLBUTTON_YSIZE;
+
+ gfx_unpressed = scrollbutton_info[i].gfx_unpressed;
+ gfx_pressed = scrollbutton_info[i].gfx_pressed;
+ gd_bitmap_unpressed = graphic_info[gfx_unpressed].bitmap;
+ gd_bitmap_pressed = graphic_info[gfx_pressed].bitmap;
+ gd_x1 = graphic_info[gfx_unpressed].src_x;
+ gd_y1 = graphic_info[gfx_unpressed].src_y;
+ gd_x2 = graphic_info[gfx_pressed].src_x;
+ gd_y2 = graphic_info[gfx_pressed].src_y;
+
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_INFO_TEXT, scrollbutton_info[i].infotext,
+ GDI_X, x,
+ GDI_Y, y,
+ GDI_WIDTH, width,
+ GDI_HEIGHT, height,
+ GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
+ GDI_STATE, GD_BUTTON_UNPRESSED,
+ GDI_DESIGN_UNPRESSED, gd_bitmap_unpressed, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd_bitmap_pressed, gd_x2, gd_y2,
+ GDI_EVENT_MASK, event_mask,
+ GDI_CALLBACK_ACTION, HandleScreenGadgets,
+ GDI_END);
+
+ if (gi == NULL)
+ Error(ERR_EXIT, "cannot create gadget");
+
+ screen_gadget[id] = gi;
+ }
+}
+
+static void CreateScreenScrollbars()
+{
+ int i;
+
+ for (i=0; i<NUM_SCREEN_SCROLLBARS; i++)
+ {
+ Bitmap *gd_bitmap_unpressed, *gd_bitmap_pressed;
+#if !defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ int gfx_unpressed, gfx_pressed;
+#endif
+ int gd_x1, gd_x2, gd_y1, gd_y2;
+ struct GadgetInfo *gi;
+ int items_max, items_visible, item_position;
+ unsigned long event_mask;
+ int num_page_entries = MAX_MENU_ENTRIES_ON_SCREEN - 1;
+ int id = scrollbar_info[i].gadget_id;
+
+ items_max = num_page_entries;
+ items_visible = num_page_entries;
+ item_position = 0;
+
+ event_mask = GD_EVENT_MOVING | GD_EVENT_OFF_BORDERS;
+
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ gd_bitmap_unpressed = *scrollbar_info[i].gfx_unpressed;
+ gd_bitmap_pressed = *scrollbar_info[i].gfx_pressed;
+ gd_x1 = 0;
+ gd_y1 = 0;
+ gd_x2 = 0;
+ gd_y2 = 0;
+#else
+ gfx_unpressed = scrollbar_info[i].gfx_unpressed;
+ gfx_pressed = scrollbar_info[i].gfx_pressed;
+ gd_bitmap_unpressed = graphic_info[gfx_unpressed].bitmap;
+ gd_bitmap_pressed = graphic_info[gfx_pressed].bitmap;
+ gd_x1 = graphic_info[gfx_unpressed].src_x;
+ gd_y1 = graphic_info[gfx_unpressed].src_y;
+ gd_x2 = graphic_info[gfx_pressed].src_x;
+ gd_y2 = graphic_info[gfx_pressed].src_y;
+#endif
+
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_INFO_TEXT, scrollbar_info[i].infotext,
+ GDI_X, scrollbar_info[i].x,
+ GDI_Y, scrollbar_info[i].y,
+ GDI_WIDTH, scrollbar_info[i].width,
+ GDI_HEIGHT, scrollbar_info[i].height,
+ GDI_TYPE, scrollbar_info[i].type,
+ GDI_SCROLLBAR_ITEMS_MAX, items_max,
+ GDI_SCROLLBAR_ITEMS_VISIBLE, items_visible,
+ GDI_SCROLLBAR_ITEM_POSITION, item_position,
+ GDI_STATE, GD_BUTTON_UNPRESSED,
+ GDI_DESIGN_UNPRESSED, gd_bitmap_unpressed, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd_bitmap_pressed, gd_x2, gd_y2,
+ GDI_BORDER_SIZE, SC_BORDER_SIZE,
+ GDI_EVENT_MASK, event_mask,
+ GDI_CALLBACK_ACTION, HandleScreenGadgets,
+ GDI_END);
+
+ if (gi == NULL)
+ Error(ERR_EXIT, "cannot create gadget");
+
+ screen_gadget[id] = gi;
+ }
+}
+
+void CreateScreenGadgets()
+{
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ int i;
+
+ for (i=0; i<4; i++)
+ {
+ scrollbar_bitmap[i] = CreateBitmap(TILEX, TILEY, DEFAULT_DEPTH);
+
+ /* copy pointers to clip mask and GC */
+ scrollbar_bitmap[i]->clip_mask =
+ graphic_info[IMG_SCROLLBAR_BLUE + i].clip_mask;
+ scrollbar_bitmap[i]->stored_clip_gc =
+ graphic_info[IMG_SCROLLBAR_BLUE + i].clip_gc;
+
+ BlitBitmap(graphic_info[IMG_SCROLLBAR_BLUE + i].bitmap,
+ scrollbar_bitmap[i],
+ graphic_info[IMG_SCROLLBAR_BLUE + i].src_x,
+ graphic_info[IMG_SCROLLBAR_BLUE + i].src_y,
+ TILEX, TILEY, 0, 0);
+ }
+#endif
+
+ CreateScreenScrollbuttons();
+ CreateScreenScrollbars();
+}
+
+void FreeScreenGadgets()
+{
+ int i;
+
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ for (i=0; i<4; i++)
+ {
+ /* prevent freeing clip mask and GC twice */
+ scrollbar_bitmap[i]->clip_mask = None;
+ scrollbar_bitmap[i]->stored_clip_gc = None;
+
+ FreeBitmap(scrollbar_bitmap[i]);
+ }
+#endif
+
+ for (i=0; i<NUM_SCREEN_GADGETS; i++)
+ FreeGadget(screen_gadget[i]);
+}
+
+void MapChooseTreeGadgets(TreeInfo *ti)
+{
+ int num_entries = numTreeInfoInGroup(ti);
+ int i;
+
+ if (num_entries <= MAX_MENU_ENTRIES_ON_SCREEN)
+ return;
+
+ for (i=0; i<NUM_SCREEN_GADGETS; i++)
+ MapGadget(screen_gadget[i]);
+}
+
+void UnmapChooseTreeGadgets()
+{
+ int i;
+
+ for (i=0; i<NUM_SCREEN_GADGETS; i++)
+ UnmapGadget(screen_gadget[i]);
+}
+
+static void HandleScreenGadgets(struct GadgetInfo *gi)
+{
+ int id = gi->custom_id;
+
+ if (game_status != CHOOSELEVEL && game_status != SETUP)
+ return;
+
+ switch (id)
+ {
+ case SCREEN_CTRL_ID_SCROLL_UP:
+ if (game_status == CHOOSELEVEL)
+ HandleChooseLevel(SX,SY + 32, 0,0, MB_MENU_MARK);
+ else if (game_status == SETUP)
+ HandleSetupScreen(SX,SY + 32, 0,0, MB_MENU_MARK);
+ break;
+
+ case SCREEN_CTRL_ID_SCROLL_DOWN:
+ if (game_status == CHOOSELEVEL)
+ HandleChooseLevel(SX,SY + SYSIZE - 32, 0,0, MB_MENU_MARK);
+ else if (game_status == SETUP)
+ HandleSetupScreen(SX,SY + SYSIZE - 32, 0,0, MB_MENU_MARK);
+ break;
+
+ case SCREEN_CTRL_ID_SCROLL_VERTICAL:
+ if (game_status == CHOOSELEVEL)
+ HandleChooseLevel(0,0, 999,gi->event.item_position,MB_MENU_INITIALIZE);
+ else if (game_status == SETUP)
+ HandleSetupScreen(0,0, 999,gi->event.item_position,MB_MENU_INITIALIZE);
+ break;
+
+ default:
+ break;
+ }
+}