rnd-19990104-2
authorHolger Schemel <info@artsoft.org>
Mon, 4 Jan 1999 17:51:46 +0000 (18:51 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:32:48 +0000 (10:32 +0200)
src/buttons.c
src/buttons.h
src/editor.c
src/events.c
src/main.h
src/misc.c
src/misc.h

index 2d6c173eb5a52145194fb3828f537d14d257113c..77c374376bae17aa3ed4224996fc564ef1b60eca 100644 (file)
@@ -1586,7 +1586,35 @@ struct GadgetInfo *CreateGadget(int first_tag, ...)
        break;
 
       case GDI_TEXT_VALUE:
-       strcpy(new_gadget->text_value, va_arg(ap, char *));
+       {
+         int max_textsize = MAX_GADGET_TEXTSIZE;
+
+         if (new_gadget->text_size)
+           max_textsize = MIN(new_gadget->text_size, MAX_GADGET_TEXTSIZE - 1);
+
+         strncpy(new_gadget->text_value, va_arg(ap, char *), max_textsize);
+         new_gadget->text_value[max_textsize] = '\0';
+       }
+       break;
+
+      case GDI_TEXT_SIZE:
+       {
+         int tag_value = va_arg(ap, int);
+         int max_textsize = MIN(tag_value, MAX_GADGET_TEXTSIZE - 1);
+
+         new_gadget->text_size = max_textsize;
+         new_gadget->text_value[max_textsize] = '\0';
+
+         if (new_gadget->width == 0 && new_gadget->height == 0)
+         {
+           new_gadget->width = (new_gadget->text_size + 1) * FONT2_XSIZE + 6;
+           new_gadget->height = ED_WIN_COUNT_YSIZE;
+         }
+       }
+       break;
+
+      case GDI_TEXT_BORDER:
+       new_gadget->text_border = va_arg(ap, int);
        break;
 
       case GDI_DESIGN_UNPRESSED:
@@ -1735,12 +1763,52 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct)
                             &gi->alt_design[state] :
                             &gi->design[state]);
 
-  if (gi->type != GD_TYPE_NORMAL_BUTTON &&
-      gi->type != GD_TYPE_RADIO_BUTTON)
-    return;
+  switch (gi->type)
+  {
+    case GD_TYPE_NORMAL_BUTTON:
+    case GD_TYPE_RADIO_BUTTON:
+      XCopyArea(display, gd->pixmap, drawto, gc,
+               gd->x, gd->y, gi->width, gi->height, gi->x, gi->y);
+      break;
 
-  XCopyArea(display, gd->pixmap, drawto, gc,
-           gd->x, gd->y, gi->width, gi->height, gi->x, gi->y);
+    case GD_TYPE_TEXTINPUT:
+      {
+       int i;
+
+       /* left part of gadget */
+       XCopyArea(display, gd->pixmap, drawto, gc,
+                 gd->x, gd->y,
+                 gi->text_border, gi->height,
+                 gi->x, gi->y);
+
+       /* middle part of gadget */
+       for (i=0; i<=gi->text_size; i++)
+         XCopyArea(display, gd->pixmap, drawto, gc,
+                   gd->x + gi->text_border, gd->y,
+                   FONT2_XSIZE, gi->height,
+                   gi->x + gi->text_border + i * FONT2_XSIZE, gi->y);
+
+       /* right part of gadget */
+       XCopyArea(display, gd->pixmap, drawto, gc,
+                 gd->x + ED_WIN_COUNT_XSIZE - gi->text_border, gd->y,
+                 gi->text_border, gi->height,
+                 gi->x + gi->width - gi->text_border, gi->y);
+
+       /* gadget text value */
+       DrawText(gi->x + gi->text_border, gi->y + gi->text_border,
+                gi->text_value, FS_SMALL, (pressed ? FC_GREEN : FC_YELLOW));
+
+       /* draw cursor, if active */
+       DrawText(gi->x + gi->text_border + strlen(gi->text_value)*FONT2_XSIZE,
+                gi->y + gi->text_border,
+                (pressed ? "<" : " "),
+                FS_SMALL, FC_RED);
+      }
+      break;
+
+    default:
+      return;
+  }
 
   if (direct)
     XCopyArea(display, drawto, window, gc,
@@ -1780,9 +1848,10 @@ void UnmapGadget(struct GadgetInfo *gi)
   gi->mapped = FALSE;
 }
 
+static struct GadgetInfo *last_gi = NULL;
+
 void HandleGadgets(int mx, int my, int button)
 {
-  static struct GadgetInfo *last_gi = NULL;
   static unsigned long pressed_delay = 0;
 
   struct GadgetInfo *new_gi, *gi;
@@ -1793,11 +1862,25 @@ void HandleGadgets(int mx, int my, int button)
   boolean gadget_released;
   boolean gadget_released_off_borders;
 
-  if (gadget_list_first_entry == NULL)
+  if (gadget_list_first_entry == NULL) /* no gadgets defined */
     return;
 
   new_gi = getGadgetInfoFromMousePosition(mx, my);
 
+  /* if mouse button pressed outside text input gadget, deactivate it */
+  if (last_gi && last_gi->type == GD_TYPE_TEXTINPUT &&
+      button != 0 && new_gi != last_gi && !motion_status)
+  {
+    struct GadgetInfo *gi = last_gi;
+
+    DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
+
+    if (gi->event_mask & GD_EVENT_TEXT_LEAVING)
+      gi->callback(gi);
+
+    last_gi = NULL;
+  }
+
   gadget_pressed =
     (button != 0 && last_gi == NULL && new_gi != NULL && !motion_status);
   gadget_pressed_repeated =
@@ -1811,12 +1894,15 @@ void HandleGadgets(int mx, int my, int button)
   gadget_released_off_borders =
     (button == 0 && last_gi != NULL && new_gi != last_gi);
 
+  /* if new gadget pressed, store this gadget  */
   if (gadget_pressed)
     last_gi = new_gi;
 
+  /* 'gi' is actually handled gadget */
   gi = last_gi;
 
-  if (button == 0)
+  /* if mouse button released, no gadget needs to be handled anymore */
+  if (button == 0 && last_gi && last_gi->type != GD_TYPE_TEXTINPUT)
     last_gi = NULL;
 
   if (gi)
@@ -1890,7 +1976,8 @@ void HandleGadgets(int mx, int my, int button)
 
   if (gadget_moving_off_borders)
   {
-    if (gi->state == GD_BUTTON_PRESSED)
+    if (gi->state == GD_BUTTON_PRESSED &&
+       gi->type != GD_TYPE_TEXTINPUT)
       DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
 
     gi->state = GD_BUTTON_UNPRESSED;
@@ -1904,7 +1991,8 @@ void HandleGadgets(int mx, int my, int button)
 
   if (gadget_released)
   {
-    DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
+    if (gi->type != GD_TYPE_TEXTINPUT)
+      DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
 
     gi->state = GD_BUTTON_UNPRESSED;
     gi->event.type = GD_EVENT_RELEASED;
@@ -1922,3 +2010,37 @@ void HandleGadgets(int mx, int my, int button)
       gi->callback(gi);
   }
 }
+
+void HandleGadgetsKeyInput(KeySym key)
+{
+  struct GadgetInfo *gi = last_gi;
+  int text_length;
+  char letter;
+
+  if (gi == NULL || gi->type != GD_TYPE_TEXTINPUT)
+    return;
+
+  text_length = strlen(gi->text_value);
+  letter = getCharFromKeySym(key);
+
+  if (letter && text_length < gi->text_size)
+  {
+    gi->text_value[text_length] = letter;
+    gi->text_value[text_length + 1] = '\0';
+    DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+  }
+  else if ((key == XK_Delete || key == XK_BackSpace) && text_length > 0)
+  {
+    gi->text_value[text_length - 1] = '\0';
+    DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+  }
+  else if (key == XK_Return)
+  {
+    DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
+
+    if (gi->event_mask & GD_EVENT_TEXT_RETURN)
+      gi->callback(gi);
+
+    last_gi = NULL;
+  }
+}
index e3ba29be841272d50ad5f294b9dd8d69c508ef73..5dfeb377cc4a73d421e0b5a1666c8f45f85f6075 100644 (file)
@@ -288,6 +288,8 @@ int CheckCountButtons(int, int, int);
 #define GD_EVENT_MOVING                        (1<<2)
 #define GD_EVENT_REPEATED              (1<<3)
 #define GD_EVENT_OFF_BORDERS           (1<<4)
+#define GD_EVENT_TEXT_RETURN           (1<<5)
+#define GD_EVENT_TEXT_LEAVING          (1<<6)
 
 /* gadget button states */
 #define GD_BUTTON_UNPRESSED            0
@@ -311,15 +313,17 @@ int CheckCountButtons(int, int, int);
 #define GDI_NUMBER_MIN                 11
 #define GDI_NUMBER_MAX                 12
 #define GDI_TEXT_VALUE                 13
-#define GDI_DESIGN_UNPRESSED           14
-#define GDI_DESIGN_PRESSED             15
-#define GDI_ALT_DESIGN_UNPRESSED       16
-#define GDI_ALT_DESIGN_PRESSED         17
-#define GDI_EVENT_MASK                 18
-#define GDI_EVENT                      19
-#define GDI_CALLBACK                   20
-#define GDI_AREA_SIZE                  21
-#define GDI_ITEM_SIZE                  22
+#define GDI_TEXT_SIZE                  14
+#define GDI_TEXT_BORDER                        15
+#define GDI_DESIGN_UNPRESSED           16
+#define GDI_DESIGN_PRESSED             17
+#define GDI_ALT_DESIGN_UNPRESSED       18
+#define GDI_ALT_DESIGN_PRESSED         19
+#define GDI_EVENT_MASK                 20
+#define GDI_EVENT                      21
+#define GDI_CALLBACK                   22
+#define GDI_AREA_SIZE                  23
+#define GDI_ITEM_SIZE                  24
 
 typedef void (*gadget_callback_function)(void *);
 
@@ -356,6 +360,8 @@ struct GadgetInfo
   boolean mapped;                      /* gadget is active */
   long number_value;
   char text_value[MAX_GADGET_TEXTSIZE];
+  int text_size;                       /* maximal size of input text */
+  int text_border;                     /* border size of text input gadget */
   struct GadgetDesign design[2];       /* 0: normal; 1: pressed */
   struct GadgetDesign alt_design[2];   /* alternative design */
   unsigned long event_mask;            /* possible events for this gadget */
@@ -374,5 +380,6 @@ void MapGadget(struct GadgetInfo *);
 void UnmapGadget(struct GadgetInfo *);
 
 void HandleGadgets(int, int, int);
+void HandleGadgetsKeyInput(KeySym);
 
 #endif
index 1e4d4f5f33df68ab649e41bb75a9611c7b802d61..d92e27781d48dbf20e0e95667e1a2917854e249c 100644 (file)
 #define ED_CTRL_ID_ELEMCONT_7          34
 #define ED_CTRL_ID_AMOEBA_CONTENT      35
 
-#define ED_NUM_GADGETS                 36
+/* text input identifiers */
+#define ED_CTRL_ID_LEVEL_NAME          36
+
+#define ED_NUM_GADGETS                 37
 
 /* values for counter gadgets */
 #define ED_COUNTER_SCORE               0
@@ -145,9 +148,10 @@ static struct
 static void DrawDrawingWindow();
 static void DrawPropertiesWindow();
 static void CopyLevelToUndoBuffer();
-static void HandleDrawingAreas(struct GadgetInfo *);
-static void HandleCounterButtons(struct GadgetInfo *);
 static void HandleControlButtons(struct GadgetInfo *);
+static void HandleCounterButtons(struct GadgetInfo *);
+static void HandleDrawingAreas(struct GadgetInfo *);
+static void HandleTextInputGadgets(struct GadgetInfo *);
 
 static struct GadgetInfo *level_editor_gadget[ED_NUM_GADGETS];
 static boolean level_editor_gadgets_created = FALSE;
@@ -796,6 +800,39 @@ static void CreateDrawingAreas()
   level_editor_gadget[id] = gi;
 }
 
+static void CreateTextInputGadgets()
+{
+  Pixmap gd_pixmap = pix[PIX_DOOR];
+  int gd_x, gd_y;
+  struct GadgetInfo *gi;
+  unsigned long event_mask;
+  int id;
+
+  gd_x = DOOR_GFX_PAGEX4 + ED_WIN_COUNT_XPOS;
+  gd_y = DOOR_GFX_PAGEY1 + ED_WIN_COUNT_YPOS;
+  event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING;
+
+  /* text input gadget for the level name */
+  id = ED_CTRL_ID_LEVEL_NAME;
+  gi = CreateGadget(GDI_CUSTOM_ID, id,
+                   GDI_X, SX + ED_COUNT_ELEMCONT_XPOS,
+                   GDI_Y, SY + ED_AREA_ELEMCONT_YPOS + 3 * TILEX,
+                   GDI_TYPE, GD_TYPE_TEXTINPUT,
+                   GDI_TEXT_VALUE, level.name,
+                   GDI_TEXT_SIZE, 30,
+                   GDI_TEXT_BORDER, 3,
+                   GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x, gd_y,
+                   GDI_DESIGN_PRESSED, gd_pixmap, gd_x, gd_y,
+                   GDI_EVENT_MASK, event_mask,
+                   GDI_CALLBACK, HandleTextInputGadgets,
+                   GDI_END);
+
+  if (gi == NULL)
+    Error(ERR_EXIT, "cannot create gadget");
+
+  level_editor_gadget[id] = gi;
+}
+
 static void CreateLevelEditorGadgets()
 {
   if (level_editor_gadgets_created)
@@ -804,6 +841,7 @@ static void CreateLevelEditorGadgets()
   CreateControlButtons();
   CreateCounterButtons();
   CreateDrawingAreas();
+  CreateTextInputGadgets();
 
   level_editor_gadgets_created = TRUE;
 }
@@ -829,6 +867,11 @@ static void MapDrawingArea(int id)
   MapGadget(level_editor_gadget[id]);
 }
 
+static void MapTextInputGadget(int id)
+{
+  MapGadget(level_editor_gadget[id]);
+}
+
 static void MapMainDrawingArea()
 {
   MapDrawingArea(ED_CTRL_ID_DRAWING_LEVEL);
@@ -2086,6 +2129,9 @@ static void DrawPropertiesWindow()
     else
       DrawElementContentAreas();
   }
+
+  /* TEST ONLY: level name text input gadget */
+  MapTextInputGadget(ED_CTRL_ID_LEVEL_NAME);
 }
 
 static void swap_numbers(int *i1, int *i2)
@@ -2478,7 +2524,11 @@ static void HandleDrawingAreas(struct GadgetInfo *gi)
   int new_element;
   int button = gi->event.button;
   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 lx, ly;
+  int min_lx = 0, min_ly = 0;
+  int max_lx = lev_fieldx - 1, max_ly = lev_fieldy - 1;
   int x, y;
 
   /*
@@ -2489,23 +2539,24 @@ static void HandleDrawingAreas(struct GadgetInfo *gi)
   button_press_event = (gi->event.type == GD_EVENT_PRESSED);
   button_release_event = (gi->event.type == GD_EVENT_RELEASED);
 
+  /* make sure to stay inside drawing area boundaries */
+  sx = (sx < min_sx ? min_sx : sx > max_sx ? max_sx : sx);
+  sy = (sy < min_sy ? min_sy : sy > max_sy ? max_sy : sy);
+
   if (draw_level)
   {
-    sx = (sx < 0 ? 0 : sx > 2*SCR_FIELDX - 1 ? 2*SCR_FIELDX - 1 : sx);
-    sy = (sy < 0 ? 0 : sy > 2*SCR_FIELDY - 1 ? 2*SCR_FIELDY - 1 : sy);
+    /* get positions inside level field */
     lx = sx + level_xpos;
     ly = sy + level_ypos;
 
-    lx = (lx < 0 ? 0 : lx > lev_fieldx - 1 ? lev_fieldx - 1 : lx);
-    ly = (ly < 0 ? 0 : ly > lev_fieldy - 1 ? lev_fieldy - 1 : ly);
+    /* make sure to stay inside level field boundaries */
+    lx = (lx < min_lx ? min_lx : lx > max_lx ? max_lx : lx);
+    ly = (ly < min_ly ? min_ly : ly > max_ly ? max_ly : ly);
+
+    /* correct drawing area positions accordingly */
     sx = lx - level_xpos;
     sy = ly - level_ypos;
   }
-  else
-  {
-    sx = (sx < 0 ? 0 : sx > 2 ? 2 : sx);
-    sy = (sy < 0 ? 0 : sy > 2 ? 2 : sy);
-  }
 
   if (button_press_event)
     started_inside_drawing_area = inside_drawing_area;
@@ -2971,19 +3022,7 @@ void HandleLevelEditorKeyInput(KeySym key)
 {
   if (edit_mode == ED_MODE_DRAWING && drawing_function == ED_CTRL_ID_TEXT)
   {
-    char *keyname = getKeyNameFromKeySym(key);
-    char letter = 0;
-
-    if (strlen(keyname) == 1)
-      letter = keyname[0];
-    else if (strcmp(keyname, "space") == 0)
-      letter = ' ';
-    else if (strcmp(keyname, "less") == 0)
-      letter = '<';
-    else if (strcmp(keyname, "equal") == 0)
-      letter = '=';
-    else if (strcmp(keyname, "greater") == 0)
-      letter = '>';
+    char letter = getCharFromKeySym(key);
 
     /* map lower case letters to upper case */
     if (letter >= 'a' && letter <= 'z')
@@ -3003,3 +3042,19 @@ void HandleLevelEditorKeyInput(KeySym key)
       DrawLevelText(0, 0, 0, TEXT_NEWLINE);
   }
 }
+
+
+static void HandleTextInputGadgets(struct GadgetInfo *gi)
+{
+  int id = gi->custom_id;
+
+  switch (id)
+  {
+    case ED_CTRL_ID_LEVEL_NAME:
+      strcpy(level.name, gi->text_value);
+      break;
+
+    default:
+      break;
+  }
+}
index f4ab83e3a65b8cf4aa375408ca38e0174428ad42..e3ebe5f98d9ab752c991b61ec4f3c5caf910b1e0 100644 (file)
@@ -461,6 +461,8 @@ void HandleKey(KeySym key, int key_status)
 
 
 
+  HandleGadgetsKeyInput(key);
+
   switch(game_status)
   {
     case TYPENAME:
index 26251e847bdb997d14cdd29d87bff2c0945593fe..8b20fb7afdc1c9c3a1197e07fd89e148afd05a00 100644 (file)
@@ -523,7 +523,7 @@ extern int          num_bg_loops;
 #define MINI_MORE_STARTX       0
 #define MINI_MORE_STARTY       160
 #define MICRO_MORE_STARTX      0
-#define MICRO_MORE_STARTY      208
+#define MICRO_MORE_STARTY      240
 #define MORE_PER_LINE          16
 #define MINI_MORE_PER_LINE     16
 #define MICRO_MORE_PER_LINE    16
index 7f6bc4bc7ef705f72ebda309f7c825053990a360..3b3f6a04212dcbde4775d8a54874d9bdf8a4c844 100644 (file)
@@ -819,6 +819,25 @@ KeySym getKeySymFromX11KeyName(char *x11name)
   return keysym;
 }
 
+char getCharFromKeySym(KeySym keysym)
+{
+  char *keyname = getKeyNameFromKeySym(keysym);
+  char letter = 0;
+
+  if (strlen(keyname) == 1)
+    letter = keyname[0];
+  else if (strcmp(keyname, "space") == 0)
+    letter = ' ';
+  else if (strcmp(keyname, "less") == 0)
+    letter = '<';
+  else if (strcmp(keyname, "equal") == 0)
+    letter = '=';
+  else if (strcmp(keyname, "greater") == 0)
+    letter = '>';
+
+  return letter;
+}
+
 #define TRANSLATE_JOYSYMBOL_TO_JOYNAME 0
 #define TRANSLATE_JOYNAME_TO_JOYSYMBOL 1
 
index ae8ae79e9ad85e266d8778c503a43e25d735d5d7..c1c18bb5b4821fdecc54532985aba766aaaf21ac 100644 (file)
@@ -58,6 +58,7 @@ void *checked_calloc(unsigned long);
 char *getKeyNameFromKeySym(KeySym);
 char *getX11KeyNameFromKeySym(KeySym);
 KeySym getKeySymFromX11KeyName(char *);
+char getCharFromKeySym(KeySym);
 char *getJoyNameFromJoySymbol(int);
 int getJoySymbolFromJoyName(char *);
 int getJoystickNrFromDeviceName(char *);