ManaPlus
setup_input.cpp
Go to the documentation of this file.
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 
26 
27 #include "configuration.h"
28 
29 #include "const/gui/pages.h"
30 
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"
50 #include "gui/widgets/listbox.h"
51 #include "gui/widgets/scrollarea.h"
52 #include "gui/widgets/tabstrip.h"
53 
55 
56 #include "utils/delete2.h"
57 #include "utils/gettext.h"
58 
59 #include "debug.h"
60 
61 Setup_Input::Setup_Input(const Widget2 *const widget) :
62  SetupTab(widget),
63  mKeyListModel(new KeyListModel),
64  mKeyList(CREATEWIDGETR(ListBox, this, mKeyListModel, "")),
65  // TRANSLATORS: button in input settings tab
66  mAssignKeyButton(new Button(this, _("Assign"), "assign",
67  BUTTON_SKIN, this)),
68  // TRANSLATORS: button in input settings tab
69  mUnassignKeyButton(new Button(this, _("Unassign"), "unassign",
70  BUTTON_SKIN, this)),
71  // TRANSLATORS: button in input settings tab
72  mDefaultButton(new Button(this, _("Default"), "default",
73  BUTTON_SKIN, this)),
74  // TRANSLATORS: button in input settings tab
75  mResetKeysButton(new Button(this, _("Reset all keys"), "resetkeys",
76  BUTTON_SKIN, this)),
77  mTabs(new TabStrip(this, config.getIntValue("fontSize") + 10, 0)),
78  mScrollArea(new ScrollArea(this, mKeyList,
79  Opaque_true, "setup_input_background.xml")),
80  mKeySetting(false),
81  mActionDataSize(new int [SETUP_PAGES])
82 {
84  // TRANSLATORS: setting tab name
85  setName(_("Input"));
86 
88 
89  for (int f = 0; f < SETUP_PAGES; f ++)
90  {
91  int cnt = 0;
92  while (!setupActionData[f][cnt].name.empty())
93  cnt ++;
94  mActionDataSize[f] = cnt;
95  }
96 
98  refreshKeys();
99  if (gui != nullptr)
102 
110 
111  mTabs->addActionListener(this);
112  mTabs->setActionEventId("tabs_");
113  int k = 0;
114  while (pages[k] != nullptr)
115  {
116  mTabs->addButton(gettext(pages[k]), pages[k], false);
117  k ++;
118  }
119 
120  fixTranslations();
121 
122  // Do the layout
123  LayoutHelper h(this);
124  ContainerPlacer place = h.getPlacer(0, 0);
125 
126  place(0, 0, mTabs, 5, 1);
127  place(0, 1, mScrollArea, 5, 5).setPadding(2);
128  place(0, 6, mResetKeysButton, 1, 1);
129  place(2, 6, mAssignKeyButton, 1, 1);
130  place(3, 6, mUnassignKeyButton, 1, 1);
131  place(4, 6, mDefaultButton, 1, 1);
132 
133  int width = 600;
134  if (config.getIntValue("screenwidth") >= 730)
135  width += 100;
136 
137  setDimension(Rect(0, 0, width, 350));
138 }
139 
141 {
147  delete [] mActionDataSize;
148  mActionDataSize = nullptr;
150 }
151 
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 
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"),
173  Modal_true,
175  nullptr,
176  260);
177  }
178  keyboard.setEnabled(true);
180 }
181 
183 {
184  keyUnresolved();
186  keyboard.setEnabled(true);
187  refreshKeys();
188 }
189 
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
204  {
207  }
208  else
209  {
212  }
213  }
214  }
215  }
216  else if (id == "assign")
217  {
218  mKeySetting = true;
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;
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;
242  }
244  }
245  else if (id == "resetkeys")
246  {
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;
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  {
276  refreshKeys();
277  mKeyList->setSelected(0);
278  }
279  }
280 }
281 
282 void Setup_Input::refreshAssignedKey(const int index)
283 {
284  const int selectedData = mKeyListModel->getSelectedData();
285  const SetupActionData &key = setupActionData[selectedData][index];
286  if (key.actionId == InputAction::NO_VALUE)
287  {
288  const std::string str(" \342\200\225\342\200\225\342\200\225"
289  "\342\200\225\342\200\225 ");
291  str + gettext(key.name.c_str()) + str);
292  }
293  else
294  {
295  std::string str = gettext(key.name.c_str());
296  unsigned int sz = 20;
297  if (mainGraphics->mWidth > 800)
298  sz = 30;
299  while (str.size() < sz)
300  str.append(" ");
301  mKeyListModel->setElementAt(index, strprintf("%s: %s", str.c_str(),
302  inputManager.getKeyStringLong(key.actionId).c_str()));
303  }
304 }
305 
307 {
308  mKeySetting = false;
309  const int i = keyToSetupData(index);
310  if (i >= 0)
313 }
314 
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 
343 {
344  const int selectedData = mKeyListModel->getSelectedData();
345  for (int i = 0; i < mActionDataSize[selectedData]; i++)
347 }
348 
350 {
351  if (mKeySetting)
352  {
355  }
356 }
357 
359  const InputActionT actionStart,
360  const InputActionT actionEnd,
361  const std::string &text)
362 {
363  int k = 0;
364 
365  while (!actionDatas[k].name.empty())
366  {
367  SetupActionData &data = actionDatas[k];
368 
369  const InputActionT actionId = data.actionId;
370  if (actionId >= actionStart && actionId <= actionEnd)
371  {
372  data.name = strprintf(gettext(text.c_str()),
373  actionId - actionStart + 1);
374  }
375  k ++;
376  }
377 }
378 
380 {
384  "Item Shortcut %d");
385 
389  "Emote Shortcut %d");
390 
394  "Craft shortcut %d");
395 
399  "Outfit Shortcut %d");
400 
404  "Move to point Shortcut %d");
405 }
const std::string BUTTON_SKIN
Definition: button.h:89
Definition: button.h:102
int getIntValue(const std::string &key) const
Widget * getSource() const
Definition: event.h:104
int mWidth
Definition: graphics.h:484
Font * getHelpFont() const
Definition: gui.h:166
static void update()
void store() const
void setSetupInput(Setup_Input *const setupInput)
Definition: inputmanager.h:110
void unassignKey()
InputActionT getNewKeyIndex() const
Definition: inputmanager.h:117
std::string getKeyStringLong(const InputActionT index) const
bool hasConflicts(InputActionT &key1, InputActionT &key2) const
void makeDefault(const InputActionT i)
void setNewKeyIndex(const InputActionT value)
Definition: inputmanager.h:104
void setSize(const int size)
Definition: keylistmodel.h:71
int getSelectedData() const
Definition: keylistmodel.h:80
void setElementAt(const int i, const std::string &caption)
Definition: keylistmodel.h:68
void setSelectedData(const int i)
Definition: keylistmodel.h:77
void setEnabled(const bool flag)
ContainerPlacer getPlacer(const int x, const int y)
int getSelected() const
Definition: listbox.h:168
void setSelected(const int selected)
Definition: listbox.cpp:399
Definition: rect.h:74
void setHorizontalScrollPolicy(const ScrollPolicy hPolicy)
void setName(const std::string &name)
Definition: setuptab.h:68
Button * mUnassignKeyButton
Definition: setup_input.h:97
Button * mResetKeysButton
Definition: setup_input.h:99
TabStrip * mTabs
Definition: setup_input.h:100
void action(const ActionEvent &event)
std::string keyToString(const InputActionT index) const
void refreshKeys()
int keyToSetupData(const InputActionT index) const
ScrollArea * mScrollArea
Definition: setup_input.h:101
static void fixTranslation(SetupActionData *const actionDatas, const InputActionT actionStart, const InputActionT actionEnd, const std::string &text)
static void fixTranslations()
ListBox * mKeyList
Definition: setup_input.h:94
bool mKeySetting
Definition: setup_input.h:102
void newKeyCallback(const InputActionT index)
Button * mAssignKeyButton
Definition: setup_input.h:96
KeyListModel * mKeyListModel
Definition: setup_input.h:93
int * mActionDataSize
Definition: setup_input.h:103
Button * mDefaultButton
Definition: setup_input.h:98
void keyUnresolved()
Setup_Input(const Widget2 *const widget)
Definition: setup_input.cpp:61
void refreshAssignedKey(const int index)
virtual void addButton(const std::string &text, const std::string &tag, const bool pressed)
Definition: widgetgroup.cpp:42
void setEnabled(const bool enabled)
Definition: widget.h:352
void setFont(Font *const font)
Definition: widget.cpp:349
void setActionEventId(const std::string &actionEventId)
Definition: widget.h:596
void setDimension(const Rect &dimension)
Definition: widget.cpp:169
void addActionListener(ActionListener *const actionListener)
Definition: widget.cpp:252
Configuration config
SetupActionData setupActionDataCraft[]
Definition: craft.cpp:29
#define CREATEWIDGET(type,...)
Definition: createwidget.h:29
#define CREATEWIDGETR(type,...)
Definition: createwidget.h:36
#define new
Definition: debug_new.h:147
#define delete2(var)
Definition: delete2.h:25
SetupActionData setupActionDataEmotes[]
Definition: emotes.cpp:32
#define _(s)
Definition: gettext.h:35
Graphics * mainGraphics
Definition: graphics.cpp:109
Gui * gui
Definition: gui.cpp:111
SetupActionData setupActionDataMove[]
Definition: move.cpp:32
InputAction ::T InputActionT
Definition: inputaction.h:717
InputManager inputManager
KeyboardConfig keyboard
SetupActionData *const setupActionData[]
uint32_t data
const bool Modal_true
Definition: modal.h:30
const bool Opaque_true
Definition: opaque.h:30
SetupActionData setupActionDataOutfits[]
Definition: outfits.cpp:32
const int SETUP_PAGES
Definition: pages.h:29
const char *const pages[SETUP_PAGES+1]
SetupActionData setupActionDataShortcuts[]
Definition: shortcuts.cpp:32
const bool ShowCenter_true
Definition: showcenter.h:30
std::string strprintf(const char *const format,...)
bool strStartWith(const std::string &str1, const std::string &str2)
std::string name
const InputActionT actionId