ManaPlus
pincode.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2011-2019 The ManaPlus Developers
4  * Copyright (C) 2019-2021 Andrei Karas
5  *
6  * This file is part of The ManaPlus Client.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include "gui/widgets/pincode.h"
23 
24 #include "gui/gui.h"
25 #include "gui/skin.h"
26 
27 #include "gui/widgets/button.h"
28 #include "gui/widgets/textfield.h"
29 
30 #include "utils/gettext.h"
31 #include "utils/stringutils.h"
32 
33 #include "debug.h"
34 
35 Skin *Pincode::mSkin = nullptr;
36 int Pincode::mInstances = 0;
37 
38 Pincode::Pincode(const Widget2 *const widget,
39  TextField *const textField) :
40  Container(widget),
43  mButtons(),
44  mText(),
45  mTextField(textField),
46  mPadding(0),
47  mSpacing(2),
48  mButtonWidth(0),
49  mButtonHeight(0)
50 {
51  mAllowLogic = false;
53 
54  if (mInstances == 0)
55  {
56  if (theme != nullptr)
57  {
58  mSkin = theme->load("pin.xml",
59  "",
60  true,
62  }
63  }
64  mInstances ++;
65 
66  if (mSkin != nullptr)
67  {
69  mSpacing = mSkin->getOption("spacing", 2);
70  }
71  setSelectable(false);
72 
73  addButtons();
74  adjustSize();
75 }
76 
78 {
79  if (mWindow != nullptr)
81 
82  if (gui != nullptr)
83  gui->removeDragged(this);
84 
85  mInstances --;
86  if (mInstances == 0)
87  {
88  if (theme != nullptr)
89  theme->unload(mSkin);
90  }
91 }
92 
94 {
95  int buttonWidth = 0;
96  int buttonHeight = 0;
97  for (int f = 0; f < 10; f ++)
98  {
99  const std::string str = toString(f);
100  mButtons[f] = new Button(this,
101  str,
102  str,
104  this);
105  mButtons[f]->adjustSize();
106  const Rect &rect = mButtons[f]->getDimension();
107  if (rect.width > buttonWidth)
108  buttonWidth = rect.width;
109  if (rect.height > buttonHeight)
110  buttonHeight = rect.height;
111  add(mButtons[f]);
112  }
113  int x = 0;
114  int y = 0;
115  const int xSize = buttonWidth + mSpacing;
116  const int ySize = buttonHeight + mSpacing;
117  for (int f = 0; f < 10; f ++)
118  {
119  mButtons[f]->setPosition(mPadding + x * xSize,
120  mPadding + y * ySize);
121  x ++;
122  if (x > 2)
123  {
124  x = 0;
125  y ++;
126  }
127  }
128  mButtons[10] = new Button(this,
129  // TRANSLATORS: clear pin code button
130  _("Clear"),
131  "clear",
133  this);
134  mButtons[10]->adjustSize();
135  add(mButtons[10]);
136  mButtons[10]->setPosition(mPadding + xSize,
137  mPadding + 3 * ySize);
138 
140  mButtonHeight = buttonHeight;
141 }
142 
144 {
145  const int pad2 = mPadding * 2;
146  setSize(pad2 + 3 * mButtonWidth + 2 * mSpacing,
147  pad2 + 4 * mButtonHeight + 3 * mSpacing);
148 }
149 
151 {
152  mSkin = nullptr;
153 }
154 
155 void Pincode::action(const ActionEvent &event)
156 {
157  if (event.getId() == "clear")
158  {
159  mText.clear();
162  return;
163  }
164  if (mText.size() >= 4)
165  return;
166  const Widget *const eventSrc = event.getSource();
167  for (int f = 0; f < 10; f ++)
168  {
169  if (mButtons[f] == eventSrc)
170  {
171  const std::string str = toString(f);
172  mText.append(str);
175  return;
176  }
177  }
178 }
179 
180 void Pincode::shuffle(uint32_t seed) const
181 {
182  int tab[10];
183  const uint32_t multiplier = 0x3498;
184  const uint32_t baseSeed = 0x881234;
185  int k = 2;
186 
187  for (size_t f = 0; f < 10; f ++)
188  tab[f] = CAST_S32(f);
189  for (size_t f = 1; f < 10; f ++)
190  {
191  seed = baseSeed + seed * multiplier;
192  const size_t pos = seed % k;
193  if (f != pos)
194  {
195  const int tmp = tab[f];
196  tab[f] = tab[pos];
197  tab[pos] = tmp;
198  }
199  k = k + 1;
200  }
201  for (size_t f = 0; f < 10; f ++)
202  {
203  const std::string str = toString(tab[f]);
204  mButtons[f]->setCaption(str);
205  }
206 }
const std::string BUTTON_PIN_SKIN
Definition: button.h:90
#define CAST_S32
Definition: cast.h:30
const std::string & getId() const
Definition: actionevent.h:122
virtual void add(Widget *const widget)
void setOpaque(Opaque opaque)
Definition: button.h:102
void setCaption(const std::string &caption)
Definition: button.h:214
void adjustSize()
Definition: button.cpp:799
void removeDragged(const Widget *const widget)
Definition: gui.cpp:1162
int mSpacing
Definition: pincode.h:68
void shuffle(uint32_t seed) const
Definition: pincode.cpp:180
void action(const ActionEvent &event)
Definition: pincode.cpp:155
int mButtonWidth
Definition: pincode.h:69
static void finalCleanup()
Definition: pincode.cpp:150
Pincode(const Widget2 *const widget, TextField *const textField)
Definition: pincode.cpp:38
void addButtons()
Definition: pincode.cpp:93
int mButtonHeight
Definition: pincode.h:70
~Pincode()
Definition: pincode.cpp:77
int mPadding
Definition: pincode.h:67
static Skin * mSkin
Definition: pincode.h:54
std::string mText
Definition: pincode.h:65
void adjustSize()
Definition: pincode.cpp:143
Button * mButtons[11]
Definition: pincode.h:64
static int mInstances
Definition: pincode.h:56
TextField * mTextField
Definition: pincode.h:66
Definition: rect.h:74
int width
Definition: rect.h:219
int height
Definition: rect.h:224
Definition: skin.h:37
int getOption(const std::string &name) const
Definition: skin.h:106
int getPadding() const
Definition: skin.h:100
void setText(const std::string &text)
Definition: textfield.cpp:803
void signalEvent()
Definition: textfield.cpp:843
void unload(Skin *const skin)
Definition: theme.cpp:250
static std::string getThemePath()
Definition: theme.h:67
Skin * load(const std::string &filename, const std::string &filename2, const bool full, const std::string &defaultPath)
Definition: theme.cpp:179
Widget * mWindow
Definition: widget2.h:112
Definition: widget.h:99
void setSize(const int width, const int height)
Definition: widget.cpp:367
const Rect & getDimension() const
Definition: widget.h:317
bool mAllowLogic
Definition: widget.h:1160
void removeWidgetListener(WidgetListener *const widgetListener)
Definition: widget.cpp:307
void setSelectable(const bool selectable)
Definition: widget.h:948
void setPosition(const int x, const int y)
Definition: widget.cpp:161
#define _(s)
Definition: gettext.h:35
Gui * gui
Definition: gui.cpp:111
std::string toString(T const &value)
converts any type to a string
Definition: catch.hpp:1774
const bool Opaque_false
Definition: opaque.h:30
static const int buttonWidth
Definition: sliderlist.cpp:35
Theme * theme
Definition: theme.cpp:62