misc_gui.c
changeset 5418 793a133c6d2a
parent 5380 8ea58542b6e0
child 5429 a664da42d64e
equal deleted inserted replaced
5417:a0224e6cedd1 5418:793a133c6d2a
  1167 	WP(w, querystr_d).wnd_num = window_number;
  1167 	WP(w, querystr_d).wnd_num = window_number;
  1168 	WP(w, querystr_d).afilter = afilter;
  1168 	WP(w, querystr_d).afilter = afilter;
  1169 	InitializeTextBuffer(&WP(w, querystr_d).text, _edit_str_buf, realmaxlen, maxwidth);
  1169 	InitializeTextBuffer(&WP(w, querystr_d).text, _edit_str_buf, realmaxlen, maxwidth);
  1170 }
  1170 }
  1171 
  1171 
       
  1172 
       
  1173 enum QueryWidgets {
       
  1174 	QUERY_WIDGET_CAPTION = 1,
       
  1175 	QUERY_WIDGET_NO = 3,
       
  1176 	QUERY_WIDGET_YES
       
  1177 };
       
  1178 
       
  1179 
       
  1180 typedef struct query_d {
       
  1181 	StringID message;            ///< message shown for query window
       
  1182 	uint32 params[20];           ///< local copy of _decode_parameters
       
  1183 	void (*proc)(Window*, bool); ///< callback function executed on closing of popup. Window* points to parent, bool is true if 'yes' clicked, false otherwise
       
  1184 	bool calledback;             ///< has callback been executed already (internal usage for WE_DESTROY event)
       
  1185 } query_d;
       
  1186 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(query_d));
       
  1187 
       
  1188 
  1172 static void QueryWndProc(Window *w, WindowEvent *e)
  1189 static void QueryWndProc(Window *w, WindowEvent *e)
  1173 {
  1190 {
       
  1191 	query_d *q = &WP(w, query_d);
       
  1192 
  1174 	switch (e->event) {
  1193 	switch (e->event) {
  1175 	case WE_PAINT:
  1194 		case WE_PAINT:
  1176 		SetDParam(0, WP(w, query_d).caption);
  1195 			COPY_IN_DPARAM(0, q->params, lengthof(q->params));
  1177 		DrawWindowWidgets(w);
  1196 			DrawWindowWidgets(w);
  1178 
  1197 			COPY_IN_DPARAM(0, q->params, lengthof(q->params));
  1179 		DrawStringMultiCenter(90, 38, WP(w, query_d).message, 178);
  1198 
  1180 		break;
  1199 			DrawStringMultiCenter(w->width / 2, (w->height / 2) - 10, q->message, w->width);
  1181 
  1200 			break;
  1182 	case WE_CLICK:
  1201 
  1183 		switch (e->we.click.widget) {
  1202 		case WE_CLICK:
  1184 		case 3:
  1203 			switch (e->we.click.widget) {
  1185 		case 4:
  1204 				case QUERY_WIDGET_YES:
  1186 			WP(w, query_d).calledback = true;
  1205 					q->calledback = true;
  1187 			if (WP(w, query_d).ok_cancel_callback != NULL) WP(w, query_d).ok_cancel_callback(e->we.click.widget == 4);
  1206 					if (q->proc != NULL) q->proc(w->parent, true);
  1188 			DeleteWindow(w);
  1207 					/* Fallthrough */
  1189 			break;
  1208 				case QUERY_WIDGET_NO:
  1190 		}
  1209 					DeleteWindow(w);
  1191 		break;
  1210 					break;
  1192 
  1211 				}
  1193 	case WE_MOUSELOOP:
  1212 			break;
  1194 		if (!FindWindowById(WP(w, query_d).wnd_class, WP(w, query_d).wnd_num)) DeleteWindow(w);
  1213 
  1195 		break;
  1214 		case WE_KEYPRESS: /* ESC closes the window, Enter confirms the action */
  1196 
  1215 			switch (e->we.keypress.keycode) {
  1197 	case WE_DESTROY:
  1216 				case WKC_RETURN:
  1198 		if (!WP(w, query_d).calledback && WP(w, query_d).ok_cancel_callback != NULL) WP(w, query_d).ok_cancel_callback(false);
  1217 				case WKC_NUM_ENTER:
  1199 		break;
  1218 					q->calledback = true;
  1200 	}
  1219 					if (q->proc != NULL) q->proc(w->parent, true);
  1201 }
  1220 					/* Fallthrough */
       
  1221 				case WKC_ESC:
       
  1222 					e->we.keypress.cont = false;
       
  1223 					DeleteWindow(w);
       
  1224 					break;
       
  1225 			}
       
  1226 			break;
       
  1227 
       
  1228 		case WE_DESTROY: /* Call callback function (if any) on window close if not yet called */
       
  1229 			if (!q->calledback && q->proc != NULL) q->proc(w->parent, false);
       
  1230 			break;
       
  1231 	}
       
  1232 }
       
  1233 
  1202 
  1234 
  1203 static const Widget _query_widgets[] = {
  1235 static const Widget _query_widgets[] = {
  1204 { WWT_CLOSEBOX, RESIZE_NONE,  4,   0,  10,   0,  13, STR_00C5,        STR_018B_CLOSE_WINDOW},
  1236 {  WWT_CLOSEBOX, RESIZE_NONE,  4,   0,  10,   0,  13, STR_00C5,        STR_018B_CLOSE_WINDOW},
  1205 {  WWT_CAPTION, RESIZE_NONE,  4,  11, 179,   0,  13, STR_012D,        STR_NULL},
  1237 {   WWT_CAPTION, RESIZE_NONE,  4,  11, 209,   0,  13, STR_NULL,        STR_NULL},
  1206 {    WWT_PANEL, RESIZE_NONE,  4,   0, 179,  14,  91, 0x0,             STR_NULL},
  1238 {     WWT_PANEL, RESIZE_NONE,  4,   0, 209,  14,  81, 0x0, /*OVERRIDE*/STR_NULL},
  1207 {  WWT_TEXTBTN, RESIZE_NONE, 12,  25,  84,  72,  83, STR_012E_CANCEL, STR_NULL},
  1239 {WWT_PUSHTXTBTN, RESIZE_NONE,  3,  20,  90,  62,  73, STR_00C9_NO,     STR_NULL},
  1208 {  WWT_TEXTBTN, RESIZE_NONE, 12,  95, 154,  72,  83, STR_012F_OK,     STR_NULL},
  1240 {WWT_PUSHTXTBTN, RESIZE_NONE,  3, 120, 190,  62,  73, STR_00C8_YES,    STR_NULL},
  1209 {  WIDGETS_END },
  1241 {   WIDGETS_END },
  1210 };
  1242 };
  1211 
  1243 
  1212 static const WindowDesc _query_desc = {
  1244 static const WindowDesc _query_desc = {
  1213 	WDP_CENTER, WDP_CENTER, 180, 92,
  1245 	WDP_CENTER, WDP_CENTER, 210, 82,
  1214 	WC_OK_CANCEL_QUERY, 0,
  1246 	WC_CONFIRM_POPUP_QUERY, 0,
  1215 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
  1247 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_UNCLICK_BUTTONS | WDF_DEF_WIDGET | WDF_MODAL,
  1216 	_query_widgets,
  1248 	_query_widgets,
  1217 	QueryWndProc
  1249 	QueryWndProc
  1218 };
  1250 };
  1219 
  1251 
  1220 void ShowQuery(StringID caption, StringID message, void (*ok_cancel_callback)(bool ok_clicked), WindowClass window_class, WindowNumber window_number)
  1252 /** Show a modal confirmation window with standard 'yes' and 'no' buttons
  1221 {
  1253  * The window is aligned to the centre of its parent.
  1222 	Window *w;
  1254  * NOTE: You cannot use BindCString as parameter for this window!
  1223 
  1255  * @param caption string shown as window caption
  1224 	DeleteWindowById(WC_OK_CANCEL_QUERY, 0);
  1256  * @param message string that will be shown for the window
  1225 
  1257  * @param parent pointer to parent window, if this pointer is NULL the parent becomes
  1226 	w = AllocateWindowDesc(&_query_desc);
  1258  * the main window WC_MAIN_WINDOW
  1227 
  1259  * @param x,y coordinates to show the window at
  1228 	WP(w, query_d).caption            = caption;
  1260  * @param yes_no_callback callback function called when window is closed through any button */
  1229 	WP(w, query_d).message            = message;
  1261 void ShowQuery(StringID caption, StringID message, Window *parent, void (*callback)(Window*, bool))
  1230 	WP(w, query_d).wnd_class          = window_class;
  1262 {
  1231 	WP(w, query_d).wnd_num            = window_number;
  1263 	Window *w = AllocateWindowDesc(&_query_desc);
  1232 	WP(w, query_d).ok_cancel_callback = ok_cancel_callback;
  1264 	if (w == NULL) return;
  1233 	WP(w, query_d).calledback         = false;
  1265 
       
  1266 	if (parent == NULL) parent = FindWindowById(WC_MAIN_WINDOW, 0);
       
  1267 	w->parent = parent;
       
  1268 	w->left = parent->left + (parent->width / 2) - (w->width / 2);
       
  1269 	w->top = parent->top + (parent->height / 2) - (w->height / 2);
       
  1270 
       
  1271 	/* Create a backup of the variadic arguments to strings because it will be
       
  1272 	 * overridden pretty often. We will copy these back for drawing */
       
  1273 	COPY_OUT_DPARAM(WP(w, query_d).params, 0, lengthof(WP(w, query_d).params));
       
  1274 	w->widget[QUERY_WIDGET_CAPTION].data = caption;
       
  1275 	WP(w, query_d).message    = message;
       
  1276 	WP(w, query_d).proc       = callback;
       
  1277 	WP(w, query_d).calledback = false;
  1234 }
  1278 }
  1235 
  1279 
  1236 
  1280 
  1237 static const Widget _load_dialog_widgets[] = {
  1281 static const Widget _load_dialog_widgets[] = {
  1238 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,         STR_018B_CLOSE_WINDOW},
  1282 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,         STR_018B_CLOSE_WINDOW},