GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/* |
||
2 |
* The ManaPlus Client |
||
3 |
* Copyright (C) 2007 Joshua Langley <[email protected]> |
||
4 |
* Copyright (C) 2009 The Mana World Development Team |
||
5 |
* Copyright (C) 2009-2010 The Mana Developers |
||
6 |
* Copyright (C) 2011-2019 The ManaPlus Developers |
||
7 |
* Copyright (C) 2019-2021 Andrei Karas |
||
8 |
* |
||
9 |
* This file is part of The ManaPlus Client. |
||
10 |
* |
||
11 |
* This program is free software; you can redistribute it and/or modify |
||
12 |
* it under the terms of the GNU General Public License as published by |
||
13 |
* the Free Software Foundation; either version 2 of the License, or |
||
14 |
* any later version. |
||
15 |
* |
||
16 |
* This program is distributed in the hope that it will be useful, |
||
17 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
18 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
19 |
* GNU General Public License for more details. |
||
20 |
* |
||
21 |
* You should have received a copy of the GNU General Public License |
||
22 |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
23 |
*/ |
||
24 |
|||
25 |
#include "gui/widgets/tabs/setup_input.h" |
||
26 |
|||
27 |
#include "configuration.h" |
||
28 |
|||
29 |
#include "const/gui/pages.h" |
||
30 |
|||
31 |
#include "input/inputactionoperators.h" |
||
32 |
#include "input/inputmanager.h" |
||
33 |
#include "input/keyboardconfig.h" |
||
34 |
|||
35 |
#include "input/pages/craft.h" |
||
36 |
#include "input/pages/emotes.h" |
||
37 |
#include "input/pages/move.h" |
||
38 |
#include "input/pages/outfits.h" |
||
39 |
#include "input/pages/shortcuts.h" |
||
40 |
|||
41 |
#include "gui/gui.h" |
||
42 |
#include "gui/setupinputpages.h" |
||
43 |
|||
44 |
#include "gui/windows/okdialog.h" |
||
45 |
|||
46 |
#include "gui/widgets/button.h" |
||
47 |
#include "gui/widgets/containerplacer.h" |
||
48 |
#include "gui/widgets/createwidget.h" |
||
49 |
#include "gui/widgets/layouthelper.h" |
||
50 |
#include "gui/widgets/listbox.h" |
||
51 |
#include "gui/widgets/scrollarea.h" |
||
52 |
#include "gui/widgets/tabstrip.h" |
||
53 |
|||
54 |
#include "gui/models/keylistmodel.h" |
||
55 |
|||
56 |
#include "utils/delete2.h" |
||
57 |
#include "utils/gettext.h" |
||
58 |
|||
59 |
#include "debug.h" |
||
60 |
|||
61 |
2 |
Setup_Input::Setup_Input(const Widget2 *const widget) : |
|
62 |
SetupTab(widget), |
||
63 |
✓✗ | 4 |
mKeyListModel(new KeyListModel), |
64 |
✓✗✓✗ ✓✗✓✗ |
8 |
mKeyList(CREATEWIDGETR(ListBox, this, mKeyListModel, "")), |
65 |
// TRANSLATORS: button in input settings tab |
||
66 |
2 |
mAssignKeyButton(new Button(this, _("Assign"), "assign", |
|
67 |
✓✗✓✗ |
2 |
BUTTON_SKIN, this)), |
68 |
// TRANSLATORS: button in input settings tab |
||
69 |
2 |
mUnassignKeyButton(new Button(this, _("Unassign"), "unassign", |
|
70 |
✓✗✓✗ |
2 |
BUTTON_SKIN, this)), |
71 |
// TRANSLATORS: button in input settings tab |
||
72 |
2 |
mDefaultButton(new Button(this, _("Default"), "default", |
|
73 |
✓✗✓✗ |
2 |
BUTTON_SKIN, this)), |
74 |
// TRANSLATORS: button in input settings tab |
||
75 |
2 |
mResetKeysButton(new Button(this, _("Reset all keys"), "resetkeys", |
|
76 |
✓✗✓✗ |
2 |
BUTTON_SKIN, this)), |
77 |
✓✗✓✗ ✓✗✓✗ |
8 |
mTabs(new TabStrip(this, config.getIntValue("fontSize") + 10, 0)), |
78 |
2 |
mScrollArea(new ScrollArea(this, mKeyList, |
|
79 |
✓✗✓✗ |
4 |
Opaque_true, "setup_input_background.xml")), |
80 |
mKeySetting(false), |
||
81 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
76 |
mActionDataSize(new int [SETUP_PAGES]) |
82 |
{ |
||
83 |
2 |
inputManager.setSetupInput(this); |
|
84 |
// TRANSLATORS: setting tab name |
||
85 |
✓✗ | 10 |
setName(_("Input")); |
86 |
|||
87 |
4 |
mKeyListModel->setSelectedData(0); |
|
88 |
|||
89 |
✓✓ | 22 |
for (int f = 0; f < SETUP_PAGES; f ++) |
90 |
{ |
||
91 |
int cnt = 0; |
||
92 |
✓✓ | 2548 |
while (!setupActionData[f][cnt].name.empty()) |
93 |
836 |
cnt ++; |
|
94 |
20 |
mActionDataSize[f] = cnt; |
|
95 |
} |
||
96 |
|||
97 |
4 |
mKeyListModel->setSize(mActionDataSize[0]); |
|
98 |
✓✗ | 2 |
refreshKeys(); |
99 |
✓✗ | 2 |
if (gui != nullptr) |
100 |
✓✗ | 4 |
mKeyList->setFont(gui->getHelpFont()); |
101 |
✓✗ | 2 |
mKeyList->addActionListener(this); |
102 |
|||
103 |
✓✗ | 2 |
mScrollArea->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER); |
104 |
✓✗ | 2 |
mAssignKeyButton->addActionListener(this); |
105 |
4 |
mAssignKeyButton->setEnabled(false); |
|
106 |
✓✗ | 2 |
mUnassignKeyButton->addActionListener(this); |
107 |
4 |
mUnassignKeyButton->setEnabled(false); |
|
108 |
✓✗ | 2 |
mResetKeysButton->addActionListener(this); |
109 |
✓✗ | 2 |
mDefaultButton->addActionListener(this); |
110 |
|||
111 |
✓✗ | 2 |
mTabs->addActionListener(this); |
112 |
✓✗ | 10 |
mTabs->setActionEventId("tabs_"); |
113 |
2 |
int k = 0; |
|
114 |
✓✓ | 42 |
while (pages[k] != nullptr) |
115 |
{ |
||
116 |
✓✗✓✗ ✓✗ |
140 |
mTabs->addButton(gettext(pages[k]), pages[k], false); |
117 |
20 |
k ++; |
|
118 |
} |
||
119 |
|||
120 |
✓✗ | 2 |
fixTranslations(); |
121 |
|||
122 |
// Do the layout |
||
123 |
✓✗ | 4 |
LayoutHelper h(this); |
124 |
✓✗ | 2 |
ContainerPlacer place = h.getPlacer(0, 0); |
125 |
|||
126 |
✓✗ | 2 |
place(0, 0, mTabs, 5, 1); |
127 |
✓✗ | 4 |
place(0, 1, mScrollArea, 5, 5).setPadding(2); |
128 |
✓✗ | 2 |
place(0, 6, mResetKeysButton, 1, 1); |
129 |
✓✗ | 2 |
place(2, 6, mAssignKeyButton, 1, 1); |
130 |
✓✗ | 2 |
place(3, 6, mUnassignKeyButton, 1, 1); |
131 |
✓✗ | 2 |
place(4, 6, mDefaultButton, 1, 1); |
132 |
|||
133 |
2 |
int width = 600; |
|
134 |
✓✗✓✗ ✓✗ |
8 |
if (config.getIntValue("screenwidth") >= 730) |
135 |
2 |
width += 100; |
|
136 |
|||
137 |
✓✗ | 2 |
setDimension(Rect(0, 0, width, 350)); |
138 |
2 |
} |
|
139 |
|||
140 |
6 |
Setup_Input::~Setup_Input() |
|
141 |
{ |
||
142 |
✓✗ | 2 |
delete2(mKeyList) |
143 |
✓✗ | 4 |
delete2(mKeyListModel) |
144 |
✓✗ | 2 |
delete2(mAssignKeyButton) |
145 |
✓✗ | 2 |
delete2(mUnassignKeyButton) |
146 |
✓✗ | 2 |
delete2(mResetKeysButton) |
147 |
✓✗ | 2 |
delete [] mActionDataSize; |
148 |
2 |
mActionDataSize = nullptr; |
|
149 |
✓✗ | 2 |
delete2(mScrollArea) |
150 |
4 |
} |
|
151 |
|||
152 |
void Setup_Input::apply() |
||
153 |
{ |
||
154 |
keyUnresolved(); |
||
155 |
InputActionT key1; |
||
156 |
InputActionT key2; |
||
157 |
|||
158 |
if (inputManager.hasConflicts(key1, key2)) |
||
159 |
{ |
||
160 |
const std::string str1 = keyToString(key1); |
||
161 |
const std::string str2 = keyToString(key2); |
||
162 |
|||
163 |
CREATEWIDGET(OkDialog, |
||
164 |
// TRANSLATORS: input settings error header |
||
165 |
_("Key Conflict(s) Detected."), |
||
166 |
// TRANSLATORS: input settings error |
||
167 |
strprintf(_("Conflict \"%s\" and \"%s\" keys. " |
||
168 |
"Resolve them, or gameplay may result in strange behaviour."), |
||
169 |
gettext(str1.c_str()), gettext(str2.c_str())), |
||
170 |
// TRANSLATORS: ok dialog button |
||
171 |
_("OK"), |
||
172 |
DialogType::ERROR, |
||
173 |
Modal_true, |
||
174 |
ShowCenter_true, |
||
175 |
nullptr, |
||
176 |
260); |
||
177 |
} |
||
178 |
keyboard.setEnabled(true); |
||
179 |
inputManager.store(); |
||
180 |
} |
||
181 |
|||
182 |
void Setup_Input::cancel() |
||
183 |
{ |
||
184 |
keyUnresolved(); |
||
185 |
inputManager.retrieve(); |
||
186 |
keyboard.setEnabled(true); |
||
187 |
refreshKeys(); |
||
188 |
} |
||
189 |
|||
190 |
void Setup_Input::action(const ActionEvent &event) |
||
191 |
{ |
||
192 |
const std::string &id = event.getId(); |
||
193 |
const int selectedData = mKeyListModel->getSelectedData(); |
||
194 |
|||
195 |
if (event.getSource() == mKeyList) |
||
196 |
{ |
||
197 |
if (!mKeySetting) |
||
198 |
{ |
||
199 |
const int i(mKeyList->getSelected()); |
||
200 |
if (i >= 0 && i < mActionDataSize[selectedData]) |
||
201 |
{ |
||
202 |
if (setupActionData[selectedData][i].actionId |
||
203 |
== InputAction::NO_VALUE) |
||
204 |
{ |
||
205 |
mAssignKeyButton->setEnabled(false); |
||
206 |
mUnassignKeyButton->setEnabled(false); |
||
207 |
} |
||
208 |
else |
||
209 |
{ |
||
210 |
mAssignKeyButton->setEnabled(true); |
||
211 |
mUnassignKeyButton->setEnabled(true); |
||
212 |
} |
||
213 |
} |
||
214 |
} |
||
215 |
} |
||
216 |
else if (id == "assign") |
||
217 |
{ |
||
218 |
mKeySetting = true; |
||
219 |
mAssignKeyButton->setEnabled(false); |
||
220 |
keyboard.setEnabled(false); |
||
221 |
const int i(mKeyList->getSelected()); |
||
222 |
if (i >= 0 && i < mActionDataSize[selectedData]) |
||
223 |
{ |
||
224 |
const SetupActionData &key = setupActionData[selectedData][i]; |
||
225 |
const InputActionT ik = key.actionId; |
||
226 |
inputManager.setNewKeyIndex(ik); |
||
227 |
mKeyListModel->setElementAt(i, std::string( |
||
228 |
gettext(key.name.c_str())).append(": ?")); |
||
229 |
} |
||
230 |
} |
||
231 |
else if (id == "unassign") |
||
232 |
{ |
||
233 |
const int i(mKeyList->getSelected()); |
||
234 |
if (i >= 0 && i < mActionDataSize[selectedData]) |
||
235 |
{ |
||
236 |
const SetupActionData &key = setupActionData[selectedData][i]; |
||
237 |
const InputActionT ik = key.actionId; |
||
238 |
inputManager.setNewKeyIndex(ik); |
||
239 |
refreshAssignedKey(mKeyList->getSelected()); |
||
240 |
inputManager.unassignKey(); |
||
241 |
inputManager.setNewKeyIndex(InputAction::NO_VALUE); |
||
242 |
} |
||
243 |
mAssignKeyButton->setEnabled(true); |
||
244 |
} |
||
245 |
else if (id == "resetkeys") |
||
246 |
{ |
||
247 |
inputManager.resetKeys(); |
||
248 |
InputManager::update(); |
||
249 |
refreshKeys(); |
||
250 |
} |
||
251 |
else if (id == "default") |
||
252 |
{ |
||
253 |
const int i(mKeyList->getSelected()); |
||
254 |
if (i >= 0 && i < mActionDataSize[selectedData]) |
||
255 |
{ |
||
256 |
const SetupActionData &key = setupActionData[selectedData][i]; |
||
257 |
const InputActionT ik = key.actionId; |
||
258 |
inputManager.makeDefault(ik); |
||
259 |
refreshKeys(); |
||
260 |
} |
||
261 |
} |
||
262 |
else if (strStartWith(id, "tabs_")) |
||
263 |
{ |
||
264 |
int k = 0; |
||
265 |
std::string str("tabs_"); |
||
266 |
while (pages[k] != nullptr) |
||
267 |
{ |
||
268 |
if (str + pages[k] == id) |
||
269 |
break; |
||
270 |
k ++; |
||
271 |
} |
||
272 |
if ((pages[k] != nullptr) && str + pages[k] == id) |
||
273 |
{ |
||
274 |
mKeyListModel->setSelectedData(k); |
||
275 |
mKeyListModel->setSize(mActionDataSize[k]); |
||
276 |
refreshKeys(); |
||
277 |
mKeyList->setSelected(0); |
||
278 |
} |
||
279 |
} |
||
280 |
} |
||
281 |
|||
282 |
78 |
void Setup_Input::refreshAssignedKey(const int index) |
|
283 |
{ |
||
284 |
156 |
const int selectedData = mKeyListModel->getSelectedData(); |
|
285 |
78 |
const SetupActionData &key = setupActionData[selectedData][index]; |
|
286 |
✓✓ | 78 |
if (key.actionId == InputAction::NO_VALUE) |
287 |
{ |
||
288 |
const std::string str(" \342\200\225\342\200\225\342\200\225" |
||
289 |
16 |
"\342\200\225\342\200\225 "); |
|
290 |
4 |
mKeyListModel->setElementAt(index, |
|
291 |
✓✗✓✗ |
24 |
str + gettext(key.name.c_str()) + str); |
292 |
} |
||
293 |
else |
||
294 |
{ |
||
295 |
370 |
std::string str = gettext(key.name.c_str()); |
|
296 |
74 |
unsigned int sz = 20; |
|
297 |
✗✓ | 74 |
if (mainGraphics->mWidth > 800) |
298 |
sz = 30; |
||
299 |
✓✓ | 514 |
while (str.size() < sz) |
300 |
✓✗ | 440 |
str.append(" "); |
301 |
✓✗ | 222 |
mKeyListModel->setElementAt(index, strprintf("%s: %s", str.c_str(), |
302 |
✓✗ | 296 |
inputManager.getKeyStringLong(key.actionId).c_str())); |
303 |
} |
||
304 |
78 |
} |
|
305 |
|||
306 |
void Setup_Input::newKeyCallback(const InputActionT index) |
||
307 |
{ |
||
308 |
mKeySetting = false; |
||
309 |
const int i = keyToSetupData(index); |
||
310 |
if (i >= 0) |
||
311 |
refreshAssignedKey(i); |
||
312 |
mAssignKeyButton->setEnabled(true); |
||
313 |
} |
||
314 |
|||
315 |
int Setup_Input::keyToSetupData(const InputActionT index) const |
||
316 |
{ |
||
317 |
const int selectedData = mKeyListModel->getSelectedData(); |
||
318 |
for (int i = 0; i < mActionDataSize[selectedData]; i++) |
||
319 |
{ |
||
320 |
const SetupActionData &key = setupActionData[selectedData][i]; |
||
321 |
if (key.actionId == index) |
||
322 |
return i; |
||
323 |
} |
||
324 |
return -1; |
||
325 |
} |
||
326 |
|||
327 |
std::string Setup_Input::keyToString(const InputActionT index) const |
||
328 |
{ |
||
329 |
for (int f = 0; f < SETUP_PAGES; f ++) |
||
330 |
{ |
||
331 |
for (int i = 0; i < mActionDataSize[f]; i++) |
||
332 |
{ |
||
333 |
const SetupActionData &key = setupActionData[f][i]; |
||
334 |
if (key.actionId == index) |
||
335 |
return key.name; |
||
336 |
} |
||
337 |
} |
||
338 |
// TRANSLATORS: unknown key name |
||
339 |
return _("unknown"); |
||
340 |
} |
||
341 |
|||
342 |
2 |
void Setup_Input::refreshKeys() |
|
343 |
{ |
||
344 |
4 |
const int selectedData = mKeyListModel->getSelectedData(); |
|
345 |
✓✓ | 80 |
for (int i = 0; i < mActionDataSize[selectedData]; i++) |
346 |
78 |
refreshAssignedKey(i); |
|
347 |
2 |
} |
|
348 |
|||
349 |
void Setup_Input::keyUnresolved() |
||
350 |
{ |
||
351 |
if (mKeySetting) |
||
352 |
{ |
||
353 |
newKeyCallback(inputManager.getNewKeyIndex()); |
||
354 |
inputManager.setNewKeyIndex(InputAction::NO_VALUE); |
||
355 |
} |
||
356 |
} |
||
357 |
|||
358 |
10 |
void Setup_Input::fixTranslation(SetupActionData *const actionDatas, |
|
359 |
const InputActionT actionStart, |
||
360 |
const InputActionT actionEnd, |
||
361 |
const std::string &text) |
||
362 |
{ |
||
363 |
10 |
int k = 0; |
|
364 |
|||
365 |
✓✓ | 1232 |
while (!actionDatas[k].name.empty()) |
366 |
{ |
||
367 |
404 |
SetupActionData &data = actionDatas[k]; |
|
368 |
|||
369 |
404 |
const InputActionT actionId = data.actionId; |
|
370 |
✓✓✓✓ |
404 |
if (actionId >= actionStart && actionId <= actionEnd) |
371 |
{ |
||
372 |
1038 |
data.name = strprintf(gettext(text.c_str()), |
|
373 |
692 |
actionId - actionStart + 1); |
|
374 |
} |
||
375 |
404 |
k ++; |
|
376 |
} |
||
377 |
10 |
} |
|
378 |
|||
379 |
2 |
void Setup_Input::fixTranslations() |
|
380 |
{ |
||
381 |
8 |
fixTranslation(setupActionDataShortcuts, |
|
382 |
InputAction::SHORTCUT_1, |
||
383 |
InputAction::SHORTCUT_20, |
||
384 |
✓✗ | 2 |
"Item Shortcut %d"); |
385 |
|||
386 |
8 |
fixTranslation(setupActionDataEmotes, |
|
387 |
InputAction::EMOTE_1, |
||
388 |
InputAction::EMOTE_48, |
||
389 |
✓✗ | 2 |
"Emote Shortcut %d"); |
390 |
|||
391 |
8 |
fixTranslation(setupActionDataCraft, |
|
392 |
InputAction::CRAFT_1, |
||
393 |
InputAction::CRAFT_9, |
||
394 |
✓✗ | 2 |
"Craft shortcut %d"); |
395 |
|||
396 |
8 |
fixTranslation(setupActionDataOutfits, |
|
397 |
InputAction::OUTFIT_1, |
||
398 |
InputAction::OUTFIT_48, |
||
399 |
✓✗ | 2 |
"Outfit Shortcut %d"); |
400 |
|||
401 |
8 |
fixTranslation(setupActionDataMove, |
|
402 |
InputAction::MOVE_TO_POINT_1, |
||
403 |
InputAction::MOVE_TO_POINT_48, |
||
404 |
✓✗ | 2 |
"Move to point Shortcut %d"); |
405 |
✓✗✓✗ |
5 |
} |
Generated by: GCOVR (Version 3.3) |