From 7e9c6831600ef2b81a0b2e9a9e21314e6804b4f9 Mon Sep 17 00:00:00 2001 From: terencehill Date: Fri, 1 May 2015 23:08:10 +0200 Subject: [PATCH] Make crosshair picker code similar to the charmap's in order to simplify cell highlighting (each single crosshair was a special button). Add a custom simplified class for the crosshair preview too (it's not a button anymore). --- gfx/menu/luminos/skinvalues.txt | 3 - gfx/menu/wickedx/skinvalues.txt | 3 - gfx/menu/xaw/skinvalues.txt | 3 - qcsrc/menu/classes.qc | 3 +- qcsrc/menu/skin-customizables.inc | 3 - qcsrc/menu/xonotic/crosshairbutton.qc | 128 ---------- qcsrc/menu/xonotic/crosshairpicker.qc | 225 ++++++++++++++++++ qcsrc/menu/xonotic/crosshairpreview.qc | 60 +++++ .../xonotic/dialog_settings_game_crosshair.qc | 22 +- 9 files changed, 290 insertions(+), 160 deletions(-) delete mode 100644 qcsrc/menu/xonotic/crosshairbutton.qc create mode 100644 qcsrc/menu/xonotic/crosshairpicker.qc create mode 100644 qcsrc/menu/xonotic/crosshairpreview.qc diff --git a/gfx/menu/luminos/skinvalues.txt b/gfx/menu/luminos/skinvalues.txt index dd653973c..cce525534 100755 --- a/gfx/menu/luminos/skinvalues.txt +++ b/gfx/menu/luminos/skinvalues.txt @@ -173,9 +173,6 @@ COLOR_CHECKBOX_C '1 1 1' COLOR_CHECKBOX_F '1 1 1' COLOR_CHECKBOX_D '1 1 1' -// item: crosshair button -// uses "crosshairbutton" images - // dialog background colors // uses "border" images COLOR_DIALOG_MULTIPLAYER '1 1 1' diff --git a/gfx/menu/wickedx/skinvalues.txt b/gfx/menu/wickedx/skinvalues.txt index 7f1ed4500..6eecd78cc 100644 --- a/gfx/menu/wickedx/skinvalues.txt +++ b/gfx/menu/wickedx/skinvalues.txt @@ -173,9 +173,6 @@ COLOR_CHECKBOX_C '0.5 0.75 1' COLOR_CHECKBOX_F '0.5 0.75 1' COLOR_CHECKBOX_D '1 1 1' -// item: crosshair button -// uses "crosshairbutton" images - // dialog background colors // uses "border" images COLOR_DIALOG_MULTIPLAYER '1 1 1' diff --git a/gfx/menu/xaw/skinvalues.txt b/gfx/menu/xaw/skinvalues.txt index 6de99761e..bb6b78d16 100644 --- a/gfx/menu/xaw/skinvalues.txt +++ b/gfx/menu/xaw/skinvalues.txt @@ -107,9 +107,6 @@ ALPHA_CREDITS_PERSON 1 ROWS_CREDITS 20 WIDTH_CREDITS 0.5 -// item: crosshair button -// uses "crosshairbutton" images - // item: cvar list ALPHA_CVARLIST_SAVED 1 ALPHA_CVARLIST_TEMPORARY 0.7 diff --git a/qcsrc/menu/classes.qc b/qcsrc/menu/classes.qc index 9b4bb4dab..41522d6c5 100644 --- a/qcsrc/menu/classes.qc +++ b/qcsrc/menu/classes.qc @@ -67,10 +67,11 @@ #include "xonotic/skinlist.qc" #include "xonotic/languagelist.qc" #include "xonotic/image.qc" -#include "xonotic/crosshairbutton.qc" #include "xonotic/playermodel.qc" #include "xonotic/checkbox_slider_invalid.qc" #include "xonotic/charmap.qc" +#include "xonotic/crosshairpicker.qc" +#include "xonotic/crosshairpreview.qc" #include "xonotic/keybinder.qc" #include "xonotic/dialog_settings_input.qc" #include "xonotic/dialog_settings_input_userbind.qc" diff --git a/qcsrc/menu/skin-customizables.inc b/qcsrc/menu/skin-customizables.inc index fa5a5df19..58884a0f9 100644 --- a/qcsrc/menu/skin-customizables.inc +++ b/qcsrc/menu/skin-customizables.inc @@ -144,9 +144,6 @@ SKINBEGIN SKINFLOAT(ROWS_CREDITS, 20); SKINFLOAT(WIDTH_CREDITS, 0.5); - // item: crosshair button - SKINSTRING(GFX_CROSSHAIRBUTTON, "crosshairbutton"); - // item: cvar list SKINFLOAT(ALPHA_CVARLIST_SAVED, 1); SKINFLOAT(ALPHA_CVARLIST_TEMPORARY, 0.7); diff --git a/qcsrc/menu/xonotic/crosshairbutton.qc b/qcsrc/menu/xonotic/crosshairbutton.qc deleted file mode 100644 index 3b562cb77..000000000 --- a/qcsrc/menu/xonotic/crosshairbutton.qc +++ /dev/null @@ -1,128 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticCrosshairButton) EXTENDS(RadioButton) - METHOD(XonoticCrosshairButton, configureXonoticCrosshairButton, void(entity, float, float)) - METHOD(XonoticCrosshairButton, setChecked, void(entity, float)) - METHOD(XonoticCrosshairButton, draw, void(entity)) - ATTRIB(XonoticCrosshairButton, fontSize, float, SKINFONTSIZE_NORMAL) - ATTRIB(XonoticCrosshairButton, image, string, SKINGFX_CROSSHAIRBUTTON) - - ATTRIB(XonoticCrosshairButton, useDownAsChecked, float, 1) - ATTRIB(XonoticCrosshairButton, src3, string, string_null) - ATTRIB(XonoticCrosshairButton, src4, string, string_null) - - ATTRIB(XonoticCrosshairButton, cvarName, string, string_null) - ATTRIB(XonoticCrosshairButton, cvarValueFloat, float, 0) - METHOD(XonoticCrosshairButton, loadCvars, void(entity)) - METHOD(XonoticCrosshairButton, saveCvars, void(entity)) -ENDCLASS(XonoticCrosshairButton) -entity makeXonoticCrosshairButton(float, float); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticCrosshairButton(float theGroup, float theCrosshair) -{ - entity me; - me = spawnXonoticCrosshairButton(); - me.configureXonoticCrosshairButton(me, theGroup, theCrosshair); - return me; -} -void XonoticCrosshairButton_configureXonoticCrosshairButton(entity me, float theGroup, float theCrosshair) -{ - me.cvarName = "crosshair"; - me.cvarValueFloat = theCrosshair; - me.loadCvars(me); - me.configureRadioButton(me, string_null, me.fontSize, me.image, theGroup, 0); - me.srcMulti = 1; - if(me.cvarValueFloat == -1) - me.src3 = strzone(strcat("/gfx/crosshair", cvar_string("crosshair"))); - else - me.src3 = strzone(strcat("/gfx/crosshair", ftos(me.cvarValueFloat))); - me.src4 = "/gfx/crosshairdot"; -} -void XonoticCrosshairButton_setChecked(entity me, float val) -{ - if(me.cvarValueFloat != -1) // preview shouldn't work as a button - if(val != me.checked) - { - me.checked = val; - me.saveCvars(me); - } -} -void XonoticCrosshairButton_loadCvars(entity me) -{ - if (!me.cvarName) - return; - - me.checked = (cvar(me.cvarName) == me.cvarValueFloat); -} -void XonoticCrosshairButton_saveCvars(entity me) -{ - if (!me.cvarName) - return; - - if(me.checked) - cvar_set(me.cvarName, ftos(me.cvarValueFloat)); - // TODO on an apply button, read _cl_color and execute the color command for it -} -void XonoticCrosshairButton_draw(entity me) -{ - vector sz, rgb; - float a; - - - if(me.cvarValueFloat == -1) - { - rgb = stov(cvar_string("crosshair_color")); - a = cvar("crosshair_alpha"); - } - else if(me.checked || me.focused) - { - a = 1; - rgb = '1 1 1'; - } - else - { - a = me.disabledAlpha; - rgb = '1 1 1'; - } - - if(me.cvarValueFloat == -1) // update the preview if this is the preview button - { - if(me.src3) - strunzone(me.src3); - me.src3 = strzone(strcat("/gfx/crosshair", cvar_string("crosshair"))); - me.focused = 1; - me.checked = 0; - } - - SUPER(XonoticCrosshairButton).draw(me); - - sz = draw_PictureSize(me.src3); - sz = globalToBoxSize(sz, me.size); - if(me.cvarValueFloat == -1) - { - sz = sz * cvar("crosshair_size"); // (6 * '1 1 0' + ...) * 0.08 here to make visible size changes happen also at bigger sizes - /* - if(sz_x > 0.95) - sz = sz * (0.95 / sz_x); - if(sz_y > 0.95) - sz = sz * (0.95 / sz_y); - */ - } - else // show the crosshair picker at full size - { - sz = sz * (0.95 / sz.x); - if(sz.y > 0.95) - sz = sz * (0.95 / sz.y); - } - - draw_Picture('0.5 0.5 0' - 0.5 * sz, me.src3, sz, rgb, a); - if(cvar("crosshair_dot")) - { - if(cvar("crosshair_dot_color_custom") && (cvar_string("crosshair_dot_color") != "0")) - rgb = stov(cvar_string("crosshair_dot_color")); - - draw_Picture('0.5 0.5 0' - 0.5 * sz * cvar("crosshair_dot_size"), me.src4, sz * cvar("crosshair_dot_size"), rgb, a * cvar("crosshair_dot_alpha")); - } -} -#endif diff --git a/qcsrc/menu/xonotic/crosshairpicker.qc b/qcsrc/menu/xonotic/crosshairpicker.qc new file mode 100644 index 000000000..9236e61eb --- /dev/null +++ b/qcsrc/menu/xonotic/crosshairpicker.qc @@ -0,0 +1,225 @@ +#ifdef INTERFACE +CLASS(XonoticCrosshairPicker) EXTENDS(Item) + METHOD(XonoticCrosshairPicker, configureXonoticCrosshairPicker, void(entity)) + METHOD(XonoticCrosshairPicker, mousePress, float(entity, vector)) + METHOD(XonoticCrosshairPicker, mouseRelease, float(entity, vector)) + METHOD(XonoticCrosshairPicker, mouseMove, float(entity, vector)) + METHOD(XonoticCrosshairPicker, mouseDrag, float(entity, vector)) + METHOD(XonoticCrosshairPicker, keyDown, float(entity, float, float, float)) + METHOD(XonoticCrosshairPicker, draw, void(entity)) + ATTRIB(XonoticCrosshairPicker, focusable, float, 1) + ATTRIB(XonoticCrosshairPicker, disabled, float, 0) + ATTRIB(XonoticCrosshairPicker, alpha, float, 1) + ATTRIB(XonoticCrosshairPicker, disabledAlpha, float, SKINALPHA_DISABLED) + + METHOD(XonoticCrosshairPicker, moveFocus, void(entity, vector, vector)) + METHOD(XonoticCrosshairPicker, setCrosshair, void(entity)) + ATTRIB(XonoticCrosshairPicker, realCellSize, vector, '0 0 0') + ATTRIB(XonoticCrosshairPicker, focusedCell, vector, '-1 -1 0') + ATTRIB(XonoticCrosshairPicker, focusedCellTime, float, 0) + ATTRIB(XonoticCrosshairPicker, pressedCell, vector, '-1 -1 0') +ENDCLASS(XonoticCrosshairPicker) +entity makeXonoticCrosshairPicker(); +#endif + +#ifdef IMPLEMENTATION + +const float CROSSHAIRPICKER_COLS = 12; +const float CROSSHAIRPICKER_ROWS = 3; + +string crosshairpicker_cellToCrosshair(vector cell) +{ + float crosshair = 31 + cell.y * CROSSHAIRPICKER_COLS + cell.x; + + if (crosshair >= 31 && crosshair < 31 + CROSSHAIRPICKER_COLS * CROSSHAIRPICKER_ROWS) + return ftos(crosshair); + else + return ""; +} + +entity makeXonoticCrosshairPicker() +{ + entity me; + me = spawnXonoticCrosshairPicker(); + me.configureXonoticCrosshairPicker(me); + return me; +} + +void XonoticCrosshairPicker_configureXonoticCrosshairPicker(entity me) +{ + me.realCellSize = eX / CROSSHAIRPICKER_COLS + eY / CROSSHAIRPICKER_ROWS; +} + +float XonoticCrosshairPicker_mouseMove(entity me, vector coords) +{ + vector prevFocusedCell = me.focusedCell; + me.focusedCell_x = floor(coords.x * CROSSHAIRPICKER_COLS); + me.focusedCell_y = floor(coords.y * CROSSHAIRPICKER_ROWS); + + if(me.focusedCell.x < 0 || me.focusedCell.y < 0 || + me.focusedCell.x >= CROSSHAIRPICKER_COLS || me.focusedCell.y >= CROSSHAIRPICKER_ROWS) + { + me.focusedCell = '-1 -1 0'; + return 0; + } + + if(me.focusedCell != prevFocusedCell) + me.focusedCellTime = time; + + return 1; +} + +float XonoticCrosshairPicker_mouseDrag(entity me, vector coords) +{ + return me.mouseMove(me, coords); +} + +float XonoticCrosshairPicker_mousePress(entity me, vector coords) +{ + me.mouseMove(me, coords); + + if(me.focusedCell.x >= 0) + { + me.pressed = 1; + me.pressedCell = me.focusedCell; + } + + return 1; +} + +float XonoticCrosshairPicker_mouseRelease(entity me, vector coords) +{ + if(!me.pressed) + return 0; + + me.mouseMove(me, coords); + + if(me.focusedCell == me.pressedCell) + me.setCrosshair(me); + + me.pressed = 0; + return 1; +} + +float XonoticCrosshairPicker_keyDown(entity me, float key, float ascii, float shift) +{ + switch(key) + { + case K_LEFTARROW: + case K_KP_LEFTARROW: + me.moveFocus(me, me.focusedCell, '-1 0 0'); + return 1; + case K_RIGHTARROW: + case K_KP_RIGHTARROW: + me.moveFocus(me, me.focusedCell, '1 0 0'); + return 1; + case K_UPARROW: + case K_KP_UPARROW: + me.moveFocus(me, me.focusedCell, '0 -1 0'); + return 1; + case K_DOWNARROW: + case K_KP_DOWNARROW: + me.moveFocus(me, me.focusedCell, '0 1 0'); + return 1; + case K_HOME: + case K_KP_HOME: + me.focusedCell = '0 0 0'; + return 1; + case K_END: + case K_KP_END: + me.focusedCell_x = CROSSHAIRPICKER_COLS - 1; + me.focusedCell_y = CROSSHAIRPICKER_ROWS - 1; + return 1; + case K_ENTER: + case K_KP_ENTER: + case K_INS: + case K_KP_INS: + me.setCrosshair(me); + return 1; + } + return 0; +} + +void XonoticCrosshairPicker_moveFocus(entity me, vector initialCell, vector step) +{ + me.focusedCell_x = mod(me.focusedCell.x + step.x + CROSSHAIRPICKER_COLS, CROSSHAIRPICKER_COLS); + me.focusedCell_y = mod(me.focusedCell.y + step.y + CROSSHAIRPICKER_ROWS, CROSSHAIRPICKER_ROWS); + + if(me.focusedCell != initialCell) // Recursion break + if(crosshairpicker_cellToCrosshair(me.focusedCell) == "") + me.moveFocus(me, initialCell, step); +} + +void XonoticCrosshairPicker_setCrosshair(entity me) +{ + cvar_set("crosshair", crosshairpicker_cellToCrosshair(me.focusedCell)); +} + +void XonoticCrosshairPicker_draw(entity me) +{ + vector sz, rgb; + float save; + + me.focusable = !me.disabled; + + save = draw_alpha; + if(me.disabled) + draw_alpha *= me.disabledAlpha; + + string crosshair; + vector cell, cellPos, crosshairPos; + cell = '0 0 0'; + cellPos = '0 0 0'; + crosshairPos = '0 0 0'; + + + for(cell_y = 0; cell.y < CROSSHAIRPICKER_ROWS; ++cell.y) + { + crosshairPos_y = cell.y / CROSSHAIRPICKER_ROWS + 0.5 * me.realCellSize.y; + for(cell_x = 0; cell.x < CROSSHAIRPICKER_COLS; ++cell.x) + { + crosshair = crosshairpicker_cellToCrosshair(cell); + + if(crosshair == "") + continue; + + // Draw focused cell + if(cell == me.focusedCell && me.focused) + { + if(!me.pressed || me.focusedCell == me.pressedCell) + { + cellPos_x = mod(me.focusedCell.x, CROSSHAIRPICKER_COLS) / CROSSHAIRPICKER_COLS; + cellPos_y = mod(me.focusedCell.y, CROSSHAIRPICKER_ROWS) / CROSSHAIRPICKER_ROWS; + draw_Fill(cellPos, me.realCellSize, SKINCOLOR_LISTBOX_FOCUSED, getHighlightAlpha(SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED, me.focusedCellTime)); + } + } + + // Draw crosshair + crosshairPos_x = cell.x / CROSSHAIRPICKER_COLS + 0.5 * me.realCellSize.x; + string cross = strcat("/gfx/crosshair", crosshairpicker_cellToCrosshair(cell)); + sz = draw_PictureSize(cross); + sz = globalToBoxSize(sz, me.size); + + float ar = sz.x / sz.y; + sz.x = me.realCellSize.x; + sz.y = sz.x / ar; + + sz = sz * 0.95; + + rgb = '1 1 1'; + draw_Picture(crosshairPos - 0.5 * sz, cross, sz, rgb, me.alpha); + if(cvar("crosshair_dot")) + { + if(cvar("crosshair_dot_color_custom") && (cvar_string("crosshair_dot_color") != "0")) + rgb = stov(cvar_string("crosshair_dot_color")); + + draw_Picture(crosshairPos - 0.5 * sz * cvar("crosshair_dot_size"), "/gfx/crosshairdot", sz * cvar("crosshair_dot_size"), rgb, me.alpha); + } + } + } + + draw_alpha = save; + + SUPER(XonoticCrosshairPicker).draw(me); +} +#endif diff --git a/qcsrc/menu/xonotic/crosshairpreview.qc b/qcsrc/menu/xonotic/crosshairpreview.qc new file mode 100644 index 000000000..b271f4dab --- /dev/null +++ b/qcsrc/menu/xonotic/crosshairpreview.qc @@ -0,0 +1,60 @@ +#ifdef INTERFACE +CLASS(XonoticCrosshairPreview) EXTENDS(Item) + METHOD(XonoticCrosshairPreview, configureXonoticCrosshairPreview, void(entity)) + METHOD(XonoticCrosshairPreview, draw, void(entity)) + ATTRIB(XonoticCrosshairPreview, src, string, string_null) + ATTRIB(XonoticCrosshairPreview, src2, string, string_null) + ATTRIB(XonoticCrosshairPreview, disabled, float, 0) + ATTRIB(XonoticCrosshairPreview, disabledAlpha, float, SKINALPHA_DISABLED) +ENDCLASS(XonoticCrosshairPreview) +entity makeXonoticCrosshairPreview(); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticCrosshairPreview() +{ + entity me; + me = spawnXonoticCrosshairPreview(); + me.configureXonoticCrosshairPreview(me); + return me; +} + +void XonoticCrosshairPreview_configureXonoticCrosshairPreview(entity me) +{ + me.src = strzone(strcat("/gfx/crosshair", cvar_string("crosshair"))); + me.src2 = "/gfx/crosshairdot"; +} + +void XonoticCrosshairPreview_draw(entity me) +{ + float save; + save = draw_alpha; + if(me.disabled) + draw_alpha *= me.disabledAlpha; + + vector sz, rgb; + float a; + rgb = stov(cvar_string("crosshair_color")); + a = cvar("crosshair_alpha"); + if(me.src) + strunzone(me.src); + me.src = strzone(strcat("/gfx/crosshair", cvar_string("crosshair"))); + + sz = draw_PictureSize(me.src); + sz = globalToBoxSize(sz, me.size); + sz = sz * cvar("crosshair_size"); + + draw_Picture('0.5 0.5 0' - 0.5 * sz, me.src, sz, rgb, a); + if(cvar("crosshair_dot")) + { + if(cvar("crosshair_dot_color_custom") && (cvar_string("crosshair_dot_color") != "0")) + rgb = stov(cvar_string("crosshair_dot_color")); + + draw_Picture('0.5 0.5 0' - 0.5 * sz * cvar("crosshair_dot_size"), me.src2, sz * cvar("crosshair_dot_size"), rgb, a * cvar("crosshair_dot_alpha")); + } + + draw_alpha = save; + + SUPER(XonoticCrosshairPreview).draw(me); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc b/qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc index 28cf3708f..3bfcb0bb0 100644 --- a/qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc +++ b/qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc @@ -27,7 +27,6 @@ entity makeXonoticGameCrosshairSettingsTab() void XonoticGameCrosshairSettingsTab_fill(entity me) { entity e; - float i; // crosshair_enabled: 0 = no crosshair options, 1 = no crosshair selection, but everything else enabled, 2 = all crosshair options enabled // FIXME: In the future, perhaps make one global crosshair_type cvar which has 0 for disabled, 1 for custom, 2 for per weapon, etc? @@ -39,27 +38,12 @@ void XonoticGameCrosshairSettingsTab_fill(entity me) //me.TR(me); me.TD(me, 1, 1, e = makeXonoticRadioButton(3, "crosshair_enabled", "2", _("Custom"))); me.TR(me); - me.TDempty(me, 0.1); - for(i = 31; i <= 42; ++i) { - me.TDNoMargin(me, 1, 2 / 12, e = makeXonoticCrosshairButton(4, i), '1 1 0'); - setDependentAND(e, "crosshair_per_weapon", 0, 0, "crosshair_enabled", 1, 2); - } - // show a larger preview of the selected crosshair - me.TDempty(me, 0.1); - me.TDNoMargin(me, 3, 0.8, e = makeXonoticCrosshairButton(7, -1), '1 1 0'); // crosshair -1 makes this a preview + me.TD(me, 3, 2, e = makeXonoticCrosshairPicker()); + setDependentAND(e, "crosshair_per_weapon", 0, 0, "crosshair_enabled", 1, 2); + me.TD(me, 3, 1, e = makeXonoticCrosshairPreview()); setDependentAND(e, "crosshair_per_weapon", 0, 0, "crosshair_enabled", 1, 2); me.TR(me); - me.TDempty(me, 0.1); - for(i = 43; i <= 54; ++i) { - me.TDNoMargin(me, 1, 2 / 12, e = makeXonoticCrosshairButton(4, i), '1 1 0'); - setDependentAND(e, "crosshair_per_weapon", 0, 0, "crosshair_enabled", 1, 2); - } me.TR(me); - me.TDempty(me, 0.1); - for(i = 55; i <= 66; ++i) { - me.TDNoMargin(me, 1, 2 / 12, e = makeXonoticCrosshairButton(4, i), '1 1 0'); - setDependentAND(e, "crosshair_per_weapon", 0, 0, "crosshair_enabled", 1, 2); - } me.TR(me); me.TDempty(me, 0.1); me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Crosshair size:"))); -- 2.39.2