FIFE  6e1afdbeda11afe9ac53e6023a4be96ef88f1dc6
fifechanmanager.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2017 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 <fifechan/sdl/sdlinput.hpp>
26 #include <fifechan/key.hpp>
27 #include <fifechan/focushandler.hpp>
28 #include <fifechan.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
36 #endif
38 #include "util/base/exception.h"
39 #include "util/log/logger.h"
40 #include "video/renderbackend.h"
44 #include "video/fonts/fontbase.h"
47 #include "eventchannel/key/key.h"
51 
52 #include "fifechanmanager.h"
53 
54 namespace FIFE {
55  static Logger _log(LM_GUI);
56 
58  m_fcn_gui(new fcn::Gui()),
59  m_focushandler(0),
60  m_fcn_topcontainer(new fcn::Container()),
61  m_imgloader(new GuiImageLoader()) ,
62  m_input(new fcn::SDLInput()),
63  m_console(0),
64  m_cursor(0),
65  m_defaultfont(0),
66  m_fonts(),
67  m_logic_executed(false),
68  m_enabled_console(true),
69  m_backend("") {
70 
71  m_fcn_gui->setInput(m_input);
72  fcn::Image::setImageLoader(m_imgloader);
73 
75  m_focushandler = m_fcn_topcontainer->_getFocusHandler();
76 
77  m_fcn_topcontainer->setOpaque(false);
78  m_fcn_topcontainer->setFocusable(false);
79  m_had_mouse = false;
80  m_had_widget = false;
81  m_lastMotionX = 0;
82  m_lastMotionY = 0;
83  }
84 
86  delete m_console;
87  delete m_fcn_topcontainer;
88  delete m_imgloader;
89  delete m_input;
90  delete m_fcn_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 FifechanManager::onSdlEvent(SDL_Event& evt) {
100  if (!m_input) {
101  FL_WARN(_log, "FifechanManager, FifechanGUI->getInput == 0 ... discarding events!");
102  return false;
103  }
104 
105  bool overWidget = m_fcn_topcontainer->getWidgetAt(m_lastMotionX, m_lastMotionY) != 0;
106 
107  switch(evt.type) {
108  case SDL_MOUSEWHEEL:
109  case SDL_MOUSEBUTTONDOWN:
110  m_had_widget = overWidget;
111  case SDL_MOUSEBUTTONUP:
112  // Always send the button up/down events to fifechan
113  m_input->pushInput(evt);
114 
115  // Button was pressed over a widget and still is over a widget
116  // so we mark the event as processed.
117  if( m_had_widget && overWidget ) {
118  return true;
119  }
120 
121  // Button wasn't pressed over a widget so we want to release focus
122  // no matter what.
123  if (!m_had_widget) {
124  m_focushandler->focusNone();
125  }
126 
127  // Button up was processed by fifechan but there was no widget under
128  // the mouse at the time. Don't mark it as processed here so the
129  // other listeners have a chance to process the event.
130  return false;
131 
132  case SDL_MOUSEMOTION:
133  m_lastMotionX = evt.motion.x;
134  m_lastMotionY = evt.motion.y;
135  if (m_fcn_topcontainer->getWidgetAt(evt.motion.x,evt.motion.y)) {
136  m_had_mouse = true;
137  m_input->pushInput(evt);
138  return true;
139  }
140  if( m_had_mouse ) {
141  // We only keep the mouse if a widget/window has requested
142  // dragging.
143  m_had_mouse = m_focushandler->getDraggedWidget() != 0;
144  m_input->pushInput(evt);
145  return true;
146  }
147  return false;
148 
149  case SDL_KEYDOWN:
150  case SDL_KEYUP:
151  if(m_focushandler->getFocused()) {
152  m_input->pushInput(evt);
153  return true;
154  }
155  return false;
156 
157  case SDL_TEXTINPUT:
158  // don't consume TEXTINPUT
159  m_input->pushInput(evt);
160  return false;
161 
162  case SDL_WINDOWEVENT:
163  // don't consume WINDOWEVENTS
164  m_input->pushInput(evt);
165  return false;
166 
167  default:
168  return false;
169  }
170  }
171 
173  if (m_backend == "SDL") {
174  static_cast<SdlGuiGraphics*>(m_gui_graphics)->updateTarget();
175  } else {
176  static_cast<OpenGLGuiGraphics*>(m_gui_graphics)->updateTarget();
177  }
178  m_fcn_topcontainer->setDimension(fcn::Rectangle(x, y, width, height));
179  invalidateFonts();
180  if (m_console) {
181  m_console->reLayout();
182  }
183  }
184 
186  return m_fcn_gui;
187  }
188 
189  void FifechanManager::add(fcn::Widget* widget) {
190  if( !m_widgets.count(widget) ) {
191  m_fcn_topcontainer->add(widget);
192  m_widgets.insert(widget);
193  }
194  }
195 
196  void FifechanManager::remove(fcn::Widget* widget) {
197  if( m_widgets.count(widget) ) {
198  m_widgets.erase(widget);
199  m_fcn_topcontainer->remove(widget);
200  }
201  }
202 
204  m_enabled_console = console;
205  }
206 
208  return m_enabled_console;
209  }
210 
211  void FifechanManager::init(const std::string& backend, int32_t screenWidth, int32_t screenHeight) {
212  if( backend == "SDL" ) {
214  }
215 #ifdef HAVE_OPENGL
216  else if (backend == "OpenGL") {
218  }
219 #endif
220  else {
221  //should never get here
222  assert(0);
223  }
224  m_backend = backend;
225 
226  m_fcn_gui->setGraphics(m_gui_graphics);
227  if (m_enabled_console) {
228  m_console = new Console();
229  }
230 
231  resizeTopContainer(0, 0, screenWidth, screenHeight);
232  }
233 
234  GuiFont* FifechanManager::createFont(const std::string& path, uint32_t size, const std::string& glyphs) {
235  std::string fontpath = path;
236  std::string fontglyphs = glyphs;
237  int32_t fontsize = size;
238 
239  // Set default settings if necessary
240  if(fontpath == "") {
241  fontpath = m_fontpath;
242  }
243  if(fontsize == 0) {
244  fontsize = m_fontsize;
245  }
246  if(fontglyphs == "") {
247  fontglyphs = m_fontglyphs;
248  }
249 
250  IFont* font = NULL;
251  GuiFont* guifont = NULL;
252  if( bfs::extension(fontpath) == ".ttf" || bfs::extension(fontpath) == ".ttc" ) {
253  font = new TrueTypeFont(fontpath, fontsize);
254  } else {
255  font = new SubImageFont(fontpath, fontglyphs);
256  }
257  guifont = new GuiFont(font);
258 
259  m_fonts.push_back(guifont);
260  return guifont;
261  }
262 
264  std::vector<GuiFont*>::iterator i = m_fonts.begin();
265  while (i != m_fonts.end()) {
266  if ((*i) == font) {
267  m_fonts.erase(i);
268  delete font;
269  return;
270  }
271  ++i;
272  }
273  }
274 
276  std::vector<GuiFont*>::iterator it = m_fonts.begin();
277  while (it != m_fonts.end()) {
278  (*it)->invalidate();
279  ++it;
280  }
281  }
282 
283  GuiFont* FifechanManager::setDefaultFont(const std::string& path, uint32_t size, const std::string& glyphs) {
284  m_fontpath = path;
285  m_fontsize = size;
286  m_fontglyphs = glyphs;
287 
289  fcn::Widget::setGlobalFont(m_defaultfont);
290  if (m_console) {
291  m_console->reLayout();
292  }
293 
294  return m_defaultfont;
295  }
296 
298  if (!m_logic_executed)
299  m_fcn_gui->logic();
300  m_logic_executed = false;
301  m_fcn_gui->draw();
302  }
303 
304  KeyEvent FifechanManager::translateKeyEvent(const fcn::KeyEvent& fcnevt) {
305  KeyEvent keyevt;
306  if(fcnevt.getType() == fcn::KeyEvent::Pressed)
307  keyevt.setType(KeyEvent::PRESSED);
308  else if(fcnevt.getType() == fcn::KeyEvent::Released)
309  keyevt.setType(KeyEvent::RELEASED);
310  else {
311  FL_WARN(_log, LMsg("FifechanManager::translateKeyEvent() - ") << "Unknown event type: " << fcnevt.getType());
312  keyevt.setType(KeyEvent::UNKNOWN);
313  }
314  keyevt.setShiftPressed(fcnevt.isShiftPressed());
315  keyevt.setControlPressed(fcnevt.isControlPressed());
316  keyevt.setAltPressed(fcnevt.isAltPressed());
317  keyevt.setMetaPressed(fcnevt.isMetaPressed());
318  keyevt.setNumericPad(fcnevt.isNumericPad());
319 
320  // Convert from fifechan keyval to FIFE keyval
321  int32_t keyval = fcnevt.getKey().getValue();
322  keyval = convertFifechanKeyToFifeKey(keyval);
323 
324  keyevt.setKey(Key(static_cast<Key::KeyType>(keyval)));
325 
326  return keyevt;
327  }
328 
329  MouseEvent FifechanManager::translateMouseEvent(const fcn::MouseEvent& fcnevt) {
330  MouseEvent mouseevt;
331  mouseevt.setShiftPressed(fcnevt.isShiftPressed());
332  mouseevt.setControlPressed(fcnevt.isControlPressed());
333  mouseevt.setAltPressed(fcnevt.isAltPressed());
334  mouseevt.setMetaPressed(fcnevt.isMetaPressed());
335  mouseevt.setX(fcnevt.getX());
336  mouseevt.setY(fcnevt.getY());
337 
338  switch(fcnevt.getType()) {
339  case fcn::MouseEvent::Pressed:
340  mouseevt.setType(MouseEvent::PRESSED);
341  break;
342  case fcn::MouseEvent::Released:
343  mouseevt.setType(MouseEvent::RELEASED);
344  break;
345  case fcn::MouseEvent::Moved:
346  mouseevt.setType(MouseEvent::MOVED);
347  break;
348  case fcn::MouseEvent::Clicked:
349  mouseevt.setType(MouseEvent::CLICKED);
350  break;
351  case fcn::MouseEvent::Entered:
352  mouseevt.setType(MouseEvent::ENTERED);
353  break;
354  case fcn::MouseEvent::Exited:
355  mouseevt.setType(MouseEvent::EXITED);
356  break;
357  case fcn::MouseEvent::Dragged:
358  mouseevt.setType(MouseEvent::DRAGGED);
359  break;
360  case fcn::MouseEvent::WheelMovedDown:
362  break;
363  case fcn::MouseEvent::WheelMovedUp:
365  break;
366  default:
368  }
369 
370  switch(fcnevt.getButton()) {
371  case fcn::MouseInput::Left:
372  mouseevt.setButton(MouseEvent::LEFT);
373  break;
374  case fcn::MouseInput::Right:
375  mouseevt.setButton(MouseEvent::RIGHT);
376  break;
377  case fcn::MouseInput::Middle:
378  mouseevt.setButton(MouseEvent::MIDDLE);
379  break;
380  case fcn::MouseInput::X1:
381  mouseevt.setButton(MouseEvent::X1);
382  break;
383  case fcn::MouseInput::X2:
384  mouseevt.setButton(MouseEvent::X2);
385  break;
386  default:
388  break;
389  }
390  return mouseevt;
391  }
392 
394  m_fcn_gui->setTabbingEnabled(tabbing);
395  }
396 
398  return m_fcn_gui->isTabbingEnabled();
399  }
400 
402 
403  switch (value) {
404  case fcn::Key::Tab:
405  value = Key::TAB;
406  break;
407  case fcn::Key::LeftAlt:
408  value = Key::LEFT_ALT;
409  break;
410  case fcn::Key::RightAlt:
411  value = Key::RIGHT_ALT;
412  break;
413  case fcn::Key::LeftShift:
414  value = Key::LEFT_SHIFT;
415  break;
416  case fcn::Key::RightShift:
417  value = Key::RIGHT_SHIFT;
418  break;
419  case fcn::Key::LeftControl:
420  value = Key::LEFT_CONTROL;
421  break;
422  case fcn::Key::RightControl:
423  value = Key::RIGHT_CONTROL;
424  break;
425  case fcn::Key::Backspace:
426  value = Key::BACKSPACE;
427  break;
428  case fcn::Key::Pause:
429  value = Key::PAUSE;
430  break;
431  case fcn::Key::Space:
432  value = Key::SPACE;
433  break;
434  case fcn::Key::Escape:
435  value = Key::ESCAPE;
436  break;
437  case fcn::Key::Delete:
438  value = Key::DELETE;
439  break;
440  case fcn::Key::Insert:
441  value = Key::INSERT;
442  break;
443  case fcn::Key::Home:
444  value = Key::HOME;
445  break;
446  case fcn::Key::End:
447  value = Key::END;
448  break;
449  case fcn::Key::PageUp:
450  value = Key::PAGE_UP;
451  break;
452  case fcn::Key::PrintScreen:
453  value = Key::PRINT_SCREEN;
454  break;
455  case fcn::Key::PageDown:
456  value = Key::PAGE_DOWN;
457  break;
458  case fcn::Key::F1:
459  value = Key::F1;
460  break;
461  case fcn::Key::F2:
462  value = Key::F2;
463  break;
464  case fcn::Key::F3:
465  value = Key::F3;
466  break;
467  case fcn::Key::F4:
468  value = Key::F4;
469  break;
470  case fcn::Key::F5:
471  value = Key::F5;
472  break;
473  case fcn::Key::F6:
474  value = Key::F6;
475  break;
476  case fcn::Key::F7:
477  value = Key::F7;
478  break;
479  case fcn::Key::F8:
480  value = Key::F8;
481  break;
482  case fcn::Key::F9:
483  value = Key::F9;
484  break;
485  case fcn::Key::F10:
486  value = Key::F10;
487  break;
488  case fcn::Key::F11:
489  value = Key::F11;
490  break;
491  case fcn::Key::F12:
492  value = Key::F12;
493  break;
494  case fcn::Key::F13:
495  value = Key::F13;
496  break;
497  case fcn::Key::F14:
498  value = Key::F14;
499  break;
500  case fcn::Key::F15:
501  value = Key::F15;
502  break;
503  case fcn::Key::NumLock:
504  value = Key::NUM_LOCK;
505  break;
506  case fcn::Key::CapsLock:
507  value = Key::CAPS_LOCK;
508  break;
509  case fcn::Key::ScrollLock:
510  value = Key::SCROLL_LOCK;
511  break;
512  case fcn::Key::LeftSuper:
513  value = Key::LEFT_SUPER;
514  break;
515  case fcn::Key::RightSuper:
516  value = Key::RIGHT_SUPER;
517  break;
518  case fcn::Key::AltGr:
519  value = Key::ALT_GR;
520  break;
521  case fcn::Key::Up:
522  value = Key::UP;
523  break;
524  case fcn::Key::Down:
525  value = Key::DOWN;
526  break;
527  case fcn::Key::Left:
528  value = Key::LEFT;
529  break;
530  case fcn::Key::Right:
531  value = Key::RIGHT;
532  break;
533  case fcn::Key::Enter:
534  value = Key::ENTER;
535  break;
536 
537  default:
538  // Convert from unicode to lowercase letters
539  if (value >= 1 && value <= 26) {
540  // Control characters
541  value = value - 1 + 'a';
542  } else if (value >= 'A' && value <= 'Z') {
543  value = value - 'A' + 'a';
544  }
545 
546  // FIXME: Accented characters (รก) will not get converted properly.
547  break;
548  }
549 
550  return value;
551  }
552 }
Definition: modules.h:41
#define FL_WARN(logger, msg)
Definition: logger.h:72
KeyEvent translateKeyEvent(const fcn::KeyEvent &evt)
void add(fcn::Widget *widget)
Adds a new widget.
virtual void turn()
Performs the GUI logic and draws the GUI accordingly.
void setY(int32_t y)
Definition: mouseevent.h:119
Class for mouse events.
Definition: mouseevent.h:42
fcn::FocusHandler * m_focushandler
void setKey(const Key &key)
Definition: keyevent.h:72
Helper class to create log strings out from separate parts Usage: LMsg("some text") << variable << "...
Definition: logger.h:82
virtual void setControlPressed(bool pressed)
Sets control to pressed.
Definition: mouseevent.h:124
FifechanManager()
Constructor.
virtual void setShiftPressed(bool pressed)
Sets shift to pressed.
Definition: mouseevent.h:128
void resizeTopContainer(uint32_t x, uint32_t y, uint32_t width, uint32_t height)
Resizes the top container.
GuiFont * setDefaultFont(const std::string &path, uint32_t size, const std::string &glyphs)
Set the global font properties.
virtual ~FifechanManager()
Destructor.
static Logger _log(LM_AUDIO)
virtual bool onSdlEvent(SDL_Event &evt)
Called when an SDL event is received from SDL.
virtual void setControlPressed(bool pressed)
Sets control to pressed.
Definition: keyevent.h:77
virtual void setAltPressed(bool pressed)
Sets alt to pressed.
Definition: mouseevent.h:122
GuiFont * createFont(const std::string &path="", uint32_t size=0, const std::string &glyphs="")
Gets font with given properties.
bool isTabbingEnabled() const
Checks if tabbing is enabled.
bool isConsoleEnabled() const
Checks if the console is enabled, or not.
virtual void setShiftPressed(bool pressed)
Sets shift to pressed.
Definition: keyevent.h:81
fcn::SDLInput * m_input
virtual void setMetaPressed(bool pressed)
Sets meta to pressed.
Definition: keyevent.h:79
fcn::Container * m_fcn_topcontainer
GuiImageLoader * m_imgloader
SDL True Type Font implementation of Font.
Definition: truetypefont.h:51
std::vector< GuiFont * > m_fonts
void remove(fcn::Widget *widget)
Removes a widget.
Represents a key.
Definition: key.h:41
std::set< fcn::Widget * > m_widgets
void releaseFont(GuiFont *font)
Releases given font.
void setX(int32_t x)
Definition: mouseevent.h:111
void setNumericPad(bool ispad)
Definition: keyevent.h:69
void setButton(MouseButtonType type)
Definition: mouseevent.h:96
virtual void setMetaPressed(bool pressed)
Sets meta to pressed.
Definition: mouseevent.h:126
fcn::Graphics * m_gui_graphics
void setType(KeyEventType type)
Definition: keyevent.h:66
void init(const std::string &backend, int32_t screenWidth, int32_t screenHeight)
Inits the Fifechan GUI Manager.
Pure abstract Font interface.
Definition: ifont.h:43
Overrides Fifechan Graphics to enable usage of normal fife images & related facilities.
void setConsoleEnabled(bool console)
Enables the console, or not.
Imagefont that is able to read glyphs from single image sheet, see e.g.
Definition: subimagefont.h:44
Class for key events.
Definition: keyevent.h:45
MouseEvent translateMouseEvent(const fcn::MouseEvent &evt)
static int32_t convertFifechanKeyToFifeKey(int32_t value)
void setType(MouseEventType type)
Definition: mouseevent.h:103
void reLayout()
Layouts the console to match e.g.
Definition: console.cpp:88
Ingame Console.
Definition: console.h:64
unsigned int uint32_t
Definition: core.h:40
virtual void setAltPressed(bool pressed)
Sets alt to pressed.
Definition: keyevent.h:75
fcn::Gui * getFifechanGUI() const
Gets the member pointer to the Fifechan GUI.
void setTabbingEnabled(bool tabbing)
Sets tabbing enabled, or not.
Overrides Fifechan Graphics to enable usage of normal fife images & related facilities.