+ /* one for the level drawing area ... */
+ id = GADGET_ID_DRAWING_LEVEL;
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_X, SX,
+ GDI_Y, SY,
+ GDI_TYPE, GD_TYPE_DRAWING_AREA,
+ GDI_AREA_SIZE, ed_fieldx, ed_fieldy,
+ 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;
+
+ /* ... up to eight areas for element content ... */
+ for (i=0; i<MAX_ELEMENT_CONTENTS; i++)
+ {
+ int gx = SX + ED_AREA_ELEM_CONTENT_XPOS + 5 * (i % 4) * MINI_TILEX;
+ int gy = SX + ED_AREA_ELEM_CONTENT_YPOS + 6 * (i / 4) * MINI_TILEY;
+
+ id = GADGET_ID_ELEMENT_CONTENT_0 + i;
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_X, gx,
+ GDI_Y, gy,
+ GDI_WIDTH, 3 * MINI_TILEX,
+ GDI_HEIGHT, 3 * MINI_TILEY,
+ GDI_TYPE, GD_TYPE_DRAWING_AREA,
+ 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;
+ }
+
+ /* ... one for the amoeba content ... */
+ id = GADGET_ID_AMOEBA_CONTENT;
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_X, SX + ED_AREA_ELEM_CONTENT_XPOS,
+ GDI_Y, SY + ED_AREA_ELEM_CONTENT_YPOS,
+ GDI_WIDTH, MINI_TILEX,
+ GDI_HEIGHT, MINI_TILEY,
+ GDI_TYPE, GD_TYPE_DRAWING_AREA,
+ 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;
+
+ /* ... one for each custom element optional graphic element ... */
+ id = GADGET_ID_CUSTOM_GRAPHIC;
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_X, SX + ED_AREA_ELEM_CONTENT3_XPOS,
+ GDI_Y, SY + ED_AREA_ELEM_CONTENT3_YPOS,
+ GDI_WIDTH, MINI_TILEX,
+ GDI_HEIGHT, MINI_TILEY,
+ GDI_TYPE, GD_TYPE_DRAWING_AREA,
+ 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;
+
+ /* ... one area for custom element explosion content ... */
+ id = GADGET_ID_CUSTOM_CONTENT;
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_X, SX + ED_AREA_ELEM_CONTENT4_XPOS,
+ GDI_Y, SX + ED_AREA_ELEM_CONTENT4_YPOS,
+ GDI_WIDTH, 3 * MINI_TILEX,
+ GDI_HEIGHT, 3 * MINI_TILEY,
+ GDI_TYPE, GD_TYPE_DRAWING_AREA,
+ 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;
+
+ /* ... one for each custom element change target element ... */
+ id = GADGET_ID_CUSTOM_CHANGE_TARGET;
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_X, SX + ED_AREA_ELEM_CONTENT2_XPOS,
+ GDI_Y, SY + ED_AREA_ELEM_CONTENT2_YPOS,
+ GDI_WIDTH, MINI_TILEX,
+ GDI_HEIGHT, MINI_TILEY,
+ GDI_TYPE, GD_TYPE_DRAWING_AREA,
+ 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;
+
+ /* ... one area for extended custom element change target content ... */
+ id = GADGET_ID_CUSTOM_CHANGE_CONTENT;
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_X, SX + ED_AREA_ELEM_CONTENT6_XPOS,
+ GDI_Y, SX + ED_AREA_ELEM_CONTENT6_YPOS,
+ GDI_WIDTH, 3 * MINI_TILEX,
+ GDI_HEIGHT, 3 * MINI_TILEY,
+ GDI_TYPE, GD_TYPE_DRAWING_AREA,
+ 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;
+
+ /* ... one for each custom element change trigger element ... */
+ id = GADGET_ID_CUSTOM_CHANGE_TRIGGER;
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_X, SX + ED_AREA_ELEM_CONTENT5_XPOS,
+ GDI_Y, SY + ED_AREA_ELEM_CONTENT5_YPOS,
+ GDI_WIDTH, MINI_TILEX,
+ GDI_HEIGHT, MINI_TILEY,
+ GDI_TYPE, GD_TYPE_DRAWING_AREA,
+ 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;
+
+ /* ... and one for random placement background restrictions */
+ id = GADGET_ID_RANDOM_BACKGROUND;
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_X, SX + ED_AREA_RANDOM_BACKGROUND_XPOS,
+ GDI_Y, SY + ED_AREA_RANDOM_BACKGROUND_YPOS,
+ GDI_WIDTH, MINI_TILEX,
+ GDI_HEIGHT, MINI_TILEY,
+ GDI_TYPE, GD_TYPE_DRAWING_AREA,
+ 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;
+}
+
+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_TEXTINPUT_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 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;
+ int xoffset = 0;
+ struct GadgetInfo *gi;
+ unsigned long event_mask;
+ char infotext[MAX_OUTPUT_LINESIZE + 1];
+ int id = selectbox_info[i].gadget_id;
+
+ 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 offset for leading selectbox text */
+ if (selectbox_info[i].text_left != NULL)
+ xoffset = (getFontWidth(FONT_TEXT_1) *
+ strlen(selectbox_info[i].text_left) +
+ ED_GADGET_TEXT_DISTANCE);
+
+ 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, SX + selectbox_info[i].x + xoffset,
+ GDI_Y, SY + selectbox_info[i].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, getFontWidth(FONT_INPUT_1),
+ 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;
+ }
+}
+
+static void CreateTextbuttonGadgets()
+{
+ int max_infotext_len = getMaxInfoTextLength();
+ int i;
+
+ for (i=0; i<ED_NUM_TEXTBUTTON; 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;
+
+ 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_ADVANCED)
+ {
+ 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';
+
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_INFO_TEXT, infotext,
+ GDI_X, SX + textbutton_info[i].x,
+ GDI_Y, SY + textbutton_info[i].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_BORDER2_SIZE, 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;
+ }
+}
+
+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 = 0;
+ }
+ 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;
+ boolean checked;
+ 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;
+
+ checked =
+ (*radiobutton_info[i].value == radiobutton_info[i].checked_value);
+
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_INFO_TEXT, radiobutton_info[i].infotext,
+ GDI_X, SX + radiobutton_info[i].x,
+ GDI_Y, SY + radiobutton_info[i].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);
+
+ if (gi == NULL)
+ Error(ERR_EXIT, "cannot create gadget");
+
+ level_editor_gadget[id] = gi;
+ }
+
+ for (i=0; i<ED_NUM_CHECKBUTTONS; i++)
+ {
+ int id = checkbutton_info[i].gadget_id;
+
+ if (id == GADGET_ID_STICK_ELEMENT)
+ gd_y = DOOR_GFX_PAGEY1 + ED_STICKYBUTTON_YPOS;
+ else
+ gd_y = DOOR_GFX_PAGEY1 + ED_CHECKBUTTON_YPOS;
+
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_INFO_TEXT, checkbutton_info[i].infotext,
+ GDI_X, SX + checkbutton_info[i].x,
+ GDI_Y, SY + checkbutton_info[i].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;
+ }
+}
+
+void CreateLevelEditorGadgets()
+{
+ int old_game_status = game_status;
+
+ /* setting 'game_status' is needed to get the right fonts for the editor */
+ game_status = GAME_MODE_EDITOR;
+
+ ReinitializeElementList();
+
+ CreateControlButtons();
+ CreateCounterButtons();
+ CreateDrawingAreas();
+ CreateTextInputGadgets();
+ CreateSelectboxGadgets();
+ CreateTextbuttonGadgets();
+ CreateScrollbarGadgets();
+ CreateCheckbuttonGadgets();
+
+ game_status = old_game_status;
+}
+
+void FreeLevelEditorGadgets()
+{
+ int i;
+
+ for (i=0; i<NUM_EDITOR_GADGETS; i++)
+ FreeGadget(level_editor_gadget[i]);
+}
+
+static void MapCounterButtons(int id)
+{
+ char infotext[MAX_OUTPUT_LINESIZE + 1];
+ int max_infotext_len = getMaxInfoTextLength();
+ int xoffset_above = 0;
+ int yoffset_above = -(MINI_TILEX + ED_GADGET_DISTANCE);
+ int xoffset_left = 0;
+ int yoffset_left = ED_BORDER_SIZE;
+ int xoffset_right = getCounterGadgetWidth();
+ int yoffset_right = ED_BORDER_SIZE;
+ int x, y;
+
+ if (counterbutton_info[id].text_above)
+ {
+ x = SX + counterbutton_info[id].x + xoffset_above;
+ y = SY + counterbutton_info[id].y + yoffset_above;
+
+ sprintf(infotext, "%s:", counterbutton_info[id].text_above);
+ infotext[max_infotext_len] = '\0';
+ DrawText(x, y, infotext, FONT_TEXT_1);
+ }
+
+ if (counterbutton_info[id].text_left)
+ {
+ x = SX + counterbutton_info[id].x + xoffset_left;
+ y = SY + counterbutton_info[id].y + yoffset_left;
+
+ sprintf(infotext, "%s", counterbutton_info[id].text_left);
+ infotext[max_infotext_len] = '\0';
+ DrawText(x, y, infotext, FONT_TEXT_1);
+ }
+
+ if (counterbutton_info[id].text_right)
+ {
+ int gadget_id = counterbutton_info[id].gadget_id_down;
+
+ x = level_editor_gadget[gadget_id]->x + xoffset_right;
+ y = SY + counterbutton_info[id].y + yoffset_right;
+
+ sprintf(infotext, "%s", counterbutton_info[id].text_right);
+ infotext[max_infotext_len] = '\0';
+ DrawText(x, y, infotext, FONT_TEXT_1);
+ }
+
+ ModifyEditorCounter(id, *counterbutton_info[id].value);
+
+ MapGadget(level_editor_gadget[counterbutton_info[id].gadget_id_down]);
+ MapGadget(level_editor_gadget[counterbutton_info[id].gadget_id_text]);
+ MapGadget(level_editor_gadget[counterbutton_info[id].gadget_id_up]);
+}
+
+static void MapControlButtons()
+{
+ int counter_id;
+ int i;
+
+ /* map toolbox buttons */
+ for (i=0; i<ED_NUM_CTRL_BUTTONS; i++)
+ MapGadget(level_editor_gadget[i]);
+
+ /* map buttons to select elements */
+ for (i=0; i<ED_NUM_ELEMENTLIST_BUTTONS; i++)
+ MapGadget(level_editor_gadget[GADGET_ID_ELEMENTLIST_FIRST + i]);
+ MapGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL]);
+ MapGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_UP]);
+ MapGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_DOWN]);
+
+ /* map buttons to select level */
+ counter_id = ED_COUNTER_ID_SELECT_LEVEL;
+ ModifyEditorCounterLimits(counter_id,
+ leveldir_current->first_level,
+ leveldir_current->last_level);
+ MapCounterButtons(counter_id);
+}
+
+static void MapDrawingArea(int id)
+{
+ MapGadget(level_editor_gadget[id]);
+}
+
+static void MapTextInputGadget(int id)
+{
+ char infotext[MAX_OUTPUT_LINESIZE + 1];
+ int max_infotext_len = getMaxInfoTextLength();
+ int xoffset_above = 0;
+ int yoffset_above = -(MINI_TILEX + ED_GADGET_DISTANCE);
+ int x = textinput_info[id].x + xoffset_above;
+ int y = textinput_info[id].y + yoffset_above;
+
+ sprintf(infotext, "%s:", textinput_info[id].infotext);
+ infotext[max_infotext_len] = '\0';
+ DrawTextF(x, y, FONT_TEXT_1, infotext);
+
+ ModifyGadget(level_editor_gadget[textinput_info[id].gadget_id],
+ GDI_TEXT_VALUE, textinput_info[id].value, GDI_END);
+
+ MapGadget(level_editor_gadget[textinput_info[id].gadget_id]);
+}
+
+static void MapSelectboxGadget(int id)
+{
+ int xoffset_left = 0;
+ int yoffset_left = ED_BORDER_SIZE;
+ int xoffset_right = ED_GADGET_TEXT_DISTANCE;
+ int yoffset_right = ED_BORDER_SIZE;
+ int x = selectbox_info[id].x + xoffset_left;
+ int y = selectbox_info[id].y + yoffset_left;
+
+ DrawTextF(x, y, FONT_TEXT_1, selectbox_info[id].text_left);
+
+ if (selectbox_info[id].text_right)
+ {
+ struct GadgetInfo *gi = level_editor_gadget[selectbox_info[id].gadget_id];
+
+ x = gi->x + gi->width + xoffset_right;
+ y = SY + selectbox_info[id].y + yoffset_right;
+
+ DrawText(x, y, selectbox_info[id].text_right, FONT_TEXT_1);
+ }
+
+ ModifyEditorSelectbox(id, *selectbox_info[id].value);
+
+ MapGadget(level_editor_gadget[selectbox_info[id].gadget_id]);
+}
+
+static void MapTextbuttonGadget(int id)
+{
+ MapGadget(level_editor_gadget[textbutton_info[id].gadget_id]);
+}
+
+static void MapRadiobuttonGadget(int id)
+{
+ int xoffset_right = ED_XOFFSET_CHECKBOX;
+ int yoffset_right = ED_BORDER_SIZE;
+ int x = radiobutton_info[id].x + xoffset_right;
+ int y = radiobutton_info[id].y + yoffset_right;
+ boolean checked =
+ (*radiobutton_info[id].value == radiobutton_info[id].checked_value);
+
+ DrawTextF(x, y, FONT_TEXT_1, radiobutton_info[id].text_right);
+ ModifyGadget(level_editor_gadget[radiobutton_info[id].gadget_id],
+ GDI_CHECKED, checked, GDI_END);
+
+ MapGadget(level_editor_gadget[radiobutton_info[id].gadget_id]);
+}
+
+static void MapCheckbuttonGadget(int id)
+{
+ int xoffset_right = ED_XOFFSET_CHECKBOX;
+ int yoffset_right = ED_BORDER_SIZE;
+ int x = checkbutton_info[id].x + xoffset_right;
+ int y = checkbutton_info[id].y + yoffset_right;
+
+ DrawTextF(x, y, FONT_TEXT_1, checkbutton_info[id].text_right);
+ ModifyGadget(level_editor_gadget[checkbutton_info[id].gadget_id],
+ GDI_CHECKED, *checkbutton_info[id].value,
+ GDI_Y, SY + checkbutton_info[id].y, GDI_END);
+
+ MapGadget(level_editor_gadget[checkbutton_info[id].gadget_id]);
+}
+
+static void MapMainDrawingArea()
+{
+ boolean no_horizontal_scrollbar = (lev_fieldx + 2 <= ed_fieldx);
+ boolean no_vertical_scrollbar = (lev_fieldy + 2 <= ed_fieldy);
+ int i;
+
+ for (i=ED_SCROLLBUTTON_ID_AREA_FIRST; i<=ED_SCROLLBUTTON_ID_AREA_LAST; i++)
+ {
+ if (((i == ED_SCROLLBUTTON_ID_AREA_LEFT ||
+ i == ED_SCROLLBUTTON_ID_AREA_RIGHT) &&
+ no_horizontal_scrollbar) ||
+ ((i == ED_SCROLLBUTTON_ID_AREA_UP ||
+ i == ED_SCROLLBUTTON_ID_AREA_DOWN) &&
+ no_vertical_scrollbar))
+ continue;
+
+ MapGadget(level_editor_gadget[scrollbutton_info[i].gadget_id]);
+ }
+
+ for (i=ED_SCROLLBAR_ID_AREA_FIRST; i<=ED_SCROLLBAR_ID_AREA_LAST; i++)
+ {
+ if ((i == ED_SCROLLBAR_ID_AREA_HORIZONTAL && no_horizontal_scrollbar) ||
+ (i == ED_SCROLLBAR_ID_AREA_VERTICAL && no_vertical_scrollbar))
+ continue;
+
+ MapGadget(level_editor_gadget[scrollbar_info[i].gadget_id]);
+ }
+
+ MapDrawingArea(GADGET_ID_DRAWING_LEVEL);
+}
+
+static void UnmapDrawingArea(int id)
+{
+ UnmapGadget(level_editor_gadget[id]);
+}
+
+void UnmapLevelEditorWindowGadgets()
+{
+ int i;
+
+ for (i=0; i<NUM_EDITOR_GADGETS; i++)
+ if (level_editor_gadget[i]->x < SX + SXSIZE)
+ UnmapGadget(level_editor_gadget[i]);
+}
+
+void UnmapLevelEditorGadgets()
+{
+ int i;
+
+ for (i=0; i<NUM_EDITOR_GADGETS; i++)
+ UnmapGadget(level_editor_gadget[i]);
+}
+
+static void ResetUndoBuffer()
+{
+ undo_buffer_position = -1;
+ undo_buffer_steps = -1;
+ CopyLevelToUndoBuffer(UNDO_IMMEDIATE);
+}
+
+static void DrawEditModeWindow()
+{
+ if (edit_mode == ED_MODE_INFO)
+ DrawLevelInfoWindow();
+ else if (edit_mode == ED_MODE_PROPERTIES)
+ DrawPropertiesWindow();
+ else /* edit_mode == ED_MODE_DRAWING */
+ DrawDrawingWindow();
+}
+
+static boolean LevelChanged()
+{
+ boolean level_changed = FALSE;
+ int x, y;
+
+ for(y=0; y<lev_fieldy; y++)
+ for(x=0; x<lev_fieldx; x++)
+ if (Feld[x][y] != Ur[x][y])
+ level_changed = TRUE;
+
+ return level_changed;
+}
+
+static boolean LevelContainsPlayer()
+{
+ boolean player_found = FALSE;
+ int x, y;
+
+ for(y=0; y<lev_fieldy; y++)
+ for(x=0; x<lev_fieldx; x++)
+ if (Feld[x][y] == EL_PLAYER_1 ||
+ Feld[x][y] == EL_SP_MURPHY)
+ player_found = TRUE;
+
+ return player_found;
+}
+
+static void CopyPlayfield(short src[MAX_LEV_FIELDX][MAX_LEV_FIELDY],
+ short dst[MAX_LEV_FIELDX][MAX_LEV_FIELDY])
+{
+ int x, y;
+
+ for(x=0; x<lev_fieldx; x++)
+ for(y=0; y<lev_fieldy; y++)
+ dst[x][y] = src[x][y];
+}
+
+static void CopyCustomElementPropertiesToEditor(int element)
+{
+ int i;
+
+ /* needed here to initialize combined element properties */
+ InitElementPropertiesEngine(level.game_version);
+
+ custom_element = element_info[properties_element];
+
+ for (i=0; i < NUM_ELEMENT_PROPERTIES; i++)
+ custom_element_properties[i] = HAS_PROPERTY(element, i);
+
+ for (i=0; i < NUM_CHANGE_EVENTS; i++)
+ custom_element_change_events[i] = HAS_CHANGE_EVENT(element, i);
+
+ /* ---------- element settings: configure (custom elements) ------------- */
+
+ /* set accessible layer selectbox help value */
+ value_access_type =
+ (IS_WALKABLE(element) ? EP_WALKABLE :
+ IS_PASSABLE(element) ? EP_PASSABLE :
+ value_access_type);
+ value_access_layer =
+ (IS_ACCESSIBLE_OVER(element) ? EP_ACCESSIBLE_OVER :
+ IS_ACCESSIBLE_INSIDE(element) ? EP_ACCESSIBLE_INSIDE :
+ IS_ACCESSIBLE_UNDER(element) ? EP_ACCESSIBLE_UNDER :
+ value_access_layer);
+ custom_element_properties[EP_ACCESSIBLE] =
+ (IS_ACCESSIBLE_OVER(element) ||
+ IS_ACCESSIBLE_INSIDE(element) ||
+ IS_ACCESSIBLE_UNDER(element));
+
+ /* set walk-to-object action selectbox help value */
+ value_walk_to_action =
+ (IS_DIGGABLE(element) ? EP_DIGGABLE :
+ IS_COLLECTIBLE(element) ? EP_COLLECTIBLE :
+ IS_PUSHABLE(element) ? EP_PUSHABLE :
+ value_walk_to_action);
+ custom_element_properties[EP_WALK_TO_OBJECT] =
+ (IS_DIGGABLE(element) ||
+ IS_COLLECTIBLE(element) ||
+ IS_PUSHABLE(element));
+
+ /* set smash targets selectbox help value */
+ value_smash_targets =
+ (CAN_SMASH_EVERYTHING(element) ? EP_CAN_SMASH_EVERYTHING :
+ CAN_SMASH_ENEMIES(element) ? EP_CAN_SMASH_ENEMIES :
+ CAN_SMASH_PLAYER(element) ? EP_CAN_SMASH_PLAYER :
+ value_smash_targets);
+ custom_element_properties[EP_CAN_SMASH] =
+ (CAN_SMASH_EVERYTHING(element) ||
+ CAN_SMASH_ENEMIES(element) ||
+ CAN_SMASH_PLAYER(element));
+
+ /* set deadliness selectbox help value */
+ value_deadliness =
+ (DONT_TOUCH(element) ? EP_DONT_TOUCH :
+ DONT_COLLIDE_WITH(element) ? EP_DONT_COLLIDE_WITH :
+ DONT_RUN_INTO(element) ? EP_DONT_RUN_INTO :
+ value_deadliness);
+ custom_element_properties[EP_DEADLY] =
+ (DONT_TOUCH(element) ||
+ DONT_COLLIDE_WITH(element) ||
+ DONT_RUN_INTO(element));
+
+ /* set consistency selectbox help value */
+ value_consistency =
+ (IS_INDESTRUCTIBLE(element) ? EP_INDESTRUCTIBLE :
+ CAN_EXPLODE(element) ? EP_CAN_EXPLODE :
+ value_consistency);
+ custom_element_properties[EP_EXPLODE_RESULT] =
+ (IS_INDESTRUCTIBLE(element) ||
+ CAN_EXPLODE(element));
+
+ /* special case: sub-settings dependent from main setting */
+ if (CAN_EXPLODE(element))
+ {
+ can_explode_by_fire = CAN_EXPLODE_BY_FIRE(element);
+ can_explode_smashed = CAN_EXPLODE_SMASHED(element);
+ can_explode_impact = CAN_EXPLODE_IMPACT(element);
+ };
+
+ /* ---------- element settings: advanced (custom elements) --------------- */
+
+ /* set change by player selectbox help value */
+ value_change_player_action =
+ (HAS_CHANGE_EVENT(element, CE_PUSHED_BY_PLAYER) ? CE_PUSHED_BY_PLAYER :
+ HAS_CHANGE_EVENT(element, CE_PRESSED_BY_PLAYER) ? CE_PRESSED_BY_PLAYER :
+ HAS_CHANGE_EVENT(element, CE_TOUCHED_BY_PLAYER) ? CE_TOUCHED_BY_PLAYER :
+ value_change_player_action);
+
+ /* set change by collision selectbox help value */
+ value_change_collide_action =
+ (HAS_CHANGE_EVENT(element, CE_SMASHED) ? CE_SMASHED :
+ HAS_CHANGE_EVENT(element, CE_IMPACT) ? CE_IMPACT :
+ HAS_CHANGE_EVENT(element, CE_COLLISION) ? CE_COLLISION :
+ value_change_collide_action);
+
+ /* set change by other element action selectbox help value */
+ value_change_other_action =
+ (HAS_CHANGE_EVENT(element, CE_OTHER_GETS_COLLECTED) ? CE_OTHER_GETS_COLLECTED :
+ HAS_CHANGE_EVENT(element, CE_OTHER_GETS_PUSHED) ? CE_OTHER_GETS_PUSHED :
+ HAS_CHANGE_EVENT(element, CE_OTHER_GETS_PRESSED) ? CE_OTHER_GETS_PRESSED :
+ HAS_CHANGE_EVENT(element, CE_OTHER_GETS_TOUCHED) ? CE_OTHER_GETS_TOUCHED :
+ HAS_CHANGE_EVENT(element, CE_OTHER_IS_EXPLODING) ? CE_OTHER_IS_EXPLODING :
+ HAS_CHANGE_EVENT(element, CE_OTHER_IS_CHANGING) ? CE_OTHER_IS_CHANGING :
+ HAS_CHANGE_EVENT(element, CE_OTHER_IS_TOUCHING) ? CE_OTHER_IS_TOUCHING :
+ value_change_other_action);
+}
+
+static void CopyCustomElementPropertiesToGame(int element)
+{
+ int i;
+
+ element_info[properties_element] = custom_element;
+
+ /* ---------- element settings: configure (custom elements) ------------- */
+
+ /* set accessible property from checkbox and selectbox */
+ custom_element_properties[EP_WALKABLE_OVER] = FALSE;
+ custom_element_properties[EP_WALKABLE_INSIDE] = FALSE;
+ custom_element_properties[EP_WALKABLE_UNDER] = FALSE;
+ custom_element_properties[EP_PASSABLE_OVER] = FALSE;
+ custom_element_properties[EP_PASSABLE_INSIDE] = FALSE;
+ custom_element_properties[EP_PASSABLE_UNDER] = FALSE;
+ custom_element_properties[((value_access_type == EP_WALKABLE ?
+ EP_WALKABLE_OVER : EP_PASSABLE_OVER) +
+ (value_access_layer - EP_ACCESSIBLE_OVER))] =
+ custom_element_properties[EP_ACCESSIBLE];
+
+ /* set walk-to-object property from checkbox and selectbox */
+ custom_element_properties[EP_DIGGABLE] = FALSE;
+ custom_element_properties[EP_COLLECTIBLE] = FALSE;
+ custom_element_properties[EP_PUSHABLE] = FALSE;
+ custom_element_properties[value_walk_to_action] =
+ custom_element_properties[EP_WALK_TO_OBJECT];
+
+ /* set smash property from checkbox and selectbox */
+ custom_element_properties[EP_CAN_SMASH_PLAYER] = FALSE;
+ custom_element_properties[EP_CAN_SMASH_ENEMIES] = FALSE;
+ custom_element_properties[EP_CAN_SMASH_EVERYTHING] = FALSE;
+ custom_element_properties[value_smash_targets] =
+ custom_element_properties[EP_CAN_SMASH];
+
+ /* set deadliness property from checkbox and selectbox */
+ custom_element_properties[EP_DONT_RUN_INTO] = FALSE;
+ custom_element_properties[EP_DONT_COLLIDE_WITH] = FALSE;
+ custom_element_properties[EP_DONT_TOUCH] = FALSE;
+ custom_element_properties[value_deadliness] =
+ custom_element_properties[EP_DEADLY];
+
+ /* set consistency property from checkbox and selectbox */
+ custom_element_properties[EP_INDESTRUCTIBLE] = FALSE;
+ custom_element_properties[EP_CAN_EXPLODE] = FALSE;
+ custom_element_properties[EP_CAN_EXPLODE_BY_FIRE] = FALSE;
+ custom_element_properties[EP_CAN_EXPLODE_SMASHED] = FALSE;
+ custom_element_properties[EP_CAN_EXPLODE_IMPACT] = FALSE;
+ custom_element_properties[value_consistency] =
+ custom_element_properties[EP_EXPLODE_RESULT];
+
+ /* special case: sub-settings dependent from main setting */
+ if (custom_element_properties[EP_CAN_EXPLODE])
+ {
+ custom_element_properties[EP_CAN_EXPLODE_BY_FIRE] = can_explode_by_fire;
+ custom_element_properties[EP_CAN_EXPLODE_SMASHED] = can_explode_smashed;
+ custom_element_properties[EP_CAN_EXPLODE_IMPACT] = can_explode_impact;
+ }
+
+ /* ---------- element settings: advanced (custom elements) --------------- */
+
+ /* set player change event from checkbox and selectbox */
+ custom_element_change_events[CE_TOUCHED_BY_PLAYER] = FALSE;
+ custom_element_change_events[CE_PRESSED_BY_PLAYER] = FALSE;
+ custom_element_change_events[CE_PUSHED_BY_PLAYER] = FALSE;
+ custom_element_change_events[value_change_player_action] =
+ custom_element_change_events[CE_BY_PLAYER];
+
+ /* set collision change event from checkbox and selectbox */
+ custom_element_change_events[CE_COLLISION] = FALSE;
+ custom_element_change_events[CE_IMPACT] = FALSE;
+ custom_element_change_events[CE_SMASHED] = FALSE;
+ custom_element_change_events[value_change_collide_action] =
+ custom_element_change_events[CE_BY_COLLISION];
+
+ /* set other element action change event from checkbox and selectbox */
+ custom_element_change_events[CE_OTHER_IS_TOUCHING] = FALSE;
+ custom_element_change_events[CE_OTHER_IS_CHANGING] = FALSE;
+ custom_element_change_events[CE_OTHER_IS_EXPLODING] = FALSE;
+ custom_element_change_events[CE_OTHER_GETS_TOUCHED] = FALSE;
+ custom_element_change_events[CE_OTHER_GETS_PRESSED] = FALSE;
+ custom_element_change_events[CE_OTHER_GETS_PUSHED] = FALSE;
+ custom_element_change_events[CE_OTHER_GETS_COLLECTED] = FALSE;
+ custom_element_change_events[value_change_other_action] =
+ custom_element_change_events[CE_BY_OTHER];
+
+ for (i=0; i < NUM_ELEMENT_PROPERTIES; i++)
+ SET_PROPERTY(element, i, custom_element_properties[i]);
+
+ for (i=0; i < NUM_CHANGE_EVENTS; i++)
+ SET_CHANGE_EVENT(element, i, custom_element_change_events[i]);
+
+ /* copy change events also to special level editor variable */
+ custom_element = element_info[properties_element];
+}
+
+void DrawLevelEd()
+{
+ CloseDoor(DOOR_CLOSE_ALL);
+ OpenDoor(DOOR_OPEN_2 | DOOR_NO_DELAY);
+
+ if (level_editor_test_game)
+ {
+ CopyPlayfield(Ur, Feld);
+ CopyPlayfield(FieldBackup, Ur);
+
+ level_editor_test_game = FALSE;
+ }
+ else
+ {
+ edit_mode = ED_MODE_DRAWING;
+ edit_mode_properties = ED_MODE_PROPERTIES_INFO;
+
+ ResetUndoBuffer();
+
+ level_xpos = -1;
+ level_ypos = -1;
+ }
+
+ /* copy default editor door content to main double buffer */
+ BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
+ DOOR_GFX_PAGEX6, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY);
+
+ /* draw mouse button brush elements */
+ DrawMiniGraphicExt(drawto,
+ DX + ED_WIN_MB_LEFT_XPOS, DY + ED_WIN_MB_LEFT_YPOS,
+ el2edimg(new_element1));
+ DrawMiniGraphicExt(drawto,
+ DX + ED_WIN_MB_MIDDLE_XPOS, DY + ED_WIN_MB_MIDDLE_YPOS,
+ el2edimg(new_element2));
+ DrawMiniGraphicExt(drawto,
+ DX + ED_WIN_MB_RIGHT_XPOS, DY + ED_WIN_MB_RIGHT_YPOS,
+ el2edimg(new_element3));
+
+ /* draw bigger door */
+ DrawSpecialEditorDoor();
+
+ /* draw new control window */
+ BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
+ DOOR_GFX_PAGEX8, 236, EXSIZE, EYSIZE, EX, EY);
+
+ redraw_mask |= REDRAW_ALL;
+
+ ReinitializeElementListButtons(); /* only needed after setup changes */
+ ModifyEditorElementList(); /* may be needed for custom elements */
+
+ UnmapTapeButtons();
+ MapControlButtons();
+
+ /* copy actual editor door content to door double buffer for OpenDoor() */
+ BlitBitmap(drawto, bitmap_db_door,
+ DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+
+ DrawEditModeWindow();
+
+ OpenDoor(DOOR_OPEN_1);
+}
+
+static void AdjustDrawingAreaGadgets()
+{
+ int ed_xsize = lev_fieldx + 2;
+ int ed_ysize = lev_fieldy + 2;
+ int max_ed_fieldx = MAX_ED_FIELDX;
+ int max_ed_fieldy = MAX_ED_FIELDY;
+ boolean horizontal_scrollbar_needed;
+ boolean vertical_scrollbar_needed;
+ int x, y, width, height;
+ int xoffset, yoffset;
+
+ /* check if we need any scrollbars */
+ horizontal_scrollbar_needed = (ed_xsize > max_ed_fieldx);
+ vertical_scrollbar_needed = (ed_ysize > max_ed_fieldy);
+
+ /* check if we have a smaller editor field because of scrollbars */
+ if (horizontal_scrollbar_needed)
+ max_ed_fieldy = MAX_ED_FIELDY - 1;
+ if (vertical_scrollbar_needed)
+ max_ed_fieldx = MAX_ED_FIELDX - 1;
+
+ /* check again if we now need more scrollbars because of less space */
+ horizontal_scrollbar_needed = (ed_xsize > max_ed_fieldx);
+ vertical_scrollbar_needed = (ed_ysize > max_ed_fieldy);
+
+ /* check if editor field gets even smaller after adding new scrollbars */
+ if (horizontal_scrollbar_needed)
+ max_ed_fieldy = MAX_ED_FIELDY - 1;
+ if (vertical_scrollbar_needed)
+ max_ed_fieldx = MAX_ED_FIELDX - 1;
+
+ ed_fieldx = (ed_xsize < MAX_ED_FIELDX ? ed_xsize : max_ed_fieldx);
+ ed_fieldy = (ed_ysize < MAX_ED_FIELDY ? ed_ysize : max_ed_fieldy);
+
+ ModifyGadget(level_editor_gadget[GADGET_ID_DRAWING_LEVEL],
+ GDI_WIDTH, ed_fieldx * MINI_TILEX,
+ GDI_HEIGHT, ed_fieldy * MINI_TILEY,
+ GDI_AREA_SIZE, ed_fieldx, ed_fieldy,
+ GDI_END);
+
+ xoffset = (ed_fieldx == MAX_ED_FIELDX ? ED_SCROLLBUTTON_XSIZE : 0);
+ yoffset = (ed_fieldy == MAX_ED_FIELDY ? ED_SCROLLBUTTON_YSIZE : 0);
+
+ x = SX + scrollbutton_info[ED_SCROLLBUTTON_ID_AREA_RIGHT].x + xoffset;
+ y = SX + scrollbutton_info[ED_SCROLLBUTTON_ID_AREA_DOWN].y + yoffset;
+
+ ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_RIGHT], GDI_X, x, GDI_END);
+ ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_DOWN], GDI_Y, y, GDI_END);
+
+ width = scrollbar_info[ED_SCROLLBAR_ID_AREA_HORIZONTAL].width + xoffset;
+ height = scrollbar_info[ED_SCROLLBAR_ID_AREA_VERTICAL].height + yoffset;
+
+ ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_HORIZONTAL],
+ GDI_WIDTH, width,
+ GDI_SCROLLBAR_ITEMS_VISIBLE, ed_fieldx,
+ GDI_END);
+ ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_VERTICAL],
+ GDI_HEIGHT, height,
+ GDI_SCROLLBAR_ITEMS_VISIBLE, ed_fieldy,
+ GDI_END);
+}
+
+static void AdjustLevelScrollPosition()
+{
+ if (level_xpos < -1)
+ level_xpos = -1;
+ if (level_xpos > lev_fieldx - ed_fieldx + 1)
+ level_xpos = lev_fieldx - ed_fieldx + 1;
+ if (lev_fieldx < ed_fieldx - 2)
+ level_xpos = -1;
+
+ if (level_ypos < -1)
+ level_ypos = -1;
+ if (level_ypos > lev_fieldy - ed_fieldy + 1)
+ level_ypos = lev_fieldy - ed_fieldy + 1;
+ if (lev_fieldy < ed_fieldy - 2)
+ level_ypos = -1;
+}
+
+static void AdjustEditorScrollbar(int id)
+{
+ struct GadgetInfo *gi = level_editor_gadget[id];
+ int items_max, items_visible, item_position;
+
+ if (id == GADGET_ID_SCROLL_HORIZONTAL)
+ {
+ items_max = MAX(lev_fieldx + 2, ed_fieldx);
+ items_visible = ed_fieldx;
+ item_position = level_xpos + 1;
+ }
+ else
+ {
+ items_max = MAX(lev_fieldy + 2, ed_fieldy);
+ items_visible = ed_fieldy;
+ item_position = level_ypos + 1;
+ }
+
+ if (item_position > items_max - items_visible)
+ item_position = items_max - items_visible;
+
+ ModifyGadget(gi, GDI_SCROLLBAR_ITEMS_MAX, items_max,
+ GDI_SCROLLBAR_ITEM_POSITION, item_position, GDI_END);
+}
+
+static void ModifyEditorCounter(int counter_id, int new_value)
+{
+ int *counter_value = counterbutton_info[counter_id].value;
+ int gadget_id = counterbutton_info[counter_id].gadget_id_text;
+ struct GadgetInfo *gi = level_editor_gadget[gadget_id];
+
+ ModifyGadget(gi, GDI_NUMBER_VALUE, new_value, GDI_END);
+
+ if (counter_value != NULL)
+ *counter_value = gi->text.number_value;
+}
+
+static void ModifyEditorCounterLimits(int counter_id, int min, int max)
+{
+ int gadget_id = counterbutton_info[counter_id].gadget_id_text;
+ struct GadgetInfo *gi = level_editor_gadget[gadget_id];
+
+ ModifyGadget(gi, GDI_NUMBER_MIN, min, GDI_NUMBER_MAX, max, GDI_END);
+}
+
+static void ModifyEditorSelectbox(int selectbox_id, int new_value)
+{
+ int gadget_id = selectbox_info[selectbox_id].gadget_id;
+ struct GadgetInfo *gi = level_editor_gadget[gadget_id];
+ int new_index_value = 0;
+ int i;
+
+ for(i=0; selectbox_info[selectbox_id].options[i].text != NULL; i++)
+ if (selectbox_info[selectbox_id].options[i].value == new_value)
+ new_index_value = i;
+
+ *selectbox_info[selectbox_id].value =
+ selectbox_info[selectbox_id].options[new_index_value].value;
+
+ ModifyGadget(gi, GDI_SELECTBOX_INDEX, new_index_value, GDI_END);
+}
+
+static void ModifyEditorElementList()
+{
+ int i;
+
+ for (i=0; i<ED_NUM_ELEMENTLIST_BUTTONS; i++)
+ {
+ int gadget_id = GADGET_ID_ELEMENTLIST_FIRST + i;
+ struct GadgetInfo *gi = level_editor_gadget[gadget_id];
+ struct GadgetDesign *gd = &gi->deco.design;
+ int element = editor_elements[element_shift + i];
+
+ UnmapGadget(gi);
+ getMiniGraphicSource(el2edimg(element), &gd->bitmap, &gd->x, &gd->y);
+ ModifyGadget(gi, GDI_INFO_TEXT, getElementInfoText(element), GDI_END);
+ MapGadget(gi);
+ }
+}
+
+static void PickDrawingElement(int button, int element)
+{
+ if (button < 1 || button > 3)
+ return;
+
+ if (button == 1)
+ {
+ new_element1 = element;
+ DrawMiniGraphicExt(drawto,
+ DX + ED_WIN_MB_LEFT_XPOS, DY + ED_WIN_MB_LEFT_YPOS,
+ el2edimg(new_element1));
+ }
+ else if (button == 2)
+ {
+ new_element2 = element;
+ DrawMiniGraphicExt(drawto,
+ DX + ED_WIN_MB_MIDDLE_XPOS, DY + ED_WIN_MB_MIDDLE_YPOS,
+ el2edimg(new_element2));
+ }
+ else
+ {
+ new_element3 = element;
+ DrawMiniGraphicExt(drawto,
+ DX + ED_WIN_MB_RIGHT_XPOS, DY + ED_WIN_MB_RIGHT_YPOS,
+ el2edimg(new_element3));
+ }