1 // by Kris Morness (originally created by Bret Rowden)
2 
3 #ifndef BUTTON_SYSTEM_H
4 #define BUTTON_SYSTEM_H
5 
6 #include "MouseSystem.h"
7 
8 #include <string_theory/string>
9 
10 
11 #define MAX_BUTTONS     400
12 #define MAX_BUTTON_PICS 256
13 
14 
15 // Some GUI_BUTTON system defines
16 #define BUTTON_NO_IMAGE    -1
17 
18 //effects how the button is rendered.
19 #define BUTTON_TYPES (BUTTON_QUICK | BUTTON_GENERIC | BUTTON_HOT_SPOT | BUTTON_CHECKBOX)
20 
21 //button flags
22 #define BUTTON_TOGGLE           0x00000000
23 #define BUTTON_QUICK            0x00000000
24 #define BUTTON_ENABLED          0x00000001
25 #define BUTTON_CLICKED_ON       0x00000002
26 #define BUTTON_GENERIC          0x00000020
27 #define BUTTON_HOT_SPOT         0x00000040
28 #define BUTTON_SELFDELETE_IMAGE 0x00000080
29 #define BUTTON_DELETION_PENDING 0x00000100
30 #define BUTTON_DIRTY            0x00000400
31 #define BUTTON_CHECKBOX         0x00001000
32 #define BUTTON_NEWTOGGLE        0x00002000
33 #define BUTTON_FORCE_UNDIRTY    0x00004000 // no matter what happens this buttons does NOT get marked dirty
34 #define BUTTON_NO_DUPLICATE     0x80000000 // Exclude button from duplicate check
35 
36 
37 extern SGPVSurface* ButtonDestBuffer;
38 
39 struct GUI_BUTTON;
40 
41 // GUI_BUTTON callback function type
42 typedef void (*GUI_CALLBACK)(GUI_BUTTON*, INT32);
43 
44 // GUI_BUTTON structure definitions.
45 struct GUI_BUTTON
46 {
47 	GUI_BUTTON(UINT32 flags, INT16 left, INT16 top, INT16 width, INT16 height, INT8 priority, GUI_CALLBACK click, GUI_CALLBACK move);
48 	~GUI_BUTTON();
49 
ClickedGUI_BUTTON50 	bool Clicked() const { return uiFlags & BUTTON_CLICKED_ON; }
51 
EnabledGUI_BUTTON52 	bool Enabled() const { return uiFlags & BUTTON_ENABLED; }
53 
54 	// Set the text that will be displayed as the FastHelp
55 	void SetFastHelpText(const ST::string& str);
56 
57 	void Hide();
58 	void Show();
59 
60 	// Draw the button on the screen.
61 	void Draw();
62 
63 	void SpecifyDownTextColors(INT16 fore_colour_down, INT16 shadow_colour_down);
64 	void SpecifyHilitedTextColors(INT16 fore_colour_highlighted, INT16 shadow_colour_highlighted);
65 
66 	enum Justification
67 	{
68 		TEXT_LEFT   = -1,
69 		TEXT_CENTER =  0,
70 		TEXT_RIGHT  =  1
71 	};
72 	void SpecifyTextJustification(Justification);
73 
74 	void SpecifyText(const ST::string& str);
75 	void SpecifyGeneralTextAttributes(const ST::string& str, SGPFont font, INT16 fore_colour, INT16 shadow_colour);
76 	void SpecifyTextOffsets(INT8 text_x_offset, INT8 text_y_offset, BOOLEAN shift_text);
77 	void SpecifyTextSubOffsets(INT8 text_x_offset, INT8 text_y_offset, BOOLEAN shift_text);
78 	void SpecifyTextWrappedWidth(INT16 wrapped_width);
79 
80 	void AllowDisabledFastHelp();
81 
82 	enum DisabledStyle
83 	{
84 		DISABLED_STYLE_NONE,    // for dummy buttons, panels, etc.  Always displays normal state.
85 		DISABLED_STYLE_DEFAULT, // if button has text then shade, else hatch
86 		DISABLED_STYLE_HATCHED, // always hatches the disabled button
87 		DISABLED_STYLE_SHADED   // always shades the disabled button 25% darker
88 	};
89 	void SpecifyDisabledStyle(DisabledStyle);
90 
91 	/* Note:  Text is always on top
92 	 * If fShiftImage is true, then the image will shift down one pixel and right
93 	 * one pixel just like the text does.
94 	 */
95 	void SpecifyIcon(SGPVObject const* icon, UINT16 usVideoObjectIndex, INT8 bXOffset, INT8 bYOffset, BOOLEAN fShiftImage);
96 
97 	// will simply set the cursor for the mouse region the button occupies
SetCursorGUI_BUTTON98 	void SetCursor(UINT16 const cursor) { Area.ChangeCursor(cursor); }
99 
100 	void DrawCheckBoxOnOff(BOOLEAN on);
101 
102 	// Coordinates where button is on the screen
XGUI_BUTTON103 	INT16 X()            const { return Area.RegionTopLeftX; }
YGUI_BUTTON104 	INT16 Y()            const { return Area.RegionTopLeftY; }
WGUI_BUTTON105 	INT16 W()            const { return Area.RegionBottomRightX - Area.RegionTopLeftX; }
HGUI_BUTTON106 	INT16 H()            const { return Area.RegionBottomRightY - Area.RegionTopLeftY; }
BottomRightXGUI_BUTTON107 	INT16 BottomRightX() const { return Area.RegionBottomRightX; }
BottomRightYGUI_BUTTON108 	INT16 BottomRightY() const { return Area.RegionBottomRightY; }
109 
MouseXGUI_BUTTON110 	INT16 MouseX()    const { return Area.MouseXPos; }
MouseYGUI_BUTTON111 	INT16 MouseY()    const { return Area.MouseYPos; }
RelativeXGUI_BUTTON112 	INT16 RelativeX() const { return Area.RelativeXPos; }
RelativeYGUI_BUTTON113 	INT16 RelativeY() const { return Area.RelativeYPos; }
114 
GetUserDataGUI_BUTTON115 	INT32 GetUserData() const { return User.Data; }
SetUserDataGUI_BUTTON116 	void  SetUserData(INT32 const data) { User.Data = data; }
117 
GetUserPtrGUI_BUTTON118 	template<typename T> T* GetUserPtr() const { return static_cast<T*>(User.Ptr); }
SetUserPtrGUI_BUTTON119 	void SetUserPtr(void* const p) { User.Ptr = p; }
120 
121 	INT32        IDNum;         // ID Number, contains it's own button number
122 	BUTTON_PICS* image;         // Image to use (see DOCs for details)
123 	MouseRegion  Area;          // Mouse System's mouse region to use for this button
124 	GUI_CALLBACK ClickCallback; // Button Callback when button is clicked
125 	GUI_CALLBACK MoveCallback;  // Button Callback when mouse moved on this region
126 	UINT32       uiFlags;       // Button state flags etc.( 32-bit )
127 	UINT32       uiOldFlags;    // Old flags from previous render loop
128 	union                       // Place holder for user data etc.
129 	{
130 		INT32 Data;
131 		void* Ptr;
132 	} User;
133 	INT8         bDisabledStyle; // Button disabled style
134 
135 	// For buttons with text
136 	ST::utf32_buffer codepoints;
137 	SGPFont      usFont;              // font for text
138 	INT16        sForeColor;          // text colors if there is text
139 	INT16        sShadowColor;
140 	INT16        sForeColorDown;      // text colors when button is down (optional)
141 	INT16        sShadowColorDown;
142 	INT16        sForeColorHilited;   // text colors when button is down (optional)
143 	INT16        sShadowColorHilited;
144 	INT8         bJustification;      // BUTTON_TEXT_LEFT, BUTTON_TEXT_CENTER, BUTTON_TEXT_RIGHT
145 	INT8         bTextXOffset;
146 	INT8         bTextYOffset;
147 	INT8         bTextXSubOffSet;
148 	INT8         bTextYSubOffSet;
149 	BOOLEAN      fShiftText;
150 	INT16        sWrappedWidth;
151 
152 	// For buttons with icons (don't confuse this with quickbuttons which have up to 5 states)
153 	const SGPVObject* icon;
154 	INT16        usIconIndex;
155 	INT8         bIconXOffset; // -1 means horizontally centered
156 	INT8         bIconYOffset; // -1 means vertically centered
157 	BOOLEAN      fShiftImage;  // if true, icon is shifted +1,+1 when button state is down.
158 
159 	UINT8        ubToggleButtonActivated;
160 
161 	UINT8        ubSoundSchemeID;
162 };
163 
164 
165 extern GUI_BUTTON* ButtonList[MAX_BUTTONS]; // Button System's Main Button List
166 
167 
168 class GUIButtonRef
169 {
170 	public:
GUIButtonRef()171 		GUIButtonRef() : btn_id_(0) {}
172 
GUIButtonRef(GUI_BUTTON * const b)173 		GUIButtonRef(GUI_BUTTON* const b) : btn_id_(b->IDNum) {}
174 
Reset()175 		void Reset() { btn_id_ = 0; }
176 
ID()177 		INT32 ID() const { return btn_id_; }
178 
179 		GUI_BUTTON* operator ->() const { return ButtonList[btn_id_]; }
180 
181 		operator GUI_BUTTON*() const { return ButtonList[btn_id_]; }
182 
NoButton()183 		static GUIButtonRef NoButton() { GUIButtonRef b; b.btn_id_ = -1; return b; };
184 
185 	private:
186 		INT32 btn_id_;
187 };
188 
189 
190 /* Initializes the GUI button system for use. Must be called before using any
191  * other button functions.
192  */
193 void InitButtonSystem(void);
194 
195 /* Shuts down and cleans up the GUI button system. Must be called before exiting
196  * the program.  Button functions should not be used after calling this
197  * function.
198  */
199 void ShutdownButtonSystem(void);
200 
201 #if defined _JA2_RENDER_DIRTY
202 
203 void RenderButtonsFastHelp(void);
204 #	define RenderButtonsFastHelp() RenderFastHelp()
205 
206 #endif
207 
208 // Loads an image file for use as a button icon.
209 INT16 LoadGenericButtonIcon(const char* filename);
210 
211 // Removes a button icon graphic from the system
212 void UnloadGenericButtonIcon(INT16 GenImg);
213 
214 // Load images for use with QuickButtons.
215 BUTTON_PICS* LoadButtonImage(const char* filename, INT32 Grayed, INT32 OffNormal, INT32 OffHilite, INT32 OnNormal, INT32 OnHilite);
216 BUTTON_PICS* LoadButtonImage(char const* filename, INT32 off_normal, INT32 on_normal);
217 
218 /* Uses a previously loaded quick button image for use with QuickButtons.  The
219  * function simply duplicates the vobj!
220  */
221 BUTTON_PICS* UseLoadedButtonImage(BUTTON_PICS* LoadedImg, INT32 Grayed, INT32 OffNormal, INT32 OffHilite, INT32 OnNormal, INT32 OnHilite);
222 BUTTON_PICS* UseLoadedButtonImage(BUTTON_PICS* img, INT32 off_normal, INT32 on_normal);
223 
224 // Removes a QuickButton image from the system.
225 void UnloadButtonImage(BUTTON_PICS*);
226 
227 // Enables an already created button.
228 void EnableButton(GUIButtonRef);
229 
230 /* Disables a button. The button remains in the system list, and can be
231  * reactivated by calling EnableButton.  Diabled buttons will appear "grayed
232  * out" on the screen (unless the graphics for such are not available).
233  */
234 void DisableButton(GUIButtonRef);
235 
236 void EnableButton(GUIButtonRef, bool enable);
237 
238 /* Removes a button from the system's list. All memory associated with the
239  * button is released.
240  */
241 void RemoveButton(GUIButtonRef&);
242 
243 void HideButton(GUIButtonRef);
244 void ShowButton(GUIButtonRef);
245 
246 void RenderButtons(void);
247 
248 extern BOOLEAN gfRenderHilights;
249 
250 /* Creates a QuickButton. QuickButtons only have graphics associated with them.
251  * They cannot be re-sized, nor can the graphic be changed.  Providing you have
252  * allocated your own image, this is a somewhat simplified function.
253  */
254 GUIButtonRef QuickCreateButton(BUTTON_PICS* image, INT16 x, INT16 y, INT16 priority, GUI_CALLBACK click);
255 GUIButtonRef QuickCreateButtonNoMove(BUTTON_PICS* image, INT16 x, INT16 y, INT16 priority, GUI_CALLBACK click);
256 GUIButtonRef QuickCreateButtonToggle(BUTTON_PICS* image, INT16 x, INT16 y, INT16 priority, GUI_CALLBACK click);
257 
258 GUIButtonRef QuickCreateButtonImg(const char* gfx, INT32 grayed, INT32 off_normal, INT32 off_hilite, INT32 on_normal, INT32 on_hilite, INT16 x, INT16 y, INT16 priority, GUI_CALLBACK click);
259 GUIButtonRef QuickCreateButtonImg(const char* gfx, INT32 off_normal, INT32 on_normal, INT16 x, INT16 y, INT16 priority, GUI_CALLBACK click);
260 
261 GUIButtonRef CreateCheckBoxButton(INT16 x, INT16 y, const char* filename, INT16 Priority, GUI_CALLBACK ClickCallback);
262 
263 // Creates an Iconic type button.
264 GUIButtonRef CreateIconButton(INT16 Icon, INT16 IconIndex, INT16 xloc, INT16 yloc, INT16 w, INT16 h, INT16 Priority, GUI_CALLBACK ClickCallback);
265 
266 /* Creates a button like HotSpot. HotSpots have no graphics associated with
267  * them.
268  */
269 GUIButtonRef CreateHotSpot(INT16 xloc, INT16 yloc, INT16 Width, INT16 Height, INT16 Priority, GUI_CALLBACK ClickCallback);
270 
271 // Creates a generic button with text on it.
272 GUIButtonRef CreateTextButton(const ST::string& str, SGPFont font, INT16 sForeColor, INT16 sShadowColor, INT16 xloc, INT16 yloc, INT16 w, INT16 h, INT16 Priority, GUI_CALLBACK ClickCallback);
273 
274 GUIButtonRef CreateIconAndTextButton(BUTTON_PICS* Image, const ST::string& str, SGPFont font, INT16 sForeColor, INT16 sShadowColor, INT16 sForeColorDown, INT16 sShadowColorDown, INT16 xloc, INT16 yloc, INT16 Priority, GUI_CALLBACK ClickCallback);
275 
276 /* This is technically not a clickable button, but just a label with text. It is
277  * implemented as button */
278 GUIButtonRef CreateLabel(const ST::string& str, SGPFont font, INT16 forecolor, INT16 shadowcolor, INT16 x, INT16 y, INT16 w, INT16 h, INT16 priority);
279 
280 void MarkAButtonDirty(GUIButtonRef); // will mark only selected button dirty
281 void MarkButtonsDirty(void);// Function to mark buttons dirty ( all will redraw at next RenderButtons )
282 void UnMarkButtonDirty(GUIButtonRef);  // unmark button
283 void UnmarkButtonsDirty(void); // unmark ALL the buttoms on the screen dirty
284 void ForceButtonUnDirty(GUIButtonRef); // forces button undirty no matter the reason, only lasts one frame
285 
286 
287 struct ButtonDimensions
288 {
289 	UINT32 w;
290 	UINT32 h;
291 };
292 
293 const ButtonDimensions* GetDimensionsOfButtonPic(const BUTTON_PICS*);
294 
295 UINT16 GetGenericButtonFillColor(void);
296 
297 void ReleaseAnchorMode(void);
298 
299 #endif
300