+ EL_EMPTY
+};
+static int *editor_hl_custom_special_ptr = editor_hl_custom_special;
+static int *editor_el_custom_special_ptr = editor_el_custom_special;
+static int num_editor_hl_custom_special = SIZEOF_ARRAY_INT(editor_hl_custom_special);
+static int num_editor_el_custom_special = SIZEOF_ARRAY_INT(editor_el_custom_special);
+
+static int editor_hl_group[] =
+{
+ EL_CHAR('G'),
+ EL_CHAR('R'),
+ EL_CHAR('O'),
+ EL_CHAR('U'),
+
+ EL_CHAR('P'),
+ EL_CHAR(' '),
+ EL_CHAR(' '),
+ EL_CHAR(' '),
+
+ EL_CHAR('E'),
+ EL_CHAR('L'),
+ EL_CHAR('E'),
+ EL_CHAR('M'),
+
+ EL_CHAR('E'),
+ EL_CHAR('N'),
+ EL_CHAR('T'),
+ EL_CHAR('S'),
+};
+
+static int editor_el_group[] =
+{
+ EL_GROUP_START + 0,
+ EL_GROUP_START + 1,
+ EL_GROUP_START + 2,
+ EL_GROUP_START + 3,
+
+ EL_GROUP_START + 4,
+ EL_GROUP_START + 5,
+ EL_GROUP_START + 6,
+ EL_GROUP_START + 7,
+
+ EL_GROUP_START + 8,
+ EL_GROUP_START + 9,
+ EL_GROUP_START + 10,
+ EL_GROUP_START + 11,
+
+ EL_GROUP_START + 12,
+ EL_GROUP_START + 13,
+ EL_GROUP_START + 14,
+ EL_GROUP_START + 15
+};
+static int *editor_hl_group_ptr = editor_hl_group;
+static int *editor_el_group_ptr = editor_el_group;
+static int num_editor_hl_group = SIZEOF_ARRAY_INT(editor_hl_group);
+static int num_editor_el_group = SIZEOF_ARRAY_INT(editor_el_group);
+
+static int editor_hl_group_more[] =
+{
+};
+
+static int editor_el_group_more[] =
+{
+ EL_GROUP_START + 16,
+ EL_GROUP_START + 17,
+ EL_GROUP_START + 18,
+ EL_GROUP_START + 19,
+
+ EL_GROUP_START + 20,
+ EL_GROUP_START + 21,
+ EL_GROUP_START + 22,
+ EL_GROUP_START + 23,
+
+ EL_GROUP_START + 24,
+ EL_GROUP_START + 25,
+ EL_GROUP_START + 26,
+ EL_GROUP_START + 27,
+
+ EL_GROUP_START + 28,
+ EL_GROUP_START + 29,
+ EL_GROUP_START + 30,
+ EL_GROUP_START + 31
+};
+static int *editor_hl_group_more_ptr = editor_hl_group_more;
+static int *editor_el_group_more_ptr = editor_el_group_more;
+static int num_editor_hl_group_more = SIZEOF_ARRAY_INT(editor_hl_group_more);
+static int num_editor_el_group_more = SIZEOF_ARRAY_INT(editor_el_group_more);
+
+static int editor_hl_user_defined[] =
+{
+ EL_CHAR('U'),
+ EL_CHAR('S'),
+ EL_CHAR('E'),
+ EL_CHAR('R'),
+
+ EL_CHAR('D'),
+ EL_CHAR('E'),
+ EL_CHAR('F'),
+ EL_CHAR('I'),
+
+ EL_CHAR('-'),
+ EL_CHAR('N'),
+ EL_CHAR('E'),
+ EL_CHAR('D'),
+};
+
+static int *editor_hl_user_defined_ptr = editor_hl_user_defined;
+static int *editor_el_user_defined_ptr = NULL;
+static int num_editor_hl_user_defined=SIZEOF_ARRAY_INT(editor_hl_user_defined);
+static int num_editor_el_user_defined = 0;
+
+static int editor_hl_empty[] = { };
+static int editor_el_empty[ED_NUM_ELEMENTLIST_BUTTONS];
+
+static int *editor_hl_empty_ptr = editor_hl_empty;
+static int *editor_el_empty_ptr = editor_el_empty;
+static int num_editor_hl_empty = 0;
+static int num_editor_el_empty = 0; /* dynamically determined, if needed */
+
+static boolean use_el_empty = FALSE;
+
+static int *editor_elements = NULL; /* dynamically allocated */
+static int num_editor_elements = 0; /* dynamically determined */
+
+static struct
+{
+ boolean *setup_value;
+
+ int **headline_list;
+ int *headline_list_size;
+
+ int **element_list;
+ int *element_list_size;
+
+ boolean last_setup_value;
+}
+editor_elements_info[] =
+{
+ {
+ &setup.editor.el_boulderdash,
+ &editor_hl_boulderdash_ptr, &num_editor_hl_boulderdash,
+ &editor_el_boulderdash_ptr, &num_editor_el_boulderdash
+ },
+ {
+ &setup.editor.el_emerald_mine,
+ &editor_hl_emerald_mine_ptr, &num_editor_hl_emerald_mine,
+ &editor_el_emerald_mine_ptr, &num_editor_el_emerald_mine
+ },
+ {
+ &setup.editor.el_emerald_mine_club,
+ &editor_hl_emerald_mine_club_ptr, &num_editor_hl_emerald_mine_club,
+ &editor_el_emerald_mine_club_ptr, &num_editor_el_emerald_mine_club
+ },
+ {
+ &setup.editor.el_more,
+ &editor_hl_more_ptr, &num_editor_hl_more,
+ &editor_el_more_ptr, &num_editor_el_more
+ },
+ {
+ &setup.editor.el_sokoban,
+ &editor_hl_sokoban_ptr, &num_editor_hl_sokoban,
+ &editor_el_sokoban_ptr, &num_editor_el_sokoban
+ },
+ {
+ &setup.editor.el_supaplex,
+ &editor_hl_supaplex_ptr, &num_editor_hl_supaplex,
+ &editor_el_supaplex_ptr, &num_editor_el_supaplex
+ },
+ {
+ &setup.editor.el_diamond_caves,
+ &editor_hl_diamond_caves_ptr, &num_editor_hl_diamond_caves,
+ &editor_el_diamond_caves_ptr, &num_editor_el_diamond_caves
+ },
+ {
+ &setup.editor.el_dx_boulderdash,
+ &editor_hl_dx_boulderdash_ptr, &num_editor_hl_dx_boulderdash,
+ &editor_el_dx_boulderdash_ptr, &num_editor_el_dx_boulderdash
+ },
+ {
+ &setup.editor.el_chars,
+ &editor_hl_chars_ptr, &num_editor_hl_chars,
+ &editor_el_chars_ptr, &num_editor_el_chars
+ },
+ {
+ &setup.editor.el_custom,
+ &editor_hl_custom_ptr, &num_editor_hl_custom,
+ &editor_el_custom_ptr, &num_editor_el_custom
+ },
+ {
+ &setup.editor.el_custom_more,
+ &editor_hl_custom_more_ptr, &num_editor_hl_custom_more,
+ &editor_el_custom_more_ptr, &num_editor_el_custom_more
+ },
+ {
+ &setup.editor.el_custom,
+ &editor_hl_custom_special_ptr, &num_editor_hl_custom_special,
+ &editor_el_custom_special_ptr, &num_editor_el_custom_special
+ },
+ {
+ &setup.editor.el_custom,
+ &editor_hl_group_ptr, &num_editor_hl_group,
+ &editor_el_group_ptr, &num_editor_el_group
+ },
+ {
+ &setup.editor.el_custom_more,
+ &editor_hl_group_more_ptr, &num_editor_hl_group_more,
+ &editor_el_group_more_ptr, &num_editor_el_group_more
+ },
+ {
+ &setup.editor.el_user_defined,
+ &editor_hl_user_defined_ptr, &num_editor_hl_user_defined,
+ &editor_el_user_defined_ptr, &num_editor_el_user_defined
+ },
+ {
+ &use_el_empty,
+ &editor_hl_empty_ptr, &num_editor_hl_empty,
+ &editor_el_empty_ptr, &num_editor_el_empty,
+ },
+ {
+ NULL,
+ NULL, NULL,
+ NULL, NULL
+ }
+};
+
+
+/*
+ -----------------------------------------------------------------------------
+ functions
+ -----------------------------------------------------------------------------
+*/
+
+static int getMaxInfoTextLength()
+{
+ return (SXSIZE / getFontWidth(FONT_TEXT_2));
+}
+
+static int getTextWidthForGadget(char *text)
+{
+ if (text == NULL)
+ return 0;
+
+ return (getTextWidth(text, FONT_TEXT_1) + ED_GADGET_TEXT_DISTANCE);
+}
+
+static int getTextWidthForDrawingArea(char *text)
+{
+ if (text == NULL)
+ return 0;
+
+ return (getTextWidth(text, FONT_TEXT_1) + ED_DRAWINGAREA_TEXT_DISTANCE);
+}
+
+static int getRightGadgetBorder(struct GadgetInfo *gi, char *text)
+{
+ return (gi->x + gi->width + getTextWidthForGadget(text));
+}
+
+static char *getElementInfoText(int element)
+{
+ char *info_text = NULL;
+
+ if (element < NUM_FILE_ELEMENTS)
+ {
+ if (strlen(element_info[element].description) > 0)
+ info_text = element_info[element].description;
+ else if (element_info[element].custom_description != NULL)
+ info_text = element_info[element].custom_description;
+ else if (element_info[element].editor_description != NULL)
+ info_text = element_info[element].editor_description;
+ }
+
+ if (info_text == NULL)
+ info_text = INFOTEXT_UNKNOWN_ELEMENT;
+
+ return info_text;
+}
+
+static void ReinitializeElementList()
+{
+ int pos = 0;
+ int i, j;
+
+ checked_free(editor_elements);
+
+ /* reload optional user defined element list for each invocation of editor */
+ LoadUserDefinedEditorElementList(&editor_el_user_defined_ptr,
+ &num_editor_el_user_defined);
+
+ /* initialize list of empty elements (used for padding, if needed) */
+ for (i = 0; i < ED_NUM_ELEMENTLIST_BUTTONS; i++)
+ editor_el_empty[i] = EL_EMPTY;
+
+ /* do some sanity checks for each element from element list */
+ for (i = 0; editor_elements_info[i].setup_value != NULL; i++)
+ {
+ for (j = 0; j < *editor_elements_info[i].element_list_size; j++)
+ {
+ int element = (*editor_elements_info[i].element_list)[j];
+
+ if (element >= NUM_FILE_ELEMENTS)
+ Error(ERR_WARN, "editor element %d is runtime element", element);
+
+ if (strcmp(getElementInfoText(element), INFOTEXT_UNKNOWN_ELEMENT) == 0)
+ Error(ERR_WARN, "no element description for element %d", element);
+ }
+ }
+
+ num_editor_elements = 0;
+ use_el_empty = FALSE;
+
+ /* determine size of element list */
+ for (i = 0; editor_elements_info[i].setup_value != NULL; i++)
+ {
+ if (*editor_elements_info[i].setup_value)
+ {
+ if (setup.editor.el_headlines)
+ num_editor_elements += *editor_elements_info[i].headline_list_size;
+
+ num_editor_elements += *editor_elements_info[i].element_list_size;
+ }
+ }
+
+ if (num_editor_elements < ED_NUM_ELEMENTLIST_BUTTONS)
+ {
+ /* offer at least as many elements as element buttons exist */
+ use_el_empty = TRUE;
+ num_editor_el_empty = ED_NUM_ELEMENTLIST_BUTTONS - num_editor_elements;
+
+ num_editor_elements += num_editor_el_empty;
+ }
+
+ editor_elements = checked_malloc(num_editor_elements * sizeof(int));
+
+ /* fill element list */
+ for (i = 0; editor_elements_info[i].setup_value != NULL; i++)
+ {
+ if (*editor_elements_info[i].setup_value)
+ {
+ if (setup.editor.el_headlines)
+ for (j = 0; j < *editor_elements_info[i].headline_list_size; j++)
+ editor_elements[pos++] = (*editor_elements_info[i].headline_list)[j];
+
+ for (j = 0; j < *editor_elements_info[i].element_list_size; j++)
+ editor_elements[pos++] = (*editor_elements_info[i].element_list)[j];
+ }
+ }
+
+ /* correct position of element list scrollbar */
+ if (element_shift < 0)
+ element_shift = 0;
+ if (element_shift > num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS)
+ element_shift = num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS;
+}
+
+void PrintEditorElementList()
+{
+ boolean *stop = &setup.editor.el_user_defined;
+ int i, j;
+
+ for (i = 0; editor_elements_info[i].setup_value != stop; i++)
+ {
+ for (j = 0; j < *editor_elements_info[i].headline_list_size; j++)
+ {
+ int element = (*editor_elements_info[i].headline_list)[j];
+
+ printf("# %s\n", element_info[element].token_name);
+ }
+
+ if (j > 0)
+ printf("#\n");
+
+ for (j = 0; j < *editor_elements_info[i].element_list_size; j++)
+ {
+ int element = (*editor_elements_info[i].element_list)[j];
+
+ printf("# %s\n", element_info[element].token_name);
+ }
+
+ if (j > 0)
+ printf("#\n");
+ }
+}
+
+static void ReinitializeElementListButtons()
+{
+ static boolean last_setup_value_headlines = FALSE;
+ static boolean initialization_needed = TRUE;
+ int i;
+
+ if (!initialization_needed) /* check if editor element setup has changed */
+ {
+ if (last_setup_value_headlines != setup.editor.el_headlines)
+ initialization_needed = TRUE;
+
+ for (i = 0; editor_elements_info[i].setup_value != NULL; i++)
+ if (editor_elements_info[i].last_setup_value !=
+ *editor_elements_info[i].setup_value)
+ initialization_needed = TRUE;
+ }
+
+ if (!initialization_needed)
+ return;
+
+ FreeLevelEditorGadgets();
+ CreateLevelEditorGadgets();
+
+ /* store current setup values for next invocation of this function */
+ last_setup_value_headlines = setup.editor.el_headlines;
+ for (i = 0; editor_elements_info[i].setup_value != NULL; i++)
+ editor_elements_info[i].last_setup_value =
+ *editor_elements_info[i].setup_value;
+
+ initialization_needed = FALSE;
+}
+
+static void DrawElementBorder(int dest_x, int dest_y, int width, int height,
+ boolean input)
+{
+ int border_graphic =
+ (input ? IMG_EDITOR_ELEMENT_BORDER_INPUT : IMG_EDITOR_ELEMENT_BORDER);
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ int num_mini_tilex = width / MINI_TILEX + 1;
+ int num_mini_tiley = height / MINI_TILEY + 1;
+ int x, y;
+
+ getMiniGraphicSource(border_graphic, &src_bitmap, &src_x, &src_y);
+
+ for (y = 0; y < num_mini_tiley; y++)
+ for (x = 0; x < num_mini_tilex; x++)
+ BlitBitmap(src_bitmap, drawto, src_x, src_y, MINI_TILEX, MINI_TILEY,
+ dest_x - MINI_TILEX / 2 + x * MINI_TILEX,
+ dest_y - MINI_TILEY / 2 + y * MINI_TILEY);
+
+ ClearRectangle(drawto, dest_x - 1, dest_y - 1, width + 2, height + 2);
+}
+
+static void DrawDrawingArea(int id)
+{
+ struct GadgetInfo *gi = level_editor_gadget[drawingarea_info[id].gadget_id];
+ int x, y;
+
+ if (id == ED_DRAWING_ID_RANDOM_BACKGROUND)
+ DrawMiniGraphicExt(drawto, gi->x, gi->y,
+ el2edimg(random_placement_background_element));
+ else if (id == ED_DRAWING_ID_AMOEBA_CONTENT)
+ DrawMiniGraphicExt(drawto, gi->x, gi->y, el2edimg(level.amoeba_content));
+ else if (id == ED_DRAWING_ID_CUSTOM_GRAPHIC)
+ DrawMiniGraphicExt(drawto, gi->x, gi->y,
+ el2edimg(custom_element.gfx_element));
+ else if (id == ED_DRAWING_ID_CUSTOM_CONTENT)
+ for (y = 0; y < 3; y++)
+ for (x = 0; x < 3; x++)
+ DrawMiniGraphicExt(drawto,
+ gi->x + x * MINI_TILEX, gi->y + y * MINI_TILEY,
+ el2edimg(custom_element.content[x][y]));
+ else if (id == ED_DRAWING_ID_CUSTOM_MOVE_ENTER)
+ DrawMiniGraphicExt(drawto, gi->x, gi->y,
+ el2edimg(custom_element.move_enter_element));
+ else if (id == ED_DRAWING_ID_CUSTOM_MOVE_LEAVE)
+ DrawMiniGraphicExt(drawto, gi->x, gi->y,
+ el2edimg(custom_element.move_leave_element));
+ else if (id == ED_DRAWING_ID_CUSTOM_CHANGE_TARGET)
+ DrawMiniGraphicExt(drawto, gi->x, gi->y,
+ el2edimg(custom_element_change.target_element));
+ else if (id == ED_DRAWING_ID_CUSTOM_CHANGE_CONTENT)
+ for (y = 0; y < 3; y++)
+ for (x = 0; x < 3; x++)
+ DrawMiniGraphicExt(drawto,
+ gi->x + x * MINI_TILEX, gi->y + y * MINI_TILEY,
+ el2edimg(custom_element_change.target_content[x][y]));
+ else if (id == ED_DRAWING_ID_CUSTOM_CHANGE_TRIGGER)
+ DrawMiniGraphicExt(drawto, gi->x, gi->y,
+ el2edimg(custom_element_change.trigger_element));
+ else if (id == ED_DRAWING_ID_GROUP_CONTENT)
+ for (x = 0; x < group_element_info.num_elements; x++)
+ DrawMiniGraphicExt(drawto, gi->x + x * MINI_TILEX, gi->y,
+ el2edimg(group_element_info.element[x]));
+ else if (id >= ED_DRAWING_ID_YAMYAM_CONTENT_0 &&
+ id <= ED_DRAWING_ID_YAMYAM_CONTENT_7)
+ {
+ int nr = id - ED_DRAWING_ID_YAMYAM_CONTENT_0;
+
+ for (y = 0; y < 3; y++)
+ for (x = 0; x < 3; x++)
+ DrawMiniGraphicExt(drawto,
+ gi->x + x * MINI_TILEX, gi->y + y * MINI_TILEY,
+ el2edimg(level.yamyam_content[nr][x][y]));
+ }
+ else if (id >= ED_DRAWING_ID_MAGIC_BALL_CONTENT_0 &&
+ id <= ED_DRAWING_ID_MAGIC_BALL_CONTENT_7)
+ {
+ int nr = id - ED_DRAWING_ID_MAGIC_BALL_CONTENT_0;
+
+ for (y = 0; y < 3; y++)
+ for (x = 0; x < 3; x++)
+ DrawMiniGraphicExt(drawto,
+ gi->x + x * MINI_TILEX, gi->y + y * MINI_TILEY,
+ el2edimg(level.ball_content[nr][x][y]));
+ }
+}
+
+static void ScrollMiniLevel(int from_x, int from_y, int scroll)
+{
+ int x,y;
+ int dx = (scroll == ED_SCROLL_LEFT ? -1 : scroll == ED_SCROLL_RIGHT ? 1 : 0);
+ int dy = (scroll == ED_SCROLL_UP ? -1 : scroll == ED_SCROLL_DOWN ? 1 : 0);
+
+ BlitBitmap(drawto, drawto,
+ SX + (dx == -1 ? MINI_TILEX : 0),
+ SY + (dy == -1 ? MINI_TILEY : 0),
+ (ed_fieldx * MINI_TILEX) - (dx != 0 ? MINI_TILEX : 0),
+ (ed_fieldy * MINI_TILEY) - (dy != 0 ? MINI_TILEY : 0),
+ SX + (dx == +1 ? MINI_TILEX : 0),
+ SY + (dy == +1 ? MINI_TILEY : 0));
+ if (dx)
+ {
+ x = (dx == 1 ? 0 : ed_fieldx - 1);
+ for (y = 0; y < ed_fieldy; y++)
+ DrawMiniElementOrWall(x, y, from_x, from_y);
+ }
+ else if (dy)
+ {
+ y = (dy == 1 ? 0 : ed_fieldy - 1);
+ for (x = 0; x < ed_fieldx; x++)
+ DrawMiniElementOrWall(x, y, from_x, from_y);
+ }
+
+ redraw_mask |= REDRAW_FIELD;
+ BackToFront();
+}
+
+static void CreateControlButtons()
+{
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+ struct GadgetInfo *gi;
+ unsigned long event_mask;
+ int i;
+
+ /* create toolbox buttons */
+ for (i = 0; i < ED_NUM_CTRL_BUTTONS; i++)
+ {
+ int id = i;
+ int width, height;
+ int gd_xoffset, gd_yoffset;
+ int gd_x1, gd_x2, gd_y1, gd_y2;
+ int button_type;
+ int radio_button_nr;
+ boolean checked;
+
+ if (id == GADGET_ID_SINGLE_ITEMS ||
+ id == GADGET_ID_CONNECTED_ITEMS ||
+ id == GADGET_ID_LINE ||
+ id == GADGET_ID_ARC ||
+ id == GADGET_ID_TEXT ||
+ id == GADGET_ID_RECTANGLE ||
+ id == GADGET_ID_FILLED_BOX ||
+ id == GADGET_ID_FLOOD_FILL ||
+ id == GADGET_ID_GRAB_BRUSH ||
+ id == GADGET_ID_PICK_ELEMENT ||
+ id == GADGET_ID_CUSTOM_COPY_FROM ||
+ id == GADGET_ID_CUSTOM_COPY_TO ||
+ id == GADGET_ID_CUSTOM_EXCHANGE)
+ {
+ button_type = GD_TYPE_RADIO_BUTTON;
+ radio_button_nr = RADIO_NR_DRAWING_TOOLBOX;
+ checked = (id == drawing_function ? TRUE : FALSE);
+ event_mask = GD_EVENT_PRESSED;
+ }
+ else
+ {
+ button_type = GD_TYPE_NORMAL_BUTTON;
+ radio_button_nr = RADIO_NR_NONE;
+ checked = FALSE;
+
+ if (id == GADGET_ID_WRAP_LEFT ||
+ id == GADGET_ID_WRAP_RIGHT ||
+ id == GADGET_ID_WRAP_UP ||
+ id == GADGET_ID_WRAP_DOWN)
+ event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED;
+ else
+ event_mask = GD_EVENT_RELEASED;
+ }
+
+ if (id < ED_NUM_CTRL1_BUTTONS)
+ {
+ int x = i % ED_CTRL1_BUTTONS_HORIZ;
+ int y = i / ED_CTRL1_BUTTONS_HORIZ;
+
+ gd_xoffset = ED_CTRL1_BUTTONS_XPOS + x * ED_CTRL1_BUTTON_XSIZE;
+ gd_yoffset = ED_CTRL1_BUTTONS_YPOS + y * ED_CTRL1_BUTTON_YSIZE;
+ width = ED_CTRL1_BUTTON_XSIZE;
+ height = ED_CTRL1_BUTTON_YSIZE;
+
+ gd_x1 = DOOR_GFX_PAGEX8 + gd_xoffset;
+ gd_x2 = DOOR_GFX_PAGEX7 + gd_xoffset;
+ gd_y1 = DOOR_GFX_PAGEY1 + ED_CTRL1_BUTTONS_GFX_YPOS + gd_yoffset;
+ gd_y2 = DOOR_GFX_PAGEY1 + ED_CTRL1_BUTTONS_ALT_GFX_YPOS + gd_yoffset;
+ }
+ else if (id < ED_NUM_CTRL1_2_BUTTONS)
+ {
+ int x = (i - ED_NUM_CTRL1_BUTTONS) % ED_CTRL2_BUTTONS_HORIZ;
+ int y = (i - ED_NUM_CTRL1_BUTTONS) / ED_CTRL2_BUTTONS_HORIZ;
+
+ gd_xoffset = ED_CTRL2_BUTTONS_XPOS + x * ED_CTRL2_BUTTON_XSIZE;
+ gd_yoffset = ED_CTRL2_BUTTONS_YPOS + y * ED_CTRL2_BUTTON_YSIZE;
+ width = ED_CTRL2_BUTTON_XSIZE;
+ height = ED_CTRL2_BUTTON_YSIZE;
+
+ gd_x1 = DOOR_GFX_PAGEX8 + gd_xoffset;
+ gd_x2 = DOOR_GFX_PAGEX7 + gd_xoffset;
+ gd_y1 = DOOR_GFX_PAGEY1 + ED_CTRL2_BUTTONS_GFX_YPOS + gd_yoffset;
+ gd_y2 = 0; /* no alternative graphic for these buttons */
+ }
+ else if (id < ED_NUM_CTRL1_3_BUTTONS)
+ {
+ int x = (i - ED_NUM_CTRL1_2_BUTTONS) % ED_CTRL3_BUTTONS_HORIZ + 1;
+ int y = (i - ED_NUM_CTRL1_2_BUTTONS) / ED_CTRL3_BUTTONS_HORIZ;
+
+ gd_xoffset = ED_CTRL3_BUTTONS_XPOS + x * ED_CTRL3_BUTTON_XSIZE;
+ gd_yoffset = ED_CTRL3_BUTTONS_YPOS + y * ED_CTRL3_BUTTON_YSIZE;
+ width = ED_CTRL3_BUTTON_XSIZE;
+ height = ED_CTRL3_BUTTON_YSIZE;
+
+ gd_x1 = DOOR_GFX_PAGEX6 + gd_xoffset;
+ gd_x2 = DOOR_GFX_PAGEX5 + gd_xoffset;
+ gd_y1 = DOOR_GFX_PAGEY1 + ED_CTRL3_BUTTONS_GFX_YPOS + gd_yoffset;
+ gd_y2 = DOOR_GFX_PAGEY1 + ED_CTRL3_BUTTONS_ALT_GFX_YPOS + gd_yoffset;
+ }
+ else
+ {
+ int x = (i - ED_NUM_CTRL1_3_BUTTONS) % ED_CTRL4_BUTTONS_HORIZ;
+ int y = (i - ED_NUM_CTRL1_3_BUTTONS) / ED_CTRL4_BUTTONS_HORIZ + 3;
+
+ gd_xoffset = ED_CTRL4_BUTTONS_XPOS + x * ED_CTRL4_BUTTON_XSIZE;
+ gd_yoffset = ED_CTRL4_BUTTONS_YPOS + y * ED_CTRL4_BUTTON_YSIZE;
+ width = ED_CTRL4_BUTTON_XSIZE;
+ height = ED_CTRL4_BUTTON_YSIZE;
+
+ gd_x1 = DOOR_GFX_PAGEX6 + ED_CTRL4_BUTTONS_GFX_XPOS + gd_xoffset;
+ gd_x2 = DOOR_GFX_PAGEX5 + ED_CTRL4_BUTTONS_GFX_XPOS + gd_xoffset;
+ gd_y1 = DOOR_GFX_PAGEY1 + ED_CTRL4_BUTTONS_GFX_YPOS + gd_yoffset;
+ gd_y2 = 0; /* no alternative graphic for these buttons */
+ }
+
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_INFO_TEXT, control_info[i].text,
+ GDI_X, EX + gd_xoffset,
+ GDI_Y, EY + gd_yoffset,
+ GDI_WIDTH, width,
+ GDI_HEIGHT, height,
+ GDI_TYPE, button_type,
+ GDI_STATE, GD_BUTTON_UNPRESSED,
+ GDI_RADIO_NR, radio_button_nr,
+ GDI_CHECKED, checked,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y1,
+ GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y2,
+ GDI_ALT_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2,
+ GDI_EVENT_MASK, event_mask,
+ GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
+ GDI_CALLBACK_ACTION, HandleControlButtons,
+ GDI_END);
+
+ if (gi == NULL)
+ Error(ERR_EXIT, "cannot create gadget");
+
+ level_editor_gadget[id] = gi;
+ }
+
+ /* create buttons for scrolling of drawing area and element list */
+ for (i = 0; i < ED_NUM_SCROLLBUTTONS; i++)
+ {
+ int id = scrollbutton_info[i].gadget_id;
+ int x, y, width, height;
+ int gd_x1, gd_x2, gd_y1, gd_y2;
+
+ x = scrollbutton_info[i].x;
+ y = scrollbutton_info[i].y;
+
+ event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED;
+
+ if (id == GADGET_ID_SCROLL_LIST_UP ||
+ id == GADGET_ID_SCROLL_LIST_DOWN)
+ {
+ x += DX;
+ y += DY;
+ width = ED_SCROLLBUTTON2_XSIZE;
+ height = ED_SCROLLBUTTON2_YSIZE;
+ gd_x1 = DOOR_GFX_PAGEX8 + scrollbutton_info[i].gd_x;
+ gd_y1 = DOOR_GFX_PAGEY1 + scrollbutton_info[i].gd_y;
+ gd_x2 = gd_x1 - ED_SCROLLBUTTON2_XSIZE;
+ gd_y2 = gd_y1;
+ }
+ else
+ {
+ x += SX;
+ y += SY;
+ width = ED_SCROLLBUTTON_XSIZE;
+ height = ED_SCROLLBUTTON_YSIZE;
+ gd_x1 = DOOR_GFX_PAGEX8 + scrollbutton_info[i].gd_x;
+ gd_y1 = DOOR_GFX_PAGEY1 + scrollbutton_info[i].gd_y;
+ gd_x2 = gd_x1 - ED_SCROLLBUTTON_XSIZE;
+ gd_y2 = gd_y1;
+ }
+
+ 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, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2,
+ GDI_EVENT_MASK, event_mask,
+ GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
+ GDI_CALLBACK_ACTION, HandleControlButtons,
+ GDI_END);
+
+ if (gi == NULL)
+ Error(ERR_EXIT, "cannot create gadget");
+
+ level_editor_gadget[id] = gi;
+ }
+
+ /* create buttons for element list */
+ for (i = 0; i < ED_NUM_ELEMENTLIST_BUTTONS; i++)
+ {
+ Bitmap *deco_bitmap;
+ int deco_x, deco_y, deco_xpos, deco_ypos;
+ int gd_xoffset, gd_yoffset;
+ int gd_x1, gd_x2, gd_y;
+ int x = i % ED_ELEMENTLIST_BUTTONS_HORIZ;
+ int y = i / ED_ELEMENTLIST_BUTTONS_HORIZ;
+ int id = GADGET_ID_ELEMENTLIST_FIRST + i;
+ int element = editor_elements[i];
+
+ event_mask = GD_EVENT_RELEASED;
+
+ gd_xoffset = ED_ELEMENTLIST_XPOS + x * ED_ELEMENTLIST_XSIZE;
+ gd_yoffset = ED_ELEMENTLIST_YPOS + y * ED_ELEMENTLIST_YSIZE;
+
+ gd_x1 = DOOR_GFX_PAGEX6 + ED_ELEMENTLIST_XPOS + ED_ELEMENTLIST_XSIZE;
+ gd_x2 = DOOR_GFX_PAGEX6 + ED_ELEMENTLIST_XPOS;
+ gd_y = DOOR_GFX_PAGEY1 + ED_ELEMENTLIST_YPOS;
+
+ getMiniGraphicSource(el2edimg(element), &deco_bitmap, &deco_x, &deco_y);
+ deco_xpos = (ED_ELEMENTLIST_XSIZE - MINI_TILEX) / 2;
+ deco_ypos = (ED_ELEMENTLIST_YSIZE - MINI_TILEY) / 2;
+
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_INFO_TEXT, getElementInfoText(element),
+ GDI_X, DX + gd_xoffset,
+ GDI_Y, DY + gd_yoffset,
+ GDI_WIDTH, ED_ELEMENTLIST_XSIZE,
+ GDI_HEIGHT, ED_ELEMENTLIST_YSIZE,
+ GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
+ GDI_STATE, GD_BUTTON_UNPRESSED,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
+ GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
+ GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
+ GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
+ GDI_DECORATION_SHIFTING, 1, 1,
+ GDI_EVENT_MASK, event_mask,
+ GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
+ GDI_CALLBACK_ACTION, HandleControlButtons,
+ GDI_END);
+
+ if (gi == NULL)
+ Error(ERR_EXIT, "cannot create gadget");
+
+ level_editor_gadget[id] = gi;
+ }
+}
+
+static void CreateCounterButtons()
+{
+ int max_infotext_len = getMaxInfoTextLength();
+ int i;
+
+ for (i = 0; i < ED_NUM_COUNTERBUTTONS; i++)
+ {
+ int j;
+ int x = SX + counterbutton_info[i].x; /* down count button */
+ int y = SY + counterbutton_info[i].y;
+
+ /* determine horizontal position to the right of specified gadget */
+ if (counterbutton_info[i].gadget_id_align != GADGET_ID_NONE)
+ x = (right_gadget_border[counterbutton_info[i].gadget_id_align] +
+ ED_GADGET_TEXT_DISTANCE);
+
+ /* determine horizontal offset for leading text */
+ if (counterbutton_info[i].text_left != NULL)
+ x += getTextWidthForGadget(counterbutton_info[i].text_left);
+
+ for (j = 0; j < 2; j++)
+ {
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+ struct GadgetInfo *gi;
+ int id = (j == 0 ?
+ counterbutton_info[i].gadget_id_down :
+ counterbutton_info[i].gadget_id_up);
+ int gd_xoffset;
+ int gd_x, gd_x1, gd_x2, gd_y;
+ int x_size, y_size;
+ unsigned long event_mask;
+ char infotext[max_infotext_len + 1];
+
+ event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED;
+
+ if (i == ED_COUNTER_ID_SELECT_LEVEL)
+ {
+ int sid = (j == 0 ?
+ ED_SCROLLBUTTON_ID_AREA_LEFT :
+ ED_SCROLLBUTTON_ID_AREA_RIGHT);
+
+ event_mask |= GD_EVENT_RELEASED;
+
+ if (j == 1)
+ x += 2 * ED_GADGET_DISTANCE;
+ y += ED_GADGET_DISTANCE;
+
+ gd_x1 = DOOR_GFX_PAGEX8 + scrollbutton_info[sid].gd_x;
+ gd_x2 = gd_x1 - ED_SCROLLBUTTON_XSIZE;
+ gd_y = DOOR_GFX_PAGEY1 + scrollbutton_info[sid].gd_y;
+ x_size = ED_SCROLLBUTTON_XSIZE;
+ y_size = ED_SCROLLBUTTON_YSIZE;
+ }
+ else
+ {
+ gd_xoffset = (j == 0 ? ED_BUTTON_MINUS_XPOS : ED_BUTTON_PLUS_XPOS);
+ gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
+ gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
+ gd_y = DOOR_GFX_PAGEY1 + ED_BUTTON_COUNT_YPOS;
+ x_size = ED_BUTTON_COUNT_XSIZE;
+ y_size = ED_BUTTON_COUNT_YSIZE;
+ }
+
+ sprintf(infotext, "%s counter value by 1, 5 or 10",
+ (j == 0 ? "decrease" : "increase"));
+
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_INFO_TEXT, infotext,
+ GDI_X, x,
+ GDI_Y, y,
+ GDI_WIDTH, x_size,
+ GDI_HEIGHT, y_size,
+ GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
+ GDI_STATE, GD_BUTTON_UNPRESSED,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
+ GDI_EVENT_MASK, event_mask,
+ GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
+ GDI_CALLBACK_ACTION, HandleCounterButtons,
+ GDI_END);
+
+ if (gi == NULL)
+ Error(ERR_EXIT, "cannot create gadget");
+
+ level_editor_gadget[id] = gi;
+ right_gadget_border[id] =
+ getRightGadgetBorder(gi, counterbutton_info[i].text_right);
+
+ x += gi->width + ED_GADGET_DISTANCE; /* text count button */
+
+ if (j == 0)
+ {
+ int font_type = FONT_INPUT_1;
+ int font_type_active = FONT_INPUT_1_ACTIVE;
+ int gd_width = ED_WIN_COUNT_XSIZE;
+
+ id = counterbutton_info[i].gadget_id_text;
+ event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING;
+
+ if (i == ED_COUNTER_ID_SELECT_LEVEL)
+ {
+ font_type = FONT_LEVEL_NUMBER;
+ font_type_active = FONT_LEVEL_NUMBER;
+
+ x += 2 * ED_GADGET_DISTANCE;
+ y -= ED_GADGET_DISTANCE;
+
+ gd_x = DOOR_GFX_PAGEX6 + ED_WIN_COUNT2_XPOS;
+ gd_y = DOOR_GFX_PAGEY1 + ED_WIN_COUNT2_YPOS;
+ gd_width = ED_WIN_COUNT2_XSIZE;
+ }
+ else
+ {
+ gd_x = DOOR_GFX_PAGEX4 + ED_WIN_COUNT_XPOS;
+ gd_y = DOOR_GFX_PAGEY1 + ED_WIN_COUNT_YPOS;
+ }
+
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_INFO_TEXT, "enter counter value",
+ GDI_X, x,
+ GDI_Y, y,
+ GDI_TYPE, GD_TYPE_TEXT_INPUT_NUMERIC,
+ GDI_NUMBER_VALUE, 0,
+ GDI_NUMBER_MIN, counterbutton_info[i].min_value,
+ GDI_NUMBER_MAX, counterbutton_info[i].max_value,
+ GDI_TEXT_SIZE, 3, /* minimal counter text size */
+ GDI_TEXT_FONT, font_type,
+ GDI_TEXT_FONT_ACTIVE, font_type_active,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y,
+ GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE,
+ GDI_DESIGN_WIDTH, gd_width,
+ GDI_EVENT_MASK, event_mask,
+ GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
+ GDI_CALLBACK_ACTION, HandleCounterButtons,
+ GDI_END);
+
+ if (gi == NULL)
+ Error(ERR_EXIT, "cannot create gadget");
+
+ level_editor_gadget[id] = gi;
+ right_gadget_border[id] =
+ getRightGadgetBorder(gi, counterbutton_info[i].text_right);
+
+ x += gi->width + ED_GADGET_DISTANCE; /* up count button */
+ }
+ }
+ }
+}
+
+static void CreateDrawingAreas()
+{
+ int i;
+
+ for (i = 0; i < ED_NUM_DRAWING_AREAS; i++)
+ {
+ struct GadgetInfo *gi;
+ unsigned long event_mask;
+ int id = drawingarea_info[i].gadget_id;
+ int x = SX + drawingarea_info[i].x;
+ int y = SY + drawingarea_info[i].y;
+ int area_xsize = drawingarea_info[i].area_xsize;
+ int area_ysize = drawingarea_info[i].area_ysize;
+
+ event_mask =
+ GD_EVENT_PRESSED | GD_EVENT_RELEASED | GD_EVENT_MOVING |
+ GD_EVENT_OFF_BORDERS;
+
+ /* determine horizontal position to the right of specified gadget */
+ if (drawingarea_info[i].gadget_id_align != GADGET_ID_NONE)
+ x = (right_gadget_border[drawingarea_info[i].gadget_id_align] +
+ ED_DRAWINGAREA_TEXT_DISTANCE);
+
+ /* determine horizontal offset for leading text */
+ if (drawingarea_info[i].text_left != NULL)
+ x += getTextWidthForDrawingArea(drawingarea_info[i].text_left);
+
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_X, x,
+ GDI_Y, y,
+ GDI_TYPE, GD_TYPE_DRAWING_AREA,
+ GDI_AREA_SIZE, area_xsize, area_ysize,
+ GDI_ITEM_SIZE, MINI_TILEX, MINI_TILEY,
+ GDI_EVENT_MASK, event_mask,
+ GDI_CALLBACK_INFO, HandleDrawingAreaInfo,
+ GDI_CALLBACK_ACTION, HandleDrawingAreas,
+ GDI_END);
+
+ if (gi == NULL)
+ Error(ERR_EXIT, "cannot create gadget");
+
+ level_editor_gadget[id] = gi;
+ right_gadget_border[id] =
+ getRightGadgetBorder(gi, drawingarea_info[i].text_right);
+ }
+}
+
+static void CreateTextInputGadgets()
+{
+ int max_infotext_len = getMaxInfoTextLength();
+ int i;
+
+ for (i = 0; i < ED_NUM_TEXTINPUT; i++)
+ {
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+ int gd_x, gd_y;
+ struct GadgetInfo *gi;
+ unsigned long event_mask;
+ char infotext[MAX_OUTPUT_LINESIZE + 1];
+ int id = textinput_info[i].gadget_id;
+
+ event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING;
+
+ gd_x = DOOR_GFX_PAGEX4 + ED_WIN_COUNT_XPOS;
+ gd_y = DOOR_GFX_PAGEY1 + ED_WIN_COUNT_YPOS;
+
+ sprintf(infotext, "Enter %s", textinput_info[i].infotext);
+ infotext[max_infotext_len] = '\0';
+
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_INFO_TEXT, infotext,
+ GDI_X, SX + textinput_info[i].x,
+ GDI_Y, SY + textinput_info[i].y,
+ GDI_TYPE, GD_TYPE_TEXT_INPUT_ALPHANUMERIC,
+ GDI_TEXT_VALUE, textinput_info[i].value,
+ GDI_TEXT_SIZE, textinput_info[i].size,
+ GDI_TEXT_FONT, FONT_INPUT_1,
+ GDI_TEXT_FONT_ACTIVE, FONT_INPUT_1_ACTIVE,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y,
+ GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE,
+ GDI_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE,
+ GDI_EVENT_MASK, event_mask,
+ GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
+ GDI_CALLBACK_ACTION, HandleTextInputGadgets,
+ GDI_END);
+
+ if (gi == NULL)
+ Error(ERR_EXIT, "cannot create gadget");
+
+ level_editor_gadget[id] = gi;
+ }
+}
+
+static void CreateTextAreaGadgets()
+{
+ int max_infotext_len = getMaxInfoTextLength();
+ int i;
+
+ for (i = 0; i < ED_NUM_TEXTAREAS; i++)
+ {
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+ int gd_x, gd_y;
+ struct GadgetInfo *gi;
+ unsigned long event_mask;
+ char infotext[MAX_OUTPUT_LINESIZE + 1];
+ int id = textarea_info[i].gadget_id;
+ int area_xsize = textarea_info[i].xsize;
+ int area_ysize = textarea_info[i].ysize;
+
+ event_mask = GD_EVENT_TEXT_LEAVING;
+
+ gd_x = DOOR_GFX_PAGEX4 + ED_WIN_COUNT_XPOS;
+ gd_y = DOOR_GFX_PAGEY1 + ED_WIN_COUNT_YPOS;
+
+ sprintf(infotext, "Enter %s", textarea_info[i].infotext);
+ infotext[max_infotext_len] = '\0';
+
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_INFO_TEXT, infotext,
+ GDI_X, SX + textarea_info[i].x,
+ GDI_Y, SY + textarea_info[i].y,
+ GDI_TYPE, GD_TYPE_TEXT_AREA,
+ GDI_AREA_SIZE, area_xsize, area_ysize,
+ GDI_TEXT_FONT, FONT_INPUT_1,
+ GDI_TEXT_FONT_ACTIVE, FONT_INPUT_1_ACTIVE,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y,
+ GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE,
+ GDI_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE,
+ GDI_EVENT_MASK, event_mask,
+ GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
+ GDI_CALLBACK_ACTION, HandleTextAreaGadgets,
+ GDI_END);
+
+ if (gi == NULL)
+ Error(ERR_EXIT, "cannot create gadget");
+
+ level_editor_gadget[id] = gi;
+ }
+}
+
+static void CreateSelectboxGadgets()
+{
+ int max_infotext_len = getMaxInfoTextLength();
+ int i, j;
+
+ for (i = 0; i < ED_NUM_SELECTBOX; i++)
+ {
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+ int gd_x, gd_y;
+ struct GadgetInfo *gi;
+ unsigned long event_mask;
+ char infotext[MAX_OUTPUT_LINESIZE + 1];
+ int id = selectbox_info[i].gadget_id;
+ int x = SX + selectbox_info[i].x;
+ int y = SY + selectbox_info[i].y;
+
+ if (selectbox_info[i].size == -1) /* dynamically determine size */
+ {
+ /* (we cannot use -1 for uninitialized values if we directly compare
+ with results from strlen(), because the '<' and '>' operation will
+ implicitely cast -1 to an unsigned integer value!) */
+ selectbox_info[i].size = 0;
+
+ for (j = 0; selectbox_info[i].options[j].text != NULL; j++)
+ if (strlen(selectbox_info[i].options[j].text) > selectbox_info[i].size)
+ selectbox_info[i].size = strlen(selectbox_info[i].options[j].text);
+
+ selectbox_info[i].size++; /* add one character empty space */
+ }
+
+ event_mask = GD_EVENT_RELEASED |
+ GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING;
+
+ gd_x = DOOR_GFX_PAGEX4 + ED_SELECTBOX_XPOS;
+ gd_y = DOOR_GFX_PAGEY1 + ED_SELECTBOX_YPOS;
+
+ /* determine horizontal position to the right of specified gadget */
+ if (selectbox_info[i].gadget_id_align != GADGET_ID_NONE)
+ x = (right_gadget_border[selectbox_info[i].gadget_id_align] +
+ ED_GADGET_TEXT_DISTANCE);
+
+ /* determine horizontal offset for leading text */
+ if (selectbox_info[i].text_left != NULL)
+ x += getTextWidthForGadget(selectbox_info[i].text_left);
+
+ sprintf(infotext, "Select %s", selectbox_info[i].infotext);
+ infotext[max_infotext_len] = '\0';
+
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_INFO_TEXT, infotext,
+ GDI_X, x,
+ GDI_Y, y,
+ GDI_TYPE, GD_TYPE_SELECTBOX,
+ GDI_SELECTBOX_OPTIONS, selectbox_info[i].options,
+ GDI_TEXT_SIZE, selectbox_info[i].size,
+ GDI_TEXT_FONT, FONT_INPUT_1,
+ GDI_TEXT_FONT_ACTIVE, FONT_INPUT_1_ACTIVE,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y,
+ GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE,
+ GDI_BORDER_SIZE_SELECTBUTTON, ED_SELECTBOX_BUTTON_XSIZE,
+ GDI_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE,
+ GDI_EVENT_MASK, event_mask,
+ GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
+ GDI_CALLBACK_ACTION, HandleSelectboxGadgets,
+ GDI_END);
+
+ if (gi == NULL)
+ Error(ERR_EXIT, "cannot create gadget");
+
+ level_editor_gadget[id] = gi;
+ right_gadget_border[id] =
+ getRightGadgetBorder(gi, selectbox_info[i].text_right);
+ }
+}
+
+static void CreateTextbuttonGadgets()
+{
+ int max_infotext_len = getMaxInfoTextLength();
+ int i;
+
+ for (i = 0; i < ED_NUM_TEXTBUTTONS; i++)
+ {
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+ int gd_x1, gd_x2, gd_y1, gd_y2;
+ struct GadgetInfo *gi;
+ unsigned long event_mask;
+ char infotext[MAX_OUTPUT_LINESIZE + 1];
+ int id = textbutton_info[i].gadget_id;
+ int x = SX + textbutton_info[i].x;
+ int y = SY + textbutton_info[i].y;
+
+ if (textbutton_info[i].size == -1) /* dynamically determine size */
+ textbutton_info[i].size = strlen(textbutton_info[i].text);
+
+ event_mask = GD_EVENT_RELEASED;
+
+ if (id >= GADGET_ID_PROPERTIES_INFO && id <= GADGET_ID_PROPERTIES_CHANGE)
+ {
+ gd_x1 = DOOR_GFX_PAGEX4 + ED_TEXTBUTTON_TAB_XPOS;
+ gd_x2 = DOOR_GFX_PAGEX3 + ED_TEXTBUTTON_TAB_XPOS;
+ gd_y1 = DOOR_GFX_PAGEY1 + ED_TEXTBUTTON_TAB_YPOS;
+ gd_y2 = DOOR_GFX_PAGEY1 + ED_TEXTBUTTON_TAB_INACTIVE_YPOS;
+ }
+ else
+ {
+ gd_x1 = DOOR_GFX_PAGEX4 + ED_TEXTBUTTON_XPOS;
+ gd_x2 = DOOR_GFX_PAGEX3 + ED_TEXTBUTTON_XPOS;
+ gd_y1 = DOOR_GFX_PAGEY1 + ED_TEXTBUTTON_YPOS;
+ gd_y2 = DOOR_GFX_PAGEY1 + ED_TEXTBUTTON_INACTIVE_YPOS;
+ }
+
+ sprintf(infotext, "%s", textbutton_info[i].infotext);
+ infotext[max_infotext_len] = '\0';
+
+ /* determine horizontal position to the right of specified gadget */
+ if (textbutton_info[i].gadget_id_align != GADGET_ID_NONE)
+ x = (right_gadget_border[textbutton_info[i].gadget_id_align] +
+ ED_GADGET_TEXT_DISTANCE);
+
+ /* determine horizontal offset for leading text */
+ if (textbutton_info[i].text_left != NULL)
+ x += getTextWidthForGadget(textbutton_info[i].text_left);
+
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_INFO_TEXT, infotext,
+ GDI_X, x,
+ GDI_Y, y,
+ GDI_TYPE, GD_TYPE_TEXT_BUTTON,
+ GDI_TEXT_VALUE, textbutton_info[i].text,
+ GDI_TEXT_SIZE, textbutton_info[i].size,
+ GDI_TEXT_FONT, FONT_INPUT_2_ACTIVE,
+ GDI_TEXT_FONT_ACTIVE, FONT_INPUT_2,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y1,
+ GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y2,
+ GDI_BORDER_SIZE, ED_BORDER_TEXT_XSIZE, ED_BORDER_SIZE,
+ GDI_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE,
+ GDI_DECORATION_SHIFTING, 1, 1,
+ GDI_EVENT_MASK, event_mask,
+ GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
+ GDI_CALLBACK_ACTION, HandleTextbuttonGadgets,
+ GDI_END);
+
+ if (gi == NULL)
+ Error(ERR_EXIT, "cannot create gadget");
+
+ level_editor_gadget[id] = gi;
+ right_gadget_border[id] =
+ getRightGadgetBorder(gi, textbutton_info[i].text_right);
+ }
+}
+
+static void CreateGraphicbuttonGadgets()
+{
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+ struct GadgetInfo *gi;
+ unsigned long event_mask;
+ int i;
+
+ /* create buttons for scrolling of drawing area and element list */
+ for (i = 0; i < ED_NUM_GRAPHICBUTTONS; i++)
+ {
+ int id = graphicbutton_info[i].gadget_id;
+ int gd_x1, gd_x2, gd_y1, gd_y2;
+ int x = SX + graphicbutton_info[i].x;
+ int y = SY + graphicbutton_info[i].y;
+
+ event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED;
+
+ if (i <= ED_GRAPHICBUTTON_ID_NEXT_CHANGE_PAGE)
+ {
+ gd_x1 = DOOR_GFX_PAGEX4 + graphicbutton_info[i].gd_x;
+ gd_y1 = DOOR_GFX_PAGEY1 + graphicbutton_info[i].gd_y;
+ gd_x2 = DOOR_GFX_PAGEX3 + graphicbutton_info[i].gd_x;
+ gd_y2 = gd_y1;
+ }
+ else /* (i <= ED_GRAPHICBUTTON_ID_PASTE_CHANGE_PAGE) */
+ {
+ gd_x1 = DOOR_GFX_PAGEX6 + graphicbutton_info[i].gd_x;
+ gd_y1 = DOOR_GFX_PAGEY1 + graphicbutton_info[i].gd_y;
+ gd_x2 = gd_x1 - ED_BUTTON_COUNT_XSIZE;
+ gd_y2 = gd_y1;
+ }
+
+ /* determine horizontal position to the right of specified gadget */
+ if (graphicbutton_info[i].gadget_id_align != GADGET_ID_NONE)
+ x = (right_gadget_border[graphicbutton_info[i].gadget_id_align] +
+ ED_GADGET_TEXT_DISTANCE);
+
+ /* determine horizontal offset for leading text */
+ if (graphicbutton_info[i].text_left != NULL)
+ x += getTextWidthForGadget(graphicbutton_info[i].text_left);
+
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_INFO_TEXT, graphicbutton_info[i].infotext,
+ GDI_X, x,
+ GDI_Y, y,
+ GDI_WIDTH, graphicbutton_info[i].width,
+ GDI_HEIGHT, graphicbutton_info[i].height,
+ GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
+ GDI_STATE, GD_BUTTON_UNPRESSED,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2,
+ GDI_EVENT_MASK, event_mask,
+ GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
+ GDI_CALLBACK_ACTION, HandleGraphicbuttonGadgets,
+ GDI_END);
+
+ if (gi == NULL)
+ Error(ERR_EXIT, "cannot create gadget");
+
+ level_editor_gadget[id] = gi;
+ right_gadget_border[id] =
+ getRightGadgetBorder(gi, graphicbutton_info[i].text_right);
+ }
+}
+
+static void CreateScrollbarGadgets()
+{
+ int i;
+
+ for (i = 0; i < ED_NUM_SCROLLBARS; i++)
+ {
+ int id = scrollbar_info[i].gadget_id;
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+ int gd_x1, gd_x2, gd_y1, gd_y2;
+ struct GadgetInfo *gi;
+ int items_max, items_visible, item_position;
+ unsigned long event_mask;
+
+ if (i == ED_SCROLLBAR_ID_LIST_VERTICAL)
+ {
+ items_max = num_editor_elements / ED_ELEMENTLIST_BUTTONS_HORIZ;
+ items_visible = ED_ELEMENTLIST_BUTTONS_VERT;
+ item_position = element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ;
+ }
+ else /* drawing area scrollbars */
+ {
+ if (scrollbar_info[i].type == GD_TYPE_SCROLLBAR_HORIZONTAL)
+ {
+ items_max = MAX(lev_fieldx + 2, ed_fieldx);
+ items_visible = ed_fieldx;
+ item_position = 0;
+ }
+ else
+ {
+ items_max = MAX(lev_fieldy + 2, ed_fieldy);
+ items_visible = ed_fieldy;
+ item_position = 0;
+ }
+ }
+
+ event_mask = GD_EVENT_MOVING | GD_EVENT_OFF_BORDERS;
+
+ gd_x1 = DOOR_GFX_PAGEX8 + scrollbar_info[i].gd_x;
+ gd_x2 = (gd_x1 - (scrollbar_info[i].type == GD_TYPE_SCROLLBAR_HORIZONTAL ?
+ scrollbar_info[i].height : scrollbar_info[i].width));
+ gd_y1 = DOOR_GFX_PAGEY1 + scrollbar_info[i].gd_y;
+ gd_y2 = DOOR_GFX_PAGEY1 + scrollbar_info[i].gd_y;
+
+ 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, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2,
+ GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE,
+ GDI_EVENT_MASK, event_mask,
+ GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
+ GDI_CALLBACK_ACTION, HandleControlButtons,
+ GDI_END);
+
+ if (gi == NULL)
+ Error(ERR_EXIT, "cannot create gadget");
+
+ level_editor_gadget[id] = gi;
+ }
+}
+
+static void CreateCheckbuttonGadgets()
+{
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+ struct GadgetInfo *gi;
+ unsigned long event_mask;
+ int gd_x1, gd_x2, gd_x3, gd_x4, gd_y;
+ int i;
+
+ event_mask = GD_EVENT_PRESSED;
+
+ gd_x1 = DOOR_GFX_PAGEX4 + ED_CHECKBUTTON_UNCHECKED_XPOS;
+ gd_x2 = DOOR_GFX_PAGEX3 + ED_CHECKBUTTON_UNCHECKED_XPOS;
+ gd_x3 = DOOR_GFX_PAGEX4 + ED_CHECKBUTTON_CHECKED_XPOS;
+ gd_x4 = DOOR_GFX_PAGEX3 + ED_CHECKBUTTON_CHECKED_XPOS;
+ gd_y = DOOR_GFX_PAGEY1 + ED_RADIOBUTTON_YPOS;
+
+ for (i = 0; i < ED_NUM_CHECKBUTTONS; i++)
+ {
+ int id = checkbutton_info[i].gadget_id;
+ int x = SX + checkbutton_info[i].x;
+ int y = SY + checkbutton_info[i].y;
+
+ if (id == GADGET_ID_STICK_ELEMENT)
+ gd_y = DOOR_GFX_PAGEY1 + ED_STICKYBUTTON_YPOS;
+ else
+ gd_y = DOOR_GFX_PAGEY1 + ED_CHECKBUTTON_YPOS;
+
+ /* determine horizontal position to the right of specified gadget */
+ if (checkbutton_info[i].gadget_id_align != GADGET_ID_NONE)
+ x = (right_gadget_border[checkbutton_info[i].gadget_id_align] +
+ ED_GADGET_TEXT_DISTANCE);
+
+ /* determine horizontal offset for leading text */
+ if (checkbutton_info[i].text_left != NULL)
+ x += getTextWidthForGadget(checkbutton_info[i].text_left);
+
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_INFO_TEXT, checkbutton_info[i].infotext,
+ GDI_X, x,
+ GDI_Y, y,
+ GDI_WIDTH, ED_CHECKBUTTON_XSIZE,
+ GDI_HEIGHT, ED_CHECKBUTTON_YSIZE,
+ GDI_TYPE, GD_TYPE_CHECK_BUTTON,
+ GDI_CHECKED, *checkbutton_info[i].value,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
+ GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x3, gd_y,
+ GDI_ALT_DESIGN_PRESSED, gd_bitmap, gd_x4, gd_y,
+ GDI_EVENT_MASK, event_mask,
+ GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
+ GDI_CALLBACK_ACTION, HandleCheckbuttons,
+ GDI_END);
+
+ if (gi == NULL)
+ Error(ERR_EXIT, "cannot create gadget");
+
+ level_editor_gadget[id] = gi;
+ right_gadget_border[id] =
+ getRightGadgetBorder(gi, checkbutton_info[i].text_right);
+ }
+}
+
+static void CreateRadiobuttonGadgets()
+{
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+ struct GadgetInfo *gi;
+ unsigned long event_mask;
+ int gd_x1, gd_x2, gd_x3, gd_x4, gd_y;
+ int i;
+
+ event_mask = GD_EVENT_PRESSED;
+
+ gd_x1 = DOOR_GFX_PAGEX4 + ED_CHECKBUTTON_UNCHECKED_XPOS;
+ gd_x2 = DOOR_GFX_PAGEX3 + ED_CHECKBUTTON_UNCHECKED_XPOS;
+ gd_x3 = DOOR_GFX_PAGEX4 + ED_CHECKBUTTON_CHECKED_XPOS;
+ gd_x4 = DOOR_GFX_PAGEX3 + ED_CHECKBUTTON_CHECKED_XPOS;
+ gd_y = DOOR_GFX_PAGEY1 + ED_RADIOBUTTON_YPOS;
+
+ for (i = 0; i < ED_NUM_RADIOBUTTONS; i++)
+ {
+ int id = radiobutton_info[i].gadget_id;
+ int x = SX + radiobutton_info[i].x;
+ int y = SY + radiobutton_info[i].y;
+
+ int checked =
+ (*radiobutton_info[i].value == radiobutton_info[i].checked_value);
+
+ /* determine horizontal position to the right of specified gadget */
+ if (radiobutton_info[i].gadget_id_align != GADGET_ID_NONE)
+ x = (right_gadget_border[radiobutton_info[i].gadget_id_align] +
+ ED_GADGET_TEXT_DISTANCE);
+
+ /* determine horizontal offset for leading text */
+ if (radiobutton_info[i].text_left != NULL)
+ x += getTextWidthForGadget(radiobutton_info[i].text_left);
+
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_INFO_TEXT, radiobutton_info[i].infotext,
+ GDI_X, x,
+ GDI_Y, y,
+ GDI_WIDTH, ED_CHECKBUTTON_XSIZE,
+ GDI_HEIGHT, ED_CHECKBUTTON_YSIZE,
+ GDI_TYPE, GD_TYPE_RADIO_BUTTON,
+ GDI_RADIO_NR, radiobutton_info[i].radio_button_nr,
+ GDI_CHECKED, checked,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
+ GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x3, gd_y,
+ GDI_ALT_DESIGN_PRESSED, gd_bitmap, gd_x4, gd_y,
+ GDI_EVENT_MASK, event_mask,
+ GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
+ GDI_CALLBACK_ACTION, HandleRadiobuttons,
+ GDI_END);