|
1 /* $Id$ */ |
|
2 |
|
3 #include "stdafx.h" |
|
4 #include "openttd.h" |
|
5 #include "functions.h" |
|
6 #include "variables.h" |
|
7 #include "gfx.h" |
|
8 #include "gui.h" |
|
9 #include "window.h" |
|
10 #include "table/strings.h" |
|
11 #include "table/sprites.h" |
|
12 #include "newgrf.h" |
|
13 #include "newgrf_config.h" |
|
14 |
|
15 |
|
16 /** Parse an integerlist string and set each found value |
|
17 * @param p the string to be parsed. Each element in the list is seperated by a |
|
18 * comma or a space character |
|
19 * @param items pointer to the integerlist-array that will be filled with values |
|
20 * @param maxitems the maximum number of elements the integerlist-array has |
|
21 * @return returns the number of items found, or -1 on an error */ |
|
22 static int parse_intlist(const char *p, int *items, int maxitems) |
|
23 { |
|
24 int n = 0, v; |
|
25 char *end; |
|
26 |
|
27 for (;;) { |
|
28 v = strtol(p, &end, 0); |
|
29 if (p == end || n == maxitems) return -1; |
|
30 p = end; |
|
31 items[n++] = v; |
|
32 if (*p == '\0') break; |
|
33 if (*p != ',' && *p != ' ') return -1; |
|
34 p++; |
|
35 } |
|
36 |
|
37 return n; |
|
38 } |
|
39 |
|
40 |
|
41 static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint w, bool show_params) |
|
42 { |
|
43 char buff[512]; |
|
44 char *s; |
|
45 uint i; |
|
46 |
|
47 /* Draw filename or not if it is not known (GRF sent over internet) */ |
|
48 if (c->filename != NULL) { |
|
49 SetDParamStr(0, c->filename); |
|
50 y += DrawStringMultiLine(x, y, STR_NEWGRF_FILENAME, w); |
|
51 } |
|
52 |
|
53 /* Prepare and draw GRF ID */ |
|
54 snprintf(buff, lengthof(buff), "%08X", (uint32)BSWAP32(c->grfid)); |
|
55 SetDParamStr(0, buff); |
|
56 y += DrawStringMultiLine(x, y, STR_NEWGRF_GRF_ID, w); |
|
57 |
|
58 /* Prepare and draw MD5 sum */ |
|
59 s = buff; |
|
60 for (i = 0; i < lengthof(c->md5sum); i++) { |
|
61 s += snprintf(s, lastof(buff) - s, "%02X", c->md5sum[i]); |
|
62 } |
|
63 SetDParamStr(0, buff); |
|
64 y += DrawStringMultiLine(x, y, STR_NEWGRF_MD5SUM, w); |
|
65 |
|
66 /* Show GRF parameter list */ |
|
67 if (show_params) { |
|
68 if (c->num_params > 0) { |
|
69 GRFBuildParamList(buff, c, lastof(buff)); |
|
70 SetDParamStr(0, buff); |
|
71 } else { |
|
72 SetDParam(0, STR_01A9_NONE); |
|
73 } |
|
74 y += DrawStringMultiLine(x, y, STR_NEWGRF_PARAMETER, w); |
|
75 } |
|
76 |
|
77 /* Show flags */ |
|
78 if (HASBIT(c->flags, GCF_NOT_FOUND)) y += DrawStringMultiLine(x, y, STR_NEWGRF_NOT_FOUND, w); |
|
79 if (HASBIT(c->flags, GCF_DISABLED)) y += DrawStringMultiLine(x, y, STR_NEWGRF_DISABLED, w); |
|
80 |
|
81 /* Draw GRF info if it exists */ |
|
82 if (c->info != NULL && strlen(c->info) != 0) { |
|
83 SetDParamStr(0, c->info); |
|
84 y += DrawStringMultiLine(x, y, STR_02BD, w); |
|
85 } else { |
|
86 y += DrawStringMultiLine(x, y, STR_NEWGRF_NO_INFO, w); |
|
87 } |
|
88 } |
|
89 |
|
90 |
|
91 /* Dialogue for adding NewGRF files to the selection */ |
|
92 typedef struct newgrf_add_d { |
|
93 GRFConfig **list; |
|
94 const GRFConfig *sel; |
|
95 } newgrf_add_d; |
|
96 |
|
97 |
|
98 static void NewGRFAddDlgWndProc(Window *w, WindowEvent *e) |
|
99 { |
|
100 switch (e->event) { |
|
101 case WE_PAINT: { |
|
102 const GRFConfig *c; |
|
103 int y; |
|
104 int n = 0; |
|
105 |
|
106 /* Count the number of GRFs */ |
|
107 for (c = _all_grfs; c != NULL; c = c->next) n++; |
|
108 |
|
109 w->vscroll.cap = (w->widget[3].bottom - w->widget[3].top) / 10; |
|
110 SetVScrollCount(w, n); |
|
111 |
|
112 SetWindowWidgetDisabledState(w, 6, WP(w, newgrf_add_d).sel == NULL); |
|
113 DrawWindowWidgets(w); |
|
114 |
|
115 GfxFillRect(w->widget[3].left + 1, w->widget[3].top + 1, w->widget[3].right, w->widget[3].bottom, 0xD7); |
|
116 |
|
117 n = 0; |
|
118 y = w->widget[3].top + 1; |
|
119 |
|
120 for (c = _all_grfs; c != NULL; c = c->next) { |
|
121 if (n >= w->vscroll.pos && n < w->vscroll.pos + w->vscroll.cap) { |
|
122 bool h = c == WP(w, newgrf_add_d).sel; |
|
123 const char *text = (c->name != NULL && strlen(c->name) != 0) ? c->name : c->filename; |
|
124 |
|
125 /* Draw selection background */ |
|
126 if (h) GfxFillRect(3, y, w->width - 15, y + 9, 156); |
|
127 DoDrawStringTruncated(text, 4, y, h ? 0xC : 0x6, w->width - 18); |
|
128 y += 10; |
|
129 } |
|
130 n++; |
|
131 } |
|
132 |
|
133 if (WP(w, newgrf_add_d).sel != NULL) { |
|
134 const Widget *wi = &w->widget[5]; |
|
135 ShowNewGRFInfo(WP(w, newgrf_add_d).sel, wi->left + 2, wi->top + 2, wi->right - wi->left - 2, false); |
|
136 } |
|
137 break; |
|
138 } |
|
139 |
|
140 case WE_CLICK: |
|
141 switch (e->we.click.widget) { |
|
142 case 3: { |
|
143 // Get row... |
|
144 const GRFConfig *c; |
|
145 uint i = (e->we.click.pt.y - w->widget[3].top) / 10 + w->vscroll.pos; |
|
146 |
|
147 for (c = _all_grfs; c != NULL && i > 0; c = c->next, i--); |
|
148 WP(w, newgrf_add_d).sel = c; |
|
149 SetWindowDirty(w); |
|
150 break; |
|
151 } |
|
152 |
|
153 case 6: /* Add selection to list */ |
|
154 if (WP(w, newgrf_add_d).sel != NULL) { |
|
155 const GRFConfig *src = WP(w, newgrf_add_d).sel; |
|
156 GRFConfig **list, *c; |
|
157 |
|
158 /* Find last entry in the list, checking for duplicate grfid on the way */ |
|
159 for (list = WP(w, newgrf_add_d).list; *list != NULL; list = &(*list)->next) { |
|
160 if ((*list)->grfid == src->grfid) { |
|
161 ShowErrorMessage(INVALID_STRING_ID, STR_NEWGRF_DUPLICATE_GRFID, 0, 0); |
|
162 return; |
|
163 } |
|
164 } |
|
165 |
|
166 /* Copy GRF details from scanned list */ |
|
167 c = calloc(1, sizeof(*c)); |
|
168 *c = *src; |
|
169 c->filename = strdup(src->filename); |
|
170 if (src->name != NULL) c->name = strdup(src->name); |
|
171 if (src->info != NULL) c->info = strdup(src->info); |
|
172 c->next = NULL; |
|
173 |
|
174 /* Append GRF config to configuration list */ |
|
175 *list = c; |
|
176 |
|
177 DeleteWindowByClass(WC_SAVELOAD); |
|
178 InvalidateWindowData(WC_GAME_OPTIONS, 0); |
|
179 } |
|
180 break; |
|
181 |
|
182 case 7: /* Rescan list */ |
|
183 WP(w, newgrf_add_d).sel = NULL; |
|
184 ScanNewGRFFiles(); |
|
185 SetWindowDirty(w); |
|
186 break; |
|
187 } |
|
188 break; |
|
189 } |
|
190 } |
|
191 |
|
192 |
|
193 static const Widget _newgrf_add_dlg_widgets[] = { |
|
194 { WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW }, |
|
195 { WWT_CAPTION, RESIZE_RIGHT, 14, 11, 306, 0, 13, STR_NEWGRF_ADD_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS }, |
|
196 |
|
197 /* List of files */ |
|
198 { WWT_PANEL, RESIZE_RB, 14, 0, 294, 14, 221, 0x0, STR_NULL }, |
|
199 { WWT_INSET, RESIZE_RB, 14, 2, 292, 16, 219, 0x0, STR_NULL }, |
|
200 { WWT_SCROLLBAR, RESIZE_LRB, 14, 295, 306, 14, 221, 0x0, STR_NULL }, |
|
201 |
|
202 /* NewGRF file info */ |
|
203 { WWT_PANEL, RESIZE_RTB, 14, 0, 306, 222, 324, 0x0, STR_NULL }, |
|
204 |
|
205 { WWT_PUSHTXTBTN, RESIZE_RTB, 14, 0, 146, 325, 336, STR_NEWGRF_ADD_FILE, STR_NEWGRF_ADD_FILE_TIP }, |
|
206 { WWT_PUSHTXTBTN, RESIZE_LRTB, 14, 147, 294, 325, 336, STR_NEWGRF_RESCAN_FILES, STR_NEWGRF_RESCAN_FILES_TIP }, |
|
207 { WWT_RESIZEBOX, RESIZE_LRTB, 14, 295, 306, 325, 336, 0x0, STR_RESIZE_BUTTON }, |
|
208 { WIDGETS_END }, |
|
209 }; |
|
210 |
|
211 |
|
212 static const WindowDesc _newgrf_add_dlg_desc = { |
|
213 WDP_CENTER, WDP_CENTER, 307, 337, |
|
214 WC_SAVELOAD, 0, |
|
215 WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE, |
|
216 _newgrf_add_dlg_widgets, |
|
217 NewGRFAddDlgWndProc, |
|
218 }; |
|
219 |
|
220 |
|
221 /* 'NewGRF Settings' dialogue */ |
|
222 typedef struct newgrf_d { |
|
223 GRFConfig **orig_list; ///< grf list the window is shown with |
|
224 GRFConfig **list; ///< temporary grf list to which changes are made |
|
225 GRFConfig *sel; ///< selected grf item |
|
226 bool editable; ///< is the window editable |
|
227 bool show_params; ///< are the grf-parameters shown in the info-panel |
|
228 bool execute; ///< on pressing 'apply changes' are grf changes applied immediately, or only list is updated |
|
229 } newgrf_d; |
|
230 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(newgrf_d)); |
|
231 |
|
232 |
|
233 enum ShowNewGRFStateWidgets { |
|
234 SNGRFS_ADD = 3, |
|
235 SNGRFS_REMOVE, |
|
236 SNGRFS_MOVE_UP, |
|
237 SNGRFS_MOVE_DOWN, |
|
238 SNGRFS_FILE_LIST = 7, |
|
239 SNGRFS_NEWGRF_INFO = 9, |
|
240 SNGRFS_SET_PARAMETERS, |
|
241 SNGRFS_APPLY_CHANGES, |
|
242 }; |
|
243 |
|
244 |
|
245 static void SetupNewGRFState(Window *w) |
|
246 { |
|
247 bool disable_all = WP(w, newgrf_d).sel == NULL || !WP(w, newgrf_d).editable; |
|
248 |
|
249 SetWindowWidgetDisabledState(w, 3, !WP(w, newgrf_d).editable); |
|
250 SetWindowWidgetsDisabledState(w, disable_all, |
|
251 SNGRFS_REMOVE, |
|
252 SNGRFS_MOVE_UP, |
|
253 SNGRFS_MOVE_DOWN, |
|
254 WIDGET_LIST_END |
|
255 ); |
|
256 SetWindowWidgetDisabledState(w, SNGRFS_SET_PARAMETERS, !WP(w, newgrf_d).show_params || disable_all); |
|
257 |
|
258 if (!disable_all) { |
|
259 /* All widgets are now enabled, so disable widgets we can't use */ |
|
260 if (WP(w, newgrf_d).sel == *WP(w, newgrf_d).list) DisableWindowWidget(w, SNGRFS_MOVE_UP); |
|
261 if (WP(w, newgrf_d).sel->next == NULL) DisableWindowWidget(w, SNGRFS_MOVE_DOWN); |
|
262 } |
|
263 } |
|
264 |
|
265 |
|
266 static void SetupNewGRFWindow(Window *w) |
|
267 { |
|
268 const GRFConfig *c; |
|
269 int i; |
|
270 |
|
271 for (c = *WP(w, newgrf_d).list, i = 0; c != NULL; c = c->next, i++); |
|
272 |
|
273 w->vscroll.cap = (w->widget[SNGRFS_FILE_LIST].bottom - w->widget[SNGRFS_FILE_LIST].top) / 14 + 1; |
|
274 SetVScrollCount(w, i); |
|
275 SetWindowWidgetDisabledState(w, SNGRFS_APPLY_CHANGES, !WP(w, newgrf_d).editable); |
|
276 } |
|
277 |
|
278 |
|
279 /** Callback function for the newgrf 'apply changes' confirmation window |
|
280 * @param yes_clicked boolean value, true when yes was clicked, false otherwise */ |
|
281 static void NewGRFConfirmationCallback(Window *w, bool confirmed) |
|
282 { |
|
283 if (confirmed) { |
|
284 newgrf_d *nd = &WP(w, newgrf_d); |
|
285 |
|
286 CopyGRFConfigList(nd->orig_list, *nd->list); |
|
287 ReloadNewGRFData(); |
|
288 } |
|
289 } |
|
290 |
|
291 |
|
292 static void NewGRFWndProc(Window *w, WindowEvent *e) |
|
293 { |
|
294 switch (e->event) { |
|
295 case WE_PAINT: { |
|
296 const GRFConfig *c; |
|
297 int i, y; |
|
298 |
|
299 SetupNewGRFState(w); |
|
300 |
|
301 DrawWindowWidgets(w); |
|
302 |
|
303 /* Draw NewGRF list */ |
|
304 y = w->widget[SNGRFS_FILE_LIST].top; |
|
305 for (c = *WP(w, newgrf_d).list, i = 0; c != NULL; c = c->next, i++) { |
|
306 if (i >= w->vscroll.pos && i < w->vscroll.pos + w->vscroll.cap) { |
|
307 const char *text = (c->name != NULL && strlen(c->name) != 0) ? c->name : c->filename; |
|
308 PalSpriteID pal; |
|
309 |
|
310 /* Pick a colour */ |
|
311 if (HASBIT(c->flags, GCF_NOT_FOUND) || HASBIT(c->flags, GCF_DISABLED)) { |
|
312 pal = PALETTE_TO_RED; |
|
313 } else if (HASBIT(c->flags, GCF_STATIC)) { |
|
314 pal = PALETTE_TO_YELLOW; |
|
315 } else if (HASBIT(c->flags, GCF_ACTIVATED)) { |
|
316 pal = PALETTE_TO_GREEN; |
|
317 } else { |
|
318 pal = PALETTE_TO_BLUE; |
|
319 } |
|
320 |
|
321 DrawSprite(SPRITE_PALETTE(SPR_SQUARE | pal), 5, y + 2); |
|
322 DoDrawString(text, 25, y + 3, WP(w, newgrf_d).sel == c ? 0xC : 0x10); |
|
323 y += 14; |
|
324 } |
|
325 } |
|
326 |
|
327 if (WP(w, newgrf_d).sel != NULL) { |
|
328 /* Draw NewGRF file info */ |
|
329 const Widget *wi = &w->widget[SNGRFS_NEWGRF_INFO]; |
|
330 ShowNewGRFInfo(WP(w, newgrf_d).sel, wi->left + 2, wi->top + 2, wi->right - wi->left - 2, WP(w, newgrf_d).show_params); |
|
331 } |
|
332 |
|
333 break; |
|
334 } |
|
335 |
|
336 case WE_INVALIDATE_DATA: |
|
337 SetupNewGRFWindow(w); |
|
338 break; |
|
339 |
|
340 case WE_CLICK: |
|
341 switch (e->we.click.widget) { |
|
342 case SNGRFS_ADD: { /* Add GRF */ |
|
343 GRFConfig **list = WP(w, newgrf_d).list; |
|
344 Window *w; |
|
345 |
|
346 DeleteWindowByClass(WC_SAVELOAD); |
|
347 w = AllocateWindowDesc(&_newgrf_add_dlg_desc); |
|
348 w->resize.step_height = 10; |
|
349 |
|
350 WP(w, newgrf_add_d).list = list; |
|
351 break; |
|
352 } |
|
353 |
|
354 case SNGRFS_REMOVE: { /* Remove GRF */ |
|
355 GRFConfig **pc, *c, *newsel; |
|
356 |
|
357 /* Choose the next GRF file to be the selected file */ |
|
358 newsel = WP(w, newgrf_d).sel->next; |
|
359 |
|
360 for (pc = WP(w, newgrf_d).list; (c = *pc) != NULL; pc = &c->next) { |
|
361 /* If the new selection is empty (i.e. we're deleting the last item |
|
362 * in the list, pick the file just before the selected file */ |
|
363 if (newsel == NULL && c->next == WP(w, newgrf_d).sel) newsel = c; |
|
364 |
|
365 if (c == WP(w, newgrf_d).sel) { |
|
366 *pc = c->next; |
|
367 free(c); |
|
368 break; |
|
369 } |
|
370 } |
|
371 |
|
372 WP(w, newgrf_d).sel = newsel; |
|
373 SetupNewGRFWindow(w); |
|
374 SetWindowDirty(w); |
|
375 break; |
|
376 } |
|
377 |
|
378 case SNGRFS_MOVE_UP: { /* Move GRF up */ |
|
379 GRFConfig **pc, *c; |
|
380 if (WP(w, newgrf_d).sel == NULL) break; |
|
381 |
|
382 for (pc = WP(w, newgrf_d).list; (c = *pc) != NULL; pc = &c->next) { |
|
383 if (c->next == WP(w, newgrf_d).sel) { |
|
384 c->next = WP(w, newgrf_d).sel->next; |
|
385 WP(w, newgrf_d).sel->next = c; |
|
386 *pc = WP(w, newgrf_d).sel; |
|
387 break; |
|
388 } |
|
389 } |
|
390 SetWindowDirty(w); |
|
391 break; |
|
392 } |
|
393 |
|
394 case SNGRFS_MOVE_DOWN: { /* Move GRF down */ |
|
395 GRFConfig **pc, *c; |
|
396 if (WP(w, newgrf_d).sel == NULL) break; |
|
397 |
|
398 for (pc = WP(w, newgrf_d).list; (c = *pc) != NULL; pc = &c->next) { |
|
399 if (c == WP(w, newgrf_d).sel) { |
|
400 *pc = c->next; |
|
401 c->next = c->next->next; |
|
402 (*pc)->next = c; |
|
403 break; |
|
404 } |
|
405 } |
|
406 SetWindowDirty(w); |
|
407 break; |
|
408 } |
|
409 |
|
410 case SNGRFS_FILE_LIST: { /* Select a GRF */ |
|
411 GRFConfig *c; |
|
412 uint i = (e->we.click.pt.y - w->widget[SNGRFS_FILE_LIST].top) / 14 + w->vscroll.pos; |
|
413 |
|
414 for (c = *WP(w, newgrf_d).list; c != NULL && i > 0; c = c->next, i--); |
|
415 WP(w, newgrf_d).sel = c; |
|
416 |
|
417 SetWindowDirty(w); |
|
418 break; |
|
419 } |
|
420 |
|
421 case SNGRFS_APPLY_CHANGES: /* Apply changes made to GRF list */ |
|
422 if (WP(w, newgrf_d).execute) { |
|
423 ShowQuery( |
|
424 STR_POPUP_CAUTION_CAPTION, |
|
425 STR_NEWGRF_CONFIRMATION_TEXT, |
|
426 w, |
|
427 NewGRFConfirmationCallback |
|
428 ); |
|
429 } else { |
|
430 CopyGRFConfigList(WP(w, newgrf_d).orig_list, *WP(w, newgrf_d).list); |
|
431 } |
|
432 break; |
|
433 |
|
434 case SNGRFS_SET_PARAMETERS: { /* Edit parameters */ |
|
435 char buff[512]; |
|
436 if (WP(w, newgrf_d).sel == NULL) break; |
|
437 |
|
438 GRFBuildParamList(buff, WP(w, newgrf_d).sel, lastof(buff)); |
|
439 ShowQueryString(BindCString(buff), STR_NEWGRF_PARAMETER_QUERY, 63, 250, w, CS_ALPHANUMERAL); |
|
440 break; |
|
441 } |
|
442 } |
|
443 break; |
|
444 |
|
445 case WE_ON_EDIT_TEXT: |
|
446 if (e->we.edittext.str != NULL) { |
|
447 /* Parse our new "int list" */ |
|
448 GRFConfig *c = WP(w, newgrf_d).sel; |
|
449 c->num_params = parse_intlist(e->we.edittext.str, (int*)c->param, lengthof(c->param)); |
|
450 |
|
451 /* parse_intlist returns -1 on error */ |
|
452 if (c->num_params == (byte)-1) c->num_params = 0; |
|
453 } |
|
454 SetWindowDirty(w); |
|
455 break; |
|
456 |
|
457 case WE_DESTROY: |
|
458 /* Remove the temporary copy of grf-list used in window */ |
|
459 ClearGRFConfigList(WP(w, newgrf_d).list); |
|
460 break; |
|
461 |
|
462 case WE_RESIZE: |
|
463 w->vscroll.cap += e->we.sizing.diff.y / 14; |
|
464 w->widget[SNGRFS_FILE_LIST].data = (w->vscroll.cap << 8) + 1; |
|
465 break; |
|
466 } |
|
467 } |
|
468 |
|
469 |
|
470 static const Widget _newgrf_widgets[] = { |
|
471 { WWT_CLOSEBOX, RESIZE_NONE, 10, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW }, |
|
472 { WWT_CAPTION, RESIZE_RIGHT, 10, 11, 299, 0, 13, STR_NEWGRF_SETTINGS_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS }, |
|
473 |
|
474 /* NewGRF file Add, Remove, Move up, Move down */ |
|
475 { WWT_PANEL, RESIZE_RIGHT, 10, 0, 299, 14, 29, STR_NULL, STR_NULL }, |
|
476 { WWT_PUSHTXTBTN, RESIZE_NONE, 3, 10, 79, 16, 27, STR_NEWGRF_ADD, STR_NEWGRF_ADD_TIP }, |
|
477 { WWT_PUSHTXTBTN, RESIZE_NONE, 3, 80, 149, 16, 27, STR_NEWGRF_REMOVE, STR_NEWGRF_REMOVE_TIP }, |
|
478 { WWT_PUSHTXTBTN, RESIZE_NONE, 3, 150, 219, 16, 27, STR_NEWGRF_MOVEUP, STR_NEWGRF_MOVEUP_TIP }, |
|
479 { WWT_PUSHTXTBTN, RESIZE_NONE, 3, 220, 289, 16, 27, STR_NEWGRF_MOVEDOWN, STR_NEWGRF_MOVEDOWN_TIP }, |
|
480 |
|
481 /* NewGRF file list */ |
|
482 { WWT_MATRIX, RESIZE_RB, 10, 0, 287, 30, 99, 0x501, STR_NEWGRF_FILE_TIP }, |
|
483 { WWT_SCROLLBAR, RESIZE_LRB, 10, 288, 299, 30, 99, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST }, |
|
484 |
|
485 /* NewGRF file info */ |
|
486 { WWT_PANEL, RESIZE_RTB, 10, 0, 299, 100, 212, STR_NULL, STR_NULL }, |
|
487 |
|
488 /* Edit parameter and apply changes button... */ |
|
489 { WWT_PUSHTXTBTN, RESIZE_TB, 10, 0, 143, 213, 224, STR_NEWGRF_SET_PARAMETERS, STR_NULL }, |
|
490 { WWT_PUSHTXTBTN, RESIZE_RTB, 10, 144, 287, 213, 224, STR_NEWGRF_APPLY_CHANGES, STR_NULL }, |
|
491 |
|
492 { WWT_RESIZEBOX, RESIZE_LRTB, 10, 288, 299, 213, 224, 0x0, STR_RESIZE_BUTTON }, |
|
493 |
|
494 { WIDGETS_END }, |
|
495 }; |
|
496 |
|
497 |
|
498 static const WindowDesc _newgrf_desc = { |
|
499 WDP_CENTER, WDP_CENTER, 300, 225, |
|
500 WC_GAME_OPTIONS, 0, |
|
501 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE, |
|
502 _newgrf_widgets, |
|
503 NewGRFWndProc, |
|
504 }; |
|
505 |
|
506 |
|
507 /** Setup the NewGRF gui |
|
508 * @param editable allow the user to make changes to the grfconfig in the window |
|
509 * @param show_params show information about what parameters are set for the grf files |
|
510 * @param exec_changes if changes are made to the list (editable is true), apply these |
|
511 * changes immediately or only update the list |
|
512 * @param config pointer to a linked-list of grfconfig's that will be shown */ |
|
513 void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfig **config) |
|
514 { |
|
515 static GRFConfig *local = NULL; |
|
516 Window *w; |
|
517 |
|
518 DeleteWindowByClass(WC_GAME_OPTIONS); |
|
519 w = AllocateWindowDesc(&_newgrf_desc); |
|
520 if (w == NULL) return; |
|
521 |
|
522 w->resize.step_height = 14; |
|
523 CopyGRFConfigList(&local, *config); |
|
524 |
|
525 /* Clear selections */ |
|
526 WP(w, newgrf_d).sel = NULL; |
|
527 WP(w, newgrf_d).list = &local; |
|
528 WP(w, newgrf_d).orig_list = config; |
|
529 WP(w, newgrf_d).editable = editable; |
|
530 WP(w, newgrf_d).execute = exec_changes; |
|
531 WP(w, newgrf_d).show_params = show_params; |
|
532 |
|
533 SetupNewGRFWindow(w); |
|
534 } |