1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: TenKey.cpp
4
5 Copyright (C)2009-2012 Nintendo Co., Ltd. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Rev: 46365 $
14 *---------------------------------------------------------------------------*/
15
16 #include <string.h>
17 #include "TenKey.h"
18 #include "Gui.h"
19 #include "Util.h"
20
21 //////////////////////////////////////////////////////////////////////////////////////////
22 // Constant definitions
23 //////////////////////////////////////////////////////////////////////////////////////////
24
25 // Control ID
26 #define CONTROL_ID_OK 1000
27 #define CONTROL_ID_CANCEL 1001
28 #define CONTROL_ID_BACK 1002
29 #define CONTROL_ID_CLEAR 1003
30 #define CONTROL_ID_INPUT_BASE 2000
31
32 // Size of the input box
33 #define BOX_SIZE 16
34 // Hyphen size
35 #define HYPHEN_SIZE 6
36
37 //////////////////////////////////////////////////////////////////////////////////////////
38 // Function definitions
39 //////////////////////////////////////////////////////////////////////////////////////////
40
41 namespace
42 {
CreateInputBox(u32 id,u16 x,const wchar_t * pText)43 scene::Label* CreateInputBox(u32 id, u16 x, const wchar_t* pText)
44 {
45 // Label
46 scene::Label* pLabel = new scene::Label(id, x, 8, BOX_SIZE, 36, pText);
47 // Border color
48 nn::util::Color8 borderColor = nn::util::Color8(64, 64, 64, 255);
49
50 pLabel->SetTextAlign(scene::TEXT_ALIGN_CENTER);
51 pLabel->SetBorderColor(scene::CONTROL_STATE_DEFAULT, borderColor);
52 pLabel->SetBorderWidth(1.0f);
53
54 return pLabel;
55 }
56
CreateHyphen(u16 x)57 scene::Label* CreateHyphen(u16 x)
58 {
59 // Label
60 scene::Label* pLabel = new scene::Label(scene::CONTROL_ID_UNUSED, x, 12, HYPHEN_SIZE, 30, L"-");
61
62 pLabel->SetTextAlign(scene::TEXT_ALIGN_CENTER);
63
64 return pLabel;
65 }
66 }
67
68 //////////////////////////////////////////////////////////////////////////////////////////
69 namespace scene
70 {
71
72 // Constructor.
TenKey()73 TenKey::TenKey()
74 {
75 m_pInput = NULL;
76 m_length = 0;
77 m_split = 0;
78 m_numLowestChars = 1;
79 m_cursor = 0;
80 m_state = STATE_NORMAL;
81 }
82
83 // Destructor.
~TenKey()84 TenKey::~TenKey()
85 {
86 Finalize();
87 }
88
89 // Performs initialization.
Initialize(u32 length,u32 split,const wchar_t * pInitial,u32 numLowestChars,bool isPassword)90 void TenKey::Initialize(u32 length, u32 split, const wchar_t* pInitial, u32 numLowestChars, bool isPassword)
91 {
92 NN_ASSERT(m_pInput == NULL);
93
94 m_pInput = new wchar_t[length + 1];
95 NN_ASSERT(m_pInput != NULL);
96
97 memset(m_pInput, 0, (length + 1) * sizeof (m_pInput[0]));
98
99 m_length = length;
100 m_split = split;
101 m_numLowestChars = numLowestChars;
102 m_isPassword = isPassword;
103
104 // Return icon
105 wchar_t backIcon[] = {0xE072, '\0'};
106
107 scene::AddYesNoButtons(&m_controlManager, CONTROL_ID_OK, CONTROL_ID_CANCEL, L"OK", L"Cancel");
108
109 m_controlManager.Add(new scene::Button(CONTROL_ID_BACK, 258, 58, 60, 30, backIcon));
110 m_controlManager.Add(new scene::Button(CONTROL_ID_CLEAR, 2, 58, 60, 30, L"CLR"));
111 m_controlManager.Add(new scene::Button(1, 66, 58, 60, 30, L"1"));
112 m_controlManager.Add(new scene::Button(2, 130, 58, 60, 30, L"2"));
113 m_controlManager.Add(new scene::Button(3, 194, 58, 60, 30, L"3"));
114 m_controlManager.Add(new scene::Button(4, 66, 92, 60, 30, L"4"));
115 m_controlManager.Add(new scene::Button(5, 130, 92, 60, 30, L"5"));
116 m_controlManager.Add(new scene::Button(6, 194, 92, 60, 30, L"6"));
117 m_controlManager.Add(new scene::Button(7, 66, 126, 60, 30, L"7"));
118 m_controlManager.Add(new scene::Button(8, 130, 126, 60, 30, L"8"));
119 m_controlManager.Add(new scene::Button(9, 194, 126, 60, 30, L"9"));
120 m_controlManager.Add(new scene::Button(0, 130, 160, 60, 30, L"0"));
121
122 // Input information
123 {
124 // Margin
125 const u16 margin = 2;
126 // Number of hyphens
127 u16 hyphenNum = split > 0 ? ((length - 1) / split) : 0;
128 // Size of field where the input box is placed
129 u16 fieldWidth = BOX_SIZE * length + HYPHEN_SIZE * hyphenNum + (margin * (length + hyphenNum - 1));
130 // Position of the input box
131 u16 x = (NN_GX_DISPLAY1_HEIGHT - fieldWidth) / 2;
132
133 for (u32 i = 0; i < length; i++)
134 {
135 u32 id = CONTROL_ID_INPUT_BASE + i;
136
137 m_controlManager.Add(CreateInputBox(id, x, L""));
138 x += BOX_SIZE + margin;
139
140 if (hyphenNum > 0 && i != (length - 1) && ((i + 1) % split) == 0)
141 {
142 m_controlManager.Add(CreateHyphen(x));
143 x += HYPHEN_SIZE + margin;
144 }
145 }
146 }
147
148 if (pInitial)
149 {
150 Reset(pInitial);
151 }
152
153 m_controlManager.RegisterControlEventCallback(TenKey::MyControlEventCallback, this);
154 }
155
156 // Performs shutdown.
Finalize()157 void TenKey::Finalize()
158 {
159 if (m_pInput)
160 {
161 delete[] m_pInput;
162 }
163
164 m_pInput = NULL;
165 m_length = 0;
166 m_split = 0;
167 m_numLowestChars = 1;
168 m_cursor = 0;
169 m_state = STATE_NORMAL;
170
171 m_controlManager.Clear();
172 }
173
174 // Perform update processing.
Update()175 void TenKey::Update()
176 {
177 m_controlManager.Update();
178 }
179
180 // Performs rendering.
Draw()181 void TenKey::Draw()
182 {
183 m_controlManager.Draw();
184 }
185
186 // Resets the state.
Reset(const wchar_t * pInitial)187 void TenKey::Reset(const wchar_t* pInitial)
188 {
189 m_cursor = 0;
190 m_state = STATE_NORMAL;
191
192 if (m_pInput)
193 {
194 memset(m_pInput, 0, (m_length + 1) * sizeof (m_pInput[0]));
195
196 if (pInitial)
197 {
198 m_cursor = scene::wstrlen(pInitial);
199 memcpy(m_pInput, pInitial, (m_cursor > m_length ? m_length : m_cursor) * sizeof (m_pInput[0]));
200 }
201
202 if (m_cursor >= m_numLowestChars)
203 {
204 // Enable the OK button
205 m_controlManager.FindBy(CONTROL_ID_OK)->SetState(scene::CONTROL_STATE_DEFAULT);
206 }
207 else
208 {
209 // Disable the OK button
210 m_controlManager.FindBy(CONTROL_ID_OK)->SetState(scene::CONTROL_STATE_DISABLED);
211 }
212
213 for (u32 i = 0; i < m_length; i++)
214 {
215 if (m_pInput[i] != '\0' && m_isPassword)
216 {
217 // *
218 m_controlManager.FindBy(CONTROL_ID_INPUT_BASE + i)->SetText(L"*");
219 }
220 else
221 {
222 // Character
223 wchar_t text[] = {m_pInput[i], '\0'};
224
225 m_controlManager.FindBy(CONTROL_ID_INPUT_BASE + i)->SetText(text);
226 }
227 }
228 }
229 }
230
231 // Get values that were input.
GetInputInteger() const232 u32 TenKey::GetInputInteger() const
233 {
234 return scene::wtoi(m_pInput);
235 }
236
237 // Event callback
MyControlEventCallback(scene::ControlEvent event,scene::ControlBase * pControl,s16 x,s16 y,void * pParam)238 void TenKey::MyControlEventCallback(scene::ControlEvent event, scene::ControlBase* pControl, s16 x, s16 y, void* pParam)
239 {
240 (void)x;
241 (void)y;
242
243 if (event == scene::CONTROL_EVENT_TOUCH)
244 {
245 // Numeric keypad
246 TenKey* pTenKey = (TenKey*)pParam;
247 // ID of the tapped control
248 u16 controlId = pControl->GetId();
249
250 switch (controlId)
251 {
252 case CONTROL_ID_OK:
253 {
254 pTenKey->m_state = STATE_OK;
255 }
256 break;
257 case CONTROL_ID_CANCEL:
258 {
259 pTenKey->m_state = STATE_CANCELLED;
260 }
261 break;
262 case CONTROL_ID_CLEAR:
263 {
264 pTenKey->Reset(NULL);
265 }
266 break;
267 case CONTROL_ID_BACK:
268 {
269 if (pTenKey->m_cursor > 0)
270 {
271 // Makes the text at the cursor position blank
272 pTenKey->m_pInput[--pTenKey->m_cursor] = '\0';
273 pTenKey->m_controlManager.FindBy(CONTROL_ID_INPUT_BASE + pTenKey->m_cursor)->SetText(L"");
274
275 if (pTenKey->m_cursor < pTenKey->m_numLowestChars)
276 {
277 // Disable the OK button
278 pTenKey->m_controlManager.FindBy(CONTROL_ID_OK)->SetState(scene::CONTROL_STATE_DISABLED);
279 }
280 }
281 }
282 break;
283 default:
284 {
285 if (controlId < 10)
286 {
287 if (pTenKey->m_cursor < pTenKey->m_length)
288 {
289 if (pTenKey->m_isPassword)
290 {
291 pTenKey->m_controlManager.FindBy(CONTROL_ID_INPUT_BASE + pTenKey->m_cursor)->SetText(L"*");
292 }
293 else
294 {
295 // Character
296 wchar_t text[] = {'0' + controlId, '\0'};
297
298 pTenKey->m_controlManager.FindBy(CONTROL_ID_INPUT_BASE + pTenKey->m_cursor)->SetText(text);
299 }
300
301 pTenKey->m_pInput[pTenKey->m_cursor++] = '0' + controlId;
302 }
303
304 if (pTenKey->m_cursor >= pTenKey->m_numLowestChars)
305 {
306 // Enable the OK button
307 pTenKey->m_controlManager.FindBy(CONTROL_ID_OK)->SetState(scene::CONTROL_STATE_DEFAULT);
308 }
309 }
310 }
311 }
312 }
313 }
314
315 } // namespace scene
316