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-2018 The ManaPlus Developers
7  *
8  * This file is part of The ManaPlus Client.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
25 
26 #include "configuration.h"
27 
28 #include "const/gui/pages.h"
29 
31 #include "input/inputmanager.h"
32 #include "input/keyboardconfig.h"
33 
34 #include "input/pages/craft.h"
35 #include "input/pages/emotes.h"
36 #include "input/pages/move.h"
37 #include "input/pages/outfits.h"
38 #include "input/pages/shortcuts.h"
39 
40 #include "gui/gui.h"
41 #include "gui/setupinputpages.h"
42 
43 #include "gui/windows/okdialog.h"
44 
45 #include "gui/widgets/button.h"
49 #include "gui/widgets/listbox.h"
50 #include "gui/widgets/scrollarea.h"
51 #include "gui/widgets/tabstrip.h"
52 
54 
55 #include "utils/delete2.h"
56 #include "utils/gettext.h"
57 
58 #include "debug.h"
59 
60 Setup_Input::Setup_Input(const Widget2 *const widget) :
61  SetupTab(widget),
62  mKeyListModel(new KeyListModel),
63  mKeyList(CREATEWIDGETR(ListBox, this, mKeyListModel, "")),
64  // TRANSLATORS: button in input settings tab
65  mAssignKeyButton(new Button(this, _("Assign"), "assign",
66  BUTTON_SKIN, this)),
67  // TRANSLATORS: button in input settings tab
68  mUnassignKeyButton(new Button(this, _("Unassign"), "unassign",
69  BUTTON_SKIN, this)),
70  // TRANSLATORS: button in input settings tab
71  mDefaultButton(new Button(this, _("Default"), "default",
72  BUTTON_SKIN, this)),
73  // TRANSLATORS: button in input settings tab
74  mResetKeysButton(new Button(this, _("Reset all keys"), "resetkeys",
75  BUTTON_SKIN, this)),
76  mTabs(new TabStrip(this, config.getIntValue("fontSize") + 10, 0)),
77  mScrollArea(new ScrollArea(this, mKeyList,
78  Opaque_true, "setup_input_background.xml")),
79  mKeySetting(false),
80  mActionDataSize(new int [SETUP_PAGES])
81 {
83  // TRANSLATORS: setting tab name
84  setName(_("Input"));
85 
87 
88  for (int f = 0; f < SETUP_PAGES; f ++)
89  {
90  int cnt = 0;
91  while (!setupActionData[f][cnt].name.empty())
92  cnt ++;
93  mActionDataSize[f] = cnt;
94  }
95 
97  refreshKeys();
98  if (gui != nullptr)
101 
109 
110  mTabs->addActionListener(this);
111  mTabs->setActionEventId("tabs_");
112  int k = 0;
113  while (pages[k] != nullptr)
114  {
115  mTabs->addButton(gettext(pages[k]), pages[k], false);
116  k ++;
117  }
118 
119  fixTranslations();
120 
121  // Do the layout
122  LayoutHelper h(this);
123  ContainerPlacer place = h.getPlacer(0, 0);
124 
125  place(0, 0, mTabs, 5, 1);
126  place(0, 1, mScrollArea, 5, 5).setPadding(2);
127  place(0, 6, mResetKeysButton, 1, 1);
128  place(2, 6, mAssignKeyButton, 1, 1);
129  place(3, 6, mUnassignKeyButton, 1, 1);
130  place(4, 6, mDefaultButton, 1, 1);
131 
132  int width = 600;
133  if (config.getIntValue("screenwidth") >= 730)
134  width += 100;
135 
136  setDimension(Rect(0, 0, width, 350));
137 }
138 
140 {
141  delete2(mKeyList);
146  delete [] mActionDataSize;
147  mActionDataSize = nullptr;
149 }
150 
152 {
153  keyUnresolved();
154  InputActionT key1;
155  InputActionT key2;
156 
157  if (inputManager.hasConflicts(key1, key2))
158  {
159  const std::string str1 = keyToString(key1);
160  const std::string str2 = keyToString(key2);
161 
163  // TRANSLATORS: input settings error header
164  _("Key Conflict(s) Detected."),
165  // TRANSLATORS: input settings error
166  strprintf(_("Conflict \"%s\" and \"%s\" keys. "
167  "Resolve them, or gameplay may result in strange behaviour."),
168  gettext(str1.c_str()), gettext(str2.c_str())),
169  // TRANSLATORS: ok dialog button
170  _("OK"),
172  Modal_true,
174  nullptr,
175  260);
176  }
177  keyboard.setEnabled(true);
179 }
180 
182 {
183  keyUnresolved();
185  keyboard.setEnabled(true);
186  refreshKeys();
187 }
188 
190 {
191  const std::string &id = event.getId();
192  const int selectedData = mKeyListModel->getSelectedData();
193 
194  if (event.getSource() == mKeyList)
195  {
196  if (!mKeySetting)
197  {
198  const int i(mKeyList->getSelected());
199  if (i >= 0 && i < mActionDataSize[selectedData])
200  {
201  if (setupActionData[selectedData][i].actionId
203  {
206  }
207  else
208  {
211  }
212  }
213  }
214  }
215  else if (id == "assign")
216  {
217  mKeySetting = true;
219  keyboard.setEnabled(false);
220  const int i(mKeyList->getSelected());
221  if (i >= 0 && i < mActionDataSize[selectedData])
222  {
223  const SetupActionData &key = setupActionData[selectedData][i];
224  const InputActionT ik = key.actionId;
226  mKeyListModel->setElementAt(i, std::string(
227  gettext(key.name.c_str())).append(": ?"));
228  }
229  }
230  else if (id == "unassign")
231  {
232  const int i(mKeyList->getSelected());
233  if (i >= 0 && i < mActionDataSize[selectedData])
234  {
235  const SetupActionData &key = setupActionData[selectedData][i];
236  const InputActionT ik = key.actionId;
241  }
243  }
244  else if (id == "resetkeys")
245  {
248  refreshKeys();
249  }
250  else if (id == "default")
251  {
252  const int i(mKeyList->getSelected());
253  if (i >= 0 && i < mActionDataSize[selectedData])
254  {
255  const SetupActionData &key = setupActionData[selectedData][i];
256  const InputActionT ik = key.actionId;
258  refreshKeys();
259  }
260  }
261  else if (strStartWith(id, "tabs_"))
262  {
263  int k = 0;
264  std::string str("tabs_");
265  while (pages[k] != nullptr)
266  {
267  if (str + pages[k] == id)
268  break;
269  k ++;
270  }
271  if ((pages[k] != nullptr) && str + pages[k] == id)
272  {
275  refreshKeys();
276  mKeyList->setSelected(0);
277  }
278  }
279 }
280 
281 void Setup_Input::refreshAssignedKey(const int index)
282 {
283  const int selectedData = mKeyListModel->getSelectedData();
284  const SetupActionData &key = setupActionData[selectedData][index];
285  if (key.actionId == InputAction::NO_VALUE)
286  {
287  const std::string str(" \342\200\225\342\200\225\342\200\225"
288  "\342\200\225\342\200\225 ");
290  str + gettext(key.name.c_str()) + str);
291  }
292  else
293  {
294  std::string str = gettext(key.name.c_str());
295  unsigned int sz = 20;
296  if (mainGraphics->mWidth > 800)
297  sz = 30;
298  while (str.size() < sz)
299  str.append(" ");
300  mKeyListModel->setElementAt(index, strprintf("%s: %s", str.c_str(),
301  inputManager.getKeyStringLong(key.actionId).c_str()));
302  }
303 }
304 
306 {
307  mKeySetting = false;
308  const int i = keyToSetupData(index);
309  if (i >= 0)
312 }
313 
315 {
316  const int selectedData = mKeyListModel->getSelectedData();
317  for (int i = 0; i < mActionDataSize[selectedData]; i++)
318  {
319  const SetupActionData &key = setupActionData[selectedData][i];
320  if (key.actionId == index)
321  return i;
322  }
323  return -1;
324 }
325 
326 std::string Setup_Input::keyToString(const InputActionT index) const
327 {
328  for (int f = 0; f < SETUP_PAGES; f ++)
329  {
330  for (int i = 0; i < mActionDataSize[f]; i++)
331  {
332  const SetupActionData &key = setupActionData[f][i];
333  if (key.actionId == index)
334  return key.name;
335  }
336  }
337  // TRANSLATORS: unknown key name
338  return _("unknown");
339 }
340 
342 {
343  const int selectedData = mKeyListModel->getSelectedData();
344  for (int i = 0; i < mActionDataSize[selectedData]; i++)
346 }
347 
349 {
350  if (mKeySetting)
351  {
354  }
355 }
356 
358  const InputActionT actionStart,
359  const InputActionT actionEnd,
360  const std::string &text)
361 {
362  int k = 0;
363 
364  while (!actionDatas[k].name.empty())
365  {
366  SetupActionData &data = actionDatas[k];
367 
368  const InputActionT actionId = data.actionId;
369  if (actionId >= actionStart && actionId <= actionEnd)
370  {
371  data.name = strprintf(gettext(text.c_str()),
372  actionId - actionStart + 1);
373  }
374  k ++;
375  }
376 }
377 
379 {
383  "Item Shortcut %d");
384 
388  "Emote Shortcut %d");
389 
393  "Craft shortcut %d");
394 
398  "Outfit Shortcut %d");
399 
403  "Move to point Shortcut %d");
404 }
bool strStartWith(const std::string &str1, const std::string &str2)
#define _(s)
Definition: gettext.h:34
void action(const ActionEvent &event)
ListBox * mKeyList
Definition: setup_input.h:93
void setSelected(const int selected)
Definition: listbox.cpp:398
Font * getHelpFont() const
Definition: gui.h:165
SetupActionData setupActionDataShortcuts[]
Definition: shortcuts.cpp:31
void unassignKey()
static void fixTranslation(SetupActionData *const actionDatas, const InputActionT actionStart, const InputActionT actionEnd, const std::string &text)
Gui * gui
Definition: gui.cpp:110
int getSelectedData() const
Definition: keylistmodel.h:79
void refreshAssignedKey(const int index)
SetupActionData setupActionDataEmotes[]
Definition: emotes.cpp:31
virtual void addButton(const std::string &text, const std::string &tag, const bool pressed)
Definition: widgetgroup.cpp:41
void setNewKeyIndex(const InputActionT value)
Definition: inputmanager.h:103
void setSelectedData(const int i)
Definition: keylistmodel.h:76
Setup_Input(const Widget2 *const widget)
Definition: setup_input.cpp:60
void addActionListener(ActionListener *const actionListener)
Definition: widget.cpp:251
static void fixTranslations()
Button * mAssignKeyButton
Definition: setup_input.h:95
int * mActionDataSize
Definition: setup_input.h:102
Definition: rect.h:72
void setSetupInput(Setup_Input *const setupInput)
Definition: inputmanager.h:109
int mWidth
Definition: graphics.h:483
Definition: button.h:96
Configuration config
SetupActionData *const setupActionData[]
KeyListModel * mKeyListModel
Definition: setup_input.h:92
void setDimension(const Rect &dimension)
Definition: widget.cpp:168
void setElementAt(const int i, const std::string &caption)
Definition: keylistmodel.h:67
std::string getKeyStringLong(const InputActionT index) const
SetupActionData setupActionDataMove[]
Definition: move.cpp:31
int getIntValue(const std::string &key) const
const int SETUP_PAGES
Definition: pages.h:28
void setActionEventId(const std::string &actionEventId)
Definition: widget.h:595
std::string name
#define delete2(var)
Definition: delete2.h:24
void newKeyCallback(const InputActionT index)
void setSize(const int size)
Definition: keylistmodel.h:70
bool mKeySetting
Definition: setup_input.h:101
#define new
Definition: debug_new.h:147
void refreshKeys()
const std::string BUTTON_SKIN
Definition: button.h:88
std::string strprintf(const char *const format,...)
Definition: stringutils.cpp:99
const InputActionT actionId
uint32_t data
Widget * getSource() const
Definition: event.h:103
Button * mUnassignKeyButton
Definition: setup_input.h:96
Button * mResetKeysButton
Definition: setup_input.h:98
int getSelected() const
Definition: listbox.h:167
InputAction ::T InputActionT
Definition: inputaction.h:715
static void update()
Graphics * mainGraphics
Definition: graphics.cpp:108
const bool ShowCenter_true
Definition: showcenter.h:29
void store() const
ScrollArea * mScrollArea
Definition: setup_input.h:100
ContainerPlacer getPlacer(const int x, const int y)
void setEnabled(const bool enabled)
Definition: widget.h:351
InputActionT getNewKeyIndex() const
Definition: inputmanager.h:116
SetupActionData setupActionDataOutfits[]
Definition: outfits.cpp:31
#define CREATEWIDGET(type,...)
Definition: createwidget.h:28
void setFont(Font *const font)
Definition: widget.cpp:348
Button * mDefaultButton
Definition: setup_input.h:97
void setName(const std::string &name)
Definition: setuptab.h:67
const bool Opaque_true
Definition: opaque.h:29
void makeDefault(const InputActionT i)
const char *const pages[SETUP_PAGES+1]
SetupActionData setupActionDataCraft[]
Definition: craft.cpp:28
KeyboardConfig keyboard
TabStrip * mTabs
Definition: setup_input.h:99
int keyToSetupData(const InputActionT index) const
InputManager inputManager
#define CREATEWIDGETR(type,...)
Definition: createwidget.h:35
void keyUnresolved()
bool hasConflicts(InputActionT &key1, InputActionT &key2) const
void setEnabled(const bool flag)
std::string keyToString(const InputActionT index) const
void setHorizontalScrollPolicy(const ScrollPolicy hPolicy)