129 } |
113 } |
130 return false; |
114 return false; |
131 } |
115 } |
132 |
116 |
133 |
117 |
|
118 enum GameOptionsWidgets { |
|
119 GAMEOPT_CURRENCY_BTN = 4, |
|
120 GAMEOPT_DISTANCE_BTN = 6, |
|
121 GAMEOPT_ROADSIDE_BTN = 8, |
|
122 GAMEOPT_TOWNNAME_BTN = 10, |
|
123 GAMEOPT_AUTOSAVE_BTN = 12, |
|
124 GAMEOPT_VEHICLENAME_BTN = 14, |
|
125 GAMEOPT_VEHICLENAME_SAVE, |
|
126 GAMEOPT_LANG_BTN = 17, |
|
127 GAMEOPT_RESOLUTION_BTN = 19, |
|
128 GAMEOPT_FULLSCREEN, |
|
129 GAMEOPT_SCREENSHOT_BTN = 22, |
|
130 }; |
|
131 |
|
132 /** |
|
133 * Update/redraw the townnames dropdown |
|
134 * @param w the window the dropdown belongs to |
|
135 * @param sel the currently selected townname generator |
|
136 */ |
|
137 static void ShowTownnameDropdown(Window *w, int sel) |
|
138 { |
|
139 typedef std::map<StringID, int, StringIDCompare> TownList; |
|
140 TownList townnames; |
|
141 |
|
142 /* Add and sort original townnames generators */ |
|
143 for (int i = 0; i < _nb_orig_names; i++) townnames[STR_TOWNNAME_ORIGINAL_ENGLISH + i] = i; |
|
144 |
|
145 /* Add and sort newgrf townnames generators */ |
|
146 for (int i = 0; i < _nb_grf_names; i++) townnames[_grf_names[i]] = _nb_orig_names + i; |
|
147 |
|
148 DropDownList *list = new DropDownList(); |
|
149 for (TownList::iterator it = townnames.begin(); it != townnames.end(); it++) { |
|
150 list->push_back(new DropDownListStringItem((*it).first, (*it).second, !(_game_mode == GM_MENU || (*it).second == sel))); |
|
151 } |
|
152 |
|
153 ShowDropDownList(w, list, sel, GAMEOPT_TOWNNAME_BTN); |
|
154 } |
|
155 |
|
156 /** |
|
157 * Update/redraw the languages dropdown |
|
158 * @param w the window the dropdown belongs to |
|
159 */ |
|
160 static void ShowLangDropdown(Window *w) |
|
161 { |
|
162 typedef std::map<StringID, int, StringIDCompare> LangList; |
|
163 |
|
164 /* Sort language names */ |
|
165 LangList langs; |
|
166 for (int i = 0; i < _dynlang.num; i++) langs[SPECSTR_LANGUAGE_START + i] = i; |
|
167 |
|
168 DropDownList *list = new DropDownList(); |
|
169 for (LangList::iterator it = langs.begin(); it != langs.end(); it++) { |
|
170 list->push_back(new DropDownListStringItem((*it).first, (*it).second, false)); |
|
171 } |
|
172 |
|
173 ShowDropDownList(w, list, _dynlang.curr, GAMEOPT_LANG_BTN); |
|
174 } |
|
175 |
134 static void ShowCustCurrency(); |
176 static void ShowCustCurrency(); |
135 |
177 |
136 static void GameOptionsWndProc(Window *w, WindowEvent *e) |
178 static void GameOptionsWndProc(Window *w, WindowEvent *e) |
137 { |
179 { |
138 switch (e->event) { |
180 switch (e->event) { |
139 case WE_PAINT: { |
181 case WE_PAINT: { |
140 int i; |
182 int i; |
141 StringID str = STR_02BE_DEFAULT; |
183 StringID str = STR_02BE_DEFAULT; |
142 |
184 |
143 w->SetWidgetDisabledState(21, !(_vehicle_design_names & 1)); |
185 w->SetWidgetDisabledState(GAMEOPT_VEHICLENAME_SAVE, !(_vehicle_design_names & 1)); |
144 if (!w->IsWidgetDisabled(21)) str = STR_02BF_CUSTOM; |
186 if (!w->IsWidgetDisabled(GAMEOPT_VEHICLENAME_SAVE)) str = STR_02BF_CUSTOM; |
145 SetDParam(0, str); |
187 SetDParam(0, str); |
146 SetDParam(1, _currency_specs[_opt_ptr->currency].name); |
188 SetDParam(1, _currency_specs[_opt_ptr->currency].name); |
147 SetDParam(2, STR_UNITS_IMPERIAL + _opt_ptr->units); |
189 SetDParam(2, STR_UNITS_IMPERIAL + _opt_ptr->units); |
148 SetDParam(3, STR_02E9_DRIVE_ON_LEFT + _opt_ptr->road_side); |
190 SetDParam(3, STR_02E9_DRIVE_ON_LEFT + _opt_ptr->road_side); |
149 SetDParam(4, TownName(_opt_ptr->town_name)); |
191 SetDParam(4, TownName(_opt_ptr->town_name)); |
150 SetDParam(5, _autosave_dropdown[_opt_ptr->autosave]); |
192 SetDParam(5, _autosave_dropdown[_opt_ptr->autosave]); |
151 SetDParam(6, SPECSTR_LANGUAGE_START + _dynlang.curr); |
193 SetDParam(6, SPECSTR_LANGUAGE_START + _dynlang.curr); |
152 i = GetCurRes(); |
194 i = GetCurRes(); |
153 SetDParam(7, i == _num_resolutions ? STR_RES_OTHER : SPECSTR_RESOLUTION_START + i); |
195 SetDParam(7, i == _num_resolutions ? STR_RES_OTHER : SPECSTR_RESOLUTION_START + i); |
154 SetDParam(8, SPECSTR_SCREENSHOT_START + _cur_screenshot_format); |
196 SetDParam(8, SPECSTR_SCREENSHOT_START + _cur_screenshot_format); |
155 w->SetWidgetLoweredState(28, _fullscreen); |
197 w->SetWidgetLoweredState(GAMEOPT_FULLSCREEN, _fullscreen); |
156 |
198 |
157 DrawWindowWidgets(w); |
199 DrawWindowWidgets(w); |
158 DrawString(20, 175, STR_OPTIONS_FULLSCREEN, TC_FROMSTRING); // fullscreen |
200 DrawString(20, 175, STR_OPTIONS_FULLSCREEN, TC_FROMSTRING); // fullscreen |
159 } break; |
201 } break; |
160 |
202 |
161 case WE_CLICK: |
203 case WE_CLICK: |
162 switch (e->we.click.widget) { |
204 switch (e->we.click.widget) { |
163 case 4: case 5: /* Setup currencies dropdown */ |
205 case GAMEOPT_CURRENCY_BTN: /* Setup currencies dropdown */ |
164 ShowDropDownMenu(w, BuildCurrencyDropdown(), _opt_ptr->currency, 5, _game_mode == GM_MENU ? 0 : ~GetMaskOfAllowedCurrencies(), 0);; |
206 ShowDropDownMenu(w, BuildCurrencyDropdown(), _opt_ptr->currency, GAMEOPT_CURRENCY_BTN, _game_mode == GM_MENU ? 0 : ~GetMaskOfAllowedCurrencies(), 0); |
165 return; |
207 break; |
166 case 7: case 8: /* Setup distance unit dropdown */ |
208 |
167 ShowDropDownMenu(w, _units_dropdown, _opt_ptr->units, 8, 0, 0); |
209 case GAMEOPT_DISTANCE_BTN: /* Setup distance unit dropdown */ |
168 return; |
210 ShowDropDownMenu(w, _units_dropdown, _opt_ptr->units, GAMEOPT_DISTANCE_BTN, 0, 0); |
169 case 10: case 11: { /* Setup road-side dropdown */ |
211 break; |
170 int i = 0; |
212 |
171 |
213 case GAMEOPT_ROADSIDE_BTN: { /* Setup road-side dropdown */ |
172 /* You can only change the drive side if you are in the menu or ingame with |
214 int i = 0; |
173 * no vehicles present. In a networking game only the server can change it */ |
215 |
174 if ((_game_mode != GM_MENU && RoadVehiclesAreBuilt()) || (_networking && !_network_server)) |
216 /* You can only change the drive side if you are in the menu or ingame with |
175 i = (-1) ^ (1 << _opt_ptr->road_side); // disable the other value |
217 * no vehicles present. In a networking game only the server can change it */ |
176 |
218 if ((_game_mode != GM_MENU && RoadVehiclesAreBuilt()) || (_networking && !_network_server)) |
177 ShowDropDownMenu(w, _driveside_dropdown, _opt_ptr->road_side, 11, i, 0); |
219 i = (-1) ^ (1 << _opt_ptr->road_side); // disable the other value |
178 } return; |
220 |
179 case 13: case 14: { /* Setup townname dropdown */ |
221 ShowDropDownMenu(w, _driveside_dropdown, _opt_ptr->road_side, GAMEOPT_ROADSIDE_BTN, i, 0); |
180 uint sel = 0; |
222 } break; |
181 for (uint i = 0; _town_names[i] != INVALID_STRING_ID; i++) { |
223 |
182 if (_town_names[i] == TownName(_opt_ptr->town_name)) { |
224 case GAMEOPT_TOWNNAME_BTN: /* Setup townname dropdown */ |
183 sel = i; |
225 ShowTownnameDropdown(w, _opt_ptr->town_name); |
184 break; |
226 break; |
185 } |
227 |
186 } |
228 case GAMEOPT_AUTOSAVE_BTN: /* Setup autosave dropdown */ |
187 ShowDropDownMenu(w, _town_names, sel, 14, (_game_mode == GM_MENU) ? 0 : (-1) ^ (1 << sel), 0); |
229 ShowDropDownMenu(w, _autosave_dropdown, _opt_ptr->autosave, GAMEOPT_AUTOSAVE_BTN, 0, 0); |
188 return; |
230 break; |
189 } |
231 |
190 case 16: case 17: /* Setup autosave dropdown */ |
232 case GAMEOPT_VEHICLENAME_BTN: /* Setup customized vehicle-names dropdown */ |
191 ShowDropDownMenu(w, _autosave_dropdown, _opt_ptr->autosave, 17, 0, 0); |
233 ShowDropDownMenu(w, _designnames_dropdown, (_vehicle_design_names & 1) ? 1 : 0, GAMEOPT_VEHICLENAME_BTN, (_vehicle_design_names & 2) ? 0 : 2, 0); |
192 return; |
234 break; |
193 case 19: case 20: /* Setup customized vehicle-names dropdown */ |
235 |
194 ShowDropDownMenu(w, _designnames_dropdown, (_vehicle_design_names & 1) ? 1 : 0, 20, (_vehicle_design_names & 2) ? 0 : 2, 0); |
236 case GAMEOPT_VEHICLENAME_SAVE: /* Save customized vehicle-names to disk */ |
195 return; |
237 break; // not implemented |
196 case 21: /* Save customized vehicle-names to disk */ |
238 |
197 return; |
239 case GAMEOPT_LANG_BTN: /* Setup interface language dropdown */ |
198 case 23: case 24: /* Setup interface language dropdown */ |
240 ShowLangDropdown(w); |
199 ShowDropDownMenu(w, _dynlang.dropdown, _dynlang.curr, 24, 0, 0); |
241 break; |
200 return; |
242 |
201 case 26: case 27: /* Setup resolution dropdown */ |
243 case GAMEOPT_RESOLUTION_BTN: /* Setup resolution dropdown */ |
202 ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_RESOLUTION_START, _num_resolutions), GetCurRes(), 27, 0, 0); |
244 ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_RESOLUTION_START, _num_resolutions), GetCurRes(), GAMEOPT_RESOLUTION_BTN, 0, 0); |
203 return; |
245 break; |
204 case 28: /* Click fullscreen on/off */ |
246 |
205 w->SetWidgetLoweredState(28, !_fullscreen); |
247 case GAMEOPT_FULLSCREEN: /* Click fullscreen on/off */ |
206 ToggleFullScreen(!_fullscreen); // toggle full-screen on/off |
248 /* try to toggle full-screen on/off */ |
207 SetWindowDirty(w); |
249 if (!ToggleFullScreen(!_fullscreen)) { |
208 return; |
250 ShowErrorMessage(INVALID_STRING_ID, STR_FULLSCREEN_FAILED, 0, 0); |
209 case 30: case 31: /* Setup screenshot format dropdown */ |
251 } |
210 ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_SCREENSHOT_START, _num_screenshot_formats), _cur_screenshot_format, 31, 0, 0); |
252 w->SetWidgetLoweredState(GAMEOPT_FULLSCREEN, _fullscreen); |
211 return; |
253 SetWindowDirty(w); |
212 } |
254 break; |
213 break; |
255 |
214 |
256 case GAMEOPT_SCREENSHOT_BTN: /* Setup screenshot format dropdown */ |
215 case WE_DROPDOWN_SELECT: |
257 ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_SCREENSHOT_START, _num_screenshot_formats), _cur_screenshot_format, GAMEOPT_SCREENSHOT_BTN, 0, 0); |
216 switch (e->we.dropdown.button) { |
258 break; |
217 case 20: /* Vehicle design names */ |
|
218 if (e->we.dropdown.index == 0) { |
|
219 DeleteCustomEngineNames(); |
|
220 MarkWholeScreenDirty(); |
|
221 } else if (!(_vehicle_design_names & 1)) { |
|
222 LoadCustomEngineNames(); |
|
223 MarkWholeScreenDirty(); |
|
224 } |
259 } |
225 break; |
260 break; |
226 case 5: /* Currency */ |
261 |
227 if (e->we.dropdown.index == CUSTOM_CURRENCY_ID) ShowCustCurrency(); |
262 case WE_DROPDOWN_SELECT: |
228 _opt_ptr->currency = e->we.dropdown.index; |
263 switch (e->we.dropdown.button) { |
229 MarkWholeScreenDirty(); |
264 case GAMEOPT_VEHICLENAME_BTN: /* Vehicle design names */ |
230 break; |
265 if (e->we.dropdown.index == 0) { |
231 case 8: /* Measuring units */ |
266 DeleteCustomEngineNames(); |
232 _opt_ptr->units = e->we.dropdown.index; |
267 MarkWholeScreenDirty(); |
233 MarkWholeScreenDirty(); |
268 } else if (!(_vehicle_design_names & 1)) { |
234 break; |
269 LoadCustomEngineNames(); |
235 case 11: /* Road side */ |
270 MarkWholeScreenDirty(); |
236 if (_opt_ptr->road_side != e->we.dropdown.index) { // only change if setting changed |
271 } |
237 DoCommandP(0, e->we.dropdown.index, 0, NULL, CMD_SET_ROAD_DRIVE_SIDE | CMD_MSG(STR_00B4_CAN_T_DO_THIS)); |
272 break; |
238 MarkWholeScreenDirty(); |
273 |
|
274 case GAMEOPT_CURRENCY_BTN: /* Currency */ |
|
275 if (e->we.dropdown.index == CUSTOM_CURRENCY_ID) ShowCustCurrency(); |
|
276 _opt_ptr->currency = e->we.dropdown.index; |
|
277 MarkWholeScreenDirty(); |
|
278 break; |
|
279 |
|
280 case GAMEOPT_DISTANCE_BTN: /* Measuring units */ |
|
281 _opt_ptr->units = e->we.dropdown.index; |
|
282 MarkWholeScreenDirty(); |
|
283 break; |
|
284 |
|
285 case GAMEOPT_ROADSIDE_BTN: /* Road side */ |
|
286 if (_opt_ptr->road_side != e->we.dropdown.index) { // only change if setting changed |
|
287 DoCommandP(0, e->we.dropdown.index, 0, NULL, CMD_SET_ROAD_DRIVE_SIDE | CMD_MSG(STR_00B4_CAN_T_DO_THIS)); |
|
288 MarkWholeScreenDirty(); |
|
289 } |
|
290 break; |
|
291 |
|
292 case GAMEOPT_TOWNNAME_BTN: /* Town names */ |
|
293 if (_game_mode == GM_MENU) { |
|
294 _opt_ptr->town_name = e->we.dropdown.index; |
|
295 InvalidateWindow(WC_GAME_OPTIONS, 0); |
|
296 } |
|
297 break; |
|
298 |
|
299 case GAMEOPT_AUTOSAVE_BTN: /* Autosave options */ |
|
300 _opt.autosave = _opt_newgame.autosave = e->we.dropdown.index; |
|
301 SetWindowDirty(w); |
|
302 break; |
|
303 |
|
304 case GAMEOPT_LANG_BTN: /* Change interface language */ |
|
305 ReadLanguagePack(e->we.dropdown.index); |
|
306 CheckForMissingGlyphsInLoadedLanguagePack(); |
|
307 UpdateAllStationVirtCoord(); |
|
308 MarkWholeScreenDirty(); |
|
309 break; |
|
310 |
|
311 case GAMEOPT_RESOLUTION_BTN: /* Change resolution */ |
|
312 if (e->we.dropdown.index < _num_resolutions && ChangeResInGame(_resolutions[e->we.dropdown.index][0],_resolutions[e->we.dropdown.index][1])) |
|
313 SetWindowDirty(w); |
|
314 break; |
|
315 |
|
316 case GAMEOPT_SCREENSHOT_BTN: /* Change screenshot format */ |
|
317 SetScreenshotFormat(e->we.dropdown.index); |
|
318 SetWindowDirty(w); |
|
319 break; |
239 } |
320 } |
240 break; |
321 break; |
241 case 14: /* Town names */ |
322 |
242 if (_game_mode == GM_MENU) { |
323 case WE_DESTROY: |
243 for (uint i = 0; _town_names[i] != INVALID_STRING_ID; i++) { |
324 DeleteWindowById(WC_CUSTOM_CURRENCY, 0); |
244 if (_town_names[e->we.dropdown.index] == TownName(i)) { |
|
245 _opt_ptr->town_name = i; |
|
246 break; |
|
247 } |
|
248 } |
|
249 InvalidateWindow(WC_GAME_OPTIONS, 0); |
|
250 } |
|
251 break; |
325 break; |
252 case 17: /* Autosave options */ |
|
253 _opt.autosave = _opt_newgame.autosave = e->we.dropdown.index; |
|
254 SetWindowDirty(w); |
|
255 break; |
|
256 case 24: /* Change interface language */ |
|
257 ReadLanguagePack(e->we.dropdown.index); |
|
258 UpdateAllStationVirtCoord(); |
|
259 MarkWholeScreenDirty(); |
|
260 break; |
|
261 case 27: /* Change resolution */ |
|
262 if (e->we.dropdown.index < _num_resolutions && ChangeResInGame(_resolutions[e->we.dropdown.index][0],_resolutions[e->we.dropdown.index][1])) |
|
263 SetWindowDirty(w); |
|
264 break; |
|
265 case 31: /* Change screenshot format */ |
|
266 SetScreenshotFormat(e->we.dropdown.index); |
|
267 SetWindowDirty(w); |
|
268 break; |
|
269 } |
|
270 break; |
|
271 |
|
272 case WE_DESTROY: |
|
273 DeleteWindowById(WC_CUSTOM_CURRENCY, 0); |
|
274 break; |
|
275 } |
326 } |
276 |
327 |
277 } |
328 } |
278 |
329 |
279 /** Change the side of the road vehicles drive on (server only). |
330 /** Change the side of the road vehicles drive on (server only). |
298 static const Widget _game_options_widgets[] = { |
349 static const Widget _game_options_widgets[] = { |
299 { WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
350 { WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
300 { WWT_CAPTION, RESIZE_NONE, 14, 11, 369, 0, 13, STR_00B1_GAME_OPTIONS, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
351 { WWT_CAPTION, RESIZE_NONE, 14, 11, 369, 0, 13, STR_00B1_GAME_OPTIONS, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
301 { WWT_PANEL, RESIZE_NONE, 14, 0, 369, 14, 238, 0x0, STR_NULL}, |
352 { WWT_PANEL, RESIZE_NONE, 14, 0, 369, 14, 238, 0x0, STR_NULL}, |
302 { WWT_FRAME, RESIZE_NONE, 14, 10, 179, 20, 55, STR_02E0_CURRENCY_UNITS, STR_NULL}, |
353 { WWT_FRAME, RESIZE_NONE, 14, 10, 179, 20, 55, STR_02E0_CURRENCY_UNITS, STR_NULL}, |
303 { WWT_INSET, RESIZE_NONE, 14, 20, 169, 34, 45, STR_02E1, STR_02E2_CURRENCY_UNITS_SELECTION}, |
354 { WWT_DROPDOWNIN, RESIZE_NONE, 14, 20, 169, 34, 45, STR_02E1, STR_02E2_CURRENCY_UNITS_SELECTION}, |
304 { WWT_TEXTBTN, RESIZE_NONE, 14, 158, 168, 35, 44, STR_0225, STR_02E2_CURRENCY_UNITS_SELECTION}, |
|
305 { WWT_FRAME, RESIZE_NONE, 14, 190, 359, 20, 55, STR_MEASURING_UNITS, STR_NULL}, |
355 { WWT_FRAME, RESIZE_NONE, 14, 190, 359, 20, 55, STR_MEASURING_UNITS, STR_NULL}, |
306 { WWT_INSET, RESIZE_NONE, 14, 200, 349, 34, 45, STR_02E4, STR_MEASURING_UNITS_SELECTION}, |
356 { WWT_DROPDOWNIN, RESIZE_NONE, 14, 200, 349, 34, 45, STR_02E4, STR_MEASURING_UNITS_SELECTION}, |
307 { WWT_TEXTBTN, RESIZE_NONE, 14, 338, 348, 35, 44, STR_0225, STR_MEASURING_UNITS_SELECTION}, |
|
308 { WWT_FRAME, RESIZE_NONE, 14, 10, 179, 62, 97, STR_02E6_ROAD_VEHICLES, STR_NULL}, |
357 { WWT_FRAME, RESIZE_NONE, 14, 10, 179, 62, 97, STR_02E6_ROAD_VEHICLES, STR_NULL}, |
309 { WWT_INSET, RESIZE_NONE, 14, 20, 169, 76, 87, STR_02E7, STR_02E8_SELECT_SIDE_OF_ROAD_FOR}, |
358 { WWT_DROPDOWNIN, RESIZE_NONE, 14, 20, 169, 76, 87, STR_02E7, STR_02E8_SELECT_SIDE_OF_ROAD_FOR}, |
310 { WWT_TEXTBTN, RESIZE_NONE, 14, 158, 168, 77, 86, STR_0225, STR_02E8_SELECT_SIDE_OF_ROAD_FOR}, |
|
311 { WWT_FRAME, RESIZE_NONE, 14, 190, 359, 62, 97, STR_02EB_TOWN_NAMES, STR_NULL}, |
359 { WWT_FRAME, RESIZE_NONE, 14, 190, 359, 62, 97, STR_02EB_TOWN_NAMES, STR_NULL}, |
312 { WWT_INSET, RESIZE_NONE, 14, 200, 349, 76, 87, STR_02EC, STR_02ED_SELECT_STYLE_OF_TOWN_NAMES}, |
360 { WWT_DROPDOWNIN, RESIZE_NONE, 14, 200, 349, 76, 87, STR_02EC, STR_02ED_SELECT_STYLE_OF_TOWN_NAMES}, |
313 { WWT_TEXTBTN, RESIZE_NONE, 14, 338, 348, 77, 86, STR_0225, STR_02ED_SELECT_STYLE_OF_TOWN_NAMES}, |
|
314 { WWT_FRAME, RESIZE_NONE, 14, 10, 179, 104, 139, STR_02F4_AUTOSAVE, STR_NULL}, |
361 { WWT_FRAME, RESIZE_NONE, 14, 10, 179, 104, 139, STR_02F4_AUTOSAVE, STR_NULL}, |
315 { WWT_INSET, RESIZE_NONE, 14, 20, 169, 118, 129, STR_02F5, STR_02F6_SELECT_INTERVAL_BETWEEN}, |
362 { WWT_DROPDOWNIN, RESIZE_NONE, 14, 20, 169, 118, 129, STR_02F5, STR_02F6_SELECT_INTERVAL_BETWEEN}, |
316 { WWT_TEXTBTN, RESIZE_NONE, 14, 158, 168, 119, 128, STR_0225, STR_02F6_SELECT_INTERVAL_BETWEEN}, |
|
317 |
363 |
318 { WWT_FRAME, RESIZE_NONE, 14, 10, 359, 194, 228, STR_02BC_VEHICLE_DESIGN_NAMES, STR_NULL}, |
364 { WWT_FRAME, RESIZE_NONE, 14, 10, 359, 194, 228, STR_02BC_VEHICLE_DESIGN_NAMES, STR_NULL}, |
319 { WWT_INSET, RESIZE_NONE, 14, 20, 119, 207, 218, STR_02BD, STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION}, |
365 { WWT_DROPDOWNIN, RESIZE_NONE, 14, 20, 119, 207, 218, STR_02BD, STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION}, |
320 { WWT_TEXTBTN, RESIZE_NONE, 14, 108, 118, 208, 217, STR_0225, STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION}, |
|
321 { WWT_TEXTBTN, RESIZE_NONE, 14, 130, 349, 207, 218, STR_02C0_SAVE_CUSTOM_NAMES, STR_02C2_SAVE_CUSTOMIZED_VEHICLE}, |
366 { WWT_TEXTBTN, RESIZE_NONE, 14, 130, 349, 207, 218, STR_02C0_SAVE_CUSTOM_NAMES, STR_02C2_SAVE_CUSTOMIZED_VEHICLE}, |
322 |
367 |
323 { WWT_FRAME, RESIZE_NONE, 14, 190, 359, 104, 139, STR_OPTIONS_LANG, STR_NULL}, |
368 { WWT_FRAME, RESIZE_NONE, 14, 190, 359, 104, 139, STR_OPTIONS_LANG, STR_NULL}, |
324 { WWT_INSET, RESIZE_NONE, 14, 200, 349, 118, 129, STR_OPTIONS_LANG_CBO, STR_OPTIONS_LANG_TIP}, |
369 { WWT_DROPDOWNIN, RESIZE_NONE, 14, 200, 349, 118, 129, STR_OPTIONS_LANG_CBO, STR_OPTIONS_LANG_TIP}, |
325 { WWT_TEXTBTN, RESIZE_NONE, 14, 338, 348, 119, 128, STR_0225, STR_OPTIONS_LANG_TIP}, |
|
326 |
370 |
327 { WWT_FRAME, RESIZE_NONE, 14, 10, 179, 146, 190, STR_OPTIONS_RES, STR_NULL}, |
371 { WWT_FRAME, RESIZE_NONE, 14, 10, 179, 146, 190, STR_OPTIONS_RES, STR_NULL}, |
328 { WWT_INSET, RESIZE_NONE, 14, 20, 169, 160, 171, STR_OPTIONS_RES_CBO, STR_OPTIONS_RES_TIP}, |
372 { WWT_DROPDOWNIN, RESIZE_NONE, 14, 20, 169, 160, 171, STR_OPTIONS_RES_CBO, STR_OPTIONS_RES_TIP}, |
329 { WWT_TEXTBTN, RESIZE_NONE, 14, 158, 168, 161, 170, STR_0225, STR_OPTIONS_RES_TIP}, |
|
330 { WWT_TEXTBTN, RESIZE_NONE, 14, 149, 169, 176, 184, STR_EMPTY, STR_OPTIONS_FULLSCREEN_TIP}, |
373 { WWT_TEXTBTN, RESIZE_NONE, 14, 149, 169, 176, 184, STR_EMPTY, STR_OPTIONS_FULLSCREEN_TIP}, |
331 |
374 |
332 { WWT_FRAME, RESIZE_NONE, 14, 190, 359, 146, 190, STR_OPTIONS_SCREENSHOT_FORMAT, STR_NULL}, |
375 { WWT_FRAME, RESIZE_NONE, 14, 190, 359, 146, 190, STR_OPTIONS_SCREENSHOT_FORMAT, STR_NULL}, |
333 { WWT_INSET, RESIZE_NONE, 14, 200, 349, 160, 171, STR_OPTIONS_SCREENSHOT_FORMAT_CBO, STR_OPTIONS_SCREENSHOT_FORMAT_TIP}, |
376 { WWT_DROPDOWNIN, RESIZE_NONE, 14, 200, 349, 160, 171, STR_OPTIONS_SCREENSHOT_FORMAT_CBO, STR_OPTIONS_SCREENSHOT_FORMAT_TIP}, |
334 { WWT_TEXTBTN, RESIZE_NONE, 14, 338, 348, 161, 170, STR_0225, STR_OPTIONS_SCREENSHOT_FORMAT_TIP}, |
|
335 |
377 |
336 { WIDGETS_END}, |
378 { WIDGETS_END}, |
337 }; |
379 }; |
338 |
380 |
339 static const WindowDesc _game_options_desc = { |
381 static const WindowDesc _game_options_desc = { |
445 /* Temporary holding place of values in the difficulty window until 'Save' is clicked */ |
487 /* Temporary holding place of values in the difficulty window until 'Save' is clicked */ |
446 static GameOptions _opt_mod_temp; |
488 static GameOptions _opt_mod_temp; |
447 // 0x383E = (1 << 13) | (1 << 12) | (1 << 11) | (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1) |
489 // 0x383E = (1 << 13) | (1 << 12) | (1 << 11) | (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1) |
448 #define DIFF_INGAME_DISABLED_BUTTONS 0x383E |
490 #define DIFF_INGAME_DISABLED_BUTTONS 0x383E |
449 |
491 |
|
492 /* Names of the game difficulty settings window */ |
|
493 enum GameDifficultyWidgets { |
|
494 GDW_CLOSEBOX = 0, |
|
495 GDW_CAPTION, |
|
496 GDW_UPPER_BG, |
|
497 GDW_LVL_EASY, |
|
498 GDW_LVL_MEDIUM, |
|
499 GDW_LVL_HARD, |
|
500 GDW_LVL_CUSTOM, |
|
501 GDW_HIGHSCORE, |
|
502 GDW_SETTING_BG, |
|
503 GDW_LOWER_BG, |
|
504 GDW_ACCEPT, |
|
505 GDW_CANCEL, |
|
506 }; |
|
507 |
450 static void GameDifficultyWndProc(Window *w, WindowEvent *e) |
508 static void GameDifficultyWndProc(Window *w, WindowEvent *e) |
451 { |
509 { |
452 switch (e->event) { |
510 switch (e->event) { |
453 case WE_CREATE: // Setup disabled buttons when creating window |
511 case WE_CREATE: |
454 /* disable all other difficulty buttons during gameplay except for 'custom' */ |
512 /* Hide the closebox to make sure that the user aborts or confirms his changes */ |
455 w->SetWidgetDisabledState( 3, _game_mode == GM_NORMAL); |
513 w->HideWidget(GDW_CLOSEBOX); |
456 w->SetWidgetDisabledState( 4, _game_mode == GM_NORMAL); |
514 w->widget[GDW_CAPTION].left = 0; |
457 w->SetWidgetDisabledState( 5, _game_mode == GM_NORMAL); |
515 /* Setup disabled buttons when creating window |
458 w->SetWidgetDisabledState( 6, _game_mode == GM_NORMAL); |
516 * disable all other difficulty buttons during gameplay except for 'custom' */ |
459 w->SetWidgetDisabledState( 7, _game_mode == GM_EDITOR || _networking); // highscore chart in multiplayer |
517 w->SetWidgetsDisabledState(_game_mode == GM_NORMAL, |
460 w->SetWidgetDisabledState(10, _networking && !_network_server); // Save-button in multiplayer (and if client) |
518 GDW_LVL_EASY, |
461 w->LowerWidget(_opt_mod_temp.diff_level + 3); |
519 GDW_LVL_MEDIUM, |
462 |
520 GDW_LVL_HARD, |
463 break; |
521 GDW_LVL_CUSTOM, |
464 case WE_PAINT: { |
522 WIDGET_LIST_END); |
465 uint32 click_a, click_b, disabled; |
523 w->SetWidgetDisabledState(GDW_HIGHSCORE, _game_mode == GM_EDITOR || _networking); // highscore chart in multiplayer |
466 int i; |
524 w->SetWidgetDisabledState(GDW_ACCEPT, _networking && !_network_server); // Save-button in multiplayer (and if client) |
467 int y, value; |
525 w->LowerWidget(GDW_LVL_EASY + _opt_mod_temp.diff_level); |
468 |
526 break; |
469 DrawWindowWidgets(w); |
527 |
470 |
528 case WE_PAINT: { |
471 click_a = _difficulty_click_a; |
529 DrawWindowWidgets(w); |
472 click_b = _difficulty_click_b; |
530 |
473 |
531 /* XXX - Disabled buttons in normal gameplay or during muliplayer as non server. |
474 /* XXX - Disabled buttons in normal gameplay. Bitshifted for each button to see if |
532 * Bitshifted for each button to see if that bit is set. If it is set, the |
475 * that bit is set. If it is set, the button is disabled */ |
533 * button is disabled */ |
476 disabled = (_game_mode == GM_NORMAL) ? DIFF_INGAME_DISABLED_BUTTONS : 0; |
534 uint32 disabled = 0; |
477 |
535 if (_networking && !_network_server) { |
478 y = GAMEDIFF_WND_TOP_OFFSET; |
536 disabled = MAX_UVALUE(uint32); // Disable all |
479 for (i = 0; i != GAME_DIFFICULTY_NUM; i++) { |
537 } else if (_game_mode == GM_NORMAL) { |
480 DrawFrameRect( 5, y, 5 + 8, y + 8, 3, HasBit(click_a, i) ? FR_LOWERED : FR_NONE); |
538 disabled = DIFF_INGAME_DISABLED_BUTTONS; |
481 DrawFrameRect(15, y, 15 + 8, y + 8, 3, HasBit(click_b, i) ? FR_LOWERED : FR_NONE); |
|
482 if (HasBit(disabled, i) || (_networking && !_network_server)) { |
|
483 int color = (1 << PALETTE_MODIFIER_GREYOUT) | _colour_gradient[COLOUR_YELLOW][2]; |
|
484 GfxFillRect( 6, y + 1, 6 + 8, y + 8, color); |
|
485 GfxFillRect(16, y + 1, 16 + 8, y + 8, color); |
|
486 } |
539 } |
487 |
540 |
488 DrawStringCentered(10, y, STR_6819, TC_FROMSTRING); |
541 int value; |
489 DrawStringCentered(20, y, STR_681A, TC_FROMSTRING); |
542 int y = GAMEDIFF_WND_TOP_OFFSET; |
490 |
543 for (uint i = 0; i != GAME_DIFFICULTY_NUM; i++) { |
491 |
544 const GameSettingData *gsd = &_game_setting_info[i]; |
492 value = _game_setting_info[i].str + ((GDType*)&_opt_mod_temp.diff)[i]; |
545 value = ((GDType*)&_opt_mod_temp.diff)[i]; |
493 if (i == 4) value *= 1000; // XXX - handle currency option |
546 |
494 SetDParam(0, value); |
547 DrawArrowButtons(5, y, 3, |
495 DrawString(30, y, STR_6805_MAXIMUM_NO_COMPETITORS + i, TC_FROMSTRING); |
548 !!HasBit(_difficulty_click_a, i) | !!HasBit(_difficulty_click_b, i) << 1, |
496 |
549 !(HasBit(disabled, i) || gsd->min == value), |
497 y += GAMEDIFF_WND_ROWSIZE + 2; // space items apart a bit |
550 !(HasBit(disabled, i) || gsd->max == value)); |
498 } |
551 |
499 } break; |
552 value += _game_setting_info[i].str; |
500 |
553 if (i == 4) value *= 1000; // XXX - handle currency option |
501 case WE_CLICK: |
554 SetDParam(0, value); |
502 switch (e->we.click.widget) { |
555 DrawString(30, y, STR_6805_MAXIMUM_NO_COMPETITORS + i, TC_FROMSTRING); |
503 case 8: { /* Difficulty settings widget, decode click */ |
556 |
504 const GameSettingData *info; |
557 y += GAMEDIFF_WND_ROWSIZE + 2; // space items apart a bit |
505 int x, y; |
|
506 uint btn, dis; |
|
507 int16 val; |
|
508 |
|
509 /* Don't allow clients to make any changes */ |
|
510 if (_networking && !_network_server) |
|
511 return; |
|
512 |
|
513 x = e->we.click.pt.x - 5; |
|
514 if (!IsInsideMM(x, 0, 21)) // Button area |
|
515 return; |
|
516 |
|
517 y = e->we.click.pt.y - GAMEDIFF_WND_TOP_OFFSET; |
|
518 if (y < 0) |
|
519 return; |
|
520 |
|
521 /* Get button from Y coord. */ |
|
522 btn = y / (GAMEDIFF_WND_ROWSIZE + 2); |
|
523 if (btn >= GAME_DIFFICULTY_NUM || y % (GAMEDIFF_WND_ROWSIZE + 2) >= 9) |
|
524 return; |
|
525 |
|
526 /* Clicked disabled button? */ |
|
527 dis = (_game_mode == GM_NORMAL) ? DIFF_INGAME_DISABLED_BUTTONS : 0; |
|
528 |
|
529 if (HasBit(dis, btn)) |
|
530 return; |
|
531 |
|
532 _difficulty_timeout = 5; |
|
533 |
|
534 val = ((GDType*)&_opt_mod_temp.diff)[btn]; |
|
535 |
|
536 info = &_game_setting_info[btn]; // get information about the difficulty setting |
|
537 if (x >= 10) { |
|
538 // Increase button clicked |
|
539 val = min(val + info->step, info->max); |
|
540 SetBit(_difficulty_click_b, btn); |
|
541 } else { |
|
542 // Decrease button clicked |
|
543 val -= info->step; |
|
544 val = max(val, info->min); |
|
545 SetBit(_difficulty_click_a, btn); |
|
546 } |
558 } |
547 |
|
548 // save value in temporary variable |
|
549 ((GDType*)&_opt_mod_temp.diff)[btn] = val; |
|
550 w->RaiseWidget(_opt_mod_temp.diff_level + 3); |
|
551 SetDifficultyLevel(3, &_opt_mod_temp); // set difficulty level to custom |
|
552 w->LowerWidget(_opt_mod_temp.diff_level + 3); |
|
553 SetWindowDirty(w); |
|
554 } break; |
559 } break; |
555 case 3: case 4: case 5: case 6: /* Easy / Medium / Hard / Custom */ |
560 |
556 // temporarily change difficulty level |
561 case WE_CLICK: |
557 w->RaiseWidget(_opt_mod_temp.diff_level + 3); |
562 switch (e->we.click.widget) { |
558 SetDifficultyLevel(e->we.click.widget - 3, &_opt_mod_temp); |
563 case GDW_SETTING_BG: { /* Difficulty settings widget, decode click */ |
559 w->LowerWidget(_opt_mod_temp.diff_level + 3); |
564 /* Don't allow clients to make any changes */ |
560 SetWindowDirty(w); |
565 if (_networking && !_network_server) return; |
|
566 |
|
567 const int x = e->we.click.pt.x - 5; |
|
568 if (!IsInsideMM(x, 0, 21)) // Button area |
|
569 return; |
|
570 |
|
571 const int y = e->we.click.pt.y - GAMEDIFF_WND_TOP_OFFSET; |
|
572 if (y < 0) return; |
|
573 |
|
574 /* Get button from Y coord. */ |
|
575 const uint btn = y / (GAMEDIFF_WND_ROWSIZE + 2); |
|
576 if (btn >= GAME_DIFFICULTY_NUM || y % (GAMEDIFF_WND_ROWSIZE + 2) >= 9) |
|
577 return; |
|
578 |
|
579 /* Clicked disabled button? */ |
|
580 if (_game_mode == GM_NORMAL && HasBit(DIFF_INGAME_DISABLED_BUTTONS, btn)) |
|
581 return; |
|
582 |
|
583 _difficulty_timeout = 5; |
|
584 |
|
585 int16 val = ((GDType*)&_opt_mod_temp.diff)[btn]; |
|
586 |
|
587 const GameSettingData *info = &_game_setting_info[btn]; // get information about the difficulty setting |
|
588 if (x >= 10) { |
|
589 /* Increase button clicked */ |
|
590 val = min(val + info->step, info->max); |
|
591 SetBit(_difficulty_click_b, btn); |
|
592 } else { |
|
593 /* Decrease button clicked */ |
|
594 val -= info->step; |
|
595 val = max(val, info->min); |
|
596 SetBit(_difficulty_click_a, btn); |
|
597 } |
|
598 |
|
599 /* save value in temporary variable */ |
|
600 ((GDType*)&_opt_mod_temp.diff)[btn] = val; |
|
601 w->RaiseWidget(GDW_LVL_EASY + _opt_mod_temp.diff_level); |
|
602 SetDifficultyLevel(3, &_opt_mod_temp); // set difficulty level to custom |
|
603 w->LowerWidget(GDW_LVL_CUSTOM); |
|
604 SetWindowDirty(w); |
|
605 } break; |
|
606 |
|
607 case GDW_LVL_EASY: |
|
608 case GDW_LVL_MEDIUM: |
|
609 case GDW_LVL_HARD: |
|
610 case GDW_LVL_CUSTOM: |
|
611 /* temporarily change difficulty level */ |
|
612 w->RaiseWidget(GDW_LVL_EASY + _opt_mod_temp.diff_level); |
|
613 SetDifficultyLevel(e->we.click.widget - GDW_LVL_EASY, &_opt_mod_temp); |
|
614 w->LowerWidget(GDW_LVL_EASY + _opt_mod_temp.diff_level); |
|
615 SetWindowDirty(w); |
|
616 break; |
|
617 |
|
618 case GDW_HIGHSCORE: // Highscore Table |
|
619 ShowHighscoreTable(_opt_mod_temp.diff_level, -1); |
|
620 break; |
|
621 |
|
622 case GDW_ACCEPT: { // Save button - save changes |
|
623 GDType btn, val; |
|
624 for (btn = 0; btn != GAME_DIFFICULTY_NUM; btn++) { |
|
625 val = ((GDType*)&_opt_mod_temp.diff)[btn]; |
|
626 /* if setting has changed, change it */ |
|
627 if (val != ((GDType*)&_opt_ptr->diff)[btn]) |
|
628 DoCommandP(0, btn, val, NULL, CMD_CHANGE_DIFFICULTY_LEVEL); |
|
629 } |
|
630 DoCommandP(0, UINT_MAX, _opt_mod_temp.diff_level, NULL, CMD_CHANGE_DIFFICULTY_LEVEL); |
|
631 DeleteWindow(w); |
|
632 /* If we are in the editor, we should reload the economy. |
|
633 * This way when you load a game, the max loan and interest rate |
|
634 * are loaded correctly. */ |
|
635 if (_game_mode == GM_EDITOR) StartupEconomy(); |
|
636 break; |
|
637 } |
|
638 |
|
639 case GDW_CANCEL: // Cancel button - close window, abandon changes |
|
640 DeleteWindow(w); |
|
641 break; |
|
642 } break; |
|
643 |
|
644 case WE_MOUSELOOP: /* Handle the visual 'clicking' of the buttons */ |
|
645 if (_difficulty_timeout != 0 && !--_difficulty_timeout) { |
|
646 _difficulty_click_a = 0; |
|
647 _difficulty_click_b = 0; |
|
648 SetWindowDirty(w); |
|
649 } |
561 break; |
650 break; |
562 case 7: /* Highscore Table */ |
|
563 ShowHighscoreTable(_opt_mod_temp.diff_level, -1); |
|
564 break; |
|
565 case 10: { /* Save button - save changes */ |
|
566 GDType btn, val; |
|
567 for (btn = 0; btn != GAME_DIFFICULTY_NUM; btn++) { |
|
568 val = ((GDType*)&_opt_mod_temp.diff)[btn]; |
|
569 // if setting has changed, change it |
|
570 if (val != ((GDType*)&_opt_ptr->diff)[btn]) |
|
571 DoCommandP(0, btn, val, NULL, CMD_CHANGE_DIFFICULTY_LEVEL); |
|
572 } |
|
573 DoCommandP(0, UINT_MAX, _opt_mod_temp.diff_level, NULL, CMD_CHANGE_DIFFICULTY_LEVEL); |
|
574 DeleteWindow(w); |
|
575 // If we are in the editor, we should reload the economy. |
|
576 // This way when you load a game, the max loan and interest rate |
|
577 // are loaded correctly. |
|
578 if (_game_mode == GM_EDITOR) |
|
579 StartupEconomy(); |
|
580 break; |
|
581 } |
|
582 case 11: /* Cancel button - close window, abandon changes */ |
|
583 DeleteWindow(w); |
|
584 break; |
|
585 } break; |
|
586 |
|
587 case WE_MOUSELOOP: /* Handle the visual 'clicking' of the buttons */ |
|
588 if (_difficulty_timeout != 0 && !--_difficulty_timeout) { |
|
589 _difficulty_click_a = 0; |
|
590 _difficulty_click_b = 0; |
|
591 SetWindowDirty(w); |
|
592 } |
|
593 break; |
|
594 } |
651 } |
595 } |
652 } |
596 |
|
597 #undef DIFF_INGAME_DISABLED_BUTTONS |
653 #undef DIFF_INGAME_DISABLED_BUTTONS |
598 |
654 |
|
655 /* Widget definition for the game difficulty settings window */ |
599 static const Widget _game_difficulty_widgets[] = { |
656 static const Widget _game_difficulty_widgets[] = { |
600 { WWT_CLOSEBOX, RESIZE_NONE, 10, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
657 { WWT_CLOSEBOX, RESIZE_NONE, 10, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, // GDW_CLOSEBOX |
601 { WWT_CAPTION, RESIZE_NONE, 10, 11, 369, 0, 13, STR_6800_DIFFICULTY_LEVEL, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
658 { WWT_CAPTION, RESIZE_NONE, 10, 11, 369, 0, 13, STR_6800_DIFFICULTY_LEVEL, STR_018C_WINDOW_TITLE_DRAG_THIS}, // GDW_CAPTION |
602 { WWT_PANEL, RESIZE_NONE, 10, 0, 369, 14, 29, 0x0, STR_NULL}, |
659 { WWT_PANEL, RESIZE_NONE, 10, 0, 369, 14, 41, 0x0, STR_NULL}, // GDW_UPPER_BG |
603 { WWT_PUSHTXTBTN, RESIZE_NONE, 3, 10, 96, 16, 27, STR_6801_EASY, STR_NULL}, |
660 { WWT_PUSHTXTBTN, RESIZE_NONE, 3, 10, 96, 16, 27, STR_6801_EASY, STR_NULL}, // GDW_LVL_EASY |
604 { WWT_PUSHTXTBTN, RESIZE_NONE, 3, 97, 183, 16, 27, STR_6802_MEDIUM, STR_NULL}, |
661 { WWT_PUSHTXTBTN, RESIZE_NONE, 3, 97, 183, 16, 27, STR_6802_MEDIUM, STR_NULL}, // GDW_LVL_MEDIUM |
605 { WWT_PUSHTXTBTN, RESIZE_NONE, 3, 184, 270, 16, 27, STR_6803_HARD, STR_NULL}, |
662 { WWT_PUSHTXTBTN, RESIZE_NONE, 3, 184, 270, 16, 27, STR_6803_HARD, STR_NULL}, // GDW_LVL_HARD |
606 { WWT_PUSHTXTBTN, RESIZE_NONE, 3, 271, 357, 16, 27, STR_6804_CUSTOM, STR_NULL}, |
663 { WWT_PUSHTXTBTN, RESIZE_NONE, 3, 271, 357, 16, 27, STR_6804_CUSTOM, STR_NULL}, // GDW_LVL_CUSTOM |
607 { WWT_TEXTBTN, RESIZE_NONE, 10, 0, 369, 30, 41, STR_6838_SHOW_HI_SCORE_CHART, STR_NULL}, |
664 { WWT_TEXTBTN, RESIZE_NONE, 6, 10, 357, 28, 39, STR_6838_SHOW_HI_SCORE_CHART, STR_NULL}, // GDW_HIGHSCORE |
608 { WWT_PANEL, RESIZE_NONE, 10, 0, 369, 42, 262, 0x0, STR_NULL}, |
665 { WWT_PANEL, RESIZE_NONE, 10, 0, 369, 42, 262, 0x0, STR_NULL}, // GDW_SETTING_BG |
609 { WWT_PANEL, RESIZE_NONE, 10, 0, 369, 263, 278, 0x0, STR_NULL}, |
666 { WWT_PANEL, RESIZE_NONE, 10, 0, 369, 263, 278, 0x0, STR_NULL}, // GDW_LOWER_BG |
610 { WWT_PUSHTXTBTN, RESIZE_NONE, 3, 105, 185, 265, 276, STR_OPTIONS_SAVE_CHANGES, STR_NULL}, |
667 { WWT_PUSHTXTBTN, RESIZE_NONE, 3, 105, 185, 265, 276, STR_OPTIONS_SAVE_CHANGES, STR_NULL}, // GDW_ACCEPT |
611 { WWT_PUSHTXTBTN, RESIZE_NONE, 3, 186, 266, 265, 276, STR_012E_CANCEL, STR_NULL}, |
668 { WWT_PUSHTXTBTN, RESIZE_NONE, 3, 186, 266, 265, 276, STR_012E_CANCEL, STR_NULL}, // GDW_CANCEL |
612 { WIDGETS_END}, |
669 { WIDGETS_END}, |
613 }; |
670 }; |
614 |
671 |
|
672 /* Window definition for the game difficulty settings window */ |
615 static const WindowDesc _game_difficulty_desc = { |
673 static const WindowDesc _game_difficulty_desc = { |
616 WDP_CENTER, WDP_CENTER, 370, 279, 370, 279, |
674 WDP_CENTER, WDP_CENTER, 370, 279, 370, 279, |
617 WC_GAME_OPTIONS, WC_NONE, |
675 WC_GAME_OPTIONS, WC_NONE, |
618 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, |
676 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, |
619 _game_difficulty_widgets, |
677 _game_difficulty_widgets, |
772 {_patches_stations, NULL, lengthof(_patches_stations)}, |
830 {_patches_stations, NULL, lengthof(_patches_stations)}, |
773 {_patches_economy, NULL, lengthof(_patches_economy)}, |
831 {_patches_economy, NULL, lengthof(_patches_economy)}, |
774 {_patches_ai, NULL, lengthof(_patches_ai)}, |
832 {_patches_ai, NULL, lengthof(_patches_ai)}, |
775 }; |
833 }; |
776 |
834 |
|
835 enum PatchesSelectionWidgets { |
|
836 PATCHSEL_OPTIONSPANEL = 3, |
|
837 PATCHSEL_INTERFACE, |
|
838 PATCHSEL_CONSTRUCTION, |
|
839 PATCHSEL_VEHICLES, |
|
840 PATCHSEL_STATIONS, |
|
841 PATCHSEL_ECONOMY, |
|
842 PATCHSEL_COMPETITORS |
|
843 }; |
|
844 |
777 /** The main patches window. Shows a number of categories on top and |
845 /** The main patches window. Shows a number of categories on top and |
778 * a selection of patches in that category. |
846 * a selection of patches in that category. |
779 * Uses WP(w, def_d) macro - data_1, data_2, data_3 */ |
847 * Uses WP(w, def_d) macro - data_1, data_2, data_3 */ |
780 static void PatchesSelectionWndProc(Window *w, WindowEvent *e) |
848 static void PatchesSelectionWndProc(Window *w, WindowEvent *e) |
781 { |
849 { |
782 static Patches *patches_ptr; |
850 static Patches *patches_ptr; |
783 |
851 |
784 switch (e->event) { |
852 switch (e->event) { |
785 case WE_CREATE: { |
853 case WE_CREATE: { |
786 static bool first_time = true; |
854 static bool first_time = true; |
787 |
855 |
788 patches_ptr = (_game_mode == GM_MENU) ? &_patches_newgame : &_patches; |
856 patches_ptr = (_game_mode == GM_MENU) ? &_patches_newgame : &_patches; |
789 |
857 |
790 /* Build up the dynamic settings-array only once per OpenTTD session */ |
858 /* Build up the dynamic settings-array only once per OpenTTD session */ |
791 if (first_time) { |
859 if (first_time) { |
792 PatchPage *page; |
860 PatchPage *page; |
793 for (page = &_patches_page[0]; page != endof(_patches_page); page++) { |
861 for (page = &_patches_page[0]; page != endof(_patches_page); page++) { |
794 uint i; |
862 uint i; |
795 |
863 |
796 page->entries = MallocT<PatchEntry>(page->num); |
864 page->entries = MallocT<PatchEntry>(page->num); |
797 for (i = 0; i != page->num; i++) { |
865 for (i = 0; i != page->num; i++) { |
798 uint index; |
866 uint index; |
799 const SettingDesc *sd = GetPatchFromName(page->names[i], &index); |
867 const SettingDesc *sd = GetPatchFromName(page->names[i], &index); |
800 assert(sd != NULL); |
868 assert(sd != NULL); |
801 |
869 |
802 page->entries[i].setting = sd; |
870 page->entries[i].setting = sd; |
803 page->entries[i].index = index; |
871 page->entries[i].index = index; |
|
872 } |
804 } |
873 } |
|
874 first_time = false; |
805 } |
875 } |
806 first_time = false; |
876 w->LowerWidget(4); |
807 } |
877 } break; |
808 w->LowerWidget(4); |
878 |
809 } break; |
879 case WE_PAINT: { |
810 |
880 int x, y; |
811 case WE_PAINT: { |
881 const PatchPage *page = &_patches_page[WP(w, def_d).data_1]; |
812 int x, y; |
882 uint i; |
813 const PatchPage *page = &_patches_page[WP(w,def_d).data_1]; |
883 |
814 uint i; |
884 /* Set up selected category */ |
815 |
885 DrawWindowWidgets(w); |
816 /* Set up selected category */ |
886 |
817 DrawWindowWidgets(w); |
887 x = 5; |
818 |
888 y = 47; |
819 x = 5; |
889 for (i = 0; i != page->num; i++) { |
820 y = 47; |
890 const SettingDesc *sd = page->entries[i].setting; |
821 for (i = 0; i != page->num; i++) { |
891 const SettingDescBase *sdb = &sd->desc; |
822 const SettingDesc *sd = page->entries[i].setting; |
892 const void *var = GetVariableAddress(patches_ptr, &sd->save); |
823 const SettingDescBase *sdb = &sd->desc; |
893 bool editable = true; |
824 const void *var = GetVariableAddress(patches_ptr, &sd->save); |
894 bool disabled = false; |
825 bool editable = true; |
895 |
826 bool disabled = false; |
896 // We do not allow changes of some items when we are a client in a networkgame |
827 |
897 if (!(sd->save.conv & SLF_NETWORK_NO) && _networking && !_network_server) editable = false; |
828 // We do not allow changes of some items when we are a client in a networkgame |
898 if ((sdb->flags & SGF_NETWORK_ONLY) && !_networking) editable = false; |
829 if (!(sd->save.conv & SLF_NETWORK_NO) && _networking && !_network_server) editable = false; |
899 if ((sdb->flags & SGF_NO_NETWORK) && _networking) editable = false; |
830 if ((sdb->flags & SGF_NETWORK_ONLY) && !_networking) editable = false; |
900 |
831 if ((sdb->flags & SGF_NO_NETWORK) && _networking) editable = false; |
901 if (sdb->cmd == SDT_BOOLX) { |
832 |
902 static const int _bool_ctabs[2][2] = {{9, 4}, {7, 6}}; |
833 if (sdb->cmd == SDT_BOOLX) { |
903 /* Draw checkbox for boolean-value either on/off */ |
834 static const int _bool_ctabs[2][2] = {{9, 4}, {7, 6}}; |
904 bool on = (*(bool*)var); |
835 /* Draw checkbox for boolean-value either on/off */ |
905 |
836 bool on = (*(bool*)var); |
906 DrawFrameRect(x, y, x + 19, y + 8, _bool_ctabs[!!on][!!editable], on ? FR_LOWERED : FR_NONE); |
837 |
907 SetDParam(0, on ? STR_CONFIG_PATCHES_ON : STR_CONFIG_PATCHES_OFF); |
838 DrawFrameRect(x, y, x + 19, y + 8, _bool_ctabs[!!on][!!editable], on ? FR_LOWERED : FR_NONE); |
|
839 SetDParam(0, on ? STR_CONFIG_PATCHES_ON : STR_CONFIG_PATCHES_OFF); |
|
840 } else { |
|
841 int32 value; |
|
842 |
|
843 value = (int32)ReadValue(var, sd->save.conv); |
|
844 |
|
845 /* Draw [<][>] boxes for settings of an integer-type */ |
|
846 DrawArrowButtons(x, y, 3, WP(w,def_d).data_2 - (i * 2), (editable && value != sdb->min), (editable && value != sdb->max)); |
|
847 |
|
848 disabled = (value == 0) && (sdb->flags & SGF_0ISDISABLED); |
|
849 if (disabled) { |
|
850 SetDParam(0, STR_CONFIG_PATCHES_DISABLED); |
|
851 } else { |
908 } else { |
852 if (sdb->flags & SGF_CURRENCY) { |
909 int32 value; |
853 SetDParam(0, STR_CONFIG_PATCHES_CURRENCY); |
910 |
854 } else if (sdb->flags & SGF_MULTISTRING) { |
911 value = (int32)ReadValue(var, sd->save.conv); |
855 SetDParam(0, sdb->str + value + 1); |
912 |
|
913 /* Draw [<][>] boxes for settings of an integer-type */ |
|
914 DrawArrowButtons(x, y, 3, WP(w, def_d).data_2 - (i * 2), (editable && value != sdb->min), (editable && value != sdb->max)); |
|
915 |
|
916 disabled = (value == 0) && (sdb->flags & SGF_0ISDISABLED); |
|
917 if (disabled) { |
|
918 SetDParam(0, STR_CONFIG_PATCHES_DISABLED); |
856 } else { |
919 } else { |
857 SetDParam(0, (sdb->flags & SGF_NOCOMMA) ? STR_CONFIG_PATCHES_INT32 : STR_7024); |
920 if (sdb->flags & SGF_CURRENCY) { |
|
921 SetDParam(0, STR_CONFIG_PATCHES_CURRENCY); |
|
922 } else if (sdb->flags & SGF_MULTISTRING) { |
|
923 SetDParam(0, sdb->str + value + 1); |
|
924 } else { |
|
925 SetDParam(0, (sdb->flags & SGF_NOCOMMA) ? STR_CONFIG_PATCHES_INT32 : STR_7024); |
|
926 } |
|
927 SetDParam(1, value); |
858 } |
928 } |
859 SetDParam(1, value); |
|
860 } |
929 } |
|
930 DrawString(30, y, (sdb->str) + disabled, TC_FROMSTRING); |
|
931 y += 11; |
861 } |
932 } |
862 DrawString(30, y, (sdb->str) + disabled, TC_FROMSTRING); |
933 } break; |
863 y += 11; |
934 |
864 } |
935 case WE_CLICK: |
865 break; |
936 switch (e->we.click.widget) { |
866 } |
937 case PATCHSEL_OPTIONSPANEL: { |
867 |
938 const PatchPage *page = &_patches_page[WP(w, def_d).data_1]; |
868 case WE_CLICK: |
939 const SettingDesc *sd; |
869 switch (e->we.click.widget) { |
940 void *var; |
870 case 3: { |
941 int32 value; |
871 const PatchPage *page = &_patches_page[WP(w,def_d).data_1]; |
942 int x, y; |
872 const SettingDesc *sd; |
943 byte btn; |
873 void *var; |
944 |
874 int32 value; |
945 y = e->we.click.pt.y - 46 - 1; |
875 int x, y; |
946 if (y < 0) return; |
876 byte btn; |
947 |
877 |
948 x = e->we.click.pt.x - 5; |
878 y = e->we.click.pt.y - 46 - 1; |
949 if (x < 0) return; |
879 if (y < 0) return; |
950 |
880 |
951 btn = y / 11; |
881 x = e->we.click.pt.x - 5; |
952 if (y % 11 > 9) return; |
882 if (x < 0) return; |
953 if (btn >= page->num) return; |
883 |
954 |
884 btn = y / 11; |
955 sd = page->entries[btn].setting; |
885 if (y % 11 > 9) return; |
956 |
886 if (btn >= page->num) return; |
957 /* return if action is only active in network, or only settable by server */ |
887 |
958 if (!(sd->save.conv & SLF_NETWORK_NO) && _networking && !_network_server) return; |
888 sd = page->entries[btn].setting; |
959 if ((sd->desc.flags & SGF_NETWORK_ONLY) && !_networking) return; |
889 |
960 if ((sd->desc.flags & SGF_NO_NETWORK) && _networking) return; |
890 /* return if action is only active in network, or only settable by server */ |
961 |
891 if (!(sd->save.conv & SLF_NETWORK_NO) && _networking && !_network_server) return; |
962 var = GetVariableAddress(patches_ptr, &sd->save); |
892 if ((sd->desc.flags & SGF_NETWORK_ONLY) && !_networking) return; |
963 value = (int32)ReadValue(var, sd->save.conv); |
893 if ((sd->desc.flags & SGF_NO_NETWORK) && _networking) return; |
964 |
894 |
965 /* clicked on the icon on the left side. Either scroller or bool on/off */ |
895 var = GetVariableAddress(patches_ptr, &sd->save); |
966 if (x < 21) { |
896 value = (int32)ReadValue(var, sd->save.conv); |
967 const SettingDescBase *sdb = &sd->desc; |
897 |
968 int32 oldvalue = value; |
898 /* clicked on the icon on the left side. Either scroller or bool on/off */ |
969 |
899 if (x < 21) { |
970 switch (sdb->cmd) { |
900 const SettingDescBase *sdb = &sd->desc; |
971 case SDT_BOOLX: value ^= 1; break; |
901 int32 oldvalue = value; |
972 case SDT_NUMX: { |
902 |
973 /* Add a dynamic step-size to the scroller. In a maximum of |
903 switch (sdb->cmd) { |
974 * 50-steps you should be able to get from min to max, |
904 case SDT_BOOLX: value ^= 1; break; |
975 * unless specified otherwise in the 'interval' variable |
905 case SDT_NUMX: { |
976 * of the current patch. */ |
906 /* Add a dynamic step-size to the scroller. In a maximum of |
977 uint32 step = (sdb->interval == 0) ? ((sdb->max - sdb->min) / 50) : sdb->interval; |
907 * 50-steps you should be able to get from min to max, |
978 if (step == 0) step = 1; |
908 * unless specified otherwise in the 'interval' variable |
979 |
909 * of the current patch. */ |
980 // don't allow too fast scrolling |
910 uint32 step = (sdb->interval == 0) ? ((sdb->max - sdb->min) / 50) : sdb->interval; |
981 if ((w->flags4 & WF_TIMEOUT_MASK) > 2 << WF_TIMEOUT_SHL) { |
911 if (step == 0) step = 1; |
982 _left_button_clicked = false; |
912 |
983 return; |
913 // don't allow too fast scrolling |
984 } |
914 if ((w->flags4 & WF_TIMEOUT_MASK) > 2 << WF_TIMEOUT_SHL) { |
985 |
915 _left_button_clicked = false; |
986 /* Increase or decrease the value and clamp it to extremes */ |
916 return; |
987 if (x >= 10) { |
917 } |
988 value += step; |
918 |
989 if (value > sdb->max) value = sdb->max; |
919 /* Increase or decrease the value and clamp it to extremes */ |
990 } else { |
920 if (x >= 10) { |
991 value -= step; |
921 value += step; |
992 if (value < sdb->min) value = (sdb->flags & SGF_0ISDISABLED) ? 0 : sdb->min; |
922 if (value > sdb->max) value = sdb->max; |
993 } |
|
994 |
|
995 /* Set up scroller timeout for numeric values */ |
|
996 if (value != oldvalue && !(sd->desc.flags & SGF_MULTISTRING)) { |
|
997 WP(w, def_d).data_2 = btn * 2 + 1 + ((x >= 10) ? 1 : 0); |
|
998 w->flags4 |= 5 << WF_TIMEOUT_SHL; |
|
999 _left_button_clicked = false; |
|
1000 } |
|
1001 } break; |
|
1002 default: NOT_REACHED(); |
|
1003 } |
|
1004 |
|
1005 if (value != oldvalue) { |
|
1006 SetPatchValue(page->entries[btn].index, patches_ptr, value); |
|
1007 SetWindowDirty(w); |
|
1008 } |
923 } else { |
1009 } else { |
924 value -= step; |
1010 /* only open editbox for types that its sensible for */ |
925 if (value < sdb->min) value = (sdb->flags & SGF_0ISDISABLED) ? 0 : sdb->min; |
1011 if (sd->desc.cmd != SDT_BOOLX && !(sd->desc.flags & SGF_MULTISTRING)) { |
926 } |
1012 /* Show the correct currency-translated value */ |
927 |
1013 if (sd->desc.flags & SGF_CURRENCY) value *= _currency->rate; |
928 /* Set up scroller timeout for numeric values */ |
1014 |
929 if (value != oldvalue && !(sd->desc.flags & SGF_MULTISTRING)) { |
1015 WP(w, def_d).data_3 = btn; |
930 WP(w,def_d).data_2 = btn * 2 + 1 + ((x >= 10) ? 1 : 0); |
1016 SetDParam(0, value); |
931 w->flags4 |= 5 << WF_TIMEOUT_SHL; |
1017 ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_CONFIG_PATCHES_QUERY_CAPT, 10, 100, w, CS_NUMERAL); |
932 _left_button_clicked = false; |
1018 } |
933 } |
1019 } |
934 } break; |
1020 } break; |
935 default: NOT_REACHED(); |
1021 |
936 } |
1022 case PATCHSEL_INTERFACE: case PATCHSEL_CONSTRUCTION: case PATCHSEL_VEHICLES: |
937 |
1023 case PATCHSEL_STATIONS: case PATCHSEL_ECONOMY: case PATCHSEL_COMPETITORS: |
938 if (value != oldvalue) { |
1024 w->RaiseWidget(WP(w, def_d).data_1 + PATCHSEL_INTERFACE); |
939 SetPatchValue(page->entries[btn].index, patches_ptr, value); |
1025 WP(w, def_d).data_1 = e->we.click.widget - PATCHSEL_INTERFACE; |
|
1026 w->LowerWidget(WP(w, def_d).data_1 + PATCHSEL_INTERFACE); |
|
1027 DeleteWindowById(WC_QUERY_STRING, 0); |
940 SetWindowDirty(w); |
1028 SetWindowDirty(w); |
941 } |
1029 break; |
942 } else { |
|
943 /* only open editbox for types that its sensible for */ |
|
944 if (sd->desc.cmd != SDT_BOOLX && !(sd->desc.flags & SGF_MULTISTRING)) { |
|
945 /* Show the correct currency-translated value */ |
|
946 if (sd->desc.flags & SGF_CURRENCY) value *= _currency->rate; |
|
947 |
|
948 WP(w,def_d).data_3 = btn; |
|
949 SetDParam(0, value); |
|
950 ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_CONFIG_PATCHES_QUERY_CAPT, 10, 100, w, CS_NUMERAL); |
|
951 } |
|
952 } |
1030 } |
953 |
|
954 break; |
1031 break; |
955 } |
1032 |
956 case 4: case 5: case 6: case 7: case 8: case 9: |
1033 case WE_TIMEOUT: |
957 w->RaiseWidget(WP(w, def_d).data_1 + 4); |
1034 WP(w, def_d).data_2 = 0; |
958 WP(w, def_d).data_1 = e->we.click.widget - 4; |
|
959 w->LowerWidget(WP(w, def_d).data_1 + 4); |
|
960 DeleteWindowById(WC_QUERY_STRING, 0); |
|
961 SetWindowDirty(w); |
1035 SetWindowDirty(w); |
962 break; |
1036 break; |
963 } |
1037 |
964 break; |
1038 case WE_ON_EDIT_TEXT: |
965 |
1039 if (e->we.edittext.str != NULL) { |
966 case WE_TIMEOUT: |
1040 const PatchEntry *pe = &_patches_page[WP(w, def_d).data_1].entries[WP(w,def_d).data_3]; |
967 WP(w,def_d).data_2 = 0; |
1041 const SettingDesc *sd = pe->setting; |
968 SetWindowDirty(w); |
1042 int32 value = atoi(e->we.edittext.str); |
969 break; |
1043 |
970 |
1044 /* Save the correct currency-translated value */ |
971 case WE_ON_EDIT_TEXT: { |
1045 if (sd->desc.flags & SGF_CURRENCY) value /= _currency->rate; |
972 if (e->we.edittext.str != NULL) { |
1046 |
973 const PatchEntry *pe = &_patches_page[WP(w,def_d).data_1].entries[WP(w,def_d).data_3]; |
1047 SetPatchValue(pe->index, patches_ptr, value); |
974 const SettingDesc *sd = pe->setting; |
1048 SetWindowDirty(w); |
975 int32 value = atoi(e->we.edittext.str); |
1049 } |
976 |
1050 break; |
977 /* Save the correct currency-translated value */ |
1051 |
978 if (sd->desc.flags & SGF_CURRENCY) value /= _currency->rate; |
1052 case WE_DESTROY: |
979 |
1053 DeleteWindowById(WC_QUERY_STRING, 0); |
980 SetPatchValue(pe->index, patches_ptr, value); |
1054 break; |
981 SetWindowDirty(w); |
|
982 } |
|
983 break; |
|
984 } |
|
985 |
|
986 case WE_DESTROY: |
|
987 DeleteWindowById(WC_QUERY_STRING, 0); |
|
988 break; |
|
989 } |
1055 } |
990 } |
1056 } |
991 |
1057 |
992 static const Widget _patches_selection_widgets[] = { |
1058 static const Widget _patches_selection_widgets[] = { |
993 { WWT_CLOSEBOX, RESIZE_NONE, 10, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
1059 { WWT_CLOSEBOX, RESIZE_NONE, 10, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
1042 GfxFillRect(x + 1, y + 1, x + 1 + 8, y + 8, color); |
1108 GfxFillRect(x + 1, y + 1, x + 1 + 8, y + 8, color); |
1043 if (!clickable_right) |
1109 if (!clickable_right) |
1044 GfxFillRect(x + 11, y + 1, x + 11 + 8, y + 8, color); |
1110 GfxFillRect(x + 11, y + 1, x + 11 + 8, y + 8, color); |
1045 } |
1111 } |
1046 |
1112 |
|
1113 /** These are not, strickly speaking, widget enums, |
|
1114 * since they have been changed as line coordinates. |
|
1115 * So, rather, they are more like order of appearance */ |
|
1116 enum CustomCurrenciesWidgets { |
|
1117 CUSTCURR_EXCHANGERATE = 0, |
|
1118 CUSTCURR_SEPARATOR, |
|
1119 CUSTCURR_PREFIX, |
|
1120 CUSTCURR_SUFFIX, |
|
1121 CUSTCURR_TO_EURO, |
|
1122 }; |
|
1123 |
1047 static char _str_separator[2]; |
1124 static char _str_separator[2]; |
1048 |
1125 |
1049 static void CustCurrencyWndProc(Window *w, WindowEvent *e) |
1126 static void CustCurrencyWndProc(Window *w, WindowEvent *e) |
1050 { |
1127 { |
1051 switch (e->event) { |
1128 switch (e->event) { |
1052 case WE_PAINT: { |
1129 case WE_PAINT: { |
1053 int x; |
1130 int x; |
1054 int y = 20; |
1131 int y = 20; |
1055 int clk = WP(w,def_d).data_1; |
1132 int clk = WP(w, def_d).data_1; |
1056 DrawWindowWidgets(w); |
1133 DrawWindowWidgets(w); |
1057 |
1134 |
1058 // exchange rate |
1135 /* exchange rate */ |
1059 DrawArrowButtons(10, y, 3, GB(clk, 0, 2), true, true); |
1136 DrawArrowButtons(10, y, 3, GB(clk, 0, 2), true, true); |
1060 SetDParam(0, 1); |
1137 SetDParam(0, 1); |
1061 SetDParam(1, 1); |
1138 SetDParam(1, 1); |
1062 DrawString(35, y + 1, STR_CURRENCY_EXCHANGE_RATE, TC_FROMSTRING); |
1139 DrawString(35, y + 1, STR_CURRENCY_EXCHANGE_RATE, TC_FROMSTRING); |
1063 y += 12; |
1140 y += 12; |
1064 |
1141 |
1065 // separator |
1142 /* separator */ |
1066 DrawFrameRect(10, y + 1, 29, y + 9, 0, GB(clk, 2, 2) ? FR_LOWERED : FR_NONE); |
1143 DrawFrameRect(10, y + 1, 29, y + 9, 0, GB(clk, 2, 2) ? FR_LOWERED : FR_NONE); |
1067 x = DrawString(35, y + 1, STR_CURRENCY_SEPARATOR, TC_FROMSTRING); |
1144 x = DrawString(35, y + 1, STR_CURRENCY_SEPARATOR, TC_FROMSTRING); |
1068 DoDrawString(_str_separator, x + 4, y + 1, TC_ORANGE); |
1145 DoDrawString(_str_separator, x + 4, y + 1, TC_ORANGE); |
1069 y += 12; |
1146 y += 12; |
1070 |
1147 |
1071 // prefix |
1148 /* prefix */ |
1072 DrawFrameRect(10, y + 1, 29, y + 9, 0, GB(clk, 4, 2) ? FR_LOWERED : FR_NONE); |
1149 DrawFrameRect(10, y + 1, 29, y + 9, 0, GB(clk, 4, 2) ? FR_LOWERED : FR_NONE); |
1073 x = DrawString(35, y + 1, STR_CURRENCY_PREFIX, TC_FROMSTRING); |
1150 x = DrawString(35, y + 1, STR_CURRENCY_PREFIX, TC_FROMSTRING); |
1074 DoDrawString(_custom_currency.prefix, x + 4, y + 1, TC_ORANGE); |
1151 DoDrawString(_custom_currency.prefix, x + 4, y + 1, TC_ORANGE); |
1075 y += 12; |
1152 y += 12; |
1076 |
1153 |
1077 // suffix |
1154 /* suffix */ |
1078 DrawFrameRect(10, y + 1, 29, y + 9, 0, GB(clk, 6, 2) ? FR_LOWERED : FR_NONE); |
1155 DrawFrameRect(10, y + 1, 29, y + 9, 0, GB(clk, 6, 2) ? FR_LOWERED : FR_NONE); |
1079 x = DrawString(35, y + 1, STR_CURRENCY_SUFFIX, TC_FROMSTRING); |
1156 x = DrawString(35, y + 1, STR_CURRENCY_SUFFIX, TC_FROMSTRING); |
1080 DoDrawString(_custom_currency.suffix, x + 4, y + 1, TC_ORANGE); |
1157 DoDrawString(_custom_currency.suffix, x + 4, y + 1, TC_ORANGE); |
1081 y += 12; |
1158 y += 12; |
1082 |
1159 |
1083 // switch to euro |
1160 /* switch to euro */ |
1084 DrawArrowButtons(10, y, 3, GB(clk, 8, 2), true, true); |
1161 DrawArrowButtons(10, y, 3, GB(clk, 8, 2), true, true); |
1085 SetDParam(0, _custom_currency.to_euro); |
1162 SetDParam(0, _custom_currency.to_euro); |
1086 DrawString(35, y + 1, (_custom_currency.to_euro != CF_NOEURO) ? STR_CURRENCY_SWITCH_TO_EURO : STR_CURRENCY_SWITCH_TO_EURO_NEVER, TC_FROMSTRING); |
1163 DrawString(35, y + 1, (_custom_currency.to_euro != CF_NOEURO) ? STR_CURRENCY_SWITCH_TO_EURO : STR_CURRENCY_SWITCH_TO_EURO_NEVER, TC_FROMSTRING); |
1087 y += 12; |
1164 y += 12; |
1088 |
1165 |
1089 // Preview |
1166 /* Preview */ |
1090 y += 12; |
1167 y += 12; |
1091 SetDParam(0, 10000); |
1168 SetDParam(0, 10000); |
1092 DrawString(35, y + 1, STR_CURRENCY_PREVIEW, TC_FROMSTRING); |
1169 DrawString(35, y + 1, STR_CURRENCY_PREVIEW, TC_FROMSTRING); |
1093 break; |
1170 } break; |
1094 } |
|
1095 |
1171 |
1096 case WE_CLICK: { |
1172 case WE_CLICK: { |
1097 int line = (e->we.click.pt.y - 20) / 12; |
1173 int line = (e->we.click.pt.y - 20) / 12; |
1098 int len = 0; |
1174 int len = 0; |
1099 int x = e->we.click.pt.x; |
1175 int x = e->we.click.pt.x; |
1100 StringID str = 0; |
1176 StringID str = 0; |
1101 CharSetFilter afilter = CS_ALPHANUMERAL; |
1177 CharSetFilter afilter = CS_ALPHANUMERAL; |
1102 |
1178 |
1103 switch (line) { |
1179 switch (line) { |
1104 case 0: // rate |
1180 case CUSTCURR_EXCHANGERATE: |
1105 if (IsInsideMM(x, 10, 30)) { // clicked buttons |
1181 if (IsInsideMM(x, 10, 30)) { // clicked buttons |
1106 if (x < 20) { |
1182 if (x < 20) { |
1107 if (_custom_currency.rate > 1) _custom_currency.rate--; |
1183 if (_custom_currency.rate > 1) _custom_currency.rate--; |
1108 WP(w,def_d).data_1 = 1 << (line * 2 + 0); |
1184 WP(w, def_d).data_1 = 1 << (line * 2 + 0); |
1109 } else { |
1185 } else { |
1110 if (_custom_currency.rate < 5000) _custom_currency.rate++; |
1186 if (_custom_currency.rate < 5000) _custom_currency.rate++; |
1111 WP(w,def_d).data_1 = 1 << (line * 2 + 1); |
1187 WP(w, def_d).data_1 = 1 << (line * 2 + 1); |
1112 } |
1188 } |
1113 } else { // enter text |
1189 } else { // enter text |
1114 SetDParam(0, _custom_currency.rate); |
1190 SetDParam(0, _custom_currency.rate); |
1115 str = STR_CONFIG_PATCHES_INT32; |
1191 str = STR_CONFIG_PATCHES_INT32; |
1116 len = 4; |
1192 len = 4; |
1117 afilter = CS_NUMERAL; |
1193 afilter = CS_NUMERAL; |
1118 } |
1194 } |
1119 break; |
1195 break; |
1120 |
1196 |
1121 case 1: // separator |
1197 case CUSTCURR_SEPARATOR: |
1122 if (IsInsideMM(x, 10, 30)) { // clicked button |
1198 if (IsInsideMM(x, 10, 30)) { // clicked button |
1123 WP(w,def_d).data_1 = 1 << (line * 2 + 1); |
1199 WP(w, def_d).data_1 = 1 << (line * 2 + 1); |
1124 } |
1200 } |
1125 str = BindCString(_str_separator); |
1201 str = BindCString(_str_separator); |
1126 len = 1; |
1202 len = 1; |
1127 break; |
1203 break; |
1128 |
1204 |
1129 case 2: // prefix |
1205 case CUSTCURR_PREFIX: |
1130 if (IsInsideMM(x, 10, 30)) { // clicked button |
1206 if (IsInsideMM(x, 10, 30)) { // clicked button |
1131 WP(w,def_d).data_1 = 1 << (line * 2 + 1); |
1207 WP(w, def_d).data_1 = 1 << (line * 2 + 1); |
1132 } |
1208 } |
1133 str = BindCString(_custom_currency.prefix); |
1209 str = BindCString(_custom_currency.prefix); |
1134 len = 12; |
1210 len = 12; |
1135 break; |
1211 break; |
1136 |
1212 |
1137 case 3: // suffix |
1213 case CUSTCURR_SUFFIX: |
1138 if (IsInsideMM(x, 10, 30)) { // clicked button |
1214 if (IsInsideMM(x, 10, 30)) { // clicked button |
1139 WP(w,def_d).data_1 = 1 << (line * 2 + 1); |
1215 WP(w, def_d).data_1 = 1 << (line * 2 + 1); |
1140 } |
1216 } |
1141 str = BindCString(_custom_currency.suffix); |
1217 str = BindCString(_custom_currency.suffix); |
1142 len = 12; |
1218 len = 12; |
1143 break; |
1219 break; |
1144 |
1220 |
1145 case 4: // to euro |
1221 case CUSTCURR_TO_EURO: |
1146 if (IsInsideMM(x, 10, 30)) { // clicked buttons |
1222 if (IsInsideMM(x, 10, 30)) { // clicked buttons |
1147 if (x < 20) { |
1223 if (x < 20) { |
1148 _custom_currency.to_euro = (_custom_currency.to_euro <= 2000) ? |
1224 _custom_currency.to_euro = (_custom_currency.to_euro <= 2000) ? |
1149 CF_NOEURO : _custom_currency.to_euro - 1; |
1225 CF_NOEURO : _custom_currency.to_euro - 1; |
1150 WP(w,def_d).data_1 = 1 << (line * 2 + 0); |
1226 WP(w, def_d).data_1 = 1 << (line * 2 + 0); |
1151 } else { |
1227 } else { |
1152 _custom_currency.to_euro = |
1228 _custom_currency.to_euro = |
1153 Clamp(_custom_currency.to_euro + 1, 2000, MAX_YEAR); |
1229 Clamp(_custom_currency.to_euro + 1, 2000, MAX_YEAR); |
1154 WP(w,def_d).data_1 = 1 << (line * 2 + 1); |
1230 WP(w, def_d).data_1 = 1 << (line * 2 + 1); |
1155 } |
1231 } |
1156 } else { // enter text |
1232 } else { // enter text |
1157 SetDParam(0, _custom_currency.to_euro); |
1233 SetDParam(0, _custom_currency.to_euro); |
1158 str = STR_CONFIG_PATCHES_INT32; |
1234 str = STR_CONFIG_PATCHES_INT32; |
1159 len = 4; |
1235 len = 4; |