1#ifndef GAME_CLIENT_COMPONENTS_MENUS_INGAME_TOUCH_CONTROLS_H
2#define GAME_CLIENT_COMPONENTS_MENUS_INGAME_TOUCH_CONTROLS_H
3#include <game/client/component.h>
4#include <game/client/components/touch_controls.h>
5#include <game/client/ui.h>
6
7#include <memory>
8
9class CMenusIngameTouchControls : public CComponentInterfaces
10{
11public:
12 static constexpr const float BUTTON_EDITOR_WIDTH = 700.0f;
13 enum class EBehaviorType
14 {
15 BIND,
16 BIND_TOGGLE,
17 PREDEFINED,
18 NUM_BEHAVIORS
19 };
20
21 enum class EPredefinedType
22 {
23 INGAME_MENU,
24 EXTRA_MENU,
25 EMOTICON,
26 SPECTATE,
27 SWAP_ACTION,
28 USE_ACTION,
29 JOYSTICK_ACTION,
30 JOYSTICK_AIM,
31 JOYSTICK_FIRE,
32 JOYSTICK_HOOK,
33 NUM_PREDEFINEDTYPES
34 };
35
36 // Which menu is selected.
37 enum class EMenuType
38 {
39 MENU_FILE,
40 MENU_BUTTONS,
41 MENU_SETTINGS,
42 MENU_PREVIEW,
43 NUM_MENUS
44 };
45 EMenuType m_CurrentMenu = EMenuType::MENU_FILE;
46
47 enum class ESortType
48 {
49 LABEL,
50 X,
51 Y,
52 W,
53 H,
54 NUM_SORTS
55 };
56 ESortType m_SortType = ESortType::LABEL;
57
58 enum class EElementType
59 {
60 LAYOUT,
61 VISIBILITY,
62 BEHAVIOR,
63 NUM_ELEMENTS
64 };
65 EElementType m_EditElement = EElementType::LAYOUT;
66
67 enum class EVisibilityType
68 {
69 EXCLUDE,
70 INCLUDE,
71 IGNORE,
72 NUM_VISIBILITIES
73 };
74 std::array<EVisibilityType, (size_t)CTouchControls::EButtonVisibility::NUM_VISIBILITIES> m_aCachedVisibilities; // 0:-, 1:+, 2:Ignored.
75
76 // Mainly for passing values in popups.
77 CTouchControls::CTouchButton *m_pOldSelectedButton = nullptr;
78 CTouchControls::CTouchButton *m_pNewSelectedButton = nullptr;
79
80 // Storing everything you are editing.
81 CLineInputNumber m_InputX;
82 CLineInputNumber m_InputY;
83 CLineInputNumber m_InputW;
84 CLineInputNumber m_InputH;
85 CTouchControls::EButtonShape m_CachedShape;
86
87 EBehaviorType m_EditBehaviorType = EBehaviorType::BIND;
88 EPredefinedType m_PredefinedBehaviorType = EPredefinedType::EXTRA_MENU;
89 int m_CachedExtraMenuNumber = 0;
90
91 class CBehaviorElements
92 {
93 public:
94 CLineInputBuffered<1024> m_InputCommand;
95 CLineInputBuffered<1024> m_InputLabel;
96 CTouchControls::CBindToggleTouchButtonBehavior::CCommand m_CachedCommands;
97 CButtonContainer m_BindToggleAddButtons;
98 CButtonContainer m_BindToggleDeleteButtons;
99 CButtonContainer m_aLabelTypeRadios[(int)CTouchControls::CButtonLabel::EType::NUM_TYPES];
100
101 CBehaviorElements() noexcept;
102 CBehaviorElements(CBehaviorElements &&Other) noexcept;
103 ~CBehaviorElements();
104 CBehaviorElements &operator=(CBehaviorElements &&Other) noexcept;
105
106 CBehaviorElements &operator=(const CBehaviorElements &) = delete;
107 CBehaviorElements(const CBehaviorElements &Other) = delete;
108
109 std::string ParseLabel(const char *pLabel) const;
110 void UpdateInputs();
111 void UpdateLabel() { m_CachedCommands.m_Label = ParseLabel(pLabel: m_InputLabel.GetString()); }
112 void UpdateCommand() { m_CachedCommands.m_Command = m_InputCommand.GetString(); }
113 void Reset();
114 };
115 std::vector<std::unique_ptr<CBehaviorElements>> m_vBehaviorElements;
116
117 unsigned m_ColorActive = 0;
118 unsigned m_ColorInactive = 0;
119
120 // Used for creating ui elements.
121 std::array<CButtonContainer, (unsigned)CTouchControls::EButtonVisibility::NUM_VISIBILITIES> m_aVisibilityIds = {};
122 std::array<CButtonContainer, (unsigned)ESortType::NUM_SORTS> m_aSortHeaderIds = {};
123 std::array<CButtonContainer, (unsigned)EElementType::NUM_ELEMENTS> m_aEditElementIds = {};
124
125 // Functional variables.
126 bool m_FirstEnter = true; // Execute something when first opening the editor.
127 bool m_CloseMenu = false; // Decide if closing menu after the popup confirm.
128 bool m_NeedUpdatePreview = true; // Whether to reload the button being previewed.
129 bool m_NeedSort = true; // Whether to sort all previewed buttons.
130 bool m_NeedFilter = false; // Whether to exclude some buttons from preview.
131 std::vector<CTouchControls::CTouchButton *> m_vpButtons;
132 std::vector<CTouchControls::CTouchButton *> m_vpMutableButtons;
133 CLineInputBuffered<1024> m_FilterInput;
134 int m_SelectedPreviewButtonIndex = -1;
135
136 void RenderTouchButtonEditor(CUIRect MainView);
137 bool RenderLayoutSettingBlock(CUIRect Block);
138 bool RenderBehaviorSettingBlock(CUIRect Block);
139 bool RenderVisibilitySettingBlock(CUIRect Block);
140 void RenderTouchButtonBrowser(CUIRect MainView);
141 void RenderPreviewButton(CUIRect MainView);
142
143 void RenderSelectingTab(CUIRect SelectingTab);
144 void RenderConfigSettings(CUIRect MainView);
145 void RenderPreviewSettings(CUIRect MainView);
146 void RenderTouchControlsEditor(CUIRect MainView);
147
148 // Confirm, Cancel only decide if saving cached settings.
149 void DoPopupType(CTouchControls::CPopupParam PopupParam);
150 void ChangeSelectedButtonWhileHavingUnsavedChanges() const;
151 void NoSpaceForOverlappingButton() const;
152 void SelectedButtonNotVisible();
153
154 // Getter and setters.
155 bool UnsavedChanges() const;
156 void SetUnsavedChanges(bool UnsavedChanges);
157
158 // Convenient functions.
159 bool CheckCachedSettings() const;
160 void ResetCachedSettings();
161 void CacheAllSettingsFromTarget(CTouchControls::CTouchButton *pTargetButton);
162 void SaveCachedSettingsToTarget(CTouchControls::CTouchButton *pTargetButton) const;
163 void SetPosInputs(CTouchControls::CUnitRect MyRect);
164 void InputPosFunction(CLineInputNumber *pInput);
165 void UpdateSampleButton();
166 void ResetButtonPointers();
167 void NewVirtualButton();
168 void ResolveIssues();
169 int CalculatePredefinedType(const char *pType) const;
170 std::string DetermineTouchButtonCommandLabel(CTouchControls::CTouchButton *pButton) const;
171 const char **VisibilityNames() const;
172 const char **PredefinedNames() const;
173
174 class CBehaviorFactoryEditor
175 {
176 public:
177 const char *m_pId;
178 std::function<std::unique_ptr<CTouchControls::CPredefinedTouchButtonBehavior>()> m_Factory;
179 };
180
181 static const CBehaviorFactoryEditor BEHAVIOR_FACTORIES_EDITOR[10];
182};
183
184#endif
185