X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Feditor.c;h=ce97227216f0e26d7a28180a7db03b234bc8d47e;hb=ba4235954c2f507e24bcffa0faa3fc02266da3a2;hp=e007d7a8847da91038df8b46e5b7eb3b99dc22ab;hpb=82935bc1d2a8bba3be5a29cd5449edc155118521;p=rocksndiamonds.git diff --git a/src/editor.c b/src/editor.c index e007d7a8..ce972272 100644 --- a/src/editor.c +++ b/src/editor.c @@ -32,39 +32,6 @@ */ /* values for the control window */ -#define ED_CTRL_NO_BUTTONS_GFX_XPOS 6 -#define ED_CTRL_NO_BUTTONS_GFX_YPOS 286 -#define ED_CTRL1_BUTTONS_GFX_YPOS 236 -#define ED_CTRL2_BUTTONS_GFX_YPOS 236 -#define ED_CTRL3_BUTTONS_GFX_YPOS 324 -#define ED_CTRL4_BUTTONS_GFX_XPOS 44 -#define ED_CTRL4_BUTTONS_GFX_YPOS 214 -#define ED_CTRL1_BUTTONS_ALT_GFX_YPOS 142 -#define ED_CTRL3_BUTTONS_ALT_GFX_YPOS 302 -#define ED_CTRL5_BUTTONS_GFX_XPOS 5 -#define ED_CTRL5_BUTTONS_GFX_YPOS 110 - -#define ED_CTRL1_BUTTON_XSIZE 22 -#define ED_CTRL1_BUTTON_YSIZE 22 -#define ED_CTRL1_BUTTONS_XPOS 6 -#define ED_CTRL1_BUTTONS_YPOS 6 -#define ED_CTRL2_BUTTON_XSIZE 30 -#define ED_CTRL2_BUTTON_YSIZE 20 -#define ED_CTRL2_BUTTONS_XPOS 5 -#define ED_CTRL2_BUTTONS_YPOS 99 -#define ED_CTRL3_BUTTON_XSIZE 22 -#define ED_CTRL3_BUTTON_YSIZE 22 -#define ED_CTRL3_BUTTONS_XPOS 6 -#define ED_CTRL3_BUTTONS_YPOS 6 -#define ED_CTRL4_BUTTON_XSIZE 22 -#define ED_CTRL4_BUTTON_YSIZE 22 -#define ED_CTRL4_BUTTONS_XPOS 6 -#define ED_CTRL4_BUTTONS_YPOS 6 -#define ED_CTRL5_BUTTON_XSIZE 90 -#define ED_CTRL5_BUTTON_YSIZE 20 -#define ED_CTRL5_BUTTONS_XPOS 5 -#define ED_CTRL5_BUTTONS_YPOS 230 - #define ED_CTRL1_BUTTONS_HORIZ 4 #define ED_CTRL1_BUTTONS_VERT 4 #define ED_CTRL2_BUTTONS_HORIZ 3 @@ -100,6 +67,8 @@ #define ED_BORDER_SIZE 3 #define ED_BORDER_TEXT_XSIZE 5 #define ED_BORDER_AREA_YSIZE 1 +#define ED_ELEMENT_BORDER 8 +#define ED_ELEMENT_BORDER_INPUT 4 #define ED_GADGET_DISTANCE 2 #define ED_GADGET_TEXT_DISTANCE (2 * ED_GADGET_DISTANCE) @@ -141,16 +110,6 @@ 2 * MINI_TILEY) #define ED_SETTINGS1_YPOS MINI_TILEY -#define ED_SETTINGS2_XPOS MINI_TILEX -#define ED_SETTINGS2_YPOS (ED_SETTINGS1_YPOS + 12 * TILEY - 2) - -/* values for counter gadgets */ -#define ED_COUNTER_YSTART (ED_SETTINGS1_YPOS + 2 * TILEY) -#define ED_COUNTER_YDISTANCE (3 * MINI_TILEY) -#define ED_COUNTER_YPOS(n) (ED_COUNTER_YSTART + \ - (n) * ED_COUNTER_YDISTANCE) -#define ED_COUNTER2_YPOS(n) (ED_COUNTER_YSTART + \ - (n) * ED_COUNTER_YDISTANCE - 2) /* values for element content drawing areas */ #define ED_AREA_1X1_SETTINGS_XPOS(n) (ED_ELEMENT_SETTINGS_XPOS(n)) @@ -174,11 +133,6 @@ 6 * ((n) / 4) * MINI_TILEY) /* values for scrolling gadgets for drawing area */ -#define ED_SCROLLBUTTON_XPOS 24 -#define ED_SCROLLBUTTON_YPOS 0 -#define ED_SCROLLBAR_XPOS 24 -#define ED_SCROLLBAR_YPOS 64 - #define ED_SCROLLBUTTON_XSIZE 16 #define ED_SCROLLBUTTON_YSIZE 16 @@ -202,11 +156,6 @@ #define ED_SCROLL_VERTICAL_YSIZE (SYSIZE - 4 * ED_SCROLLBUTTON_YSIZE) /* values for scrolling gadgets for element list */ -#define ED_SCROLLBUTTON2_XPOS 50 -#define ED_SCROLLBUTTON2_YPOS 0 -#define ED_SCROLLBAR2_XPOS 50 -#define ED_SCROLLBAR2_YPOS 20 - #define ED_SCROLLBUTTON2_XSIZE (graphic_info[IMG_EDITOR_PALETTE_SCROLL_UP].width) #define ED_SCROLLBUTTON2_YSIZE (graphic_info[IMG_EDITOR_PALETTE_SCROLL_UP].height) @@ -228,66 +177,14 @@ 2 * ED_SCROLLBUTTON2_YSIZE) /* values for checkbutton gadgets */ -#define ED_CHECKBUTTON_XSIZE ED_BUTTON_COUNT_XSIZE -#define ED_CHECKBUTTON_YSIZE ED_BUTTON_COUNT_YSIZE -#define ED_CHECKBUTTON_UNCHECKED_XPOS ED_BUTTON_MINUS_XPOS -#define ED_CHECKBUTTON_CHECKED_XPOS ED_BUTTON_PLUS_XPOS -#define ED_CHECKBUTTON_YPOS (ED_BUTTON_MINUS_YPOS + 22) -#define ED_RADIOBUTTON_YPOS (ED_BUTTON_MINUS_YPOS + 44) -#define ED_STICKYBUTTON_YPOS (ED_BUTTON_MINUS_YPOS + 66) - -/* values for some special graphic buttons */ -#define ED_COPY_CHANGE_PAGE_XPOS 25 -#define ED_COPY_CHANGE_PAGE_YPOS 50 -#define ED_PASTE_CHANGE_PAGE_XPOS 25 -#define ED_PASTE_CHANGE_PAGE_YPOS 70 - -/* some values for text input, selectbox and counter gadgets */ -#define ED_BUTTON_COUNT_YPOS 60 -#define ED_BUTTON_COUNT_XSIZE 20 -#define ED_BUTTON_COUNT_YSIZE 20 -#define ED_WIN_COUNT_XPOS (2 + ED_BUTTON_COUNT_XSIZE + 2) -#define ED_WIN_COUNT_YPOS ED_BUTTON_COUNT_YPOS -#define ED_WIN_COUNT_XSIZE 52 -#define ED_WIN_COUNT_YSIZE ED_BUTTON_COUNT_YSIZE - -#define ED_BUTTON_MINUS_XPOS 2 -#define ED_BUTTON_MINUS_YPOS ED_BUTTON_COUNT_YPOS -#define ED_BUTTON_MINUS_XSIZE ED_BUTTON_COUNT_XSIZE -#define ED_BUTTON_MINUS_YSIZE ED_BUTTON_COUNT_YSIZE -#define ED_BUTTON_PLUS_XPOS (ED_WIN_COUNT_XPOS + \ - ED_WIN_COUNT_XSIZE + 2) -#define ED_BUTTON_PLUS_YPOS ED_BUTTON_COUNT_YPOS -#define ED_BUTTON_PLUS_XSIZE ED_BUTTON_COUNT_XSIZE -#define ED_BUTTON_PLUS_YSIZE ED_BUTTON_COUNT_YSIZE - -#define ED_SELECTBOX_XPOS ED_WIN_COUNT_XPOS -#define ED_SELECTBOX_YPOS (ED_WIN_COUNT_YPOS + \ - 2 + ED_WIN_COUNT_YSIZE) -#define ED_SELECTBOX_XSIZE ED_WIN_COUNT_XSIZE -#define ED_SELECTBOX_YSIZE ED_WIN_COUNT_YSIZE - -#define ED_SELECTBOX_BUTTON_XSIZE 14 - -#define ED_TEXTBUTTON_XPOS ED_WIN_COUNT_XPOS -#define ED_TEXTBUTTON_YPOS (ED_WIN_COUNT_YPOS + \ - 4 * (2 + ED_WIN_COUNT_YSIZE)) -#define ED_TEXTBUTTON_INACTIVE_YPOS ED_TEXTBUTTON_YPOS - -#define ED_TEXTBUTTON_TAB_XPOS ED_WIN_COUNT_XPOS -#define ED_TEXTBUTTON_TAB_YPOS (ED_WIN_COUNT_YPOS + \ - 2 * (2 + ED_WIN_COUNT_YSIZE)) -#define ED_TEXTBUTTON_TAB_INACTIVE_YPOS (ED_WIN_COUNT_YPOS + \ - 3 * (2 + ED_WIN_COUNT_YSIZE)) - -#define ED_TEXTBUTTON_XSIZE ED_WIN_COUNT_XSIZE -#define ED_TEXTBUTTON_YSIZE ED_WIN_COUNT_YSIZE +#define ED_CHECKBUTTON_XSIZE 20 +#define ED_CHECKBUTTON_YSIZE 20 /* values for ClearEditorGadgetInfoText() and HandleEditorGadgetInfoText() */ #define INFOTEXT_XPOS SX #define INFOTEXT_YPOS (SY + SYSIZE - MINI_TILEX + 2) #define INFOTEXT_XSIZE SXSIZE -#define INFOTEXT_YSIZE MINI_TILEX +#define INFOTEXT_YSIZE MINI_TILEY /* @@ -953,7 +850,7 @@ #define ED_MODE_PROPERTIES_CHANGE ED_TEXTBUTTON_ID_PROPERTIES_CHANGE /* how many steps can be cancelled */ -#define NUM_UNDO_STEPS (10 + 1) +#define NUM_UNDO_STEPS (64 + 1) /* values for elements with score for certain actions */ #define MIN_SCORE 0 @@ -967,9 +864,8 @@ #define RANDOM_USE_PERCENTAGE 0 #define RANDOM_USE_QUANTITY 1 -/* maximal size of level editor drawing area */ -#define MAX_ED_FIELDX (SCR_FIELDX) -#define MAX_ED_FIELDY (SCR_FIELDY - 1) +/* default value for element tile size in drawing area */ +#define DEFAULT_EDITOR_TILESIZE MINI_TILESIZE /* @@ -980,45 +876,168 @@ static struct { + int graphic; + int gadget_id; + struct XY *pos; + int gadget_type; + char *infotext; char shortcut; - char *text; -} control_info[ED_NUM_CTRL_BUTTONS] = +} controlbutton_info[ED_NUM_CTRL_BUTTONS] = { /* note: some additional characters are already reserved for "cheat mode" shortcuts (":XYZ" style) -- for details, see "events.c" */ - { 's', "draw single items" }, - { 'd', "draw connected items" }, - { 'l', "draw lines" }, - { 'a', "draw arcs" }, - { 'r', "draw outline rectangles" }, - { 'R', "draw filled rectangles" }, - { '\0', "wrap (rotate) level up" }, - { 't', "enter text elements" }, - { 'f', "flood fill" }, - { '\0', "wrap (rotate) level left" }, - { 'z', "zoom level tile size" }, - { '\0', "wrap (rotate) level right" }, - { '\0', "random element placement" }, - { 'b', "grab brush" }, - { '\0', "wrap (rotate) level down" }, - { ',', "pick drawing element" }, - - { 'U', "undo last operation" }, - { 'I', "properties of level" }, - { 'S', "save level" }, - { 'C', "clear level" }, - { 'T', "test level" }, - { 'E', "exit level editor" }, - - { '\0', "copy settings from other element" }, - { '\0', "copy settings to other element" }, - { '\0', "exchange element with other element" }, - - { '\0', "copy settings from this element" }, - { '\0', "paste settings to this element" }, - - { 'p', "properties of drawing element" }, + /* ---------- toolbox control buttons ------------------------------------ */ + + { + IMG_EDITOR_BUTTON_GFX_DRAW_SINGLE, GADGET_ID_SINGLE_ITEMS, + &editor.button.draw_single, GD_TYPE_RADIO_BUTTON, + "draw single items", 's' + }, + { + IMG_EDITOR_BUTTON_GFX_DRAW_CONNECTED, GADGET_ID_CONNECTED_ITEMS, + &editor.button.draw_connected, GD_TYPE_RADIO_BUTTON, + "draw connected items", 'd' + }, + { + IMG_EDITOR_BUTTON_GFX_DRAW_LINE, GADGET_ID_LINE, + &editor.button.draw_line, GD_TYPE_RADIO_BUTTON, + "draw lines", 'l' + }, + { + IMG_EDITOR_BUTTON_GFX_DRAW_ARC, GADGET_ID_ARC, + &editor.button.draw_arc, GD_TYPE_RADIO_BUTTON, + "draw arcs", 'a' + }, + { + IMG_EDITOR_BUTTON_GFX_DRAW_RECTANGLE, GADGET_ID_RECTANGLE, + &editor.button.draw_rectangle, GD_TYPE_RADIO_BUTTON, + "draw outline rectangles", 'r' + }, + { + IMG_EDITOR_BUTTON_GFX_DRAW_FILLED_BOX, GADGET_ID_FILLED_BOX, + &editor.button.draw_filled_box, GD_TYPE_RADIO_BUTTON, + "draw filled rectangles", 'R' + }, + { + IMG_EDITOR_BUTTON_GFX_ROTATE_UP, GADGET_ID_WRAP_UP, + &editor.button.rotate_up, GD_TYPE_NORMAL_BUTTON, + "wrap (rotate) level up", 0 + }, + { + IMG_EDITOR_BUTTON_GFX_DRAW_TEXT, GADGET_ID_TEXT, + &editor.button.draw_text, GD_TYPE_RADIO_BUTTON, + "enter text elements", 't' + }, + { + IMG_EDITOR_BUTTON_GFX_FLOOD_FILL, GADGET_ID_FLOOD_FILL, + &editor.button.flood_fill, GD_TYPE_RADIO_BUTTON, + "flood fill", 'f' + }, + { + IMG_EDITOR_BUTTON_GFX_ROTATE_LEFT, GADGET_ID_WRAP_LEFT, + &editor.button.rotate_left, GD_TYPE_NORMAL_BUTTON, + "wrap (rotate) level left", 0 + }, + { + IMG_EDITOR_BUTTON_GFX_ZOOM_LEVEL, GADGET_ID_ZOOM, + &editor.button.zoom_level, GD_TYPE_NORMAL_BUTTON, + "zoom level tile size", '-' + }, + { + IMG_EDITOR_BUTTON_GFX_ROTATE_RIGHT, GADGET_ID_WRAP_RIGHT, + &editor.button.rotate_right, GD_TYPE_NORMAL_BUTTON, + "wrap (rotate) level right", 0 + }, + { + IMG_EDITOR_BUTTON_GFX_DRAW_RANDOM, GADGET_ID_RANDOM_PLACEMENT, + &editor.button.draw_random, GD_TYPE_NORMAL_BUTTON, + "random element placement", 0 + }, + { + IMG_EDITOR_BUTTON_GFX_GRAB_BRUSH, GADGET_ID_GRAB_BRUSH, + &editor.button.grab_brush, GD_TYPE_RADIO_BUTTON, + "grab brush", 'b' + }, + { + IMG_EDITOR_BUTTON_GFX_ROTATE_DOWN, GADGET_ID_WRAP_DOWN, + &editor.button.rotate_down, GD_TYPE_NORMAL_BUTTON, + "wrap (rotate) level down", 0 + }, + { + IMG_EDITOR_BUTTON_GFX_PICK_ELEMENT, GADGET_ID_PICK_ELEMENT, + &editor.button.pick_element, GD_TYPE_RADIO_BUTTON, + "pick drawing element", ',' + }, + + /* ---------- level control buttons -------------------------------------- */ + + { + IMG_EDITOR_BUTTON_GFX_UNDO, GADGET_ID_UNDO, + &editor.button.undo, GD_TYPE_NORMAL_BUTTON, + "undo/redo last operation", 'u' + }, + { + IMG_EDITOR_BUTTON_GFX_CONF, GADGET_ID_INFO, + &editor.button.conf, GD_TYPE_NORMAL_BUTTON, + "properties of level", 'I' + }, + { + IMG_EDITOR_BUTTON_GFX_SAVE, GADGET_ID_SAVE, + &editor.button.save, GD_TYPE_NORMAL_BUTTON, + "save level", 'S' + }, + { + IMG_EDITOR_BUTTON_GFX_CLEAR, GADGET_ID_CLEAR, + &editor.button.clear, GD_TYPE_NORMAL_BUTTON, + "clear level", 'C' + }, + { + IMG_EDITOR_BUTTON_GFX_TEST, GADGET_ID_TEST, + &editor.button.test, GD_TYPE_NORMAL_BUTTON, + "test level", 'T' + }, + { + IMG_EDITOR_BUTTON_GFX_EXIT, GADGET_ID_EXIT, + &editor.button.exit, GD_TYPE_NORMAL_BUTTON, + "exit level editor", 'E' + }, + + /* ---------- CE and GE control buttons ---------------------------------- */ + + { + IMG_EDITOR_BUTTON_GFX_CE_COPY_FROM, GADGET_ID_CUSTOM_COPY_FROM, + &editor.button.ce_copy_from, GD_TYPE_RADIO_BUTTON, + "copy settings from other element", 0 + }, + { + IMG_EDITOR_BUTTON_GFX_CE_COPY_TO, GADGET_ID_CUSTOM_COPY_TO, + &editor.button.ce_copy_to, GD_TYPE_RADIO_BUTTON, + "copy settings to other element", 0 + }, + { + IMG_EDITOR_BUTTON_GFX_CE_SWAP, GADGET_ID_CUSTOM_EXCHANGE, + &editor.button.ce_swap, GD_TYPE_RADIO_BUTTON, + "exchange element with other element", 0 + }, + { + IMG_EDITOR_BUTTON_GFX_CE_COPY, GADGET_ID_CUSTOM_COPY, + &editor.button.ce_copy, GD_TYPE_NORMAL_BUTTON, + "copy settings from this element", 0 + }, + { + IMG_EDITOR_BUTTON_GFX_CE_PASTE, GADGET_ID_CUSTOM_PASTE, + &editor.button.ce_paste, GD_TYPE_NORMAL_BUTTON, + "paste settings to this element", 0 + }, + + /* ---------- palette control buttons ------------------------------------ */ + + { + IMG_EDITOR_BUTTON_GFX_PROPERTIES, GADGET_ID_PROPERTIES, + &editor.button.properties, GD_TYPE_NORMAL_BUTTON, + "properties of drawing element", 'p' + } }; static int random_placement_value = 10; @@ -1199,7 +1218,7 @@ static struct /* ---------- element settings: configure 1 (custom elements) ------------ */ { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(6), + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(5), MIN_SCORE, MAX_SCORE, GADGET_ID_CUSTOM_SCORE_DOWN, GADGET_ID_CUSTOM_SCORE_UP, GADGET_ID_CUSTOM_SCORE_TEXT, GADGET_ID_NONE, @@ -1207,7 +1226,7 @@ static struct NULL, "CE score", " " }, { - -1, ED_ELEMENT_SETTINGS_YPOS(6), + -1, ED_ELEMENT_SETTINGS_YPOS(5), MIN_COLLECT_COUNT, MAX_COLLECT_COUNT, GADGET_ID_CUSTOM_GEMCOUNT_DOWN, GADGET_ID_CUSTOM_GEMCOUNT_UP, GADGET_ID_CUSTOM_GEMCOUNT_TEXT, GADGET_ID_CUSTOM_SCORE_UP, @@ -1215,7 +1234,7 @@ static struct NULL, "CE count", NULL }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(12), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10), 0, 9999, GADGET_ID_CUSTOM_VALUE_FIX_DOWN, GADGET_ID_CUSTOM_VALUE_FIX_UP, GADGET_ID_CUSTOM_VALUE_FIX_TEXT, GADGET_ID_NONE, @@ -1223,7 +1242,7 @@ static struct NULL, "CE value", NULL }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(12), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10), 0, 9999, GADGET_ID_CUSTOM_VALUE_RND_DOWN, GADGET_ID_CUSTOM_VALUE_RND_UP, GADGET_ID_CUSTOM_VALUE_RND_TEXT, GADGET_ID_CUSTOM_VALUE_FIX_UP, @@ -1231,7 +1250,7 @@ static struct NULL, "+random", NULL }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(7), + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(6), 0, 999, GADGET_ID_PUSH_DELAY_FIX_DOWN, GADGET_ID_PUSH_DELAY_FIX_UP, GADGET_ID_PUSH_DELAY_FIX_TEXT, GADGET_ID_NONE, @@ -1239,7 +1258,7 @@ static struct NULL, "push delay", NULL }, { - -1, ED_ELEMENT_SETTINGS_YPOS(7), + -1, ED_ELEMENT_SETTINGS_YPOS(6), 0, 999, GADGET_ID_PUSH_DELAY_RND_DOWN, GADGET_ID_PUSH_DELAY_RND_UP, GADGET_ID_PUSH_DELAY_RND_TEXT, GADGET_ID_PUSH_DELAY_FIX_UP, @@ -1247,7 +1266,7 @@ static struct NULL, "+random", NULL }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(8), + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(7), 0, 999, GADGET_ID_DROP_DELAY_FIX_DOWN, GADGET_ID_DROP_DELAY_FIX_UP, GADGET_ID_DROP_DELAY_FIX_TEXT, GADGET_ID_NONE, @@ -1255,7 +1274,7 @@ static struct NULL, "drop delay", NULL }, { - -1, ED_ELEMENT_SETTINGS_YPOS(8), + -1, ED_ELEMENT_SETTINGS_YPOS(7), 0, 999, GADGET_ID_DROP_DELAY_RND_DOWN, GADGET_ID_DROP_DELAY_RND_UP, GADGET_ID_DROP_DELAY_RND_TEXT, GADGET_ID_DROP_DELAY_FIX_UP, @@ -1301,7 +1320,7 @@ static struct /* ---------- element settings: configure (group elements) --------------- */ { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), MIN_ELEMENTS_IN_GROUP, MAX_ELEMENTS_IN_GROUP, GADGET_ID_GROUP_CONTENT_DOWN, GADGET_ID_GROUP_CONTENT_UP, GADGET_ID_GROUP_CONTENT_TEXT, GADGET_ID_NONE, @@ -2141,7 +2160,7 @@ static struct /* ---------- element settings: configure 1 (custom elements) ------------ */ { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(3), + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(2), GADGET_ID_CUSTOM_ACCESS_TYPE, GADGET_ID_NONE, -1, options_access_type, @@ -2149,7 +2168,7 @@ static struct NULL, NULL, "type of access to this field" }, { - -1, ED_ELEMENT_SETTINGS_YPOS(3), + -1, ED_ELEMENT_SETTINGS_YPOS(2), GADGET_ID_CUSTOM_ACCESS_LAYER, GADGET_ID_CUSTOM_ACCESS_TYPE, -1, options_access_layer, @@ -2157,7 +2176,7 @@ static struct NULL, NULL, "layer of access for this field" }, { - -1, ED_ELEMENT_SETTINGS_YPOS(3), + -1, ED_ELEMENT_SETTINGS_YPOS(2), GADGET_ID_CUSTOM_ACCESS_PROTECTED, GADGET_ID_CUSTOM_ACCESS_LAYER, -1, options_access_protected, @@ -2165,7 +2184,7 @@ static struct NULL, NULL, "protected access for this field" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(4), + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(3), GADGET_ID_CUSTOM_ACCESS_DIRECTION, GADGET_ID_NONE, -1, options_access_direction, @@ -2173,7 +2192,7 @@ static struct "from", NULL, "access direction for this field" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(5), + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(4), GADGET_ID_CUSTOM_WALK_TO_ACTION, GADGET_ID_NONE, -1, options_walk_to_action, @@ -2342,7 +2361,7 @@ static struct /* ---------- element settings: configure (group elements) --------------- */ { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(6), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), GADGET_ID_GROUP_CHOICE_MODE, GADGET_ID_NONE, -1, options_group_choice_mode, @@ -2404,7 +2423,7 @@ static struct NULL, NULL, "Configure custom element change pages" }, { - -1, ED_ELEMENT_SETTINGS_YPOS(2), + -1, ED_ELEMENT_SETTINGS_YPOS(14), GADGET_ID_SAVE_AS_TEMPLATE, GADGET_ID_CUSTOM_USE_TEMPLATE, -1, "Save", " ", "As Template", "Save current settings as new template" @@ -2425,39 +2444,34 @@ static struct static struct { - int gd_x, gd_y; + int graphic; int x, y; - int width, height; int gadget_id; int gadget_id_align; char *text_left, *text_right, *infotext; } graphicbutton_info[ED_NUM_GRAPHICBUTTONS] = { { - ED_BUTTON_MINUS_XPOS, ED_BUTTON_COUNT_YPOS, + IMG_EDITOR_COUNTER_DOWN, ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(14), - ED_BUTTON_COUNT_XSIZE, ED_BUTTON_COUNT_YSIZE, GADGET_ID_PREV_CHANGE_PAGE, GADGET_ID_NONE, NULL, NULL, "select previous change page" }, { - ED_BUTTON_PLUS_XPOS, ED_BUTTON_COUNT_YPOS, + IMG_EDITOR_COUNTER_UP, -1, ED_ELEMENT_SETTINGS_YPOS(14), - ED_BUTTON_COUNT_XSIZE, ED_BUTTON_COUNT_YSIZE, GADGET_ID_NEXT_CHANGE_PAGE, GADGET_ID_SELECT_CHANGE_PAGE, NULL, "change page", "select next change page" }, { - ED_COPY_CHANGE_PAGE_XPOS, ED_COPY_CHANGE_PAGE_YPOS, + IMG_EDITOR_BUTTON_GFX_CP_COPY, -1, ED_ELEMENT_SETTINGS_YPOS(14), - ED_BUTTON_COUNT_XSIZE, ED_BUTTON_COUNT_YSIZE, GADGET_ID_COPY_CHANGE_PAGE, GADGET_ID_NEXT_CHANGE_PAGE, " ", NULL, "copy settings from this change page" }, { - ED_PASTE_CHANGE_PAGE_XPOS, ED_PASTE_CHANGE_PAGE_YPOS, + IMG_EDITOR_BUTTON_GFX_CP_PASTE, -1, ED_ELEMENT_SETTINGS_YPOS(14), - ED_BUTTON_COUNT_XSIZE, ED_BUTTON_COUNT_YSIZE, GADGET_ID_PASTE_CHANGE_PAGE, GADGET_ID_COPY_CHANGE_PAGE, NULL, NULL, "paste settings to this change page" }, @@ -2785,42 +2799,42 @@ static struct "use graphic of element:", "use existing element graphic" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(14), GADGET_ID_CUSTOM_USE_TEMPLATE, GADGET_ID_NONE, &level.use_custom_template, NULL, "use template", "use template for custom properties" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), GADGET_ID_CUSTOM_ACCESSIBLE, GADGET_ID_NONE, &custom_element_properties[EP_ACCESSIBLE], NULL, NULL, "player can walk to or pass this field" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), GADGET_ID_CUSTOM_GRAV_REACHABLE, GADGET_ID_NONE, &custom_element_properties[EP_GRAVITY_REACHABLE], NULL, "reachable despite gravity", "player can walk/dig despite gravity" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(13), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(11), GADGET_ID_CUSTOM_USE_LAST_VALUE, GADGET_ID_NONE, &custom_element.use_last_ce_value, NULL, "use last CE value after change", "use last CE value after change" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), GADGET_ID_CUSTOM_WALK_TO_OBJECT, GADGET_ID_NONE, &custom_element_properties[EP_WALK_TO_OBJECT], NULL, NULL, "player can dig/collect/push element" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8), GADGET_ID_CUSTOM_INDESTRUCTIBLE, GADGET_ID_NONE, &custom_element_properties[EP_INDESTRUCTIBLE], NULL, @@ -3214,7 +3228,7 @@ static struct /* ---------- group element content -------------------------------------- */ { - ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(4), + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(2), GADGET_ID_GROUP_CONTENT, GADGET_ID_NONE, &group_element_info.element[0], MAX_ELEMENTS_IN_GROUP, 1, "content:", NULL, NULL, NULL @@ -3237,12 +3251,18 @@ static struct ----------------------------------------------------------------------------- */ +/* maximal size of level editor drawing area */ +static int MAX_ED_FIELDX, MAX_ED_FIELDY; + /* actual size of level editor drawing area */ static int ed_fieldx, ed_fieldy; /* actual position of level editor drawing area in level playfield */ static int level_xpos = -1, level_ypos = -1; +/* actual tile size used to display level editor playfield */ +static int ed_tilesize = DEFAULT_EDITOR_TILESIZE; + #define IN_ED_FIELD(x,y) IN_FIELD(x, y, ed_fieldx, ed_fieldy) /* drawing elements on the three mouse buttons */ @@ -3254,7 +3274,10 @@ static int new_element3 = EL_SAND; #define BUTTON_ELEMENT(button) ((button) == 1 ? new_element1 : \ (button) == 2 ? new_element2 : \ (button) == 3 ? new_element3 : EL_EMPTY) -#define BUTTON_STEPSIZE(button) ((button) == 1 ? 1 : (button) == 2 ? 5 : 10) +#define BUTTON_STEPSIZE(button) ((button) == 1 ? 1 : \ + (button) == 2 ? 5 : \ + (button) == 3 ? 10 : \ + (button)) /* forward declaration for internal use */ static void ModifyEditorCounterValue(int, int); @@ -3299,6 +3322,7 @@ static short UndoBuffer[NUM_UNDO_STEPS][MAX_LEV_FIELDX][MAX_LEV_FIELDY]; static short IntelliDrawBuffer[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; static int undo_buffer_position = 0; static int undo_buffer_steps = 0; +static int redo_buffer_steps = 0; static int edit_mode; static int edit_mode_levelinfo; @@ -4787,27 +4811,47 @@ static char *getElementInfoText(int element) return info_text; } -char *getElementDescriptionFilename(int element) +static char *getElementDescriptionFilenameExt(char *basename) { - char *docs_dir = options.docs_directory; char *elements_subdir = "elements"; + static char *elements_subdir2 = NULL; static char *filename = NULL; - char basename[MAX_FILENAME_LEN]; + + if (elements_subdir2 == NULL) + elements_subdir2 = getPath2(DOCS_DIRECTORY, elements_subdir); checked_free(filename); - /* 1st try: look for element description file for exactly this element */ - sprintf(basename, "%s.txt", element_info[element].token_name); - filename = getPath3(docs_dir, elements_subdir, basename); + /* 1st try: look for element description in current level set directory */ + filename = getPath3(getCurrentLevelDir(), elements_subdir2, basename); if (fileExists(filename)) return filename; free(filename); + /* 2nd try: look for element description in the game's base directory */ + filename = getPath3(options.docs_directory, elements_subdir, basename); + if (fileExists(filename)) + return filename; + + return NULL; +} + +char *getElementDescriptionFilename(int element) +{ + char basename[MAX_FILENAME_LEN]; + char *filename; + + /* 1st try: look for element description file for exactly this element */ + sprintf(basename, "%s.txt", element_info[element].token_name); + filename = getElementDescriptionFilenameExt(basename); + if (filename != NULL) + return filename; + /* 2nd try: look for element description file for this element's class */ sprintf(basename, "%s.txt", element_info[element].class_name); - filename = getPath3(docs_dir, elements_subdir, basename); - if (fileExists(filename)) + filename = getElementDescriptionFilenameExt(basename); + if (filename != NULL) return filename; return NULL; @@ -4926,7 +4970,9 @@ static void ReinitializeElementList() { if (setup.editor.el_headlines) { - num_editor_elements += *editor_elements_info[i].headline_list_size; + // required for correct padding of palette headline buttons + if (*editor_elements_info[i].headline_list_size > 0) + num_editor_elements += editor.palette.cols; for (j = 0; j < *editor_elements_info[i].headline_list_size; j++) { @@ -4940,7 +4986,13 @@ static void ReinitializeElementList() if (found_inactive_cascade) continue; - num_editor_elements += *editor_elements_info[i].element_list_size; + // required for correct padding of palette element buttons + int element_list_size = *editor_elements_info[i].element_list_size; + int element_rows = + (element_list_size + editor.palette.cols - 1) / editor.palette.cols; + int element_buttons = editor.palette.cols * element_rows; + + num_editor_elements += element_buttons; } } @@ -4964,9 +5016,16 @@ static void ReinitializeElementList() { if (setup.editor.el_headlines) { - for (j = 0; j < *editor_elements_info[i].headline_list_size; j++) + // required for correct padding of palette headline buttons + int headline_size = (*editor_elements_info[i].headline_list_size > 0 ? + editor.palette.cols : 0); + + for (j = 0; j < headline_size; j++) { - int element = (*editor_elements_info[i].headline_list)[j]; + // use empty elements for padding of palette headline buttons + int element = (j < *editor_elements_info[i].headline_list_size ? + (*editor_elements_info[i].headline_list)[j] : + editor_el_empty[0]); editor_elements[pos++] = element; @@ -4978,8 +5037,19 @@ static void ReinitializeElementList() if (found_inactive_cascade) continue; - for (j = 0; j < *editor_elements_info[i].element_list_size; j++) + // required for correct padding of palette element buttons + int element_list_size = *editor_elements_info[i].element_list_size; + int element_rows = + (element_list_size + editor.palette.cols - 1) / editor.palette.cols; + int element_buttons = editor.palette.cols * element_rows; + + // copy all elements from element list + for (j = 0; j < element_list_size; j++) editor_elements[pos++] = (*editor_elements_info[i].element_list)[j]; + + // use empty elements for padding of palette element buttons + for (j = 0; j < element_buttons - element_list_size; j++) + editor_elements[pos++] = editor_el_empty[0]; } } @@ -5070,8 +5140,8 @@ static void DrawElementBorder(int dest_x, int dest_y, int width, int height, (input ? IMG_EDITOR_ELEMENT_BORDER_INPUT : IMG_EDITOR_ELEMENT_BORDER); Bitmap *src_bitmap; int src_x, src_y; - int bx = (input ? 4 : 8); - int by = (input ? 4 : 8); + int bx = (input ? ED_ELEMENT_BORDER_INPUT : ED_ELEMENT_BORDER); + int by = (input ? ED_ELEMENT_BORDER_INPUT : ED_ELEMENT_BORDER); int bx2 = TILEX - bx; int by2 = TILEY - by; int i; @@ -5106,6 +5176,21 @@ static void DrawElementBorder(int dest_x, int dest_y, int width, int height, ClearRectangle(drawto, dest_x - 1, dest_y - 1, width + 2, height + 2); } +static void DrawEditorElement(int x, int y, int element) +{ + DrawSizedElement(x, y, element, ed_tilesize); +} + +static void DrawEditorElementOrWall(int x, int y, int scroll_x, int scroll_y) +{ + DrawSizedElementOrWall(x, y, scroll_x, scroll_y, ed_tilesize); +} + +static void DrawEditorLevel(int size_x, int size_y, int scroll_x, int scroll_y) +{ + DrawSizedLevel(size_x, size_y, scroll_x, scroll_y, ed_tilesize); +} + static void DrawDrawingArea(int id) { struct GadgetInfo *gi = level_editor_gadget[drawingarea_info[id].gadget_id]; @@ -5123,31 +5208,31 @@ static void DrawDrawingArea(int id) el2edimg(value[x * area_ysize + y])); } -static void ScrollMiniLevel(int from_x, int from_y, int scroll) +static void ScrollEditorLevel(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)); + SX + (dx == -1 ? ed_tilesize : 0), + SY + (dy == -1 ? ed_tilesize : 0), + (ed_fieldx * ed_tilesize) - (dx != 0 ? ed_tilesize : 0), + (ed_fieldy * ed_tilesize) - (dy != 0 ? ed_tilesize : 0), + SX + (dx == +1 ? ed_tilesize : 0), + SY + (dy == +1 ? ed_tilesize : 0)); if (dx) { x = (dx == 1 ? 0 : ed_fieldx - 1); for (y = 0; y < ed_fieldy; y++) - DrawMiniElementOrWall(x, y, from_x, from_y); + DrawEditorElementOrWall(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); + DrawEditorElementOrWall(x, y, from_x, from_y); } redraw_mask |= REDRAW_FIELD; @@ -5165,48 +5250,41 @@ void getElementListGraphicSource(int element, Bitmap **bitmap, int *x, int *y) static void CreateControlButtons() { - Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; struct GadgetInfo *gi; - unsigned int 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 gd_x1a, gd_x2a, gd_y1a, gd_y2a; - 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) + int id = controlbutton_info[i].gadget_id; + int type = controlbutton_info[i].gadget_type; + int graphic = controlbutton_info[i].graphic; + struct XY *pos = controlbutton_info[i].pos; + struct GraphicInfo *gd = &graphic_info[graphic]; + int gd_x1 = gd->src_x; + int gd_y1 = gd->src_y; + int gd_x2 = gd->src_x + gd->pressed_xoffset; + int gd_y2 = gd->src_y + gd->pressed_yoffset; + int gd_x1a = gd->src_x + gd->active_xoffset; + int gd_y1a = gd->src_y + gd->active_yoffset; + int gd_x2a = gd->src_x + gd->active_xoffset + gd->pressed_xoffset; + int gd_y2a = gd->src_y + gd->active_yoffset + gd->pressed_yoffset; + int x = pos->x; + int y = pos->y; + unsigned int event_mask; + int radio_button_nr = RADIO_NR_NONE; + boolean checked = FALSE; + + if (type == GD_TYPE_RADIO_BUTTON) { - button_type = GD_TYPE_RADIO_BUTTON; - radio_button_nr = RADIO_NR_DRAWING_TOOLBOX; - checked = (id == drawing_function ? TRUE : FALSE); event_mask = GD_EVENT_PRESSED; + radio_button_nr = RADIO_NR_DRAWING_TOOLBOX; + + if (id == drawing_function) + checked = TRUE; } 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 || @@ -5216,117 +5294,32 @@ static void CreateControlButtons() 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 if (id < ED_NUM_CTRL1_4_BUTTONS) - { - 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 */ - } - else - { - gd_xoffset = DX - EX + ED_CTRL5_BUTTONS_XPOS; - gd_yoffset = DY - EY + ED_CTRL5_BUTTONS_YPOS; - width = ED_CTRL5_BUTTON_XSIZE; - height = ED_CTRL5_BUTTON_YSIZE; - - gd_x1 = DOOR_GFX_PAGEX6 + ED_CTRL5_BUTTONS_GFX_XPOS; - gd_x2 = 0; /* no alternative graphic for these buttons */ - gd_y1 = DOOR_GFX_PAGEY1 + ED_CTRL5_BUTTONS_GFX_YPOS; - gd_y2 = DOOR_GFX_PAGEY1 + ED_CTRL5_BUTTONS_GFX_YPOS - height; - } - - if (id < ED_NUM_CTRL1_4_BUTTONS) + if (id == GADGET_ID_PROPERTIES) { - gd_x1a = gd_x1; - gd_y1a = gd_y2; - gd_x2a = gd_x2; - gd_y2a = gd_y2; - gd_x1 = gd_x1; - gd_y1 = gd_y1; - gd_x2 = gd_x2; - gd_y2 = gd_y1; + x += DX; + y += DY; } else { - gd_x1a = 0; - gd_y1a = 0; - gd_x2a = 0; - gd_y2a = 0; - gd_x1 = gd_x1; - gd_y1 = gd_y1; - gd_x2 = gd_x1; - gd_y2 = gd_y2; + x += EX; + y += EY; } 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_INFO_TEXT, controlbutton_info[i].infotext, + GDI_X, x, + GDI_Y, y, + GDI_WIDTH, gd->width, + GDI_HEIGHT, gd->height, + GDI_TYPE, 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_y2, - GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x1a, gd_y1a, - GDI_ALT_DESIGN_PRESSED, gd_bitmap, gd_x2a, gd_y2a, + GDI_DESIGN_UNPRESSED, gd->bitmap, gd_x1, gd_y1, + GDI_DESIGN_PRESSED, gd->bitmap, gd_x2, gd_y2, + GDI_ALT_DESIGN_UNPRESSED, gd->bitmap, gd_x1a, gd_y1a, + GDI_ALT_DESIGN_PRESSED, gd->bitmap, gd_x2a, gd_y2a, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleControlButtons, @@ -5358,36 +5351,27 @@ static void CreateControlButtons() int id = scrollbutton_info[i].gadget_id; int graphic = scrollbutton_info[i].graphic; struct GraphicInfo *gd = &graphic_info[graphic]; - int x, y, width, height; - int gd_x1, gd_x2, gd_y1, gd_y2; - - x = scrollbutton_pos[i].x; - y = scrollbutton_pos[i].y; - - event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED; + Bitmap *gd_bitmap = gd->bitmap; + int gd_x1 = gd->src_x; + int gd_y1 = gd->src_y; + int gd_x2 = gd->src_x + gd->pressed_xoffset; + int gd_y2 = gd->src_y + gd->pressed_yoffset; + int width = gd->width; + int height = gd->height; + int x = scrollbutton_pos[i].x; + int y = scrollbutton_pos[i].y; + unsigned int 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 = gd->width; - height = gd->height; - gd_x1 = gd->src_x; - gd_y1 = gd->src_y; - gd_x2 = gd->src_x + gd->pressed_xoffset; - gd_y2 = gd->src_y + gd->pressed_yoffset; } else { x += SX; y += SY; - width = gd->width; - height = gd->height; - gd_x1 = gd->src_x; - gd_y1 = gd->src_y; - gd_x2 = gd->src_x + gd->pressed_xoffset; - gd_y2 = gd->src_y + gd->pressed_yoffset; } gi = CreateGadget(GDI_CUSTOM_ID, id, @@ -5415,27 +5399,24 @@ static void CreateControlButtons() /* create buttons for element list */ for (i = 0; i < ED_NUM_ELEMENTLIST_BUTTONS; i++) { - struct GraphicInfo *gd = &graphic_info[IMG_EDITOR_PALETTE_BUTTON]; + int id = GADGET_ID_ELEMENTLIST_FIRST + i; + int graphic = IMG_EDITOR_PALETTE_BUTTON; + struct GraphicInfo *gd = &graphic_info[graphic]; + Bitmap *gd_bitmap = gd->bitmap; Bitmap *deco_bitmap; int deco_x, deco_y, deco_xpos, deco_ypos; - int gd_xoffset, gd_yoffset; - int gd_x1, gd_y1, gd_x2, gd_y2; - int x = i % ED_ELEMENTLIST_BUTTONS_HORIZ; - int y = i / ED_ELEMENTLIST_BUTTONS_HORIZ; - int id = GADGET_ID_ELEMENTLIST_FIRST + i; + int gd_x1 = gd->src_x; + int gd_y1 = gd->src_y; + int gd_x2 = gd->src_x + gd->pressed_xoffset; + int gd_y2 = gd->src_y + gd->pressed_yoffset; + int xx = i % ED_ELEMENTLIST_BUTTONS_HORIZ; + int yy = i / ED_ELEMENTLIST_BUTTONS_HORIZ; + int x = DX + ED_ELEMENTLIST_XPOS + xx * gd->width; + int y = DY + ED_ELEMENTLIST_YPOS + yy * gd->height; int element = editor_elements[i]; int tile_size = (editor.palette.tile_size >= TILESIZE ? TILESIZE : MINI_TILESIZE); - - event_mask = GD_EVENT_RELEASED; - - gd_xoffset = ED_ELEMENTLIST_XPOS + x * gd->width; - gd_yoffset = ED_ELEMENTLIST_YPOS + y * gd->height; - - gd_x1 = gd->src_x; - gd_y1 = gd->src_y; - gd_x2 = gd->src_x + gd->pressed_xoffset; - gd_y2 = gd->src_y + gd->pressed_yoffset; + unsigned int event_mask = GD_EVENT_RELEASED; getElementListGraphicSource(element, &deco_bitmap, &deco_x, &deco_y); deco_xpos = (gd->width - tile_size) / 2; @@ -5444,14 +5425,14 @@ static void CreateControlButtons() 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_X, x, + GDI_Y, y, GDI_WIDTH, gd->width, GDI_HEIGHT, gd->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_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1, + GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2, GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y, GDI_DECORATION_POSITION, deco_xpos, deco_ypos, GDI_DECORATION_SIZE, tile_size, tile_size, @@ -5490,14 +5471,13 @@ static void CreateCounterButtons() 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_y, gd_x1, gd_x2, gd_y1, gd_y2; - int x_size, y_size; + int graphic; + struct GraphicInfo *gd; + int gd_x1, gd_x2, gd_y1, gd_y2; unsigned int event_mask; char infotext[max_infotext_len + 1]; @@ -5505,12 +5485,9 @@ static void CreateCounterButtons() if (i == ED_COUNTER_ID_SELECT_LEVEL) { - int graphic = (j == 0 ? - IMG_EDITOR_BUTTON_GFX_PREV_LEVEL : - IMG_EDITOR_BUTTON_GFX_NEXT_LEVEL); - struct GraphicInfo *gd = &graphic_info[graphic]; - - gd_bitmap = gd->bitmap; + graphic = (j == 0 ? + IMG_EDITOR_BUTTON_GFX_PREV_LEVEL : + IMG_EDITOR_BUTTON_GFX_NEXT_LEVEL); event_mask |= GD_EVENT_RELEASED; @@ -5524,25 +5501,21 @@ static void CreateCounterButtons() x = DX + editor.button.next_level.x; y = DY + editor.button.next_level.y; } - - gd_x1 = gd->src_x; - gd_y1 = gd->src_y; - gd_x2 = gd->src_x + gd->pressed_xoffset; - gd_y2 = gd->src_y + gd->pressed_yoffset; - x_size = gd->width; - y_size = gd->height; } 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_y1 = DOOR_GFX_PAGEY1 + ED_BUTTON_COUNT_YPOS; - gd_y2 = gd_y1; - x_size = ED_BUTTON_COUNT_XSIZE; - y_size = ED_BUTTON_COUNT_YSIZE; + graphic = (j == 0 ? + IMG_EDITOR_COUNTER_DOWN : + IMG_EDITOR_COUNTER_UP); } + gd = &graphic_info[graphic]; + + gd_x1 = gd->src_x; + gd_y1 = gd->src_y; + gd_x2 = gd->src_x + gd->pressed_xoffset; + gd_y2 = gd->src_y + gd->pressed_yoffset; + sprintf(infotext, "%s counter value by 1, 5 or 10", (j == 0 ? "decrease" : "increase")); @@ -5551,12 +5524,12 @@ static void CreateCounterButtons() GDI_INFO_TEXT, infotext, GDI_X, x, GDI_Y, y, - GDI_WIDTH, x_size, - GDI_HEIGHT, y_size, + GDI_WIDTH, gd->width, + GDI_HEIGHT, gd->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_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, HandleCounterButtons, @@ -5575,36 +5548,33 @@ static void CreateCounterButtons() { int font_type = FONT_INPUT_1; int font_type_active = FONT_INPUT_1_ACTIVE; - int gd_width = ED_WIN_COUNT_XSIZE; - int border_size = ED_BORDER_SIZE; id = counterbutton_info[i].gadget_id_text; + event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING; if (i == ED_COUNTER_ID_SELECT_LEVEL) { - int graphic = IMG_EDITOR_INPUT_GFX_LEVEL_NUMBER; - struct GraphicInfo *gd = &graphic_info[graphic]; + graphic = IMG_EDITOR_INPUT_GFX_LEVEL_NUMBER; - gd_bitmap = gd->bitmap; + font_type = FONT_LEVEL_NUMBER; + font_type_active = FONT_LEVEL_NUMBER_ACTIVE; x = DX + editor.input.level_number.x; y = DY + editor.input.level_number.y; - - gd_x = gd->src_x; - gd_y = gd->src_y; - gd_width = gd->width; - border_size = gd->border_size; - - font_type = FONT_LEVEL_NUMBER; - font_type_active = FONT_LEVEL_NUMBER_ACTIVE; } else { - gd_x = DOOR_GFX_PAGEX4 + ED_WIN_COUNT_XPOS; - gd_y = DOOR_GFX_PAGEY1 + ED_WIN_COUNT_YPOS; + graphic = IMG_EDITOR_COUNTER_INPUT; } + gd = &graphic_info[graphic]; + + gd_x1 = gd->src_x; + gd_y1 = gd->src_y; + gd_x2 = gd->src_x + gd->active_xoffset; + gd_y2 = gd->src_y + gd->active_yoffset; + gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_CUSTOM_TYPE_ID, i, GDI_INFO_TEXT, "enter counter value", @@ -5617,10 +5587,10 @@ static void CreateCounterButtons() 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, border_size, border_size, - GDI_DESIGN_WIDTH, gd_width, + GDI_DESIGN_UNPRESSED, gd->bitmap, gd_x1, gd_y1, + GDI_DESIGN_PRESSED, gd->bitmap, gd_x2, gd_y2, + GDI_BORDER_SIZE, gd->border_size, gd->border_size, + GDI_DESIGN_WIDTH, gd->width, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleCounterButtons, @@ -5676,7 +5646,7 @@ static void CreateDrawingAreas() GDI_Y, y, GDI_TYPE, GD_TYPE_DRAWING_AREA, GDI_AREA_SIZE, area_xsize, area_ysize, - GDI_ITEM_SIZE, MINI_TILEX, MINI_TILEY, + GDI_ITEM_SIZE, ed_tilesize, ed_tilesize, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_INFO, HandleDrawingAreaInfo, GDI_CALLBACK_ACTION, HandleDrawingAreas, @@ -5698,8 +5668,11 @@ static void CreateTextInputGadgets() for (i = 0; i < ED_NUM_TEXTINPUT; i++) { - Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; - int gd_x, gd_y; + struct GraphicInfo *gd = &graphic_info[IMG_EDITOR_INPUT_TEXT]; + int gd_x1 = gd->src_x; + int gd_y1 = gd->src_y; + int gd_x2 = gd->src_x + gd->active_xoffset; + int gd_y2 = gd->src_y + gd->active_yoffset; struct GadgetInfo *gi; unsigned int event_mask; char infotext[MAX_OUTPUT_LINESIZE + 1]; @@ -5707,9 +5680,6 @@ static void CreateTextInputGadgets() 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'; @@ -5723,10 +5693,10 @@ static void CreateTextInputGadgets() 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_DESIGN_UNPRESSED, gd->bitmap, gd_x1, gd_y1, + GDI_DESIGN_PRESSED, gd->bitmap, gd_x2, gd_y2, + GDI_BORDER_SIZE, gd->border_size, gd->border_size, + GDI_DESIGN_WIDTH, gd->width, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleTextInputGadgets, @@ -5746,8 +5716,11 @@ static void CreateTextAreaGadgets() for (i = 0; i < ED_NUM_TEXTAREAS; i++) { - Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; - int gd_x, gd_y; + struct GraphicInfo *gd = &graphic_info[IMG_EDITOR_INPUT_TEXTAREA]; + int gd_x1 = gd->src_x; + int gd_y1 = gd->src_y; + int gd_x2 = gd->src_x + gd->active_xoffset; + int gd_y2 = gd->src_y + gd->active_yoffset; struct GadgetInfo *gi; unsigned int event_mask; char infotext[MAX_OUTPUT_LINESIZE + 1]; @@ -5757,9 +5730,6 @@ static void CreateTextAreaGadgets() 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'; @@ -5772,10 +5742,10 @@ static void CreateTextAreaGadgets() 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_DESIGN_UNPRESSED, gd->bitmap, gd_x1, gd_y1, + GDI_DESIGN_PRESSED, gd->bitmap, gd_x2, gd_y2, + GDI_BORDER_SIZE, gd->border_size, gd->border_size, + GDI_DESIGN_WIDTH, gd->width, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleTextAreaGadgets, @@ -5795,8 +5765,13 @@ static void CreateSelectboxGadgets() for (i = 0; i < ED_NUM_SELECTBOX; i++) { - Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; - int gd_x, gd_y; + struct GraphicInfo *gd = &graphic_info[IMG_EDITOR_SELECTBOX_INPUT]; + struct GraphicInfo *gd2 = &graphic_info[IMG_EDITOR_SELECTBOX_BUTTON]; + int gd_x1 = gd->src_x; + int gd_y1 = gd->src_y; + int gd_x2 = gd->src_x + gd->active_xoffset; + int gd_y2 = gd->src_y + gd->active_yoffset; + int selectbox_button_xsize = gd2->width; struct GadgetInfo *gi; unsigned int event_mask; char infotext[MAX_OUTPUT_LINESIZE + 1]; @@ -5821,9 +5796,6 @@ static void CreateSelectboxGadgets() 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] + @@ -5848,11 +5820,11 @@ static void CreateSelectboxGadgets() GDI_TEXT_FONT, FONT_INPUT_1, GDI_TEXT_FONT_ACTIVE, FONT_INPUT_1_ACTIVE, GDI_TEXT_FONT_UNSELECTABLE, FONT_TEXT_1, - 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_DESIGN_UNPRESSED, gd->bitmap, gd_x1, gd_y1, + GDI_DESIGN_PRESSED, gd->bitmap, gd_x2, gd_y2, + GDI_BORDER_SIZE, gd->border_size, gd->border_size, + GDI_BORDER_SIZE_SELECTBUTTON, selectbox_button_xsize, + GDI_DESIGN_WIDTH, gd->width, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleSelectboxGadgets, @@ -5874,12 +5846,23 @@ static void CreateTextbuttonGadgets() 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; + int id = textbutton_info[i].gadget_id; + int graphic = + ((id >= GADGET_ID_LEVELINFO_LEVEL && id <= GADGET_ID_LEVELINFO_EDITOR) || + (id >= GADGET_ID_PROPERTIES_INFO && id <= GADGET_ID_PROPERTIES_CHANGE) ? + IMG_EDITOR_TABBUTTON : IMG_EDITOR_TEXTBUTTON); + struct GraphicInfo *gd = &graphic_info[graphic]; + int gd_x1 = gd->src_x; + int gd_y1 = gd->src_y; + int gd_x2 = gd->src_x + gd->pressed_xoffset; + int gd_y2 = gd->src_y + gd->pressed_yoffset; + int gd_x1a = gd->src_x + gd->active_xoffset; + int gd_y1a = gd->src_y + gd->active_yoffset; + int border_xsize = gd->border_size + gd->draw_xoffset; + int border_ysize = gd->border_size; struct GadgetInfo *gi; unsigned int 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; @@ -5888,22 +5871,6 @@ static void CreateTextbuttonGadgets() event_mask = GD_EVENT_RELEASED; - if ((id >= GADGET_ID_LEVELINFO_LEVEL && id <= GADGET_ID_LEVELINFO_EDITOR) || - (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'; @@ -5924,13 +5891,13 @@ static void CreateTextbuttonGadgets() 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_TEXT_FONT, FONT_INPUT_2, + GDI_TEXT_FONT_ACTIVE, FONT_INPUT_2_ACTIVE, + GDI_DESIGN_UNPRESSED, gd->bitmap, gd_x1, gd_y1, + GDI_DESIGN_PRESSED, gd->bitmap, gd_x2, gd_y2, + GDI_ALT_DESIGN_UNPRESSED, gd->bitmap, gd_x1a, gd_y1a, + GDI_BORDER_SIZE, border_xsize, border_ysize, + GDI_DESIGN_WIDTH, gd->width, GDI_DECORATION_SHIFTING, 1, 1, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, @@ -5948,7 +5915,6 @@ static void CreateTextbuttonGadgets() static void CreateGraphicbuttonGadgets() { - Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; struct GadgetInfo *gi; unsigned int event_mask; int i; @@ -5957,27 +5923,16 @@ static void CreateGraphicbuttonGadgets() 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; + struct GraphicInfo *gd = &graphic_info[graphicbutton_info[i].graphic]; + int gd_x1 = gd->src_x; + int gd_y1 = gd->src_y; + int gd_x2 = gd->src_x + gd->pressed_xoffset; + int gd_y2 = gd->src_y + gd->pressed_yoffset; 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] + @@ -5992,12 +5947,12 @@ static void CreateGraphicbuttonGadgets() 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_WIDTH, gd->width, + GDI_HEIGHT, gd->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_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, @@ -6129,31 +6084,29 @@ static void CreateScrollbarGadgets() static void CreateCheckbuttonGadgets() { - Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; struct GadgetInfo *gi; unsigned int 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 graphic = (id == GADGET_ID_STICK_ELEMENT ? IMG_EDITOR_STICKYBUTTON : + IMG_EDITOR_CHECKBOX); + struct GraphicInfo *gd = &graphic_info[graphic]; + int gd_x1 = gd->src_x; + int gd_y1 = gd->src_y; + int gd_x2 = gd->src_x + gd->pressed_xoffset; + int gd_y2 = gd->src_y + gd->pressed_yoffset; + int gd_x1a = gd->src_x + gd->active_xoffset; + int gd_y1a = gd->src_y + gd->active_yoffset; + int gd_x2a = gd->src_x + gd->active_xoffset + gd->pressed_xoffset; + int gd_y2a = gd->src_y + gd->active_yoffset + gd->pressed_yoffset; 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] + @@ -6168,14 +6121,14 @@ static void CreateCheckbuttonGadgets() GDI_INFO_TEXT, checkbutton_info[i].infotext, GDI_X, x, GDI_Y, y, - GDI_WIDTH, ED_CHECKBUTTON_XSIZE, - GDI_HEIGHT, ED_CHECKBUTTON_YSIZE, + GDI_WIDTH, gd->width, + GDI_HEIGHT, gd->height, 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_DESIGN_UNPRESSED, gd->bitmap, gd_x1, gd_y1, + GDI_DESIGN_PRESSED, gd->bitmap, gd_x2, gd_y2, + GDI_ALT_DESIGN_UNPRESSED, gd->bitmap, gd_x1a, gd_y1a, + GDI_ALT_DESIGN_PRESSED, gd->bitmap, gd_x2a, gd_y2a, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleCheckbuttons, @@ -6192,20 +6145,21 @@ static void CreateCheckbuttonGadgets() static void CreateRadiobuttonGadgets() { - Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; + struct GraphicInfo *gd = &graphic_info[IMG_EDITOR_RADIOBUTTON]; + int gd_x1 = gd->src_x; + int gd_y1 = gd->src_y; + int gd_x2 = gd->src_x + gd->pressed_xoffset; + int gd_y2 = gd->src_y + gd->pressed_yoffset; + int gd_x1a = gd->src_x + gd->active_xoffset; + int gd_y1a = gd->src_y + gd->active_yoffset; + int gd_x2a = gd->src_x + gd->active_xoffset + gd->pressed_xoffset; + int gd_y2a = gd->src_y + gd->active_yoffset + gd->pressed_yoffset; struct GadgetInfo *gi; unsigned int 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; @@ -6229,15 +6183,15 @@ static void CreateRadiobuttonGadgets() GDI_INFO_TEXT, radiobutton_info[i].infotext, GDI_X, x, GDI_Y, y, - GDI_WIDTH, ED_CHECKBUTTON_XSIZE, - GDI_HEIGHT, ED_CHECKBUTTON_YSIZE, + GDI_WIDTH, gd->width, + GDI_HEIGHT, gd->height, 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_DESIGN_UNPRESSED, gd->bitmap, gd_x1, gd_y1, + GDI_DESIGN_PRESSED, gd->bitmap, gd_x2, gd_y2, + GDI_ALT_DESIGN_UNPRESSED, gd->bitmap, gd_x1a, gd_y1a, + GDI_ALT_DESIGN_PRESSED, gd->bitmap, gd_x2a, gd_y2a, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleRadiobuttons, @@ -6635,7 +6589,6 @@ static void UnmapLevelEditorToolboxCustomGadgets() static void MapOrUnmapLevelEditorToolboxDrawingGadgets(boolean map) { - Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; int i; for (i = 0; i < ED_NUM_CTRL1_BUTTONS; i++) @@ -6646,14 +6599,17 @@ static void MapOrUnmapLevelEditorToolboxDrawingGadgets(boolean map) struct GadgetInfo *gi = level_editor_gadget[i]; if (map) + { MapGadget(gi); + } else { + int graphic = IMG_EDITOR_NO_TOOLBOX_BUTTON; + struct GraphicInfo *gd = &graphic_info[graphic]; + UnmapGadget(gi); - BlitBitmap(gd_bitmap, drawto, - DOOR_GFX_PAGEX6 + ED_CTRL_NO_BUTTONS_GFX_XPOS, - DOOR_GFX_PAGEY1 + ED_CTRL_NO_BUTTONS_GFX_YPOS, + BlitBitmap(gd->bitmap, drawto, gd->src_x, gd->src_y, gi->width, gi->height, gi->x, gi->y); redraw_mask |= REDRAW_DOOR_3; @@ -6699,6 +6655,8 @@ static void ResetUndoBuffer() { undo_buffer_position = -1; undo_buffer_steps = -1; + redo_buffer_steps = 0; + CopyLevelToUndoBuffer(UNDO_IMMEDIATE); level.changed = FALSE; @@ -7423,6 +7381,31 @@ void CheckElementDescriptions() Error(ERR_WARN, "no element description for element '%s'", EL_NAME(i)); } +static int getMaxEdFieldX(boolean has_scrollbar) +{ + int scrollbar_width = (has_scrollbar ? ED_SCROLLBUTTON_XSIZE : 0); + int sxsize = SXSIZE - scrollbar_width; + int max_ed_fieldx = sxsize / ed_tilesize; + + return max_ed_fieldx; +} + +static int getMaxEdFieldY(boolean has_scrollbar) +{ + int infotext_height = INFOTEXT_YSIZE; + int scrollbar_height = (has_scrollbar ? ED_SCROLLBUTTON_YSIZE : 0); + int sysize = SYSIZE - scrollbar_height - infotext_height; + int max_ed_fieldy = sysize / ed_tilesize; + + return max_ed_fieldy; +} + +void InitZoomLevelSettings() +{ + MAX_ED_FIELDX = getMaxEdFieldX(FALSE); + MAX_ED_FIELDY = getMaxEdFieldY(FALSE); +} + static boolean playfield_area_changed = FALSE; void DrawLevelEd() @@ -7439,6 +7422,8 @@ void DrawLevelEd() /* needed if different viewport properties defined for editor */ ChangeViewportPropertiesIfNeeded(); + InitZoomLevelSettings(); + playfield_area_changed = DrawingAreaChanged(); OpenDoor(DOOR_OPEN_1 | DOOR_OPEN_2 | DOOR_NO_DELAY); @@ -7466,6 +7451,9 @@ void DrawLevelEd() level_ypos = -1; } + /* needed for gadgets drawn on background (like palette scrollbar) */ + SetDoorBackgroundImage(IMG_UNDEFINED); + /* copy default editor door content to main double buffer */ BlitBitmap(graphic_info[IMG_BACKGROUND_PALETTE].bitmap, drawto, graphic_info[IMG_BACKGROUND_PALETTE].src_x, @@ -7476,8 +7464,10 @@ void DrawLevelEd() DrawSpecialEditorDoor(); /* draw new control window */ - BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, - DOOR_GFX_PAGEX8, 236, EXSIZE, EYSIZE, EX, EY); + BlitBitmap(graphic_info[IMG_BACKGROUND_TOOLBOX].bitmap, drawto, + graphic_info[IMG_BACKGROUND_TOOLBOX].src_x, + graphic_info[IMG_BACKGROUND_TOOLBOX].src_y, + EXSIZE, EYSIZE, EX, EY); // redraw_mask |= REDRAW_ALL; @@ -7509,54 +7499,62 @@ static void AdjustDrawingAreaGadgets() 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); + 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; + max_ed_fieldx = getMaxEdFieldX(vertical_scrollbar_needed); + max_ed_fieldy = getMaxEdFieldY(horizontal_scrollbar_needed); /* 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); + 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; + max_ed_fieldx = getMaxEdFieldX(vertical_scrollbar_needed); + max_ed_fieldy = getMaxEdFieldY(horizontal_scrollbar_needed); + + ed_fieldx = (ed_xsize > max_ed_fieldx ? max_ed_fieldx : ed_xsize); + ed_fieldy = (ed_ysize > max_ed_fieldy ? max_ed_fieldy : ed_ysize); - ed_fieldx = (ed_xsize < MAX_ED_FIELDX ? ed_xsize : max_ed_fieldx); - ed_fieldy = (ed_ysize < MAX_ED_FIELDY ? ed_ysize : max_ed_fieldy); + x = SX + ed_fieldx * ed_tilesize; + y = SY + ed_fieldy * ed_tilesize; + width = ed_fieldx * ed_tilesize - 2 * ED_SCROLLBUTTON_XSIZE; + height = ed_fieldy * ed_tilesize - 2 * ED_SCROLLBUTTON_YSIZE; + + /* adjust drawing area gadget */ 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_ITEM_SIZE, ed_tilesize, ed_tilesize, 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_pos[ED_SCROLLBUTTON_ID_AREA_RIGHT].x + xoffset; - y = SX + scrollbutton_pos[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_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].width + xoffset; - height = scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].height + yoffset; - + /* adjust horizontal scrollbar gadgets */ + ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LEFT], + GDI_Y, y, + GDI_END); + ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_RIGHT], + GDI_X, x - ED_SCROLLBUTTON_XSIZE, + GDI_Y, y, + GDI_END); ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_HORIZONTAL], + GDI_Y, y, GDI_WIDTH, width, GDI_SCROLLBAR_ITEMS_VISIBLE, ed_fieldx, GDI_END); + + /* adjust vertical scrollbar gadgets */ + ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_UP], + GDI_X, x, + GDI_END); + ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_DOWN], + GDI_X, x, + GDI_Y, y - ED_SCROLLBUTTON_YSIZE, + GDI_END); ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_VERTICAL], + GDI_X, x, GDI_HEIGHT, height, GDI_SCROLLBAR_ITEMS_VISIBLE, ed_fieldy, GDI_END); @@ -7761,7 +7759,7 @@ static void DrawDrawingWindow() AdjustEditorScrollbar(GADGET_ID_SCROLL_HORIZONTAL); AdjustEditorScrollbar(GADGET_ID_SCROLL_VERTICAL); - DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); + DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); MapMainDrawingArea(); MapLevelEditorToolboxDrawingGadgets(); @@ -8047,8 +8045,10 @@ static void DrawGroupElementArea(int element) { int num_elements = group_element_info.num_elements; int id = ED_DRAWING_ID_GROUP_CONTENT; - int sx = SX + drawingarea_info[id].x - MINI_TILEX / 2; - int sy = SY + drawingarea_info[id].y - MINI_TILEY / 2; + int bx = ED_ELEMENT_BORDER_INPUT; + int by = ED_ELEMENT_BORDER_INPUT; + int sx = SX + drawingarea_info[id].x - bx; + int sy = SY + drawingarea_info[id].y - by; int xsize = MAX_ELEMENTS_IN_GROUP; int ysize = 1; @@ -8060,7 +8060,7 @@ static void DrawGroupElementArea(int element) ModifyEditorDrawingArea(id, num_elements, 1); /* delete content areas in case of reducing number of them */ - DrawBackground(sx, sy, (xsize + 1) * MINI_TILEX, (ysize + 1) * MINI_TILEY); + DrawBackground(sx, sy, xsize * MINI_TILEX + 2*bx, ysize * MINI_TILEY + 2*by); MapDrawingArea(id); } @@ -8430,6 +8430,7 @@ static boolean checkPropertiesConfig(int element) static void DrawPropertiesConfig() { + boolean draw_footer_line = FALSE; int max_num_element_counters = 4; int num_element_counters = 0; int i; @@ -8672,6 +8673,8 @@ static void DrawPropertiesConfig() /* draw drawing area gadgets */ MapDrawingArea(ED_DRAWING_ID_CUSTOM_GRAPHIC); + + draw_footer_line = TRUE; } else if (edit_mode_properties == ED_MODE_PROPERTIES_CONFIG_2) { @@ -8722,6 +8725,25 @@ static void DrawPropertiesConfig() /* draw drawing area gadgets */ MapDrawingArea(ED_DRAWING_ID_CUSTOM_GRAPHIC); + + draw_footer_line = TRUE; + } + + /* draw little footer border line above CE/GE use/save template gadgets */ + if (draw_footer_line) + { + struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_PROPERTIES_INFO]; + struct GadgetDesign *gd = &gd_gi1->alt_design[GD_BUTTON_UNPRESSED]; + int gd_x = gd->x + gd_gi1->border.width / 2; + int gd_y = gd->y + gd_gi1->height - 1; + Pixel tab_color = GetPixel(gd->bitmap, gd_x, gd_y); + + if (tab_color != BLACK_PIXEL) /* black => transparent */ + FillRectangle(drawto, + SX + ED_ELEMENT_SETTINGS_XPOS(0), + SY + ED_ELEMENT_SETTINGS_YPOS(14) - MINI_TILEY / 2, + getTabulatorBarWidth(), ED_GADGET_DISTANCE, + tab_color); } } @@ -9356,7 +9378,7 @@ static void SetElementSimple(int x, int y, int element, boolean change_level) Feld[x][y] = element; if (IN_ED_FIELD(sx, sy)) - DrawMiniElement(sx, sy, element); + DrawEditorElement(sx, sy, element); } static void MergeAndCloseNeighbourElements(int x1, int y1, int *element1, @@ -10057,10 +10079,10 @@ static void DrawAreaBorder(int from_x, int from_y, int to_x, int to_y) if (from_y > to_y) swap_numbers(&from_y, &to_y); - from_sx = SX + from_x * MINI_TILEX; - from_sy = SY + from_y * MINI_TILEY; - to_sx = SX + to_x * MINI_TILEX + MINI_TILEX - 1; - to_sy = SY + to_y * MINI_TILEY + MINI_TILEY - 1; + from_sx = SX + from_x * ed_tilesize; + from_sy = SY + from_y * ed_tilesize; + to_sx = SX + (to_x + 1) * ed_tilesize - 1; + to_sy = SY + (to_y + 1) * ed_tilesize - 1; DrawSimpleWhiteLine(drawto, from_sx, from_sy, to_sx, from_sy); DrawSimpleWhiteLine(drawto, to_sx, from_sy, to_sx, to_sy); @@ -10326,7 +10348,7 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) break; case TEXT_SETCURSOR: - DrawMiniElement(last_sx, last_sy, Feld[lx][ly]); + DrawEditorElement(last_sx, last_sy, Feld[lx][ly]); DrawAreaBorder(sx, sy, sx, sy); last_sx = sx; last_sy = sy; @@ -10357,7 +10379,7 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) if (sx > start_sx) { Feld[lx - 1][ly] = delete_buffer[sx - start_sx - 1]; - DrawMiniElement(sx - 1, sy, Feld[lx - 1][ly]); + DrawEditorElement(sx - 1, sy, Feld[lx - 1][ly]); DrawLevelText(sx - 1, sy, 0, TEXT_SETCURSOR); } break; @@ -10371,7 +10393,7 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) case TEXT_END: CopyLevelToUndoBuffer(UNDO_IMMEDIATE); - DrawMiniElement(sx, sy, Feld[lx][ly]); + DrawEditorElement(sx, sy, Feld[lx][ly]); typing = FALSE; break; @@ -10392,7 +10414,7 @@ static void SetTextCursor(int unused_sx, int unused_sy, int sx, int sy, int ly = sy + level_ypos; if (element == -1) - DrawMiniElement(sx, sy, Feld[lx][ly]); + DrawEditorElement(sx, sy, Feld[lx][ly]); else DrawAreaBorder(sx, sy, sx, sy); } @@ -10404,7 +10426,7 @@ static void CheckLevelBorderElement(boolean redraw_playfield) SetBorderElement(); if (redraw_playfield && BorderElement != last_border_element) - DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); + DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); } static void CopyLevelToUndoBuffer(int mode) @@ -10413,6 +10435,9 @@ static void CopyLevelToUndoBuffer(int mode) boolean new_undo_buffer_position = TRUE; int x, y; + if (undo_buffer_steps == 0) + accumulated_undo = FALSE; + switch (mode) { case UNDO_IMMEDIATE: @@ -10431,13 +10456,16 @@ static void CopyLevelToUndoBuffer(int mode) if (new_undo_buffer_position) { - /* new position in undo buffer ring */ + /* advance position in undo buffer ring */ undo_buffer_position = (undo_buffer_position + 1) % NUM_UNDO_STEPS; if (undo_buffer_steps < NUM_UNDO_STEPS - 1) undo_buffer_steps++; } + /* always reset redo buffer when storing level change into undo buffer */ + redo_buffer_steps = 0; + for (x = 0; x < lev_fieldx; x++) for (y = 0; y < lev_fieldy; y++) UndoBuffer[undo_buffer_position][x][y] = Feld[x][y]; @@ -10499,7 +10527,7 @@ static void RandomPlacement(int new_element) } } - DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); + DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); CopyLevelToUndoBuffer(UNDO_IMMEDIATE); } @@ -10518,7 +10546,7 @@ void WrapLevel(int dx, int dy) Feld[x][y] = FieldBackup[(x + wrap_dx) % lev_fieldx][(y + wrap_dy) % lev_fieldy]; - DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); + DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); CopyLevelToUndoBuffer(UNDO_ACCUMULATE); } @@ -10751,7 +10779,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (button_press_event && Feld[lx][ly] != new_element) { FloodFill(lx, ly, new_element); - DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); + DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); CopyLevelToUndoBuffer(UNDO_IMMEDIATE); } break; @@ -10855,6 +10883,10 @@ static void HandleCounterButtons(struct GadgetInfo *gi) case ED_COUNTER_ID_LEVEL_YSIZE: lev_fieldx = level.fieldx; lev_fieldy = level.fieldy; + + /* check if resizing of level results in change of border border */ + SetBorderElement(); + break; default: @@ -11140,9 +11172,9 @@ static void HandleControlButtons(struct GadgetInfo *gi) if (level_xpos < -1) level_xpos = -1; if (button == 1) - ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_RIGHT); + ScrollEditorLevel(level_xpos, level_ypos, ED_SCROLL_RIGHT); else - DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); + DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_HORIZONTAL], GDI_SCROLLBAR_ITEM_POSITION, level_xpos + 1, GDI_END); @@ -11159,9 +11191,9 @@ static void HandleControlButtons(struct GadgetInfo *gi) if (level_xpos > lev_fieldx - ed_fieldx + 1) level_xpos = lev_fieldx - ed_fieldx + 1; if (button == 1) - ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_LEFT); + ScrollEditorLevel(level_xpos, level_ypos, ED_SCROLL_LEFT); else - DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); + DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_HORIZONTAL], GDI_SCROLLBAR_ITEM_POSITION, level_xpos + 1, GDI_END); @@ -11178,9 +11210,9 @@ static void HandleControlButtons(struct GadgetInfo *gi) if (level_ypos < -1) level_ypos = -1; if (button == 1) - ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_DOWN); + ScrollEditorLevel(level_xpos, level_ypos, ED_SCROLL_DOWN); else - DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); + DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_VERTICAL], GDI_SCROLLBAR_ITEM_POSITION, level_ypos + 1, GDI_END); @@ -11197,9 +11229,9 @@ static void HandleControlButtons(struct GadgetInfo *gi) if (level_ypos > lev_fieldy - ed_fieldy + 1) level_ypos = lev_fieldy - ed_fieldy + 1; if (button == 1) - ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_UP); + ScrollEditorLevel(level_xpos, level_ypos, ED_SCROLL_UP); else - DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); + DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_VERTICAL], GDI_SCROLLBAR_ITEM_POSITION, level_ypos + 1, GDI_END); @@ -11208,12 +11240,12 @@ static void HandleControlButtons(struct GadgetInfo *gi) case GADGET_ID_SCROLL_HORIZONTAL: level_xpos = gi->event.item_position - 1; - DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); + DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); break; case GADGET_ID_SCROLL_VERTICAL: level_ypos = gi->event.item_position - 1; - DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); + DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); break; case GADGET_ID_SCROLL_LIST_UP: @@ -11298,7 +11330,19 @@ static void HandleControlButtons(struct GadgetInfo *gi) break; case GADGET_ID_ZOOM: - printf("::: zoom button pressed with mouse button %d\n", button); + // zoom level editor tile size in or out (or reset to default size) + ed_tilesize = (button == 1 ? ed_tilesize * 2 : + button == 2 ? DEFAULT_EDITOR_TILESIZE : + button == 3 ? ed_tilesize / 2 : ed_tilesize); + + // limit zoom level by upper and lower bound + ed_tilesize = MIN(MAX(MICRO_TILESIZE, ed_tilesize), TILESIZE); + + InitZoomLevelSettings(); + + if (edit_mode == ED_MODE_DRAWING) + DrawDrawingWindow(); + break; case GADGET_ID_CUSTOM_COPY_FROM: @@ -11317,9 +11361,20 @@ static void HandleControlButtons(struct GadgetInfo *gi) break; case GADGET_ID_UNDO: - if (undo_buffer_steps == 0) + if (button == 1 && undo_buffer_steps == 0) { Request("Undo buffer empty!", REQ_CONFIRM); + + break; + } + else if (button == 2) + { + break; + } + else if (button == 3 && redo_buffer_steps == 0) + { + Request("Redo buffer empty!", REQ_CONFIRM); + break; } @@ -11329,9 +11384,25 @@ static void HandleControlButtons(struct GadgetInfo *gi) edit_mode = ED_MODE_DRAWING; } - undo_buffer_position = - (undo_buffer_position - 1 + NUM_UNDO_STEPS) % NUM_UNDO_STEPS; - undo_buffer_steps--; + if (button == 1) + { + /* undo */ + + undo_buffer_position = + (undo_buffer_position - 1 + NUM_UNDO_STEPS) % NUM_UNDO_STEPS; + + undo_buffer_steps--; + redo_buffer_steps++; + } + else + { + /* redo */ + + undo_buffer_position = (undo_buffer_position + 1) % NUM_UNDO_STEPS; + + undo_buffer_steps++; + redo_buffer_steps--; + } for (x = 0; x < lev_fieldx; x++) for (y = 0; y < lev_fieldy; y++) @@ -11340,7 +11411,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) /* check if undo operation forces change of border style */ CheckLevelBorderElement(FALSE); - DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); + DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); break; @@ -11373,7 +11444,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) CopyLevelToUndoBuffer(GADGET_ID_CLEAR); - DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); + DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); break; case GADGET_ID_SAVE: @@ -11574,11 +11645,11 @@ void HandleLevelEditorKeyInput(Key key) break; case KSYM_Page_Up: id = GADGET_ID_SCROLL_LIST_UP; - button = MB_RIGHTBUTTON; + button = ED_ELEMENTLIST_BUTTONS_VERT - 1; break; case KSYM_Page_Down: id = GADGET_ID_SCROLL_LIST_DOWN; - button = MB_RIGHTBUTTON; + button = ED_ELEMENTLIST_BUTTONS_VERT - 1; break; case KSYM_Home: @@ -11660,13 +11731,21 @@ void HandleLevelEditorKeyInput(Key key) ClickOnGadget(level_editor_gadget[GADGET_ID_PROPERTIES], button); else if (letter == '.') ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS], button); + else if (letter == 'U') + ClickOnGadget(level_editor_gadget[GADGET_ID_UNDO], 3); + else if (key == KSYM_KP_Subtract) + ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 1); + else if (key == KSYM_KP_0 || letter == '0') + ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 2); + else if (key == KSYM_KP_Add || letter == '+') + ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 3); else if (key == KSYM_Return || key == KSYM_space || key == setup.shortcut.toggle_pause) ClickOnGadget(level_editor_gadget[GADGET_ID_TEST], button); else for (i = 0; i < ED_NUM_CTRL_BUTTONS; i++) - if (letter && letter == control_info[i].shortcut) + if (letter && letter == controlbutton_info[i].shortcut) if (!anyTextGadgetActive()) ClickOnGadget(level_editor_gadget[i], button); } @@ -11721,17 +11800,21 @@ void PrintEditorGadgetInfoText(struct GadgetInfo *gi) if (gi->custom_id < ED_NUM_CTRL_BUTTONS) { - int key = control_info[gi->custom_id].shortcut; + int key = controlbutton_info[gi->custom_id].shortcut; if (key) { - if (gi->custom_id == GADGET_ID_SINGLE_ITEMS) /* special case 1 */ + if (gi->custom_id == GADGET_ID_SINGLE_ITEMS) sprintf(shortcut, " ('.' or '%c')", key); - else if (gi->custom_id == GADGET_ID_PICK_ELEMENT) /* special case 2 */ + else if (gi->custom_id == GADGET_ID_PICK_ELEMENT) sprintf(shortcut, " ('%c' or 'Ctrl')", key); - else if (gi->custom_id == GADGET_ID_TEST) /* special case 3 */ + else if (gi->custom_id == GADGET_ID_TEST) sprintf(shortcut, " ('Enter' or 'Shift-%c')", key); - else /* normal case */ + else if (gi->custom_id == GADGET_ID_UNDO) + sprintf(shortcut, " ('%c/Shift-U')", key); + else if (gi->custom_id == GADGET_ID_ZOOM) + sprintf(shortcut, " ('%c', '0', '+')", key); + else sprintf(shortcut, " ('%s%c')", (key >= 'A' && key <= 'Z' ? "Shift-" : ""), key);