# newgrf_gui.cpp

Go to the documentation of this file.

    00001 /* $Id: newgrf_gui.cpp 12368 2008-03-15 13:21:31Z smatz $ */
    00002
    00005 #include "stdafx.h"
    00006 #include "openttd.h"
    00007 #include "variables.h"
    00008 #include "gui.h"
    00009 #include "window_gui.h"
    00010 #include "textbuf_gui.h"
    00011 #include "newgrf.h"
    00012 #include "newgrf_config.h"
    00013 #include "strings_func.h"
    00014 #include "window_func.h"
    00015 #include "core/alloc_func.hpp"
    00016 #include "string_func.h"
    00017 #include "gfx_func.h"
    00018
    00019 #include "table/strings.h"
    00020 #include "table/sprites.h"
    00021
    00028 static int parse_intlist(const char *p, int *items, int maxitems)
    00029 {
    00030   int n = 0, v;
    00031   char *end;
    00032
    00033   for (;;) {
    00034     v = strtol(p, &end, 0);
    00035     if (p == end || n == maxitems) return -1;
    00036     p = end;
    00037     items[n++] = v;
    00038     if (*p == '\0') break;
    00039     if (*p != ',' && *p != ' ') return -1;
    00040     p++;
    00041   }
    00042
    00043   return n;
    00044 }
    00045
    00046
    00047 static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint w, uint bottom, bool show_params)
    00048 {
    00049   char buff[256];
    00050
    00051   if (c->error != NULL) {
    00052     SetDParamStr(0, c->filename);
    00053     SetDParamStr(1, c->error->data);
    00054     for (uint i = 0; i < c->error->num_params; i++) {
    00055       uint32 param = 0;
    00056       byte param_number = c->error->param_number[i];
    00057
    00058       if (param_number < c->num_params) param = c->param[param_number];
    00059
    00060       SetDParam(2 + i, param);
    00061     }
    00062
    00063     char message[512];
    00064     GetString(message, c->error->custom_message != NULL ? BindCString(c->error->custom_message) : c->error->message, lastof(message));
    00065
    00066     SetDParamStr(0, message);
    00067     y += DrawStringMultiLine(x, y, c->error->severity, w, bottom - y);
    00068   }
    00069
    00070   /* Draw filename or not if it is not known (GRF sent over internet) */
    00071   if (c->filename != NULL) {
    00072     SetDParamStr(0, c->filename);
    00073     y += DrawStringMultiLine(x, y, STR_NEWGRF_FILENAME, w, bottom - y);
    00074   }
    00075
    00076   /* Prepare and draw GRF ID */
    00077   snprintf(buff, lengthof(buff), "%08X", BSWAP32(c->grfid));
    00078   SetDParamStr(0, buff);
    00079   y += DrawStringMultiLine(x, y, STR_NEWGRF_GRF_ID, w, bottom - y);
    00080
    00081   /* Prepare and draw MD5 sum */
    00082   md5sumToString(buff, lastof(buff), c->md5sum);
    00083   SetDParamStr(0, buff);
    00084   y += DrawStringMultiLine(x, y, STR_NEWGRF_MD5SUM, w, bottom - y);
    00085
    00086   /* Show GRF parameter list */
    00087   if (show_params) {
    00088     if (c->num_params > 0) {
    00089       GRFBuildParamList(buff, c, lastof(buff));
    00090       SetDParamStr(0, buff);
    00091     } else {
    00092       SetDParam(0, STR_01A9_NONE);
    00093     }
    00094     y += DrawStringMultiLine(x, y, STR_NEWGRF_PARAMETER, w, bottom - y);
    00095   }
    00096
    00097   /* Show flags */
    00098   if (c->status == GCS_NOT_FOUND)        y += DrawStringMultiLine(x, y, STR_NEWGRF_NOT_FOUND, w, bottom - y);
    00099   if (c->status == GCS_DISABLED)         y += DrawStringMultiLine(x, y, STR_NEWGRF_DISABLED, w, bottom - y);
    00100   if (HasBit(c->flags, GCF_COMPATIBLE)) y += DrawStringMultiLine(x, y, STR_NEWGRF_COMPATIBLE_LOADED, w, bottom - y);
    00101
    00102   /* Draw GRF info if it exists */
    00103   if (c->info != NULL && !StrEmpty(c->info)) {
    00104     SetDParamStr(0, c->info);
    00105     y += DrawStringMultiLine(x, y, STR_02BD, w, bottom - y);
    00106   } else {
    00107     y += DrawStringMultiLine(x, y, STR_NEWGRF_NO_INFO, w, bottom - y);
    00108   }
    00109 }
    00110
    00111
    00112 /* Dialogue for adding NewGRF files to the selection */
    00113 struct newgrf_add_d {
    00114   GRFConfig **list;
    00115   const GRFConfig *sel;
    00116 };
    00117
    00118 /* Names of the add a newgrf window widgets */
    00119 enum AddNewGRFWindowWidgets {
    00120   ANGRFW_CLOSEBOX = 0,
    00121   ANGRFW_CAPTION,
    00122   ANGRFW_BACKGROUND,
    00123   ANGRFW_GRF_LIST,
    00124   ANGRFW_SCROLLBAR,
    00125   ANGRFW_GRF_INFO,
    00126   ANGRFW_ADD,
    00127   ANGRFW_RESCAN,
    00128   ANGRFW_RESIZE,
    00129 };
    00130
    00131 static void NewGRFAddDlgWndProc(Window *w, WindowEvent *e)
    00132 {
    00133   switch (e->event) {
    00134     case WE_PAINT: {
    00135       const GRFConfig *c;
    00136       const Widget *wl = &w->widget[ANGRFW_GRF_LIST];
    00137       int n = 0;
    00138
    00139       /* Count the number of GRFs */
    00140       for (c = _all_grfs; c != NULL; c = c->next) n++;
    00141
    00142       w->vscroll.cap = (wl->bottom - wl->top) / 10;
    00143       SetVScrollCount(w, n);
    00144
    00145       w->SetWidgetDisabledState(ANGRFW_ADD, WP(w, newgrf_add_d).sel == NULL || WP(w, newgrf_add_d).sel->IsOpenTTDBaseGRF());
    00146       DrawWindowWidgets(w);
    00147
    00148       GfxFillRect(wl->left + 1, wl->top + 1, wl->right, wl->bottom, 0xD7);
    00149
    00150       uint y = wl->top + 1;
    00151       for (c = _all_grfs, n = 0; c != NULL && n < (w->vscroll.pos + w->vscroll.cap); c = c->next, n++) {
    00152         if (n >= w->vscroll.pos) {
    00153           bool h = c == WP(w, newgrf_add_d).sel;
    00154           const char *text = (c->name != NULL && !StrEmpty(c->name)) ? c->name : c->filename;
    00155
    00156           /* Draw selection background */
    00157           if (h) GfxFillRect(3, y, w->width - 15, y + 9, 156);
    00158           DoDrawStringTruncated(text, 4, y, h ? TC_WHITE : TC_ORANGE, w->width - 18);
    00159           y += 10;
    00160         }
    00161       }
    00162
    00163       if (WP(w, newgrf_add_d).sel != NULL) {
    00164         const Widget *wi = &w->widget[ANGRFW_GRF_INFO];
    00165         ShowNewGRFInfo(WP(w, newgrf_add_d).sel, wi->left + 2, wi->top + 2, wi->right - wi->left - 2, wi->bottom, false);
    00166       }
    00167       break;
    00168     }
    00169
    00170     case WE_DOUBLE_CLICK:
    00171       if (e->we.click.widget != ANGRFW_GRF_LIST) break;
    00172       e->we.click.widget = ANGRFW_ADD;
    00173       /* Fall through */
    00174
    00175     case WE_CLICK:
    00176       switch (e->we.click.widget) {
    00177         case ANGRFW_GRF_LIST: {
    00178           /* Get row... */
    00179           const GRFConfig *c;
    00180           uint i = (e->we.click.pt.y - w->widget[ANGRFW_GRF_LIST].top) / 10 + w->vscroll.pos;
    00181
    00182           for (c = _all_grfs; c != NULL && i > 0; c = c->next, i--) {}
    00183           WP(w, newgrf_add_d).sel = c;
    00184           SetWindowDirty(w);
    00185           break;
    00186         }
    00187
    00188         case ANGRFW_ADD: // Add selection to list
    00189           if (WP(w, newgrf_add_d).sel != NULL) {
    00190             const GRFConfig *src = WP(w, newgrf_add_d).sel;
    00191             GRFConfig **list;
    00192
    00193             /* Find last entry in the list, checking for duplicate grfid on the way */
    00194             for (list = WP(w, newgrf_add_d).list; *list != NULL; list = &(*list)->next) {
    00195               if ((*list)->grfid == src->grfid) {
    00196                 ShowErrorMessage(INVALID_STRING_ID, STR_NEWGRF_DUPLICATE_GRFID, 0, 0);
    00197                 return;
    00198               }
    00199             }
    00200
    00201             /* Copy GRF details from scanned list */
    00202             GRFConfig *c = CallocT<GRFConfig>(1);
    00203             *c = *src;
    00204             c->filename = strdup(src->filename);
    00205             if (src->name      != NULL) c->name      = strdup(src->name);
    00206             if (src->info      != NULL) c->info      = strdup(src->info);
    00207             c->next = NULL;
    00208
    00209             /* Append GRF config to configuration list */
    00210             *list = c;
    00211
    00212             DeleteWindowByClass(WC_SAVELOAD);
    00213             InvalidateWindowData(WC_GAME_OPTIONS, 0);
    00214           }
    00215           break;
    00216
    00217         case ANGRFW_RESCAN: // Rescan list
    00218           WP(w, newgrf_add_d).sel = NULL;
    00219           ScanNewGRFFiles();
    00220           SetWindowDirty(w);
    00221           break;
    00222       }
    00223       break;
    00224   }
    00225 }
    00226
    00227 /* Widget definition for the add a newgrf window */
    00228 static const Widget _newgrf_add_dlg_widgets[] = {
    00229 {   WWT_CLOSEBOX,    RESIZE_NONE, 14,   0,  10,   0,  13, STR_00C5,                STR_018B_CLOSE_WINDOW },           // ANGRFW_CLOSEBOX
    00230 {    WWT_CAPTION,   RESIZE_RIGHT, 14,  11, 306,   0,  13, STR_NEWGRF_ADD_CAPTION,  STR_018C_WINDOW_TITLE_DRAG_THIS }, // ANGRFW_CAPTION
    00231 {      WWT_PANEL,      RESIZE_RB, 14,   0, 294,  14, 121, 0x0,                     STR_NULL },                        // ANGRFW_BACKGROUND
    00232 {      WWT_INSET,      RESIZE_RB, 14,   2, 292,  16, 119, 0x0,                     STR_NULL },                        // ANGRFW_GRF_LIST
    00233 {  WWT_SCROLLBAR,     RESIZE_LRB, 14, 295, 306,  14, 121, 0x0,                     STR_NULL },                        // ANGRFW_SCROLLBAR
    00234 {      WWT_PANEL,     RESIZE_RTB, 14,   0, 306, 122, 224, 0x0,                     STR_NULL },                        // ANGRFW_GRF_INFO
    00235 { WWT_PUSHTXTBTN,     RESIZE_RTB, 14,   0, 146, 225, 236, STR_NEWGRF_ADD_FILE,     STR_NEWGRF_ADD_FILE_TIP },         // ANGRFW_ADD
    00236 { WWT_PUSHTXTBTN,    RESIZE_LRTB, 14, 147, 294, 225, 236, STR_NEWGRF_RESCAN_FILES, STR_NEWGRF_RESCAN_FILES_TIP },     // ANGRFW_RESCAN
    00237 {  WWT_RESIZEBOX,    RESIZE_LRTB, 14, 295, 306, 225, 236, 0x0,                     STR_RESIZE_BUTTON },               // ANGRFW_RESIZE
    00238 {   WIDGETS_END },
    00239 };
    00240
    00241 /* Window definition for the add a newgrf window */
    00242 static const WindowDesc _newgrf_add_dlg_desc = {
    00243   WDP_CENTER, WDP_CENTER, 307, 237, 307, 337,
    00244   WC_SAVELOAD, WC_NONE,
    00245   WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
    00246   _newgrf_add_dlg_widgets,
    00247   NewGRFAddDlgWndProc,
    00248 };
    00249
    00250
    00251 /* 'NewGRF Settings' dialogue */
    00252 struct newgrf_d {
    00253   GRFConfig **orig_list;
    00254   GRFConfig **list;
    00255   GRFConfig *sel;
    00256   bool editable;
    00257   bool show_params;
    00258   bool execute;
    00259 };
    00260 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(newgrf_d));
    00261
    00262
    00263 /* Names of the manage newgrfs window widgets */
    00264 enum ShowNewGRFStateWidgets {
    00265   SNGRFS_CLOSEBOX = 0,
    00266   SNGRFS_CAPTION,
    00267   SNGRFS_BACKGROUND,
    00268   SNGRFS_ADD,
    00269   SNGRFS_REMOVE,
    00270   SNGRFS_MOVE_UP,
    00271   SNGRFS_MOVE_DOWN,
    00272   SNGRFS_FILE_LIST,
    00273   SNGRFS_SCROLLBAR,
    00274   SNGRFS_NEWGRF_INFO,
    00275   SNGRFS_SET_PARAMETERS,
    00276   SNGRFS_APPLY_CHANGES,
    00277   SNGRFS_RESIZE,
    00278 };
    00279
    00280 static void SetupNewGRFState(Window *w)
    00281 {
    00282   bool disable_all = WP(w, newgrf_d).sel == NULL || !WP(w, newgrf_d).editable;
    00283
    00284   w->SetWidgetDisabledState(SNGRFS_ADD, !WP(w, newgrf_d).editable);
    00285   w->SetWidgetsDisabledState(disable_all,
    00286     SNGRFS_REMOVE,
    00287     SNGRFS_MOVE_UP,
    00288     SNGRFS_MOVE_DOWN,
    00289     WIDGET_LIST_END
    00290   );
    00291   w->SetWidgetDisabledState(SNGRFS_SET_PARAMETERS, !WP(w, newgrf_d).show_params || disable_all);
    00292
    00293   if (!disable_all) {
    00294     /* All widgets are now enabled, so disable widgets we can't use */
    00295     if (WP(w, newgrf_d).sel == *WP(w, newgrf_d).list) w->DisableWidget(SNGRFS_MOVE_UP);
    00296     if (WP(w, newgrf_d).sel->next == NULL) w->DisableWidget(SNGRFS_MOVE_DOWN);
    00297     if (WP(w, newgrf_d).sel->IsOpenTTDBaseGRF()) w->DisableWidget(SNGRFS_REMOVE);
    00298   }
    00299 }
    00300
    00301
    00302 static void SetupNewGRFWindow(Window *w)
    00303 {
    00304   const GRFConfig *c;
    00305   int i;
    00306
    00307   for (c = *WP(w, newgrf_d).list, i = 0; c != NULL; c = c->next, i++) {}
    00308
    00309   w->vscroll.cap = (w->widget[SNGRFS_FILE_LIST].bottom - w->widget[SNGRFS_FILE_LIST].top) / 14 + 1;
    00310   SetVScrollCount(w, i);
    00311   w->SetWidgetDisabledState(SNGRFS_APPLY_CHANGES, !WP(w, newgrf_d).editable);
    00312 }
    00313
    00314
    00319 static void NewGRFConfirmationCallback(Window *w, bool confirmed)
    00320 {
    00321   if (confirmed) {
    00322     newgrf_d *nd = &WP(w, newgrf_d);
    00323     GRFConfig *c;
    00324     int i = 0;
    00325
    00326     CopyGRFConfigList(nd->orig_list, *nd->list, false);
    00327     ReloadNewGRFData();
    00328
    00329     /* Show new, updated list */
    00330     for (c = *nd->list; c != NULL && c != nd->sel; c = c->next, i++) {}
    00331     CopyGRFConfigList(nd->list, *nd->orig_list, false);
    00332     for (c = *nd->list; c != NULL && i > 0; c = c->next, i--) {}
    00333     nd->sel = c;
    00334
    00335     SetWindowDirty(w);
    00336   }
    00337 }
    00338
    00339
    00340 static void NewGRFWndProc(Window *w, WindowEvent *e)
    00341 {
    00342   switch (e->event) {
    00343     case WE_PAINT: {
    00344       const GRFConfig *c;
    00345       int i, y;
    00346
    00347       SetupNewGRFState(w);
    00348
    00349       DrawWindowWidgets(w);
    00350
    00351       /* Draw NewGRF list */
    00352       y = w->widget[SNGRFS_FILE_LIST].top;
    00353       for (c = *WP(w, newgrf_d).list, i = 0; c != NULL; c = c->next, i++) {
    00354         if (i >= w->vscroll.pos && i < w->vscroll.pos + w->vscroll.cap) {
    00355           const char *text = (c->name != NULL && !StrEmpty(c->name)) ? c->name : c->filename;
    00356           SpriteID pal;
    00357           byte txtoffset;
    00358
    00359           /* Pick a colour */
    00360           switch (c->status) {
    00361             case GCS_NOT_FOUND:
    00362             case GCS_DISABLED:
    00363               pal = PALETTE_TO_RED;
    00364               break;
    00365             case GCS_ACTIVATED:
    00366               pal = PALETTE_TO_GREEN;
    00367               break;
    00368             default:
    00369               pal = PALETTE_TO_BLUE;
    00370               break;
    00371           }
    00372
    00373           /* Do not show a "not-failure" colour when it actually failed to load */
    00374           if (pal != PALETTE_TO_RED) {
    00375             if (HasBit(c->flags, GCF_STATIC)) {
    00376               pal = PALETTE_TO_GREY;
    00377             } else if (HasBit(c->flags, GCF_COMPATIBLE)) {
    00378               pal = PALETTE_TO_ORANGE;
    00379             }
    00380           }
    00381
    00382           DrawSprite(SPR_SQUARE, pal, 5, y + 2);
    00383           if (c->error != NULL) DrawSprite(SPR_WARNING_SIGN, 0, 20, y + 2);
    00384           txtoffset = c->error != NULL ? 35 : 25;
    00385           DoDrawStringTruncated(text, txtoffset, y + 3, WP(w, newgrf_d).sel == c ? TC_WHITE : TC_BLACK, w->width - txtoffset - 10);
    00386           y += 14;
    00387         }
    00388       }
    00389
    00390       if (WP(w, newgrf_d).sel != NULL) {
    00391         /* Draw NewGRF file info */
    00392         const Widget *wi = &w->widget[SNGRFS_NEWGRF_INFO];
    00393         ShowNewGRFInfo(WP(w, newgrf_d).sel, wi->left + 2, wi->top + 2, wi->right - wi->left - 2, wi->bottom, WP(w, newgrf_d).show_params);
    00394       }
    00395
    00396       break;
    00397     }
    00398
    00399     case WE_INVALIDATE_DATA:
    00400       SetupNewGRFWindow(w);
    00401       break;
    00402
    00403     case WE_CLICK:
    00404       switch (e->we.click.widget) {
    00405         case SNGRFS_ADD: { // Add GRF
    00406           GRFConfig **list = WP(w, newgrf_d).list;
    00407           Window *w;
    00408
    00409           DeleteWindowByClass(WC_SAVELOAD);
    00410           w = AllocateWindowDesc(&_newgrf_add_dlg_desc);
    00411           w->resize.step_height = 10;
    00412
    00413           WP(w, newgrf_add_d).list = list;
    00414           break;
    00415         }
    00416
    00417         case SNGRFS_REMOVE: { // Remove GRF
    00418           GRFConfig **pc, *c, *newsel;
    00419
    00420           /* Choose the next GRF file to be the selected file */
    00421           newsel = WP(w, newgrf_d).sel->next;
    00422
    00423           for (pc = WP(w, newgrf_d).list; (c = *pc) != NULL; pc = &c->next) {
    00424             /* If the new selection is empty (i.e. we're deleting the last item
    00425              * in the list, pick the file just before the selected file */
    00426             if (newsel == NULL && c->next == WP(w, newgrf_d).sel) newsel = c;
    00427
    00428             if (c == WP(w, newgrf_d).sel) {
    00429               *pc = c->next;
    00430               free(c);
    00431               break;
    00432             }
    00433           }
    00434
    00435           WP(w, newgrf_d).sel = newsel;
    00436           SetupNewGRFWindow(w);
    00437           SetWindowDirty(w);
    00438           break;
    00439         }
    00440
    00441         case SNGRFS_MOVE_UP: { // Move GRF up
    00442           GRFConfig **pc, *c;
    00443           if (WP(w, newgrf_d).sel == NULL) break;
    00444
    00445           for (pc = WP(w, newgrf_d).list; (c = *pc) != NULL; pc = &c->next) {
    00446             if (c->next == WP(w, newgrf_d).sel) {
    00447               c->next = WP(w, newgrf_d).sel->next;
    00448               WP(w, newgrf_d).sel->next = c;
    00449               *pc = WP(w, newgrf_d).sel;
    00450               break;
    00451             }
    00452           }
    00453           SetWindowDirty(w);
    00454           break;
    00455         }
    00456
    00457         case SNGRFS_MOVE_DOWN: { // Move GRF down
    00458           GRFConfig **pc, *c;
    00459           if (WP(w, newgrf_d).sel == NULL) break;
    00460
    00461           for (pc = WP(w, newgrf_d).list; (c = *pc) != NULL; pc = &c->next) {
    00462             if (c == WP(w, newgrf_d).sel) {
    00463               *pc = c->next;
    00464               c->next = c->next->next;
    00465               (*pc)->next = c;
    00466               break;
    00467             }
    00468           }
    00469           SetWindowDirty(w);
    00470           break;
    00471         }
    00472
    00473         case SNGRFS_FILE_LIST: { // Select a GRF
    00474           GRFConfig *c;
    00475           uint i = (e->we.click.pt.y - w->widget[SNGRFS_FILE_LIST].top) / 14 + w->vscroll.pos;
    00476
    00477           for (c = *WP(w, newgrf_d).list; c != NULL && i > 0; c = c->next, i--) {}
    00478           WP(w, newgrf_d).sel = c;
    00479
    00480           SetWindowDirty(w);
    00481           break;
    00482         }
    00483
    00484         case SNGRFS_APPLY_CHANGES: // Apply changes made to GRF list
    00485           if (WP(w, newgrf_d).execute) {
    00486             ShowQuery(
    00487               STR_POPUP_CAUTION_CAPTION,
    00488               STR_NEWGRF_CONFIRMATION_TEXT,
    00489               w,
    00490               NewGRFConfirmationCallback
    00491             );
    00492           } else {
    00493             CopyGRFConfigList(WP(w, newgrf_d).orig_list, *WP(w, newgrf_d).list, true);
    00494             ResetGRFConfig(false);
    00495             ReloadNewGRFData();
    00496           }
    00497           break;
    00498
    00499         case SNGRFS_SET_PARAMETERS: { // Edit parameters
    00500           char buff[512];
    00501           if (WP(w, newgrf_d).sel == NULL) break;
    00502
    00503           GRFBuildParamList(buff, WP(w, newgrf_d).sel, lastof(buff));
    00504           ShowQueryString(BindCString(buff), STR_NEWGRF_PARAMETER_QUERY, 63, 250, w, CS_ALPHANUMERAL);
    00505           break;
    00506         }
    00507       }
    00508       break;
    00509
    00510     case WE_ON_EDIT_TEXT:
    00511       if (e->we.edittext.str != NULL) {
    00512         /* Parse our new "int list" */
    00513         GRFConfig *c = WP(w, newgrf_d).sel;
    00514         c->num_params = parse_intlist(e->we.edittext.str, (int*)c->param, lengthof(c->param));
    00515
    00516         /* parse_intlist returns -1 on error */
    00517         if (c->num_params == (byte)-1) c->num_params = 0;
    00518       }
    00519       SetWindowDirty(w);
    00520       break;
    00521
    00522     case WE_DESTROY:
    00523       if (!WP(w, newgrf_d).execute) {
    00524         CopyGRFConfigList(WP(w, newgrf_d).orig_list, *WP(w, newgrf_d).list, true);
    00525         ResetGRFConfig(false);
    00526         ReloadNewGRFData();
    00527       }
    00528       /* Remove the temporary copy of grf-list used in window */
    00529       ClearGRFConfigList(WP(w, newgrf_d).list);
    00530       break;
    00531
    00532     case WE_RESIZE:
    00533       if (e->we.sizing.diff.x != 0) {
    00534         ResizeButtons(w, SNGRFS_ADD, SNGRFS_MOVE_DOWN);
    00535         ResizeButtons(w, SNGRFS_SET_PARAMETERS, SNGRFS_APPLY_CHANGES);
    00536       }
    00537       w->vscroll.cap += e->we.sizing.diff.y / 14;
    00538       w->widget[SNGRFS_FILE_LIST].data = (w->vscroll.cap << 8) + 1;
    00539       SetupNewGRFWindow(w);
    00540       break;
    00541   }
    00542 }
    00543
    00544 /* Widget definition of the manage newgrfs window */
    00545 static const Widget _newgrf_widgets[] = {
    00546 {   WWT_CLOSEBOX,  RESIZE_NONE, 10,   0,  10,   0,  13, STR_00C5,                    STR_018B_CLOSE_WINDOW },            // SNGRFS_CLOSEBOX
    00547 {    WWT_CAPTION, RESIZE_RIGHT, 10,  11, 299,   0,  13, STR_NEWGRF_SETTINGS_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS },  // SNGRFS_CAPTION
    00548 {      WWT_PANEL, RESIZE_RIGHT, 10,   0, 299,  14,  29, STR_NULL,                    STR_NULL },                         // SNGRFS_BACKGROUND
    00549 { WWT_PUSHTXTBTN,  RESIZE_NONE,  3,  10,  79,  16,  27, STR_NEWGRF_ADD,              STR_NEWGRF_ADD_TIP },               // SNGRFS_ADD
    00550 { WWT_PUSHTXTBTN,  RESIZE_NONE,  3,  80, 149,  16,  27, STR_NEWGRF_REMOVE,           STR_NEWGRF_REMOVE_TIP },            // SNGRFS_REMOVE
    00551 { WWT_PUSHTXTBTN,  RESIZE_NONE,  3, 150, 219,  16,  27, STR_NEWGRF_MOVEUP,           STR_NEWGRF_MOVEUP_TIP },            // SNGRFS_MOVE_UP
    00552 { WWT_PUSHTXTBTN, RESIZE_RIGHT,  3, 220, 289,  16,  27, STR_NEWGRF_MOVEDOWN,         STR_NEWGRF_MOVEDOWN_TIP },          // SNGRFS_MOVE_DOWN
    00553 {     WWT_MATRIX,    RESIZE_RB, 10,   0, 287,  30,  99, 0x501,                       STR_NEWGRF_FILE_TIP },              // SNGRFS_FILE_LIST
    00554 {  WWT_SCROLLBAR,   RESIZE_LRB, 10, 288, 299,  30,  99, 0x0,                         STR_0190_SCROLL_BAR_SCROLLS_LIST }, // SNGRFS_SCROLLBAR
    00555 {      WWT_PANEL,   RESIZE_RTB, 10,   0, 299, 100, 212, STR_NULL,                    STR_NULL },                         // SNGRFS_NEWGRF_INFO
    00556 { WWT_PUSHTXTBTN,    RESIZE_TB, 10,   0, 143, 213, 224, STR_NEWGRF_SET_PARAMETERS,   STR_NULL },                         // SNGRFS_SET_PARAMETERS
    00557 { WWT_PUSHTXTBTN,   RESIZE_RTB, 10, 144, 287, 213, 224, STR_NEWGRF_APPLY_CHANGES,    STR_NULL },                         // SNGRFS_APPLY_CHANGES
    00558 {  WWT_RESIZEBOX,  RESIZE_LRTB, 10, 288, 299, 213, 224, 0x0,                         STR_RESIZE_BUTTON },                // SNGRFS_RESIZE
    00559 { WIDGETS_END },
    00560 };
    00561
    00562 /* Window definition of the manage newgrfs window */
    00563 static const WindowDesc _newgrf_desc = {
    00564   WDP_CENTER, WDP_CENTER, 300, 225, 300, 225,
    00565   WC_GAME_OPTIONS, WC_NONE,
    00566   WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
    00567   _newgrf_widgets,
    00568   NewGRFWndProc,
    00569 };
    00570
    00571
    00578 void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfig **config)
    00579 {
    00580   static GRFConfig *local = NULL;
    00581   Window *w;
    00582
    00583   DeleteWindowByClass(WC_GAME_OPTIONS);
    00584   w = AllocateWindowDesc(&_newgrf_desc);
    00585   if (w == NULL) return;
    00586
    00587   w->resize.step_height = 14;
    00588   CopyGRFConfigList(&local, *config, false);
    00589
    00590   /* Clear selections */
    00591   WP(w, newgrf_d).sel         = NULL;
    00592   WP(w, newgrf_d).list        = &local;
    00593   WP(w, newgrf_d).orig_list   = config;
    00594   WP(w, newgrf_d).editable    = editable;
    00595   WP(w, newgrf_d).execute     = exec_changes;
    00596   WP(w, newgrf_d).show_params = show_params;
    00597
    00598   SetupNewGRFWindow(w);
    00599 }