SHARE
TWEET

OpenTTD View Readme

LordAro Apr 1st, 2011 136 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. diff --git a/src/fileio_func.h b/src/fileio_func.h
  2. --- a/src/fileio_func.h
  3. +++ b/src/fileio_func.h
  4. @@ -66,6 +66,8 @@
  5.  
  6.  extern char *_personal_dir; ///< custom directory for personal settings, saves, newgrf, etc.
  7.  
  8. +static const uint16 MAX_README_LENGTH = 8191;
  9. +
  10.  /** Helper for scanning for files with a given name */
  11.  class FileScanner
  12.  {
  13. diff --git a/src/lang/english.txt b/src/lang/english.txt
  14. --- a/src/lang/english.txt
  15. +++ b/src/lang/english.txt
  16. @@ -2390,6 +2390,7 @@
  17.  STR_NEWGRF_SETTINGS_MOVEDOWN                                    :{BLACK}Move Down
  18.  STR_NEWGRF_SETTINGS_MOVEDOWN_TOOLTIP                            :{BLACK}Move the selected NewGRF file down the list
  19.  STR_NEWGRF_SETTINGS_FILE_TOOLTIP                                :{BLACK}A list of the NewGRF files that are installed. Click a file to change its parameters
  20. +STR_NEWGRF_SETTINGS_VIEW_README                                 :{BLACK}View Readme
  21.  
  22.  STR_NEWGRF_SETTINGS_SET_PARAMETERS                              :{BLACK}Set parameters
  23.  STR_NEWGRF_SETTINGS_TOGGLE_PALETTE                              :{BLACK}Toggle palette
  24. @@ -2423,6 +2424,9 @@
  25.  STR_NEWGRF_PARAMETERS_SETTING                                   :{STRING1}: {ORANGE}{STRING1}
  26.  STR_NEWGRF_PARAMETERS_NUM_PARAM                                 :{LTBLUE}Number of parameters: {ORANGE}{NUM}
  27.  
  28. +# NewGRF readme window
  29. +STR_NEWGRF_README_CAPTION                                       :{WHITE}View NewGRF Readme
  30. +
  31.  # NewGRF inspect window
  32.  STR_NEWGRF_INSPECT_CAPTION                                      :{WHITE}Inspect - {STRING5}
  33.  STR_NEWGRF_INSPECT_PARENT_BUTTON                                :{BLACK}Parent
  34. diff --git a/src/newgrf_config.cpp b/src/newgrf_config.cpp
  35. --- a/src/newgrf_config.cpp
  36. +++ b/src/newgrf_config.cpp
  37. @@ -20,6 +20,7 @@
  38.  
  39.  #include "fileio_func.h"
  40.  #include "fios.h"
  41. +#include "tar_type.h"
  42.  
  43.  /** Create a new GRFTextWrapper. */
  44.  GRFTextWrapper::GRFTextWrapper() :
  45. @@ -761,3 +762,27 @@
  46.  {
  47.         return (this->ident.grfid & 0x00FFFFFF) == OPENTTD_GRAPHICS_BASE_GRF_ID;
  48.  }
  49. +
  50. +/**
  51. + * Check a grf for a readme.txt file.
  52. + * @param cfg The GRFConfig to check.
  53. + * @return true is the GRF is packaged with a readme.txt file.
  54. + * @note a GRF can only have a readme if it is inside a tar archive.
  55. + */
  56. +bool GrfHasReadme(const GRFConfig *cfg)
  57. +{
  58. +       if (cfg == NULL || cfg->filename == NULL) return false;
  59. +
  60. +       const char *slash = strrchr(cfg->filename, PATHSEPCHAR);
  61. +       if (slash == NULL) return false;
  62. +       int prefix_length = slash - cfg->filename + 1; // Including the path separator.
  63. +       if (prefix_length + 10 + 1 > MAX_PATH) return false; // "foo/" + "readme.txt" + '\0' must fit.
  64. +
  65. +       char readme_path[MAX_PATH];
  66. +       memcpy(readme_path, cfg->filename, prefix_length);
  67. +       strecpy(readme_path + prefix_length, "readme.txt", lastof(readme_path));
  68. +
  69. +       TarFileList::iterator tar_entry = _tar_filelist.find(readme_path);
  70. +       if (tar_entry == _tar_filelist.end()) return false;
  71. +       return true;
  72. +}
  73. diff --git a/src/newgrf_config.h b/src/newgrf_config.h
  74. --- a/src/newgrf_config.h
  75. +++ b/src/newgrf_config.h
  76. @@ -200,6 +200,7 @@
  77.  GRFListCompatibility IsGoodGRFConfigList(GRFConfig *grfconfig);
  78.  bool FillGRFDetails(GRFConfig *config, bool is_static);
  79.  char *GRFBuildParamList(char *dst, const GRFConfig *c, const char *last);
  80. +bool GrfHasReadme(const GRFConfig *cfg);
  81.  
  82.  /* In newgrf_gui.cpp */
  83.  void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfig **config);
  84. diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp
  85. --- a/src/newgrf_gui.cpp
  86. +++ b/src/newgrf_gui.cpp
  87. @@ -25,6 +25,7 @@
  88.  #include "core/geometry_func.hpp"
  89.  #include "newgrf_text.h"
  90.  #include "fileio_func.h"
  91. +#include "tar_type.h"
  92.  
  93.  #include "table/strings.h"
  94.  #include "table/sprites.h"
  95. @@ -449,17 +450,121 @@
  96.  /* Window definition for the change grf parameters window */
  97.  static const WindowDesc _newgrf_parameters_desc(
  98.         WDP_CENTER, 500, 208,
  99. -       WC_GRF_PARAMETERS, WC_NONE,
  100. +       WC_NEWGRF_PARAMETERS, WC_NONE,
  101.         WDF_UNCLICK_BUTTONS,
  102.         _nested_newgrf_parameter_widgets, lengthof(_nested_newgrf_parameter_widgets)
  103.  );
  104.  
  105.  void OpenGRFParameterWindow(GRFConfig *c)
  106.  {
  107. -       DeleteWindowByClass(WC_GRF_PARAMETERS);
  108. +       DeleteWindowByClass(WC_NEWGRF_PARAMETERS);
  109.         new NewGRFParametersWindow(&_newgrf_parameters_desc, c);
  110.  }
  111.  
  112. +enum ShowNewGRFReadmeWidgets {
  113. +       GRW_WIDGET_BACKGROUND,       ///< Panel to draw the readme on
  114. +       GRW_WIDGET_SCROLLBAR,        ///< Scrollbar to scroll through the readme
  115. +};
  116. +
  117. +struct NewGRFReadmeWindow : public Window {
  118. +       GRFConfig *grf_config; ///< View the readme of this GRFConfig.
  119. +       uint clicked_button;   ///< The row in which a button was clicked or UINT_MAX.
  120. +       bool clicked_increase; ///< True if the increase button was clicked, false for the decrease button.
  121. +       int timeout;           ///< How long before we unpress the last-pressed button?
  122. +       int line_height;       ///< Height of a row in the matrix widget.
  123. +       Scrollbar *vscroll;
  124. +      
  125. +      
  126. +       static const int top_spacing;    ///< Additional spacing at the top of the #MHW_BACKGROUND widget.
  127. +       static const int bottom_spacing; ///< Additional spacing at the bottom of the #MHW_BACKGROUND widget.
  128. +
  129. +       int date_width;  /// < Width needed for the date part.
  130. +
  131. +       NewGRFReadmeWindow(const WindowDesc *desc, GRFConfig *c) : Window(),
  132. +               grf_config(c),
  133. +               clicked_button(UINT_MAX),
  134. +               timeout(0)
  135. +       {
  136. +               this->CreateNestedTree(desc);
  137. +               this->vscroll = this->GetScrollbar(GRFPAR_WIDGET_SCROLLBAR);
  138. +               this->FinishInitNested(desc);  // Initializes 'this->line_height' as side effect.
  139. +               this->OnInvalidateData();
  140. +       }
  141. +
  142. +       virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
  143. +       {
  144. +               switch (widget) {
  145. +                       case GRW_WIDGET_BACKGROUND:
  146. +                               this->line_height = FONT_HEIGHT_NORMAL + 2;
  147. +                               resize->height = this->line_height;
  148. +
  149. +                               size->height = 4 * resize->height + this->top_spacing + this->bottom_spacing; // At least 4 lines are visible.
  150. +                               size->width = max(200u, size->width); // At least 200 pixels wide.
  151. +                               break;
  152. +               }
  153. +       }
  154. +
  155. +       virtual void OnPaint()
  156. +       {
  157. +               this->OnInvalidateData(0);
  158. +               this->DrawWidgets();
  159. +       }
  160. +
  161. +       virtual void DrawWidget(const Rect &r, int widget) const
  162. +       {
  163. +               if (widget != GRW_WIDGET_BACKGROUND) return;
  164. +       }
  165. +
  166. +       virtual void OnResize()
  167. +       {
  168. +       }
  169. +
  170. +       /**
  171. +        * Some data on this window has become invalid.
  172. +        * @param data Information about the changed data.
  173. +        * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
  174. +        */
  175. +       virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
  176. +       {
  177. +               if (!gui_scope) return;
  178. +               DeleteChildWindows(WC_NEWGRF_README);
  179. +       }
  180. +};
  181. +
  182. +const int NewGRFReadmeWindow::top_spacing = WD_FRAMERECT_TOP + 4;
  183. +const int NewGRFReadmeWindow::bottom_spacing = WD_FRAMERECT_BOTTOM;
  184. +
  185. +static const NWidgetPart _nested_newgrf_readme_widgets[] = {
  186. +       NWidget(NWID_HORIZONTAL),
  187. +               NWidget(WWT_CLOSEBOX, COLOUR_MAUVE),
  188. +               NWidget(WWT_CAPTION, COLOUR_MAUVE), SetDataTip(STR_NEWGRF_README_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
  189. +               NWidget(WWT_SHADEBOX, COLOUR_MAUVE),
  190. +               NWidget(WWT_STICKYBOX, COLOUR_MAUVE),
  191. +       EndContainer(),
  192. +       NWidget(NWID_HORIZONTAL),
  193. +               NWidget(WWT_PANEL, COLOUR_MAUVE, GRW_WIDGET_BACKGROUND), SetMinimalSize(200, 125), SetResize(1, 12), SetScrollbar(GRW_WIDGET_SCROLLBAR),
  194. +               EndContainer(),
  195. +               NWidget(NWID_VERTICAL),
  196. +                       NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, GRW_WIDGET_SCROLLBAR),
  197. +                       NWidget(WWT_RESIZEBOX, COLOUR_MAUVE),
  198. +               EndContainer(),
  199. +       EndContainer(),
  200. +};
  201. +
  202. +/* Window definition for the grf readme window */
  203. +static const WindowDesc _newgrf_readme_desc(
  204. +       WDP_CENTER, 630, 460,
  205. +       WC_NEWGRF_README, WC_NONE,
  206. +       WDF_UNCLICK_BUTTONS,
  207. +       _nested_newgrf_readme_widgets, lengthof(_nested_newgrf_readme_widgets)
  208. +);
  209. +
  210. +void OpenNewGRFReadmeWindow(GRFConfig *c)
  211. +{
  212. +       DeleteWindowByClass(WC_NEWGRF_README);
  213. +       new NewGRFReadmeWindow(&_newgrf_readme_desc, c);
  214. +}
  215. +
  216.  static GRFPresetList _grf_preset_list;
  217.  
  218.  class DropDownListPresetItem : public DropDownListItem {
  219. @@ -497,6 +602,7 @@
  220.         SNGRFS_SCROLL2BAR,
  221.         SNGRFS_NEWGRF_INFO_TITLE,
  222.         SNGRFS_NEWGRF_INFO,
  223. +       SNGRFS_NEWGRF_README,
  224.         SNGRFS_SET_PARAMETERS,
  225.         SNGRFS_TOGGLE_PALETTE,
  226.         SNGRFS_APPLY_CHANGES,
  227. @@ -574,7 +680,8 @@
  228.  
  229.         ~NewGRFWindow()
  230.         {
  231. -               DeleteWindowByClass(WC_GRF_PARAMETERS);
  232. +               DeleteWindowByClass(WC_NEWGRF_PARAMETERS);
  233. +               DeleteWindowByClass(WC_NEWGRF_README);
  234.  
  235.                 if (this->editable && !this->execute) {
  236.                         CopyGRFConfigList(this->orig_list, this->actives, true);
  237. @@ -847,7 +954,7 @@
  238.                                 GRFConfig *c;
  239.                                 for (c = this->actives; c != NULL && i > 0; c = c->next, i--) {}
  240.  
  241. -                               if (this->active_sel != c) DeleteWindowByClass(WC_GRF_PARAMETERS);
  242. +                               if (this->active_sel != c) DeleteWindowByClass(WC_NEWGRF_PARAMETERS);
  243.                                 this->active_sel = c;
  244.                                 this->avail_sel = NULL;
  245.                                 this->avail_pos = -1;
  246. @@ -859,7 +966,7 @@
  247.  
  248.                         case SNGRFS_REMOVE: { // Remove GRF
  249.                                 if (this->active_sel == NULL || !this->editable) break;
  250. -                               DeleteWindowByClass(WC_GRF_PARAMETERS);
  251. +                               DeleteWindowByClass(WC_NEWGRF_PARAMETERS);
  252.  
  253.                                 /* Choose the next GRF file to be the selected file. */
  254.                                 GRFConfig *newsel = this->active_sel->next;
  255. @@ -888,7 +995,7 @@
  256.                         case SNGRFS_AVAIL_LIST: { // Select a non-active GRF.
  257.                                 uint i = this->vscroll2->GetScrolledRowFromWidget(pt.y, this, SNGRFS_AVAIL_LIST);
  258.                                 this->active_sel = NULL;
  259. -                               DeleteWindowByClass(WC_GRF_PARAMETERS);
  260. +                               DeleteWindowByClass(WC_NEWGRF_PARAMETERS);
  261.                                 if (i < this->avails.Length()) {
  262.                                         this->avail_sel = this->avails[i];
  263.                                         this->avail_pos = i;
  264. @@ -941,6 +1048,18 @@
  265.                                 }
  266.                                 this->DeleteChildWindows(WC_QUERY_STRING); // Remove the parameter query window
  267.                                 break;
  268. +                      
  269. +                       case SNGRFS_NEWGRF_README: { // View GRF readme
  270. +                               if (this->active_sel == NULL && this->avail_sel == NULL) break;
  271. +                              
  272. +                               if (this->active_sel) {
  273. +                                       OpenNewGRFReadmeWindow(this->active_sel);
  274. +                                       break;
  275. +                               }
  276. +                               GRFConfig *c = new GRFConfig(*this->avail_sel);
  277. +                               OpenNewGRFReadmeWindow(c);
  278. +                               break;
  279. +                       }
  280.  
  281.                         case SNGRFS_SET_PARAMETERS: { // Edit parameters
  282.                                 if (this->active_sel == NULL || !this->editable || !this->show_params || this->active_sel->num_valid_params == 0) break;
  283. @@ -991,6 +1110,7 @@
  284.                                 this->avails.ForceRebuild();
  285.                                 this->InvalidateData(GOID_NEWGRF_RESCANNED);
  286.                                 this->DeleteChildWindows(WC_QUERY_STRING); // Remove the parameter query window
  287. +                               this->DeleteChildWindows(WC_NEWGRF_README); // Remove the view readme window
  288.                                 InvalidateWindowClassesData(WC_SAVELOAD);
  289.                                 break;
  290.                 }
  291. @@ -1008,7 +1128,7 @@
  292.                 }
  293.                 this->avails.ForceRebuild();
  294.  
  295. -               DeleteWindowByClass(WC_GRF_PARAMETERS);
  296. +               DeleteWindowByClass(WC_NEWGRF_PARAMETERS);
  297.                 this->active_sel = NULL;
  298.                 this->InvalidateData(GOID_NEWGRF_PRESET_LOADED);
  299.         }
  300. @@ -1098,6 +1218,13 @@
  301.                         SNGRFS_MOVE_DOWN,
  302.                         WIDGET_LIST_END
  303.                 );
  304. +
  305. +               bool disable_readme = false;
  306. +               if (this->avail_sel == NULL && this->active_sel == NULL) disable_readme = true;
  307. +               const GRFConfig *c = (this->avail_sel == NULL ? this->active_sel : this->avail_sel);
  308. +               if (GrfHasReadme(c)) disable_readme = true;
  309. +               this->SetWidgetDisabledState(SNGRFS_NEWGRF_README, disable_readme);
  310. +
  311.                 this->SetWidgetDisabledState(SNGRFS_SET_PARAMETERS, !this->show_params || disable_all || this->active_sel->num_valid_params == 0);
  312.                 this->SetWidgetDisabledState(SNGRFS_TOGGLE_PALETTE, disable_all);
  313.  
  314. @@ -1582,6 +1709,8 @@
  315.         NWidget(WWT_PANEL, COLOUR_MAUVE), SetPadding(0, 0, 2, 0),
  316.                 NWidget(WWT_EMPTY, COLOUR_MAUVE, SNGRFS_NEWGRF_INFO_TITLE), SetFill(1, 0), SetResize(1, 0),
  317.                 NWidget(WWT_EMPTY, COLOUR_MAUVE, SNGRFS_NEWGRF_INFO), SetFill(1, 1), SetResize(1, 1), SetMinimalSize(150, 100),
  318. +               NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, SNGRFS_NEWGRF_README), SetFill(1, 0), SetResize(1, 0),
  319. +                               SetDataTip(STR_NEWGRF_SETTINGS_VIEW_README, STR_NULL), SetPadding(2, 2, 2, 2),
  320.         EndContainer(),
  321.         NWidget(NWID_SELECTION, INVALID_COLOUR, SNGRFS_SHOW_APPLY),
  322.                 /* Right side, buttons. */
  323. @@ -1645,7 +1774,7 @@
  324.  static void NewGRFConfirmationCallback(Window *w, bool confirmed)
  325.  {
  326.         if (confirmed) {
  327. -               DeleteWindowByClass(WC_GRF_PARAMETERS);
  328. +               DeleteWindowByClass(WC_NEWGRF_PARAMETERS);
  329.                 NewGRFWindow *nw = dynamic_cast<NewGRFWindow*>(w);
  330.  
  331.                 GamelogStartAction(GLAT_GRF);
  332. diff --git a/src/window_type.h b/src/window_type.h
  333. --- a/src/window_type.h
  334. +++ b/src/window_type.h
  335. @@ -109,8 +109,9 @@
  336.         WC_NEWGRF_INSPECT,
  337.         WC_SPRITE_ALIGNER,
  338.         WC_INDUSTRY_CARGOES,
  339. -       WC_GRF_PARAMETERS,
  340. +       WC_NEWGRF_PARAMETERS,
  341.         WC_BUILD_OBJECT,
  342. +       WC_NEWGRF_README,
  343.  
  344.         WC_INVALID = 0xFFFF
  345.  };
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top