guimanager.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <iostream>
00024
00025
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
00033
00034
00035
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
00114
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
00131
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
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
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
00463 if (value >= 1 && value <= 26) {
00464
00465 value = value - 1 + 'a';
00466 } else if (value >= 'A' && value <= 'Z') {
00467 value = value - 'A' + 'a';
00468 }
00469
00470
00471 break;
00472 }
00473
00474 return value;
00475 }
00476 }