00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <GLW/GLWWindowManager.h>
00022 #include <GLEXT/GLViewPort.h>
00023 #include <image/ImageFactory.h>
00024 #include <dialogs/MainMenuDialog.h>
00025 #include <graph/OptionsDisplay.h>
00026 #include <common/Defines.h>
00027 #include <lang/LangResource.h>
00028 #include <XML/XMLFile.h>
00029 #include <limits.h>
00030 #include <set>
00031
00032 GLWWindowManager *GLWWindowManager::instance_ = 0;
00033
00034 GLWWindowManager *GLWWindowManager::instance()
00035 {
00036 if (!instance_)
00037 {
00038 instance_ = new GLWWindowManager;
00039 }
00040
00041 return instance_;
00042 }
00043
00044 GLWWindowManager::GLWWindowManager() :
00045 GameStateI("GLWWindowManager"),
00046 currentStateEntry_(0),
00047 changeEpoc_(0)
00048 {
00049 setCurrentEntry(UINT_MAX);
00050
00051 Image *map = ImageFactory::loadImage(
00052 S3D::getDataFile("data/windows/screen.bmp"),
00053 S3D::getDataFile("data/windows/screena.bmp"),
00054 false);
00055 DIALOG_ASSERT(map->getBits());
00056 MainMenuDialog::instance()->
00057 addMenu(LANG_RESOURCE("WINDOWS", "Windows"),
00058 "Windows",
00059 LANG_RESOURCE("WINDOWS_WINDOW", "Hide and display aspects of the user interface"),
00060 32.0f, 0, this, map);
00061 }
00062
00063 GLWWindowManager::~GLWWindowManager()
00064 {
00065
00066 }
00067
00068 void GLWWindowManager::clear()
00069 {
00070 currentStateEntry_ = 0;
00071 setCurrentEntry(UINT_MAX);
00072 stateEntrys_.clear();
00073 idToWindow_.clear();
00074 windowVisibility_.clear();
00075 }
00076
00077 void GLWWindowManager::setCurrentEntry(const unsigned state)
00078 {
00079
00080 std::set<unsigned int> shownWindows;
00081 std::deque<GLWWindow *> windowsCopy;
00082 std::deque<GLWWindow *>::iterator qitor;
00083
00084 if (currentStateEntry_)
00085 {
00086 windowsCopy = currentStateEntry_->windows_;
00087 for (qitor = windowsCopy.begin();
00088 qitor != windowsCopy.end();
00089 qitor++)
00090 {
00091 GLWWindow *window = *qitor;
00092 if (windowVisible(window->getId()))
00093 {
00094 shownWindows.insert(window->getId());
00095 }
00096 }
00097 }
00098
00099
00100 static StateEntry defaultStateEntry;
00101 defaultStateEntry.state_ = UINT_MAX;
00102
00103 std::map<unsigned, StateEntry>::iterator itor =
00104 stateEntrys_.find(state);
00105 if (itor == stateEntrys_.end())
00106 {
00107 currentStateEntry_ = &defaultStateEntry;
00108 }
00109 else
00110 {
00111 currentStateEntry_ = &(*itor).second;
00112 }
00113
00114
00115 windowsCopy = currentStateEntry_->windows_;
00116 for (qitor = windowsCopy.begin();
00117 qitor != windowsCopy.end();
00118 qitor++)
00119 {
00120 GLWWindow *window = *qitor;
00121 window->windowInit(state);
00122
00123
00124 if (windowVisible(window->getId()))
00125 {
00126
00127
00128 std::set<unsigned int>::iterator shownPrev =
00129 shownWindows.find(window->getId());
00130 if (shownPrev == shownWindows.end())
00131 {
00132 window->display();
00133 }
00134 }
00135 else
00136 {
00137
00138
00139 std::set<unsigned int>::iterator shownPrev =
00140 shownWindows.find(window->getId());
00141 if (shownPrev != shownWindows.end())
00142 {
00143 window->hide();
00144 }
00145 }
00146 }
00147
00148 sortWindowLevels();
00149 }
00150
00151 void GLWWindowManager::addWindow(const unsigned state, GLWWindow *window, KeyboardKey *key, bool visible)
00152 {
00153 windowVisibility_[window->getId()] = visible;
00154 idToWindow_[window->getId()] = window;
00155
00156 stateEntrys_[state].windows_.push_back(window);
00157 stateEntrys_[state].state_ = state;
00158 stateEntrys_[state].windowKeys_.push_back(
00159 std::pair<KeyboardKey *, GLWWindow *>(key, window));
00160 }
00161
00162 bool GLWWindowManager::showWindow(unsigned id)
00163 {
00164 std::map<unsigned, bool>::iterator itor =
00165 windowVisibility_.find(id);
00166 if (itor != windowVisibility_.end())
00167 {
00168 if (!(*itor).second)
00169 {
00170 GLWWindow *window = idToWindow_[id];
00171 (*itor).second = true;
00172 window->display();
00173 moveToFront(id);
00174
00175 changeEpoc_++;
00176 return true;
00177 }
00178 }
00179
00180 return false;
00181 }
00182
00183 bool GLWWindowManager::moveToFront(unsigned id)
00184 {
00185 GLWWindow *found = 0;
00186 std::deque<GLWWindow *> tmpList;
00187
00188 while (!currentStateEntry_->windows_.empty())
00189 {
00190 GLWWindow *window = currentStateEntry_->windows_.front();
00191 currentStateEntry_->windows_.pop_front();
00192 if (window->getId() == id) found = window;
00193 else tmpList.push_back(window);
00194 }
00195
00196 currentStateEntry_->windows_ = tmpList;
00197 if (found)
00198 {
00199 changeEpoc_++;
00200 currentStateEntry_->windows_.push_back(found);
00201 sortWindowLevels();
00202 }
00203
00204 return (found != 0);
00205 }
00206
00207 void GLWWindowManager::sortWindowLevels()
00208 {
00209 if (!currentStateEntry_) return;
00210
00211 std::deque<GLWWindow *> &windows = currentStateEntry_->windows_;
00212
00213 bool changed = true;
00214 while (changed)
00215 {
00216 changed = false;
00217 for (int i=0; i<int(windows.size())-1; i++)
00218 {
00219 GLWWindow *first = windows[i];
00220 GLWWindow *second = windows[i+1];
00221 if (first->getWindowLevel() < second->getWindowLevel())
00222 {
00223 windows[i] = second;
00224 windows[i+1] = first;
00225 changed = true;
00226 changeEpoc_++;
00227 }
00228 }
00229 }
00230 }
00231
00232 bool GLWWindowManager::windowVisible(unsigned id)
00233 {
00234 std::map<unsigned, bool>::iterator itor =
00235 windowVisibility_.find(id);
00236 if (itor != windowVisibility_.end())
00237 {
00238 return ((*itor).second);
00239 }
00240
00241 return false;
00242 }
00243
00244 bool GLWWindowManager::hideWindow(unsigned id)
00245 {
00246 std::map<unsigned, bool>::iterator itor =
00247 windowVisibility_.find(id);
00248 if (itor != windowVisibility_.end())
00249 {
00250 if ((*itor).second)
00251 {
00252 GLWWindow *window = idToWindow_[id];
00253 window->hide();
00254
00255 (*itor).second = false;
00256 changeEpoc_++;
00257 return true;
00258 }
00259 }
00260
00261 return false;
00262 }
00263
00264 bool GLWWindowManager::windowInCurrentState(unsigned id)
00265 {
00266 if (!currentStateEntry_) return false;
00267
00268 std::deque<GLWWindow *>::iterator itor;
00269 for (itor = currentStateEntry_->windows_.begin();
00270 itor != currentStateEntry_->windows_.end();
00271 itor++)
00272 {
00273 GLWWindow *window = (*itor);
00274 if (window->getId() == id)
00275 {
00276 return true;
00277 }
00278 }
00279 return false;
00280 }
00281
00282 void GLWWindowManager::enterState(const unsigned state)
00283 {
00284 if (currentStateEntry_ &&
00285 currentStateEntry_->state_ != UINT_MAX &&
00286 currentStateEntry_->state_ != state) setCurrentEntry(state);
00287 }
00288
00289 void GLWWindowManager::draw(const unsigned state)
00290 {
00291 if (currentStateEntry_->state_ != state) setCurrentEntry(state);
00292 unsigned int entryEpoc = changeEpoc_;
00293
00294 std::deque<GLWWindow *>::iterator itor;
00295 for (itor = currentStateEntry_->windows_.begin();
00296 itor != currentStateEntry_->windows_.end();
00297 itor++)
00298 {
00299 GLWWindow *window = (*itor);
00300 if (windowVisible(window->getId()))
00301 {
00302 window->draw();
00303 if (entryEpoc != changeEpoc_) break;
00304 }
00305 }
00306 }
00307
00308 GLWWindow *GLWWindowManager::getWindowByName(const char *name)
00309 {
00310 if (!currentStateEntry_) return 0;
00311
00312 std::deque<GLWWindow *>::iterator itor;
00313 for (itor = currentStateEntry_->windows_.begin();
00314 itor != currentStateEntry_->windows_.end();
00315 itor++)
00316 {
00317 GLWWindow *window = (*itor);
00318 if (0 == strcmp(window->getName(), name)) return window;
00319 }
00320 return 0;
00321 }
00322
00323 unsigned int GLWWindowManager::getFocus(int x, int y)
00324 {
00325 std::deque<GLWWindow *>::reverse_iterator itor;
00326 for (itor = currentStateEntry_->windows_.rbegin();
00327 itor != currentStateEntry_->windows_.rend();
00328 itor++)
00329 {
00330 GLWWindow *window = (*itor);
00331 if (windowVisible(window->getId()))
00332 {
00333 if (GLWidget::inBox(
00334 (float) x, (float) y,
00335 window->getX(), window->getY(),
00336 window->getW(), window->getH()))
00337 {
00338 return window->getId();
00339 }
00340 }
00341 }
00342 return 0;
00343 }
00344
00345 void GLWWindowManager::simulate(const unsigned state, float simTime)
00346 {
00347 if (currentStateEntry_->state_ != state) setCurrentEntry(state);
00348 unsigned int entryEpoc = changeEpoc_;
00349
00350 std::deque<GLWWindow *>::iterator itor;
00351 for (itor = currentStateEntry_->windows_.begin();
00352 itor != currentStateEntry_->windows_.end();
00353 itor++)
00354 {
00355 GLWWindow *window = (*itor);
00356 if (windowVisible(window->getId()))
00357 {
00358 window->simulate(simTime);
00359 if (entryEpoc != changeEpoc_) break;
00360 }
00361 }
00362 }
00363
00364 void GLWWindowManager::keyboardCheck(const unsigned state, float frameTime,
00365 char *buffer, unsigned int keyState,
00366 KeyboardHistory::HistoryElement *history, int hisCount,
00367 bool &skipRest)
00368 {
00369 if (currentStateEntry_->state_ != state) setCurrentEntry(state);
00370 unsigned int entryEpoc = changeEpoc_;
00371
00372 std::deque<GLWWindow *>::reverse_iterator itor;
00373 for (itor = currentStateEntry_->windows_.rbegin();
00374 itor != currentStateEntry_->windows_.rend();
00375 itor++)
00376 {
00377 GLWWindow *window = (*itor);
00378 if (windowVisible(window->getId()))
00379 {
00380 window->keyDown(buffer, keyState,
00381 history, hisCount,
00382 skipRest);
00383 if (skipRest) break;
00384 if (entryEpoc != changeEpoc_) break;
00385 }
00386 }
00387
00388 if (skipRest) return;
00389
00390 for (int i=0; i<hisCount; i++)
00391 {
00392 unsigned int dik = history[i].sdlKey;
00393
00394 std::list<std::pair<KeyboardKey *, GLWWindow *> >::iterator keyItor;
00395 std::list<std::pair<KeyboardKey *, GLWWindow *> >::iterator endKeyItor =
00396 currentStateEntry_->windowKeys_.end();
00397 for (keyItor = currentStateEntry_->windowKeys_.begin();
00398 keyItor != endKeyItor;
00399 keyItor++)
00400 {
00401 KeyboardKey *key = (*keyItor).first;
00402 if (key && key->keyDown(buffer, keyState))
00403 {
00404 GLWWindow *window = (*keyItor).second;
00405 if (windowVisible(window->getId()))
00406 {
00407 hideWindow(window->getId());
00408 }
00409 else
00410 {
00411 showWindow(window->getId());
00412 }
00413 }
00414 }
00415 }
00416 }
00417
00418 void GLWWindowManager::mouseDown(const unsigned state, GameState::MouseButton button, int x, int y, bool &skipRest)
00419 {
00420 if (currentStateEntry_->state_ != state) setCurrentEntry(state);
00421 unsigned int entryEpoc = changeEpoc_;
00422
00423 std::deque<GLWWindow *>::reverse_iterator itor;
00424 for (itor = currentStateEntry_->windows_.rbegin();
00425 itor != currentStateEntry_->windows_.rend();
00426 itor++)
00427 {
00428 GLWWindow *window = (*itor);
00429 if (windowVisible(window->getId()))
00430 {
00431 window->mouseDown((int) button, (float) x, (float) y, skipRest);
00432 if (skipRest) break;
00433 if (entryEpoc != changeEpoc_) break;
00434 }
00435 }
00436 }
00437
00438 void GLWWindowManager::mouseUp(const unsigned state, GameState::MouseButton button, int x, int y, bool &skipRest)
00439 {
00440 if (currentStateEntry_->state_ != state) setCurrentEntry(state);
00441 unsigned int entryEpoc = changeEpoc_;
00442
00443 std::deque<GLWWindow *>::reverse_iterator itor;
00444 for (itor = currentStateEntry_->windows_.rbegin();
00445 itor != currentStateEntry_->windows_.rend();
00446 itor++)
00447 {
00448 GLWWindow *window = (*itor);
00449 if (windowVisible(window->getId()))
00450 {
00451 window->mouseUp((int) button, (float) x, (float) y, skipRest);
00452 if (skipRest) break;
00453 if (entryEpoc != changeEpoc_) break;
00454 }
00455 }
00456 }
00457
00458 void GLWWindowManager::mouseDrag(const unsigned state, GameState::MouseButton button,
00459 int x, int y, int dx, int dy, bool &skipRest)
00460 {
00461 if (currentStateEntry_->state_ != state) setCurrentEntry(state);
00462 unsigned int entryEpoc = changeEpoc_;
00463
00464 std::deque<GLWWindow *>::reverse_iterator itor;
00465 for (itor = currentStateEntry_->windows_.rbegin();
00466 itor != currentStateEntry_->windows_.rend();
00467 itor++)
00468 {
00469 GLWWindow *window = (*itor);
00470 if (windowVisible(window->getId()))
00471 {
00472 window->mouseDrag((int) button, (float) x, (float) y, (float) dx, (float) dy, skipRest);
00473 if (skipRest) break;
00474 if (entryEpoc != changeEpoc_) break;
00475 }
00476 }
00477 }
00478
00479 void GLWWindowManager::mouseWheel(const unsigned state,
00480 int x, int y, int z, bool &skipRest)
00481 {
00482 if (currentStateEntry_->state_ != state) setCurrentEntry(state);
00483 unsigned int entryEpoc = changeEpoc_;
00484
00485 std::deque<GLWWindow *>::reverse_iterator itor;
00486 for (itor = currentStateEntry_->windows_.rbegin();
00487 itor != currentStateEntry_->windows_.rend();
00488 itor++)
00489 {
00490 GLWWindow *window = (*itor);
00491 if (windowVisible(window->getId()))
00492 {
00493 window->mouseWheel((float) x, (float) y, (float) z, skipRest);
00494 if (skipRest) break;
00495 if (entryEpoc != changeEpoc_) break;
00496 }
00497 }
00498 }
00499
00500 bool GLWWindowManager::getMenuItems(const char* menuName,
00501 std::list<GLMenuItem> &items)
00502 {
00503 if (currentStateEntry_)
00504 {
00505 std::map<unsigned, GLWWindow *>::iterator itor;
00506 for (itor = idToWindow_.begin();
00507 itor != idToWindow_.end();
00508 itor++)
00509 {
00510 unsigned id = (*itor).first;
00511 GLWWindow *window = (*itor).second;
00512
00513 if (window->getName()[0] != '\0' &&
00514 windowInCurrentState(id))
00515 {
00516 items.push_back(
00517 GLMenuItem(
00518 LANG_RESOURCE(window->getName(), window->getName()),
00519 &window->getToolTip(),
00520 windowVisible(window->getId())));
00521 }
00522 }
00523 }
00524 return true;
00525 }
00526
00527 void GLWWindowManager::menuSelection(const char* menuName,
00528 const int position, GLMenuItem &item)
00529 {
00530 if (currentStateEntry_)
00531 {
00532 int pos = 0;
00533 std::map<unsigned, GLWWindow *>::iterator itor;
00534 for (itor = idToWindow_.begin();
00535 itor != idToWindow_.end();
00536 itor++)
00537 {
00538 unsigned id = (*itor).first;
00539 GLWWindow *window = (*itor).second;
00540
00541 if (window->getName()[0] != '\0' &&
00542 windowInCurrentState(id))
00543 {
00544 if (pos++ == position)
00545 {
00546 if (windowVisible(window->getId()))
00547 {
00548 hideWindow(window->getId());
00549 }
00550 else
00551 {
00552 showWindow(window->getId());
00553 }
00554 return;
00555 }
00556 }
00557 }
00558 }
00559 }
00560
00561 void GLWWindowManager::loadPositions()
00562 {
00563 XMLFile file;
00564 std::string fileName = S3D::getSettingsFile("windowpositions.xml");
00565 if (!file.readFile(fileName))
00566 {
00567 S3D::dialogMessage("GLWWindowManager", S3D::formatStringBuffer(
00568 "Failed to parse \"%s\"\n%s",
00569 fileName.c_str(),
00570 file.getParserError()));
00571 return;
00572 }
00573 if (!file.getRootNode()) return;
00574
00575
00576 XMLNode *display = 0, *positions = 0;
00577 if (!file.getRootNode()->getNamedChild("display", display)) return;
00578 if (!file.getRootNode()->getNamedChild("positions", positions)) return;
00579
00580
00581 int width, height;
00582 if (!display->getNamedChild("width", width)) return;
00583 if (!display->getNamedChild("height", height)) return;
00584
00585
00586
00587 if (width != GLViewPort::getWidth() ||
00588 height != GLViewPort::getHeight())
00589 {
00590 return;
00591 }
00592
00593
00594 std::list<XMLNode *>::iterator childrenItor;
00595 std::list<XMLNode *> &children = positions->getChildren();
00596 for (childrenItor = children.begin();
00597 childrenItor != children.end();
00598 childrenItor++)
00599 {
00600 XMLNode *node = (*childrenItor);
00601
00602
00603 std::string window;
00604 if (!node->getNamedChild("window", window)) return;
00605
00606
00607 std::map<unsigned, GLWWindow *>::iterator winitor;
00608 for (winitor = idToWindow_.begin();
00609 winitor != idToWindow_.end();
00610 winitor++)
00611 {
00612 GLWWindow *w = (*winitor).second;
00613 if (0 == strcmp(w->getName(), window.c_str()))
00614 {
00615 w->loadPosition(node);
00616 break;
00617 }
00618 }
00619 }
00620 }
00621
00622 void GLWWindowManager::savePositions()
00623 {
00624 XMLNode node("positions");
00625
00626 XMLNode *display = new XMLNode("display");
00627 XMLNode *positions = new XMLNode("positions");
00628 node.addChild(display);
00629 node.addChild(positions);
00630
00631
00632 display->addChild(new XMLNode("width", GLViewPort::getWidth()));
00633 display->addChild(new XMLNode("height", GLViewPort::getHeight()));
00634
00635 if (OptionsDisplay::instance()->getSaveWindowPositions())
00636 {
00637
00638 std::map<unsigned, GLWWindow *>::iterator winitor;
00639 for (winitor = idToWindow_.begin();
00640 winitor != idToWindow_.end();
00641 winitor++)
00642 {
00643 GLWWindow *w = (*winitor).second;
00644
00645 if ((w->getWindowState() & GLWWindow::eSavePosition) &&
00646 w->getX() >= 0 && w->getY() >= 0)
00647 {
00648 XMLNode *position = new XMLNode("position");
00649 positions->addChild(position);
00650 position->addChild(new XMLNode("window", w->getName()));
00651 w->savePosition(position);
00652 }
00653 }
00654 }
00655
00656 std::string fileName = S3D::getSettingsFile("windowpositions.xml");
00657 node.writeToFile(fileName);
00658 }