From e69ffb6f216228eb241b972fe9182545e70768e4 Mon Sep 17 00:00:00 2001 From: Grim <69561145+LinkIsGrim@users.noreply.github.com> Date: Tue, 6 Feb 2024 20:34:52 -0300 Subject: [PATCH] Arsenal Actions - Add support for multiline text & updating on cargo event (#9771) Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/arsenal/XEH_preInit.sqf | 9 ++++ addons/arsenal/defines.hpp | 2 + addons/arsenal/functions/fnc_addAction.sqf | 8 +++- .../arsenal/functions/fnc_compileActions.sqf | 6 +++ .../arsenal/functions/fnc_handleActions.sqf | 44 +++++++++++++++---- addons/arsenal/ui/RscAttributes.hpp | 9 ++-- docs/wiki/framework/arsenal-framework.md | 5 +++ 7 files changed, 69 insertions(+), 14 deletions(-) diff --git a/addons/arsenal/XEH_preInit.sqf b/addons/arsenal/XEH_preInit.sqf index 7002886f77..0227e18f0a 100644 --- a/addons/arsenal/XEH_preInit.sqf +++ b/addons/arsenal/XEH_preInit.sqf @@ -36,6 +36,15 @@ call FUNC(compileStats); EGVAR(common,blockItemReplacement) = false; }] call CBA_fnc_addEventHandler; +[QGVAR(cargoChanged), { + params ["_display"]; + // Only update actions if necessary, this can get performance-intensive using the arrow keys + if (!GVAR(updateActionsOnCargoChange)) exitWith {}; + private _actionInfo = [_display]; + _actionInfo append GVAR(actionInfo); + [QGVAR(displayActions), _actionInfo] call CBA_fnc_localEvent; +}] call CBA_fnc_addEventHandler; + // Setup Tools tab [keys (uiNamespace getVariable [QGVAR(configItemsTools), createHashMap]), LLSTRING(toolsTab), TOOLS_TAB_ICON, -1, true] call FUNC(addRightPanelButton); diff --git a/addons/arsenal/defines.hpp b/addons/arsenal/defines.hpp index 73116dde76..ac84f0d8a4 100644 --- a/addons/arsenal/defines.hpp +++ b/addons/arsenal/defines.hpp @@ -155,6 +155,8 @@ #define IDC_statsNextPage 53 #define IDC_statsCurrentPage 54 #define IDC_actionsBox 90 +#define IDC_actionsBackground1 90010 +#define IDC_actionsBackground2 90011 #define IDC_actionsText1 9001 #define IDC_actionsButton1 9002 #define IDC_actionsText2 9003 diff --git a/addons/arsenal/functions/fnc_addAction.sqf b/addons/arsenal/functions/fnc_addAction.sqf index 9f69d2d51f..05557f159a 100644 --- a/addons/arsenal/functions/fnc_addAction.sqf +++ b/addons/arsenal/functions/fnc_addAction.sqf @@ -10,6 +10,7 @@ * 3: Actions * 4: Condition (default: {true}) * 5: Scope editor (default: 2) + * 6: Update when cargo content changes (default: false) * * Return Value: * 0: Array of IDs @@ -30,7 +31,8 @@ params [ ["_title", "", [""]], ["_actions", [], [[]]], ["_rootCondition", {true}, [{}]], - ["_scopeEditor", 2, [0]] + ["_scopeEditor", 2, [0]], + ["_updateOnCargoChange", false, [false]] ]; // Compile actions from config (in case this is called before preInit) @@ -119,4 +121,8 @@ private _group = []; }; } forEach _tabs; +if (_updateOnCargoChange) then { + GVAR(updateActionsOnCargoChange) = true; +}; + _return diff --git a/addons/arsenal/functions/fnc_compileActions.sqf b/addons/arsenal/functions/fnc_compileActions.sqf index 6eda62ac65..cec152bd6a 100644 --- a/addons/arsenal/functions/fnc_compileActions.sqf +++ b/addons/arsenal/functions/fnc_compileActions.sqf @@ -37,6 +37,8 @@ private _actionList = [ private _configGroupEntries = "true" configClasses (configFile >> QGVAR(actions)); +GVAR(updateActionsOnCargoChange) = false; + { private _scopeEditor = getNumber (_x >> "scopeEditor"); @@ -48,6 +50,10 @@ private _configGroupEntries = "true" configClasses (configFile >> QGVAR(actions) private _rootDisplayName = getText (_x >> "displayName"); private _rootCondition = getText (_x >> "condition"); private _rootTabs = getArray (_x >> "tabs"); + private _updateOnCargoChanged = getNumber (_x >> "updateOnCargoChanged"); + if (_updateOnCargoChanged > 0) then { + GVAR(updateActionsOnCargoChange) = true; + }; if (_rootCondition != "") then { _rootCondition = compile _rootCondition; diff --git a/addons/arsenal/functions/fnc_handleActions.sqf b/addons/arsenal/functions/fnc_handleActions.sqf index f89b4f1259..f28e448256 100644 --- a/addons/arsenal/functions/fnc_handleActions.sqf +++ b/addons/arsenal/functions/fnc_handleActions.sqf @@ -15,7 +15,6 @@ * * Public: No */ - params ["_display", "_control", "_curSel", "_itemCfg"]; GVAR(actionsInfo) = [_control, _curSel, _itemCfg]; @@ -46,13 +45,12 @@ private _groups = (GVAR(actionList) select _panel) select { }; private _show = _groups isNotEqualTo []; -private _ctrl = _display displayCtrl IDC_actionsBox; -_ctrl ctrlShow _show; -_ctrl ctrlCommit 0.15; +private _actionsBoxCtrl = _display displayCtrl IDC_actionsBox; +_actionsBoxCtrl ctrlShow _show; +_actionsBoxCtrl ctrlCommit 0.15; if (!_show) exitWith {}; -private _actionsBoxCtrl = _display displayCtrl IDC_actionsBox; private _actionsCurrentPageCtrl = _display displayCtrl IDC_actionsCurrentPage; private _currentPage = GVAR(currentActionPage); @@ -83,10 +81,11 @@ _actionsCurrentPageCtrl ctrlSetFade 0; _actionsCurrentPageCtrl ctrlShow true; _actionsCurrentPageCtrl ctrlCommit 0; +private _activeCtrls = []; { _x params ["", "_type", "_label", "_statement"]; - private _idc = 9001 + _forEachIndex * 2; + private _idc = IDC_actionsText1 + _forEachIndex * 2; private _actionTextCtrl = _display displayCtrl _idc; private _actionButtonCtrl = _display displayCtrl (_idc + 1); @@ -99,13 +98,23 @@ _actionsCurrentPageCtrl ctrlCommit 0; [true] call FUNC(refresh); }] call CBA_fnc_execNextFrame; }]; + + if (_activeCtrls isNotEqualTo []) then { + (ctrlPosition (_activeCtrls select -1)) params ["", "_lastPosY", "", "_lastPosH"]; + _actionButtonCtrl ctrlSetPositionY (_lastPosY + _lastPosH + GRID_H); + } else { + _actionButtonCtrl ctrlSetPositionY (6 * GRID_H); + }; + _actionButtonCtrl ctrlAddEventHandler ["ButtonClick", _statement]; _actionButtonCtrl ctrlSetText _label; _actionButtonCtrl ctrlSetFade 0; _actionButtonCtrl ctrlEnable true; _actionButtonCtrl ctrlCommit 0; _actionTextCtrl ctrlSetFade 1; + _actionTextCtrl ctrlEnable false; _actionTextCtrl ctrlCommit 0; + _activeCtrls pushBack _actionButtonCtrl; }; case ACTION_TYPE_TEXT: { private _text = call _statement; @@ -113,13 +122,25 @@ _actionsCurrentPageCtrl ctrlCommit 0; if (isNil "_text") then { _text = ""; }; + if (_text isEqualType []) then { + _text = _text joinString endl; + }; + if (_activeCtrls isNotEqualTo []) then { + (ctrlPosition (_activeCtrls select -1)) params ["", "_lastPosY", "", "_lastPosH"]; + _actionTextCtrl ctrlSetPositionY (_lastPosY + _lastPosH + GRID_H); + } else { + _actionTextCtrl ctrlSetPositionY (5 * GRID_H); + }; _actionTextCtrl ctrlSetText _text; + _actionTextCtrl ctrlSetPositionH (ctrlTextHeight _actionTextCtrl); _actionTextCtrl ctrlSetFade 0; + _actionTextCtrl ctrlEnable false; _actionTextCtrl ctrlCommit 0; _actionButtonCtrl ctrlSetFade 1; _actionButtonCtrl ctrlEnable false; _actionButtonCtrl ctrlCommit 0; + _activeCtrls pushBack _actionTextCtrl; }; default { _actionTextCtrl ctrlSetFade 1; @@ -134,7 +155,7 @@ _actionsCurrentPageCtrl ctrlCommit 0; private _actionCount = count _items; { - private _idc = 9001 + _x * 2; + private _idc = IDC_actionsText1 + _x * 2; private _actionTextCtrl = _display displayCtrl _idc; private _actionButtonCtrl = _display displayCtrl (_idc + 1); @@ -145,6 +166,11 @@ private _actionCount = count _items; } forEach ([0, 1, 2, 3, 4] select [_actionCount, 5]); private _pos = ctrlPosition _actionsBoxCtrl; -_pos set [3, ([11, (5 * _actionCount) + 6] select (_actionCount > 0)) * GRID_H]; -_actionsBoxCtrl ctrlSetPosition _pos; +(ctrlPosition (_activeCtrls select -1)) params ["", "_lastPosY", "", "_lastPosH"]; +private _actionsBoxHeight = _lastPosY + _lastPosH + GRID_H; +_actionsBoxCtrl ctrlSetPositionH _actionsBoxHeight; _actionsBoxCtrl ctrlCommit 0; + +private _background = _display displayCtrl IDC_actionsBackground1; +_background ctrlSetPositionH _actionsBoxHeight; +_background ctrlCommit 0; diff --git a/addons/arsenal/ui/RscAttributes.hpp b/addons/arsenal/ui/RscAttributes.hpp index 0265e86f3f..69acebc52c 100644 --- a/addons/arsenal/ui/RscAttributes.hpp +++ b/addons/arsenal/ui/RscAttributes.hpp @@ -450,22 +450,22 @@ class GVAR(display) { h = QUOTE(55 * GRID_H); class controls { class actionsStaticBackground1: ctrlStaticBackground { - idc = -1; + idc = IDC_actionsBackground1; x = QUOTE(0); y = QUOTE(0); w = QUOTE(47 * GRID_W); - h = QUOTE(56 * GRID_H); + h = QUOTE(55 * GRID_H); colorBackground[]={0.1,0.1,0.1,0.5}; }; class actionsStaticBackground2: ctrlStaticBackground { - idc = -1; + idc = IDC_actionsBackground2; x = QUOTE(0); y = QUOTE(0); w = QUOTE(47 * GRID_W); h = QUOTE(5 * GRID_H); colorBackground[]={0.1,0.1,0.1,0.8}; }; - class actionsText1: RscText { + class actionsText1: RscTextMulti { idc = IDC_actionsText1; fade = 1; x = QUOTE(0 * GRID_W); @@ -479,6 +479,7 @@ class GVAR(display) { }; class actionsButton1: ctrlButton { idc = IDC_actionsButton1; + onMouseEnter = QUOTE(ctrlSetFocus (_this select 0)); fade = 1; text = ""; x = QUOTE(1 * GRID_W); diff --git a/docs/wiki/framework/arsenal-framework.md b/docs/wiki/framework/arsenal-framework.md index 95c7e82211..4baddf66ad 100644 --- a/docs/wiki/framework/arsenal-framework.md +++ b/docs/wiki/framework/arsenal-framework.md @@ -402,6 +402,8 @@ For actions involving frame delays or timers, a second call of the `ace_arsenal_ Since CBA frame functions are deactivated during preInit as of Oct 24th 2023, the refresh function is executed immediatelly after the action code is executed. Take note of this information and the comment below if you'd like your actions to be usable in 3DEN. +By default actions are updated whenever the arsenal is refreshed (`ace_arsenal_fnc_refresh`) and whenever item info (the bottom right GUI element that shows item name and author) is updated. If any action with the `updateOnCargoChanged` property is added, then actions will also be updated on container inventory changes. + ### 7.1 Adding actions via config ```cpp @@ -410,6 +412,7 @@ class ace_arsenal_actions { displayName = "My Actions"; condition = QUOTE(true); scopeEditor = 2; // Only actions with scopeEditor = 2 are shown in 3DEN. Actions working with variables should take object variables being reset between editor view and mission start into account. + updateOnCargoChanged = 1; // See comment above. tabs[] = {0,5}; class text { // A simple text label @@ -417,6 +420,7 @@ class ace_arsenal_actions { }; class statement { // Statement output as text + // Return can be string or array of strings: for array each entry is automatically displayed on a separate line textStatement = QUOTE([_this select 0] call tag_fnc_myTextStatement); }; class button { @@ -441,6 +445,7 @@ The focused unit object is passed to the condition and statement functions. 3 | Actions | Array of arrays | Required 4 | Condition | Code | Optional (default: `{true}`) 5 | Scope editor | Number | Optional (default: `2`) +6 | Update on cargo change | Boolean | Optional (default: `false`) Return Value: - Array of action IDs