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 gcn::SDLInput *input = dynamic_cast<gcn::SDLInput*>(m_gcn_gui->getInput());
00092 if (!input) {
00093 FL_WARN(_log, "GUIManager, GuichanGUI->getInput == 0 ... discarding events!");
00094 return false;
00095 }
00096
00097 switch(evt.type) {
00098 case SDL_MOUSEBUTTONDOWN:
00099 case SDL_MOUSEBUTTONUP:
00100 if( m_gcn_topcontainer->getWidgetAt(evt.button.x,evt.button.y) ) {
00101 input->pushInput(evt);
00102 return true;
00103 }
00104 m_focushandler->focusNone();
00105 return false;
00106
00107 case SDL_MOUSEMOTION:
00108 if( m_gcn_topcontainer->getWidgetAt(evt.button.x,evt.button.y) ) {
00109 m_had_mouse = true;
00110 input->pushInput(evt);
00111 return true;
00112 }
00113 if( m_had_mouse ) {
00114
00115
00116 m_had_mouse = bool(m_focushandler->getDraggedWidget());
00117 input->pushInput(evt);
00118 return true;
00119 }
00120 return false;
00121
00122 case SDL_KEYDOWN:
00123 case SDL_KEYUP:
00124 if(m_focushandler->getFocused()) {
00125 input->pushInput(evt);
00126 return true;
00127 }
00128 return false;
00129
00130 case SDL_ACTIVEEVENT:
00131
00132
00133 return false;
00134
00135 default:
00136 return false;
00137 }
00138 }
00139
00140 void GUIManager::resizeTopContainer(unsigned int x, unsigned int y, unsigned int width, unsigned int height) {
00141 m_gcn_topcontainer->setDimension(gcn::Rectangle(x, y, width, height));
00142 }
00143
00144 gcn::Gui* GUIManager::getGuichanGUI() const {
00145 return m_gcn_gui;
00146 }
00147
00148 void GUIManager::add(gcn::Widget* widget) {
00149 if( !m_widgets.count(widget) ) {
00150 m_gcn_topcontainer->add(widget);
00151 m_widgets.insert(widget);
00152 }
00153 }
00154
00155 void GUIManager::remove(gcn::Widget* widget) {
00156 if( m_widgets.count(widget) ) {
00157 m_widgets.erase(widget);
00158 m_gcn_topcontainer->remove(widget);
00159 }
00160 }
00161
00162 void GUIManager::init(gcn::Graphics* graphics, int screenWidth, int screenHeight) {
00163 m_gcn_gui->setGraphics(graphics);
00164 resizeTopContainer(0, 0, screenWidth, screenHeight);
00165 m_console = new Console();
00166 }
00167
00168 GuiFont* GUIManager::createFont(const std::string& path, unsigned int size, const std::string& glyphs) {
00169 std::string fontpath = path;
00170 std::string fontglyphs = glyphs;
00171 int fontsize = size;
00172
00173
00174 if(fontpath == "") {
00175 fontpath = m_fontpath;
00176 }
00177 if(fontsize == 0) {
00178 fontsize = m_fontsize;
00179 }
00180 if(fontglyphs == "") {
00181 fontglyphs = m_fontglyphs;
00182 }
00183
00184 AbstractFont* font = NULL;
00185 GuiFont* guifont = NULL;
00186 if( boost::filesystem::extension(fontpath) == ".ttf" ) {
00187 font = new TrueTypeFont(fontpath, fontsize);
00188 } else {
00189 font = new SubImageFont(fontpath, fontglyphs, m_pool);
00190 }
00191 guifont = new GuiFont(font);
00192
00193 m_fonts.push_back(guifont);
00194 return guifont;
00195 }
00196
00197 void GUIManager::releaseFont(GuiFont* font) {
00198 std::vector<GuiFont*>::iterator i = m_fonts.begin();
00199 while (i != m_fonts.end()) {
00200 if ((*i) == font) {
00201 m_fonts.erase(i);
00202 delete font;
00203 return;
00204 }
00205 ++i;
00206 }
00207 }
00208
00209 GuiFont* GUIManager::setDefaultFont(const std::string& path, unsigned int size, const std::string& glyphs) {
00210 m_fontpath = path;
00211 m_fontsize = size;
00212 m_fontglyphs = glyphs;
00213
00214 GuiFont* defaultfont = createFont();
00215 gcn::Widget::setGlobalFont(defaultfont);
00216 if (m_console) {
00217 m_console->reLayout();
00218 }
00219
00220 return defaultfont;
00221 }
00222
00223 void GUIManager::turn() {
00224 if (!m_logic_executed)
00225 m_gcn_gui->logic();
00226 m_logic_executed = false;
00227 m_gcn_gui->draw();
00228 }
00229
00230 KeyEvent GUIManager::translateKeyEvent(const gcn::KeyEvent& gcnevt) {
00231 KeyEvent keyevt;
00232 if(gcnevt.getType() == gcn::KeyEvent::PRESSED)
00233 keyevt.setType(KeyEvent::PRESSED);
00234 else if(gcnevt.getType() == gcn::KeyEvent::RELEASED)
00235 keyevt.setType(KeyEvent::RELEASED);
00236 else
00237 throw EventException("Invalid event type in fillKeyEvent");
00238 keyevt.setShiftPressed(gcnevt.isShiftPressed());
00239 keyevt.setControlPressed(gcnevt.isControlPressed());
00240 keyevt.setAltPressed(gcnevt.isAltPressed());
00241 keyevt.setMetaPressed(gcnevt.isMetaPressed());
00242 keyevt.setNumericPad(gcnevt.isNumericPad());
00243
00244
00245 int keyval = gcnevt.getKey().getValue();
00246 keyval = convertGuichanKeyToFifeKey(keyval);
00247
00248 keyevt.setKey(Key(static_cast<Key::KeyType>(keyval), keyval));
00249
00250 return keyevt;
00251 }
00252
00253 MouseEvent GUIManager::translateMouseEvent(const gcn::MouseEvent& gcnevt) {
00254 MouseEvent mouseevt;
00255 mouseevt.setShiftPressed(gcnevt.isShiftPressed());
00256 mouseevt.setControlPressed(gcnevt.isControlPressed());
00257 mouseevt.setAltPressed(gcnevt.isAltPressed());
00258 mouseevt.setMetaPressed(gcnevt.isMetaPressed());
00259 mouseevt.setX(gcnevt.getX());
00260 mouseevt.setY(gcnevt.getY());
00261
00262 switch(gcnevt.getType()) {
00263 case gcn::MouseEvent::PRESSED:
00264 mouseevt.setType(MouseEvent::PRESSED);
00265 break;
00266 case gcn::MouseEvent::RELEASED:
00267 mouseevt.setType(MouseEvent::RELEASED);
00268 break;
00269 case gcn::MouseEvent::MOVED:
00270 mouseevt.setType(MouseEvent::MOVED);
00271 break;
00272 case gcn::MouseEvent::CLICKED:
00273 mouseevt.setType(MouseEvent::CLICKED);
00274 break;
00275 case gcn::MouseEvent::ENTERED:
00276 mouseevt.setType(MouseEvent::ENTERED);
00277 break;
00278 case gcn::MouseEvent::EXITED:
00279 mouseevt.setType(MouseEvent::EXITED);
00280 break;
00281 case gcn::MouseEvent::DRAGGED:
00282 mouseevt.setType(MouseEvent::DRAGGED);
00283 break;
00284 case gcn::MouseEvent::WHEEL_MOVED_DOWN:
00285 mouseevt.setType(MouseEvent::WHEEL_MOVED_DOWN);
00286 break;
00287 case gcn::MouseEvent::WHEEL_MOVED_UP:
00288 mouseevt.setType(MouseEvent::WHEEL_MOVED_UP);
00289 break;
00290 default:
00291 mouseevt.setType(MouseEvent::UNKNOWN_EVENT);
00292 }
00293
00294 switch(gcnevt.getButton()) {
00295 case gcn::MouseInput::LEFT:
00296 mouseevt.setButton(MouseEvent::LEFT);
00297 break;
00298 case gcn::MouseInput::RIGHT:
00299 mouseevt.setButton(MouseEvent::RIGHT);
00300 break;
00301 case gcn::MouseInput::MIDDLE:
00302 mouseevt.setButton(MouseEvent::MIDDLE);
00303 break;
00304 default:
00305 mouseevt.setButton(MouseEvent::UNKNOWN_BUTTON);
00306 break;
00307 }
00308 return mouseevt;
00309 }
00310
00311
00312 int GUIManager::convertGuichanKeyToFifeKey(int value) {
00313
00314 switch (value) {
00315 case gcn::Key::TAB:
00316 value = Key::TAB;
00317 break;
00318 case gcn::Key::LEFT_ALT:
00319 value = Key::LEFT_ALT;
00320 break;
00321 case gcn::Key::RIGHT_ALT:
00322 value = Key::RIGHT_ALT;
00323 break;
00324 case gcn::Key::LEFT_SHIFT:
00325 value = Key::LEFT_SHIFT;
00326 break;
00327 case gcn::Key::RIGHT_SHIFT:
00328 value = Key::RIGHT_SHIFT;
00329 break;
00330 case gcn::Key::LEFT_CONTROL:
00331 value = Key::LEFT_CONTROL;
00332 break;
00333 case gcn::Key::RIGHT_CONTROL:
00334 value = Key::RIGHT_CONTROL;
00335 break;
00336 case gcn::Key::BACKSPACE:
00337 value = Key::BACKSPACE;
00338 break;
00339 case gcn::Key::PAUSE:
00340 value = Key::PAUSE;
00341 break;
00342 case gcn::Key::SPACE:
00343 value = Key::SPACE;
00344 break;
00345 case gcn::Key::ESCAPE:
00346 value = Key::ESCAPE;
00347 break;
00348 case gcn::Key::DELETE:
00349 value = Key::DELETE;
00350 break;
00351 case gcn::Key::INSERT:
00352 value = Key::INSERT;
00353 break;
00354 case gcn::Key::HOME:
00355 value = Key::HOME;
00356 break;
00357 case gcn::Key::END:
00358 value = Key::END;
00359 break;
00360 case gcn::Key::PAGE_UP:
00361 value = Key::PAGE_UP;
00362 break;
00363 case gcn::Key::PRINT_SCREEN:
00364 value = Key::PRINT_SCREEN;
00365 break;
00366 case gcn::Key::PAGE_DOWN:
00367 value = Key::PAGE_DOWN;
00368 break;
00369 case gcn::Key::F1:
00370 value = Key::F1;
00371 break;
00372 case gcn::Key::F2:
00373 value = Key::F2;
00374 break;
00375 case gcn::Key::F3:
00376 value = Key::F3;
00377 break;
00378 case gcn::Key::F4:
00379 value = Key::F4;
00380 break;
00381 case gcn::Key::F5:
00382 value = Key::F5;
00383 break;
00384 case gcn::Key::F6:
00385 value = Key::F6;
00386 break;
00387 case gcn::Key::F7:
00388 value = Key::F7;
00389 break;
00390 case gcn::Key::F8:
00391 value = Key::F8;
00392 break;
00393 case gcn::Key::F9:
00394 value = Key::F9;
00395 break;
00396 case gcn::Key::F10:
00397 value = Key::F10;
00398 break;
00399 case gcn::Key::F11:
00400 value = Key::F11;
00401 break;
00402 case gcn::Key::F12:
00403 value = Key::F12;
00404 break;
00405 case gcn::Key::F13:
00406 value = Key::F13;
00407 break;
00408 case gcn::Key::F14:
00409 value = Key::F14;
00410 break;
00411 case gcn::Key::F15:
00412 value = Key::F15;
00413 break;
00414 case gcn::Key::NUM_LOCK:
00415 value = Key::NUM_LOCK;
00416 break;
00417 case gcn::Key::CAPS_LOCK:
00418 value = Key::CAPS_LOCK;
00419 break;
00420 case gcn::Key::SCROLL_LOCK:
00421 value = Key::SCROLL_LOCK;
00422 break;
00423 case gcn::Key::RIGHT_META:
00424 value = Key::RIGHT_META;
00425 break;
00426 case gcn::Key::LEFT_META:
00427 value = Key::LEFT_META;
00428 break;
00429 case gcn::Key::LEFT_SUPER:
00430 value = Key::LEFT_SUPER;
00431 break;
00432 case gcn::Key::RIGHT_SUPER:
00433 value = Key::RIGHT_SUPER;
00434 break;
00435 case gcn::Key::ALT_GR:
00436 value = Key::ALT_GR;
00437 break;
00438 case gcn::Key::UP:
00439 value = Key::UP;
00440 break;
00441 case gcn::Key::DOWN:
00442 value = Key::DOWN;
00443 break;
00444 case gcn::Key::LEFT:
00445 value = Key::LEFT;
00446 break;
00447 case gcn::Key::RIGHT:
00448 value = Key::RIGHT;
00449 break;
00450 case gcn::Key::ENTER:
00451 value = Key::ENTER;
00452 break;
00453
00454 default:
00455
00456 if (value >= 1 && value <= 26) {
00457
00458 value = value - 1 + 'a';
00459 } else if (value >= 'A' && value <= 'Z') {
00460 value = value - 'A' + 'a';
00461 }
00462
00463
00464 break;
00465 }
00466
00467 return value;
00468 }
00469 }