00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <guichan/sdl/sdlinput.hpp>
00026 #include <guichan/key.hpp>
00027 #include <guichan/focushandler.hpp>
00028 #include <guichan.hpp>
00029
00030
00031
00032
00033
00034 #ifdef HAVE_OPENGL
00035 #include "gui/guichan/base/opengl/opengl_gui_graphics.h"
00036 #include "gui/guichan/base/opengle/opengle_gui_graphics.h"
00037 #endif
00038 #include "gui/guichan/base/sdl/sdl_gui_graphics.h"
00039 #include "util/base/exception.h"
00040 #include "util/log/logger.h"
00041 #include "video/renderbackend.h"
00042 #include "gui/guichan/base/gui_imageloader.h"
00043 #include "gui/guichan/base/gui_font.h"
00044 #include "gui/guichan/console/console.h"
00045 #include "video/fonts/fontbase.h"
00046 #include "video/fonts/truetypefont.h"
00047 #include "video/fonts/subimagefont.h"
00048 #include "eventchannel/key/ec_key.h"
00049 #include "eventchannel/key/ec_keyevent.h"
00050 #include "eventchannel/mouse/ec_mouseevent.h"
00051 #include "vfs/fife_boost_filesystem.h"
00052
00053 #include "guichanmanager.h"
00054
00055 namespace FIFE {
00056 static Logger _log(LM_GUI);
00057
00058 GUIChanManager::GUIChanManager() :
00059 m_gcn_gui(new gcn::Gui()),
00060 m_focushandler(0),
00061 m_gcn_topcontainer(new gcn::Container()),
00062 m_imgloader(new GuiImageLoader()) ,
00063 m_input(new gcn::SDLInput()),
00064 m_console(0),
00065 m_defaultfont(0),
00066 m_fonts(),
00067 m_logic_executed(false) {
00068
00069 m_gcn_gui->setInput(m_input);
00070 gcn::Image::setImageLoader(m_imgloader);
00071
00072 m_gcn_gui->setTop(m_gcn_topcontainer);
00073 m_focushandler = m_gcn_topcontainer->_getFocusHandler();
00074
00075 m_gcn_topcontainer->setOpaque(false);
00076 m_gcn_topcontainer->setFocusable(false);
00077 m_had_mouse = false;
00078 m_had_widget = false;
00079 }
00080
00081 GUIChanManager::~GUIChanManager() {
00082 delete m_console;
00083 delete m_gcn_topcontainer;
00084 delete m_imgloader;
00085 delete m_input;
00086 delete m_gcn_gui;
00087 delete m_gui_graphics;
00088 std::vector<GuiFont*>::iterator i = m_fonts.begin();
00089 while (i != m_fonts.end()) {
00090 delete *i;
00091 ++i;
00092 }
00093 }
00094
00095 bool GUIChanManager::onSdlEvent(SDL_Event& evt) {
00096 if (!m_input) {
00097 FL_WARN(_log, "GUIChanManager, GuichanGUI->getInput == 0 ... discarding events!");
00098 return false;
00099 }
00100
00101 bool overWidget = m_gcn_topcontainer->getWidgetAt(evt.button.x,evt.button.y) != 0;
00102
00103 switch(evt.type) {
00104 case SDL_MOUSEBUTTONDOWN:
00105 m_had_widget = overWidget;
00106 case SDL_MOUSEBUTTONUP:
00107
00108 m_input->pushInput(evt);
00109
00110
00111
00112 if( m_had_widget && overWidget ) {
00113 return true;
00114 }
00115
00116
00117
00118 if (!m_had_widget) {
00119 m_focushandler->focusNone();
00120 }
00121
00122
00123
00124
00125 return false;
00126
00127 case SDL_MOUSEMOTION:
00128 if( m_gcn_topcontainer->getWidgetAt(evt.button.x,evt.button.y) ) {
00129 m_had_mouse = true;
00130 m_input->pushInput(evt);
00131 return true;
00132 }
00133 if( m_had_mouse ) {
00134
00135
00136 m_had_mouse = m_focushandler->getDraggedWidget() != 0;
00137 m_input->pushInput(evt);
00138 return true;
00139 }
00140 return false;
00141
00142 case SDL_KEYDOWN:
00143 case SDL_KEYUP:
00144 if(m_focushandler->getFocused()) {
00145 m_input->pushInput(evt);
00146 return true;
00147 }
00148 return false;
00149
00150 case SDL_ACTIVEEVENT:
00151
00152
00153 return false;
00154
00155 default:
00156 return false;
00157 }
00158 }
00159
00160 void GUIChanManager::resizeTopContainer(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
00161 m_gcn_topcontainer->setDimension(gcn::Rectangle(x, y, width, height));
00162 this->invalidateFonts();
00163 this->m_console->reLayout();
00164 }
00165
00166 gcn::Gui* GUIChanManager::getGuichanGUI() const {
00167 return m_gcn_gui;
00168 }
00169
00170 void GUIChanManager::add(gcn::Widget* widget) {
00171 if( !m_widgets.count(widget) ) {
00172 m_gcn_topcontainer->add(widget);
00173 m_widgets.insert(widget);
00174 }
00175 }
00176
00177 void GUIChanManager::remove(gcn::Widget* widget) {
00178 if( m_widgets.count(widget) ) {
00179 m_widgets.erase(widget);
00180 m_gcn_topcontainer->remove(widget);
00181 }
00182 }
00183
00184 void GUIChanManager::init(const std::string& backend, int32_t screenWidth, int32_t screenHeight) {
00185 if( backend == "SDL" ) {
00186 m_gui_graphics = new SdlGuiGraphics();
00187 }
00188 #ifdef HAVE_OPENGL
00189 else if (backend == "OpenGL") {
00190 m_gui_graphics = new OpenGLGuiGraphics();
00191 }
00192 else if (backend == "OpenGLe") {
00193 m_gui_graphics = new OpenGLeGuiGraphics();
00194 }
00195 #endif
00196 else {
00197
00198 assert(0);
00199 }
00200
00201 m_gcn_gui->setGraphics(m_gui_graphics);
00202 m_console = new Console();
00203
00204 resizeTopContainer(0, 0, screenWidth, screenHeight);
00205 }
00206
00207 GuiFont* GUIChanManager::createFont(const std::string& path, uint32_t size, const std::string& glyphs) {
00208 std::string fontpath = path;
00209 std::string fontglyphs = glyphs;
00210 int32_t fontsize = size;
00211
00212
00213 if(fontpath == "") {
00214 fontpath = m_fontpath;
00215 }
00216 if(fontsize == 0) {
00217 fontsize = m_fontsize;
00218 }
00219 if(fontglyphs == "") {
00220 fontglyphs = m_fontglyphs;
00221 }
00222
00223 IFont* font = NULL;
00224 GuiFont* guifont = NULL;
00225 if( bfs::extension(fontpath) == ".ttf" || bfs::extension(fontpath) == ".ttc" ) {
00226 font = new TrueTypeFont(fontpath, fontsize);
00227 } else {
00228 font = new SubImageFont(fontpath, fontglyphs);
00229 }
00230 guifont = new GuiFont(font);
00231
00232 m_fonts.push_back(guifont);
00233 return guifont;
00234 }
00235
00236 void GUIChanManager::releaseFont(GuiFont* font) {
00237 std::vector<GuiFont*>::iterator i = m_fonts.begin();
00238 while (i != m_fonts.end()) {
00239 if ((*i) == font) {
00240 m_fonts.erase(i);
00241 delete font;
00242 return;
00243 }
00244 ++i;
00245 }
00246 }
00247
00248 void GUIChanManager::invalidateFonts() {
00249 std::vector<GuiFont*>::iterator it = m_fonts.begin();
00250 while (it != m_fonts.end()) {
00251 (*it)->invalidate();
00252 ++it;
00253 }
00254 }
00255
00256 GuiFont* GUIChanManager::setDefaultFont(const std::string& path, uint32_t size, const std::string& glyphs) {
00257 m_fontpath = path;
00258 m_fontsize = size;
00259 m_fontglyphs = glyphs;
00260
00261 m_defaultfont = createFont();
00262 gcn::Widget::setGlobalFont(m_defaultfont);
00263 if (m_console) {
00264 m_console->reLayout();
00265 }
00266
00267 return m_defaultfont;
00268 }
00269
00270 void GUIChanManager::turn() {
00271 if (!m_logic_executed)
00272 m_gcn_gui->logic();
00273 m_logic_executed = false;
00274 m_gcn_gui->draw();
00275 }
00276
00277 KeyEvent GUIChanManager::translateKeyEvent(const gcn::KeyEvent& gcnevt) {
00278 KeyEvent keyevt;
00279 if(gcnevt.getType() == gcn::KeyEvent::PRESSED)
00280 keyevt.setType(KeyEvent::PRESSED);
00281 else if(gcnevt.getType() == gcn::KeyEvent::RELEASED)
00282 keyevt.setType(KeyEvent::RELEASED);
00283 else {
00284 FL_WARN(_log, LMsg("GUIChanManager::translateKeyEvent() - ") << "Unknown event type: " << gcnevt.getType());
00285 keyevt.setType(KeyEvent::UNKNOWN);
00286 }
00287 keyevt.setShiftPressed(gcnevt.isShiftPressed());
00288 keyevt.setControlPressed(gcnevt.isControlPressed());
00289 keyevt.setAltPressed(gcnevt.isAltPressed());
00290 keyevt.setMetaPressed(gcnevt.isMetaPressed());
00291 keyevt.setNumericPad(gcnevt.isNumericPad());
00292
00293
00294 int32_t keyval = gcnevt.getKey().getValue();
00295 keyval = convertGuichanKeyToFifeKey(keyval);
00296
00297 keyevt.setKey(Key(static_cast<Key::KeyType>(keyval), keyval));
00298
00299 return keyevt;
00300 }
00301
00302 MouseEvent GUIChanManager::translateMouseEvent(const gcn::MouseEvent& gcnevt) {
00303 MouseEvent mouseevt;
00304 mouseevt.setShiftPressed(gcnevt.isShiftPressed());
00305 mouseevt.setControlPressed(gcnevt.isControlPressed());
00306 mouseevt.setAltPressed(gcnevt.isAltPressed());
00307 mouseevt.setMetaPressed(gcnevt.isMetaPressed());
00308 mouseevt.setX(gcnevt.getX());
00309 mouseevt.setY(gcnevt.getY());
00310
00311 switch(gcnevt.getType()) {
00312 case gcn::MouseEvent::PRESSED:
00313 mouseevt.setType(MouseEvent::PRESSED);
00314 break;
00315 case gcn::MouseEvent::RELEASED:
00316 mouseevt.setType(MouseEvent::RELEASED);
00317 break;
00318 case gcn::MouseEvent::MOVED:
00319 mouseevt.setType(MouseEvent::MOVED);
00320 break;
00321 case gcn::MouseEvent::CLICKED:
00322 mouseevt.setType(MouseEvent::CLICKED);
00323 break;
00324 case gcn::MouseEvent::ENTERED:
00325 mouseevt.setType(MouseEvent::ENTERED);
00326 break;
00327 case gcn::MouseEvent::EXITED:
00328 mouseevt.setType(MouseEvent::EXITED);
00329 break;
00330 case gcn::MouseEvent::DRAGGED:
00331 mouseevt.setType(MouseEvent::DRAGGED);
00332 break;
00333 case gcn::MouseEvent::WHEEL_MOVED_DOWN:
00334 mouseevt.setType(MouseEvent::WHEEL_MOVED_DOWN);
00335 break;
00336 case gcn::MouseEvent::WHEEL_MOVED_UP:
00337 mouseevt.setType(MouseEvent::WHEEL_MOVED_UP);
00338 break;
00339 default:
00340 mouseevt.setType(MouseEvent::UNKNOWN_EVENT);
00341 }
00342
00343 switch(gcnevt.getButton()) {
00344 case gcn::MouseInput::LEFT:
00345 mouseevt.setButton(MouseEvent::LEFT);
00346 break;
00347 case gcn::MouseInput::RIGHT:
00348 mouseevt.setButton(MouseEvent::RIGHT);
00349 break;
00350 case gcn::MouseInput::MIDDLE:
00351 mouseevt.setButton(MouseEvent::MIDDLE);
00352 break;
00353 default:
00354 mouseevt.setButton(MouseEvent::UNKNOWN_BUTTON);
00355 break;
00356 }
00357 return mouseevt;
00358 }
00359
00360
00361 int32_t GUIChanManager::convertGuichanKeyToFifeKey(int32_t value) {
00362
00363 switch (value) {
00364 case gcn::Key::TAB:
00365 value = Key::TAB;
00366 break;
00367 case gcn::Key::LEFT_ALT:
00368 value = Key::LEFT_ALT;
00369 break;
00370 case gcn::Key::RIGHT_ALT:
00371 value = Key::RIGHT_ALT;
00372 break;
00373 case gcn::Key::LEFT_SHIFT:
00374 value = Key::LEFT_SHIFT;
00375 break;
00376 case gcn::Key::RIGHT_SHIFT:
00377 value = Key::RIGHT_SHIFT;
00378 break;
00379 case gcn::Key::LEFT_CONTROL:
00380 value = Key::LEFT_CONTROL;
00381 break;
00382 case gcn::Key::RIGHT_CONTROL:
00383 value = Key::RIGHT_CONTROL;
00384 break;
00385 case gcn::Key::BACKSPACE:
00386 value = Key::BACKSPACE;
00387 break;
00388 case gcn::Key::PAUSE:
00389 value = Key::PAUSE;
00390 break;
00391 case gcn::Key::SPACE:
00392 value = Key::SPACE;
00393 break;
00394 case gcn::Key::ESCAPE:
00395 value = Key::ESCAPE;
00396 break;
00397 case gcn::Key::DELETE:
00398 value = Key::DELETE;
00399 break;
00400 case gcn::Key::INSERT:
00401 value = Key::INSERT;
00402 break;
00403 case gcn::Key::HOME:
00404 value = Key::HOME;
00405 break;
00406 case gcn::Key::END:
00407 value = Key::END;
00408 break;
00409 case gcn::Key::PAGE_UP:
00410 value = Key::PAGE_UP;
00411 break;
00412 case gcn::Key::PRINT_SCREEN:
00413 value = Key::PRINT_SCREEN;
00414 break;
00415 case gcn::Key::PAGE_DOWN:
00416 value = Key::PAGE_DOWN;
00417 break;
00418 case gcn::Key::F1:
00419 value = Key::F1;
00420 break;
00421 case gcn::Key::F2:
00422 value = Key::F2;
00423 break;
00424 case gcn::Key::F3:
00425 value = Key::F3;
00426 break;
00427 case gcn::Key::F4:
00428 value = Key::F4;
00429 break;
00430 case gcn::Key::F5:
00431 value = Key::F5;
00432 break;
00433 case gcn::Key::F6:
00434 value = Key::F6;
00435 break;
00436 case gcn::Key::F7:
00437 value = Key::F7;
00438 break;
00439 case gcn::Key::F8:
00440 value = Key::F8;
00441 break;
00442 case gcn::Key::F9:
00443 value = Key::F9;
00444 break;
00445 case gcn::Key::F10:
00446 value = Key::F10;
00447 break;
00448 case gcn::Key::F11:
00449 value = Key::F11;
00450 break;
00451 case gcn::Key::F12:
00452 value = Key::F12;
00453 break;
00454 case gcn::Key::F13:
00455 value = Key::F13;
00456 break;
00457 case gcn::Key::F14:
00458 value = Key::F14;
00459 break;
00460 case gcn::Key::F15:
00461 value = Key::F15;
00462 break;
00463 case gcn::Key::NUM_LOCK:
00464 value = Key::NUM_LOCK;
00465 break;
00466 case gcn::Key::CAPS_LOCK:
00467 value = Key::CAPS_LOCK;
00468 break;
00469 case gcn::Key::SCROLL_LOCK:
00470 value = Key::SCROLL_LOCK;
00471 break;
00472 case gcn::Key::RIGHT_META:
00473 value = Key::RIGHT_META;
00474 break;
00475 case gcn::Key::LEFT_META:
00476 value = Key::LEFT_META;
00477 break;
00478 case gcn::Key::LEFT_SUPER:
00479 value = Key::LEFT_SUPER;
00480 break;
00481 case gcn::Key::RIGHT_SUPER:
00482 value = Key::RIGHT_SUPER;
00483 break;
00484 case gcn::Key::ALT_GR:
00485 value = Key::ALT_GR;
00486 break;
00487 case gcn::Key::UP:
00488 value = Key::UP;
00489 break;
00490 case gcn::Key::DOWN:
00491 value = Key::DOWN;
00492 break;
00493 case gcn::Key::LEFT:
00494 value = Key::LEFT;
00495 break;
00496 case gcn::Key::RIGHT:
00497 value = Key::RIGHT;
00498 break;
00499 case gcn::Key::ENTER:
00500 value = Key::ENTER;
00501 break;
00502
00503 default:
00504
00505 if (value >= 1 && value <= 26) {
00506
00507 value = value - 1 + 'a';
00508 } else if (value >= 'A' && value <= 'Z') {
00509 value = value - 'A' + 'a';
00510 }
00511
00512
00513 break;
00514 }
00515
00516 return value;
00517 }
00518 }