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, key2;
155 
156  if (inputManager.hasConflicts(key1, key2))
157  {
158  const std::string str1 = keyToString(key1);
159  const std::string str2 = keyToString(key2);
160 
162  // TRANSLATORS: input settings error header
163  _("Key Conflict(s) Detected."),
164  // TRANSLATORS: input settings error
165  strprintf(_("Conflict \"%s\" and \"%s\" keys. "
166  "Resolve them, or gameplay may result in strange behaviour."),
167  gettext(str1.c_str()), gettext(str2.c_str())),
168  // TRANSLATORS: ok dialog button
169  _("OK"),
171  Modal_true,
173  nullptr,
174  260);
175  }
176  keyboard.setEnabled(true);
178 }
179 
181 {
182  keyUnresolved();
184  keyboard.setEnabled(true);
185  refreshKeys();
186 }
187 
189 {
190  const std::string &id = event.getId();
191  const int selectedData = mKeyListModel->getSelectedData();
192 
193  if (event.getSource() == mKeyList)
194  {
195  if (!mKeySetting)
196  {
197  const int i(mKeyList->getSelected());
198  if (i >= 0 && i < mActionDataSize[selectedData])
199  {
200  if (setupActionData[selectedData][i].actionId
202  {
205  }
206  else
207  {
210  }
211  }
212  }
213  }
214  else if (id == "assign")
215  {
216  mKeySetting = true;
218  keyboard.setEnabled(false);
219  const int i(mKeyList->getSelected());
220  if (i >= 0 && i < mActionDataSize[selectedData])
221  {
222  const SetupActionData &key = setupActionData[selectedData][i];
223  const InputActionT ik = key.actionId;
225  mKeyListModel->setElementAt(i, std::string(
226  gettext(key.name.c_str())).append(": ?"));
227  }
228  }
229  else if (id == "unassign")
230  {
231  const int i(mKeyList->getSelected());
232  if (i >= 0 && i < mActionDataSize[selectedData])
233  {
234  const SetupActionData &key = setupActionData[selectedData][i];
235  const InputActionT ik = key.actionId;
240  }
242  }
243  else if (id == "resetkeys")
244  {
247  refreshKeys();
248  }
249  else if (id == "default")
250  {
251  const int i(mKeyList->getSelected());
252  if (i >= 0 && i < mActionDataSize[selectedData])
253  {
254  const SetupActionData &key = setupActionData[selectedData][i];
255  const InputActionT ik = key.actionId;
257  refreshKeys();
258  }
259  }
260  else if (strStartWith(id, "tabs_"))
261  {
262  int k = 0;
263  std::string str("tabs_");
264  while (pages[k] != nullptr)
265  {
266  if (str + pages[k] == id)
267  break;
268  k ++;
269  }
270  if ((pages[k] != nullptr) && str + pages[k] == id)
271  {
274  refreshKeys();
275  mKeyList->setSelected(0);
276  }
277  }
278 }
279 
280 void Setup_Input::refreshAssignedKey(const int index)
281 {
282  const int selectedData = mKeyListModel->getSelectedData();
283  const SetupActionData &key = setupActionData[selectedData][index];
284  if (key.actionId == InputAction::NO_VALUE)
285  {
286  const std::string str(" \342\200\225\342\200\225\342\200\225"
287  "\342\200\225\342\200\225 ");
289  str + gettext(key.name.c_str()) + str);
290  }
291  else
292  {
293  std::string str = gettext(key.name.c_str());
294  unsigned int sz = 20;
295  if (mainGraphics->mWidth > 800)
296  sz = 30;
297  while (str.size() < sz)
298  str.append(" ");
299  mKeyListModel->setElementAt(index, strprintf("%s: %s", str.c_str(),
300  inputManager.getKeyStringLong(key.actionId).c_str()));
301  }
302 }
303 
305 {
306  mKeySetting = false;
307  const int i = keyToSetupData(index);
308  if (i >= 0)
311 }
312 
314 {
315  const int selectedData = mKeyListModel->getSelectedData();
316  for (int i = 0; i < mActionDataSize[selectedData]; i++)
317  {
318  const SetupActionData &key = setupActionData[selectedData][i];
319  if (key.actionId == index)
320  return i;
321  }
322  return -1;
323 }
324 
325 std::string Setup_Input::keyToString(const InputActionT index) const
326 {
327  for (int f = 0; f < SETUP_PAGES; f ++)
328  {
329  for (int i = 0; i < mActionDataSize[f]; i++)
330  {
331  const SetupActionData &key = setupActionData[f][i];
332  if (key.actionId == index)
333  return key.name;
334  }
335  }
336  // TRANSLATORS: unknown key name
337  return _("unknown");
338 }
339 
341 {
342  const int selectedData = mKeyListModel->getSelectedData();
343  for (int i = 0; i < mActionDataSize[selectedData]; i++)
345 }
346 
348 {
349  if (mKeySetting)
350  {
353  }
354 }
355 
357  const InputActionT actionStart,
358  const InputActionT actionEnd,
359  const std::string &text)
360 {
361  int k = 0;
362 
363  while (!actionDatas[k].name.empty())
364  {
365  SetupActionData &data = actionDatas[k];
366 
367  const InputActionT actionId = data.actionId;
368  if (actionId >= actionStart && actionId <= actionEnd)
369  {
370  data.name = strprintf(gettext(text.c_str()),
371  actionId - actionStart + 1);
372  }
373  k ++;
374  }
375 }
376 
378 {
382  "Item Shortcut %d");
383 
387  "Emote Shortcut %d");
388 
392  "Craft shortcut %d");
393 
397  "Outfit Shortcut %d");
398 
402  "Move to point Shortcut %d");
403 }
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)