rnd-20030411-1-src
[rocksndiamonds.git] / src / editor.c
index 2b9a90889e1ae08cc8125dfc1d8a195a212f8494..e0ebdf2ae0428af83bbdec816550214a331c767b 100644 (file)
 #define ED_COUNTER_YDISTANCE           (3 * MINI_TILEY)
 #define ED_COUNTER_YPOS(n)             (ED_COUNTER_YSTART + \
                                         n * ED_COUNTER_YDISTANCE)
+#define ED_COUNTER_YPOS2(n)            (ED_COUNTER_YSTART + \
+                                        n * ED_COUNTER_YDISTANCE / 2)
 #define ED_COUNTER2_YPOS(n)            (ED_COUNTER_YSTART + \
                                         n * ED_COUNTER_YDISTANCE - 2)
+
 /* standard distances */
 #define ED_BORDER_SIZE                 3
+#define ED_BORDER2_SIZE                        5
 #define ED_GADGET_DISTANCE             2
 
 /* values for element content drawing areas */
 #define ED_AREA_ELEM_CONTENT_XPOS      ( 2 * MINI_TILEX)
 #define ED_AREA_ELEM_CONTENT_YPOS      (22 * MINI_TILEY)
 
+#define ED_AREA_ELEM_CONTENT2_XPOS     ( 2 * MINI_TILEX)
+#define ED_AREA_ELEM_CONTENT2_YPOS     (28 * MINI_TILEY)
+
 /* values for random placement background drawing area */
 #define ED_AREA_RANDOM_BACKGROUND_XPOS (29 * MINI_TILEX)
 #define ED_AREA_RANDOM_BACKGROUND_YPOS (31 * MINI_TILEY)
 #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_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_TEXTBUTTON_XPOS             ED_WIN_COUNT_XPOS
+#define ED_TEXTBUTTON_YPOS             (ED_WIN_COUNT_YPOS + \
+                                        2 * (2 + ED_WIN_COUNT_YSIZE))
+#define ED_TEXTBUTTON_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
+
 /* editor gadget identifiers */
 
 /* drawing toolbox buttons */
 #define GADGET_ID_NONE                 -1
-#define GADGET_ID_SINGLE_ITEMS         0
-#define GADGET_ID_CONNECTED_ITEMS      1
-#define GADGET_ID_LINE                 2
-#define GADGET_ID_ARC                  3
-#define GADGET_ID_RECTANGLE            4
-#define GADGET_ID_FILLED_BOX           5
-#define GADGET_ID_WRAP_UP              6
-#define GADGET_ID_TEXT                 7
-#define GADGET_ID_FLOOD_FILL           8
-#define GADGET_ID_WRAP_LEFT            9
-#define GADGET_ID_PROPERTIES           10
-#define GADGET_ID_WRAP_RIGHT           11
-#define GADGET_ID_RANDOM_PLACEMENT     12
-#define GADGET_ID_GRAB_BRUSH           13
-#define GADGET_ID_WRAP_DOWN            14
-#define GADGET_ID_PICK_ELEMENT         15
-#define GADGET_ID_UNDO                 16
-#define GADGET_ID_INFO                 17
-#define GADGET_ID_SAVE                 18
-#define GADGET_ID_CLEAR                        19
-#define GADGET_ID_TEST                 20
-#define GADGET_ID_EXIT                 21
+#define GADGET_ID_TOOLBOX_FIRST                0
+
+#define GADGET_ID_SINGLE_ITEMS         (GADGET_ID_TOOLBOX_FIRST + 0)
+#define GADGET_ID_CONNECTED_ITEMS      (GADGET_ID_TOOLBOX_FIRST + 1)
+#define GADGET_ID_LINE                 (GADGET_ID_TOOLBOX_FIRST + 2)
+#define GADGET_ID_ARC                  (GADGET_ID_TOOLBOX_FIRST + 3)
+#define GADGET_ID_RECTANGLE            (GADGET_ID_TOOLBOX_FIRST + 4)
+#define GADGET_ID_FILLED_BOX           (GADGET_ID_TOOLBOX_FIRST + 5)
+#define GADGET_ID_WRAP_UP              (GADGET_ID_TOOLBOX_FIRST + 6)
+#define GADGET_ID_TEXT                 (GADGET_ID_TOOLBOX_FIRST + 7)
+#define GADGET_ID_FLOOD_FILL           (GADGET_ID_TOOLBOX_FIRST + 8)
+#define GADGET_ID_WRAP_LEFT            (GADGET_ID_TOOLBOX_FIRST + 9)
+#define GADGET_ID_PROPERTIES           (GADGET_ID_TOOLBOX_FIRST + 10)
+#define GADGET_ID_WRAP_RIGHT           (GADGET_ID_TOOLBOX_FIRST + 11)
+#define GADGET_ID_RANDOM_PLACEMENT     (GADGET_ID_TOOLBOX_FIRST + 12)
+#define GADGET_ID_GRAB_BRUSH           (GADGET_ID_TOOLBOX_FIRST + 13)
+#define GADGET_ID_WRAP_DOWN            (GADGET_ID_TOOLBOX_FIRST + 14)
+#define GADGET_ID_PICK_ELEMENT         (GADGET_ID_TOOLBOX_FIRST + 15)
+#define GADGET_ID_UNDO                 (GADGET_ID_TOOLBOX_FIRST + 16)
+#define GADGET_ID_INFO                 (GADGET_ID_TOOLBOX_FIRST + 17)
+#define GADGET_ID_SAVE                 (GADGET_ID_TOOLBOX_FIRST + 18)
+#define GADGET_ID_CLEAR                        (GADGET_ID_TOOLBOX_FIRST + 19)
+#define GADGET_ID_TEST                 (GADGET_ID_TOOLBOX_FIRST + 20)
+#define GADGET_ID_EXIT                 (GADGET_ID_TOOLBOX_FIRST + 21)
 
 /* counter button identifiers */
-#define GADGET_ID_ELEM_SCORE_DOWN      22
-#define GADGET_ID_ELEM_SCORE_TEXT      23
-#define GADGET_ID_ELEM_SCORE_UP                24
-#define GADGET_ID_ELEM_CONTENT_DOWN    25
-#define GADGET_ID_ELEM_CONTENT_TEXT    26
-#define GADGET_ID_ELEM_CONTENT_UP      27
-#define GADGET_ID_LEVEL_XSIZE_DOWN     28
-#define GADGET_ID_LEVEL_XSIZE_TEXT     29
-#define GADGET_ID_LEVEL_XSIZE_UP       30
-#define GADGET_ID_LEVEL_YSIZE_DOWN     31
-#define GADGET_ID_LEVEL_YSIZE_TEXT     32
-#define GADGET_ID_LEVEL_YSIZE_UP       33
-#define GADGET_ID_LEVEL_RANDOM_DOWN    34
-#define GADGET_ID_LEVEL_RANDOM_TEXT    35
-#define GADGET_ID_LEVEL_RANDOM_UP      36
-#define GADGET_ID_LEVEL_COLLECT_DOWN   37
-#define GADGET_ID_LEVEL_COLLECT_TEXT   38
-#define GADGET_ID_LEVEL_COLLECT_UP     39
-#define GADGET_ID_LEVEL_TIMELIMIT_DOWN 40
-#define GADGET_ID_LEVEL_TIMELIMIT_TEXT 41
-#define GADGET_ID_LEVEL_TIMELIMIT_UP   42
-#define GADGET_ID_LEVEL_TIMESCORE_DOWN 43
-#define GADGET_ID_LEVEL_TIMESCORE_TEXT 44
-#define GADGET_ID_LEVEL_TIMESCORE_UP   45
-#define GADGET_ID_SELECT_LEVEL_DOWN    46
-#define GADGET_ID_SELECT_LEVEL_TEXT    47
-#define GADGET_ID_SELECT_LEVEL_UP      48
+#define GADGET_ID_COUNTER_FIRST                (GADGET_ID_TOOLBOX_FIRST + 22)
+
+#define GADGET_ID_ELEM_SCORE_DOWN      (GADGET_ID_COUNTER_FIRST + 0)
+#define GADGET_ID_ELEM_SCORE_TEXT      (GADGET_ID_COUNTER_FIRST + 1)
+#define GADGET_ID_ELEM_SCORE_UP                (GADGET_ID_COUNTER_FIRST + 2)
+#define GADGET_ID_ELEM_CONTENT_DOWN    (GADGET_ID_COUNTER_FIRST + 3)
+#define GADGET_ID_ELEM_CONTENT_TEXT    (GADGET_ID_COUNTER_FIRST + 4)
+#define GADGET_ID_ELEM_CONTENT_UP      (GADGET_ID_COUNTER_FIRST + 5)
+#define GADGET_ID_LEVEL_XSIZE_DOWN     (GADGET_ID_COUNTER_FIRST + 6)
+#define GADGET_ID_LEVEL_XSIZE_TEXT     (GADGET_ID_COUNTER_FIRST + 7)
+#define GADGET_ID_LEVEL_XSIZE_UP       (GADGET_ID_COUNTER_FIRST + 8)
+#define GADGET_ID_LEVEL_YSIZE_DOWN     (GADGET_ID_COUNTER_FIRST + 9)
+#define GADGET_ID_LEVEL_YSIZE_TEXT     (GADGET_ID_COUNTER_FIRST + 10)
+#define GADGET_ID_LEVEL_YSIZE_UP       (GADGET_ID_COUNTER_FIRST + 11)
+#define GADGET_ID_LEVEL_RANDOM_DOWN    (GADGET_ID_COUNTER_FIRST + 12)
+#define GADGET_ID_LEVEL_RANDOM_TEXT    (GADGET_ID_COUNTER_FIRST + 13)
+#define GADGET_ID_LEVEL_RANDOM_UP      (GADGET_ID_COUNTER_FIRST + 14)
+#define GADGET_ID_LEVEL_COLLECT_DOWN   (GADGET_ID_COUNTER_FIRST + 15)
+#define GADGET_ID_LEVEL_COLLECT_TEXT   (GADGET_ID_COUNTER_FIRST + 16)
+#define GADGET_ID_LEVEL_COLLECT_UP     (GADGET_ID_COUNTER_FIRST + 17)
+#define GADGET_ID_LEVEL_TIMELIMIT_DOWN (GADGET_ID_COUNTER_FIRST + 18)
+#define GADGET_ID_LEVEL_TIMELIMIT_TEXT (GADGET_ID_COUNTER_FIRST + 19)
+#define GADGET_ID_LEVEL_TIMELIMIT_UP   (GADGET_ID_COUNTER_FIRST + 20)
+#define GADGET_ID_LEVEL_TIMESCORE_DOWN (GADGET_ID_COUNTER_FIRST + 21)
+#define GADGET_ID_LEVEL_TIMESCORE_TEXT (GADGET_ID_COUNTER_FIRST + 22)
+#define GADGET_ID_LEVEL_TIMESCORE_UP   (GADGET_ID_COUNTER_FIRST + 23)
+#define GADGET_ID_SELECT_LEVEL_DOWN    (GADGET_ID_COUNTER_FIRST + 24)
+#define GADGET_ID_SELECT_LEVEL_TEXT    (GADGET_ID_COUNTER_FIRST + 25)
+#define GADGET_ID_SELECT_LEVEL_UP      (GADGET_ID_COUNTER_FIRST + 26)
 
 /* drawing area identifiers */
-#define GADGET_ID_DRAWING_LEVEL                49
-#define GADGET_ID_ELEM_CONTENT_0       50
-#define GADGET_ID_ELEM_CONTENT_1       51
-#define GADGET_ID_ELEM_CONTENT_2       52
-#define GADGET_ID_ELEM_CONTENT_3       53
-#define GADGET_ID_ELEM_CONTENT_4       54
-#define GADGET_ID_ELEM_CONTENT_5       55
-#define GADGET_ID_ELEM_CONTENT_6       56
-#define GADGET_ID_ELEM_CONTENT_7       57
-#define GADGET_ID_AMOEBA_CONTENT       58
-#define GADGET_ID_RANDOM_BACKGROUND    59
+#define GADGET_ID_DRAWING_AREA_FIRST   (GADGET_ID_COUNTER_FIRST + 27)
+
+#define GADGET_ID_DRAWING_LEVEL                (GADGET_ID_DRAWING_AREA_FIRST + 0)
+#define GADGET_ID_ELEM_CONTENT_0       (GADGET_ID_DRAWING_AREA_FIRST + 1)
+#define GADGET_ID_ELEM_CONTENT_1       (GADGET_ID_DRAWING_AREA_FIRST + 2)
+#define GADGET_ID_ELEM_CONTENT_2       (GADGET_ID_DRAWING_AREA_FIRST + 3)
+#define GADGET_ID_ELEM_CONTENT_3       (GADGET_ID_DRAWING_AREA_FIRST + 4)
+#define GADGET_ID_ELEM_CONTENT_4       (GADGET_ID_DRAWING_AREA_FIRST + 5)
+#define GADGET_ID_ELEM_CONTENT_5       (GADGET_ID_DRAWING_AREA_FIRST + 6)
+#define GADGET_ID_ELEM_CONTENT_6       (GADGET_ID_DRAWING_AREA_FIRST + 7)
+#define GADGET_ID_ELEM_CONTENT_7       (GADGET_ID_DRAWING_AREA_FIRST + 8)
+#define GADGET_ID_AMOEBA_CONTENT       (GADGET_ID_DRAWING_AREA_FIRST + 9)
+#define GADGET_ID_CUSTOM_CHANGED       (GADGET_ID_DRAWING_AREA_FIRST + 10)
+#define GADGET_ID_RANDOM_BACKGROUND    (GADGET_ID_DRAWING_AREA_FIRST + 11)
 
 /* text input identifiers */
-#define GADGET_ID_LEVEL_NAME           60
-#define GADGET_ID_LEVEL_AUTHOR         61
+#define GADGET_ID_TEXT_INPUT_FIRST     (GADGET_ID_DRAWING_AREA_FIRST + 12)
+
+#define GADGET_ID_LEVEL_NAME           (GADGET_ID_TEXT_INPUT_FIRST + 0)
+#define GADGET_ID_LEVEL_AUTHOR         (GADGET_ID_TEXT_INPUT_FIRST + 1)
 
 /* selectbox identifiers */
-#define GADGET_ID_SELECTBOX_TEST       62
+#define GADGET_ID_SELECTBOX_FIRST      (GADGET_ID_TEXT_INPUT_FIRST + 2)
+
+#define GADGET_ID_CUSTOM_CHANGE_CAUSE  (GADGET_ID_SELECTBOX_FIRST + 0)
+
+/* textbutton identifiers */
+#define GADGET_ID_TEXTBUTTON_FIRST     (GADGET_ID_SELECTBOX_FIRST + 1)
+
+#define GADGET_ID_EDIT_PROPERTIES      (GADGET_ID_TEXTBUTTON_FIRST + 0)
+#define GADGET_ID_SHOW_DESCRIPTION     (GADGET_ID_TEXTBUTTON_FIRST + 1)
+#define GADGET_ID_EDIT_CUSTOM_CHANGE   (GADGET_ID_TEXTBUTTON_FIRST + 2)
 
 /* gadgets for scrolling of drawing area */
-#define GADGET_ID_SCROLL_UP            63
-#define GADGET_ID_SCROLL_DOWN          64
-#define GADGET_ID_SCROLL_LEFT          65
-#define GADGET_ID_SCROLL_RIGHT         66
-#define GADGET_ID_SCROLL_HORIZONTAL    67
-#define GADGET_ID_SCROLL_VERTICAL      68
+#define GADGET_ID_SCROLLING_FIRST      (GADGET_ID_TEXTBUTTON_FIRST + 3)
+
+#define GADGET_ID_SCROLL_UP            (GADGET_ID_SCROLLING_FIRST + 0)
+#define GADGET_ID_SCROLL_DOWN          (GADGET_ID_SCROLLING_FIRST + 1)
+#define GADGET_ID_SCROLL_LEFT          (GADGET_ID_SCROLLING_FIRST + 2)
+#define GADGET_ID_SCROLL_RIGHT         (GADGET_ID_SCROLLING_FIRST + 3)
+#define GADGET_ID_SCROLL_HORIZONTAL    (GADGET_ID_SCROLLING_FIRST + 4)
+#define GADGET_ID_SCROLL_VERTICAL      (GADGET_ID_SCROLLING_FIRST + 5)
 
 /* gadgets for scrolling element list */
-#define GADGET_ID_SCROLL_LIST_UP       69
-#define GADGET_ID_SCROLL_LIST_DOWN     70
-#define GADGET_ID_SCROLL_LIST_VERTICAL 71
+#define GADGET_ID_SCROLLING_LIST_FIRST (GADGET_ID_SCROLLING_FIRST + 6)
+
+#define GADGET_ID_SCROLL_LIST_UP       (GADGET_ID_SCROLLING_LIST_FIRST + 0)
+#define GADGET_ID_SCROLL_LIST_DOWN     (GADGET_ID_SCROLLING_LIST_FIRST + 1)
+#define GADGET_ID_SCROLL_LIST_VERTICAL (GADGET_ID_SCROLLING_LIST_FIRST + 2)
 
 /* buttons for level/element properties */
-#define GADGET_ID_RANDOM_PERCENTAGE    72
-#define GADGET_ID_RANDOM_QUANTITY      73
-#define GADGET_ID_RANDOM_RESTRICTED    74
-#define GADGET_ID_DOUBLE_SPEED         75
-#define GADGET_ID_GRAVITY              76
-#define GADGET_ID_STICK_ELEMENT                77
-#define GADGET_ID_EM_SLIPPERY_GEMS     78
-#define GADGET_ID_CUSTOM_INDESTRUCTIBLE        79
-#define GADGET_ID_CUSTOM_CAN_FALL      80
-#define GADGET_ID_CUSTOM_CAN_SMASH     81
-#define GADGET_ID_CUSTOM_PUSHABLE      82
-#define GADGET_ID_CUSTOM_SLIPPERY      83
+#define GADGET_ID_CHECKBUTTON_FIRST    (GADGET_ID_SCROLLING_LIST_FIRST + 3)
+
+#define GADGET_ID_RANDOM_PERCENTAGE    (GADGET_ID_CHECKBUTTON_FIRST + 0)
+#define GADGET_ID_RANDOM_QUANTITY      (GADGET_ID_CHECKBUTTON_FIRST + 1)
+#define GADGET_ID_RANDOM_RESTRICTED    (GADGET_ID_CHECKBUTTON_FIRST + 2)
+#define GADGET_ID_DOUBLE_SPEED         (GADGET_ID_CHECKBUTTON_FIRST + 3)
+#define GADGET_ID_GRAVITY              (GADGET_ID_CHECKBUTTON_FIRST + 4)
+#define GADGET_ID_STICK_ELEMENT                (GADGET_ID_CHECKBUTTON_FIRST + 5)
+#define GADGET_ID_EM_SLIPPERY_GEMS     (GADGET_ID_CHECKBUTTON_FIRST + 6)
+#define GADGET_ID_CUSTOM_INDESTRUCTIBLE        (GADGET_ID_CHECKBUTTON_FIRST + 7)
+#define GADGET_ID_CUSTOM_CAN_FALL      (GADGET_ID_CHECKBUTTON_FIRST + 8)
+#define GADGET_ID_CUSTOM_CAN_SMASH     (GADGET_ID_CHECKBUTTON_FIRST + 9)
+#define GADGET_ID_CUSTOM_PUSHABLE      (GADGET_ID_CHECKBUTTON_FIRST + 10)
+#define GADGET_ID_CUSTOM_SLIPPERY      (GADGET_ID_CHECKBUTTON_FIRST + 11)
 
 /* gadgets for buttons in element list */
-#define GADGET_ID_ELEMENTLIST_FIRST    84
+#define GADGET_ID_ELEMENTLIST_FIRST    (GADGET_ID_CHECKBUTTON_FIRST + 12)
 #define GADGET_ID_ELEMENTLIST_LAST     (GADGET_ID_ELEMENTLIST_FIRST +  \
                                        ED_NUM_ELEMENTLIST_BUTTONS - 1)
 
 #define ED_TEXTINPUT_ID_LEVEL_LAST     ED_TEXTINPUT_ID_LEVEL_AUTHOR
 
 /* values for selectbox gadgets */
-#define ED_SELECTBOX_ID_TEST           0
+#define ED_SELECTBOX_ID_CUSTOM_CHANGE_CAUSE    0
 
-#define ED_NUM_SELECTBOX               1
+#define ED_NUM_SELECTBOX                       1
+
+/* values for textbutton gadgets */
+#define ED_TEXTBUTTON_ID_EDIT_PROPERTIES       0
+#define ED_TEXTBUTTON_ID_SHOW_DESCRIPTION      1
+#define ED_TEXTBUTTON_ID_EDIT_CUSTOM_CHANGE    2
+
+#define ED_NUM_TEXTBUTTON                      3
 
 /* values for checkbutton gadgets */
 #define ED_CHECKBUTTON_ID_DOUBLE_SPEED         0
@@ -568,35 +614,65 @@ static struct
   }
 };
 
-static char *test_values[] =
+static struct ValueTextInfo options_change_cause[] =
 {
-  "test 1",
-  "test 2",
-  "dieser test-text ist viel zu lang fuer die selectbox",
-  "letzter text",
-  NULL
+  { 1, "specified delay"       },
+  { 2, "impact (active)"       },
+  { 3, "impact (passive)"      },
+  { 4, "touched by player"     },
+  { 5, "pressed by player"     },
+  { -1,        NULL                    }
 };
-static int test_index = 0;
+static int index_change_cause = 0;
 
 static struct
 {
   int x, y;
   int gadget_id;
   int size;
-  char **values;
+  struct ValueTextInfo *options;
   int *index;
   char *text, *infotext;
 } selectbox_info[ED_NUM_SELECTBOX] =
 {
   {
     ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS(3),
-    GADGET_ID_SELECTBOX_TEST,
-    MAX_PLAYER_NAME_LEN,
-    test_values, &test_index,
+    GADGET_ID_CUSTOM_CHANGE_CAUSE,
+    17,
+    options_change_cause, &index_change_cause,
     "test:", "test-selectbox entry"
   },
 };
 
+static struct
+{
+  int x, y;
+  int gadget_id;
+  int size;
+  char *value;
+  char *infotext;
+} textbutton_info[ED_NUM_TEXTBUTTON] =
+{
+  {
+    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS(1),
+    GADGET_ID_EDIT_PROPERTIES,
+    11, "Properties",
+    "Edit element properties"
+  },
+  {
+    ED_SETTINGS_XPOS + 166,            ED_COUNTER_YPOS(1),
+    GADGET_ID_SHOW_DESCRIPTION,
+    11, "Description",
+    "Show element description"
+  },
+  {
+    ED_SETTINGS_XPOS + 332,            ED_COUNTER_YPOS(1),
+    GADGET_ID_EDIT_CUSTOM_CHANGE,
+    11, "Advanced",
+    "Advanced element features"
+  },
+};
+
 static struct
 {
   int xpos, ypos;
@@ -744,31 +820,31 @@ static struct
     "slip down from certain flat walls","use EM style slipping behaviour"
   },
   {
-    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS(4),
+    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(10),
     GADGET_ID_CUSTOM_INDESTRUCTIBLE,
     &custom_element_properties[0].indestructible,
     "indestructible",                  "element cannot be destroyed"
   },
   {
-    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS(5),
+    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(11),
     GADGET_ID_CUSTOM_CAN_FALL,
     &custom_element_properties[0].can_fall,
     "can fall",                                "element can fall down"
   },
   {
-    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS(6),
+    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(12),
     GADGET_ID_CUSTOM_CAN_SMASH,
     &custom_element_properties[0].can_smash,
     "can smash",                       "element can smash other elements"
   },
   {
-    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS(7),
+    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(13),
     GADGET_ID_CUSTOM_PUSHABLE,
     &custom_element_properties[0].pushable,
     "pushable",                                "element can be pushed"
   },
   {
-    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS(8),
+    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(14),
     GADGET_ID_CUSTOM_SLIPPERY,
     &custom_element_properties[0].slippery,
     "slippery",                                "other elements can fall down from it"
@@ -808,6 +884,7 @@ static void HandleDrawingAreas(struct GadgetInfo *);
 static void HandleCounterButtons(struct GadgetInfo *);
 static void HandleTextInputGadgets(struct GadgetInfo *);
 static void HandleSelectboxGadgets(struct GadgetInfo *);
+static void HandleTextbuttonGadgets(struct GadgetInfo *);
 static void HandleRadiobuttons(struct GadgetInfo *);
 static void HandleCheckbuttons(struct GadgetInfo *);
 static void HandleControlButtons(struct GadgetInfo *);
@@ -1363,17 +1440,22 @@ static int editor_el_chars[] =
   EL_CHAR('X'),
   EL_CHAR('Y'),
   EL_CHAR('Z'),
-  EL_CHAR('Ä'),
+  EL_CHAR('['),
 
-  EL_CHAR('Ö'),
-  EL_CHAR('Ü'),
+  EL_CHAR('\\'),
+  EL_CHAR(']'),
   EL_CHAR('^'),
   EL_CHAR('_'),
 
-  EL_CHAR(' '),
+  EL_CHAR('©'),
+  EL_CHAR('Ä'),
+  EL_CHAR('Ö'),
+  EL_CHAR('Ü'),
+
   EL_CHAR('°'),
-  EL_CHAR('´'),
-  EL_CHAR('|')
+  EL_CHAR('®'),
+  EL_CHAR(FONT_ASCII_CURSOR),
+  EL_CHAR(' ')
 };
 static int num_editor_el_chars = SIZEOF_ARRAY_INT(editor_el_chars);
 
@@ -1656,7 +1738,7 @@ static void ReinitializeElementListButtons()
 
 static int getCounterGadgetWidth()
 {
-  return (DXSIZE + getFontWidth(FONT_INPUT) - 2 * ED_GADGET_DISTANCE);
+  return (DXSIZE + getFontWidth(FONT_INPUT_1) - 2 * ED_GADGET_DISTANCE);
 }
 
 static int getMaxInfoTextLength()
@@ -2008,7 +2090,8 @@ static void CreateCounterButtons()
 
       if (j == 0)
       {
-       int font_type = FONT_INPUT;
+       int font_type = FONT_INPUT_1;
+       int font_type_active = FONT_INPUT_1_ACTIVE;
        int gd_width = ED_WIN_COUNT_XSIZE;
 
        id = counterbutton_info[i].gadget_id_text;
@@ -2017,6 +2100,7 @@ static void CreateCounterButtons()
        if (i == ED_COUNTER_ID_SELECT_LEVEL)
        {
          font_type = FONT_LEVEL_NUMBER;
+         font_type_active = FONT_LEVEL_NUMBER;
 
          xpos += 2 * ED_GADGET_DISTANCE;
          ypos -= ED_GADGET_DISTANCE;
@@ -2042,10 +2126,11 @@ static void CreateCounterButtons()
                          GDI_NUMBER_MAX, counterbutton_info[i].max_value,
                          GDI_TEXT_SIZE, 3,
                          GDI_TEXT_FONT, font_type,
+                         GDI_TEXT_FONT_ACTIVE, font_type_active,
                          GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y,
                          GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y,
-                         GDI_BORDER_SIZE, ED_BORDER_SIZE,
-                         GDI_TEXTINPUT_DESIGN_WIDTH, gd_width,
+                         GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE,
+                         GDI_DESIGN_WIDTH, gd_width,
                          GDI_EVENT_MASK, event_mask,
                          GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
                          GDI_CALLBACK_ACTION, HandleCounterButtons,
@@ -2116,7 +2201,7 @@ static void CreateDrawingAreas()
     level_editor_gadget[id] = gi;
   }
 
-  /* ... one for the amoeba content */
+  /* ... one for the amoeba content ... */
   id = GADGET_ID_AMOEBA_CONTENT;
   gi = CreateGadget(GDI_CUSTOM_ID, id,
                    GDI_X, SX + ED_AREA_ELEM_CONTENT_XPOS,
@@ -2135,6 +2220,25 @@ static void CreateDrawingAreas()
 
   level_editor_gadget[id] = gi;
 
+  /* ... one for each custom element change target element ... */
+  id = GADGET_ID_CUSTOM_CHANGED;
+  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;
+
   /* ... and one for random placement background restrictions */
 
   id = GADGET_ID_RANDOM_BACKGROUND;
@@ -2186,11 +2290,12 @@ static void CreateTextInputGadgets()
                      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,
+                     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,
-                     GDI_TEXTINPUT_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE,
+                     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,
@@ -2232,15 +2337,16 @@ static void CreateSelectboxGadgets()
                      GDI_X, SX + selectbox_info[i].x,
                      GDI_Y, SY + selectbox_info[i].y,
                      GDI_TYPE, GD_TYPE_SELECTBOX,
-                     GDI_SELECTBOX_VALUES, selectbox_info[i].values,
+                     GDI_SELECTBOX_OPTIONS, selectbox_info[i].options,
                      GDI_SELECTBOX_INDEX, selectbox_info[i].index,
                      GDI_TEXT_SIZE, selectbox_info[i].size,
-                     GDI_TEXT_FONT, FONT_INPUT,
+                     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,
-                     GDI_BORDER_SIZE_SELECTBUTTON, getFontHeight(FONT_INPUT),
-                     GDI_TEXTINPUT_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE,
+                     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,
@@ -2253,6 +2359,58 @@ static void CreateSelectboxGadgets()
   }
 }
 
+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;
+
+    event_mask = GD_EVENT_RELEASED;
+
+    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].value,
+                     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;
@@ -2310,7 +2468,7 @@ static void CreateScrollbarGadgets()
                      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,
+                     GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE,
                      GDI_EVENT_MASK, event_mask,
                      GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
                      GDI_CALLBACK_ACTION, HandleControlButtons,
@@ -2408,6 +2566,11 @@ static void CreateCheckbuttonGadgets()
 
 void CreateLevelEditorGadgets()
 {
+  int old_game_status = game_status;
+
+  /* setting 'game_status' is needed to get the right fonts for the editor */
+  game_status = LEVELED;
+
   ReinitializeElementList();
 
   CreateControlButtons();
@@ -2415,8 +2578,11 @@ void CreateLevelEditorGadgets()
   CreateDrawingAreas();
   CreateTextInputGadgets();
   CreateSelectboxGadgets();
+  CreateTextbuttonGadgets();
   CreateScrollbarGadgets();
   CreateCheckbuttonGadgets();
+
+  game_status = old_game_status;
 }
 
 void FreeLevelEditorGadgets()
@@ -2474,6 +2640,11 @@ static void MapSelectboxGadget(int id)
   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)
 {
   MapGadget(level_editor_gadget[radiobutton_info[id].gadget_id]);
@@ -3035,6 +3206,32 @@ static void DrawAmoebaContentArea()
   MapDrawingArea(GADGET_ID_AMOEBA_CONTENT);
 }
 
+static void DrawCustomChangedArea()
+{
+  int area_x = ED_AREA_ELEM_CONTENT2_XPOS / MINI_TILEX;
+  int area_y = ED_AREA_ELEM_CONTENT2_YPOS / MINI_TILEY;
+  int area_sx = SX + ED_AREA_ELEM_CONTENT2_XPOS;
+  int area_sy = SY + ED_AREA_ELEM_CONTENT2_YPOS;
+  int i = properties_element - EL_CUSTOM_START;
+
+  if (!IS_CUSTOM_ELEMENT(properties_element))
+  {
+    /* this should never happen */
+    Error(ERR_WARN, "element %d is no custom element", properties_element);
+
+    return;
+  }
+
+  ElementContent[0][0][0] = level.custom_element_successor[i];
+
+  DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY);
+  DrawMiniElement(area_x, area_y, ElementContent[0][0][0]);
+
+  DrawText(area_sx + TILEX, area_sy + 1, "Element after change", FONT_TEXT_1);
+
+  MapDrawingArea(GADGET_ID_CUSTOM_CHANGED);
+}
+
 static void DrawElementContentAreas()
 {
   int counter_id = ED_COUNTER_ID_ELEM_CONTENT;
@@ -3215,7 +3412,8 @@ static void DrawPropertiesWindow()
     }
   }
 
-  if (HAS_CONTENT(properties_element))
+  if (HAS_CONTENT(properties_element) ||
+      IS_CUSTOM_ELEMENT(properties_element))
   {
     /* draw stickybutton gadget */
     i = ED_CHECKBUTTON_ID_STICK_ELEMENT;
@@ -3227,10 +3425,15 @@ static void DrawPropertiesWindow()
                 GDI_CHECKED, *checkbutton_info[i].value, GDI_END);
     MapCheckbuttonGadget(i);
 
-    if (IS_AMOEBOID(properties_element))
-      DrawAmoebaContentArea();
-    else
-      DrawElementContentAreas();
+    if (HAS_CONTENT(properties_element))
+    {
+      if (IS_AMOEBOID(properties_element))
+       DrawAmoebaContentArea();
+      else
+       DrawElementContentAreas();
+    }
+    else if (IS_CUSTOM_ELEMENT(properties_element))
+      DrawCustomChangedArea();
   }
 
   if (IS_GEM(properties_element))
@@ -3313,17 +3516,47 @@ static void DrawPropertiesWindow()
     MapCheckbuttonGadget(i);
 
     /* draw selectbox gadget */
-    i = ED_SELECTBOX_ID_TEST;
+    i = ED_SELECTBOX_ID_CUSTOM_CHANGE_CAUSE;
     x = selectbox_info[i].x + xoffset_right2;
     y = selectbox_info[i].y + yoffset_right2;
 
-    selectbox_info[i].index = &test_index;
+    selectbox_info[i].index = &index_change_cause;
 
     DrawTextF(x, y, FONT_TEXT_1, selectbox_info[i].text);
     ModifyGadget(level_editor_gadget[selectbox_info[i].gadget_id],
                 GDI_SELECTBOX_INDEX, *selectbox_info[i].index, GDI_END);
     MapSelectboxGadget(i);
   }
+
+  /* draw textbutton gadget */
+  i = ED_TEXTBUTTON_ID_EDIT_PROPERTIES;
+  x = textbutton_info[i].x + xoffset_right2;
+  y = textbutton_info[i].y + yoffset_right2;
+
+  ModifyGadget(level_editor_gadget[textbutton_info[i].gadget_id],
+              GDI_ACTIVE, FALSE, GDI_END);
+  MapTextbuttonGadget(i);
+
+  /* draw textbutton gadget */
+  i = ED_TEXTBUTTON_ID_SHOW_DESCRIPTION;
+  x = textbutton_info[i].x + xoffset_right2;
+  y = textbutton_info[i].y + yoffset_right2;
+
+  ModifyGadget(level_editor_gadget[textbutton_info[i].gadget_id],
+              GDI_ACTIVE, TRUE, GDI_END);
+  MapTextbuttonGadget(i);
+
+  if (IS_CUSTOM_ELEMENT(properties_element))
+  {
+    /* draw textbutton gadget */
+    i = ED_TEXTBUTTON_ID_EDIT_CUSTOM_CHANGE;
+    x = textbutton_info[i].x + xoffset_right2;
+    y = textbutton_info[i].y + yoffset_right2;
+
+    ModifyGadget(level_editor_gadget[textbutton_info[i].gadget_id],
+                GDI_ACTIVE, TRUE, GDI_END);
+    MapTextbuttonGadget(i);
+  }
 }
 
 static void DrawLineElement(int sx, int sy, int element, boolean change_level)
@@ -3708,11 +3941,11 @@ static int DrawLevelText(int sx, int sy, char letter, int mode)
   if (letter >= 'a' && letter <= 'z')
     letter_element = EL_CHAR_ASCII0 + letter + (int)('A' - 'a');
   else if (letter == 'ä' || letter == 'Ä')
-    letter_element = EL_CHAR_AE;
+    letter_element = EL_CHAR_AUMLAUT;
   else if (letter == 'ö' || letter == 'Ö')
-    letter_element = EL_CHAR_OE;
+    letter_element = EL_CHAR_OUMLAUT;
   else if (letter == 'ü' || letter == 'Ü')
-    letter_element = EL_CHAR_UE;
+    letter_element = EL_CHAR_UUMLAUT;
   else if (letter == '^')
     letter_element = EL_CHAR_COPYRIGHT;
   else
@@ -4054,6 +4287,13 @@ static void HandleDrawingAreas(struct GadgetInfo *gi)
 
        if (id == GADGET_ID_AMOEBA_CONTENT)
          level.amoeba_content = new_element;
+       else if (id == GADGET_ID_CUSTOM_CHANGED &&
+                IS_CUSTOM_ELEMENT(properties_element))
+       {
+         int i = properties_element - EL_CUSTOM_START;
+
+         level.custom_element_successor[i] = new_element;
+       }
        else if (id == GADGET_ID_RANDOM_BACKGROUND)
          random_placement_background_element = new_element;
        else if (id >= GADGET_ID_ELEM_CONTENT_0 &&
@@ -4229,11 +4469,32 @@ static void HandleTextInputGadgets(struct GadgetInfo *gi)
 
 static void HandleSelectboxGadgets(struct GadgetInfo *gi)
 {
-  *selectbox_info[gi->custom_type_id].index = gi->selectbox.index;
+  int type_id = gi->custom_type_id;
 
-#if 1
-  printf("Selected text value: '%s'\n",
-        selectbox_info[gi->custom_type_id].values[gi->selectbox.index]);
+  *selectbox_info[type_id].index = gi->selectbox.index;
+
+#if 0
+  printf("Selected text value: '%s' [%d]\n",
+        selectbox_info[type_id].options[gi->selectbox.index].text,
+        selectbox_info[type_id].options[gi->selectbox.index].value);
+#endif
+}
+
+static void HandleTextbuttonGadgets(struct GadgetInfo *gi)
+{
+  int i;
+
+  for (i=0; i<ED_NUM_TEXTBUTTON; i++)
+  {
+    struct GadgetInfo *gii = level_editor_gadget[textbutton_info[i].gadget_id];
+    boolean active = (gii->custom_type_id != gi->custom_type_id);
+
+    ModifyGadget(level_editor_gadget[textbutton_info[i].gadget_id],
+                GDI_ACTIVE, active, GDI_END);
+  }
+
+#if 0
+  printf("text button %d pressed\n", gi->custom_type_id);
 #endif
 }
 
@@ -4543,8 +4804,12 @@ static void HandleControlButtons(struct GadgetInfo *gi)
 
        PickDrawingElement(button, new_element);
 
+#if 1
+       if (!stick_element_properties_window)
+#else
        if (!HAS_CONTENT(properties_element) ||
            !stick_element_properties_window)
+#endif
        {
          properties_element = new_element;
          if (edit_mode == ED_MODE_PROPERTIES)
@@ -4836,6 +5101,9 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi)
   else if (id == GADGET_ID_AMOEBA_CONTENT)
     DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
              "Amoeba content");
+  else if (id == GADGET_ID_CUSTOM_CHANGED)
+    DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
+             "Next element after change");
   else if (id == GADGET_ID_RANDOM_BACKGROUND)
     DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
              "Random placement background");