FIFE
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
guichanmanager.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2013 by the FIFE team *
3  * http://www.fifengine.net *
4  * This file is part of FIFE. *
5  * *
6  * FIFE is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU Lesser General Public *
8  * License as published by the Free Software Foundation; either *
9  * version 2.1 of the License, or (at your option) any later version. *
10  * *
11  * This library is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14  * Lesser General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU Lesser General Public *
17  * License along with this library; if not, write to the *
18  * Free Software Foundation, Inc., *
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20  ***************************************************************************/
21 
22 // Standard C++ library includes
23 
24 // 3rd party library includes
25 #include <guichan/sdl/sdlinput.hpp>
26 #include <guichan/key.hpp>
27 #include <guichan/focushandler.hpp>
28 #include <guichan.hpp>
29 
30 // FIFE includes
31 // These includes are split up in two parts, separated by one empty line
32 // First block: files included from the FIFE root src directory
33 // Second block: files included from the same folder
34 #ifdef HAVE_OPENGL
37 #endif
39 #include "util/base/exception.h"
40 #include "util/log/logger.h"
41 #include "video/renderbackend.h"
45 #include "video/fonts/fontbase.h"
52 
53 #include "guichanmanager.h"
54 
55 namespace FIFE {
59  static Logger _log(LM_GUI);
60 
62  m_gcn_gui(new gcn::Gui()),
63  m_focushandler(0),
64  m_gcn_topcontainer(new gcn::Container()),
65  m_imgloader(new GuiImageLoader()) ,
66  m_input(new gcn::SDLInput()),
67  m_console(0),
68  m_defaultfont(0),
69  m_fonts(),
70  m_logic_executed(false) {
71 
72  m_gcn_gui->setInput(m_input);
73  gcn::Image::setImageLoader(m_imgloader);
74 
76  m_focushandler = m_gcn_topcontainer->_getFocusHandler();
77 
78  m_gcn_topcontainer->setOpaque(false);
79  m_gcn_topcontainer->setFocusable(false);
80  m_had_mouse = false;
81  m_had_widget = false;
82  m_isPressed = false;
83  }
84 
86  delete m_console;
87  delete m_gcn_topcontainer;
88  delete m_imgloader;
89  delete m_input;
90  delete m_gcn_gui;
91  delete m_gui_graphics;
92  std::vector<GuiFont*>::iterator i = m_fonts.begin();
93  while (i != m_fonts.end()) {
94  delete *i;
95  ++i;
96  }
97  }
98 
99  bool GUIChanManager::onSdlEvent(SDL_Event& evt) {
100  if (!m_input) {
101  FL_WARN(_log, "GUIChanManager, GuichanGUI->getInput == 0 ... discarding events!");
102  return false;
103  }
104 
105  bool overWidget = m_gcn_topcontainer->getWidgetAt(evt.button.x,evt.button.y) != 0;
106 
107  switch(evt.type) {
108  case SDL_MOUSEBUTTONDOWN:
109  m_isPressed = true;
110  m_had_widget = overWidget;
111  // Always send the button up/down events to guichan
112  m_input->pushInput(evt);
113  // Button was pressed over a widget so we mark the event as processed.
114  if (m_had_widget) {
115  return true;
116  }
117 
118  // Button wasn't pressed over a widget so we want to release focus
119  // no matter what.
120  m_focushandler->focusNone();
121  // Don't mark it as processed here so the
122  // other listeners have a chance to process the event.
123  return false;
124 
125  case SDL_MOUSEBUTTONUP:
126  m_isPressed = false;
127  // Always send the button up/down events to guichan
128  m_input->pushInput(evt);
129  // Button was pressed over a widget and still is over a widget
130  // so we mark the event as processed.
131  if (m_had_widget && overWidget) {
132  return true;
133  }
134 
135  // Button wasn't pressed over a widget so we want to release focus
136  // no matter what.
137  if (!m_had_widget) {
138  m_focushandler->focusNone();
139  }
140  // Button up was processed by guichan but there was no widget under
141  // the mouse at the time. Don't mark it as processed here so the
142  // other listeners have a chance to process the event.
143  return false;
144 
145  case SDL_MOUSEMOTION:
146  // If the mouse is over a widget and not dragging.
147  if (overWidget && !m_isPressed) {
148  m_had_mouse = true;
149  m_input->pushInput(evt);
150  return true;
151  }
152  // If the mouse "dragging" a widget.
154  // We only keep the mouse if a widget/window has requested
155  // dragging.
156  m_had_mouse = m_focushandler->getDraggedWidget() != 0;
157  m_input->pushInput(evt);
158  return true;
159  }
160  // Mouse is already dragging or not over a widget.
161  // Let other listeners have a chance to process the event.
162  return false;
163 
164  case SDL_KEYDOWN:
165  case SDL_KEYUP:
166  if(m_focushandler->getFocused()) {
167  m_input->pushInput(evt);
168  return true;
169  }
170  return false;
171 
172  case SDL_ACTIVEEVENT:
173  // Actually Guichan doesn't care (it should!)
174  // so at least don't swallow mouse_focus events up.
175  return false;
176 
177  default:
178  return false;
179  }
180  }
181 
183  m_gcn_topcontainer->setDimension(gcn::Rectangle(x, y, width, height));
184  this->invalidateFonts();
185  this->m_console->reLayout();
186  }
187 
188  gcn::Gui* GUIChanManager::getGuichanGUI() const {
189  return m_gcn_gui;
190  }
191 
192  void GUIChanManager::add(gcn::Widget* widget) {
193  if( !m_widgets.count(widget) ) {
194  m_gcn_topcontainer->add(widget);
195  m_widgets.insert(widget);
196  }
197  }
198 
199  void GUIChanManager::remove(gcn::Widget* widget) {
200  if( m_widgets.count(widget) ) {
201  m_widgets.erase(widget);
202  m_gcn_topcontainer->remove(widget);
203  }
204  }
205 
206  void GUIChanManager::init(const std::string& backend, int32_t screenWidth, int32_t screenHeight) {
207  if( backend == "SDL" ) {
209  }
210 #ifdef HAVE_OPENGL
211  else if (backend == "OpenGL") {
213  }
214  else if (backend == "OpenGLe") {
216  }
217 #endif
218  else {
219  //should never get here
220  assert(0);
221  }
222 
223  m_gcn_gui->setGraphics(m_gui_graphics);
224  m_console = new Console();
225 
226  resizeTopContainer(0, 0, screenWidth, screenHeight);
227  }
228 
229  GuiFont* GUIChanManager::createFont(const std::string& path, uint32_t size, const std::string& glyphs) {
230  std::string fontpath = path;
231  std::string fontglyphs = glyphs;
232  int32_t fontsize = size;
233 
234  // Set default settings if necessary
235  if(fontpath == "") {
236  fontpath = m_fontpath;
237  }
238  if(fontsize == 0) {
239  fontsize = m_fontsize;
240  }
241  if(fontglyphs == "") {
242  fontglyphs = m_fontglyphs;
243  }
244 
245  IFont* font = NULL;
246  GuiFont* guifont = NULL;
247  if( bfs::extension(fontpath) == ".ttf" || bfs::extension(fontpath) == ".ttc" ) {
248  font = new TrueTypeFont(fontpath, fontsize);
249  } else {
250  font = new SubImageFont(fontpath, fontglyphs);
251  }
252  guifont = new GuiFont(font);
253 
254  m_fonts.push_back(guifont);
255  return guifont;
256  }
257 
259  std::vector<GuiFont*>::iterator i = m_fonts.begin();
260  while (i != m_fonts.end()) {
261  if ((*i) == font) {
262  m_fonts.erase(i);
263  delete font;
264  return;
265  }
266  ++i;
267  }
268  }
269 
271  std::vector<GuiFont*>::iterator it = m_fonts.begin();
272  while (it != m_fonts.end()) {
273  (*it)->invalidate();
274  ++it;
275  }
276  }
277 
278  GuiFont* GUIChanManager::setDefaultFont(const std::string& path, uint32_t size, const std::string& glyphs) {
279  m_fontpath = path;
280  m_fontsize = size;
281  m_fontglyphs = glyphs;
282 
284  gcn::Widget::setGlobalFont(m_defaultfont);
285  if (m_console) {
286  m_console->reLayout();
287  }
288 
289  return m_defaultfont;
290  }
291 
293  if (!m_logic_executed)
294  m_gcn_gui->logic();
295  m_logic_executed = false;
296  m_gcn_gui->draw();
297  }
298 
299  KeyEvent GUIChanManager::translateKeyEvent(const gcn::KeyEvent& gcnevt) {
300  KeyEvent keyevt;
301  if(gcnevt.getType() == gcn::KeyEvent::PRESSED)
302  keyevt.setType(KeyEvent::PRESSED);
303  else if(gcnevt.getType() == gcn::KeyEvent::RELEASED)
304  keyevt.setType(KeyEvent::RELEASED);
305  else {
306  FL_WARN(_log, LMsg("GUIChanManager::translateKeyEvent() - ") << "Unknown event type: " << gcnevt.getType());
307  keyevt.setType(KeyEvent::UNKNOWN);
308  }
309  keyevt.setShiftPressed(gcnevt.isShiftPressed());
310  keyevt.setControlPressed(gcnevt.isControlPressed());
311  keyevt.setAltPressed(gcnevt.isAltPressed());
312  keyevt.setMetaPressed(gcnevt.isMetaPressed());
313  keyevt.setNumericPad(gcnevt.isNumericPad());
314 
315  // Convert from guichan keyval to FIFE keyval
316  int32_t keyval = gcnevt.getKey().getValue();
317  keyval = convertGuichanKeyToFifeKey(keyval);
318 
319  keyevt.setKey(Key(static_cast<Key::KeyType>(keyval), keyval));
320 
321  return keyevt;
322  }
323 
324  MouseEvent GUIChanManager::translateMouseEvent(const gcn::MouseEvent& gcnevt) {
325  MouseEvent mouseevt;
326  mouseevt.setShiftPressed(gcnevt.isShiftPressed());
327  mouseevt.setControlPressed(gcnevt.isControlPressed());
328  mouseevt.setAltPressed(gcnevt.isAltPressed());
329  mouseevt.setMetaPressed(gcnevt.isMetaPressed());
330  mouseevt.setX(gcnevt.getX());
331  mouseevt.setY(gcnevt.getY());
332 
333  switch(gcnevt.getType()) {
334  case gcn::MouseEvent::PRESSED:
335  mouseevt.setType(MouseEvent::PRESSED);
336  break;
337  case gcn::MouseEvent::RELEASED:
338  mouseevt.setType(MouseEvent::RELEASED);
339  break;
340  case gcn::MouseEvent::MOVED:
341  mouseevt.setType(MouseEvent::MOVED);
342  break;
343  case gcn::MouseEvent::CLICKED:
344  mouseevt.setType(MouseEvent::CLICKED);
345  break;
346  case gcn::MouseEvent::ENTERED:
347  mouseevt.setType(MouseEvent::ENTERED);
348  break;
349  case gcn::MouseEvent::EXITED:
350  mouseevt.setType(MouseEvent::EXITED);
351  break;
352  case gcn::MouseEvent::DRAGGED:
353  mouseevt.setType(MouseEvent::DRAGGED);
354  break;
355  case gcn::MouseEvent::WHEEL_MOVED_DOWN:
357  break;
358  case gcn::MouseEvent::WHEEL_MOVED_UP:
360  break;
361  default:
363  }
364 
365  switch(gcnevt.getButton()) {
366  case gcn::MouseInput::LEFT:
367  mouseevt.setButton(MouseEvent::LEFT);
368  break;
369  case gcn::MouseInput::RIGHT:
370  mouseevt.setButton(MouseEvent::RIGHT);
371  break;
372  case gcn::MouseInput::MIDDLE:
373  mouseevt.setButton(MouseEvent::MIDDLE);
374  break;
375  default:
377  break;
378  }
379  return mouseevt;
380  }
381 
382 
384 
385  switch (value) {
386  case gcn::Key::TAB:
387  value = Key::TAB;
388  break;
389  case gcn::Key::LEFT_ALT:
390  value = Key::LEFT_ALT;
391  break;
392  case gcn::Key::RIGHT_ALT:
393  value = Key::RIGHT_ALT;
394  break;
395  case gcn::Key::LEFT_SHIFT:
396  value = Key::LEFT_SHIFT;
397  break;
398  case gcn::Key::RIGHT_SHIFT:
399  value = Key::RIGHT_SHIFT;
400  break;
401  case gcn::Key::LEFT_CONTROL:
402  value = Key::LEFT_CONTROL;
403  break;
404  case gcn::Key::RIGHT_CONTROL:
405  value = Key::RIGHT_CONTROL;
406  break;
407  case gcn::Key::BACKSPACE:
408  value = Key::BACKSPACE;
409  break;
410  case gcn::Key::PAUSE:
411  value = Key::PAUSE;
412  break;
413  case gcn::Key::SPACE:
414  value = Key::SPACE;
415  break;
416  case gcn::Key::ESCAPE:
417  value = Key::ESCAPE;
418  break;
419  case gcn::Key::DELETE:
420  value = Key::DELETE;
421  break;
422  case gcn::Key::INSERT:
423  value = Key::INSERT;
424  break;
425  case gcn::Key::HOME:
426  value = Key::HOME;
427  break;
428  case gcn::Key::END:
429  value = Key::END;
430  break;
431  case gcn::Key::PAGE_UP:
432  value = Key::PAGE_UP;
433  break;
434  case gcn::Key::PRINT_SCREEN:
435  value = Key::PRINT_SCREEN;
436  break;
437  case gcn::Key::PAGE_DOWN:
438  value = Key::PAGE_DOWN;
439  break;
440  case gcn::Key::F1:
441  value = Key::F1;
442  break;
443  case gcn::Key::F2:
444  value = Key::F2;
445  break;
446  case gcn::Key::F3:
447  value = Key::F3;
448  break;
449  case gcn::Key::F4:
450  value = Key::F4;
451  break;
452  case gcn::Key::F5:
453  value = Key::F5;
454  break;
455  case gcn::Key::F6:
456  value = Key::F6;
457  break;
458  case gcn::Key::F7:
459  value = Key::F7;
460  break;
461  case gcn::Key::F8:
462  value = Key::F8;
463  break;
464  case gcn::Key::F9:
465  value = Key::F9;
466  break;
467  case gcn::Key::F10:
468  value = Key::F10;
469  break;
470  case gcn::Key::F11:
471  value = Key::F11;
472  break;
473  case gcn::Key::F12:
474  value = Key::F12;
475  break;
476  case gcn::Key::F13:
477  value = Key::F13;
478  break;
479  case gcn::Key::F14:
480  value = Key::F14;
481  break;
482  case gcn::Key::F15:
483  value = Key::F15;
484  break;
485  case gcn::Key::NUM_LOCK:
486  value = Key::NUM_LOCK;
487  break;
488  case gcn::Key::CAPS_LOCK:
489  value = Key::CAPS_LOCK;
490  break;
491  case gcn::Key::SCROLL_LOCK:
492  value = Key::SCROLL_LOCK;
493  break;
494  case gcn::Key::RIGHT_META:
495  value = Key::RIGHT_META;
496  break;
497  case gcn::Key::LEFT_META:
498  value = Key::LEFT_META;
499  break;
500  case gcn::Key::LEFT_SUPER:
501  value = Key::LEFT_SUPER;
502  break;
503  case gcn::Key::RIGHT_SUPER:
504  value = Key::RIGHT_SUPER;
505  break;
506  case gcn::Key::ALT_GR:
507  value = Key::ALT_GR;
508  break;
509  case gcn::Key::UP:
510  value = Key::UP;
511  break;
512  case gcn::Key::DOWN:
513  value = Key::DOWN;
514  break;
515  case gcn::Key::LEFT:
516  value = Key::LEFT;
517  break;
518  case gcn::Key::RIGHT:
519  value = Key::RIGHT;
520  break;
521  case gcn::Key::ENTER:
522  value = Key::ENTER;
523  break;
524 
525  default:
526  // Convert from unicode to lowercase letters
527  if (value >= 1 && value <= 26) {
528  // Control characters
529  value = value - 1 + 'a';
530  } else if (value >= 'A' && value <= 'Z') {
531  value = value - 'A' + 'a';
532  }
533 
534  // FIXME: Accented characters (รก) will not get converted properly.
535  break;
536  }
537 
538  return value;
539  }
540 }
Definition: modules.h:41
GuiFont * setDefaultFont(const std::string &path, uint32_t size, const std::string &glyphs)
Set the global font properties.
#define FL_WARN(logger, msg)
Definition: logger.h:72
void resizeTopContainer(uint32_t x, uint32_t y, uint32_t width, uint32_t height)
Resizes the top container.
gcn::Gui * getGuichanGUI() const
Gets the member pointer to the Guichan GUI.
void setY(int32_t y)
gcn::Graphics * m_gui_graphics
Class for mouse events.
Definition: ec_mouseevent.h:42
MouseEvent translateMouseEvent(const gcn::MouseEvent &evt)
void setKey(const Key &key)
Definition: ec_keyevent.h:72
Helper class to create log strings out from separate parts Usage: LMsg(&quot;some text&quot;) &lt;&lt; variable &lt;&lt; &quot;...
Definition: logger.h:82
gcn::Container * m_gcn_topcontainer
virtual void setControlPressed(bool pressed)
virtual void setShiftPressed(bool pressed)
virtual void turn()
Performs the GUI logic and draws the GUI accordingly.
KeyEvent translateKeyEvent(const gcn::KeyEvent &evt)
static Logger _log(LM_AUDIO)
GuiFont * createFont(const std::string &path="", uint32_t size=0, const std::string &glyphs="")
Gets font with given properties.
void remove(gcn::Widget *widget)
Removes a widget.
void add(gcn::Widget *widget)
Adds a new widget.
gcn::FocusHandler * m_focushandler
virtual void setControlPressed(bool pressed)
Definition: ec_keyevent.h:77
virtual void setAltPressed(bool pressed)
void releaseFont(GuiFont *font)
Releases given font.
virtual void setShiftPressed(bool pressed)
Definition: ec_keyevent.h:81
void init(const std::string &backend, int32_t screenWidth, int32_t screenHeight)
Inits the GUI Manager.
virtual void setMetaPressed(bool pressed)
Definition: ec_keyevent.h:79
std::string m_fontglyphs
SDL True Type Font implementation of Font.
Definition: truetypefont.h:51
Represents a key or a character.
Definition: ec_key.h:41
void setX(int32_t x)
void setNumericPad(bool ispad)
Definition: ec_keyevent.h:69
void setButton(MouseButtonType type)
Definition: ec_mouseevent.h:92
virtual void setMetaPressed(bool pressed)
void setType(KeyEventType type)
Definition: ec_keyevent.h:66
GuiImageLoader * m_imgloader
Pure abstract Font interface.
Definition: ifont.h:43
Overrides Guichan Graphics to enable usage of normal fife images &amp; related facilities.
Imagefont that is able to read glyphs from single image sheet, see e.g.
Definition: subimagefont.h:44
Class for key events.
Definition: ec_keyevent.h:45
static int32_t convertGuichanKeyToFifeKey(int32_t value)
void setType(MouseEventType type)
Definition: ec_mouseevent.h:99
GUIChanManager()
Constructor.
void reLayout()
Layouts the console to match e.g.
Definition: console.cpp:90
Ingame Console.
Definition: console.h:64
unsigned int uint32_t
Definition: core.h:40
virtual bool onSdlEvent(SDL_Event &evt)
Called when an SDL event is received from SDL.
virtual ~GUIChanManager()
Destructor.
std::set< gcn::Widget * > m_widgets
std::vector< GuiFont * > m_fonts
virtual void setAltPressed(bool pressed)
Definition: ec_keyevent.h:75
Overrides Guichan Graphics to enable usage of normal fife images &amp; related facilities.
gcn::SDLInput * m_input
Overrides Guichan Graphics to enable usage of normal fife images &amp; related facilities.