1 #ifndef MWGUI_WINDOWMANAGERIMP_H 2 #define MWGUI_WINDOWMANAGERIMP_H 3 4 /** 5 This class owns and controls all the MW specific windows in the 6 GUI. It can enable/disable Gui mode, and is responsible for sending 7 and retrieving information from the Gui. 8 **/ 9 10 #include <stack> 11 12 #include <osg/ref_ptr> 13 14 #include "../mwbase/windowmanager.hpp" 15 16 #include <components/sdlutil/events.hpp> 17 #include <components/settings/settings.hpp> 18 #include <components/to_utf8/to_utf8.hpp> 19 20 #include "mapwindow.hpp" 21 #include "statswatcher.hpp" 22 #include "textcolours.hpp" 23 24 #include <MyGUI_KeyCode.h> 25 #include <MyGUI_Types.h> 26 27 namespace MyGUI 28 { 29 class Gui; 30 class Widget; 31 class Window; 32 class UString; 33 class ImageBox; 34 } 35 36 namespace MWWorld 37 { 38 class ESMStore; 39 } 40 41 namespace Compiler 42 { 43 class Extensions; 44 } 45 46 namespace Translation 47 { 48 class Storage; 49 } 50 51 namespace osg 52 { 53 class Group; 54 } 55 namespace osgViewer 56 { 57 class Viewer; 58 } 59 60 namespace Resource 61 { 62 class ResourceSystem; 63 } 64 65 namespace SceneUtil 66 { 67 class WorkQueue; 68 } 69 70 namespace SDLUtil 71 { 72 class SDLCursorManager; 73 class VideoWrapper; 74 } 75 76 namespace osgMyGUI 77 { 78 class Platform; 79 } 80 81 namespace Gui 82 { 83 class FontLoader; 84 } 85 86 namespace MWRender 87 { 88 class LocalMap; 89 } 90 91 namespace MWGui 92 { 93 class WindowBase; 94 class HUD; 95 class MapWindow; 96 class MainMenu; 97 class StatsWindow; 98 class InventoryWindow; 99 struct JournalWindow; 100 class CharacterCreation; 101 class DragAndDrop; 102 class ToolTips; 103 class TextInputDialog; 104 class InfoBoxDialog; 105 class MessageBoxManager; 106 class SettingsWindow; 107 class AlchemyWindow; 108 class QuickKeysMenu; 109 class LoadingScreen; 110 class LevelupDialog; 111 class WaitDialog; 112 class SpellCreationDialog; 113 class EnchantingDialog; 114 class TrainingWindow; 115 class SpellIcons; 116 class MerchantRepair; 117 class SoulgemDialog; 118 class Recharge; 119 class CompanionWindow; 120 class VideoWidget; 121 class WindowModal; 122 class ScreenFader; 123 class DebugWindow; 124 class JailScreen; 125 class KeyboardNavigation; 126 127 class WindowManager : 128 public MWBase::WindowManager 129 { 130 public: 131 typedef std::pair<std::string, int> Faction; 132 typedef std::vector<Faction> FactionList; 133 134 WindowManager(SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, 135 const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, 136 ToUTF8::FromType encoding, bool exportFonts, const std::string& versionDescription, const std::string& localPath); 137 virtual ~WindowManager(); 138 139 /// Set the ESMStore to use for retrieving of GUI-related strings. 140 void setStore (const MWWorld::ESMStore& store); 141 142 void initUI(); 143 void loadUserFonts() override; 144 145 Loading::Listener* getLoadingScreen() override; 146 147 /// @note This method will block until the video finishes playing 148 /// (and will continually update the window while doing so) 149 void playVideo(const std::string& name, bool allowSkipping) override; 150 151 /// Warning: do not use MyGUI::InputManager::setKeyFocusWidget directly. Instead use this. 152 void setKeyFocusWidget (MyGUI::Widget* widget) override; 153 154 void setNewGame(bool newgame) override; 155 156 void pushGuiMode(GuiMode mode, const MWWorld::Ptr& arg) override; 157 void pushGuiMode (GuiMode mode) override; 158 void popGuiMode(bool noSound=false) override; 159 void removeGuiMode(GuiMode mode, bool noSound=false) override; ///< can be anywhere in the stack 160 161 void goToJail(int days) override; 162 163 GuiMode getMode() const override; 164 bool containsMode(GuiMode mode) const override; 165 166 bool isGuiMode() const override; 167 168 bool isConsoleMode() const override; 169 170 void toggleVisible(GuiWindow wnd) override; 171 172 void forceHide(MWGui::GuiWindow wnd) override; 173 void unsetForceHide(MWGui::GuiWindow wnd) override; 174 175 /// Disallow all inventory mode windows 176 void disallowAll() override; 177 178 /// Allow one or more windows 179 void allow(GuiWindow wnd) override; 180 181 bool isAllowed(GuiWindow wnd) const override; 182 183 /// \todo investigate, if we really need to expose every single lousy UI element to the outside world 184 MWGui::InventoryWindow* getInventoryWindow() override; 185 MWGui::CountDialog* getCountDialog() override; 186 MWGui::ConfirmationDialog* getConfirmationDialog() override; 187 MWGui::TradeWindow* getTradeWindow() override; 188 189 /// Make the player use an item, while updating GUI state accordingly 190 void useItem(const MWWorld::Ptr& item, bool bypassBeastRestrictions=false) override; 191 192 void updateSpellWindow() override; 193 194 void setConsoleSelectedObject(const MWWorld::Ptr& object) override; 195 196 /// Set time left for the player to start drowning (update the drowning bar) 197 /// @param time time left to start drowning 198 /// @param maxTime how long we can be underwater (in total) until drowning starts 199 void setDrowningTimeLeft (float time, float maxTime) override; 200 201 void changeCell(const MWWorld::CellStore* cell) override; ///< change the active cell 202 203 void setFocusObject(const MWWorld::Ptr& focus) override; 204 void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y) override; 205 206 void getMousePosition(int &x, int &y) override; 207 void getMousePosition(float &x, float &y) override; 208 void setDragDrop(bool dragDrop) override; 209 bool getWorldMouseOver() override; 210 211 float getScalingFactor() override; 212 213 bool toggleFogOfWar() override; 214 bool toggleFullHelp() override; ///< show extra info in item tooltips (owner, script) 215 bool getFullHelp() const override; 216 217 void setActiveMap(int x, int y, bool interior) override; 218 ///< set the indices of the map texture that should be used 219 220 /// sets the visibility of the drowning bar 221 void setDrowningBarVisibility(bool visible) override; 222 223 // sets the visibility of the hud health/magicka/stamina bars 224 void setHMSVisibility(bool visible) override; 225 // sets the visibility of the hud minimap 226 void setMinimapVisibility(bool visible) override; 227 void setWeaponVisibility(bool visible) override; 228 void setSpellVisibility(bool visible) override; 229 void setSneakVisibility(bool visible) override; 230 231 /// activate selected quick key 232 void activateQuickKey (int index) override; 233 /// update activated quick key state (if action executing was delayed for some reason) 234 void updateActivatedQuickKey () override; 235 getSelectedSpell()236 std::string getSelectedSpell() override { return mSelectedSpell; } 237 void setSelectedSpell(const std::string& spellId, int successChancePercent) override; 238 void setSelectedEnchantItem(const MWWorld::Ptr& item) override; 239 const MWWorld::Ptr& getSelectedEnchantItem() const override; 240 void setSelectedWeapon(const MWWorld::Ptr& item) override; 241 const MWWorld::Ptr& getSelectedWeapon() const override; 242 int getFontHeight() const override; 243 void unsetSelectedSpell() override; 244 void unsetSelectedWeapon() override; 245 246 void updateConsoleObjectPtr(const MWWorld::Ptr& currentPtr, const MWWorld::Ptr& newPtr) override; 247 248 void showCrosshair(bool show) override; 249 bool getSubtitlesEnabled() override; 250 251 /// Turn visibility of HUD on or off 252 bool toggleHud() override; 253 254 void disallowMouse() override; 255 void allowMouse() override; 256 void notifyInputActionBound() override; 257 258 void addVisitedLocation(const std::string& name, int x, int y) override; 259 260 ///Hides dialog and schedules dialog to be deleted. 261 void removeDialog(Layout* dialog) override; 262 263 ///Gracefully attempts to exit the topmost GUI mode 264 void exitCurrentGuiMode() override; 265 266 void messageBox (const std::string& message, enum MWGui::ShowInDialogueMode showInDialogueMode = MWGui::ShowInDialogueMode_IfPossible) override; 267 void staticMessageBox(const std::string& message) override; 268 void removeStaticMessageBox() override; 269 void interactiveMessageBox (const std::string& message, 270 const std::vector<std::string>& buttons = std::vector<std::string>(), bool block=false) override; 271 272 int readPressedButton () override; ///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox) 273 274 void update (float duration) override; 275 276 /** 277 * Fetches a GMST string from the store, if there is no setting with the given 278 * ID or it is not a string the default string is returned. 279 * 280 * @param id Identifier for the GMST setting, e.g. "aName" 281 * @param default Default value if the GMST setting cannot be used. 282 */ 283 std::string getGameSettingString(const std::string &id, const std::string &default_) override; 284 285 void processChangedSettings(const Settings::CategorySettingVector& changed) override; 286 287 void windowVisibilityChange(bool visible) override; 288 void windowResized(int x, int y) override; 289 void windowClosed() override; 290 bool isWindowVisible() override; 291 292 void watchActor(const MWWorld::Ptr& ptr) override; 293 MWWorld::Ptr getWatchedActor() const override; 294 295 void executeInConsole (const std::string& path) override; 296 enableRest()297 void enableRest() override { mRestAllowed = true; } 298 bool getRestEnabled() override; 299 getJournalAllowed()300 bool getJournalAllowed() override { return (mAllowed & GW_Magic) != 0; } 301 302 bool getPlayerSleeping() override; 303 void wakeUpPlayer() override; 304 305 void updatePlayer() override; 306 307 void showSoulgemDialog (MWWorld::Ptr item) override; 308 309 void changePointer (const std::string& name) override; 310 311 void setEnemy (const MWWorld::Ptr& enemy) override; 312 313 int getMessagesCount() const override; 314 315 const Translation::Storage& getTranslationDataStorage() const override; 316 317 void onSoulgemDialogButtonPressed (int button); 318 319 bool getCursorVisible() override; 320 321 /// Call when mouse cursor or buttons are used. 322 void setCursorActive(bool active) override; 323 324 /// Clear all savegame-specific data 325 void clear() override; 326 327 void write (ESM::ESMWriter& writer, Loading::Listener& progress) override; 328 void readRecord (ESM::ESMReader& reader, uint32_t type) override; 329 int countSavedGameRecords() const override; 330 331 /// Does the current stack of GUI-windows permit saving? 332 bool isSavingAllowed() const override; 333 334 /// Send exit command to active Modal window **/ 335 void exitCurrentModal() override; 336 337 /// Sets the current Modal 338 /** Used to send exit command to active Modal when Esc is pressed **/ 339 void addCurrentModal(WindowModal* input) override; 340 341 /// Removes the top Modal 342 /** Used when one Modal adds another Modal 343 \param input Pointer to the current modal, to ensure proper modal is removed **/ 344 void removeCurrentModal(WindowModal* input) override; 345 346 void pinWindow (MWGui::GuiWindow window) override; 347 void toggleMaximized(Layout *layout) override; 348 349 /// Fade the screen in, over \a time seconds 350 void fadeScreenIn(const float time, bool clearQueue, float delay) override; 351 /// Fade the screen out to black, over \a time seconds 352 void fadeScreenOut(const float time, bool clearQueue, float delay) override; 353 /// Fade the screen to a specified percentage of black, over \a time seconds 354 void fadeScreenTo(const int percent, const float time, bool clearQueue, float delay) override; 355 /// Darken the screen to a specified percentage 356 void setBlindness(const int percent) override; 357 358 void activateHitOverlay(bool interrupt) override; 359 void setWerewolfOverlay(bool set) override; 360 361 void toggleConsole() override; 362 void toggleDebugWindow() override; 363 364 /// Cycle to next or previous spell 365 void cycleSpell(bool next) override; 366 /// Cycle to next or previous weapon 367 void cycleWeapon(bool next) override; 368 369 void playSound(const std::string& soundId, float volume = 1.f, float pitch = 1.f) override; 370 371 // In WindowManager for now since there isn't a VFS singleton 372 std::string correctIconPath(const std::string& path) override; 373 std::string correctBookartPath(const std::string& path, int width, int height, bool* exists = nullptr) override; 374 std::string correctTexturePath(const std::string& path) override; 375 bool textureExists(const std::string& path) override; 376 377 void addCell(MWWorld::CellStore* cell) override; 378 void removeCell(MWWorld::CellStore* cell) override; 379 void writeFog(MWWorld::CellStore* cell) override; 380 381 const MWGui::TextColours& getTextColours() override; 382 383 bool injectKeyPress(MyGUI::KeyCode key, unsigned int text, bool repeat=false) override; 384 bool injectKeyRelease(MyGUI::KeyCode key) override; 385 386 private: 387 unsigned int mOldUpdateMask; unsigned int mOldCullMask; 388 389 const MWWorld::ESMStore* mStore; 390 Resource::ResourceSystem* mResourceSystem; 391 osg::ref_ptr<SceneUtil::WorkQueue> mWorkQueue; 392 393 osgMyGUI::Platform* mGuiPlatform; 394 osgViewer::Viewer* mViewer; 395 396 std::unique_ptr<Gui::FontLoader> mFontLoader; 397 std::unique_ptr<StatsWatcher> mStatsWatcher; 398 399 bool mConsoleOnlyScripts; 400 401 std::map<MyGUI::Window*, std::string> mTrackedWindows; 402 void trackWindow(Layout* layout, const std::string& name); 403 void onWindowChangeCoord(MyGUI::Window* _sender); 404 405 std::string mSelectedSpell; 406 MWWorld::Ptr mSelectedEnchantItem; 407 MWWorld::Ptr mSelectedWeapon; 408 409 std::vector<WindowModal*> mCurrentModals; 410 411 // Markers placed manually by the player. Must be shared between both map views (the HUD map and the map window). 412 CustomMarkerCollection mCustomMarkers; 413 414 HUD *mHud; 415 MapWindow *mMap; 416 MWRender::LocalMap* mLocalMapRender; 417 ToolTips *mToolTips; 418 StatsWindow *mStatsWindow; 419 MessageBoxManager *mMessageBoxManager; 420 Console *mConsole; 421 DialogueWindow *mDialogueWindow; 422 DragAndDrop* mDragAndDrop; 423 InventoryWindow *mInventoryWindow; 424 ScrollWindow* mScrollWindow; 425 BookWindow* mBookWindow; 426 CountDialog* mCountDialog; 427 TradeWindow* mTradeWindow; 428 SettingsWindow* mSettingsWindow; 429 ConfirmationDialog* mConfirmationDialog; 430 SpellWindow* mSpellWindow; 431 QuickKeysMenu* mQuickKeysMenu; 432 LoadingScreen* mLoadingScreen; 433 WaitDialog* mWaitDialog; 434 SoulgemDialog* mSoulgemDialog; 435 MyGUI::ImageBox* mVideoBackground; 436 VideoWidget* mVideoWidget; 437 ScreenFader* mWerewolfFader; 438 ScreenFader* mBlindnessFader; 439 ScreenFader* mHitFader; 440 ScreenFader* mScreenFader; 441 DebugWindow* mDebugWindow; 442 JailScreen* mJailScreen; 443 444 std::vector<WindowBase*> mWindows; 445 446 Translation::Storage& mTranslationDataStorage; 447 448 CharacterCreation* mCharGen; 449 450 MyGUI::Widget* mInputBlocker; 451 452 bool mCrosshairEnabled; 453 bool mSubtitlesEnabled; 454 bool mHitFaderEnabled; 455 bool mWerewolfOverlayEnabled; 456 bool mHudEnabled; 457 bool mCursorVisible; 458 bool mCursorActive; 459 460 int mPlayerBounty; 461 462 void setCursorVisible(bool visible) override; 463 464 MyGUI::Gui *mGui; // Gui 465 466 struct GuiModeState 467 { GuiModeStateMWGui::WindowManager::GuiModeState468 GuiModeState(WindowBase* window) 469 { 470 mWindows.push_back(window); 471 } GuiModeStateMWGui::WindowManager::GuiModeState472 GuiModeState(const std::vector<WindowBase*>& windows) 473 : mWindows(windows) {} GuiModeStateMWGui::WindowManager::GuiModeState474 GuiModeState() {} 475 476 void update(bool visible); 477 478 std::vector<WindowBase*> mWindows; 479 480 std::string mCloseSound; 481 std::string mOpenSound; 482 }; 483 // Defines the windows that should be shown in a particular GUI mode. 484 std::map<GuiMode, GuiModeState> mGuiModeStates; 485 // The currently active stack of GUI modes (top mode is the one we are in). 486 std::vector<GuiMode> mGuiModes; 487 488 SDLUtil::SDLCursorManager* mCursorManager; 489 490 std::vector<Layout*> mGarbageDialogs; 491 void cleanupGarbage(); 492 493 GuiWindow mShown; // Currently shown windows in inventory mode 494 GuiWindow mForceHidden; // Hidden windows (overrides mShown) 495 496 /* Currently ALLOWED windows in inventory mode. This is used at 497 the start of the game, when windows are enabled one by one 498 through script commands. You can manipulate this through using 499 allow() and disableAll(). 500 */ 501 GuiWindow mAllowed; 502 // is the rest window allowed? 503 bool mRestAllowed; 504 505 void updateVisible(); // Update visibility of all windows based on mode, shown and allowed settings 506 507 void updateMap(); 508 509 int mShowOwned; 510 511 ToUTF8::FromType mEncoding; 512 513 std::string mVersionDescription; 514 515 bool mWindowVisible; 516 517 MWGui::TextColours mTextColours; 518 519 std::unique_ptr<KeyboardNavigation> mKeyboardNavigation; 520 521 SDLUtil::VideoWrapper* mVideoWrapper; 522 523 float mScalingFactor; 524 525 /** 526 * Called when MyGUI tries to retrieve a tag's value. Tags must be denoted in #{tag} notation and will be replaced upon setting a user visible text/property. 527 * Supported syntax: 528 * #{GMSTName}: retrieves String value of the GMST called GMSTName 529 * #{setting=CATEGORY_NAME,SETTING_NAME}: retrieves String value of SETTING_NAME under category CATEGORY_NAME from settings.cfg 530 * #{sCell=CellID}: retrieves translated name of the given CellID (used only by some Morrowind localisations, in others cell ID is == cell name) 531 * #{fontcolour=FontColourName}: retrieves the value of the fallback setting "FontColor_color_<FontColourName>" from openmw.cfg, 532 * in the format "r g b a", float values in range 0-1. Useful for "Colour" and "TextColour" properties in skins. 533 * #{fontcolourhtml=FontColourName}: retrieves the value of the fallback setting "FontColor_color_<FontColourName>" from openmw.cfg, 534 * in the format "#xxxxxx" where x are hexadecimal numbers. Useful in an EditBox's caption to change the color of following text. 535 */ 536 void onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result); 537 538 void onCursorChange(const std::string& name); 539 void onKeyFocusChanged(MyGUI::Widget* widget); 540 541 // Key pressed while playing a video 542 void onVideoKeyPressed(MyGUI::Widget *_sender, MyGUI::KeyCode _key, MyGUI::Char _char); 543 544 void sizeVideo(int screenWidth, int screenHeight); 545 546 void onClipboardChanged(const std::string& _type, const std::string& _data); 547 void onClipboardRequested(const std::string& _type, std::string& _data); 548 549 void createTextures(); 550 void createCursors(); 551 void setMenuTransparency(float value); 552 553 void updatePinnedWindows(); 554 555 void enableScene(bool enable); 556 }; 557 } 558 559 #endif 560