1 /**
2  * @file
3  */
4 
5 /*
6 Copyright (C) 2002-2013 UFO: Alien Invasion.
7 
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 
17 See the GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 
23 */
24 
25 #include "ui_main.h"
26 #include "ui_nodes.h"
27 #include "ui_node.h"
28 #include "ui_popup.h"
29 #include "ui_actions.h"
30 #include "node/ui_node_abstractnode.h"
31 
32 #define POPUPBUTTON_WINDOW_NAME "popup_button"
33 #define POPUPBUTTON_NODE_NAME "popup_button_"
34 #define POPUP_WINDOW_NAME "popup"
35 
36 /** @brief strings to be used for popup when text is not static */
37 char popupText[UI_MAX_SMALLTEXTLEN];
38 static char popupAction1[UI_MAX_SMALLTEXTLEN];
39 static char popupAction2[UI_MAX_SMALLTEXTLEN];
40 static char popupAction3[UI_MAX_SMALLTEXTLEN];
41 
42 /**
43  * @brief Popup on geoscape
44  * @note Only use static strings here - or use popupText if you really have to
45  * build the string
46  */
UI_Popup(const char * title,const char * text)47 void UI_Popup (const char* title, const char* text)
48 {
49 	Cvar_Set("ui_sys_popup_title", "%s", title);
50 	UI_RegisterText(TEXT_POPUP_INFO, text);
51 	if (!UI_IsWindowOnStack(POPUP_WINDOW_NAME))
52 		UI_PushWindow(POPUP_WINDOW_NAME);
53 }
54 
55 /**
56  * @brief Generates a popup that contains a list of selectable choices.
57  * @param[in] title Title of the popup.
58  * @param[in] headline First line of text written in the popup.
59  * @param[in] entries List of the selectables choices.
60  * @param[in] clickAction Action to perform when one clicked on the popup.
61  */
UI_PopupList(const char * title,const char * headline,linkedList_t * entries,const char * clickAction)62 uiNode_t* UI_PopupList (const char* title, const char* headline, linkedList_t* entries, const char* clickAction)
63 {
64 	uiNode_t* window;
65 	uiNode_t* listNode;
66 
67 	Cvar_Set("ui_sys_popup_title", "%s", title);
68 	UI_RegisterText(TEXT_POPUP_INFO, headline);
69 
70 	/* make sure, that we are using the linked list */
71 	UI_ResetData(TEXT_LIST);
72 	UI_RegisterLinkedListText(TEXT_LIST, entries);
73 
74 	window = UI_GetWindow(POPUPLIST_WINDOW_NAME);
75 	if (!window)
76 		Com_Error(ERR_FATAL, "Could not get " POPUPLIST_WINDOW_NAME " window");
77 	listNode = UI_GetNode(window, POPUPLIST_NODE_NAME);
78 	if (!listNode)
79 		Com_Error(ERR_FATAL, "Could not get " POPUPLIST_NODE_NAME " node in " POPUPLIST_WINDOW_NAME " window");
80 
81 	/* free previous actions */
82 	if (listNode->onClick) {
83 		assert(listNode->onClick->d.terminal.d1.data);
84 		Mem_Free(listNode->onClick->d.terminal.d1.data);
85 		Mem_Free(listNode->onClick);
86 		listNode->onClick = nullptr;
87 	}
88 
89 	if (clickAction) {
90 		UI_PoolAllocAction(&listNode->onClick, EA_CMD, clickAction);
91 	} else {
92 		listNode->onClick = nullptr;
93 	}
94 
95 	if (!UI_IsWindowOnStack(window->name))
96 		UI_PushWindow(window->name);
97 	return listNode;
98 }
99 
100 /**
101  * @brief Set string and action button.
102  * @param[in] window window where buttons are modified.
103  * @param[in] button Name of the node of the button.
104  * @param[in] clickAction Action to perform when button is clicked.
105  * @note clickAction may be nullptr if button is not needed.
106  */
UI_SetOneButton(uiNode_t * window,const char * button,const char * clickAction)107 static void UI_SetOneButton (uiNode_t* window, const char* button, const char* clickAction)
108 {
109 	uiNode_t* buttonNode;
110 
111 	buttonNode = UI_GetNode(window, button);
112 	if (!buttonNode)
113 		Com_Error(ERR_FATAL, "Could not get %s node in %s window", button, window->name);
114 
115 	/* free previous actions */
116 	if (buttonNode->onClick) {
117 		assert(buttonNode->onClick->d.terminal.d1.data);
118 		Mem_Free(buttonNode->onClick->d.terminal.d1.data);
119 		Mem_Free(buttonNode->onClick);
120 		buttonNode->onClick = nullptr;
121 	}
122 
123 	if (clickAction) {
124 		UI_PoolAllocAction(&buttonNode->onClick, EA_CMD, clickAction);
125 		buttonNode->invis = false;
126 	} else {
127 		buttonNode->onClick = nullptr;
128 		buttonNode->invis = true;
129 	}
130 }
131 
132 /**
133  * @brief Generates a popup that contains up to 3 buttons.
134  * @param[in] title Title of the popup.
135  * @param[in] text Text to display in the popup (use popupText if text is nullptr).
136  * @param[in] clickAction1 Action to perform when one clicked on the first button.
137  * @param[in] clickText1 String that will be written in first button.
138  * @param[in] tooltip1 Tooltip of first button.
139  * @param[in] clickAction2 Action to perform when one clicked on the second button.
140  * @param[in] clickText2 String that will be written in second button.
141  * @param[in] tooltip2 Tooltip of second button.
142  * @param[in] clickAction3 Action to perform when one clicked on the third button.
143  * @param[in] clickText3 String that will be written in third button.
144  * @param[in] tooltip3 Tooltip of third button.
145  * @note clickAction AND clickText must be nullptr if button should be invisible.
146  */
UI_PopupButton(const char * title,const char * text,const char * clickAction1,const char * clickText1,const char * tooltip1,const char * clickAction2,const char * clickText2,const char * tooltip2,const char * clickAction3,const char * clickText3,const char * tooltip3)147 void UI_PopupButton (const char* title, const char* text,
148 	const char* clickAction1, const char* clickText1, const char* tooltip1,
149 	const char* clickAction2, const char* clickText2, const char* tooltip2,
150 	const char* clickAction3, const char* clickText3, const char* tooltip3)
151 {
152 	uiNode_t* window;
153 
154 	Cvar_Set("ui_sys_popup_title", "%s", title);
155 	if (text)
156 		UI_RegisterText(TEXT_POPUP_INFO, text);
157 	else
158 		UI_RegisterText(TEXT_POPUP_INFO, popupText);
159 
160 	window = UI_GetWindow(POPUPBUTTON_WINDOW_NAME);
161 	if (!window)
162 		Com_Error(ERR_FATAL, "Could not get \"" POPUPBUTTON_WINDOW_NAME "\" window");
163 
164 	Cvar_Set("ui_sys_popup_button_text1", "%s", clickText1);
165 	Cvar_Set("ui_sys_popup_button_tooltip1", "%s", tooltip1);
166 	if (!clickAction1 && !clickText1) {
167 		UI_SetOneButton(window, va("%s1", POPUPBUTTON_NODE_NAME),
168 			nullptr);
169 	} else {
170 		UI_SetOneButton(window, va("%s1", POPUPBUTTON_NODE_NAME),
171 			clickAction1 ? clickAction1 : popupAction1);
172 	}
173 
174 	Cvar_Set("ui_sys_popup_button_text2", "%s", clickText2);
175 	Cvar_Set("ui_sys_popup_button_tooltip2", "%s", tooltip2);
176 	if (!clickAction2 && !clickText2) {
177 		UI_SetOneButton(window, va("%s2", POPUPBUTTON_NODE_NAME), nullptr);
178 	} else {
179 		UI_SetOneButton(window, va("%s2", POPUPBUTTON_NODE_NAME),
180 			clickAction2 ? clickAction2 : popupAction2);
181 	}
182 
183 	Cvar_Set("ui_sys_popup_button_text3", "%s", clickText3);
184 	Cvar_Set("ui_sys_popup_button_tooltip3", "%s", tooltip3);
185 	if (!clickAction3 && !clickText3) {
186 		UI_SetOneButton(window, va("%s3", POPUPBUTTON_NODE_NAME), nullptr);
187 	} else {
188 		UI_SetOneButton(window, va("%s3", POPUPBUTTON_NODE_NAME),
189 			clickAction3 ? clickAction3 : popupAction3);
190 	}
191 
192 	if (!UI_IsWindowOnStack(window->name))
193 		UI_PushWindow(window->name);
194 }
195