(svn r7621) -Codechange: Rework ShowQuery into a general modal popup window. It gets passed
authorDarkvater
Fri, 29 Dec 2006 17:54:47 +0000
changeset 5669 ea25407ffa55
parent 5668 76262aa5075d
child 5670 c6dcca763ebb
(svn r7621) -Codechange: Rework ShowQuery into a general modal popup window. It gets passed
a parent pointer which will be blocked as long as the popup is open. This
applies to newgrf-apply, heightmap warning, genworld progress.
genworld_gui.c
gui.h
misc_gui.c
newgrf_gui.c
openttd.h
window.h
--- a/genworld_gui.c	Fri Dec 29 17:51:16 2006 +0000
+++ b/genworld_gui.c	Fri Dec 29 17:54:47 2006 +0000
@@ -176,16 +176,9 @@
 	}
 }
 
-static void HeightmapScaledTooMuchCallback(bool ok_clicked)
+static void HeightmapScaledTooMuchCallback(Window *w, bool confirmed)
 {
-	if (ok_clicked) {
-		Window *w;
-		glwp_modes mode = 0;
-		for (mode = 0; mode < GLWP_END; mode++) {
-			w = FindWindowById(WC_GENERATE_LANDSCAPE, mode);
-			if (w != NULL) StartGeneratingLandscape(mode);
-		}
-	}
+	if (confirmed) StartGeneratingLandscape((glwp_modes)w->window_number);
 }
 
 void GenerateLandscapeWndProc(Window *w, WindowEvent *e)
@@ -330,7 +323,11 @@
 			if (mode == GLWP_HEIGHTMAP && (
 					_heightmap_x * 2 < (1U << _patches_newgame.map_x) || _heightmap_x / 2 > (1U << _patches_newgame.map_x) ||
 					_heightmap_y * 2 < (1U << _patches_newgame.map_y) || _heightmap_y / 2 > (1U << _patches_newgame.map_y))) {
-				ShowQuery(STR_HEIGHTMAP_SCALE_WARNING_CAPTION, STR_HEIGHTMAP_SCALE_WARNING_MESSAGE, HeightmapScaledTooMuchCallback, WC_GENERATE_LANDSCAPE, mode);
+				ShowQuery(
+					STR_HEIGHTMAP_SCALE_WARNING_CAPTION,
+					STR_HEIGHTMAP_SCALE_WARNING_MESSAGE,
+					w,
+					HeightmapScaledTooMuchCallback);
 			} else {
 				StartGeneratingLandscape(mode);
 			}
@@ -722,10 +719,13 @@
 
 static tp_info _tp;
 
-static void AbortGeneratingWorldCallback(bool ok_clicked)
+static void AbortGeneratingWorldCallback(Window *w, bool confirmed)
 {
-	if (ok_clicked) AbortGeneratingWorld();
-	else if (IsGeneratingWorld() && !IsGeneratingWorldAborted()) SetMouseCursor(SPR_CURSOR_ZZZ);
+	if (confirmed) {
+		AbortGeneratingWorld();
+	} else if (IsGeneratingWorld() && !IsGeneratingWorldAborted()) {
+		SetMouseCursor(SPR_CURSOR_ZZZ);
+	}
 }
 
 static void ShowTerrainProgressProc(Window* w, WindowEvent* e)
@@ -735,7 +735,12 @@
 		switch (e->we.click.widget) {
 		case 2:
 			if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE);
-			ShowQuery(STR_GENERATION_ABORT_CAPTION, STR_GENERATION_ABORT_MESSAGE, AbortGeneratingWorldCallback, WC_GENERATE_PROGRESS_WINDOW, 0);
+			ShowQuery(
+				STR_GENERATION_ABORT_CAPTION,
+				STR_GENERATION_ABORT_MESSAGE,
+				w,
+				AbortGeneratingWorldCallback
+			);
 			break;
 		}
 		break;
--- a/gui.h	Fri Dec 29 17:51:16 2006 +0000
+++ b/gui.h	Fri Dec 29 17:54:47 2006 +0000
@@ -127,7 +127,7 @@
 
 void ShowBuildIndustryWindow(void);
 void ShowQueryString(StringID str, StringID caption, uint maxlen, uint maxwidth, WindowClass window_class, WindowNumber window_number, CharSetFilter afilter);
-void ShowQuery(StringID caption, StringID message, void (*ok_cancel_callback)(bool ok_clicked), WindowClass window_class, WindowNumber window_number);
+void ShowQuery(StringID caption, StringID message, Window *w, void (*callback)(Window*, bool));
 void ShowMusicWindow(void);
 
 /* main_gui.c */
--- a/misc_gui.c	Fri Dec 29 17:51:16 2006 +0000
+++ b/misc_gui.c	Fri Dec 29 17:54:47 2006 +0000
@@ -1169,68 +1169,112 @@
 	InitializeTextBuffer(&WP(w, querystr_d).text, _edit_str_buf, realmaxlen, maxwidth);
 }
 
+
+enum QueryWidgets {
+	QUERY_WIDGET_CAPTION = 1,
+	QUERY_WIDGET_NO = 3,
+	QUERY_WIDGET_YES
+};
+
+
+typedef struct query_d {
+	StringID message;            ///< message shown for query window
+	uint32 params[20];           ///< local copy of _decode_parameters
+	void (*proc)(Window*, bool); ///< callback function executed on closing of popup. Window* points to parent, bool is true if 'yes' clicked, false otherwise
+	bool calledback;             ///< has callback been executed already (internal usage for WE_DESTROY event)
+} query_d;
+assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(query_d));
+
+
 static void QueryWndProc(Window *w, WindowEvent *e)
 {
-	switch (e->event) {
-	case WE_PAINT:
-		SetDParam(0, WP(w, query_d).caption);
-		DrawWindowWidgets(w);
-
-		DrawStringMultiCenter(90, 38, WP(w, query_d).message, 178);
-		break;
+	query_d *q = &WP(w, query_d);
 
-	case WE_CLICK:
-		switch (e->we.click.widget) {
-		case 3:
-		case 4:
-			WP(w, query_d).calledback = true;
-			if (WP(w, query_d).ok_cancel_callback != NULL) WP(w, query_d).ok_cancel_callback(e->we.click.widget == 4);
-			DeleteWindow(w);
+	switch (e->event) {
+		case WE_PAINT:
+			COPY_IN_DPARAM(0, q->params, lengthof(q->params));
+			DrawWindowWidgets(w);
+			COPY_IN_DPARAM(0, q->params, lengthof(q->params));
+
+			DrawStringMultiCenter(w->width / 2, (w->height / 2) - 10, q->message, w->width);
 			break;
-		}
-		break;
 
-	case WE_MOUSELOOP:
-		if (!FindWindowById(WP(w, query_d).wnd_class, WP(w, query_d).wnd_num)) DeleteWindow(w);
-		break;
+		case WE_CLICK:
+			switch (e->we.click.widget) {
+				case QUERY_WIDGET_YES:
+					q->calledback = true;
+					if (q->proc != NULL) q->proc(w->parent, true);
+					/* Fallthrough */
+				case QUERY_WIDGET_NO:
+					DeleteWindow(w);
+					break;
+				}
+			break;
 
-	case WE_DESTROY:
-		if (!WP(w, query_d).calledback && WP(w, query_d).ok_cancel_callback != NULL) WP(w, query_d).ok_cancel_callback(false);
-		break;
+		case WE_KEYPRESS: /* ESC closes the window, Enter confirms the action */
+			switch (e->we.keypress.keycode) {
+				case WKC_RETURN:
+				case WKC_NUM_ENTER:
+					q->calledback = true;
+					if (q->proc != NULL) q->proc(w->parent, true);
+					/* Fallthrough */
+				case WKC_ESC:
+					e->we.keypress.cont = false;
+					DeleteWindow(w);
+					break;
+			}
+			break;
+
+		case WE_DESTROY: /* Call callback function (if any) on window close if not yet called */
+			if (!q->calledback && q->proc != NULL) q->proc(w->parent, false);
+			break;
 	}
 }
 
+
 static const Widget _query_widgets[] = {
-{ WWT_CLOSEBOX, RESIZE_NONE,  4,   0,  10,   0,  13, STR_00C5,        STR_018B_CLOSE_WINDOW},
-{  WWT_CAPTION, RESIZE_NONE,  4,  11, 179,   0,  13, STR_012D,        STR_NULL},
-{    WWT_PANEL, RESIZE_NONE,  4,   0, 179,  14,  91, 0x0,             STR_NULL},
-{  WWT_TEXTBTN, RESIZE_NONE, 12,  25,  84,  72,  83, STR_012E_CANCEL, STR_NULL},
-{  WWT_TEXTBTN, RESIZE_NONE, 12,  95, 154,  72,  83, STR_012F_OK,     STR_NULL},
-{  WIDGETS_END },
+{  WWT_CLOSEBOX, RESIZE_NONE,  4,   0,  10,   0,  13, STR_00C5,        STR_018B_CLOSE_WINDOW},
+{   WWT_CAPTION, RESIZE_NONE,  4,  11, 209,   0,  13, STR_NULL,        STR_NULL},
+{     WWT_PANEL, RESIZE_NONE,  4,   0, 209,  14,  81, 0x0, /*OVERRIDE*/STR_NULL},
+{WWT_PUSHTXTBTN, RESIZE_NONE,  3,  20,  90,  62,  73, STR_00C9_NO,     STR_NULL},
+{WWT_PUSHTXTBTN, RESIZE_NONE,  3, 120, 190,  62,  73, STR_00C8_YES,    STR_NULL},
+{   WIDGETS_END },
 };
 
 static const WindowDesc _query_desc = {
-	WDP_CENTER, WDP_CENTER, 180, 92,
-	WC_OK_CANCEL_QUERY, 0,
-	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
+	WDP_CENTER, WDP_CENTER, 210, 82,
+	WC_CONFIRM_POPUP_QUERY, 0,
+	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_UNCLICK_BUTTONS | WDF_DEF_WIDGET | WDF_MODAL,
 	_query_widgets,
 	QueryWndProc
 };
 
-void ShowQuery(StringID caption, StringID message, void (*ok_cancel_callback)(bool ok_clicked), WindowClass window_class, WindowNumber window_number)
+/** Show a modal confirmation window with standard 'yes' and 'no' buttons
+ * The window is aligned to the centre of its parent.
+ * NOTE: You cannot use BindCString as parameter for this window!
+ * @param caption string shown as window caption
+ * @param message string that will be shown for the window
+ * @param parent pointer to parent window, if this pointer is NULL the parent becomes
+ * the main window WC_MAIN_WINDOW
+ * @param x,y coordinates to show the window at
+ * @param yes_no_callback callback function called when window is closed through any button */
+void ShowQuery(StringID caption, StringID message, Window *parent, void (*callback)(Window*, bool))
 {
-	Window *w;
-
-	DeleteWindowById(WC_OK_CANCEL_QUERY, 0);
+	Window *w = AllocateWindowDesc(&_query_desc);
+	if (w == NULL) return;
 
-	w = AllocateWindowDesc(&_query_desc);
+	if (parent == NULL) parent = FindWindowById(WC_MAIN_WINDOW, 0);
+	w->parent = parent;
+	w->left = parent->left + (parent->width / 2) - (w->width / 2);
+	w->top = parent->top + (parent->height / 2) - (w->height / 2);
 
-	WP(w, query_d).caption            = caption;
-	WP(w, query_d).message            = message;
-	WP(w, query_d).wnd_class          = window_class;
-	WP(w, query_d).wnd_num            = window_number;
-	WP(w, query_d).ok_cancel_callback = ok_cancel_callback;
-	WP(w, query_d).calledback         = false;
+	/* Create a backup of the variadic arguments to strings because it will be
+	 * overridden pretty often. We will copy these back for drawing */
+	COPY_OUT_DPARAM(WP(w, query_d).params, 0, lengthof(WP(w, query_d).params));
+	w->widget[QUERY_WIDGET_CAPTION].data = caption;
+	WP(w, query_d).message    = message;
+	WP(w, query_d).proc       = callback;
+	WP(w, query_d).calledback = false;
 }
 
 
--- a/newgrf_gui.c	Fri Dec 29 17:51:16 2006 +0000
+++ b/newgrf_gui.c	Fri Dec 29 17:54:47 2006 +0000
@@ -278,10 +278,9 @@
 
 /** Callback function for the newgrf 'apply changes' confirmation window
  * @param yes_clicked boolean value, true when yes was clicked, false otherwise */
-static void NewGRFConfirmationCallback(bool yes_clicked)
+static void NewGRFConfirmationCallback(Window *w, bool confirmed)
 {
-	if (yes_clicked) {
-		Window *w = FindWindowById(WC_GAME_OPTIONS, 0);
+	if (confirmed) {
 		newgrf_d *nd = &WP(w, newgrf_d);
 
 		CopyGRFConfigList(nd->orig_list, *nd->list);
@@ -424,9 +423,8 @@
 						ShowQuery(
 							STR_POPUP_CAUTION_CAPTION,
 							STR_NEWGRF_CONFIRMATION_TEXT,
-							NewGRFConfirmationCallback,
-							w->window_class,
-							w->window_number
+							w,
+							NewGRFConfirmationCallback
 						);
 					} else {
 						CopyGRFConfigList(WP(w, newgrf_d).orig_list, *WP(w, newgrf_d).list);
--- a/openttd.h	Fri Dec 29 17:51:16 2006 +0000
+++ b/openttd.h	Fri Dec 29 17:54:47 2006 +0000
@@ -443,7 +443,7 @@
 	WC_SIGN_LIST,
 	WC_GENERATE_LANDSCAPE,
 	WC_GENERATE_PROGRESS_WINDOW,
-	WC_OK_CANCEL_QUERY,
+	WC_CONFIRM_POPUP_QUERY,
 	WC_DEPOT_SELL_ALL,
 };
 
--- a/window.h	Fri Dec 29 17:51:16 2006 +0000
+++ b/window.h	Fri Dec 29 17:54:47 2006 +0000
@@ -350,16 +350,6 @@
 } querystr_d;
 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(querystr_d));
 
-typedef struct query_d {
-	StringID caption;
-	StringID message;
-	WindowClass wnd_class;
-	WindowNumber wnd_num;
-	void (*ok_cancel_callback)(bool ok_clicked);
-	bool calledback;
-} query_d;
-assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(query_d));
-
 typedef struct {
 	byte item_count;      /* follow_vehicle */
 	byte sel_index;       /* scrollpos_x */