FIFE  be64c707dea6b3250bd4355bf5c825d25920087d
fifechanmanager.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2019 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
bool isConsoleEnabled() const
Checks if the console is enabled, or not.
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.
virtual void setShiftPressed(bool pressed)
Sets shift to pressed.
Definition: keyevent.h:81
fcn::SDLInput * m_input
bool isTabbingEnabled() const
Checks if tabbing is enabled.
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:86
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.