rnd-20030507-2-src
[rocksndiamonds.git] / src / editor.c
index fc45e2b25d3ec719c683ead0497e001c8ec651b2..8e326ea29e5fe32324bbf40c97b7f8aabaacc448 100644 (file)
 #define ED_AREA_ELEM_CONTENT_YPOS      (22 * MINI_TILEY)
 
 #define ED_AREA_ELEM_CONTENT2_XPOS     (20 * MINI_TILEX)
-#define ED_AREA_ELEM_CONTENT2_YPOS     ED_COUNTER_YPOS2(4)
+#define ED_AREA_ELEM_CONTENT2_YPOS     (ED_COUNTER_YPOS2(5) + \
+                                        ED_GADGET_DISTANCE)
 
 /* values for random placement background drawing area */
 #define ED_AREA_RANDOM_BACKGROUND_XPOS (29 * MINI_TILEX)
 #define GADGET_ID_ELEMENT_CONTENT_6    (GADGET_ID_DRAWING_AREA_FIRST + 7)
 #define GADGET_ID_ELEMENT_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)
+#define GADGET_ID_CUSTOM_GRAPHIC       (GADGET_ID_DRAWING_AREA_FIRST + 10)
+#define GADGET_ID_CUSTOM_CHANGED       (GADGET_ID_DRAWING_AREA_FIRST + 11)
+#define GADGET_ID_RANDOM_BACKGROUND    (GADGET_ID_DRAWING_AREA_FIRST + 12)
 
 /* text input identifiers */
-#define GADGET_ID_TEXT_INPUT_FIRST     (GADGET_ID_DRAWING_AREA_FIRST + 12)
+#define GADGET_ID_TEXT_INPUT_FIRST     (GADGET_ID_DRAWING_AREA_FIRST + 13)
 
 #define GADGET_ID_LEVEL_NAME           (GADGET_ID_TEXT_INPUT_FIRST + 0)
 #define GADGET_ID_LEVEL_AUTHOR         (GADGET_ID_TEXT_INPUT_FIRST + 1)
@@ -663,7 +665,7 @@ static struct
     "element content",                 NULL
   },
   {
-    ED_COUNT_CHANGE_DELAY_XPOS,                ED_COUNTER_YPOS2(5),
+    ED_COUNT_CHANGE_DELAY_XPOS,                ED_COUNTER_YPOS2(6),
     0,                                 999,
     GADGET_ID_CHANGE_DELAY_FIX_DOWN,   GADGET_ID_CHANGE_DELAY_FIX_UP,
     GADGET_ID_CHANGE_DELAY_FIX_TEXT,
@@ -671,7 +673,7 @@ static struct
     NULL,                              "units (fixed)"
   },
   {
-    ED_COUNT_CHANGE_DELAY_XPOS,                ED_COUNTER_YPOS2(6),
+    ED_COUNT_CHANGE_DELAY_XPOS,                ED_COUNTER_YPOS2(7),
     0,                                 999,
     GADGET_ID_CHANGE_DELAY_RND_DOWN,   GADGET_ID_CHANGE_DELAY_RND_UP,
     GADGET_ID_CHANGE_DELAY_RND_TEXT,
@@ -707,8 +709,8 @@ static struct
 
 static struct ValueTextInfo options_change_time_units[] =
 {
-  { 1, "frames"                },
   { 50,        "seconds"               },
+  { 1, "frames"                },
   { -1,        NULL                    }
 };
 static int index_change_time_units = 0;
@@ -735,12 +737,12 @@ static struct
 } selectbox_info[ED_NUM_SELECTBOX] =
 {
   {
-    ED_SELECTBOX_CHANGE_UNITS_XPOS,    ED_COUNTER_YPOS2(7),
+    ED_SELECTBOX_CHANGE_UNITS_XPOS,    ED_COUNTER_YPOS2(8),
     GADGET_ID_CHANGE_TIME_UNITS,
     0,
     options_change_time_units, &index_change_time_units,
     &custom_element_change.delay_frames,
-    "time units measured in", "time units for change"
+    "delay units given in", "time units for change"
   },
   {
     ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS(8),
@@ -916,10 +918,10 @@ static struct
     "restrict random placement to",    "set random placement restriction"
   },
   {
-    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS(4),
+    ED_SETTINGS_XPOS,                  0,      /* set at runtime */
     GADGET_ID_STICK_ELEMENT,
     &stick_element_properties_window,
-    "stick window to edit content",    "stick window to edit content"
+    "stick this screen to edit content","stick this screen to edit content"
   },
   {
     ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS(4),
@@ -994,19 +996,19 @@ static struct
     "player can walk under",           "player can walk under this element"
   },
   {
-    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(4),
+    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(5),
     GADGET_ID_CUSTOM_CHANGEABLE,
     &custom_element_properties[EP_CHANGEABLE],
     "element changes to    after:",    "element can change to other element"
   },
   {
-    ED_SETTINGS_XPOS2,                 ED_COUNTER_YPOS2(5),
+    ED_SETTINGS_XPOS2,                 ED_COUNTER_YPOS2(6),
     GADGET_ID_CHANGE_DELAY_FIXED,
     &custom_element_change_events[CE_DELAY_FIXED],
     "delay of",                                "element changes after fixed delay"
   },
   {
-    ED_SETTINGS_XPOS2,                 ED_COUNTER_YPOS2(6),
+    ED_SETTINGS_XPOS2,                 ED_COUNTER_YPOS2(7),
     GADGET_ID_CHANGE_DELAY_RANDOM,
     &custom_element_change_events[CE_DELAY_RANDOM],
     "delay of",                                "element changes after random delay"
@@ -1042,6 +1044,7 @@ static int new_element3 = EL_SAND;
 static void ModifyEditorCounter(int, int);
 static void ModifyEditorCounterLimits(int, int, int);
 static void ModifyEditorSelectbox(int, int);
+static void ModifyEditorElementList();
 static void DrawDrawingWindow();
 static void DrawLevelInfoWindow();
 static void DrawPropertiesWindow();
@@ -2394,6 +2397,25 @@ static void CreateDrawingAreas()
 
   level_editor_gadget[id] = gi;
 
+  /* ... one for each custom element optional graphic element ... */
+  id = GADGET_ID_CUSTOM_GRAPHIC;
+  gi = CreateGadget(GDI_CUSTOM_ID, id,
+                   GDI_X, SX + 2 * MINI_TILEX,
+                   GDI_Y, SY + 4 * MINI_TILEY + MINI_TILEY / 2,
+                   GDI_WIDTH, TILEX,
+                   GDI_HEIGHT, TILEY,
+                   GDI_TYPE, GD_TYPE_DRAWING_AREA,
+                   GDI_ITEM_SIZE, TILEX, TILEY,
+                   GDI_EVENT_MASK, event_mask,
+                   GDI_CALLBACK_INFO, HandleDrawingAreaInfo,
+                   GDI_CALLBACK_ACTION, HandleDrawingAreas,
+                   GDI_END);
+
+  if (gi == NULL)
+    Error(ERR_EXIT, "cannot create gadget");
+
+  level_editor_gadget[id] = gi;
+
   /* ... one for each custom element change target element ... */
   id = GADGET_ID_CUSTOM_CHANGED;
   gi = CreateGadget(GDI_CUSTOM_ID, id,
@@ -3185,9 +3207,30 @@ static void ModifyEditorSelectbox(int selectbox_id, int new_value)
     if (selectbox_info[selectbox_id].options[i].value == new_value)
       new_index_value = i;
 
+  *selectbox_info[selectbox_id].value =
+    selectbox_info[selectbox_id].options[new_index_value].value;
+
   ModifyGadget(gi, GDI_SELECTBOX_INDEX, new_index_value, GDI_END);
 }
 
+static void ModifyEditorElementList()
+{
+  int i;
+
+  for (i=0; i<ED_NUM_ELEMENTLIST_BUTTONS; i++)
+  {
+    int gadget_id = GADGET_ID_ELEMENTLIST_FIRST + i;
+    struct GadgetInfo *gi = level_editor_gadget[gadget_id];
+    struct GadgetDesign *gd = &gi->deco.design;
+    int element = editor_elements[element_shift + i];
+
+    UnmapGadget(gi);
+    getMiniGraphicSource(el2edimg(element), &gd->bitmap, &gd->x, &gd->y);
+    ModifyGadget(gi, GDI_INFO_TEXT, getElementInfoText(element), GDI_END);
+    MapGadget(gi);
+  }
+}
+
 static void PickDrawingElement(int button, int element)
 {
   if (button < 1 || button > 3)
@@ -3380,6 +3423,7 @@ static void DrawAmoebaContentArea()
 
 static void DrawCustomChangedArea()
 {
+  struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_CHANGED];
 #if 0
   int xoffset_right2 = ED_CHECKBUTTON_XSIZE + 2 * ED_GADGET_DISTANCE;
   int yoffset_right2 = ED_BORDER_SIZE;
@@ -3408,7 +3452,14 @@ static void DrawCustomChangedArea()
   ElementContent[0][0][0] = custom_element_change.successor;
 
   DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY);
+#if 1
+  DrawMiniGraphicExt(drawto,
+                    gi->x,
+                    gi->y,
+                    el2edimg(ElementContent[0][0][0]));
+#else
   DrawMiniElement(area_x, area_y, ElementContent[0][0][0]);
+#endif
 
 #if 0
   DrawText(area_sx + TILEX, area_sy + 1, "Element after change", FONT_TEXT_1);
@@ -3609,12 +3660,14 @@ static void DrawPropertiesConfig()
   {
     /* draw stickybutton gadget */
     i = ED_CHECKBUTTON_ID_STICK_ELEMENT;
+    checkbutton_info[i].y = ED_COUNTER_YPOS(4);
     x = checkbutton_info[i].x + xoffset_right2;
     y = checkbutton_info[i].y + yoffset_right2;
 
     DrawTextF(x, y, FONT_TEXT_1, checkbutton_info[i].text);
     ModifyGadget(level_editor_gadget[checkbutton_info[i].gadget_id],
-                GDI_CHECKED, *checkbutton_info[i].value, GDI_END);
+                GDI_CHECKED, *checkbutton_info[i].value,
+                GDI_Y, SY + checkbutton_info[i].y, GDI_END);
     MapCheckbuttonGadget(i);
 
     if (HAS_CONTENT(properties_element))
@@ -3641,8 +3694,6 @@ static void DrawPropertiesConfig()
 
   if (IS_CUSTOM_ELEMENT(properties_element))
   {
-    CopyCustomElementPropertiesToEditor(properties_element);
-
     /* draw checkbutton gadgets */
     for (i =  ED_CHECKBUTTON_ID_CUSTOM_FIRST;
         i <= ED_CHECKBUTTON_ID_CUSTOM_LAST; i++)
@@ -3980,16 +4031,16 @@ static void DrawPropertiesAdvanced()
   int yoffset_right2 = ED_BORDER_SIZE;
   int i, x, y;
 
-  CopyCustomElementPropertiesToEditor(properties_element);
-
   /* draw stickybutton gadget */
   i = ED_CHECKBUTTON_ID_STICK_ELEMENT;
+  checkbutton_info[i].y = ED_COUNTER_YPOS2(4);
   x = checkbutton_info[i].x + xoffset_right2;
   y = checkbutton_info[i].y + yoffset_right2;
 
   DrawTextF(x, y, FONT_TEXT_1, checkbutton_info[i].text);
   ModifyGadget(level_editor_gadget[checkbutton_info[i].gadget_id],
-              GDI_CHECKED, *checkbutton_info[i].value, GDI_END);
+              GDI_CHECKED, *checkbutton_info[i].value,
+              GDI_Y, SY + checkbutton_info[i].y, GDI_END);
   MapCheckbuttonGadget(i);
 
   /* draw counter gadgets */
@@ -4022,6 +4073,9 @@ static void DrawPropertiesAdvanced()
     MapCheckbuttonGadget(i);
   }
 
+  /* map gadget for optional graphic element */
+  MapDrawingArea(GADGET_ID_CUSTOM_GRAPHIC);
+
   DrawCustomChangedArea();
 
   /* draw selectbox gadgets */
@@ -4057,6 +4111,9 @@ static void DrawPropertiesWindow()
       !checkPropertiesConfig())
     edit_mode_properties = ED_MODE_PROPERTIES_INFO;
 
+  if (IS_CUSTOM_ELEMENT(properties_element))
+    CopyCustomElementPropertiesToEditor(properties_element);
+
   UnmapLevelEditorWindowGadgets();
 
   SetMainBackgroundImage(IMG_BACKGROUND_EDITOR);
@@ -4710,6 +4767,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi)
   int sx = gi->event.x, sy = gi->event.y;
   int min_sx = 0, min_sy = 0;
   int max_sx = gi->drawing.area_xsize - 1, max_sy = gi->drawing.area_ysize - 1;
+  int item_xsize = gi->drawing.item_xsize, item_ysize = gi->drawing.item_ysize;
   int lx = 0, ly = 0;
   int min_lx = 0, min_ly = 0;
   int max_lx = lev_fieldx - 1, max_ly = lev_fieldy - 1;
@@ -4805,17 +4863,34 @@ static void HandleDrawingAreas(struct GadgetInfo *gi)
       }
       else
       {
-       DrawMiniGraphicExt(drawto,
-                          gi->x + sx * MINI_TILEX,
-                          gi->y + sy * MINI_TILEY,
-                          el2edimg(new_element));
-       DrawMiniGraphicExt(window,
-                          gi->x + sx * MINI_TILEX,
-                          gi->y + sy * MINI_TILEY,
-                          el2edimg(new_element));
+       if (item_xsize == MINI_TILEX && item_ysize == MINI_TILEY)
+         DrawMiniGraphicExt(drawto,
+                            gi->x + sx * MINI_TILEX,
+                            gi->y + sy * MINI_TILEY,
+                            el2edimg(new_element));
+       else
+         DrawGraphicExt(drawto,
+                        gi->x + sx * TILEX,
+                        gi->y + sy * TILEY,
+                        el2img(new_element), 0);
 
        if (id == GADGET_ID_AMOEBA_CONTENT)
          level.amoeba_content = new_element;
+       else if (id == GADGET_ID_CUSTOM_GRAPHIC &&
+                IS_CUSTOM_ELEMENT(properties_element))
+       {
+         int i = properties_element - EL_CUSTOM_START;
+
+         if (IS_CUSTOM_ELEMENT(new_element))
+           new_element = CUSTOM_ELEMENT_INFO(new_element).change.gfx_element;
+
+         custom_element_change.gfx_element = new_element;
+         level.custom_element[i].change = custom_element_change;
+
+         ModifyEditorElementList();
+
+         FrameCounter = 0;     /* restart animation frame counter */
+       }
        else if (id == GADGET_ID_CUSTOM_CHANGED &&
                 IS_CUSTOM_ELEMENT(properties_element))
        {
@@ -5056,7 +5131,7 @@ static void HandleControlButtons(struct GadgetInfo *gi)
   int button = gi->event.button;
   int step = BUTTON_STEPSIZE(button);
   int new_element = BUTTON_ELEMENT(button);
-  int i, x, y;
+  int x, y;
 
   if (edit_mode == ED_MODE_DRAWING && drawing_function == GADGET_ID_TEXT)
     DrawLevelText(0, 0, 0, TEXT_END);
@@ -5176,18 +5251,8 @@ static void HandleControlButtons(struct GadgetInfo *gi)
                     element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END);
       }
 
-      for (i=0; i<ED_NUM_ELEMENTLIST_BUTTONS; i++)
-      {
-       int gadget_id = GADGET_ID_ELEMENTLIST_FIRST + i;
-       struct GadgetInfo *gi = level_editor_gadget[gadget_id];
-       struct GadgetDesign *gd = &gi->deco.design;
-       int element = editor_elements[element_shift + i];
-
-       UnmapGadget(gi);
-       getMiniGraphicSource(el2edimg(element), &gd->bitmap, &gd->x, &gd->y);
-       ModifyGadget(gi, GDI_INFO_TEXT, getElementInfoText(element), GDI_END);
-       MapGadget(gi);
-      }
+      ModifyEditorElementList();
+
       break;
 
     case GADGET_ID_WRAP_LEFT:
@@ -5637,6 +5702,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_GRAPHIC)
+    DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
+             "Optional custom graphic element");
   else if (id == GADGET_ID_CUSTOM_CHANGED)
     DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
              "New element after change");