added gadget tag to always execute the callback action when leaving gadget
[rocksndiamonds.git] / src / libgame / gadgets.h
index ccac2373c83117f7354287d424426480cc4c47ed..5f873747e4033a14aa0b0de8aa5c9e9ff75509cb 100644 (file)
@@ -1,41 +1,44 @@
-/***********************************************************
-*  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
-*----------------------------------------------------------*
-*  (c) 1995-98 Artsoft Entertainment                       *
-*              Holger Schemel                              *
-*              Oststrasse 11a                              *
-*              33604 Bielefeld                             *
-*              phone: ++49 +521 290471                     *
-*              email: aeglos@valinor.owl.de                *
-*----------------------------------------------------------*
-*  gadgets.h                                               *
-***********************************************************/
+// ============================================================================
+// Artsoft Retro-Game Library
+// ----------------------------------------------------------------------------
+// (c) 1995-2014 by Artsoft Entertainment
+//                         Holger Schemel
+//                 info@artsoft.org
+//                 http://www.artsoft.org/
+// ----------------------------------------------------------------------------
+// gadgets.h
+// ============================================================================
 
 #ifndef GADGETS_H
 #define GADGETS_H
 
-#include "libgame.h"
+#include "system.h"
 
 
-#define GADGET_FRAME_DELAY     150     /* delay between gadget actions */
+#define GADGET_FRAME_DELAY_FIRST       250     /* delay after first click */
+#define GADGET_FRAME_DELAY             100     /* delay for pressed butten */
 
 /* gadget types */
 #define GD_TYPE_NORMAL_BUTTON          (1 << 0)
-#define GD_TYPE_CHECK_BUTTON           (1 << 1)
-#define GD_TYPE_RADIO_BUTTON           (1 << 2)
-#define GD_TYPE_DRAWING_AREA           (1 << 3)
-#define GD_TYPE_TEXTINPUT_ALPHANUMERIC (1 << 4)
-#define GD_TYPE_TEXTINPUT_NUMERIC      (1 << 5)
-#define GD_TYPE_SCROLLBAR_VERTICAL     (1 << 6)
-#define GD_TYPE_SCROLLBAR_HORIZONTAL   (1 << 7)
+#define GD_TYPE_TEXT_BUTTON            (1 << 1)
+#define GD_TYPE_CHECK_BUTTON           (1 << 2)
+#define GD_TYPE_RADIO_BUTTON           (1 << 3)
+#define GD_TYPE_DRAWING_AREA           (1 << 4)
+#define GD_TYPE_TEXT_INPUT_ALPHANUMERIC        (1 << 5)
+#define GD_TYPE_TEXT_INPUT_NUMERIC     (1 << 6)
+#define GD_TYPE_TEXT_AREA              (1 << 7)
+#define GD_TYPE_SELECTBOX              (1 << 8)
+#define GD_TYPE_SCROLLBAR_VERTICAL     (1 << 9)
+#define GD_TYPE_SCROLLBAR_HORIZONTAL   (1 << 10)
 
 #define GD_TYPE_BUTTON                 (GD_TYPE_NORMAL_BUTTON | \
+                                        GD_TYPE_TEXT_BUTTON | \
                                         GD_TYPE_CHECK_BUTTON | \
                                         GD_TYPE_RADIO_BUTTON)
 #define GD_TYPE_SCROLLBAR              (GD_TYPE_SCROLLBAR_VERTICAL | \
                                         GD_TYPE_SCROLLBAR_HORIZONTAL)
-#define GD_TYPE_TEXTINPUT              (GD_TYPE_TEXTINPUT_ALPHANUMERIC | \
-                                        GD_TYPE_TEXTINPUT_NUMERIC)
+#define GD_TYPE_TEXT_INPUT             (GD_TYPE_TEXT_INPUT_ALPHANUMERIC | \
+                                        GD_TYPE_TEXT_INPUT_NUMERIC)
 
 /* gadget events */
 #define GD_EVENT_PRESSED               (1 << 0)
@@ -45,6 +48,9 @@
 #define GD_EVENT_OFF_BORDERS           (1 << 4)
 #define GD_EVENT_TEXT_RETURN           (1 << 5)
 #define GD_EVENT_TEXT_LEAVING          (1 << 6)
+#define GD_EVENT_INFO_ENTERING         (1 << 7)
+#define GD_EVENT_INFO_LEAVING          (1 << 8)
+#define GD_EVENT_PIXEL_PRECISE         (1 << 9)
 
 /* gadget button states */
 #define GD_BUTTON_UNPRESSED            0
 
 /* gadget creation tags */
 #define GDI_END                                0
-#define GDI_CUSTOM_ID                  1
-#define GDI_CUSTOM_TYPE_ID             2
-#define GDI_X                          3
-#define GDI_Y                          4
-#define GDI_WIDTH                      5
-#define GDI_HEIGHT                     6
-#define GDI_TYPE                       7
-#define GDI_STATE                      8
-#define GDI_CHECKED                    9
-#define GDI_RADIO_NR                   10
-#define GDI_NUMBER_VALUE               11
-#define GDI_NUMBER_MIN                 12
-#define GDI_NUMBER_MAX                 13
-#define GDI_TEXT_VALUE                 14
-#define GDI_TEXT_SIZE                  15
-#define GDI_TEXT_FONT                  16
-#define GDI_DESIGN_UNPRESSED           17
-#define GDI_DESIGN_PRESSED             18
-#define GDI_ALT_DESIGN_UNPRESSED       19
-#define GDI_ALT_DESIGN_PRESSED         20
-#define GDI_BORDER_SIZE                        21
-#define GDI_TEXTINPUT_DESIGN_WIDTH     22
-#define GDI_DECORATION_DESIGN          23
-#define GDI_DECORATION_POSITION                24
-#define GDI_DECORATION_SIZE            25
-#define GDI_DECORATION_SHIFTING                26
-#define GDI_EVENT_MASK                 27
-#define GDI_EVENT                      28
-#define GDI_CALLBACK_INFO              29
-#define GDI_CALLBACK_ACTION            30
-#define GDI_AREA_SIZE                  31
-#define GDI_ITEM_SIZE                  32
-#define GDI_SCROLLBAR_ITEMS_MAX                33
-#define GDI_SCROLLBAR_ITEMS_VISIBLE    34
-#define GDI_SCROLLBAR_ITEM_POSITION    35
-#define GDI_INFO_TEXT                  36
+#define GDI_IMAGE_ID                   1
+#define GDI_CUSTOM_ID                  2
+#define GDI_CUSTOM_TYPE_ID             3
+#define GDI_X                          4
+#define GDI_Y                          5
+#define GDI_WIDTH                      6
+#define GDI_HEIGHT                     7
+#define GDI_TYPE                       8
+#define GDI_STATE                      9
+#define GDI_CHECKED                    10
+#define GDI_RADIO_NR                   11
+#define GDI_NUMBER_VALUE               12
+#define GDI_NUMBER_MIN                 13
+#define GDI_NUMBER_MAX                 14
+#define GDI_TEXT_VALUE                 15
+#define GDI_TEXT_SIZE                  16
+#define GDI_TEXT_FONT                  17
+#define GDI_TEXT_FONT_ACTIVE           18
+#define GDI_TEXT_FONT_UNSELECTABLE     19
+#define GDI_SELECTBOX_OPTIONS          20
+#define GDI_SELECTBOX_INDEX            21
+#define GDI_SELECTBOX_CHAR_UNSELECTABLE        22
+#define GDI_DESIGN_UNPRESSED           23
+#define GDI_DESIGN_PRESSED             24
+#define GDI_ALT_DESIGN_UNPRESSED       25
+#define GDI_ALT_DESIGN_PRESSED         26
+#define GDI_BORDER_SIZE                        27
+#define GDI_BORDER_SIZE_SELECTBUTTON   28
+#define GDI_DESIGN_WIDTH               29
+#define GDI_DECORATION_DESIGN          30
+#define GDI_DECORATION_POSITION                31
+#define GDI_DECORATION_SIZE            32
+#define GDI_DECORATION_SHIFTING                33
+#define GDI_DECORATION_MASKED          34
+#define GDI_EVENT_MASK                 35
+#define GDI_EVENT                      36
+#define GDI_CALLBACK_INFO              37
+#define GDI_CALLBACK_ACTION            38
+#define GDI_AREA_SIZE                  39
+#define GDI_ITEM_SIZE                  40
+#define GDI_SCROLLBAR_ITEMS_MAX                41
+#define GDI_SCROLLBAR_ITEMS_VISIBLE    42
+#define GDI_SCROLLBAR_ITEM_POSITION    43
+#define GDI_WHEEL_AREA_X               44
+#define GDI_WHEEL_AREA_Y               45
+#define GDI_WHEEL_AREA_WIDTH           46
+#define GDI_WHEEL_AREA_HEIGHT          47
+#define GDI_INFO_TEXT                  48
+#define GDI_ACTIVE                     49
+#define GDI_DIRECT_DRAW                        50
+#define GDI_CALLBACK_ACTION_ALWAYS     51
+
+/* gadget deactivation hack */
+#define GDI_ACTIVE_POS(a)              ((a) < 0 ? POS_OFFSCREEN : (a))
+
 
 typedef void (*gadget_function)(void *);
 
 struct GadgetBorder
 {
-  int size;                            /* size of gadget border */
-  int width;                           /* for text input gadgets */
+  int xsize, ysize;                    /* size of gadget border */
+  int xsize_selectbutton;              /* for selectbox gadgets */
+  int width;                           /* for selectbox/text input gadgets */
 };
 
 struct GadgetDesign
 {
-  Bitmap bitmap;                       /* Bitmap with gadget surface */
+  Bitmap *bitmap;                      /* Bitmap with gadget surface */
   int x, y;                            /* position of rectangle in Bitmap */
 };
 
@@ -113,12 +139,14 @@ struct GadgetDecoration
   int x, y;                            /* position of deco on the gadget */
   int width, height;                   /* width and height of decoration */
   int xshift, yshift;                  /* deco shifting when gadget pressed */
+  boolean masked;                      /* draw decoration masked over button */
 };
 
 struct GadgetEvent
 {
-  unsigned long type;                  /* event type */
+  unsigned int type;                   /* event type */
   int button;                          /* button number for button events */
+  int mx, my;                          /* raw gadget position at event time */
   int x, y;                            /* gadget position at event time */
   boolean off_borders;                 /* mouse pointer outside gadget? */
   int item_x, item_y, item_position;   /* new item position */
@@ -130,15 +158,52 @@ struct GadgetDrawingArea
   int item_xsize, item_ysize;          /* size of each item in drawing area */
 };
 
+struct GadgetTextButton
+{
+  char value[MAX_GADGET_TEXTSIZE + 1]; /* text written on the button */
+  int size;                            /* maximal size of button text */
+};
+
 struct GadgetTextInput
 {
-  char value[MAX_GADGET_TEXTSIZE];     /* text string in input field */
+  char value[MAX_GADGET_TEXTSIZE + 1]; /* text string in input field */
+  char last_value[MAX_GADGET_TEXTSIZE + 1];/* last text string in input field */
+  int cursor_position;                 /* actual text cursor position */
   int number_value;                    /* integer value, if numeric */
   int number_min;                      /* minimal allowed numeric value */
   int number_max;                      /* maximal allowed numeric value */
   int size;                            /* maximal size of input text */
-  int cursor_position;                 /* actual cursor position */
-  int font_type;                       /* font to use for text input */
+};
+
+struct GadgetTextArea
+{
+  char value[MAX_GADGET_TEXTSIZE + 1]; /* text string in input field */
+  char last_value[MAX_GADGET_TEXTSIZE + 1];/* last text string in input field */
+  int cursor_position;                 /* actual text cursor position */
+  int cursor_x;                                /* actual x cursor position */
+  int cursor_y;                                /* actual y cursor position */
+  int cursor_x_preferred;              /* "preferred" x cursor position */
+  int size;                            /* maximal size of input text */
+  int xsize, ysize;                    /* size of text area (in chars) */
+};
+
+struct GadgetSelectbox
+{
+  struct ValueTextInfo *options;       /* pointer to text/value array */
+  int index;                           /* index of actual text string */
+  int size;                            /* maximal size of text strings */
+  char char_unselectable;              /* first char of unselectable options */
+
+  /* automatically determined values */
+  int x, y;                            /* open selectbox position */
+  int width, height;                   /* open selectbox size */
+  int num_values;                      /* number of text strings */
+  Pixel inverse_color;                 /* color for highlighting */
+
+  /* runtime values */
+  boolean open;                                /* opening state of selectbox */
+  boolean stay_open;                   /* open after button release */
+  int current_index;                   /* index of text while selecting */
 };
 
 struct GadgetScrollbar
@@ -146,7 +211,9 @@ struct GadgetScrollbar
   int items_max;                       /* number of items to access */
   int items_visible;                   /* number of visible items */
   int item_position;                   /* actual item position */
+  int size_min;                                /* minimal scrollbar size */
   int size_max;                                /* this is either width or height */
+  int size_max_cmp;                    /* needed for minimal scrollbar size */
   int size;                            /* scrollbar size on screen */
   int position;                                /* scrollbar position on screen */
   int position_max;                    /* bottom/right scrollbar position */
@@ -154,33 +221,56 @@ struct GadgetScrollbar
   int correction;                      /* scrollbar position correction */
 };
 
+struct GadgetWheelArea
+{
+  int x, y;                            /* active area for wheel (start) */
+  int width, height;                   /* active area for wheel (size) */ 
+};
+
 struct GadgetInfo
 {
+  boolean deactivated;                 /* flag to deactivate gadget */
+
   int id;                              /* internal gadget identifier */
+  int image_id;                                /* internal gadget image identifier */
   int custom_id;                       /* custom gadget identifier */
   int custom_type_id;                  /* custom gadget type identifier */
-  char info_text[MAX_INFO_TEXTSIZE];   /* short popup info text */
+  char info_text[MAX_INFO_TEXTSIZE + 1];/* short popup info text */
   int x, y;                            /* gadget position */
   int width, height;                   /* gadget size */
-  unsigned long type;                  /* type (button, text input, ...) */
-  unsigned long state;                 /* state (pressed, released, ...) */
+  unsigned int type;                   /* type (button, text input, ...) */
+  unsigned int state;                  /* state (pressed, released, ...) */
   boolean checked;                     /* check/radio button state */
   int radio_nr;                                /* number of radio button series */
-  boolean mapped;                      /* gadget is active */
+  boolean mapped;                      /* gadget is mapped on the screen */
+  boolean active;                      /* gadget is active */
+  boolean direct_draw;                 /* directly draw to frontbuffer */
+  boolean callback_action_always;      /* also callback if gadget unchanged */
+  int font;                            /* font to use when inactive */
+  int font_active;                     /* font to use when active */
+  int font_unselectable;               /* font to use when unselectable */
   struct GadgetBorder border;          /* gadget border design */
   struct GadgetDesign design[2];       /* 0: normal; 1: pressed */
   struct GadgetDesign alt_design[2];   /* alternative design */
   struct GadgetDecoration deco;                /* decoration on top of gadget */
-  unsigned long event_mask;            /* possible events for this gadget */
+  unsigned int event_mask;             /* possible events for this gadget */
   struct GadgetEvent event;            /* actual gadget event */
   gadget_function callback_info;       /* function for pop-up info text */
   gadget_function callback_action;     /* function for gadget action */
   struct GadgetDrawingArea drawing;    /* fields for drawing area gadget */
-  struct GadgetTextInput text;         /* fields for text input gadget */
+  struct GadgetTextButton textbutton;  /* fields for text button gadget */
+  struct GadgetTextInput textinput;    /* fields for text input gadget */
+  struct GadgetTextArea textarea;      /* fields for text area gadget */
+  struct GadgetSelectbox selectbox;    /* fields for selectbox gadget */
   struct GadgetScrollbar scrollbar;    /* fields for scrollbar gadget */
+  struct GadgetWheelArea wheelarea;    /* fields for scroll wheel area */
   struct GadgetInfo *next;             /* next list entry */
 };
 
+
+void InitGadgetsSoundCallback(void (*activating_function)(void),
+                             void (*selecting_function)(void));
+
 struct GadgetInfo *CreateGadget(int, ...);
 void FreeGadget(struct GadgetInfo *);
 
@@ -189,13 +279,21 @@ void RedrawGadget(struct GadgetInfo *);
 
 void MapGadget(struct GadgetInfo *);
 void UnmapGadget(struct GadgetInfo *);
-void UnmapAllGadgets();
-void RemapAllGadgets();
+void UnmapAllGadgets(void);
+void RemapAllGadgets(void);
+
+boolean anyTextInputGadgetActive(void);
+boolean anyTextAreaGadgetActive(void);
+boolean anySelectboxGadgetActive(void);
+boolean anyScrollbarGadgetActive(void);
+boolean anyTextGadgetActive(void);
 
-boolean anyTextGadgetActive();
 void ClickOnGadget(struct GadgetInfo *, int);
 
-void HandleGadgets(int, int, int);
-void HandleGadgetsKeyInput(Key);
+boolean HandleGadgets(int, int, int);
+boolean HandleGadgetsKeyInput(Key);
+
+void DumpGadgetIdentifiers(void);
+boolean DoGadgetAction(int);
 
 #endif /* GADGETS_H */