1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: GuiControlManager.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 "GuiControlManager.h"
17
18 namespace scene
19 {
20
21 // Constructor.
ControlManager()22 ControlManager::ControlManager()
23 {
24 m_touchStatusOld.x = 0;
25 m_touchStatusOld.y = 0;
26 m_touchStatusOld.touch = false;
27
28 m_activeId = CONTROL_ID_UNUSED;
29 m_pCallback = NULL;
30 m_pParam = NULL;
31 }
32
33 // Destructor.
~ControlManager()34 ControlManager::~ControlManager()
35 {
36 Clear();
37 }
38
39 // Adds controls.
Add(ControlBase * pControl)40 void ControlManager::Add(ControlBase* pControl)
41 {
42 if (pControl)
43 {
44 if (pControl->GetId() != CONTROL_ID_UNUSED)
45 {
46 for (ControlList::iterator it = m_controlList.begin(); it != m_controlList.end(); it++)
47 {
48 // ID duplication check
49 NN_ASSERT((*it)->GetId() != pControl->GetId());
50 }
51 }
52
53 // Set the control manager
54 pControl->SetControlManager(this);
55
56 m_controlList.push_front(pControl);
57 }
58 }
59
60 // Delete all controls.
Clear()61 void ControlManager::Clear()
62 {
63 for (ControlList::iterator it = m_controlList.begin(); it != m_controlList.end(); it++)
64 {
65 delete *it;
66 }
67
68 m_controlList.clear();
69 }
70
71 // Search for controls.
FindBy(u32 id)72 ControlBase* ControlManager::FindBy(u32 id)
73 {
74 if (id == CONTROL_ID_UNUSED)
75 {
76 return NULL;
77 }
78
79 for (ControlList::iterator it = m_controlList.begin(); it != m_controlList.end(); it++)
80 {
81 if ((*it)->GetId() == id)
82 {
83 return (*it);
84 }
85 }
86
87 return NULL;
88 }
89
90 // Get the control list.
GetList()91 ControlList* ControlManager::GetList()
92 {
93 return &m_controlList;
94 }
95
96 // Perform update processing.
Update()97 void ControlManager::Update()
98 {
99 // Get the input
100 m_touchReader.ReadLatest(&m_touchStatus);
101
102 // Current input
103 u16 nowX = m_touchStatus.x;
104 u16 nowY = m_touchStatus.y;
105 bool nowTouch = m_touchStatus.touch;
106 // Input for 1 frame prior
107 u16 prevX = m_touchStatusOld.x;
108 u16 prevY = m_touchStatusOld.y;
109 bool prevTouch = m_touchStatusOld.touch;
110
111 for (ControlList::iterator it = m_controlList.begin(); it != m_controlList.end(); it++)
112 {
113 if ((*it)->GetId() == CONTROL_ID_UNUSED)
114 {
115 continue;
116 }
117
118 s32 x = (*it)->GetX();
119 s32 y = (*it)->GetY();
120
121 u32 width = (*it)->GetWidth();
122 u32 height = (*it)->GetHeight();
123
124 // Current status
125 ControlState nowState = (*it)->GetState();
126
127 // Do nothing when disabled or hidden
128 if (nowState == CONTROL_STATE_DISABLED || nowState == CONTROL_STATE_HIDE)
129 {
130 continue;
131 }
132
133 // In control
134 if (nowX >= x && nowX <= x + width && nowY >= y && nowY <= y + height)
135 {
136 // Not tapped last time & tapped this time -> stylus down
137 if (!prevTouch && nowTouch && m_activeId == CONTROL_ID_UNUSED)
138 {
139 (*it)->OnPenDown();
140 m_activeId = (*it)->GetId();
141
142 if (m_pCallback)
143 {
144 m_pCallback(CONTROL_EVENT_PENDOWN, *it, nowX - x, nowY - y, m_pParam);
145 }
146 }
147 // Tapped last time & tapped this time -> stylus slide
148 if (prevTouch && nowTouch && m_activeId == (*it)->GetId())
149 {
150 (*it)->OnPenSlide(true);
151
152 if (m_pCallback)
153 {
154 m_pCallback(CONTROL_EVENT_SLIDE, *it, nowX - x, nowY - y, m_pParam);
155 }
156 }
157
158 // Call the callback if state is changed
159 if (nowState != (*it)->GetState() && m_pCallback)
160 {
161 m_pCallback(CONTROL_EVENT_CHANGE_STATE, *it, nowX - x, nowY - y, m_pParam);
162 }
163 }
164 else
165 {
166 if (m_activeId == (*it)->GetId())
167 {
168 // If the previous stylus position was inside the control
169 bool isIn = (prevX >= x && prevX <= x + width && prevY >= y && prevY <= y + height);
170
171 // Still being tapped -> stylus slide
172 if (nowTouch)
173 {
174 (*it)->OnPenSlide(false);
175
176 if (m_pCallback)
177 {
178 m_pCallback(CONTROL_EVENT_SLIDE, *it, nowX - x, nowY - y, m_pParam);
179 }
180 }
181 else
182 {
183 (*it)->OnPenUp(isIn);
184
185 if (m_pCallback)
186 {
187 m_pCallback(CONTROL_EVENT_PENUP, *it, nowX - x, nowY - y, m_pParam);
188 }
189
190 // Stylus released inside the control -> stylus tap
191 if (isIn)
192 {
193 (*it)->OnPenTouch();
194
195 if (m_pCallback)
196 {
197 m_pCallback(CONTROL_EVENT_TOUCH, *it, nowX - x, nowY - y, m_pParam);
198 }
199 }
200
201 m_activeId = CONTROL_ID_UNUSED;
202 }
203
204 // Call the callback if state is changed
205 if (nowState != (*it)->GetState() && m_pCallback)
206 {
207 m_pCallback(CONTROL_EVENT_CHANGE_STATE, *it, nowX - x, nowY - y, m_pParam);
208 }
209 }
210 }
211 }
212
213 if (nowTouch)
214 {
215 // If nowTouch is not valid, nowX and nowY values are also not valid
216 m_touchStatusOld.x = nowX;
217 m_touchStatusOld.y = nowY;
218 }
219
220 m_touchStatusOld.touch = nowTouch;
221 }
222
223 // Performs rendering.
Draw()224 void ControlManager::Draw()
225 {
226 for (ControlList::iterator it = m_controlList.begin(); it != m_controlList.end(); it++)
227 {
228 if ((*it)->GetState() != CONTROL_STATE_HIDE)
229 {
230 (*it)->OnDraw();
231 }
232 }
233 }
234
235 }
236