newgrf_gui.cpp

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

Generated on Tue Dec 1 00:06:17 2009 for OpenTTD by  doxygen 1.5.6