GUI
GUISystem.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 by Maciej Wiecierzewski
3  */
4 
5 #include "GUISystem.h"
6 
7 #include <stdexcpt.h>
8 
9 #include "EventObject.h"
10 #include "KeyboardEvent.h"
11 #include "MouseEvent.h"
12 
13 using namespace gui;
14 
16  mouseX(0),
17  mouseY(0),
18  renderer(NULL),
19  focus(NULL)
20 {
21  addEventType(EventType::DISPLAY_CLOSE, static_cast<CreateEventObject>(std::bind(&GUISystem::createNull, this, std::placeholders::_1)));
22  addEventType(EventType::RESIZE, static_cast<CreateEventObject>(std::bind(&GUISystem::createNull, this, std::placeholders::_1)));
23 
24  addEventType(EventType::MOUSE_MOVE, static_cast<CreateEventObject>(std::bind(&GUISystem::createMouseEvent, this, std::placeholders::_1)));
25  addEventType(EventType::MOUSE_BUTTON_DOWN, static_cast<CreateEventObject>(std::bind(&GUISystem::createMouseEvent, this, std::placeholders::_1)));
26  addEventType(EventType::MOUSE_BUTTON_UP, static_cast<CreateEventObject>(std::bind(&GUISystem::createMouseEvent, this, std::placeholders::_1)));
27 
28  addEventType(EventType::KEY_PRESS, static_cast<CreateEventObject>(std::bind(&GUISystem::createKeyboardEvent, this, std::placeholders::_1)));
29  addEventType(EventType::KEY_DOWN, static_cast<CreateEventObject>(std::bind(&GUISystem::createKeyboardEvent, this, std::placeholders::_1)));
30  addEventType(EventType::KEY_UP, static_cast<CreateEventObject>(std::bind(&GUISystem::createKeyboardEvent, this, std::placeholders::_1)));
31 }
32 
34 {
35 
36 }
37 
39 {
40  this->renderer = renderer;
41 }
42 
44 {
46  renderer->clear();
47 
48  for(std::forward_list<Widget*>::iterator i = widgets.begin(); i != widgets.end(); i++)
49  {
50  if((*i)->visible)
51  (*i)->render(renderer);
52  }
53 }
54 
56 {
57  while(!eventQueue.empty())
58  {
59  EventListener eventListener;
60  Event event = eventQueue.getNextEvent(eventListener);
61 
62  eventListener(event);
63  }
64 }
65 
66 void GUISystem::mouseMove(int x, int y)
67 {
68  mouseX = x;
69  mouseY = y;
70 
71  for(std::forward_list<Widget*>::iterator i = widgets.begin(); i != widgets.end(); i++)
72  {
73  Widget::State state = (*i)->getState();
74 
75  if((*i)->visible && (*i)->contain(mouseX, mouseY))
76  {
77  if(state == Widget::STATE_UP)
78  {
79  (*i)->stateChange(Widget::STATE_HOVER);
80  }
81  }
82  else
83  {
84  if(state == Widget::STATE_HOVER)
85  {
86  (*i)->stateChange(Widget::STATE_UP);
87  }
88  }
89 
90  (*i)->mouseMove(mouseX, mouseY);
91  }
92 }
93 
95 {
96  for(std::forward_list<Widget*>::iterator i = widgets.begin(); i != widgets.end(); i++)
97  {
98  if((*i)->visible && (*i)->getState() != Widget::STATE_UP)
99  {
100  if((*i)->contain(mouseX, mouseY))
101  (*i)->stateChange(Widget::STATE_HOVER);
102  else
103  (*i)->stateChange(Widget::STATE_UP);
104  }
105  }
106 }
107 
109 {
110  Widget *newFocus = NULL;
111 
112  for(std::forward_list<Widget*>::iterator i = widgets.begin(); i != widgets.end(); i++)
113  {
114  if((*i)->visible && (*i)->contain(mouseX, mouseY))
115  {
117  newFocus = (*i);
118  }
119  }
120 
121  if(newFocus != focus)
122  {
123  if(focus != NULL)
124  {
125  focus->focusOut();
126  }
127 
128  if(newFocus != NULL)
129  {
130  focus = newFocus;
131  focus->focusIn();
132  }
133  else
134  {
135  focus = NULL;
136  }
137  }
138 }
139 
140 void GUISystem::keyChar(int unichar)
141 {
142  if(focus != NULL)
143  {
144  focus->keyChar(unichar);
145  }
146 }
147 
148 void GUISystem::keyDown(int keyCode)
149 {
150  if(focus != NULL)
151  {
152  focus->keyDown(keyCode);
153  }
154 }
155 
156 Handle<Button> GUISystem::addButton(int x, int y, int w, int h, std::string text)
157 {
158  Button *button = new Button(this, x, y, w, h, text);
159  button->guiSystem = this;
160 
161  button->upStateColor = renderer->color(0, 0, 120);
162  button->hoverStateColor = renderer->color(20, 20, 190);
163  button->downStateColor = renderer->color(0, 0, 90);
164  button->textColor = renderer->color(255, 255, 255);
165 
166  auto addToQueue = std::bind(&EventQueue::addToQueue, &eventQueue, std::placeholders::_1, std::placeholders::_2);
167  button->setQueue(static_cast<AddToQueue>(addToQueue));
168 
169  widgets.push_front(button);
170 
171  return Handle<Button>(button);
172 }
173 
174 Handle<TextField> GUISystem::addTextField(int x, int y, int w, int h, std::string text)
175 {
176  TextField *textField = new TextField(this, x, y, w, h, text);
177  textField->guiSystem = this;
178 
179  textField->textColor = renderer->color(0, 0, 0);
180 
181  auto addToQueue = std::bind(&EventQueue::addToQueue, &eventQueue, std::placeholders::_1, std::placeholders::_2);
182  textField->setQueue(static_cast<AddToQueue>(addToQueue));
183 
184  widgets.push_front(textField);
185 
186  return Handle<TextField>(textField);
187 }
188 
189 Handle<EditBox> GUISystem::addEditBox(int x, int y, int w, int h, bool multiline)
190 {
191  EditBox *editBox = new EditBox(this, x, y, w, h);
192  editBox->guiSystem = this;
193 
194  if(multiline)
195  editBox->setMultiline();
196 
197  editBox->textColor = renderer->color(0, 0, 0);
198  editBox->frameColor = renderer->color(0, 0, 0);
199  editBox->backgroundColor = renderer->color(255, 255, 255);
200  editBox->cursorColor = renderer->color(0, 0, 0);
201 
202  auto addToQueue = std::bind(&EventQueue::addToQueue, &eventQueue, std::placeholders::_1, std::placeholders::_2);
203  editBox->setQueue(static_cast<AddToQueue>(addToQueue));
204 
205  widgets.push_front(editBox);
206 
207  return Handle<EditBox>(editBox);
208 }
209 
210 Handle<Scrollbar> GUISystem::addScrollbar(int x, int y, int w, int h)
211 {
212  Scrollbar *scrollbar = new Scrollbar(this, x, y, w, h);
213  scrollbar->guiSystem = this;
214 
215  scrollbar->backgroundColor = renderer->color(255, 255, 255);
216  scrollbar->frameColor = renderer->color(0, 0, 0);
217 
218  auto addToQueue = std::bind(&EventQueue::addToQueue, &eventQueue, std::placeholders::_1, std::placeholders::_2);
219  scrollbar->setQueue(static_cast<AddToQueue>(addToQueue));
220 
221  widgets.push_front(scrollbar);
222 
223  return Handle<Scrollbar>(scrollbar);
224 }
225 
226 Handle<Widget> GUISystem::addWidget(CreateWidget createWidget, bool setEventQueue)
227 {
228  Widget *widget = createWidget(this);
229  widget->guiSystem = this;
230 
231  widgets.push_front(widget);
232 
233  if(setEventQueue)
234  {
235  auto addToQueue = std::bind(&EventQueue::addToQueue, &eventQueue, std::placeholders::_1, std::placeholders::_2);
236  widget->setQueue(static_cast<AddToQueue>(addToQueue));
237  }
238 
239  return Handle<Widget>(widget);
240 }
241 
243 {
244  auto iter = createEvtObjFuncs.find(eventType);
245 
246  if(iter == createEvtObjFuncs.end())
247  throw std::invalid_argument("Type not found.");
248 
249  EventObject *evtObj = iter->second(NULL);
250 
251  Event event(eventType, evtObj);
252 
253  return event;
254 }
255 
257 {
258  Event event;
259  event.type = _event.type;
260 
261  auto iter = createEvtObjFuncs.find(event.type);
262 
263  if(iter == createEvtObjFuncs.end())
264  throw std::invalid_argument("Type not found.");
265 
266  EventObject *evtObj = iter->second(_event.obj);
267 
268  event.obj = evtObj;
269 
270  return event;
271 }
272 
274 {
275  EventObject *evtObj;
276 
277  if(obj == NULL)
278  evtObj = new EventObject();
279  else
280  evtObj = new EventObject(*obj);
281 
282  return evtObj;
283 }
284 
286 {
287  MouseEvent *evtObj;
288 
289  if(obj == NULL)
290  {
291  evtObj = new MouseEvent();
292  evtObj->mouseX = mouseX;
293  evtObj->mouseY = mouseY;
294  }
295  else
296  evtObj = new MouseEvent(*static_cast<MouseEvent*>(obj));
297 
298  return evtObj;
299 }
300 
302 {
303  KeyboardEvent *evtObj;
304 
305  if(obj == NULL)
306  evtObj = new KeyboardEvent();
307  else
308  evtObj = new KeyboardEvent(*static_cast<KeyboardEvent*>(obj));
309 
310  return evtObj;
311 }
312 
314 {
315  if(createEvtObjFuncs.find(eventType) != createEvtObjFuncs.end())
316  {
317  throw std::runtime_error("Type already registered.");
318  }
319 
320  createEvtObjFuncs.emplace(eventType, createFunc);
321 }