1 /* bzflag
2 * Copyright (c) 1993-2021 Tim Riker
3 *
4 * This package is free software; you can redistribute it and/or
5 * modify it under the terms of the license found in the file
6 * named COPYING that should have accompanied this file.
7 *
8 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
9 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
10 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11 */
12
13 /* interface header */
14 #include "GUIOptionsMenu.h"
15
16 /* common implementation headers */
17 #include "BZDBCache.h"
18 #include "TextUtils.h"
19 #include "FontManager.h"
20
21 /* local implementation headers */
22 #include "MainMenu.h"
23 #include "HUDDialogStack.h"
24 #include "HUDuiList.h"
25 #include "HUDuiLabel.h"
26 #include "ScoreboardRenderer.h"
27 #include "playing.h"
28
GUIOptionsMenu()29 GUIOptionsMenu::GUIOptionsMenu()
30 {
31 // add controls
32 std::vector<HUDuiControl*>& listHUD = getControls();
33
34 // cache font face ID
35 int fontFace = MainMenu::getFontFace();
36
37 HUDuiLabel* label = new HUDuiLabel;
38 label->setFontFace(fontFace);
39 label->setString("GUI Settings");
40 listHUD.push_back(label);
41
42 HUDuiList* option;
43
44 option = new HUDuiList;
45 option->setFontFace(fontFace);
46 option->setLabel("Scoreboard Font Size:");
47 option->setCallback(callback, "S");
48 std::vector<std::string>* options = &option->getList();
49 options->push_back(std::string("Auto"));
50 option->createSlider(4);
51 option->update();
52 listHUD.push_back(option);
53
54 option = new HUDuiList;
55 option->setFontFace(fontFace);
56 option->setLabel("Scoreboard Sort:");
57 option->setCallback(callback, "p");
58 options = &option->getList();
59 const char **sortLabels = ScoreboardRenderer::getSortLabels();
60 while (*sortLabels != NULL)
61 options->push_back(std::string(*sortLabels++));
62 option->update();
63 listHUD.push_back(option);
64
65 // set motto display length
66 option = new HUDuiList;
67 option->setFontFace(fontFace);
68 option->setLabel("Motto Display Length:");
69 option->setCallback(callback, "E");
70 option->createSlider(32 + 1);
71 option->update();
72 listHUD.push_back(option);
73
74
75 // set Radar Translucency
76 option = new HUDuiList;
77 option->setFontFace(fontFace);
78 option->setLabel("Radar Opacity:");
79 option->setCallback(callback, "Y");
80 option->createSlider(11);
81 option->update();
82 listHUD.push_back(option);
83
84 // set radar size
85 option = new HUDuiList;
86 option->setFontFace(fontFace);
87 option->setLabel("Radar Size:");
88 option->setCallback(callback, "R");
89 option->createSlider(maxRadarSize + 1);
90 option->update();
91 listHUD.push_back(option);
92
93 option = new HUDuiList;
94 option->setFontFace(fontFace);
95 option->setLabel("Radar Style:");
96 option->setCallback(callback, "e");
97 options = &option->getList();
98 options->push_back(std::string("Normal"));
99 options->push_back(std::string("Fast"));
100 options->push_back(std::string("Fast Sorted"));
101 options->push_back(std::string("Enhanced"));
102 option->update();
103 listHUD.push_back(option);
104
105 // set radar shot size
106 option = new HUDuiList;
107 option->setFontFace(fontFace);
108 option->setLabel("Radar Shot Size:");
109 option->setCallback(callback, "s");
110 option->createSlider(11);
111 option->update();
112 listHUD.push_back(option);
113
114 // set radar shot length
115 option = new HUDuiList;
116 option->setFontFace(fontFace);
117 option->setLabel("Radar Shot Length:");
118 option->setCallback(callback, "l");
119 option->createSlider(11);
120 option->update();
121 listHUD.push_back(option);
122
123 // radar shot leading line
124 option = new HUDuiList;
125 option->setFontFace(fontFace);
126 option->setLabel("Radar Shot Line:");
127 option->setCallback(callback, "F");
128 options = &option->getList();
129 options->push_back(std::string("Lagging"));
130 options->push_back(std::string("Leading"));
131 options->push_back(std::string("Leading & Lagging"));
132 option->update();
133 listHUD.push_back(option);
134
135 // set radar position
136 option = new HUDuiList;
137 option->setFontFace(fontFace);
138 option->setLabel("Radar Position:");
139 option->setCallback(callback, "P");
140 options = &option->getList();
141 options->push_back(std::string("Left"));
142 options->push_back(std::string("Right"));
143 option->update();
144 listHUD.push_back(option);
145
146 // toggle coloring of shots on radar
147 option = new HUDuiList;
148 option->setFontFace(fontFace);
149 option->setLabel("Colored shots on radar:");
150 option->setCallback(callback, "z");
151 options = &option->getList();
152 options->push_back(std::string("Off"));
153 options->push_back(std::string("On"));
154 option->update();
155 listHUD.push_back(option);
156
157
158
159 // set Panel Translucency
160 option = new HUDuiList;
161 option->setFontFace(fontFace);
162 option->setLabel("Panel Opacity:");
163 option->setCallback(callback, "y");
164 option->createSlider(11);
165 option->update();
166 listHUD.push_back(option);
167
168 // set panel size
169 option = new HUDuiList;
170 option->setFontFace(fontFace);
171 option->setLabel("Panel Height:");
172 option->setCallback(callback, "a");
173 option->createSlider(maxRadarSize + 1);
174 option->update();
175 listHUD.push_back(option);
176
177 option = new HUDuiList;
178 option->setFontFace(fontFace);
179 option->setLabel("ControlPanel Font Size:");
180 option->setCallback(callback, "C");
181 options = &option->getList();
182 options->push_back(std::string("Auto"));
183 option->createSlider(4);
184 option->update();
185 listHUD.push_back(option);
186
187 // Tabs
188 option = new HUDuiList;
189 option->setFontFace(fontFace);
190 option->setLabel("Control panel tabs:");
191 option->setCallback(callback, "t");
192 options = &option->getList();
193 options->push_back(std::string("Off"));
194 options->push_back(std::string("Left"));
195 options->push_back(std::string("Right"));
196 option->update();
197 listHUD.push_back(option);
198
199 // Automatic pausing of the console
200 option = new HUDuiList;
201 option->setFontFace(fontFace);
202 option->setLabel("Automatically pause the control panel:");
203 option->setCallback(callback, "o");
204 options = &option->getList();
205 options->push_back(std::string("Off"));
206 options->push_back(std::string("On"));
207 option->update();
208 listHUD.push_back(option);
209
210 // Time/date display settings
211 option = new HUDuiList;
212 option->setFontFace(fontFace);
213 option->setLabel("Timestamps in console:");
214 option->setCallback(callback, "Z");
215 options = &option->getList();
216 options->push_back(std::string("Off"));
217 options->push_back(std::string("Time"));
218 options->push_back(std::string("Date and Time"));
219 option->update();
220 listHUD.push_back(option);
221
222 // GUI coloring
223 option = new HUDuiList;
224 option->setFontFace(fontFace);
225 option->setLabel("Control panel coloring:");
226 option->setCallback(callback, "c");
227 options = &option->getList();
228 options->push_back(std::string("Off"));
229 options->push_back(std::string("On"));
230 option->update();
231 listHUD.push_back(option);
232
233 // Underline color
234 option = new HUDuiList;
235 option->setFontFace(fontFace);
236 option->setLabel("Underline color:");
237 option->setCallback(callback, "u");
238 options = &option->getList();
239 options->push_back(std::string("Cyan"));
240 options->push_back(std::string("Grey"));
241 options->push_back(std::string("Text"));
242 option->update();
243 listHUD.push_back(option);
244
245 // Killer Highlight
246 option = new HUDuiList;
247 option->setFontFace(fontFace);
248 option->setLabel("Killer Highlight:");
249 option->setCallback(callback, "k");
250 options = &option->getList();
251 options->push_back(std::string("None"));
252 options->push_back(std::string("Pulsating"));
253 options->push_back(std::string("Underline"));
254 option->update();
255 listHUD.push_back(option);
256
257 // Pulsate Rate
258 option = new HUDuiList;
259 option->setFontFace(fontFace);
260 option->setLabel("Pulsation Rate:");
261 option->setCallback(callback, "r");
262 option->createSlider(9);
263 option->update();
264 listHUD.push_back(option);
265
266 // Pulsate Depth
267 option = new HUDuiList;
268 option->setFontFace(fontFace);
269 option->setLabel("Pulsation Depth:");
270 option->setCallback(callback, "d");
271 option->createSlider(9);
272 option->update();
273 listHUD.push_back(option);
274
275
276
277 // Time/date display settings
278 option = new HUDuiList;
279 option->setFontFace(fontFace);
280 option->setLabel("Time / Date Display:");
281 option->setCallback(callback, "h");
282 options = &option->getList();
283 options->push_back(std::string("Time"));
284 options->push_back(std::string("Date"));
285 options->push_back(std::string("Date and Time"));
286 option->update();
287 listHUD.push_back(option);
288
289 // HUD Reload timer
290 option = new HUDuiList;
291 option->setFontFace(fontFace);
292 option->setLabel("Reload timer on HUD:");
293 option->setCallback(callback, "T");
294 options = &option->getList();
295 options->push_back(std::string("Off"));
296 options->push_back(std::string("On"));
297 option->update();
298 listHUD.push_back(option);
299
300 option = new HUDuiList;
301 option->setFontFace(fontFace);
302 option->setLabel("Always Show Team Scores:");
303 option->setCallback(callback, "q");
304 options = &option->getList();
305 options->push_back(std::string("Off"));
306 options->push_back(std::string("On"));
307 option->update();
308 listHUD.push_back(option);
309
310 // set observer info
311 option = new HUDuiList;
312 option->setFontFace(fontFace);
313 option->setLabel("Extended Observer Info:");
314 option->setCallback(callback, "O");
315 options = &option->getList();
316 options->push_back(std::string("Off"));
317 options->push_back(std::string("On"));
318 options->push_back(std::string("On With Apparent Speeds"));
319 options->push_back(std::string("Full"));
320 option->update();
321 listHUD.push_back(option);
322
323 option = new HUDuiList;
324 option->setFontFace(fontFace);
325 option->setLabel("Show Coordinates:");
326 option->setCallback(callback, "D");
327 options = &option->getList();
328 options->push_back(std::string("Off"));
329 options->push_back(std::string("On"));
330 option->update();
331 listHUD.push_back(option);
332
333 initNavigation(listHUD, 1, listHUD.size()-1);
334 }
335
~GUIOptionsMenu()336 GUIOptionsMenu::~GUIOptionsMenu()
337 {
338 }
339
execute()340 void GUIOptionsMenu::execute()
341 {
342 }
343
resize(int _width,int _height)344 void GUIOptionsMenu::resize(int _width, int _height)
345 {
346 HUDDialog::resize(_width, _height);
347
348 // use a big font for title, smaller font for the rest
349 const float titleFontSize = (float)_height / 15.0f;
350 const float fontSize = (float)_height / 70.0f;
351 FontManager &fm = FontManager::instance();
352
353 // reposition title
354 std::vector<HUDuiControl*>& listHUD = getControls();
355 HUDuiLabel* title = (HUDuiLabel*)listHUD[0];
356 title->setFontSize(titleFontSize);
357 const float titleWidth = fm.getStrLength(MainMenu::getFontFace(), titleFontSize, title->getString());
358 const float titleHeight = fm.getStrHeight(MainMenu::getFontFace(), titleFontSize, " ");
359 float x = 0.5f * ((float)_width - titleWidth);
360 float y = (float)_height - titleHeight;
361 title->setPosition(x, y);
362
363 // reposition options
364 x = 0.54f * (float)_width;
365 y -= 0.6f * titleHeight;
366 const float h = fm.getStrHeight(MainMenu::getFontFace(), fontSize, " ");
367 const int count = listHUD.size();
368 for (int i = 1; i < count; i++)
369 {
370 listHUD[i]->setFontSize(fontSize);
371 listHUD[i]->setPosition(x, y);
372 // Add extra space after Motto Display Length, Colored shots on radar, and Pulsation Depth
373 if (i == 3 || i == 11 || i == 22)
374 y -= 1.75f * h;
375 else
376 y -= 1.0f * h;
377 }
378
379 // load current settings
380 SceneRenderer* renderer = getSceneRenderer();
381 if (renderer)
382 {
383 int i = 1;
384 // Scoreboard Font Size
385 ((HUDuiList*)listHUD[i++])->setIndex(static_cast<int>(BZDB.eval("scorefontsize")));
386 // Scoreboard Sort
387 ((HUDuiList*)listHUD[i++])->setIndex(ScoreboardRenderer::getSort());
388 // Motto Display Length
389 if (BZDB.isTrue("hideMottos"))
390 ((HUDuiList*)listHUD[i++])->setIndex(0);
391 else
392 ((HUDuiList*)listHUD[i++])->setIndex(BZDB.evalInt("mottoDispLen") / 4);
393
394 // Radar Opacity
395 ((HUDuiList*)listHUD[i++])->setIndex((int)(10.0f * renderer->getRadarOpacity() + 0.5));
396 // Radar Size
397 ((HUDuiList*)listHUD[i++])->setIndex(renderer->getRadarSize());
398 // Radar Style
399 ((HUDuiList*)listHUD[i++])->setIndex(BZDBCache::radarStyle);
400 // Radar Shot Size
401 ((HUDuiList*)listHUD[i++])->setIndex(static_cast<int>(BZDB.eval("sizedradarshots")));
402 // Radar Shot Length
403 ((HUDuiList*)listHUD[i++])->setIndex(static_cast<int>(BZDB.eval("linedradarshots")));
404 // Radar Shot Line
405 ((HUDuiList*)listHUD[i++])->setIndex(static_cast<int>(BZDB.eval("leadingShotLine")));
406 // Radar Position
407 ((HUDuiList*)listHUD[i++])->setIndex(static_cast<int>(BZDB.eval("radarPosition")));
408 // Colored shots on radar
409 ((HUDuiList*)listHUD[i++])->setIndex(BZDB.isTrue("coloredradarshots") ? 1 : 0);
410
411
412 // Panel Opacity
413 ((HUDuiList*)listHUD[i++])->setIndex((int)(10.0f * renderer->getPanelOpacity() + 0.5));
414 // Panel Height
415 ((HUDuiList*)listHUD[i++])->setIndex(renderer->getPanelHeight());
416 // ControlPanel Font Size
417 ((HUDuiList*)listHUD[i++])->setIndex(static_cast<int>(BZDB.eval("cpanelfontsize")));
418 // Control Panel Tabs
419 ((HUDuiList*)listHUD[i++])->setIndex(static_cast<int>(BZDB.eval("showtabs")));
420 // Automatically pause the computer panel
421 ((HUDuiList*)listHUD[i++])->setIndex(BZDB.isTrue("pauseConsole") ? 1 : 0);
422 // Timestamps in console
423 ((HUDuiList*)listHUD[i++])->setIndex(BZDB.evalInt("controlPanelTimestamp"));
424 // Control panel coloring
425 ((HUDuiList*)listHUD[i++])->setIndex(BZDB.isTrue("colorful") ? 1 : 0);
426 // Underline color - find index of mode string in options
427 const std::vector<std::string> &opts = ((HUDuiList*)listHUD[i])->getList();
428 std::string uColor = BZDB.get("underlineColor");
429 ((HUDuiList*)listHUD[i++])->setIndex(std::find(opts.begin(), opts.end(), uColor) - opts.begin());
430 // Killer Highlight
431 ((HUDuiList*)listHUD[i++])->setIndex(static_cast<int>(BZDB.eval("killerhighlight")));
432 // Pulsation Rate
433 ((HUDuiList*)listHUD[i++])->setIndex(static_cast<int>(BZDB.eval("pulseRate") * 5) - 1);
434 // Pulsating Depth
435 ((HUDuiList*)listHUD[i++])->setIndex(static_cast<int>(BZDB.eval("pulseDepth") * 10) - 1);
436
437
438 // Time / Date Display
439 ((HUDuiList*)listHUD[i++])->setIndex(static_cast<int>(BZDB.eval("timedate")));
440 // Reload timer on HUD
441 ((HUDuiList*)listHUD[i++])->setIndex(BZDB.isTrue("displayReloadTimer") ? 1 : 0);
442 // Always Show Team Scores
443 ((HUDuiList*)listHUD[i++])->setIndex(ScoreboardRenderer::getAlwaysTeamScore());
444 // Extended Observer Info
445 ((HUDuiList*)listHUD[i++])->setIndex(static_cast<int>(BZDB.eval("showVelocities")));
446 // Show coordinates
447 ((HUDuiList*)listHUD[i++])->setIndex(BZDB.isTrue("showCoordinates") ? 1 : 0);
448 }
449 }
450
callback(HUDuiControl * w,const void * data)451 void GUIOptionsMenu::callback(HUDuiControl* w, const void* data)
452 {
453 HUDuiList* list = (HUDuiList*)w;
454
455 SceneRenderer* sceneRenderer = getSceneRenderer();
456 switch (((const char*)data)[0])
457 {
458 case 'e':
459 BZDB.setInt("radarStyle", list->getIndex());
460 break;
461
462 case 'C':
463 {
464 BZDB.setInt("cpanelfontsize", list->getIndex());
465 getMainWindow()->getWindow()->callResizeCallbacks();
466 break;
467 }
468
469 case 'h':
470 {
471 BZDB.setInt("timedate", list->getIndex());
472 break;
473 }
474
475 case 'Z':
476 {
477 BZDB.setInt("controlPanelTimestamp", list->getIndex());
478 break;
479 }
480
481 case 'S':
482 {
483 BZDB.setInt("scorefontsize", list->getIndex());
484 getMainWindow()->getWindow()->callResizeCallbacks();
485 break;
486 }
487
488 case 'O':
489 {
490 BZDB.setInt("showVelocities", list->getIndex());
491 getMainWindow()->getWindow()->callResizeCallbacks();
492 break;
493 }
494
495 case 'y':
496 {
497 const float newOpacity = (float)list->getIndex() / 10.0f;
498 if (newOpacity == 1.0f || sceneRenderer->getRadarOpacity() == 1.0f)
499 sceneRenderer->setRadarOpacity(newOpacity);
500 sceneRenderer->setPanelOpacity(newOpacity);
501 break;
502 }
503
504 case 'Y':
505 {
506 const float newOpacity = (float)list->getIndex() / 10.0f;
507 sceneRenderer->setRadarOpacity(newOpacity);
508 if (newOpacity == 1.0f || sceneRenderer->getPanelOpacity() == 1.0f)
509 sceneRenderer->setPanelOpacity(newOpacity);
510 break;
511 }
512
513 case 'z':
514 BZDB.set("coloredradarshots", list->getIndex() ? "1" : "0");
515 break;
516
517 case 'l':
518 BZDB.set("linedradarshots", TextUtils::format("%d", list->getIndex()));
519 break;
520
521 case 's':
522 BZDB.set("sizedradarshots", TextUtils::format("%d", list->getIndex()));
523 break;
524
525 case 'F':
526 BZDB.setInt("leadingShotLine", list->getIndex());
527 break;
528
529 case 'P':
530 BZDB.setInt("radarPosition", list->getIndex());
531 controlPanel->resize();
532 break;
533
534 case 'R':
535 {
536 BZDB.setInt("radarsize", list->getIndex());
537 break;
538 }
539
540 case 'a':
541 {
542 BZDB.setInt("panelheight", list->getIndex());
543 break;
544 }
545
546 case 'o':
547 {
548 BZDB.set("pauseConsole", list->getIndex() ? "1" : "0");
549 break;
550 }
551
552 case 'c':
553 {
554 BZDB.set("colorful", list->getIndex() ? "1" : "0");
555 break;
556 }
557
558 case 't':
559 {
560 BZDB.set("showtabs", TextUtils::format("%d", list->getIndex()));
561 break;
562 }
563
564 case 'u':
565 {
566 std::vector<std::string>* options = &list->getList();
567 std::string color = (*options)[list->getIndex()];
568 BZDB.set("underlineColor", color);
569 break;
570 }
571
572 case 'k':
573 {
574 BZDB.set("killerhighlight", TextUtils::format("%d", list->getIndex()));
575 break;
576 }
577
578 case 'r':
579 {
580 BZDB.set("pulseRate", TextUtils::format("%f", (float)(list->getIndex() + 1) / 5.0f));
581 break;
582 }
583
584 case 'd':
585 {
586 BZDB.set("pulseDepth", TextUtils::format("%f", (float)(list->getIndex() + 1) / 10.0f));
587 break;
588 }
589
590 case 'T':
591 {
592 BZDB.set("displayReloadTimer", list->getIndex() ? "1" : "0");
593 break;
594 }
595
596 case 'p':
597 ScoreboardRenderer::setSort(list->getIndex());
598 break;
599
600 case 'q':
601 ScoreboardRenderer::setAlwaysTeamScore(list->getIndex() ? true : false);
602 break;
603
604 case 'E':
605 BZDB.set("mottoDispLen", TextUtils::format("%d", list->getIndex() * 4));
606 BZDB.set("hideMottos", list->getIndex() ? "0" : "1");
607 break;
608 case 'D':
609 {
610 BZDB.setBool("showCoordinates", list->getIndex() == 1);
611 }
612
613
614 }
615 }
616
617
618 // Local Variables: ***
619 // mode: C++ ***
620 // tab-width: 4 ***
621 // c-basic-offset: 4 ***
622 // indent-tabs-mode: nil ***
623 // End: ***
624 // ex: shiftwidth=4 tabstop=4
625