newgrf_gui.cpp

Go to the documentation of this file.
00001 /* $Id: newgrf_gui.cpp 16247 2009-05-06 22:37:19Z rubidium $ */
00002 
00005 #include "stdafx.h"
00006 #include "gui.h"
00007 #include "window_gui.h"
00008 #include "textbuf_gui.h"
00009 #include "newgrf.h"
00010 #include "strings_func.h"
00011 #include "window_func.h"
00012 #include "string_func.h"
00013 #include "gfx_func.h"
00014 #include "gamelog.h"
00015 #include "settings_func.h"
00016 #include "widgets/dropdown_type.h"
00017 #include "network/network.h"
00018 #include "network/network_content.h"
00019 
00020 #include "table/strings.h"
00021 #include "table/sprites.h"
00022 
00029 static int parse_intlist(const char *p, int *items, int maxitems)
00030 {
00031   int n = 0, v;
00032   char *end;
00033 
00034   for (;;) {
00035     v = strtol(p, &end, 0);
00036     if (p == end || n == maxitems) return -1;
00037     p = end;
00038     items[n++] = v;
00039     if (*p == '\0') break;
00040     if (*p != ',' && *p != ' ') return -1;
00041     p++;
00042   }
00043 
00044   return n;
00045 }
00046 
00047 
00048 static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint w, uint bottom, bool show_params)
00049 {
00050   char buff[256];
00051 
00052   if (c->error != NULL) {
00053     char message[512];
00054     SetDParamStr(0, c->error->custom_message); // is skipped by built-in messages
00055     SetDParam   (1, STR_JUST_RAW_STRING);
00056     SetDParamStr(2, c->filename);
00057     SetDParam   (3, STR_JUST_RAW_STRING);
00058     SetDParamStr(4, c->error->data);
00059     for (uint i = 0; i < c->error->num_params; i++) {
00060       SetDParam(5 + i, c->error->param_value[i]);
00061     }
00062     GetString(message, c->error->custom_message == NULL ? c->error->message : STR_JUST_RAW_STRING, lastof(message));
00063 
00064     SetDParamStr(0, message);
00065     y += DrawStringMultiLine(x, y, c->error->severity, w, bottom - y);
00066   }
00067 
00068   /* Draw filename or not if it is not known (GRF sent over internet) */
00069   if (c->filename != NULL) {
00070     SetDParamStr(0, c->filename);
00071     y += DrawStringMultiLine(x, y, STR_NEWGRF_FILENAME, w, bottom - y);
00072   }
00073 
00074   /* Prepare and draw GRF ID */
00075   snprintf(buff, lengthof(buff), "%08X", BSWAP32(c->grfid));
00076   SetDParamStr(0, buff);
00077   y += DrawStringMultiLine(x, y, STR_NEWGRF_GRF_ID, w, bottom - y);
00078 
00079   /* Prepare and draw MD5 sum */
00080   md5sumToString(buff, lastof(buff), c->md5sum);
00081   SetDParamStr(0, buff);
00082   y += DrawStringMultiLine(x, y, STR_NEWGRF_MD5SUM, w, bottom - y);
00083 
00084   /* Show GRF parameter list */
00085   if (show_params) {
00086     if (c->num_params > 0) {
00087       GRFBuildParamList(buff, c, lastof(buff));
00088       SetDParam(0, STR_JUST_RAW_STRING);
00089       SetDParamStr(1, buff);
00090     } else {
00091       SetDParam(0, STR_01A9_NONE);
00092     }
00093     y += DrawStringMultiLine(x, y, STR_NEWGRF_PARAMETER, w, bottom - y);
00094 
00095     /* Draw the palette of the NewGRF */
00096     SetDParamStr(0, c->windows_paletted ? "Windows" : "DOS");
00097     y += DrawStringMultiLine(x, y, STR_NEWGRF_PALETTE, w, bottom - y);
00098   }
00099 
00100   /* Show flags */
00101   if (c->status == GCS_NOT_FOUND)        y += DrawStringMultiLine(x, y, STR_NEWGRF_NOT_FOUND, w, bottom - y);
00102   if (c->status == GCS_DISABLED)         y += DrawStringMultiLine(x, y, STR_NEWGRF_DISABLED, w, bottom - y);
00103   if (HasBit(c->flags, GCF_COMPATIBLE)) y += DrawStringMultiLine(x, y, STR_NEWGRF_COMPATIBLE_LOADED, w, bottom - y);
00104 
00105   /* Draw GRF info if it exists */
00106   if (c->info != NULL && !StrEmpty(c->info)) {
00107     SetDParam(0, STR_JUST_RAW_STRING);
00108     SetDParamStr(1, c->info);
00109     y += DrawStringMultiLine(x, y, STR_02BD, w, bottom - y);
00110   } else {
00111     y += DrawStringMultiLine(x, y, STR_NEWGRF_NO_INFO, w, bottom - y);
00112   }
00113 }
00114 
00115 
00119 struct NewGRFAddWindow : public Window {
00120   /* Names of the add a newgrf window widgets */
00121   enum AddNewGRFWindowWidgets {
00122     ANGRFW_CLOSEBOX = 0,
00123     ANGRFW_CAPTION,
00124     ANGRFW_BACKGROUND,
00125     ANGRFW_GRF_LIST,
00126     ANGRFW_SCROLLBAR,
00127     ANGRFW_GRF_INFO,
00128     ANGRFW_ADD,
00129     ANGRFW_RESCAN,
00130     ANGRFW_RESIZE,
00131   };
00132 
00133   GRFConfig **list;
00134   const GRFConfig *sel;
00135 
00136   NewGRFAddWindow(const WindowDesc *desc, GRFConfig **list) : Window(desc, 0)
00137   {
00138     this->list = list;
00139     this->resize.step_height = 10;
00140 
00141     this->FindWindowPlacementAndResize(desc);
00142   }
00143 
00144   virtual void OnPaint()
00145   {
00146     const GRFConfig *c;
00147     const Widget *wl = &this->widget[ANGRFW_GRF_LIST];
00148     int n = 0;
00149 
00150     /* Count the number of GRFs */
00151     for (c = _all_grfs; c != NULL; c = c->next) n++;
00152 
00153     this->vscroll.cap = (wl->bottom - wl->top) / 10;
00154     SetVScrollCount(this, n);
00155 
00156     this->SetWidgetDisabledState(ANGRFW_ADD, this->sel == NULL || this->sel->IsOpenTTDBaseGRF());
00157     this->DrawWidgets();
00158 
00159     GfxFillRect(wl->left + 1, wl->top + 1, wl->right, wl->bottom, 0xD7);
00160 
00161     uint y = wl->top + 1;
00162     for (c = _all_grfs, n = 0; c != NULL && n < (this->vscroll.pos + this->vscroll.cap); c = c->next, n++) {
00163       if (n >= this->vscroll.pos) {
00164         bool h = c == this->sel;
00165         const char *text = (c->name != NULL && !StrEmpty(c->name)) ? c->name : c->filename;
00166 
00167         /* Draw selection background */
00168         if (h) GfxFillRect(3, y, this->width - 15, y + 9, 156);
00169         DoDrawStringTruncated(text, 4, y, h ? TC_WHITE : TC_ORANGE, this->width - 18);
00170         y += 10;
00171       }
00172     }
00173 
00174     if (this->sel != NULL) {
00175       const Widget *wi = &this->widget[ANGRFW_GRF_INFO];
00176       ShowNewGRFInfo(this->sel, wi->left + 2, wi->top + 2, wi->right - wi->left - 2, wi->bottom, false);
00177     }
00178   }
00179 
00180   virtual void OnDoubleClick(Point pt, int widget)
00181   {
00182     if (widget == ANGRFW_GRF_LIST) this->OnClick(pt, ANGRFW_ADD);
00183   }
00184 
00185   virtual void OnClick(Point pt, int widget)
00186   {
00187     switch (widget) {
00188       case ANGRFW_GRF_LIST: {
00189         /* Get row... */
00190         const GRFConfig *c;
00191         uint i = (pt.y - this->widget[ANGRFW_GRF_LIST].top) / 10 + this->vscroll.pos;
00192 
00193         for (c = _all_grfs; c != NULL && i > 0; c = c->next, i--) {}
00194         this->sel = c;
00195         this->SetDirty();
00196         break;
00197       }
00198 
00199       case ANGRFW_ADD: // Add selection to list
00200         if (this->sel != NULL) {
00201           const GRFConfig *src = this->sel;
00202           GRFConfig **list;
00203 
00204           /* Find last entry in the list, checking for duplicate grfid on the way */
00205           for (list = this->list; *list != NULL; list = &(*list)->next) {
00206             if ((*list)->grfid == src->grfid) {
00207               ShowErrorMessage(INVALID_STRING_ID, STR_NEWGRF_DUPLICATE_GRFID, 0, 0);
00208               return;
00209             }
00210           }
00211 
00212           /* Copy GRF details from scanned list */
00213           GRFConfig *c = CallocT<GRFConfig>(1);
00214           *c = *src;
00215           c->filename = strdup(src->filename);
00216           if (src->name      != NULL) c->name      = strdup(src->name);
00217           if (src->info      != NULL) c->info      = strdup(src->info);
00218           c->next = NULL;
00219 
00220           /* Append GRF config to configuration list */
00221           *list = c;
00222 
00223           DeleteWindowByClass(WC_SAVELOAD);
00224           InvalidateWindowData(WC_GAME_OPTIONS, 0);
00225         }
00226         break;
00227 
00228       case ANGRFW_RESCAN: // Rescan list
00229         this->sel = NULL;
00230         ScanNewGRFFiles();
00231         this->SetDirty();
00232         break;
00233     }
00234   }
00235 };
00236 
00237 /* Widget definition for the add a newgrf window */
00238 static const Widget _newgrf_add_dlg_widgets[] = {
00239 {   WWT_CLOSEBOX,    RESIZE_NONE,  COLOUR_GREY,   0,  10,   0,  13, STR_00C5,                STR_018B_CLOSE_WINDOW },           // ANGRFW_CLOSEBOX
00240 {    WWT_CAPTION,   RESIZE_RIGHT,  COLOUR_GREY,  11, 306,   0,  13, STR_NEWGRF_ADD_CAPTION,  STR_018C_WINDOW_TITLE_DRAG_THIS }, // ANGRFW_CAPTION
00241 {      WWT_PANEL,      RESIZE_RB,  COLOUR_GREY,   0, 294,  14, 121, 0x0,                     STR_NULL },                        // ANGRFW_BACKGROUND
00242 {      WWT_INSET,      RESIZE_RB,  COLOUR_GREY,   2, 292,  16, 119, 0x0,                     STR_NULL },                        // ANGRFW_GRF_LIST
00243 {  WWT_SCROLLBAR,     RESIZE_LRB,  COLOUR_GREY, 295, 306,  14, 121, 0x0,                     STR_NULL },                        // ANGRFW_SCROLLBAR
00244 {      WWT_PANEL,     RESIZE_RTB,  COLOUR_GREY,   0, 306, 122, 224, 0x0,                     STR_NULL },                        // ANGRFW_GRF_INFO
00245 { WWT_PUSHTXTBTN,     RESIZE_RTB,  COLOUR_GREY,   0, 146, 225, 236, STR_NEWGRF_ADD_FILE,     STR_NEWGRF_ADD_FILE_TIP },         // ANGRFW_ADD
00246 { WWT_PUSHTXTBTN,    RESIZE_LRTB,  COLOUR_GREY, 147, 294, 225, 236, STR_NEWGRF_RESCAN_FILES, STR_NEWGRF_RESCAN_FILES_TIP },     // ANGRFW_RESCAN
00247 {  WWT_RESIZEBOX,    RESIZE_LRTB,  COLOUR_GREY, 295, 306, 225, 236, 0x0,                     STR_RESIZE_BUTTON },               // ANGRFW_RESIZE
00248 {   WIDGETS_END },
00249 };
00250 
00251 /* Window definition for the add a newgrf window */
00252 static const WindowDesc _newgrf_add_dlg_desc(
00253   WDP_CENTER, WDP_CENTER, 307, 237, 307, 337,
00254   WC_SAVELOAD, WC_NONE,
00255   WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
00256   _newgrf_add_dlg_widgets
00257 );
00258 
00259 static GRFPresetList _grf_preset_list;
00260 
00261 class DropDownListPresetItem : public DropDownListItem {
00262 public:
00263   DropDownListPresetItem(int result) : DropDownListItem(result, false) {}
00264 
00265   virtual ~DropDownListPresetItem() {}
00266 
00267   bool Selectable() const
00268   {
00269     return true;
00270   }
00271 
00272   void Draw(int x, int y, uint width, uint height, bool sel, int bg_colour) const
00273   {
00274     DoDrawStringTruncated(_grf_preset_list[this->result], x + 2, y, sel ? TC_WHITE : TC_BLACK, x + width);
00275   }
00276 };
00277 
00278 static void NewGRFConfirmationCallback(Window *w, bool confirmed);
00279 
00283 struct NewGRFWindow : public Window {
00284   /* Names of the manage newgrfs window widgets */
00285   enum ShowNewGRFStateWidgets {
00286     SNGRFS_CLOSEBOX = 0,
00287     SNGRFS_CAPTION,
00288     SNGRFS_BACKGROUND1,
00289     SNGRFS_PRESET_LIST,
00290     SNGRFS_PRESET_SAVE,
00291     SNGRFS_PRESET_DELETE,
00292     SNGRFS_BACKGROUND2,
00293     SNGRFS_ADD,
00294     SNGRFS_REMOVE,
00295     SNGRFS_MOVE_UP,
00296     SNGRFS_MOVE_DOWN,
00297     SNGRFS_FILE_LIST,
00298     SNGRFS_SCROLLBAR,
00299     SNGRFS_NEWGRF_INFO,
00300     SNGRFS_SET_PARAMETERS,
00301     SNGRFS_TOGGLE_PALETTE,
00302     SNGRFS_APPLY_CHANGES,
00303     SNGRFS_CONTENT_DOWNLOAD,
00304     SNGRFS_RESIZE,
00305   };
00306 
00307   GRFConfig **orig_list; 
00308   GRFConfig *list;       
00309   GRFConfig *sel;        
00310   bool editable;         
00311   bool show_params;      
00312   bool execute;          
00313   int query_widget;      
00314   int preset;            
00315 
00316   NewGRFWindow(const WindowDesc *desc, bool editable, bool show_params, bool exec_changes, GRFConfig **config) : Window(desc, 0)
00317   {
00318     this->resize.step_height = 14;
00319     this->sel         = NULL;
00320     this->list        = NULL;
00321     this->orig_list   = config;
00322     this->editable    = editable;
00323     this->execute     = exec_changes;
00324     this->show_params = show_params;
00325     this->preset      = -1;
00326 
00327     CopyGRFConfigList(&this->list, *config, false);
00328     GetGRFPresetList(&_grf_preset_list);
00329 
00330     this->FindWindowPlacementAndResize(desc);
00331     this->SetupNewGRFWindow();
00332   }
00333 
00334   ~NewGRFWindow()
00335   {
00336     if (this->editable && !this->execute) {
00337       CopyGRFConfigList(this->orig_list, this->list, true);
00338       ResetGRFConfig(false);
00339       ReloadNewGRFData();
00340     }
00341 
00342     /* Remove the temporary copy of grf-list used in window */
00343     ClearGRFConfigList(&this->list);
00344     _grf_preset_list.Clear();
00345   }
00346 
00347   void SetupNewGRFWindow()
00348   {
00349     const GRFConfig *c;
00350     int i;
00351 
00352     for (c = this->list, i = 0; c != NULL; c = c->next, i++) {}
00353 
00354     this->vscroll.cap = (this->widget[SNGRFS_FILE_LIST].bottom - this->widget[SNGRFS_FILE_LIST].top) / 14 + 1;
00355     SetVScrollCount(this, i);
00356 
00357     this->SetWidgetsDisabledState(!this->editable,
00358       SNGRFS_PRESET_LIST,
00359       SNGRFS_ADD,
00360       SNGRFS_APPLY_CHANGES,
00361       SNGRFS_TOGGLE_PALETTE,
00362       WIDGET_LIST_END
00363     );
00364   }
00365 
00366   virtual void OnPaint()
00367   {
00368     bool disable_all = this->sel == NULL || !this->editable;
00369 
00370     this->SetWidgetsDisabledState(disable_all,
00371       SNGRFS_REMOVE,
00372       SNGRFS_MOVE_UP,
00373       SNGRFS_MOVE_DOWN,
00374       WIDGET_LIST_END
00375     );
00376     this->SetWidgetDisabledState(SNGRFS_SET_PARAMETERS, !this->show_params || disable_all);
00377     this->SetWidgetDisabledState(SNGRFS_TOGGLE_PALETTE, disable_all);
00378 
00379     if (!disable_all) {
00380       /* All widgets are now enabled, so disable widgets we can't use */
00381       if (this->sel == this->list)       this->DisableWidget(SNGRFS_MOVE_UP);
00382       if (this->sel->next == NULL)       this->DisableWidget(SNGRFS_MOVE_DOWN);
00383       if (this->sel->IsOpenTTDBaseGRF()) this->DisableWidget(SNGRFS_REMOVE);
00384     }
00385 
00386     if (this->preset == -1) {
00387       this->widget[SNGRFS_PRESET_LIST].data = STR_02BF_CUSTOM;
00388     } else {
00389       SetDParamStr(0, _grf_preset_list[this->preset]);
00390       this->widget[SNGRFS_PRESET_LIST].data = STR_JUST_RAW_STRING;
00391     }
00392     this->SetWidgetDisabledState(SNGRFS_PRESET_DELETE, this->preset == -1);
00393 
00394     bool has_missing = false;
00395     bool has_compatible = false;
00396     for (const GRFConfig *c = this->list; !has_missing && c != NULL; c = c->next) {
00397       has_missing    |= c->status == GCS_NOT_FOUND;
00398       has_compatible |= HasBit(c->flags, GCF_COMPATIBLE);
00399     }
00400     if (has_missing || has_compatible) {
00401       this->widget[SNGRFS_CONTENT_DOWNLOAD].data     = STR_CONTENT_INTRO_MISSING_BUTTON;
00402       this->widget[SNGRFS_CONTENT_DOWNLOAD].tooltips = STR_CONTENT_INTRO_MISSING_BUTTON_TIP;
00403     } else {
00404       this->widget[SNGRFS_CONTENT_DOWNLOAD].data     = STR_CONTENT_INTRO_BUTTON;
00405       this->widget[SNGRFS_CONTENT_DOWNLOAD].tooltips = STR_CONTENT_INTRO_BUTTON_TIP;
00406     }
00407     this->SetWidgetDisabledState(SNGRFS_PRESET_SAVE, has_missing);
00408 
00409     this->DrawWidgets();
00410 
00411     /* Draw NewGRF list */
00412     int y = this->widget[SNGRFS_FILE_LIST].top;
00413     int i = 0;
00414     for (const GRFConfig *c = this->list; c != NULL; c = c->next, i++) {
00415       if (i >= this->vscroll.pos && i < this->vscroll.pos + this->vscroll.cap) {
00416         const char *text = (c->name != NULL && !StrEmpty(c->name)) ? c->name : c->filename;
00417         SpriteID pal;
00418         byte txtoffset;
00419 
00420         /* Pick a colour */
00421         switch (c->status) {
00422           case GCS_NOT_FOUND:
00423           case GCS_DISABLED:
00424             pal = PALETTE_TO_RED;
00425             break;
00426           case GCS_ACTIVATED:
00427             pal = PALETTE_TO_GREEN;
00428             break;
00429           default:
00430             pal = PALETTE_TO_BLUE;
00431             break;
00432         }
00433 
00434         /* Do not show a "not-failure" colour when it actually failed to load */
00435         if (pal != PALETTE_TO_RED) {
00436           if (HasBit(c->flags, GCF_STATIC)) {
00437             pal = PALETTE_TO_GREY;
00438           } else if (HasBit(c->flags, GCF_COMPATIBLE)) {
00439             pal = PALETTE_TO_ORANGE;
00440           }
00441         }
00442 
00443         DrawSprite(SPR_SQUARE, pal, 5, y + 2);
00444         if (c->error != NULL) DrawSprite(SPR_WARNING_SIGN, 0, 20, y + 2);
00445         txtoffset = c->error != NULL ? 35 : 25;
00446         DoDrawStringTruncated(text, txtoffset, y + 3, this->sel == c ? TC_WHITE : TC_BLACK, this->width - txtoffset - 10);
00447         y += 14;
00448       }
00449     }
00450 
00451     if (this->sel != NULL) {
00452       /* Draw NewGRF file info */
00453       const Widget *wi = &this->widget[SNGRFS_NEWGRF_INFO];
00454       ShowNewGRFInfo(this->sel, wi->left + 2, wi->top + 2, wi->right - wi->left - 2, wi->bottom, this->show_params);
00455     }
00456   }
00457 
00458   virtual void OnClick(Point pt, int widget)
00459   {
00460     switch (widget) {
00461       case SNGRFS_PRESET_LIST: {
00462         DropDownList *list = new DropDownList();
00463 
00464         /* Add 'None' option for clearing list */
00465         list->push_back(new DropDownListStringItem(STR_NONE, -1, false));
00466 
00467         for (uint i = 0; i < _grf_preset_list.Length(); i++) {
00468           if (_grf_preset_list[i] != NULL) {
00469             list->push_back(new DropDownListPresetItem(i));
00470           }
00471         }
00472 
00473         ShowDropDownList(this, list, this->preset, SNGRFS_PRESET_LIST);
00474         break;
00475       }
00476 
00477       case SNGRFS_PRESET_SAVE:
00478         this->query_widget = widget;
00479         ShowQueryString(STR_EMPTY, STR_NEWGRF_PRESET_SAVE_QUERY, 32, 100, this, CS_ALPHANUMERAL, QSF_NONE);
00480         break;
00481 
00482       case SNGRFS_PRESET_DELETE:
00483         if (this->preset == -1) return;
00484 
00485         DeleteGRFPresetFromConfig(_grf_preset_list[this->preset]);
00486         GetGRFPresetList(&_grf_preset_list);
00487         this->preset = -1;
00488         this->SetDirty();
00489         break;
00490 
00491       case SNGRFS_ADD: // Add GRF
00492         DeleteWindowByClass(WC_SAVELOAD);
00493         new NewGRFAddWindow(&_newgrf_add_dlg_desc, &this->list);
00494         break;
00495 
00496       case SNGRFS_REMOVE: { // Remove GRF
00497         GRFConfig **pc, *c, *newsel;
00498 
00499         /* Choose the next GRF file to be the selected file */
00500         newsel = this->sel->next;
00501 
00502         for (pc = &this->list; (c = *pc) != NULL; pc = &c->next) {
00503           /* If the new selection is empty (i.e. we're deleting the last item
00504            * in the list, pick the file just before the selected file */
00505           if (newsel == NULL && c->next == this->sel) newsel = c;
00506 
00507           if (c == this->sel) {
00508             *pc = c->next;
00509             free(c);
00510             break;
00511           }
00512         }
00513 
00514         this->sel = newsel;
00515         this->preset = -1;
00516         this->SetupNewGRFWindow();
00517         this->SetDirty();
00518         break;
00519       }
00520 
00521       case SNGRFS_MOVE_UP: { // Move GRF up
00522         GRFConfig **pc, *c;
00523         if (this->sel == NULL) break;
00524 
00525         for (pc = &this->list; (c = *pc) != NULL; pc = &c->next) {
00526           if (c->next == this->sel) {
00527             c->next = this->sel->next;
00528             this->sel->next = c;
00529             *pc = this->sel;
00530             break;
00531           }
00532         }
00533         this->preset = -1;
00534         this->SetDirty();
00535         break;
00536       }
00537 
00538       case SNGRFS_MOVE_DOWN: { // Move GRF down
00539         GRFConfig **pc, *c;
00540         if (this->sel == NULL) break;
00541 
00542         for (pc = &this->list; (c = *pc) != NULL; pc = &c->next) {
00543           if (c == this->sel) {
00544             *pc = c->next;
00545             c->next = c->next->next;
00546             (*pc)->next = c;
00547             break;
00548           }
00549         }
00550         this->preset = -1;
00551         this->SetDirty();
00552         break;
00553       }
00554 
00555       case SNGRFS_FILE_LIST: { // Select a GRF
00556         GRFConfig *c;
00557         uint i = (pt.y - this->widget[SNGRFS_FILE_LIST].top) / 14 + this->vscroll.pos;
00558 
00559         for (c = this->list; c != NULL && i > 0; c = c->next, i--) {}
00560         this->sel = c;
00561 
00562         this->SetDirty();
00563         break;
00564       }
00565 
00566       case SNGRFS_APPLY_CHANGES: // Apply changes made to GRF list
00567         if (this->execute) {
00568           ShowQuery(
00569             STR_POPUP_CAUTION_CAPTION,
00570             STR_NEWGRF_CONFIRMATION_TEXT,
00571             this,
00572             NewGRFConfirmationCallback
00573           );
00574         } else {
00575           CopyGRFConfigList(this->orig_list, this->list, true);
00576           ResetGRFConfig(false);
00577           ReloadNewGRFData();
00578         }
00579         break;
00580 
00581       case SNGRFS_SET_PARAMETERS: { // Edit parameters
00582         if (this->sel == NULL) break;
00583 
00584         this->query_widget = widget;
00585         static char buff[512];
00586         GRFBuildParamList(buff, this->sel, lastof(buff));
00587         SetDParamStr(0, buff);
00588         ShowQueryString(STR_JUST_RAW_STRING, STR_NEWGRF_PARAMETER_QUERY, 63, 250, this, CS_ALPHANUMERAL, QSF_NONE);
00589         break;
00590       }
00591 
00592       case SNGRFS_TOGGLE_PALETTE:
00593         if (this->sel != NULL) {
00594           this->sel->windows_paletted ^= true;
00595           this->SetDirty();
00596         }
00597         break;
00598 
00599       case SNGRFS_CONTENT_DOWNLOAD:
00600         if (!_network_available) {
00601           ShowErrorMessage(INVALID_STRING_ID, STR_NETWORK_ERR_NOTAVAILABLE, 0, 0);
00602         } else {
00603 #if defined(ENABLE_NETWORK)
00604         /* Only show the things in the current list, or everything when nothing's selected */
00605           ContentVector cv;
00606           for (const GRFConfig *c = this->list; c != NULL; c = c->next) {
00607             if (c->status != GCS_NOT_FOUND && !HasBit(c->flags, GCF_COMPATIBLE)) continue;
00608 
00609             ContentInfo *ci = new ContentInfo();
00610             ci->type = CONTENT_TYPE_NEWGRF;
00611             ci->state = ContentInfo::DOES_NOT_EXIST;
00612             ttd_strlcpy(ci->name, c->name != NULL ? c->name : c->filename, lengthof(ci->name));
00613             ci->unique_id = BSWAP32(c->grfid);
00614             memcpy(ci->md5sum, c->md5sum, sizeof(ci->md5sum));
00615             if (HasBit(c->flags, GCF_COMPATIBLE)) GamelogGetOriginalGRFMD5Checksum(c->grfid, ci->md5sum);
00616             *cv.Append() = ci;
00617           }
00618           ShowNetworkContentListWindow(cv.Length() == 0 ? NULL : &cv, CONTENT_TYPE_NEWGRF);
00619 #endif
00620         }
00621         break;
00622 
00623     }
00624   }
00625 
00626   virtual void OnDropdownSelect(int widget, int index)
00627   {
00628     if (index == -1) {
00629       ClearGRFConfigList(&this->list);
00630       this->preset = -1;
00631     } else {
00632       GRFConfig *c = LoadGRFPresetFromConfig(_grf_preset_list[index]);
00633 
00634       if (c != NULL) {
00635         this->sel = NULL;
00636         ClearGRFConfigList(&this->list);
00637         this->list = c;
00638         this->preset = index;
00639       }
00640     }
00641 
00642     this->sel = NULL;
00643     this->SetupNewGRFWindow();
00644     this->SetDirty();
00645   }
00646 
00647   virtual void OnQueryTextFinished(char *str)
00648   {
00649     if (str == NULL) return;
00650 
00651     switch (this->query_widget) {
00652       case SNGRFS_PRESET_SAVE:
00653         SaveGRFPresetToConfig(str, this->list);
00654         GetGRFPresetList(&_grf_preset_list);
00655 
00656         /* Switch to this preset */
00657         for (uint i = 0; i < _grf_preset_list.Length(); i++) {
00658           if (_grf_preset_list[i] != NULL && strcmp(_grf_preset_list[i], str) == 0) {
00659             this->preset = i;
00660             break;
00661           }
00662         }
00663 
00664         this->SetDirty();
00665         break;
00666 
00667       case SNGRFS_SET_PARAMETERS: {
00668         /* Parse our new "int list" */
00669         GRFConfig *c = this->sel;
00670         c->num_params = parse_intlist(str, (int*)c->param, lengthof(c->param));
00671 
00672         /* parse_intlist returns -1 on error */
00673         if (c->num_params == (byte)-1) c->num_params = 0;
00674 
00675         this->preset = -1;
00676         this->SetDirty();
00677         break;
00678       }
00679     }
00680   }
00681 
00682   virtual void OnResize(Point new_size, Point delta)
00683   {
00684     if (delta.x != 0) {
00685       ResizeButtons(this, SNGRFS_ADD, SNGRFS_MOVE_DOWN);
00686       ResizeButtons(this, SNGRFS_SET_PARAMETERS, SNGRFS_APPLY_CHANGES);
00687     }
00688 
00689     this->vscroll.cap += delta.y / 14;
00690     this->widget[SNGRFS_FILE_LIST].data = (this->vscroll.cap << 8) + 1;
00691 
00692     this->SetupNewGRFWindow();
00693   }
00694 
00695   virtual void OnInvalidateData(int data)
00696   {
00697     switch (data) {
00698       default: NOT_REACHED();
00699       case 0:
00700         this->preset = -1;
00701         this->SetupNewGRFWindow();
00702         break;
00703 
00704       case 1:
00705         /* Search the list for items that are now found and mark them as such. */
00706         for (GRFConfig *c = this->list; c != NULL; c = c->next) {
00707           if (c->status != GCS_NOT_FOUND) continue;
00708 
00709           const GRFConfig *f = FindGRFConfig(c->grfid, c->md5sum);
00710           if (f == NULL) continue;
00711 
00712           free(c->filename);
00713           free(c->name);
00714           free(c->info);
00715 
00716           c->filename  = f->filename == NULL ? NULL : strdup(f->filename);
00717           c->name      = f->name == NULL ? NULL : strdup(f->name);;
00718           c->info      = f->info == NULL ? NULL : strdup(f->info);;
00719           c->status    = GCS_UNKNOWN;
00720         }
00721         break;
00722     }
00723   }
00724 };
00725 
00726 /* Widget definition of the manage newgrfs window */
00727 static const Widget _newgrf_widgets[] = {
00728 {   WWT_CLOSEBOX,  RESIZE_NONE,  COLOUR_MAUVE,    0,  10,   0,  13, STR_00C5,                    STR_018B_CLOSE_WINDOW },            // SNGRFS_CLOSEBOX
00729 {    WWT_CAPTION, RESIZE_RIGHT,  COLOUR_MAUVE,   11, 299,   0,  13, STR_NEWGRF_SETTINGS_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS },  // SNGRFS_CAPTION
00730 {      WWT_PANEL, RESIZE_RIGHT,  COLOUR_MAUVE,    0, 299,  14,  41, STR_NULL,                    STR_NULL },                         // SNGRFS_BACKGROUND1
00731 {   WWT_DROPDOWN, RESIZE_RIGHT,  COLOUR_YELLOW,  10, 103,  16,  27, STR_EMPTY,                   STR_NEWGRF_PRESET_LIST_TIP },       // SNGRFS_PRESET_LIST
00732 { WWT_PUSHTXTBTN,    RESIZE_LR,  COLOUR_YELLOW, 104, 196,  16,  27, STR_NEWGRF_PRESET_SAVE,      STR_NEWGRF_PRESET_SAVE_TIP },       // SNGRFS_PRESET_SAVE
00733 { WWT_PUSHTXTBTN,    RESIZE_LR,  COLOUR_YELLOW, 197, 289,  16,  27, STR_NEWGRF_PRESET_DELETE,    STR_NEWGRF_PRESET_DELETE_TIP },     // SNGRFS_PRESET_DELETE
00734 {      WWT_PANEL, RESIZE_RIGHT,  COLOUR_MAUVE,    0, 299,  30,  45, STR_NULL,                    STR_NULL },                         // SNGRFS_BACKGROUND
00735 { WWT_PUSHTXTBTN,  RESIZE_NONE,  COLOUR_YELLOW,  10,  79,  32,  43, STR_NEWGRF_ADD,              STR_NEWGRF_ADD_TIP },               // SNGRFS_ADD
00736 { WWT_PUSHTXTBTN,  RESIZE_NONE,  COLOUR_YELLOW,  80, 149,  32,  43, STR_NEWGRF_REMOVE,           STR_NEWGRF_REMOVE_TIP },            // SNGRFS_REMOVE
00737 { WWT_PUSHTXTBTN,  RESIZE_NONE,  COLOUR_YELLOW, 150, 219,  32,  43, STR_NEWGRF_MOVEUP,           STR_NEWGRF_MOVEUP_TIP },            // SNGRFS_MOVE_UP
00738 { WWT_PUSHTXTBTN, RESIZE_RIGHT,  COLOUR_YELLOW, 220, 289,  32,  43, STR_NEWGRF_MOVEDOWN,         STR_NEWGRF_MOVEDOWN_TIP },          // SNGRFS_MOVE_DOWN
00739 {     WWT_MATRIX,    RESIZE_RB,  COLOUR_MAUVE,    0, 287,  46, 115, 0x501,                       STR_NEWGRF_FILE_TIP },              // SNGRFS_FILE_LIST
00740 {  WWT_SCROLLBAR,   RESIZE_LRB,  COLOUR_MAUVE,  288, 299,  46, 115, 0x0,                         STR_0190_SCROLL_BAR_SCROLLS_LIST }, // SNGRFS_SCROLLBAR
00741 {      WWT_PANEL,   RESIZE_RTB,  COLOUR_MAUVE,    0, 299, 116, 238, STR_NULL,                    STR_NULL },                         // SNGRFS_NEWGRF_INFO
00742 { WWT_PUSHTXTBTN,    RESIZE_TB,  COLOUR_MAUVE,    0,  99, 239, 250, STR_NEWGRF_SET_PARAMETERS,   STR_NULL },                         // SNGRFS_SET_PARAMETERS
00743 { WWT_PUSHTXTBTN,   RESIZE_RTB,  COLOUR_MAUVE,  100, 199, 239, 250, STR_NEWGRF_TOGGLE_PALETTE,   STR_NEWGRF_TOGGLE_PALETTE_TIP },    // SNGRFS_TOGGLE_PALETTE
00744 { WWT_PUSHTXTBTN,   RESIZE_RTB,  COLOUR_MAUVE,  200, 299, 239, 250, STR_NEWGRF_APPLY_CHANGES,    STR_NULL },                         // SNGRFS_APPLY_CHANGES
00745 { WWT_PUSHTXTBTN,   RESIZE_RTB,  COLOUR_MAUVE,    0, 287, 251, 262, STR_CONTENT_INTRO_BUTTON,    STR_CONTENT_INTRO_BUTTON_TIP },     // SNGRFS_DOWNLOAD_CONTENT
00746 {  WWT_RESIZEBOX,  RESIZE_LRTB,  COLOUR_MAUVE,  288, 299, 251, 262, 0x0,                         STR_RESIZE_BUTTON },                // SNGRFS_RESIZE
00747 { WIDGETS_END },
00748 };
00749 
00750 /* Window definition of the manage newgrfs window */
00751 static const WindowDesc _newgrf_desc(
00752   WDP_CENTER, WDP_CENTER, 300, 263, 300, 263,
00753   WC_GAME_OPTIONS, WC_NONE,
00754   WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
00755   _newgrf_widgets
00756 );
00757 
00762 static void NewGRFConfirmationCallback(Window *w, bool confirmed)
00763 {
00764   if (confirmed) {
00765     NewGRFWindow *nw = dynamic_cast<NewGRFWindow*>(w);
00766     GRFConfig *c;
00767     int i = 0;
00768 
00769     GamelogStartAction(GLAT_GRF);
00770     GamelogGRFUpdate(_grfconfig, nw->list); // log GRF changes
00771     CopyGRFConfigList(nw->orig_list, nw->list, false);
00772     ReloadNewGRFData();
00773     GamelogStopAction();
00774 
00775     /* Show new, updated list */
00776     for (c = nw->list; c != NULL && c != nw->sel; c = c->next, i++) {}
00777     CopyGRFConfigList(&nw->list, *nw->orig_list, false);
00778     for (c = nw->list; c != NULL && i > 0; c = c->next, i--) {}
00779     nw->sel = c;
00780 
00781     w->SetDirty();
00782   }
00783 }
00784 
00785 
00786 
00793 void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfig **config)
00794 {
00795   DeleteWindowByClass(WC_GAME_OPTIONS);
00796   new NewGRFWindow(&_newgrf_desc, editable, show_params, exec_changes, config);
00797 }

Generated on Wed Jul 15 20:36:00 2009 for OpenTTD by  doxygen 1.5.6