# HG changeset patch # User Darkvater # Date 1167414887 0 # Node ID ea25407ffa555b2690f9151507b3634cf8c25715 # Parent 76262aa5075de453dd0a21ea7cbb1d4b3fc919a8 (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. diff -r 76262aa5075d -r ea25407ffa55 genworld_gui.c --- 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; diff -r 76262aa5075d -r ea25407ffa55 gui.h --- 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 */ diff -r 76262aa5075d -r ea25407ffa55 misc_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; } diff -r 76262aa5075d -r ea25407ffa55 newgrf_gui.c --- 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); diff -r 76262aa5075d -r ea25407ffa55 openttd.h --- 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, }; diff -r 76262aa5075d -r ea25407ffa55 window.h --- 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 */