/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Benjamin Grauer co-programmer: ... */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI #include "glgui_handler.h" #include "event_handler.h" #include "key_names.h" #include "glgui_mainwidget.h" #include "glgui_cursor.h" #include #include "debug.h" /// TAKE THIS OUT OF HERE. #include "graphics_engine.h" #include "loading/resource_manager.h" namespace OrxGui { ObjectListDefinition(GLGuiHandler); /** * standard constructor */ GLGuiHandler::GLGuiHandler () { this->registerObject(this, GLGuiHandler::_objectList); this->setName("GLGuiHandler"); this->_resolution = Vector2D(GraphicsEngine::getInstance()->getResolutionX(), GraphicsEngine::getInstance()->getResolutionY()); EventHandler::getInstance()->withUNICODE(ES_MENU, true ); this->_cursor = NULL; for (unsigned int i = 0; i < EV_NUMBER; i++) { this->subscribeEvent(ES_GAME, i); this->subscribeEvent(ES_GAME_MENU, i); this->subscribeEvent(ES_MENU, i); } } /** * the singleton reference to this class */ GLGuiHandler* GLGuiHandler::singletonRef = NULL; /** @brief standard deconstructor */ GLGuiHandler::~GLGuiHandler () { GLGuiHandler::singletonRef = NULL; } void GLGuiHandler::activateCursor() { if (this->_cursor == NULL) this->_cursor = new GLGuiCursor(); this->_cursor->show(); this->_cursor->setMaxBorders(Vector2D(GraphicsEngine::getInstance()->getResolutionX(), GraphicsEngine::getInstance()->getResolutionY())); _cursor->loadTextureSequence(ResourceManager::getInstance()->getDataDir() + "/" + "maps/reap_mouse/reap_mouse_##.png", 1, 49); } void GLGuiHandler::deactivateCursor(bool deleteCursor) { if (this->_cursor) { if (deleteCursor) delete this->_cursor; this->_cursor = NULL; } } const Vector2D& GLGuiHandler::resolution() { if (this->_resolution == Vector2D::nullVector()) this->_resolution = Vector2D(GraphicsEngine::getInstance()->getResolutionX(), GraphicsEngine::getInstance()->getResolutionY()); return _resolution; } void GLGuiHandler::activate() { //EventHandler::getInstance()->pushState(ES_MENU); } void GLGuiHandler::deactivate() { //EventHandler::getInstance()->popState(); } void GLGuiHandler::selectNext() { // retrieve Objects. ObjectList::const_iterator it, currentIt; currentIt = GLGuiWidget::objectList().end(); if (GLGuiWidget::selected() != NULL) { it = std::find(GLGuiWidget::objectList().begin(), GLGuiWidget::objectList().end(), GLGuiWidget::selected()); if (it != GLGuiWidget::objectList().end()) { currentIt = it; it++; } } else { it = GLGuiWidget::objectList().begin(); } bool cycledOnce = false; for (; it != currentIt; ++it) { if (it == GLGuiWidget::objectList().end() && !cycledOnce) { it = GLGuiWidget::objectList().begin(); cycledOnce = true; } if ((*it)->selectable() && (*it)->isVisible()) { (*it)->select(); return; } } } void GLGuiHandler::selectPrevious() { ObjectList::const_iterator it, currentIt; currentIt = GLGuiWidget::objectList().begin(); if (GLGuiWidget::selected() != NULL) { it = std::find(GLGuiWidget::objectList().begin(), GLGuiWidget::objectList().end(), GLGuiWidget::selected()); if (it != GLGuiWidget::objectList().end()) { currentIt = it; it--; } } else { it = GLGuiWidget::objectList().end(); } bool cycledOnce = false; for (; it != currentIt; --it) { if (it == GLGuiWidget::objectList().end() && !cycledOnce) { --it ; cycledOnce = true; } if ((*it)->selectable() && (*it)->isVisible()) { (*it)->select(); return; } } } void GLGuiHandler::process(const Event &event) { switch (event.type) { case EV_MOUSE_MOTION: this->checkFocus(); break; case EV_MOUSE_BUTTON_LEFT: if (GLGuiWidget::mouseFocused() != NULL && event.bPressed) { // if clickable select the Widget. if (GLGuiWidget::mouseFocused()->clickable()) { Vector2D cursorPos = (this->_cursor != NULL) ? this->_cursor->getAbsCoor2D() : Vector2D(event.x, event.y); GLGuiWidget::mouseFocused()->select(); GLGuiWidget::mouseFocused()->click(cursorPos - GLGuiWidget::mouseFocused()->getAbsCoor2D()); } } else if (GLGuiWidget::selected() != NULL && !event.bPressed) { if (GLGuiWidget::selected()->clickable()) { Vector2D cursorPos = (this->_cursor != NULL) ? this->_cursor->getAbsCoor2D() : Vector2D(event.x, event.y); GLGuiWidget::selected()->release(cursorPos - GLGuiWidget::selected()->getAbsCoor2D()); } } break; case EV_LEAVE_STATE: if (GLGuiWidget::selected() != NULL) GLGuiWidget::selected()->unselect(); if (GLGuiWidget::mouseFocused() != NULL) GLGuiWidget::mouseFocused()->breakMouseFocus(); break; case EV_VIDEO_RESIZE: if (this->_cursor != NULL) this->_cursor->setMaxBorders(Vector2D(event.resize.w, event.resize.h)); this->_resolution = Vector2D(event.resize.w, event.resize.h); break; case SDLK_TAB: if (event.bPressed) { if (EventHandler::getInstance()->isPressed(SDLK_LSHIFT) || EventHandler::getInstance()->isPressed(SDLK_RSHIFT)) this->selectPrevious(); else this->selectNext(); } break; } // Send the Event to the Widget below. if (GLGuiWidget::selected() != NULL) { GLGuiWidget::selected()->processEvent(event); } } const Vector2D& GLGuiHandler::cursorPositionOverFocusedWidget() const { return (this->_cursor != NULL) ? this->_cursor->getAbsCoor2D() : Vector2D::nullVector(); } const Vector2D& GLGuiHandler::cursorPositionAbs() const { if (this->_cursor) return this->_cursor->getAbsCoor2D(); else return Vector2D::nullVector(); } Vector2D GLGuiHandler::cursorPositionRel(const GLGuiWidget* const widget) const { assert (widget != NULL); if (this->_cursor) return this->_cursor->getAbsCoor2D() - widget->getAbsCoor2D(); else return Vector2D::nullVector(); } void GLGuiHandler::checkFocus() { // CHECK THE COLLISIONS. if (this->_cursor != NULL) { for (ObjectList::const_iterator it = GLGuiWidget::objectList().begin(); it != GLGuiWidget::objectList().end(); it++) { GLGuiWidget* widget = (*it); if (widget->isVisible() && widget->focusable() && widget->focusOverWidget(this->_cursor)) { // receiving Focus if (GLGuiWidget::mouseFocused() != widget) { widget->giveMouseFocus(); } return ; } } if (GLGuiWidget::mouseFocused() != NULL) GLGuiWidget::mouseFocused()->breakMouseFocus(); } } void GLGuiHandler::draw() { // GLGuiMainWidget::getInstance()->draw2D(E2D_LAYER_TOP); } void GLGuiHandler::tick(float dt) { // do not change if we already clicked into a Widget. // if (GLGuiWidget::selected() != NULL && GLGuiWidget::selected()->pushed()) // return ; this->checkFocus(); } }