FIFE 2008.0
|
00001 /*************************************************************************** 00002 * Copyright (C) 2005-2008 by the FIFE team * 00003 * http://www.fifengine.de * 00004 * This file is part of FIFE. * 00005 * * 00006 * FIFE is free software; you can redistribute it and/or * 00007 * modify it under the terms of the GNU Lesser General Public * 00008 * License as published by the Free Software Foundation; either * 00009 * version 2.1 of the License, or (at your option) any later version. * 00010 * * 00011 * This library is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00014 * Lesser General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU Lesser General Public * 00017 * License along with this library; if not, write to the * 00018 * Free Software Foundation, Inc., * 00019 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * 00020 ***************************************************************************/ 00021 00022 // Standard C++ library includes 00023 #include <iostream> 00024 00025 // 3rd party library includes 00026 #include <boost/filesystem/convenience.hpp> 00027 #include <guichan/sdl/sdlinput.hpp> 00028 #include <guichan/key.hpp> 00029 #include <guichan/focushandler.hpp> 00030 #include <guichan.hpp> 00031 00032 // FIFE includes 00033 // These includes are split up in two parts, separated by one empty line 00034 // First block: files included from the FIFE root src directory 00035 // Second block: files included from the same folder 00036 #include "util/base/exception.h" 00037 #include "util/log/logger.h" 00038 #include "video/renderbackend.h" 00039 #include "gui/base/gui_imageloader.h" 00040 #include "gui/base/gui_font.h" 00041 #include "gui/console/console.h" 00042 #include "video/fonts/fontbase.h" 00043 #include "video/fonts/truetypefont.h" 00044 #include "video/fonts/subimagefont.h" 00045 #include "eventchannel/key/ec_key.h" 00046 #include "eventchannel/key/ec_keyevent.h" 00047 #include "eventchannel/mouse/ec_mouseevent.h" 00048 00049 #include "guimanager.h" 00050 00051 00052 namespace FIFE { 00053 static Logger _log(LM_GUI); 00054 00055 GUIManager::GUIManager(ImagePool& pool) : 00056 m_gcn_gui(new gcn::Gui()), 00057 m_focushandler(0), 00058 m_gcn_topcontainer(new gcn::Container()), 00059 m_imgloader(new GuiImageLoader(pool)) , 00060 m_input(new gcn::SDLInput()), 00061 m_console(0), 00062 m_fonts(), 00063 m_pool(pool), 00064 m_logic_executed(false) { 00065 00066 m_gcn_gui->setInput(m_input); 00067 gcn::Image::setImageLoader(m_imgloader); 00068 00069 m_gcn_gui->setTop(m_gcn_topcontainer); 00070 m_focushandler = m_gcn_topcontainer->_getFocusHandler(); 00071 00072 m_gcn_topcontainer->setOpaque(false); 00073 m_gcn_topcontainer->setFocusable(false); 00074 m_had_mouse = false; 00075 } 00076 00077 GUIManager::~GUIManager() { 00078 delete m_console; 00079 delete m_gcn_topcontainer; 00080 delete m_imgloader; 00081 delete m_input; 00082 delete m_gcn_gui; 00083 std::vector<GuiFont*>::iterator i = m_fonts.begin(); 00084 while (i != m_fonts.end()) { 00085 delete *i; 00086 ++i; 00087 } 00088 } 00089 00090 bool GUIManager::onSdlEvent(SDL_Event& evt) { 00091 if (!m_input) { 00092 FL_WARN(_log, "GUIManager, GuichanGUI->getInput == 0 ... discarding events!"); 00093 return false; 00094 } 00095 00096 switch(evt.type) { 00097 case SDL_MOUSEBUTTONDOWN: 00098 case SDL_MOUSEBUTTONUP: 00099 if( m_gcn_topcontainer->getWidgetAt(evt.button.x,evt.button.y) ) { 00100 m_input->pushInput(evt); 00101 return true; 00102 } 00103 m_focushandler->focusNone(); 00104 return false; 00105 00106 case SDL_MOUSEMOTION: 00107 if( m_gcn_topcontainer->getWidgetAt(evt.button.x,evt.button.y) ) { 00108 m_had_mouse = true; 00109 m_input->pushInput(evt); 00110 return true; 00111 } 00112 if( m_had_mouse ) { 00113 // We only keep the mouse if a widget/window has requested 00114 // dragging. 00115 m_had_mouse = bool(m_focushandler->getDraggedWidget()); 00116 m_input->pushInput(evt); 00117 return true; 00118 } 00119 return false; 00120 00121 case SDL_KEYDOWN: 00122 case SDL_KEYUP: 00123 if(m_focushandler->getFocused()) { 00124 m_input->pushInput(evt); 00125 return true; 00126 } 00127 return false; 00128 00129 case SDL_ACTIVEEVENT: 00130 // Actually Guichan doesn't care (it should!) 00131 // so at least don't swallow mouse_focus events up. 00132 return false; 00133 00134 default: 00135 return false; 00136 } 00137 } 00138 00139 void GUIManager::resizeTopContainer(unsigned int x, unsigned int y, unsigned int width, unsigned int height) { 00140 m_gcn_topcontainer->setDimension(gcn::Rectangle(x, y, width, height)); 00141 } 00142 00143 gcn::Gui* GUIManager::getGuichanGUI() const { 00144 return m_gcn_gui; 00145 } 00146 00147 void GUIManager::add(gcn::Widget* widget) { 00148 if( !m_widgets.count(widget) ) { 00149 m_gcn_topcontainer->add(widget); 00150 m_widgets.insert(widget); 00151 } 00152 } 00153 00154 void GUIManager::remove(gcn::Widget* widget) { 00155 if( m_widgets.count(widget) ) { 00156 m_widgets.erase(widget); 00157 m_gcn_topcontainer->remove(widget); 00158 } 00159 } 00160 00161 void GUIManager::init(gcn::Graphics* graphics, int screenWidth, int screenHeight) { 00162 m_gcn_gui->setGraphics(graphics); 00163 resizeTopContainer(0, 0, screenWidth, screenHeight); 00164 m_console = new Console(); 00165 } 00166 00167 GuiFont* GUIManager::createFont(const std::string& path, unsigned int size, const std::string& glyphs) { 00168 std::string fontpath = path; 00169 std::string fontglyphs = glyphs; 00170 int fontsize = size; 00171 00172 // Set default settings if necessary 00173 if(fontpath == "") { 00174 fontpath = m_fontpath; 00175 } 00176 if(fontsize == 0) { 00177 fontsize = m_fontsize; 00178 } 00179 if(fontglyphs == "") { 00180 fontglyphs = m_fontglyphs; 00181 } 00182 00183 AbstractFont* font = NULL; 00184 GuiFont* guifont = NULL; 00185 if( boost::filesystem::extension(fontpath) == ".ttf" ) { 00186 font = new TrueTypeFont(fontpath, fontsize); 00187 } else { 00188 font = new SubImageFont(fontpath, fontglyphs, m_pool); 00189 } 00190 guifont = new GuiFont(font); 00191 00192 m_fonts.push_back(guifont); 00193 return guifont; 00194 } 00195 00196 void GUIManager::releaseFont(GuiFont* font) { 00197 std::vector<GuiFont*>::iterator i = m_fonts.begin(); 00198 while (i != m_fonts.end()) { 00199 if ((*i) == font) { 00200 m_fonts.erase(i); 00201 delete font; 00202 return; 00203 } 00204 ++i; 00205 } 00206 } 00207 00208 void GUIManager::invalidateFonts() { 00209 std::vector<GuiFont*>::iterator it = m_fonts.begin(); 00210 while (it != m_fonts.end()) { 00211 (*it)->invalidate(); 00212 ++it; 00213 } 00214 } 00215 00216 GuiFont* GUIManager::setDefaultFont(const std::string& path, unsigned int size, const std::string& glyphs) { 00217 m_fontpath = path; 00218 m_fontsize = size; 00219 m_fontglyphs = glyphs; 00220 00221 GuiFont* defaultfont = createFont(); 00222 gcn::Widget::setGlobalFont(defaultfont); 00223 if (m_console) { 00224 m_console->reLayout(); 00225 } 00226 00227 return defaultfont; 00228 } 00229 00230 void GUIManager::turn() { 00231 if (!m_logic_executed) 00232 m_gcn_gui->logic(); 00233 m_logic_executed = false; 00234 m_gcn_gui->draw(); 00235 } 00236 00237 KeyEvent GUIManager::translateKeyEvent(const gcn::KeyEvent& gcnevt) { 00238 KeyEvent keyevt; 00239 if(gcnevt.getType() == gcn::KeyEvent::PRESSED) 00240 keyevt.setType(KeyEvent::PRESSED); 00241 else if(gcnevt.getType() == gcn::KeyEvent::RELEASED) 00242 keyevt.setType(KeyEvent::RELEASED); 00243 else 00244 throw EventException("Invalid event type in fillKeyEvent"); 00245 keyevt.setShiftPressed(gcnevt.isShiftPressed()); 00246 keyevt.setControlPressed(gcnevt.isControlPressed()); 00247 keyevt.setAltPressed(gcnevt.isAltPressed()); 00248 keyevt.setMetaPressed(gcnevt.isMetaPressed()); 00249 keyevt.setNumericPad(gcnevt.isNumericPad()); 00250 00251 // Convert from guichan keyval to FIFE keyval 00252 int keyval = gcnevt.getKey().getValue(); 00253 keyval = convertGuichanKeyToFifeKey(keyval); 00254 00255 keyevt.setKey(Key(static_cast<Key::KeyType>(keyval), keyval)); 00256 00257 return keyevt; 00258 } 00259 00260 MouseEvent GUIManager::translateMouseEvent(const gcn::MouseEvent& gcnevt) { 00261 MouseEvent mouseevt; 00262 mouseevt.setShiftPressed(gcnevt.isShiftPressed()); 00263 mouseevt.setControlPressed(gcnevt.isControlPressed()); 00264 mouseevt.setAltPressed(gcnevt.isAltPressed()); 00265 mouseevt.setMetaPressed(gcnevt.isMetaPressed()); 00266 mouseevt.setX(gcnevt.getX()); 00267 mouseevt.setY(gcnevt.getY()); 00268 00269 switch(gcnevt.getType()) { 00270 case gcn::MouseEvent::PRESSED: 00271 mouseevt.setType(MouseEvent::PRESSED); 00272 break; 00273 case gcn::MouseEvent::RELEASED: 00274 mouseevt.setType(MouseEvent::RELEASED); 00275 break; 00276 case gcn::MouseEvent::MOVED: 00277 mouseevt.setType(MouseEvent::MOVED); 00278 break; 00279 case gcn::MouseEvent::CLICKED: 00280 mouseevt.setType(MouseEvent::CLICKED); 00281 break; 00282 case gcn::MouseEvent::ENTERED: 00283 mouseevt.setType(MouseEvent::ENTERED); 00284 break; 00285 case gcn::MouseEvent::EXITED: 00286 mouseevt.setType(MouseEvent::EXITED); 00287 break; 00288 case gcn::MouseEvent::DRAGGED: 00289 mouseevt.setType(MouseEvent::DRAGGED); 00290 break; 00291 case gcn::MouseEvent::WHEEL_MOVED_DOWN: 00292 mouseevt.setType(MouseEvent::WHEEL_MOVED_DOWN); 00293 break; 00294 case gcn::MouseEvent::WHEEL_MOVED_UP: 00295 mouseevt.setType(MouseEvent::WHEEL_MOVED_UP); 00296 break; 00297 default: 00298 mouseevt.setType(MouseEvent::UNKNOWN_EVENT); 00299 } 00300 00301 switch(gcnevt.getButton()) { 00302 case gcn::MouseInput::LEFT: 00303 mouseevt.setButton(MouseEvent::LEFT); 00304 break; 00305 case gcn::MouseInput::RIGHT: 00306 mouseevt.setButton(MouseEvent::RIGHT); 00307 break; 00308 case gcn::MouseInput::MIDDLE: 00309 mouseevt.setButton(MouseEvent::MIDDLE); 00310 break; 00311 default: 00312 mouseevt.setButton(MouseEvent::UNKNOWN_BUTTON); 00313 break; 00314 } 00315 return mouseevt; 00316 } 00317 00318 00319 int GUIManager::convertGuichanKeyToFifeKey(int value) { 00320 00321 switch (value) { 00322 case gcn::Key::TAB: 00323 value = Key::TAB; 00324 break; 00325 case gcn::Key::LEFT_ALT: 00326 value = Key::LEFT_ALT; 00327 break; 00328 case gcn::Key::RIGHT_ALT: 00329 value = Key::RIGHT_ALT; 00330 break; 00331 case gcn::Key::LEFT_SHIFT: 00332 value = Key::LEFT_SHIFT; 00333 break; 00334 case gcn::Key::RIGHT_SHIFT: 00335 value = Key::RIGHT_SHIFT; 00336 break; 00337 case gcn::Key::LEFT_CONTROL: 00338 value = Key::LEFT_CONTROL; 00339 break; 00340 case gcn::Key::RIGHT_CONTROL: 00341 value = Key::RIGHT_CONTROL; 00342 break; 00343 case gcn::Key::BACKSPACE: 00344 value = Key::BACKSPACE; 00345 break; 00346 case gcn::Key::PAUSE: 00347 value = Key::PAUSE; 00348 break; 00349 case gcn::Key::SPACE: 00350 value = Key::SPACE; 00351 break; 00352 case gcn::Key::ESCAPE: 00353 value = Key::ESCAPE; 00354 break; 00355 case gcn::Key::DELETE: 00356 value = Key::DELETE; 00357 break; 00358 case gcn::Key::INSERT: 00359 value = Key::INSERT; 00360 break; 00361 case gcn::Key::HOME: 00362 value = Key::HOME; 00363 break; 00364 case gcn::Key::END: 00365 value = Key::END; 00366 break; 00367 case gcn::Key::PAGE_UP: 00368 value = Key::PAGE_UP; 00369 break; 00370 case gcn::Key::PRINT_SCREEN: 00371 value = Key::PRINT_SCREEN; 00372 break; 00373 case gcn::Key::PAGE_DOWN: 00374 value = Key::PAGE_DOWN; 00375 break; 00376 case gcn::Key::F1: 00377 value = Key::F1; 00378 break; 00379 case gcn::Key::F2: 00380 value = Key::F2; 00381 break; 00382 case gcn::Key::F3: 00383 value = Key::F3; 00384 break; 00385 case gcn::Key::F4: 00386 value = Key::F4; 00387 break; 00388 case gcn::Key::F5: 00389 value = Key::F5; 00390 break; 00391 case gcn::Key::F6: 00392 value = Key::F6; 00393 break; 00394 case gcn::Key::F7: 00395 value = Key::F7; 00396 break; 00397 case gcn::Key::F8: 00398 value = Key::F8; 00399 break; 00400 case gcn::Key::F9: 00401 value = Key::F9; 00402 break; 00403 case gcn::Key::F10: 00404 value = Key::F10; 00405 break; 00406 case gcn::Key::F11: 00407 value = Key::F11; 00408 break; 00409 case gcn::Key::F12: 00410 value = Key::F12; 00411 break; 00412 case gcn::Key::F13: 00413 value = Key::F13; 00414 break; 00415 case gcn::Key::F14: 00416 value = Key::F14; 00417 break; 00418 case gcn::Key::F15: 00419 value = Key::F15; 00420 break; 00421 case gcn::Key::NUM_LOCK: 00422 value = Key::NUM_LOCK; 00423 break; 00424 case gcn::Key::CAPS_LOCK: 00425 value = Key::CAPS_LOCK; 00426 break; 00427 case gcn::Key::SCROLL_LOCK: 00428 value = Key::SCROLL_LOCK; 00429 break; 00430 case gcn::Key::RIGHT_META: 00431 value = Key::RIGHT_META; 00432 break; 00433 case gcn::Key::LEFT_META: 00434 value = Key::LEFT_META; 00435 break; 00436 case gcn::Key::LEFT_SUPER: 00437 value = Key::LEFT_SUPER; 00438 break; 00439 case gcn::Key::RIGHT_SUPER: 00440 value = Key::RIGHT_SUPER; 00441 break; 00442 case gcn::Key::ALT_GR: 00443 value = Key::ALT_GR; 00444 break; 00445 case gcn::Key::UP: 00446 value = Key::UP; 00447 break; 00448 case gcn::Key::DOWN: 00449 value = Key::DOWN; 00450 break; 00451 case gcn::Key::LEFT: 00452 value = Key::LEFT; 00453 break; 00454 case gcn::Key::RIGHT: 00455 value = Key::RIGHT; 00456 break; 00457 case gcn::Key::ENTER: 00458 value = Key::ENTER; 00459 break; 00460 00461 default: 00462 // Convert from unicode to lowercase letters 00463 if (value >= 1 && value <= 26) { 00464 // Control characters 00465 value = value - 1 + 'a'; 00466 } else if (value >= 'A' && value <= 'Z') { 00467 value = value - 'A' + 'a'; 00468 } 00469 00470 // FIXME: Accented characters (รก) will not get converted properly. 00471 break; 00472 } 00473 00474 return value; 00475 } 00476 }