diff --git a/addons/ui/CfgFunctions.hpp b/addons/ui/CfgFunctions.hpp index 6e35a8ebc..dbd309a30 100644 --- a/addons/ui/CfgFunctions.hpp +++ b/addons/ui/CfgFunctions.hpp @@ -18,6 +18,7 @@ class CfgFunctions { file = QUOTE(PATHTOF(flexiMenu\fnc_openMenuByDef.sqf)); }; PATHTO_FNC(addPauseMenuOption); + PATHTO_FNC(progressBar); }; }; }; diff --git a/addons/ui/CfgUIGrids.hpp b/addons/ui/CfgUIGrids.hpp new file mode 100644 index 000000000..69dbb249e --- /dev/null +++ b/addons/ui/CfgUIGrids.hpp @@ -0,0 +1,30 @@ +class CfgUIGrids { + class IGUI { + class Presets { + class Arma3 { + class Variables { + GVAR(grid)[] = { + { + 1 * GUI_GRID_CENTER_W + GUI_GRID_CENTER_X, + 0 * GUI_GRID_CENTER_H + GUI_GRID_CENTER_Y, + 38 * GUI_GRID_CENTER_W, + 1 * GUI_GRID_CENTER_H + }, + 0.5 * GUI_GRID_CENTER_W, + 0.5 * GUI_GRID_CENTER_H + }; + }; + }; + }; + + class Variables { + class GVAR(grid) { + displayName = CSTRING(ProgressBarPositionName); + description = CSTRING(ProgressBarPositionDescription); + preview = "#(argb,8,8,3)color(0,0,0,1)"; + saveToProfile[] = {0,1,2,3}; + canResize = 1; + }; + }; + }; +}; diff --git a/addons/ui/RscTitles.hpp b/addons/ui/RscTitles.hpp new file mode 100644 index 000000000..ed9f9dc9e --- /dev/null +++ b/addons/ui/RscTitles.hpp @@ -0,0 +1,57 @@ +class RscText; +class RscProgress; +class RscMapControl; + +class RscTitles { + class GVAR(ProgressBar) { + onLoad = uiNamespace setVariable ['GVAR(ProgressBar)', _this select 0]; + idd = -1; + duration = 1e+11; + fadeIn = 0; + fadeOut = 0; + + controls[] = {"Background", "TitleBackground", "ProgressBar", "TitleText", "Script"}; + + class Background: RscText { + colorBackground[] = {0,0,0,0}; + x = "safezoneXAbs"; + y = "safezoneY"; + w = "safezoneWAbs"; + h = "safezoneH"; + }; + + class TitleBackground: RscText { + idc = IDC_PROGRESSBAR_BACKGROUND; + style = ST_CENTER; + sizeEx = 1 * GUI_GRID_CENTER_H; + colorBackground[] = {0,0,0,0.5}; + x = profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),X)', 0]; + y = profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),Y)', 0]; + w = profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),W)', 0]; + h = profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),H)', 0]; + }; + + class TitleText: TitleBackground { + idc = IDC_PROGRESSBAR_TITLE; + colorBackground[] = {0,0,0,0}; + colorText[] = {1,1,1,1}; + }; + + class ProgressBar: RscProgress { + idc = IDC_PROGRESSBAR_BAR; + colorFrame[] = {0,0,0,0.5}; + colorBar[] = GUI_BCG_COLOR; + texture = "#(argb,8,8,3)color(1,1,1,0.7)"; + x = profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),X)', 0]; + y = profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),Y)', 0]; + w = profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),W)', 0]; + h = profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),H)', 0]; + }; + + class Script: RscMapControl { + idc = IDC_PROGRESSBAR_SCRIPT; + w = 0; + h = 0; + }; + }; +}; diff --git a/addons/ui/XEH_preClientInit.sqf b/addons/ui/XEH_preClientInit.sqf index dbac001d0..6febc990e 100644 --- a/addons/ui/XEH_preClientInit.sqf +++ b/addons/ui/XEH_preClientInit.sqf @@ -3,3 +3,10 @@ LOG(MSG_INIT); call COMPILE_FILE(flexiMenu\init); + +// recreate after loading a savegame +addMissionEventHandler ["Loaded", { + if (!isNil QGVAR(ProgressBarParams)) then { + QGVAR(ProgressBar) cutRsc [QGVAR(ProgressBar), "PLAIN"]; + }; +}]; diff --git a/addons/ui/config.cpp b/addons/ui/config.cpp index 4bc0a57cc..cbbb4d0c4 100644 --- a/addons/ui/config.cpp +++ b/addons/ui/config.cpp @@ -19,9 +19,11 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgFunctions.hpp" +#include "RscTitles.hpp" +#include "CfgUIGrids.hpp" + //----------------------------------------------------------------------------- // TODO: Delete these rsc/_flexiMenu_RscShortcutButton classes soon and transfer properties to menu classes, if any. -class RscText; class RscShortcutButton; class _flexiMenu_RscShortcutButton: RscShortcutButton { class HitZone { diff --git a/addons/ui/fnc_progressBar.sqf b/addons/ui/fnc_progressBar.sqf new file mode 100644 index 000000000..89dd1da9e --- /dev/null +++ b/addons/ui/fnc_progressBar.sqf @@ -0,0 +1,149 @@ +/* ---------------------------------------------------------------------------- +Function: CBA_fnc_progressBar + +Description: + Opens a progress bar. Closes the currently active progress bar. + +Parameters: + _title - Title of the progress bar + _totalTime - Time for the progress bar to complete + _condition - Execute every frame. If reports false, close the progress bar + _onSuccess - Script to execute if the progress bar completed + _onFailure - Script to execute if the progress bar was aborted prematurely + (optional, default: {}) + _arguments - Arguments passed to the scripts (optional, default: []) + _blockMouse - Block mouse input (optional, default: true) + _blockKeys - Block keyboard input + requires _blockMouse to be set to true (optional, default: true) + _allowClose - Allow ESC key to abort the progress bar + requires _blockMouse to be set to true (optional, default: true) + +Arguments: + _this: + #0 - same as _arguments + #1 - true: success, false: failure + #2 - elapsed time, not more than _totalTime + #3 - total time, same as _totalTime + +Returns: + Nothing + +Examples: + (begin example) + ["progress bar", 5, {true}, {hint "done"}, {hint "aborted"}] call CBA_fnc_progressBar; + (end) + +Author: + commy2 +---------------------------------------------------------------------------- */ +#include "script_component.hpp" + +// no progress bar without interface +if (!hasInterface) exitWith {}; + +// execute in unscheduled environment +if (canSuspend) exitWith { + [CBA_fnc_progressBar, _this] call CBA_fnc_directCall; +}; + +// arguments +params [ + ["_title", "", [""]], + ["_totalTime", 0, [0]], + ["_condition", {}, [{true}]], + ["_onSuccess", {}, [{}]], + ["_onFailure", {}, [{}]], + ["_arguments", []], + ["_blockMouse", true, [false]], + ["_blockKeys", true, [false]], + ["_allowClose", true, [false]] +]; + +if (isLocalized _title) then { + _title = localize _title; +}; + +// show progress bar and set title +QGVAR(ProgressBar) cutRsc [QGVAR(ProgressBar), "PLAIN"]; +private _display = uiNamespace getVariable QGVAR(ProgressBar); + +private _ctrlTitle = _display displayCtrl IDC_PROGRESSBAR_TITLE; +_ctrlTitle ctrlSetText _title; + +// run failure code on previous progress bar +if (!isNil QGVAR(ProgressBarParams)) then { + GVAR(ProgressBarParams) params ["_arguments", "", "", "_onFailure", "_startTime", "_totalTime"]; + private _elapsedTime = (CBA_missionTime - _startTime) min _totalTime; + + [_onFailure, [_arguments, false, _elapsedTime, _totalTime]] call CBA_fnc_execNextFrame; +}; + +GVAR(ProgressBarParams) = [_arguments, _condition, _onSuccess, _onFailure, CBA_missionTime, _totalTime, _blockMouse, _blockKeys, _allowClose]; + +// update bar, check condition, execute success or failure scripts +private _ctrlScript = _display displayCtrl IDC_PROGRESSBAR_SCRIPT; +_ctrlScript ctrlAddEventHandler ["Draw", { + params ["_ctrlScript"]; + private _display = ctrlParent _ctrlScript; + + GVAR(ProgressBarParams) params ["_arguments", "_condition", "_onSuccess", "_onFailure", "_startTime", "_totalTime"]; + private _elapsedTime = (CBA_missionTime - _startTime) min _totalTime; + + private _continue = [[_arguments, true, _elapsedTime, _totalTime], _condition] call { + private ["_ctrlScript", "_display", "_arguments", "_condition", "_onSuccess", "_onFailure", "_startTime", "_totalTime", "_elapsedTime"]; + _this#0 call _this#1; + }; + + private _blockInputDisplay = uiNamespace getVariable [QGVAR(BlockInputDisplay), displayNull]; + + if (!_continue) exitWith { + GVAR(ProgressBarParams) = nil; + {QGVAR(ProgressBar) cutText ["", "PLAIN"]} call CBA_fnc_execNextFrame; // game would crash if display is killed from Draw event + _blockInputDisplay closeDisplay 0; + [_onFailure, [_arguments, false, _elapsedTime, _totalTime]] call CBA_fnc_execNextFrame; + }; + + if (_elapsedTime >= _totalTime) exitWith { + GVAR(ProgressBarParams) = nil; + {QGVAR(ProgressBar) cutText ["", "PLAIN"]} call CBA_fnc_execNextFrame; // game would crash if display is killed from Draw event + _blockInputDisplay closeDisplay 0; + [_onSuccess, [_arguments, true, _elapsedTime, _totalTime]] call CBA_fnc_execNextFrame; + }; + + private _ctrlBar = _display displayCtrl IDC_PROGRESSBAR_BAR; + _ctrlBar progressSetPosition (_elapsedTime / _totalTime); +}]; + +// block input while the bar is shown +private _blockInputDisplay = uiNamespace getVariable [QGVAR(BlockInputDisplay), displayNull]; +_blockInputDisplay closeDisplay 0; + +if (_blockMouse) then { + private _mission = uiNamespace getVariable "RscDisplayMission"; + _blockInputDisplay = _mission createDisplay "RscDisplayEmpty"; + uiNamespace setVariable [QGVAR(BlockInputDisplay), _blockInputDisplay]; + + _blockInputDisplay displayAddEventHandler ["KeyDown", { + params ["_blockInputDisplay", "_key", "_shift", "_control", "_alt"]; + + GVAR(ProgressBarParams) params ["_arguments", "", "", "_onFailure", "_startTime", "_totalTime", "_blockMouse", "_blockKeys", "_allowClose"]; + private _elapsedTime = (CBA_missionTime - _startTime) min _totalTime; + + if (_key isEqualTo DIK_ESCAPE) then { + if (_allowClose) then { + GVAR(ProgressBarParams) = nil; + QGVAR(ProgressBar) cutText ["", "PLAIN"]; + _blockInputDisplay closeDisplay 0; + [_onFailure, [_arguments, false, _elapsedTime, _totalTime]] call CBA_fnc_execNextFrame; + + _blockKeys = false; + } else { + _blockKeys = true; + }; + }; + + _blockKeys + }]; +}; + +nil diff --git a/addons/ui/script_component.hpp b/addons/ui/script_component.hpp index dcef8b91e..a048bec61 100644 --- a/addons/ui/script_component.hpp +++ b/addons/ui/script_component.hpp @@ -1,6 +1,8 @@ #define COMPONENT ui #include "\x\cba\addons\main\script_mod.hpp" +//#define DEBUG_MODE_FULL +//#define DISABLE_COMPILE_CACHE //#define DEBUG_ENABLED_UI #ifdef DEBUG_ENABLED_UI @@ -14,9 +16,14 @@ #include "\x\cba\addons\main\script_macros.hpp" #include "\a3\ui_f\hpp\defineCommonGrids.inc" +#include "\a3\ui_f\hpp\defineCommonColors.inc" #include "\a3\ui_f\hpp\defineDIKCodes.inc" #include "\a3\ui_f\hpp\defineResincl.inc" +#define IDC_PROGRESSBAR_TITLE 10 +#define IDC_PROGRESSBAR_BAR 11 +#define IDC_PROGRESSBAR_SCRIPT 12 + #define IDC_ADDON_CONTROLS 127303 #define IDC_ADDON_OPTIONS 127307 diff --git a/addons/ui/stringtable.xml b/addons/ui/stringtable.xml index 3ad2eb42f..c1577076d 100644 --- a/addons/ui/stringtable.xml +++ b/addons/ui/stringtable.xml @@ -9,5 +9,13 @@ Extensões de Base Comunitária - Interface ao Usuário Community Base Addons - Пользовательский Интерфейс + + Progress Bar + Fortschrittsanzeige + + + Position of the progress bar. + Position der Fortschrittsanzeige. +