diff options
Diffstat (limited to 'src/gui.cpp')
| -rw-r--r-- | src/gui.cpp | 66 |
1 files changed, 63 insertions, 3 deletions
diff --git a/src/gui.cpp b/src/gui.cpp index aa47868..5fb8fa7 100644 --- a/src/gui.cpp +++ b/src/gui.cpp | |||
| @@ -183,7 +183,8 @@ enum CtrlKind { | |||
| 183 | CK_SECTION, | 183 | CK_SECTION, |
| 184 | CK_INFO, | 184 | CK_INFO, |
| 185 | CK_BUTTON, | 185 | CK_BUTTON, |
| 186 | CK_COLOR | 186 | CK_COLOR, |
| 187 | CK_CHOICE | ||
| 187 | }; | 188 | }; |
| 188 | 189 | ||
| 189 | enum CtrlAction { ACT_NONE = 0, ACT_RELOAD, ACT_RESET }; | 190 | enum CtrlAction { ACT_NONE = 0, ACT_RELOAD, ACT_RESET }; |
| @@ -195,6 +196,8 @@ struct Ctrl { | |||
| 195 | bool *bval; // CK_TOGGLE | 196 | bool *bval; // CK_TOGGLE |
| 196 | int *ival; // CK_SLIDER | 197 | int *ival; // CK_SLIDER |
| 197 | int *rgb; // CK_COLOR: three ints, 0..255 | 198 | int *rgb; // CK_COLOR: three ints, 0..255 |
| 199 | const char *const *opts; // CK_CHOICE: option labels | ||
| 200 | int nopts; | ||
| 198 | int min, max; | 201 | int min, max; |
| 199 | int action; // CK_BUTTON | 202 | int action; // CK_BUTTON |
| 200 | bool zero_unlimited; // slider: value 0 displays as "All" | 203 | bool zero_unlimited; // slider: value 0 displays as "All" |
| @@ -253,6 +256,8 @@ static void add_ctrl(int card, int kind, const char *label, const char *desc, | |||
| 253 | c.action = action; | 256 | c.action = action; |
| 254 | c.zero_unlimited = false; | 257 | c.zero_unlimited = false; |
| 255 | c.rgb = nullptr; | 258 | c.rgb = nullptr; |
| 259 | c.opts = nullptr; | ||
| 260 | c.nopts = 0; | ||
| 256 | c.hue = 0.0f; | 261 | c.hue = 0.0f; |
| 257 | c.sat = 0.0f; | 262 | c.sat = 0.0f; |
| 258 | c.val = 1.0f; | 263 | c.val = 1.0f; |
| @@ -282,11 +287,19 @@ static void add_color(int card, const char *label, const char *desc, | |||
| 282 | add_ctrl(card, CK_COLOR, label, desc, 0, 255, nullptr, nullptr, ACT_NONE); | 287 | add_ctrl(card, CK_COLOR, label, desc, 0, 255, nullptr, nullptr, ACT_NONE); |
| 283 | g_ctrls[i].rgb = rgb; | 288 | g_ctrls[i].rgb = rgb; |
| 284 | } | 289 | } |
| 290 | static void add_choice(int card, const char *label, const char *desc, | ||
| 291 | const char *const *opts, int nopts, int *value) { | ||
| 292 | int i = g_nctrl; | ||
| 293 | add_ctrl(card, CK_CHOICE, label, desc, 0, nopts > 0 ? nopts - 1 : 0, | ||
| 294 | nullptr, value, ACT_NONE); | ||
| 295 | g_ctrls[i].opts = opts; | ||
| 296 | g_ctrls[i].nopts = nopts; | ||
| 297 | } | ||
| 285 | 298 | ||
| 286 | static int ctrl_val(const Ctrl &c) { | 299 | static int ctrl_val(const Ctrl &c) { |
| 287 | if (c.kind == CK_TOGGLE && c.bval) | 300 | if (c.kind == CK_TOGGLE && c.bval) |
| 288 | return *c.bval ? 1 : 0; | 301 | return *c.bval ? 1 : 0; |
| 289 | if (c.kind == CK_SLIDER && c.ival) | 302 | if ((c.kind == CK_SLIDER || c.kind == CK_CHOICE) && c.ival) |
| 290 | return *c.ival; | 303 | return *c.ival; |
| 291 | return 0; | 304 | return 0; |
| 292 | } | 305 | } |
| @@ -294,7 +307,7 @@ static void ctrl_set(Ctrl &c, int v) { | |||
| 294 | if (c.kind == CK_TOGGLE && c.bval) { | 307 | if (c.kind == CK_TOGGLE && c.bval) { |
| 295 | *c.bval = v != 0; | 308 | *c.bval = v != 0; |
| 296 | config_save(); | 309 | config_save(); |
| 297 | } else if (c.kind == CK_SLIDER && c.ival) { | 310 | } else if ((c.kind == CK_SLIDER || c.kind == CK_CHOICE) && c.ival) { |
| 298 | if (v < c.min) v = c.min; | 311 | if (v < c.min) v = c.min; |
| 299 | if (v > c.max) v = c.max; | 312 | if (v > c.max) v = c.max; |
| 300 | if (*c.ival != v) { | 313 | if (*c.ival != v) { |
| @@ -420,6 +433,13 @@ static void build_cards() { | |||
| 420 | add_toggle(fog, "Remove fog", | 433 | add_toggle(fog, "Remove fog", |
| 421 | "Disable fog entirely instead of recolouring it.", &g_fog_disable); | 434 | "Disable fog entirely instead of recolouring it.", &g_fog_disable); |
| 422 | 435 | ||
| 436 | int sky = add_card(2, &g_skybox, "Skybox", | ||
| 437 | "Swap the skybox at runtime through sv_skyname. The " | ||
| 438 | "map's own sky comes back on level change.", | ||
| 439 | true); | ||
| 440 | add_choice(sky, "Sky", "Pick a skybox from the HL2 set.", skybox_options(), | ||
| 441 | skybox_option_count(), &g_skybox_choice); | ||
| 442 | |||
| 423 | int spread = add_card(3, &g_spread, "Spread control", | 443 | int spread = add_card(3, &g_spread, "Spread control", |
| 424 | "Choose a server shot seed that tightens the cone.", | 444 | "Choose a server shot seed that tightens the cone.", |
| 425 | true); | 445 | true); |
| @@ -835,6 +855,8 @@ static int header_h(const Card &c) { | |||
| 835 | static int label_max_w(const Ctrl &c) { | 855 | static int label_max_w(const Ctrl &c) { |
| 836 | if (c.kind == CK_SLIDER) | 856 | if (c.kind == CK_SLIDER) |
| 837 | return S(214.0f); | 857 | return S(214.0f); |
| 858 | if (c.kind == CK_CHOICE) | ||
| 859 | return card_content_w() - S(16.0f) - S(250.0f); | ||
| 838 | return card_content_w() - S(16.0f) - S(110.0f); | 860 | return card_content_w() - S(16.0f) - S(110.0f); |
| 839 | } | 861 | } |
| 840 | 862 | ||
| @@ -1409,6 +1431,25 @@ static void handle_mouse_click() { | |||
| 1409 | } | 1431 | } |
| 1410 | return; | 1432 | return; |
| 1411 | } | 1433 | } |
| 1434 | if (ct.kind == CK_CHOICE) { | ||
| 1435 | int base = label_row_h(ct); | ||
| 1436 | Rect box{cr.x + cr.w - S(238.0f), | ||
| 1437 | by + (base - S(24.0f)) / 2, S(222.0f), S(24.0f)}; | ||
| 1438 | if (box.has(mx, my)) { | ||
| 1439 | int v = ctrl_val(ct); | ||
| 1440 | if (mx < box.x + S(36.0f)) | ||
| 1441 | v--; | ||
| 1442 | else if (mx >= box.x + box.w - S(36.0f)) | ||
| 1443 | v++; | ||
| 1444 | if (v < 0) v = 0; | ||
| 1445 | if (ct.nopts > 0 && v >= ct.nopts) v = ct.nopts - 1; | ||
| 1446 | if (v != ctrl_val(ct)) { | ||
| 1447 | *ct.ival = v; | ||
| 1448 | config_save(); | ||
| 1449 | } | ||
| 1450 | } | ||
| 1451 | return; | ||
| 1452 | } | ||
| 1412 | if (ct.kind == CK_BUTTON) { | 1453 | if (ct.kind == CK_BUTTON) { |
| 1413 | int bw = button_w(ct.label); | 1454 | int bw = button_w(ct.label); |
| 1414 | Rect b{cr.x + cr.w - S(16.0f) - bw, | 1455 | Rect b{cr.x + cr.w - S(16.0f) - bw, |
| @@ -1799,6 +1840,25 @@ static void draw_card(const Rect &clip, int index, int y) { | |||
| 1799 | outline(sw, picker_open_for(ct) ? C_ACCENT : C_BORDER, &clip); | 1840 | outline(sw, picker_open_for(ct) ? C_ACCENT : C_BORDER, &clip); |
| 1800 | if (picker_open_for(ct)) | 1841 | if (picker_open_for(ct)) |
| 1801 | draw_picker(clip, cr, ct, by); | 1842 | draw_picker(clip, cr, ct, by); |
| 1843 | } else if (ct.kind == CK_CHOICE) { | ||
| 1844 | int v = ctrl_val(ct); | ||
| 1845 | const char *name = (ct.opts && v >= 0 && v < ct.nopts) | ||
| 1846 | ? ct.opts[v] | ||
| 1847 | : "?"; | ||
| 1848 | Rect box{cr.x + cr.w - S(238.0f), | ||
| 1849 | by + (base_h - S(24.0f)) / 2, S(222.0f), S(24.0f)}; | ||
| 1850 | fill(box, Col{45, 50, 60, 255}, &clip); | ||
| 1851 | outline(box, C_BORDER, &clip); | ||
| 1852 | int ty = box.y + (box.h - g_body_h) / 2; | ||
| 1853 | text_in(clip, box.x + S(8.0f), ty, "<", g_font_body, g_body_h, 0, | ||
| 1854 | C_DIM); | ||
| 1855 | text_in(clip, box.x + box.w - S(16.0f), ty, ">", g_font_body, g_body_h, | ||
| 1856 | 0, C_DIM); | ||
| 1857 | int w = text_w(name, g_body_h); | ||
| 1858 | int tx = box.x + (box.w - w) / 2; | ||
| 1859 | if (tx < box.x + S(24.0f)) | ||
| 1860 | tx = box.x + S(24.0f); | ||
| 1861 | text_in(clip, tx, ty, name, g_font_body, g_body_h, 0, C_TEXT); | ||
| 1802 | } | 1862 | } |
| 1803 | } | 1863 | } |
| 1804 | by += rh; | 1864 | by += rh; |
