diff --git a/addons/settings/XEH_PREP.sqf b/addons/settings/XEH_PREP.sqf index 88ba4861d..06eef396f 100644 --- a/addons/settings/XEH_PREP.sqf +++ b/addons/settings/XEH_PREP.sqf @@ -19,6 +19,11 @@ if (hasInterface) then { PREP(gui_saveTempData); PREP(gui_export); + PREP(gui_addonList_fillList); + PREP(gui_addonList_handleSearchbar); + + PREP(gui_onKeyDown); + PREP(gui_settingCheckbox); PREP(gui_settingEditbox); PREP(gui_settingList); diff --git a/addons/settings/fnc_gui_addonChanged.sqf b/addons/settings/fnc_gui_addonChanged.sqf index 643f76cfd..75ccd3d3e 100644 --- a/addons/settings/fnc_gui_addonChanged.sqf +++ b/addons/settings/fnc_gui_addonChanged.sqf @@ -15,8 +15,6 @@ if (_selectedAddon isEqualType "") then { uiNamespace setVariable [QGVAR(addon), _selectedAddon]; }; -uiNamespace setVariable [QGVAR(addonIndex), _index]; - // toggle lists private _selectedSource = uiNamespace getVariable QGVAR(source); diff --git a/addons/settings/fnc_gui_addonList_fillList.sqf b/addons/settings/fnc_gui_addonList_fillList.sqf new file mode 100644 index 000000000..c1671c323 --- /dev/null +++ b/addons/settings/fnc_gui_addonList_fillList.sqf @@ -0,0 +1,29 @@ +#include "script_component.hpp" + +params ["_display", "_ctrlAddonList"]; + +if (lbSize _ctrlAddonList > 0) then { + for "_i" from (lbSize _ctrlAddonList - 1) to 0 step -1 do { + _ctrlAddonList lbDelete _i; + }; +}; + +private _categories = []; +{ + (GVAR(default) getVariable _x) params ["", "", "", "", "_category"]; + + if !(_category in _categories) then { + private _categoryLocalized = _category; + if (isLocalized _category) then { + _categoryLocalized = localize _category; + }; + + private _index = _ctrlAddonList lbAdd _categoryLocalized; + _ctrlAddonList lbSetData [_index, str _index]; + _display setVariable [str _index, _category]; + + _categories pushBack _category; + }; +} forEach GVAR(allSettings); + +lbSort _ctrlAddonList; diff --git a/addons/settings/fnc_gui_addonList_handleSearchbar.sqf b/addons/settings/fnc_gui_addonList_handleSearchbar.sqf new file mode 100644 index 000000000..247c94997 --- /dev/null +++ b/addons/settings/fnc_gui_addonList_handleSearchbar.sqf @@ -0,0 +1,48 @@ +#include "script_component.hpp" + +params ["_display", "_searchbar"]; + +private _searchString = ctrlText _searchbar; +if (_searchString != "") then { + _searchString = _searchString regexReplace ["[.?*+^$[\]\\(){}|-]/gio", "\\$&"]; // escape any user regex characters + _searchString = ".*?" + (_searchString splitString " " joinString ".*?") + ".*?/io"; +}; + +private _ctrlAddonList = _display displayCtrl IDC_ADDONS_LIST; + +private _selectedAddon = _ctrlAddonList lbText lbCurSel _ctrlAddonList; +if (_selectedAddon == "") then { + _selectedAddon = _ctrlAddonList lbText 0; +}; + +private _lastSearchString = _display getVariable [QGVAR(addonSearchString), ""]; +if (_lastSearchString != "" && {_lastSearchString isNotEqualTo _searchString}) then { + [_display, _ctrlAddonList] call FUNC(gui_addonList_fillList); +}; + +_display setVariable [QGVAR(addonSearchString), _searchString]; + +if (_searchString == "") exitWith { + _ctrlAddonList lbSetCurSel 0; +}; + +private _currentDisplayName = ""; + +// Go through all items in list and see if they need to be deleted or not +for "_lbIndex" from (lbSize _ctrlAddonList - 1) to 0 step -1 do { + _currentDisplayName = _ctrlAddonList lbText _lbIndex; + + if !(_currentDisplayName regexMatch _searchString) then { + _ctrlAddonList lbDelete _lbIndex; + }; +}; + +// Try to select previously selected item again +private _index = 0; +for "_lbIndex" from 0 to (lbSize _ctrlAddonList - 1) do { + if ((_ctrlAddonList lbText _lbIndex) == _selectedAddon) exitWith { + _index = _lbIndex; + }; +}; + +_ctrlAddonList lbSetCurSel _index; diff --git a/addons/settings/fnc_gui_onKeyDown.sqf b/addons/settings/fnc_gui_onKeyDown.sqf new file mode 100644 index 000000000..8913b9da0 --- /dev/null +++ b/addons/settings/fnc_gui_onKeyDown.sqf @@ -0,0 +1,24 @@ +#include "script_component.hpp" + +params ["_display", "_key", "_shift", "_ctrl"]; + +private _block = false; + +switch (_key) do { + case DIK_NUMPADENTER; + case DIK_RETURN: { + if (GVAR(AddonSearchbarFocus)) then { + [_display, _display displayCtrl IDC_ADDONS_SEARCHBAR] call FUNC(gui_addonList_handleSearchbar); + _block = true; + }; + }; + // Focus search bars + case DIK_F: { + if (_ctrl) then { + ctrlSetFocus (_display displayCtrl IDC_ADDONS_SEARCHBAR); + _block = true; + }; + }; +}; + +_block diff --git a/addons/settings/fnc_initDisplayGameOptions.sqf b/addons/settings/fnc_initDisplayGameOptions.sqf index 6cec2b18d..2dfd1c2c0 100644 --- a/addons/settings/fnc_initDisplayGameOptions.sqf +++ b/addons/settings/fnc_initDisplayGameOptions.sqf @@ -69,7 +69,7 @@ with uiNamespace do { GVAR(awaitingRestartTemp) = + GVAR(awaitingRestart); // ----- create addons list (filled later) -private _ctrlAddonList = _display ctrlCreate [QGVAR(AddonsList), -1, _ctrlAddonsGroup]; +private _ctrlAddonList = _display ctrlCreate [QGVAR(AddonsList), IDC_ADDONS_LIST, _ctrlAddonsGroup]; _ctrlAddonList ctrlAddEventHandler ["LBSelChanged", {_this call FUNC(gui_addonChanged)}]; @@ -77,26 +77,18 @@ _ctrlAddonList ctrlAddEventHandler ["LBSelChanged", {_this call FUNC(gui_addonCh _display setVariable [QGVAR(lists),[]]; // ----- fill addons list -private _categories = []; -{ - (GVAR(default) getVariable _x) params ["", "", "", "", "_category"]; - - if !(_category in _categories) then { - private _categoryLocalized = _category; - if (isLocalized _category) then { - _categoryLocalized = localize _category; +[_display, _ctrlAddonList] call FUNC(gui_addonList_fillList); + +private _listIndex = 0; +private _lastAddon = uiNamespace getVariable [QGVAR(addon), ""]; +if (_lastAddon != "") then { + for "_lbIndex" from 0 to (lbSize _ctrlAddonList - 1) do { + if ((_display getVariable [(_ctrlAddonList lbData _lbIndex), ""]) == _lastAddon) exitWith { + _listIndex = _lbIndex; }; - - private _index = _ctrlAddonList lbAdd _categoryLocalized; - _ctrlAddonList lbSetData [_index, str _index]; - _display setVariable [str _index, _category]; - - _categories pushBack _category; }; -} forEach GVAR(allSettings); - -lbSort _ctrlAddonList; -_ctrlAddonList lbSetCurSel (uiNamespace getVariable [QGVAR(addonIndex), 0]); +}; +_ctrlAddonList lbSetCurSel _listIndex; // ----- create save and load presets buttons private _ctrlButtonSave = _display ctrlCreate ["RscButtonMenu", IDC_BTN_SAVE]; @@ -131,6 +123,7 @@ _ctrlButtonLoad ctrlEnable false; _ctrlButtonLoad ctrlShow false; _ctrlButtonLoad ctrlAddEventHandler ["ButtonClick", {[ctrlParent (_this select 0), "load"] call FUNC(gui_preset)}]; + // ----- create export and import buttons private _ctrlButtonImport = _display ctrlCreate ["RscButtonMenu", IDC_BTN_IMPORT]; diff --git a/addons/settings/fnc_openSettingsMenu.sqf b/addons/settings/fnc_openSettingsMenu.sqf index cbb5c16ca..4f78fc50c 100644 --- a/addons/settings/fnc_openSettingsMenu.sqf +++ b/addons/settings/fnc_openSettingsMenu.sqf @@ -26,3 +26,11 @@ private _ctrlConfirm = _dlgSettings ctrlCreate ["RscButtonMenuOK", IDC_CANCEL]; _ctrlConfirm ctrlSetPosition ctrlPosition _ctrlScriptedOK; _ctrlConfirm ctrlCommit 0; _ctrlConfirm ctrlAddEventHandler ["ButtonClick", {call FUNC(gui_saveTempData)}]; + +// Add keyDown EH for search bar +GVAR(AddonSearchbarFocus) = false; + +_dlgSettings displayAddEventHandler ["KeyDown", {call FUNC(gui_onKeyDown)}]; +_dlgSettings displayAddEventHandler ["Unload", { + GVAR(AddonSearchbarFocus) = nil; +}]; diff --git a/addons/settings/gui.hpp b/addons/settings/gui.hpp index a5c5e3031..0be5e578b 100644 --- a/addons/settings/gui.hpp +++ b/addons/settings/gui.hpp @@ -1,6 +1,8 @@ class RscButtonMenu; class RscControlsGroupNoScrollbars; class RscText; +class RscEdit; +class ctrlButtonPicture; class RscDisplayGameOptions { // pause game in SP while this menu is shown @@ -62,12 +64,32 @@ class RscDisplayGameOptions { idc = -1; style = ST_RIGHT; text = ECSTRING(main,AddonText); - x = QUOTE(POS_W(0.5)); - y = QUOTE(POS_H(1)); + x = QUOTE(POS_W(0)); + y = QUOTE(POS_H(0.8)); w = QUOTE(POS_W(4)); h = QUOTE(POS_H(1)); sizeEx = QUOTE(POS_H(1)); }; + class AddonSearch: RscEdit { + idc = IDC_ADDONS_SEARCHBAR; + onSetFocus = QUOTE(GVAR(AddonSearchbarFocus) = true); + onKillFocus = QUOTE(GVAR(AddonSearchbarFocus) = false); + x = QUOTE(POS_W(20)); + y = QUOTE(POS_H(0.8)); + w = QUOTE(POS_W(15)); + h = QUOTE(POS_H(1)); + sizeEx = QUOTE(POS_H(1)); + }; + class AddonSearchButton: ctrlButtonPicture { + idc = -1; + text = "\a3\Ui_f\data\GUI\RscCommon\RscButtonSearch\search_start_ca.paa"; + colorBackground[] = {0,0,0,0.4}; + onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), (ctrlParentControlsGroup (_this select 0)) controlsGroupCtrl IDC_ADDONS_SEARCHBAR)] call FUNC(gui_addonList_handleSearchbar)); + x = QUOTE(POS_W(34.95)); + y = QUOTE(POS_H(0.72)); + w = QUOTE(POS_W(1)); + h = QUOTE(POS_H(1.1)); + }; class OverwriteClientText: RscText { // Set tooltip per script to avoid it being all upper case. // Disable multiline text to make in unselectable. @@ -162,9 +184,9 @@ class GVAR(AddonsList): GVAR(RscCombo) { linespacing = 1; text = ""; wholeHeight = QUOTE(POS_H(12)); - x = QUOTE(POS_W(4.5)); - y = QUOTE(POS_H(1)); - w = QUOTE(POS_W(21)); + x = QUOTE(POS_W(4)); + y = QUOTE(POS_H(0.8)); + w = QUOTE(POS_W(15)); h = QUOTE(POS_H(1)); }; @@ -292,8 +314,6 @@ class GVAR(Row_Checkbox): GVAR(Row_Base) { }; }; -class RscEdit; - class GVAR(Row_Editbox): GVAR(Row_Base) { GVAR(script) = QFUNC(gui_settingEditbox); diff --git a/addons/settings/script_component.hpp b/addons/settings/script_component.hpp index 131fdb723..71b5199d5 100644 --- a/addons/settings/script_component.hpp +++ b/addons/settings/script_component.hpp @@ -21,6 +21,8 @@ #include "\x\cba\addons\main\script_macros.hpp" #define IDC_ADDONS_GROUP 4301 +#define IDC_ADDONS_SEARCHBAR 4311 +#define IDC_ADDONS_LIST 4312 #define IDC_BTN_CONFIGURE_ADDONS 4302 #define IDC_BTN_CLIENT 9001 #define IDC_BTN_MISSION 9002