//////////////////////////////////////////////////////////////////////////////// // Scorched3D (c) 2000-2003 // // This file is part of Scorched3D. // // Scorched3D 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 of the License, or // (at your option) any later version. // // Scorched3D is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Scorched3D; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include WindowManager *WindowManager::instance_ = 0; WindowManager *WindowManager::instance() { if (!instance_) { instance_ = new WindowManager; } return instance_; } WindowManager::WindowManager() : currentStateEntry_(0) { setCurrentEntry(UINT_MAX); MainMenuDialog::instance()-> addMenu("Windows", 90.0f, this, 0, this, 0); } WindowManager::~WindowManager() { } void WindowManager::clear() { currentStateEntry_ = 0; setCurrentEntry(UINT_MAX); stateEntrys_.clear(); idToWindow_.clear(); windowVisibility_.clear(); } void WindowManager::setCurrentEntry(const unsigned state) { // Store the currently visible windows std::set shownWindows; std::deque windowsCopy; std::deque::iterator qitor; if (currentStateEntry_) { windowsCopy = currentStateEntry_->windows_; for (qitor = windowsCopy.begin(); qitor != windowsCopy.end(); qitor++) { GLWWindow *window = *qitor; if (windowVisible(window->getId())) { shownWindows.insert(window->getId()); } } } // Find the next state static StateEntry defaultStateEntry; std::map::iterator itor = stateEntrys_.find(state); if (itor == stateEntrys_.end()) { currentStateEntry_ = &defaultStateEntry; defaultStateEntry.state_ = state; } else { currentStateEntry_ = &(*itor).second; } // Tell the windows that they have been hidden or shown windowsCopy = currentStateEntry_->windows_; for (qitor = windowsCopy.begin(); qitor != windowsCopy.end(); qitor++) { GLWWindow *window = *qitor; window->windowInit(state); // This window should be visible if (windowVisible(window->getId())) { // Only call window display on windows that have not // been shown in the last state std::set::iterator shownPrev = shownWindows.find(window->getId()); if (shownPrev == shownWindows.end()) { window->windowDisplay(); } } else { // Only call window hide on windows that have // been shown in the last state std::set::iterator shownPrev = shownWindows.find(window->getId()); if (shownPrev != shownWindows.end()) { window->windowHide(); } } } moveToFront(MainMenuDialog::instance()->getId()); moveToFront(GLWSelector::instance()->getId()); } void WindowManager::addWindow(const unsigned state, GLWWindow *window, KeyboardKey *key, bool visible) { windowVisibility_[window->getId()] = visible; idToWindow_[window->getId()] = window; stateEntrys_[state].windows_.push_back(window); stateEntrys_[state].state_ = state; stateEntrys_[state].windowKeys_.push_back( std::pair(key, window)); } bool WindowManager::showWindow(unsigned id) { std::map::iterator itor = windowVisibility_.find(id); if (itor != windowVisibility_.end()) { if (!(*itor).second) { GLWWindow *window = idToWindow_[id]; (*itor).second = true; window->windowDisplay(); moveToFront(id); moveToFront(MainMenuDialog::instance()->getId()); moveToFront(GLWSelector::instance()->getId()); return true; } } return false; } bool WindowManager::moveToFront(unsigned id) { GLWWindow *found = 0; std::deque tmpList; while (!currentStateEntry_->windows_.empty()) { GLWWindow *window = currentStateEntry_->windows_.front(); currentStateEntry_->windows_.pop_front(); if (window->getId() == id) found = window; else tmpList.push_back(window); } currentStateEntry_->windows_ = tmpList; if (found) { currentStateEntry_->windows_.push_back(found); } return (found != 0); } bool WindowManager::windowVisible(unsigned id) { std::map::iterator itor = windowVisibility_.find(id); if (itor != windowVisibility_.end()) { return ((*itor).second); } return false; } bool WindowManager::hideWindow(unsigned id) { std::map::iterator itor = windowVisibility_.find(id); if (itor != windowVisibility_.end()) { if ((*itor).second) { GLWWindow *window = idToWindow_[id]; window->windowHide(); (*itor).second = false; return true; } } return false; } bool WindowManager::windowInCurrentState(unsigned id) { if (!currentStateEntry_) return false; std::deque::iterator itor; for (itor = currentStateEntry_->windows_.begin(); itor != currentStateEntry_->windows_.end(); itor++) { GLWWindow *window = (*itor); if (window->getId() == id) { return true; } } return false; } void WindowManager::draw(const unsigned state) { if (currentStateEntry_->state_ != state) setCurrentEntry(state); std::deque::iterator itor; for (itor = currentStateEntry_->windows_.begin(); itor != currentStateEntry_->windows_.end(); itor++) { GLWWindow *window = (*itor); if (windowVisible(window->getId())) { window->draw(); } } } unsigned int WindowManager::getFocus(int x, int y) { std::deque::reverse_iterator itor; for (itor = currentStateEntry_->windows_.rbegin(); itor != currentStateEntry_->windows_.rend(); itor++) { GLWWindow *window = (*itor); if (windowVisible(window->getId())) { if (GLWVisibleWidget::inBox( (float) x, (float) y, window->getX(), window->getY(), window->getW(), window->getH())) { return window->getId(); } } } return 0; } void WindowManager::simulate(const unsigned state, float simTime) { if (currentStateEntry_->state_ != state) setCurrentEntry(state); std::deque::iterator itor; for (itor = currentStateEntry_->windows_.begin(); itor != currentStateEntry_->windows_.end(); itor++) { GLWWindow *window = (*itor); window->simulate(simTime); } } void WindowManager::keyboardCheck(const unsigned state, float frameTime, char *buffer, unsigned int keyState, KeyboardHistory::HistoryElement *history, int hisCount, bool &skipRest) { std::deque::reverse_iterator itor; for (itor = currentStateEntry_->windows_.rbegin(); itor != currentStateEntry_->windows_.rend(); itor++) { GLWWindow *window = (*itor); if (windowVisible(window->getId())) { window->keyDown(buffer, keyState, history, hisCount, skipRest); if (skipRest) break; } } if (skipRest) return; for (int i=0; i >::iterator keyItor; std::list >::iterator endKeyItor = currentStateEntry_->windowKeys_.end(); for (keyItor = currentStateEntry_->windowKeys_.begin(); keyItor != endKeyItor; keyItor++) { KeyboardKey *key = (*keyItor).first; if (key && key->keyDown(buffer, keyState)) { GLWWindow *window = (*keyItor).second; if (windowVisible(window->getId())) { hideWindow(window->getId()); } else { showWindow(window->getId()); } } } } } void WindowManager::mouseDown(const unsigned state, GameState::MouseButton button, int x, int y, bool &skipRest) { std::deque::reverse_iterator itor; for (itor = currentStateEntry_->windows_.rbegin(); itor != currentStateEntry_->windows_.rend(); itor++) { GLWWindow *window = (*itor); if (windowVisible(window->getId())) { window->mouseDown((float) x, (float) y, skipRest); if (skipRest) break; } } } void WindowManager::mouseUp(const unsigned state, GameState::MouseButton button, int x, int y, bool &skipRest) { std::deque::reverse_iterator itor; for (itor = currentStateEntry_->windows_.rbegin(); itor != currentStateEntry_->windows_.rend(); itor++) { GLWWindow *window = (*itor); if (windowVisible(window->getId())) { window->mouseUp((float) x, (float) y, skipRest); if (skipRest) break; } } } void WindowManager::mouseDrag(const unsigned state, GameState::MouseButton button, int mx, int my, int x, int y, bool &skipRest) { std::deque::reverse_iterator itor; for (itor = currentStateEntry_->windows_.rbegin(); itor != currentStateEntry_->windows_.rend(); itor++) { GLWWindow *window = (*itor); if (windowVisible(window->getId())) { window->mouseDrag((float) mx, (float) my, (float) x, (float) y, skipRest); if (skipRest) break; } } } void WindowManager::getMenuItems(const char* menuName, std::list &items) { if (currentStateEntry_) { std::deque::reverse_iterator itor; for (itor = currentStateEntry_->windows_.rbegin(); itor != currentStateEntry_->windows_.rend(); itor++) { GLWWindow *window = (*itor); if (window->getName()[0] != '\0') { items.push_back( GLMenuItem( window->getName(), &window->getToolTip(), windowVisible(window->getId()))); } } } } void WindowManager::menuSelection(const char* menuName, const int position, const char *menuItem) { std::list items; if (currentStateEntry_) { int pos = 0; std::deque::reverse_iterator itor; for (itor = currentStateEntry_->windows_.rbegin(); itor != currentStateEntry_->windows_.rend(); itor++) { GLWWindow *window = (*itor); if (window->getName()[0] != '\0') { if (pos++ == position) { if (windowVisible(window->getId())) { hideWindow(window->getId()); } else { showWindow(window->getId()); } return; } } } } }