1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-27 21:35:24 +00:00
OpenMW/apps/openmw/mwgui/windowmanagerimp.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

2352 lines
80 KiB
C++
Raw Normal View History

#include "windowmanagerimp.hpp"
2012-08-12 14:07:48 +02:00
#include <algorithm>
2012-08-12 14:07:48 +02:00
#include <cassert>
2020-06-25 21:46:07 +02:00
#include <chrono>
#include <filesystem>
2020-06-25 21:46:07 +02:00
#include <thread>
2012-08-12 14:07:48 +02:00
2015-05-01 03:03:44 +02:00
#include <osgViewer/Viewer>
2015-01-10 02:50:43 +01:00
#include <MyGUI_ClipboardManager.h>
#include <MyGUI_FactoryManager.h>
#include <MyGUI_InputManager.h>
#include <MyGUI_LanguageManager.h>
#include <MyGUI_PointerManager.h>
#include <MyGUI_UString.h>
2012-08-12 14:07:48 +02:00
// For BT_NO_PROFILE
#include <LinearMath/btQuickprof.h>
2015-01-31 23:27:34 +01:00
#include <SDL_clipboard.h>
#include <SDL_keyboard.h>
2018-08-14 23:05:43 +04:00
#include <components/debug/debuglog.hpp>
#include <components/esm3/esmreader.hpp>
#include <components/esm3/esmwriter.hpp>
2015-07-07 19:16:32 +02:00
#include <components/fontloader/fontloader.hpp>
2016-02-05 23:03:53 +01:00
#include <components/resource/imagemanager.hpp>
2015-05-01 01:15:25 +02:00
#include <components/resource/resourcesystem.hpp>
2021-07-22 15:55:30 -07:00
#include <components/resource/scenemanager.hpp>
2015-05-01 01:15:25 +02:00
#include <components/sceneutil/workqueue.hpp>
2015-01-31 23:27:34 +01:00
#include <components/translation/translation.hpp>
2015-11-07 17:45:22 +01:00
#include <components/myguiplatform/additivelayer.hpp>
2015-05-01 01:15:25 +02:00
#include <components/myguiplatform/myguiplatform.hpp>
#include <components/myguiplatform/myguirendermanager.hpp>
#include <components/myguiplatform/scalinglayer.hpp>
2015-05-01 01:15:25 +02:00
2015-05-03 18:35:29 +02:00
#include <components/vfs/manager.hpp>
#include <components/widgets/tags.hpp>
2022-08-15 23:04:54 +02:00
#include <components/widgets/widgets.hpp>
#include <components/misc/frameratelimiter.hpp>
2022-10-02 22:38:37 +02:00
#include <components/l10n/manager.hpp>
2022-01-18 08:12:56 +00:00
#include <components/lua_ui/util.hpp>
2021-11-18 15:19:54 +00:00
2012-08-12 14:07:48 +02:00
#include "../mwbase/inputmanager.hpp"
2015-07-18 19:40:31 +02:00
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/statemanager.hpp"
2019-02-19 01:10:55 +03:00
#include "../mwbase/world.hpp"
2012-08-12 14:07:48 +02:00
#include "../mwrender/vismask.hpp"
2014-02-23 20:11:05 +01:00
#include "../mwworld/cellstore.hpp"
2013-05-11 18:38:27 +02:00
#include "../mwworld/class.hpp"
2015-01-10 03:56:06 +01:00
#include "../mwworld/esmstore.hpp"
#include "../mwworld/player.hpp"
2012-08-12 14:07:48 +02:00
2015-08-21 21:12:39 +12:00
#include "../mwmechanics/actorutil.hpp"
#include "../mwmechanics/npcstats.hpp"
2022-05-13 18:58:00 -07:00
#include "../mwrender/postprocessor.hpp"
2015-05-26 16:40:44 +02:00
2012-08-12 14:07:48 +02:00
#include "alchemywindow.hpp"
2010-11-03 21:21:08 +01:00
#include "backgroundimage.hpp"
2012-05-03 03:33:33 +02:00
#include "bookpage.hpp"
#include "bookwindow.hpp"
2012-05-17 17:15:44 +02:00
#include "companionwindow.hpp"
2012-05-23 05:28:25 +02:00
#include "confirmationdialog.hpp"
2012-09-14 19:44:00 +02:00
#include "console.hpp"
#include "container.hpp"
2012-09-14 19:44:00 +02:00
#include "controllers.hpp"
2012-09-18 18:29:03 +02:00
#include "countdialog.hpp"
#include "cursor.hpp"
#include "debugwindow.hpp"
2012-05-23 05:28:25 +02:00
#include "dialogue.hpp"
#include "enchantingdialog.hpp"
#include "exposedwindow.hpp"
2013-03-23 08:16:46 +01:00
#include "hud.hpp"
#include "inventorywindow.hpp"
#include "itemchargeview.hpp"
2013-05-11 18:38:27 +02:00
#include "itemview.hpp"
#include "itemwidget.hpp"
#include "jailscreen.hpp"
#include "journalviewmodel.hpp"
#include "journalwindow.hpp"
#include "keyboardnavigation.hpp"
#include "levelupdialog.hpp"
2012-09-11 16:37:54 +02:00
#include "loadingscreen.hpp"
#include "mainmenu.hpp"
2013-03-22 14:13:10 +01:00
#include "merchantrepair.hpp"
2022-05-13 18:58:00 -07:00
#include "postprocessorhud.hpp"
#include "quickkeysmenu.hpp"
#include "recharge.hpp"
2013-03-22 14:13:10 +01:00
#include "repair.hpp"
#include "resourceskin.hpp"
#include "screenfader.hpp"
#include "scrollwindow.hpp"
#include "settingswindow.hpp"
#include "spellbuyingwindow.hpp"
#include "spellview.hpp"
#include "spellwindow.hpp"
#include "statswindow.hpp"
2012-10-17 18:03:02 +02:00
#include "tradewindow.hpp"
#include "trainingwindow.hpp"
2012-09-26 18:30:47 +02:00
#include "travelwindow.hpp"
#include "ustring.hpp"
#include "videowidget.hpp"
#include "waitdialog.hpp"
2013-04-17 18:56:48 -04:00
namespace MWGui
{
WindowManager::WindowManager(SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot,
Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::filesystem::path& logpath,
bool consoleOnlyScripts, Translation::Storage& translationDataStorage, ToUTF8::FromType encoding,
const std::string& versionDescription, bool useShaders)
: mOldUpdateMask(0)
, mOldCullMask(0)
, mStore(nullptr)
, mResourceSystem(resourceSystem)
, mWorkQueue(workQueue)
, mViewer(viewer)
2015-05-01 03:03:44 +02:00
, mConsoleOnlyScripts(consoleOnlyScripts)
2015-04-25 13:37:42 -05:00
, mCurrentModals()
2018-10-09 10:21:12 +04:00
, mHud(nullptr)
, mMap(nullptr)
, mStatsWindow(nullptr)
, mConsole(nullptr)
, mDialogueWindow(nullptr)
, mInventoryWindow(nullptr)
, mScrollWindow(nullptr)
, mBookWindow(nullptr)
, mCountDialog(nullptr)
, mTradeWindow(nullptr)
, mSettingsWindow(nullptr)
, mConfirmationDialog(nullptr)
, mSpellWindow(nullptr)
, mQuickKeysMenu(nullptr)
, mLoadingScreen(nullptr)
, mWaitDialog(nullptr)
, mVideoBackground(nullptr)
, mVideoWidget(nullptr)
, mWerewolfFader(nullptr)
, mBlindnessFader(nullptr)
, mHitFader(nullptr)
, mScreenFader(nullptr)
, mDebugWindow(nullptr)
2022-05-13 18:58:00 -07:00
, mPostProcessorHud(nullptr)
2018-10-09 10:21:12 +04:00
, mJailScreen(nullptr)
, mContainerWindow(nullptr)
, mTranslationDataStorage(translationDataStorage)
2018-10-09 10:21:12 +04:00
, mInputBlocker(nullptr)
, mCrosshairEnabled(Settings::Manager::getBool("crosshair", "HUD"))
, mSubtitlesEnabled(Settings::Manager::getBool("subtitles", "GUI"))
, mHitFaderEnabled(Settings::Manager::getBool("hit fader", "GUI"))
, mWerewolfOverlayEnabled(Settings::Manager::getBool("werewolf overlay", "GUI"))
, mHudEnabled(true)
, mCursorVisible(true)
, mCursorActive(true)
, mPlayerBounty(-1)
, mGuiModes()
2013-04-17 18:56:48 -04:00
, mGarbageDialogs()
, mShown(GW_ALL)
2013-08-05 23:15:26 +02:00
, mForceHidden(GW_None)
2013-05-15 17:54:18 +02:00
, mAllowed(GW_ALL)
, mRestAllowed(true)
2015-07-18 17:13:20 +02:00
, mShowOwned(0)
, mEncoding(encoding)
, mVersionDescription(versionDescription)
, mWindowVisible(true)
2013-04-17 18:56:48 -04:00
{
int w, h;
SDL_GetWindowSize(window, &w, &h);
int dw, dh;
SDL_GL_GetDrawableSize(window, &dw, &dh);
mScalingFactor = std::clamp(Settings::Manager::getFloat("scaling factor", "GUI"), 0.5f, 8.f) * (dw / w);
2022-08-31 21:07:59 +02:00
mGuiPlatform = std::make_unique<osgMyGUI::Platform>(viewer, guiRoot, resourceSystem->getImageManager(),
resourceSystem->getVFS(), mScalingFactor, "mygui", logpath / "MyGUI.log");
2022-08-31 21:07:59 +02:00
mGui = std::make_unique<MyGUI::Gui>();
2015-05-03 18:35:29 +02:00
mGui->initialise("");
2013-04-17 18:56:48 -04:00
2015-05-02 18:06:54 +02:00
createTextures();
MyGUI::LanguageManager::getInstance().eventRequestTag = MyGUI::newDelegate(this, &WindowManager::onRetrieveTag);
2013-06-06 22:13:30 +02:00
// Load fonts
2022-07-09 19:58:40 +04:00
mFontLoader = std::make_unique<Gui::FontLoader>(encoding, resourceSystem->getVFS(), mScalingFactor);
2013-06-06 22:13:30 +02:00
2013-04-17 18:56:48 -04:00
// Register own widgets with MyGUI
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWSkill>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWAttribute>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWSpell>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWEffectList>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWSpellEffect>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWDynamicStat>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Window>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<VideoWidget>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<BackgroundImage>("Widget");
2015-11-07 17:45:22 +01:00
MyGUI::FactoryManager::getInstance().registerFactory<osgMyGUI::AdditiveLayer>("Layer");
MyGUI::FactoryManager::getInstance().registerFactory<osgMyGUI::ScalingLayer>("Layer");
2022-05-13 18:58:00 -07:00
BookPage::registerMyGUIComponents();
PostProcessorHud::registerMyGUIComponents();
2013-05-11 18:38:27 +02:00
ItemView::registerComponents();
ItemChargeView::registerComponents();
ItemWidget::registerComponents();
SpellView::registerComponents();
2014-09-25 20:28:00 +02:00
Gui::registerAllWidgets();
2021-11-18 15:19:54 +00:00
LuaUi::registerAllWidgets();
2013-04-17 18:56:48 -04:00
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Controllers::ControllerFollowMouse>("Controller");
2013-04-17 18:56:48 -04:00
MyGUI::FactoryManager::getInstance().registerFactory<ResourceImageSetPointerFix>(
"Resource", "ResourceImageSetPointer");
MyGUI::FactoryManager::getInstance().registerFactory<AutoSizedResourceSkin>(
"Resource", "AutoSizedResourceSkin");
2013-04-17 18:56:48 -04:00
MyGUI::ResourceManager::getInstance().load("core.xml");
2015-05-03 16:58:05 +02:00
bool keyboardNav = Settings::Manager::getBool("keyboard navigation", "GUI");
2022-05-29 13:24:48 +02:00
mKeyboardNavigation = std::make_unique<KeyboardNavigation>();
mKeyboardNavigation->setEnabled(keyboardNav);
Gui::ImageButton::setDefaultNeedKeyFocus(keyboardNav);
2022-08-31 21:07:59 +02:00
auto loadingScreen = std::make_unique<LoadingScreen>(mResourceSystem, mViewer);
mLoadingScreen = loadingScreen.get();
mWindows.push_back(std::move(loadingScreen));
2015-05-03 16:58:05 +02:00
// set up the hardware cursor manager
2022-08-31 21:07:59 +02:00
mCursorManager = std::make_unique<SDLUtil::SDLCursorManager>();
MyGUI::PointerManager::getInstance().eventChangeMousePointer
+= MyGUI::newDelegate(this, &WindowManager::onCursorChange);
MyGUI::InputManager::getInstance().eventChangeKeyFocus
+= MyGUI::newDelegate(this, &WindowManager::onKeyFocusChanged);
// Create all cursors in advance
createCursors();
onCursorChange(MyGUI::PointerManager::getInstance().getDefaultPointer());
mCursorManager->setEnabled(true);
// hide mygui's pointer
MyGUI::PointerManager::getInstance().setVisible(false);
mVideoBackground = MyGUI::Gui::getInstance().createWidgetReal<MyGUI::ImageBox>(
2022-02-26 13:54:42 +00:00
"ImageBox", 0, 0, 1, 1, MyGUI::Align::Default, "Video");
mVideoBackground->setImageTexture("black");
mVideoBackground->setVisible(false);
mVideoBackground->setNeedMouseFocus(true);
mVideoBackground->setNeedKeyFocus(true);
mVideoWidget = mVideoBackground->createWidgetReal<VideoWidget>("ImageBox", 0, 0, 1, 1, MyGUI::Align::Default);
mVideoWidget->setNeedMouseFocus(true);
mVideoWidget->setNeedKeyFocus(true);
2015-05-01 03:03:44 +02:00
mVideoWidget->setVFS(resourceSystem->getVFS());
// Removes default MyGUI system clipboard implementation, which supports windows only
MyGUI::ClipboardManager::getInstance().eventClipboardChanged.clear();
MyGUI::ClipboardManager::getInstance().eventClipboardRequested.clear();
MyGUI::ClipboardManager::getInstance().eventClipboardChanged
+= MyGUI::newDelegate(this, &WindowManager::onClipboardChanged);
MyGUI::ClipboardManager::getInstance().eventClipboardRequested
+= MyGUI::newDelegate(this, &WindowManager::onClipboardRequested);
2015-07-18 17:13:20 +02:00
mShowOwned = Settings::Manager::getInt("show owned", "Game");
2022-08-31 21:07:59 +02:00
mVideoWrapper = std::make_unique<SDLUtil::VideoWrapper>(window, viewer);
mVideoWrapper->setGammaContrast(
Settings::Manager::getFloat("gamma", "Video"), Settings::Manager::getFloat("contrast", "Video"));
2020-06-05 18:22:53 +04:00
2021-07-22 15:55:30 -07:00
if (useShaders)
mGuiPlatform->getRenderManagerPtr()->enableShaders(mResourceSystem->getSceneManager()->getShaderManager());
2022-05-29 13:24:48 +02:00
mStatsWatcher = std::make_unique<StatsWatcher>();
}
void WindowManager::initUI()
{
// Get size info from the Gui object
2013-04-17 18:56:48 -04:00
int w = MyGUI::RenderManager::getInstance().getViewSize().width;
int h = MyGUI::RenderManager::getInstance().getViewSize().height;
mTextColours.loadColours();
2017-07-24 13:25:01 +02:00
2022-08-31 21:07:59 +02:00
mDragAndDrop = std::make_unique<DragAndDrop>();
2013-04-17 18:56:48 -04:00
2022-08-31 21:07:59 +02:00
auto recharge = std::make_unique<Recharge>();
mGuiModeStates[GM_Recharge] = GuiModeState(recharge.get());
mWindows.push_back(std::move(recharge));
2022-08-31 21:07:59 +02:00
auto menu = std::make_unique<MainMenu>(w, h, mResourceSystem->getVFS(), mVersionDescription);
mGuiModeStates[GM_MainMenu] = GuiModeState(menu.get());
mWindows.push_back(std::move(menu));
2022-08-31 21:07:59 +02:00
mLocalMapRender = std::make_unique<MWRender::LocalMap>(mViewer->getSceneData()->asGroup());
auto map = std::make_unique<MapWindow>(mCustomMarkers, mDragAndDrop.get(), mLocalMapRender.get(), mWorkQueue);
mMap = map.get();
mWindows.push_back(std::move(map));
2017-04-21 00:50:22 +02:00
mMap->renderGlobalMap();
2013-12-03 18:42:35 +01:00
trackWindow(mMap, "map");
2022-08-31 21:07:59 +02:00
auto statsWindow = std::make_unique<StatsWindow>(mDragAndDrop.get());
mStatsWindow = statsWindow.get();
mWindows.push_back(std::move(statsWindow));
2013-12-03 18:42:35 +01:00
trackWindow(mStatsWindow, "stats");
2022-08-31 21:07:59 +02:00
auto inventoryWindow = std::make_unique<InventoryWindow>(
mDragAndDrop.get(), mViewer->getSceneData()->asGroup(), mResourceSystem);
mInventoryWindow = inventoryWindow.get();
mWindows.push_back(std::move(inventoryWindow));
2022-08-31 21:07:59 +02:00
auto spellWindow = std::make_unique<SpellWindow>(mDragAndDrop.get());
mSpellWindow = spellWindow.get();
mWindows.push_back(std::move(spellWindow));
trackWindow(mSpellWindow, "spells");
mGuiModeStates[GM_Inventory] = GuiModeState({ mMap, mInventoryWindow, mSpellWindow, mStatsWindow });
mGuiModeStates[GM_None] = GuiModeState({ mMap, mInventoryWindow, mSpellWindow, mStatsWindow });
2022-08-31 21:07:59 +02:00
auto tradeWindow = std::make_unique<TradeWindow>();
mTradeWindow = tradeWindow.get();
mWindows.push_back(std::move(tradeWindow));
trackWindow(mTradeWindow, "barter");
mGuiModeStates[GM_Barter] = GuiModeState({ mInventoryWindow, mTradeWindow });
2022-08-31 21:07:59 +02:00
auto console = std::make_unique<Console>(w, h, mConsoleOnlyScripts);
mConsole = console.get();
mWindows.push_back(std::move(console));
2013-12-03 18:42:35 +01:00
trackWindow(mConsole, "console");
bool questList = mResourceSystem->getVFS()->exists("textures/tx_menubook_options_over.dds");
2022-08-31 21:07:59 +02:00
auto journal = JournalWindow::create(JournalViewModel::create(), questList, mEncoding);
mGuiModeStates[GM_Journal] = GuiModeState(journal.get());
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID Slowly going through all the changes to make, still hundreds of errors a lot of functions/structures use std::string or stringview to designate an ID. So it takes time Continues slowly replacing ids. There are technically more and more compilation errors I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type Continue moving forward, changes to the stores slowly moving along Starting to see the fruit of those changes. still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type. More replacements. Things are starting to get easier I can see more and more often the issue is that the function is awaiting a RefId, but is given a string there is less need to go down functions and to fix a long list of them. Still moving forward, and for the first time error count is going down! Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably Cells are back to using string for the name, haven't fixed everything yet. Many other changes Under the bar of 400 compilation errors. more good progress <100 compile errors! More progress Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string some more progress on other fronts Mostly game settings clean one error opened a lot of other errors. Down to 18, but more will prbably appear only link errors left?? Fixed link errors OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
mGuiModeStates[GM_Journal].mCloseSound = ESM::RefId::stringRefId("book close");
mGuiModeStates[GM_Journal].mOpenSound = ESM::RefId::stringRefId("book open");
2022-08-31 21:07:59 +02:00
mWindows.push_back(std::move(journal));
2022-08-31 21:07:59 +02:00
mMessageBoxManager = std::make_unique<MessageBoxManager>(
mStore->get<ESM::GameSetting>().find("fMessageTimePerChar")->mValue.getFloat());
2022-08-31 21:07:59 +02:00
auto spellBuyingWindow = std::make_unique<SpellBuyingWindow>();
mGuiModeStates[GM_SpellBuying] = GuiModeState(spellBuyingWindow.get());
mWindows.push_back(std::move(spellBuyingWindow));
2022-08-31 21:07:59 +02:00
auto travelWindow = std::make_unique<TravelWindow>();
mGuiModeStates[GM_Travel] = GuiModeState(travelWindow.get());
mWindows.push_back(std::move(travelWindow));
2022-08-31 21:07:59 +02:00
auto dialogueWindow = std::make_unique<DialogueWindow>();
mDialogueWindow = dialogueWindow.get();
mWindows.push_back(std::move(dialogueWindow));
2013-12-03 18:42:35 +01:00
trackWindow(mDialogueWindow, "dialogue");
mGuiModeStates[GM_Dialogue] = GuiModeState(mDialogueWindow);
mTradeWindow->eventTradeDone += MyGUI::newDelegate(mDialogueWindow, &DialogueWindow::onTradeComplete);
2022-08-31 21:07:59 +02:00
auto containerWindow = std::make_unique<ContainerWindow>(mDragAndDrop.get());
mContainerWindow = containerWindow.get();
mWindows.push_back(std::move(containerWindow));
trackWindow(mContainerWindow, "container");
mGuiModeStates[GM_Container] = GuiModeState({ mContainerWindow, mInventoryWindow });
2022-08-31 21:07:59 +02:00
auto hud = std::make_unique<HUD>(mCustomMarkers, mDragAndDrop.get(), mLocalMapRender.get());
mHud = hud.get();
mWindows.push_back(std::move(hud));
2022-08-31 21:07:59 +02:00
mToolTips = std::make_unique<ToolTips>();
2022-08-31 21:07:59 +02:00
auto scrollWindow = std::make_unique<ScrollWindow>();
mScrollWindow = scrollWindow.get();
mWindows.push_back(std::move(scrollWindow));
mGuiModeStates[GM_Scroll] = GuiModeState(mScrollWindow);
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID Slowly going through all the changes to make, still hundreds of errors a lot of functions/structures use std::string or stringview to designate an ID. So it takes time Continues slowly replacing ids. There are technically more and more compilation errors I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type Continue moving forward, changes to the stores slowly moving along Starting to see the fruit of those changes. still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type. More replacements. Things are starting to get easier I can see more and more often the issue is that the function is awaiting a RefId, but is given a string there is less need to go down functions and to fix a long list of them. Still moving forward, and for the first time error count is going down! Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably Cells are back to using string for the name, haven't fixed everything yet. Many other changes Under the bar of 400 compilation errors. more good progress <100 compile errors! More progress Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string some more progress on other fronts Mostly game settings clean one error opened a lot of other errors. Down to 18, but more will prbably appear only link errors left?? Fixed link errors OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
mGuiModeStates[GM_Scroll].mOpenSound = ESM::RefId::stringRefId("scroll");
mGuiModeStates[GM_Scroll].mCloseSound = ESM::RefId::stringRefId("scroll");
2022-08-31 21:07:59 +02:00
auto bookWindow = std::make_unique<BookWindow>();
mBookWindow = bookWindow.get();
mWindows.push_back(std::move(bookWindow));
mGuiModeStates[GM_Book] = GuiModeState(mBookWindow);
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID Slowly going through all the changes to make, still hundreds of errors a lot of functions/structures use std::string or stringview to designate an ID. So it takes time Continues slowly replacing ids. There are technically more and more compilation errors I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type Continue moving forward, changes to the stores slowly moving along Starting to see the fruit of those changes. still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type. More replacements. Things are starting to get easier I can see more and more often the issue is that the function is awaiting a RefId, but is given a string there is less need to go down functions and to fix a long list of them. Still moving forward, and for the first time error count is going down! Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably Cells are back to using string for the name, haven't fixed everything yet. Many other changes Under the bar of 400 compilation errors. more good progress <100 compile errors! More progress Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string some more progress on other fronts Mostly game settings clean one error opened a lot of other errors. Down to 18, but more will prbably appear only link errors left?? Fixed link errors OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
mGuiModeStates[GM_Book].mOpenSound = ESM::RefId::stringRefId("book open");
mGuiModeStates[GM_Book].mCloseSound = ESM::RefId::stringRefId("book close");
2022-08-31 21:07:59 +02:00
auto countDialog = std::make_unique<CountDialog>();
mCountDialog = countDialog.get();
mWindows.push_back(std::move(countDialog));
2022-08-31 21:07:59 +02:00
auto settingsWindow = std::make_unique<SettingsWindow>();
mSettingsWindow = settingsWindow.get();
mWindows.push_back(std::move(settingsWindow));
trackWindow(mSettingsWindow, "settings");
mGuiModeStates[GM_Settings] = GuiModeState(mSettingsWindow);
2022-08-31 21:07:59 +02:00
auto confirmationDialog = std::make_unique<ConfirmationDialog>();
mConfirmationDialog = confirmationDialog.get();
mWindows.push_back(std::move(confirmationDialog));
2022-08-31 21:07:59 +02:00
auto alchemyWindow = std::make_unique<AlchemyWindow>();
trackWindow(alchemyWindow.get(), "alchemy");
mGuiModeStates[GM_Alchemy] = GuiModeState(alchemyWindow.get());
mWindows.push_back(std::move(alchemyWindow));
2022-08-31 21:07:59 +02:00
auto quickKeysMenu = std::make_unique<QuickKeysMenu>();
mQuickKeysMenu = quickKeysMenu.get();
mWindows.push_back(std::move(quickKeysMenu));
mGuiModeStates[GM_QuickKeysMenu] = GuiModeState(mQuickKeysMenu);
2022-08-31 21:07:59 +02:00
auto levelupDialog = std::make_unique<LevelupDialog>();
mGuiModeStates[GM_Levelup] = GuiModeState(levelupDialog.get());
mWindows.push_back(std::move(levelupDialog));
2022-08-31 21:07:59 +02:00
auto waitDialog = std::make_unique<WaitDialog>();
mWaitDialog = waitDialog.get();
mWindows.push_back(std::move(waitDialog));
mGuiModeStates[GM_Rest] = GuiModeState({ mWaitDialog->getProgressBar(), mWaitDialog });
2022-08-31 21:07:59 +02:00
auto spellCreationDialog = std::make_unique<SpellCreationDialog>();
mGuiModeStates[GM_SpellCreation] = GuiModeState(spellCreationDialog.get());
mWindows.push_back(std::move(spellCreationDialog));
2022-08-31 21:07:59 +02:00
auto enchantingDialog = std::make_unique<EnchantingDialog>();
mGuiModeStates[GM_Enchanting] = GuiModeState(enchantingDialog.get());
mWindows.push_back(std::move(enchantingDialog));
2022-08-31 21:07:59 +02:00
auto trainingWindow = std::make_unique<TrainingWindow>();
mGuiModeStates[GM_Training] = GuiModeState({ trainingWindow->getProgressBar(), trainingWindow.get() });
mWindows.push_back(std::move(trainingWindow));
2022-08-31 21:07:59 +02:00
auto merchantRepair = std::make_unique<MerchantRepair>();
mGuiModeStates[GM_MerchantRepair] = GuiModeState(merchantRepair.get());
mWindows.push_back(std::move(merchantRepair));
2022-08-31 21:07:59 +02:00
auto repair = std::make_unique<Repair>();
mGuiModeStates[GM_Repair] = GuiModeState(repair.get());
mWindows.push_back(std::move(repair));
2022-08-31 21:07:59 +02:00
mSoulgemDialog = std::make_unique<SoulgemDialog>(mMessageBoxManager.get());
2022-08-31 21:07:59 +02:00
auto companionWindow = std::make_unique<CompanionWindow>(mDragAndDrop.get(), mMessageBoxManager.get());
trackWindow(companionWindow.get(), "companion");
mGuiModeStates[GM_Companion] = GuiModeState({ mInventoryWindow, companionWindow.get() });
mWindows.push_back(std::move(companionWindow));
2022-08-31 21:07:59 +02:00
auto jailScreen = std::make_unique<JailScreen>();
mJailScreen = jailScreen.get();
mWindows.push_back(std::move(jailScreen));
mGuiModeStates[GM_Jail] = GuiModeState(mJailScreen);
std::string werewolfFaderTex = "textures\\werewolfoverlay.dds";
if (mResourceSystem->getVFS()->exists(werewolfFaderTex))
{
2022-08-31 21:07:59 +02:00
auto werewolfFader = std::make_unique<ScreenFader>(werewolfFaderTex);
mWerewolfFader = werewolfFader.get();
mWindows.push_back(std::move(werewolfFader));
}
2022-08-31 21:07:59 +02:00
auto blindnessFader = std::make_unique<ScreenFader>("black");
mBlindnessFader = blindnessFader.get();
mWindows.push_back(std::move(blindnessFader));
// fall back to player_hit_01.dds if bm_player_hit_01.dds is not available
std::string hitFaderTexture = "textures\\bm_player_hit_01.dds";
const std::string hitFaderLayout = "openmw_screen_fader_hit.layout";
MyGUI::FloatCoord hitFaderCoord(0, 0, 1, 1);
2015-05-03 18:35:29 +02:00
if (!mResourceSystem->getVFS()->exists(hitFaderTexture))
{
2015-05-03 18:35:29 +02:00
hitFaderTexture = "textures\\player_hit_01.dds";
hitFaderCoord = MyGUI::FloatCoord(0.2, 0.25, 0.6, 0.5);
}
2022-08-31 21:07:59 +02:00
auto hitFader = std::make_unique<ScreenFader>(hitFaderTexture, hitFaderLayout, hitFaderCoord);
mHitFader = hitFader.get();
mWindows.push_back(std::move(hitFader));
2022-08-31 21:07:59 +02:00
auto screenFader = std::make_unique<ScreenFader>("black");
mScreenFader = screenFader.get();
mWindows.push_back(std::move(screenFader));
2022-08-31 21:07:59 +02:00
auto debugWindow = std::make_unique<DebugWindow>();
mDebugWindow = debugWindow.get();
mWindows.push_back(std::move(debugWindow));
2013-04-17 18:56:48 -04:00
2022-08-31 21:07:59 +02:00
auto postProcessorHud = std::make_unique<PostProcessorHud>();
mPostProcessorHud = postProcessorHud.get();
mWindows.push_back(std::move(postProcessorHud));
2022-05-13 18:58:00 -07:00
trackWindow(mPostProcessorHud, "postprocessor");
2015-11-07 17:48:36 +01:00
mInputBlocker = MyGUI::Gui::getInstance().createWidget<MyGUI::Widget>(
"", 0, 0, w, h, MyGUI::Align::Stretch, "InputBlocker");
2013-04-17 18:56:48 -04:00
mHud->setVisible(true);
2013-04-17 18:56:48 -04:00
2022-08-31 21:07:59 +02:00
mCharGen = std::make_unique<CharacterCreation>(mViewer->getSceneData()->asGroup(), mResourceSystem);
2013-04-17 18:56:48 -04:00
updatePinnedWindows();
2013-04-17 18:56:48 -04:00
// Set up visibility
updateVisible();
2020-06-05 18:22:53 +04:00
mStatsWatcher->addListener(mHud);
mStatsWatcher->addListener(mStatsWindow);
2022-08-31 21:07:59 +02:00
mStatsWatcher->addListener(mCharGen.get());
}
2018-06-18 13:43:39 +04:00
int WindowManager::getFontHeight() const
{
2020-05-28 23:09:10 +04:00
return mFontLoader->getFontHeight();
2018-06-18 13:43:39 +04:00
}
2013-05-15 17:54:18 +02:00
void WindowManager::setNewGame(bool newgame)
{
2013-05-15 17:54:18 +02:00
if (newgame)
{
2013-05-15 17:54:18 +02:00
disallowAll();
2020-06-05 18:22:53 +04:00
2022-08-31 21:07:59 +02:00
mStatsWatcher->removeListener(mCharGen.get());
mCharGen = std::make_unique<CharacterCreation>(mViewer->getSceneData()->asGroup(), mResourceSystem);
mStatsWatcher->addListener(mCharGen.get());
}
2013-05-15 17:54:18 +02:00
else
allow(GW_ALL);
mStatsWatcher->forceUpdate();
2013-05-15 17:54:18 +02:00
}
2012-05-29 12:35:03 +02:00
2013-04-17 18:56:48 -04:00
WindowManager::~WindowManager()
{
try
{
2022-01-18 08:12:56 +00:00
LuaUi::clearUserInterface();
2020-06-05 18:22:53 +04:00
mStatsWatcher.reset();
MyGUI::LanguageManager::getInstance().eventRequestTag.clear();
MyGUI::PointerManager::getInstance().eventChangeMousePointer.clear();
MyGUI::InputManager::getInstance().eventChangeKeyFocus.clear();
MyGUI::ClipboardManager::getInstance().eventClipboardChanged.clear();
MyGUI::ClipboardManager::getInstance().eventClipboardRequested.clear();
2015-01-31 01:31:41 +01:00
mWindows.clear();
2022-08-31 21:07:59 +02:00
mMessageBoxManager.reset();
mToolTips.reset();
mCharGen.reset();
2015-01-31 01:31:41 +01:00
mKeyboardNavigation.reset();
cleanupGarbage();
2015-04-24 23:30:30 +02:00
mFontLoader.reset();
2015-05-03 17:52:50 +02:00
mGui->shutdown();
2015-05-08 15:10:17 +02:00
mGuiPlatform->shutdown();
}
catch (const MyGUI::Exception& e)
{
Log(Debug::Error) << "Error in the destructor: " << e.what();
}
2013-04-17 18:56:48 -04:00
}
void WindowManager::setStore(const MWWorld::ESMStore& store)
{
mStore = &store;
}
2013-04-17 18:56:48 -04:00
void WindowManager::cleanupGarbage()
{
// Delete any dialogs which are no longer in use
mGarbageDialogs.clear();
}
void WindowManager::enableScene(bool enable)
{
unsigned int disablemask = MWRender::Mask_GUI | MWRender::Mask_PreCompile;
if (!enable && getCullMask() != disablemask)
{
mOldUpdateMask = mViewer->getUpdateVisitor()->getTraversalMask();
mOldCullMask = getCullMask();
mViewer->getUpdateVisitor()->setTraversalMask(disablemask);
setCullMask(disablemask);
}
else if (enable && getCullMask() == disablemask)
{
mViewer->getUpdateVisitor()->setTraversalMask(mOldUpdateMask);
setCullMask(mOldCullMask);
}
}
void WindowManager::updateConsoleObjectPtr(const MWWorld::Ptr& currentPtr, const MWWorld::Ptr& newPtr)
{
mConsole->updateSelectedObjectPtr(currentPtr, newPtr);
}
2013-04-17 18:56:48 -04:00
void WindowManager::updateVisible()
{
bool loading = (getMode() == GM_Loading || getMode() == GM_LoadingWallpaper);
bool mainmenucover = containsMode(GM_MainMenu)
&& MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_NoGame;
enableScene(!loading && !mainmenucover);
if (!mMap)
return; // UI not created yet
2013-04-17 18:56:48 -04:00
mHud->setVisible(mHudEnabled && !loading);
mToolTips->setVisible(mHudEnabled && !loading);
2013-04-17 18:56:48 -04:00
bool gameMode = !isGuiMode();
MWBase::Environment::get().getInputManager()->changeInputMode(!gameMode);
2013-04-17 18:56:48 -04:00
mInputBlocker->setVisible(gameMode);
if (loading)
setCursorVisible(mMessageBoxManager && mMessageBoxManager->isInteractiveMessageBox());
else
setCursorVisible(!gameMode);
2013-04-17 18:56:48 -04:00
if (gameMode)
setKeyFocusWidget(nullptr);
2013-04-17 18:56:48 -04:00
2013-08-12 10:39:45 +02:00
// Icons of forced hidden windows are displayed
setMinimapVisibility((mAllowed & GW_Map) && (!mMap->pinned() || (mForceHidden & GW_Map)));
setWeaponVisibility(
(mAllowed & GW_Inventory) && (!mInventoryWindow->pinned() || (mForceHidden & GW_Inventory)));
setSpellVisibility((mAllowed & GW_Magic) && (!mSpellWindow->pinned() || (mForceHidden & GW_Magic)));
setHMSVisibility((mAllowed & GW_Stats) && (!mStatsWindow->pinned() || (mForceHidden & GW_Stats)));
2013-04-17 18:56:48 -04:00
mInventoryWindow->setGuiMode(getMode());
// If in game mode (or interactive messagebox), show the pinned windows
if (mGuiModes.empty())
2012-03-31 21:29:46 +02:00
{
mMap->setVisible(mMap->pinned() && !isConsoleMode() && !(mForceHidden & GW_Map) && (mAllowed & GW_Map));
mStatsWindow->setVisible(
mStatsWindow->pinned() && !isConsoleMode() && !(mForceHidden & GW_Stats) && (mAllowed & GW_Stats));
mInventoryWindow->setVisible(mInventoryWindow->pinned() && !isConsoleMode()
&& !(mForceHidden & GW_Inventory) && (mAllowed & GW_Inventory));
mSpellWindow->setVisible(
mSpellWindow->pinned() && !isConsoleMode() && !(mForceHidden & GW_Magic) && (mAllowed & GW_Magic));
return;
}
else if (getMode() != GM_Inventory)
{
mMap->setVisible(false);
mStatsWindow->setVisible(false);
mSpellWindow->setVisible(false);
mHud->setDrowningBarVisible(false);
2017-10-03 22:07:56 +00:00
mInventoryWindow->setVisible(
getMode() == GM_Container || getMode() == GM_Barter || getMode() == GM_Companion);
}
GuiMode mode = mGuiModes.back();
mInventoryWindow->setTrading(mode == GM_Barter);
if (getMode() == GM_Inventory)
{
// For the inventory mode, compute the effective set of windows to show.
// This is controlled both by what windows the
// user has opened/closed (the 'shown' variable) and by what
// windows we are allowed to show (the 'allowed' var.)
int eff = mShown & mAllowed & ~mForceHidden;
mMap->setVisible(eff & GW_Map);
mInventoryWindow->setVisible(eff & GW_Inventory);
mSpellWindow->setVisible(eff & GW_Magic);
mStatsWindow->setVisible(eff & GW_Stats);
}
switch (mode)
{
// FIXME: refactor chargen windows to use modes properly (or not use them at all)
case GM_Name:
case GM_Race:
case GM_Class:
case GM_ClassPick:
case GM_ClassCreate:
case GM_Birth:
case GM_ClassGenerate:
case GM_Review:
mCharGen->spawnDialog(mode);
break;
default:
break;
2013-04-17 18:56:48 -04:00
}
}
void WindowManager::setDrowningTimeLeft(float time, float maxTime)
{
mHud->setDrowningTimeLeft(time, maxTime);
}
void WindowManager::removeDialog(std::unique_ptr<Layout>&& dialog)
2013-04-17 18:56:48 -04:00
{
if (!dialog)
return;
dialog->setVisible(false);
mGarbageDialogs.push_back(std::move(dialog));
2013-04-17 18:56:48 -04:00
}
void WindowManager::exitCurrentGuiMode()
{
if (mDragAndDrop && mDragAndDrop->mIsOnDragAndDrop)
{
mDragAndDrop->finish();
return;
}
2017-09-23 12:18:39 +02:00
GuiModeState& state = mGuiModeStates[mGuiModes.back()];
2022-08-31 21:07:59 +02:00
for (const auto& window : state.mWindows)
2017-09-23 12:18:39 +02:00
{
if (!window->exit())
{
// unable to exit window, but give access to main menu
if (!MyGUI::InputManager::getInstance().isModalAny() && getMode() != GM_MainMenu)
pushGuiMode(GM_MainMenu);
2017-09-23 12:18:39 +02:00
return;
}
}
2017-09-23 12:18:39 +02:00
popGuiMode();
}
void WindowManager::interactiveMessageBox(
std::string_view message, const std::vector<std::string>& buttons, bool block)
2013-04-17 18:56:48 -04:00
{
mMessageBoxManager->createInteractiveMessageBox(message, buttons);
updateVisible();
if (block)
{
Misc::FrameRateLimiter frameRateLimiter
= Misc::makeFrameRateLimiter(MWBase::Environment::get().getFrameRateLimit());
while (mMessageBoxManager->readPressedButton(false) == -1
&& !MWBase::Environment::get().getStateManager()->hasQuitRequest())
{
const double dt
= std::chrono::duration_cast<std::chrono::duration<double>>(frameRateLimiter.getLastFrameDuration())
.count();
mKeyboardNavigation->onFrame();
mMessageBoxManager->onFrame(dt);
MWBase::Environment::get().getInputManager()->update(dt, true, false);
if (!mWindowVisible)
2020-06-25 21:46:07 +02:00
std::this_thread::sleep_for(std::chrono::milliseconds(5));
else
{
mViewer->eventTraversal();
mViewer->updateTraversal();
mViewer->renderingTraversals();
}
// at the time this function is called we are in the middle of a frame,
// so out of order calls are necessary to get a correct frameNumber for the next frame.
// refer to the advance() and frame() order in Engine::go()
mViewer->advance(mViewer->getFrameStamp()->getSimulationTime());
frameRateLimiter.limit();
}
}
}
void WindowManager::messageBox(std::string_view message, enum MWGui::ShowInDialogueMode showInDialogueMode)
{
if (getMode() == GM_Dialogue && showInDialogueMode != MWGui::ShowInDialogueMode_Never)
{
mDialogueWindow->addMessageBox(MyGUI::LanguageManager::getInstance().replaceTags(toUString(message)));
}
else if (showInDialogueMode != MWGui::ShowInDialogueMode_Only)
{
mMessageBoxManager->createMessageBox(message);
2013-04-17 18:56:48 -04:00
}
2011-06-14 18:29:55 +02:00
}
void WindowManager::scheduleMessageBox(std::string message, enum MWGui::ShowInDialogueMode showInDialogueMode)
{
mScheduledMessageBoxes.lock()->emplace_back(std::move(message), showInDialogueMode);
}
void WindowManager::staticMessageBox(std::string_view message)
2013-05-03 12:44:27 +02:00
{
mMessageBoxManager->createMessageBox(message, true);
}
2013-05-03 12:44:27 +02:00
void WindowManager::removeStaticMessageBox()
2010-11-03 21:21:08 +01:00
{
2013-05-03 12:44:27 +02:00
mMessageBoxManager->removeStaticMessageBox();
2010-11-03 21:21:08 +01:00
}
const std::vector<std::unique_ptr<MWGui::MessageBox>>& WindowManager::getActiveMessageBoxes() const
2021-11-26 05:20:58 +08:00
{
return mMessageBoxManager->getActiveMessageBoxes();
}
2013-04-17 18:56:48 -04:00
int WindowManager::readPressedButton()
2012-05-18 17:58:33 +02:00
{
2013-04-17 18:56:48 -04:00
return mMessageBoxManager->readPressedButton();
2012-05-18 17:58:33 +02:00
}
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID Slowly going through all the changes to make, still hundreds of errors a lot of functions/structures use std::string or stringview to designate an ID. So it takes time Continues slowly replacing ids. There are technically more and more compilation errors I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type Continue moving forward, changes to the stores slowly moving along Starting to see the fruit of those changes. still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type. More replacements. Things are starting to get easier I can see more and more often the issue is that the function is awaiting a RefId, but is given a string there is less need to go down functions and to fix a long list of them. Still moving forward, and for the first time error count is going down! Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably Cells are back to using string for the name, haven't fixed everything yet. Many other changes Under the bar of 400 compilation errors. more good progress <100 compile errors! More progress Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string some more progress on other fronts Mostly game settings clean one error opened a lot of other errors. Down to 18, but more will prbably appear only link errors left?? Fixed link errors OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
std::string_view WindowManager::getGameSettingString(const std::string_view& id, std::string_view default_)
2013-04-17 18:56:48 -04:00
{
const ESM::GameSetting* setting = mStore->get<ESM::GameSetting>().search(id);
2013-04-17 18:56:48 -04:00
if (setting && setting->mValue.getType() == ESM::VT_String)
return setting->mValue.getString();
2012-11-05 23:16:37 +01:00
2013-04-17 18:56:48 -04:00
return default_;
}
2015-05-26 16:40:44 +02:00
void WindowManager::updateMap()
{
2015-07-11 03:33:31 +02:00
if (!mLocalMapRender)
return;
MWWorld::ConstPtr player = MWMechanics::getPlayer();
2015-05-26 16:40:44 +02:00
osg::Vec3f playerPosition = player.getRefData().getPosition().asVec3();
osg::Quat playerOrientation(-player.getRefData().getPosition().rot[2], osg::Vec3(0, 0, 1));
osg::Vec3f playerdirection;
int x, y;
float u, v;
mLocalMapRender->updatePlayer(playerPosition, playerOrientation, u, v, x, y, playerdirection);
if (!player.getCell()->isExterior())
{
setActiveMap(x, y, true);
2015-05-26 16:40:44 +02:00
}
// else: need to know the current grid center, call setActiveMap from changeCell
2015-05-26 16:40:44 +02:00
mMap->setPlayerDir(playerdirection.x(), playerdirection.y());
mMap->setPlayerPos(x, y, u, v);
mHud->setPlayerDir(playerdirection.x(), playerdirection.y());
mHud->setPlayerPos(x, y, u, v);
}
void WindowManager::update(float frameDuration)
2013-04-17 18:56:48 -04:00
{
handleScheduledMessageBoxes();
bool gameRunning
= MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_NoGame;
if (gameRunning)
updateMap();
if (!mGuiModes.empty())
{
GuiModeState& state = mGuiModeStates[mGuiModes.back()];
for (WindowBase* window : state.mWindows)
window->onFrame(frameDuration);
}
2017-10-04 17:08:52 +02:00
else
{
// update pinned windows if visible
for (WindowBase* window : mGuiModeStates[GM_Inventory].mWindows)
if (window->isVisible())
window->onFrame(frameDuration);
}
// Make sure message boxes are always in front
// This is an awful workaround for a series of awfully interwoven issues that couldn't be worked around
// in a better way because of an impressive number of even more awfully interwoven issues.
if (mMessageBoxManager && mMessageBoxManager->isInteractiveMessageBox()
&& mCurrentModals.back() != mMessageBoxManager->getInteractiveMessageBox())
{
std::vector<WindowModal*>::iterator found = std::find(
mCurrentModals.begin(), mCurrentModals.end(), mMessageBoxManager->getInteractiveMessageBox());
if (found != mCurrentModals.end())
{
WindowModal* msgbox = *found;
std::swap(*found, mCurrentModals.back());
MyGUI::InputManager::getInstance().addWidgetModal(msgbox->mMainWidget);
mKeyboardNavigation->setModalWindow(msgbox->mMainWidget);
mKeyboardNavigation->setDefaultFocus(msgbox->mMainWidget, msgbox->getDefaultKeyFocus());
}
}
if (!mCurrentModals.empty())
mCurrentModals.back()->onFrame(frameDuration);
mKeyboardNavigation->onFrame();
2018-08-01 19:30:30 +04:00
if (mMessageBoxManager)
mMessageBoxManager->onFrame(frameDuration);
2013-04-17 18:56:48 -04:00
mToolTips->onFrame(frameDuration);
2015-05-26 16:40:44 +02:00
if (mLocalMapRender)
mLocalMapRender->cleanupCameras();
mDebugWindow->onFrame(frameDuration);
if (!gameRunning)
return;
// We should display message about crime only once per frame, even if there are several crimes.
// Otherwise we will get message spam when stealing several items via Take All button.
const MWWorld::Ptr player = MWMechanics::getPlayer();
int currentBounty = player.getClass().getNpcStats(player).getBounty();
if (currentBounty != mPlayerBounty)
{
if (mPlayerBounty >= 0 && currentBounty > mPlayerBounty)
messageBox("#{sCrimeMessage}");
mPlayerBounty = currentBounty;
}
mDragAndDrop->onFrame();
2013-04-17 18:56:48 -04:00
mHud->onFrame(frameDuration);
2022-05-13 18:58:00 -07:00
mPostProcessorHud->onFrame(frameDuration);
if (mCharGen)
mCharGen->onFrame(frameDuration);
2017-09-23 22:24:22 +02:00
2020-06-05 18:22:53 +04:00
updateActivatedQuickKey();
mStatsWatcher->update();
2017-09-23 22:24:22 +02:00
cleanupGarbage();
2013-04-17 18:56:48 -04:00
}
void WindowManager::changeCell(const MWWorld::CellStore* cell)
2012-03-16 17:09:31 +01:00
{
mMap->requestMapRender(cell);
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID Slowly going through all the changes to make, still hundreds of errors a lot of functions/structures use std::string or stringview to designate an ID. So it takes time Continues slowly replacing ids. There are technically more and more compilation errors I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type Continue moving forward, changes to the stores slowly moving along Starting to see the fruit of those changes. still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type. More replacements. Things are starting to get easier I can see more and more often the issue is that the function is awaiting a RefId, but is given a string there is less need to go down functions and to fix a long list of them. Still moving forward, and for the first time error count is going down! Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably Cells are back to using string for the name, haven't fixed everything yet. Many other changes Under the bar of 400 compilation errors. more good progress <100 compile errors! More progress Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string some more progress on other fronts Mostly game settings clean one error opened a lot of other errors. Down to 18, but more will prbably appear only link errors left?? Fixed link errors OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
std::string name = MWBase::Environment::get().getWorld()->getCellName(cell) ;
mMap->setCellName(name);
mHud->setCellName(name);
if (cell->getCell()->isExterior())
2012-09-20 17:30:09 +02:00
{
if (!cell->getCell()->mName.empty())
mMap->addVisitedLocation(name, cell->getCell()->getGridX(), cell->getCell()->getGridY());
2013-04-17 18:56:48 -04:00
mMap->cellExplored(cell->getCell()->getGridX(), cell->getCell()->getGridY());
setActiveMap(cell->getCell()->getGridX(), cell->getCell()->getGridY(), false);
2012-09-20 17:30:09 +02:00
}
2012-03-16 17:09:31 +01:00
else
{
mMap->setCellPrefix(cell->getCell()->mName);
mHud->setCellPrefix(cell->getCell()->mName);
2015-06-03 19:41:19 +02:00
osg::Vec3f worldPos;
if (!MWBase::Environment::get().getWorld()->findInteriorPositionInWorldSpace(cell, worldPos))
worldPos = MWBase::Environment::get().getWorld()->getPlayer().getLastKnownExteriorPosition();
else
MWBase::Environment::get().getWorld()->getPlayer().setLastKnownExteriorPosition(worldPos);
2015-06-03 19:41:19 +02:00
mMap->setGlobalMapPlayerPosition(worldPos.x(), worldPos.y());
setActiveMap(0, 0, true);
}
2013-04-17 18:56:48 -04:00
}
2012-03-23 16:51:56 +01:00
void WindowManager::setActiveMap(int x, int y, bool interior)
2013-04-17 18:56:48 -04:00
{
mMap->setActiveCell(x, y, interior);
mHud->setActiveCell(x, y, interior);
2012-03-16 17:09:31 +01:00
}
2012-03-23 16:51:56 +01:00
void WindowManager::setDrowningBarVisibility(bool visible)
{
mHud->setDrowningBarVisible(visible);
}
2013-04-17 18:56:48 -04:00
void WindowManager::setHMSVisibility(bool visible)
{
mHud->setHmsVisible(visible);
}
2013-04-17 18:56:48 -04:00
void WindowManager::setMinimapVisibility(bool visible)
{
mHud->setMinimapVisible(visible);
}
2012-03-23 15:00:48 +01:00
bool WindowManager::toggleFogOfWar()
2013-04-17 18:56:48 -04:00
{
mMap->toggleFogOfWar();
return mHud->toggleFogOfWar();
2013-04-17 18:56:48 -04:00
}
2013-04-17 18:56:48 -04:00
void WindowManager::setFocusObject(const MWWorld::Ptr& focus)
{
mToolTips->setFocusObject(focus);
2015-07-18 17:13:20 +02:00
if (mHud && (mShowOwned == 2 || mShowOwned == 3))
{
bool owned = mToolTips->checkOwned();
mHud->setCrosshairOwned(owned);
}
2013-04-17 18:56:48 -04:00
}
2013-04-17 18:56:48 -04:00
void WindowManager::setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y)
{
mToolTips->setFocusObjectScreenCoords(min_x, min_y, max_x, max_y);
}
bool WindowManager::toggleFullHelp()
2013-04-17 18:56:48 -04:00
{
return mToolTips->toggleFullHelp();
2013-04-17 18:56:48 -04:00
}
2012-04-13 13:17:50 +02:00
2013-04-17 18:56:48 -04:00
bool WindowManager::getFullHelp() const
{
return mToolTips->getFullHelp();
}
2012-04-16 15:00:44 +02:00
2013-04-17 18:56:48 -04:00
void WindowManager::setWeaponVisibility(bool visible)
{
mHud->setWeapVisible(visible);
}
2013-04-17 18:56:48 -04:00
void WindowManager::setSpellVisibility(bool visible)
{
mHud->setSpellVisible(visible);
mHud->setEffectVisible(visible);
}
void WindowManager::setSneakVisibility(bool visible)
{
mHud->setSneakVisible(visible);
}
2013-04-17 18:56:48 -04:00
void WindowManager::setDragDrop(bool dragDrop)
{
mToolTips->setEnabled(!dragDrop);
MWBase::Environment::get().getInputManager()->setDragDrop(dragDrop);
}
2012-05-12 22:44:12 +02:00
void WindowManager::setCursorVisible(bool visible)
{
mCursorVisible = visible;
2017-09-26 17:44:35 +02:00
}
void WindowManager::setCursorActive(bool active)
{
mCursorActive = active;
}
2013-04-17 18:56:48 -04:00
void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result)
{
2013-04-17 18:56:48 -04:00
std::string tag(_tag);
2022-09-22 21:26:05 +03:00
2015-07-18 22:17:46 +02:00
std::string MyGuiPrefix = "setting=";
size_t MyGuiPrefixLength = MyGuiPrefix.length();
2013-04-17 18:56:48 -04:00
std::string tokenToFind = "sCell=";
size_t tokenLength = tokenToFind.length();
2022-09-22 21:26:05 +03:00
2015-07-18 22:17:46 +02:00
if (tag.compare(0, MyGuiPrefixLength, MyGuiPrefix) == 0)
{
tag = tag.substr(MyGuiPrefixLength, tag.length());
size_t comma_pos = tag.find(',');
std::string settingSection = tag.substr(0, comma_pos);
std::string settingTag = tag.substr(comma_pos + 1, tag.length());
2022-09-22 21:26:05 +03:00
2015-07-18 22:17:46 +02:00
_result = Settings::Manager::getString(settingTag, settingSection);
}
else if (tag.compare(0, tokenLength, tokenToFind) == 0)
2013-04-17 18:56:48 -04:00
{
_result = mTranslationDataStorage.translateCellName(tag.substr(tokenLength));
_result = MyGUI::TextIterator::toTagsString(_result);
2013-04-17 18:56:48 -04:00
}
else if (Gui::replaceTag(tag, _result))
{
return;
}
2013-04-17 18:56:48 -04:00
else
{
std::vector<std::string> split;
Misc::StringUtils::split(tag, split, ":");
2022-10-02 22:38:37 +02:00
l10n::Manager& l10nManager = *MWBase::Environment::get().getL10nManager();
// If a key has a "Context:KeyName" format, use YAML to translate data
2022-10-02 22:38:37 +02:00
if (split.size() == 2)
{
2022-10-02 22:38:37 +02:00
_result = l10nManager.getContext(split[0])->formatMessage(split[1], {}, {});
return;
}
// If not, treat is as GMST name from legacy localization
if (!mStore)
{
2018-08-14 23:05:43 +04:00
Log(Debug::Error) << "Error: WindowManager::onRetrieveTag: no Store set up yet, can not replace '"
<< tag << "'";
_result = tag;
return;
}
const ESM::GameSetting* setting = mStore->get<ESM::GameSetting>().search(tag);
2013-04-17 18:56:48 -04:00
if (setting && setting->mValue.getType() == ESM::VT_String)
_result = setting->mValue.getString();
else
_result = tag;
}
}
2013-04-17 18:56:48 -04:00
void WindowManager::processChangedSettings(const Settings::CategorySettingVector& changed)
{
mToolTips->setDelay(Settings::Manager::getFloat("tooltip delay", "GUI"));
bool changeRes = false;
for (const auto& setting : changed)
2013-04-17 18:56:48 -04:00
{
if (setting.first == "HUD" && setting.second == "crosshair")
2013-04-17 18:56:48 -04:00
mCrosshairEnabled = Settings::Manager::getBool("crosshair", "HUD");
else if (setting.first == "GUI" && setting.second == "subtitles")
2013-04-17 18:56:48 -04:00
mSubtitlesEnabled = Settings::Manager::getBool("subtitles", "GUI");
else if (setting.first == "GUI" && setting.second == "menu transparency")
2015-05-02 18:06:54 +02:00
setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI"));
else if (setting.first == "Video"
&& (setting.second == "resolution x" || setting.second == "resolution y"
|| setting.second == "window mode" || setting.second == "window border"))
changeRes = true;
else if (setting.first == "Video" && setting.second == "vsync")
mVideoWrapper->setSyncToVBlank(Settings::Manager::getBool("vsync", "Video"));
else if (setting.first == "Video" && (setting.second == "gamma" || setting.second == "contrast"))
mVideoWrapper->setGammaContrast(
Settings::Manager::getFloat("gamma", "Video"), Settings::Manager::getFloat("contrast", "Video"));
}
if (changeRes)
{
mVideoWrapper->setVideoMode(Settings::Manager::getInt("resolution x", "Video"),
Settings::Manager::getInt("resolution y", "Video"),
static_cast<Settings::WindowMode>(Settings::Manager::getInt("window mode", "Video")),
Settings::Manager::getBool("window border", "Video"));
2013-04-17 18:56:48 -04:00
}
2013-07-29 02:32:08 +02:00
}
2012-12-23 23:23:24 +04:00
2013-07-29 02:32:08 +02:00
void WindowManager::windowResized(int x, int y)
{
Settings::Manager::setInt("resolution x", "Video", x);
Settings::Manager::setInt("resolution y", "Video", y);
// We only want to process changes to window-size related settings.
Settings::CategorySettingVector filter = { { "Video", "resolution x" }, { "Video", "resolution y" } };
// If the HUD has not been initialised, the World singleton will not be available.
if (mHud)
{
MWBase::Environment::get().getWorld()->processChangedSettings(Settings::Manager::getPendingChanges(filter));
}
Settings::Manager::resetPendingChanges(filter);
2015-05-15 00:41:21 +02:00
mGuiPlatform->getRenderManagerPtr()->setViewSize(x, y);
// scaled size
const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize();
x = viewSize.width;
y = viewSize.height;
sizeVideo(x, y);
2015-04-24 21:55:30 +02:00
if (!mHud)
return; // UI not initialized yet
2013-12-03 18:42:35 +01:00
for (std::map<MyGUI::Window*, std::string>::iterator it = mTrackedWindows.begin(); it != mTrackedWindows.end();
++it)
{
std::string settingName = it->second;
if (Settings::Manager::getBool(settingName + " maximized", "Windows"))
settingName += " maximized";
MyGUI::IntPoint pos(static_cast<int>(Settings::Manager::getFloat(settingName + " x", "Windows") * x),
static_cast<int>(Settings::Manager::getFloat(settingName + " y", "Windows") * y));
MyGUI::IntSize size(static_cast<int>(Settings::Manager::getFloat(settingName + " w", "Windows") * x),
static_cast<int>(Settings::Manager::getFloat(settingName + " h", "Windows") * y));
2013-12-03 18:42:35 +01:00
it->first->setPosition(pos);
it->first->setSize(size);
}
2022-08-31 21:07:59 +02:00
for (const auto& window : mWindows)
2017-09-23 22:07:30 +02:00
window->onResChange(x, y);
// TODO: check if any windows are now off-screen and move them back if so
2012-12-23 23:23:24 +04:00
}
bool WindowManager::isWindowVisible()
{
return mWindowVisible;
}
void WindowManager::windowVisibilityChange(bool visible)
{
mWindowVisible = visible;
}
void WindowManager::windowClosed()
{
MWBase::Environment::get().getStateManager()->requestQuit();
}
void WindowManager::onCursorChange(const std::string& name)
{
mCursorManager->cursorChanged(name);
2012-12-23 23:23:24 +04:00
}
2013-04-17 18:56:48 -04:00
void WindowManager::pushGuiMode(GuiMode mode)
2012-12-23 23:23:24 +04:00
{
pushGuiMode(mode, MWWorld::Ptr());
}
2012-12-23 23:23:24 +04:00
void WindowManager::pushGuiMode(GuiMode mode, const MWWorld::Ptr& arg)
{
pushGuiMode(mode, arg, false);
}
void WindowManager::forceLootMode(const MWWorld::Ptr& ptr)
{
pushGuiMode(MWGui::GM_Container, ptr, true);
}
void WindowManager::pushGuiMode(GuiMode mode, const MWWorld::Ptr& arg, bool force)
2012-12-23 23:23:24 +04:00
{
2013-04-17 18:56:48 -04:00
if (mode == GM_Inventory && mAllowed == GW_None)
return;
2012-12-23 23:23:24 +04:00
if (mGuiModes.empty() || mGuiModes.back() != mode)
{
// If this mode already exists somewhere in the stack, just bring it to the front.
if (std::find(mGuiModes.begin(), mGuiModes.end(), mode) != mGuiModes.end())
{
mGuiModes.erase(std::find(mGuiModes.begin(), mGuiModes.end(), mode));
}
2012-05-23 12:23:35 +02:00
if (!mGuiModes.empty())
{
mKeyboardNavigation->saveFocus(mGuiModes.back());
mGuiModeStates[mGuiModes.back()].update(false);
}
mGuiModes.push_back(mode);
2012-05-23 12:23:35 +02:00
mGuiModeStates[mode].update(true);
playSound(mGuiModeStates[mode].mOpenSound);
}
if (force)
mContainerWindow->treatNextOpenAsLoot();
for (WindowBase* window : mGuiModeStates[mode].mWindows)
window->setPtr(arg);
mKeyboardNavigation->restoreFocus(mode);
2013-04-17 18:56:48 -04:00
updateVisible();
2012-12-23 23:23:24 +04:00
}
void WindowManager::setCullMask(uint32_t mask)
{
mViewer->getCamera()->setCullMask(mask);
// We could check whether stereo is enabled here, but these methods are
// trivial and have no effect in mono or multiview so just call them regardless.
mViewer->getCamera()->setCullMaskLeft(mask);
mViewer->getCamera()->setCullMaskRight(mask);
}
uint32_t WindowManager::getCullMask()
{
return mViewer->getCamera()->getCullMask();
}
void WindowManager::popGuiMode(bool noSound)
{
if (mDragAndDrop && mDragAndDrop->mIsOnDragAndDrop)
{
mDragAndDrop->finish();
}
2013-04-17 18:56:48 -04:00
if (!mGuiModes.empty())
{
2017-09-23 12:18:39 +02:00
const GuiMode mode = mGuiModes.back();
mKeyboardNavigation->saveFocus(mode);
2013-04-17 18:56:48 -04:00
mGuiModes.pop_back();
2017-09-23 12:18:39 +02:00
mGuiModeStates[mode].update(false);
if (!noSound)
playSound(mGuiModeStates[mode].mCloseSound);
}
2012-05-23 12:23:35 +02:00
if (!mGuiModes.empty())
{
const GuiMode mode = mGuiModes.back();
mGuiModeStates[mode].update(true);
mKeyboardNavigation->restoreFocus(mode);
}
2012-05-23 12:23:35 +02:00
2013-04-17 18:56:48 -04:00
updateVisible();
// To make sure that console window get focus again
if (mConsole && mConsole->isVisible())
mConsole->onOpen();
2013-04-17 18:56:48 -04:00
}
void WindowManager::removeGuiMode(GuiMode mode, bool noSound)
{
if (!mGuiModes.empty() && mGuiModes.back() == mode)
{
popGuiMode(noSound);
return;
}
2013-04-17 18:56:48 -04:00
std::vector<GuiMode>::iterator it = mGuiModes.begin();
while (it != mGuiModes.end())
{
2013-04-17 18:56:48 -04:00
if (*it == mode)
it = mGuiModes.erase(it);
else
++it;
}
2012-05-23 12:23:35 +02:00
2013-04-17 18:56:48 -04:00
updateVisible();
}
void WindowManager::goToJail(int days)
{
pushGuiMode(MWGui::GM_Jail);
mJailScreen->goToJail(days);
}
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID Slowly going through all the changes to make, still hundreds of errors a lot of functions/structures use std::string or stringview to designate an ID. So it takes time Continues slowly replacing ids. There are technically more and more compilation errors I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type Continue moving forward, changes to the stores slowly moving along Starting to see the fruit of those changes. still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type. More replacements. Things are starting to get easier I can see more and more often the issue is that the function is awaiting a RefId, but is given a string there is less need to go down functions and to fix a long list of them. Still moving forward, and for the first time error count is going down! Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably Cells are back to using string for the name, haven't fixed everything yet. Many other changes Under the bar of 400 compilation errors. more good progress <100 compile errors! More progress Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string some more progress on other fronts Mostly game settings clean one error opened a lot of other errors. Down to 18, but more will prbably appear only link errors left?? Fixed link errors OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
void WindowManager::setSelectedSpell(const ESM::RefId& spellId, int successChancePercent)
{
mSelectedSpell = spellId;
mSelectedEnchantItem = MWWorld::Ptr();
2013-04-17 18:56:48 -04:00
mHud->setSelectedSpell(spellId, successChancePercent);
const ESM::Spell* spell = mStore->get<ESM::Spell>().find(spellId);
2013-04-17 18:56:48 -04:00
mSpellWindow->setTitle(spell->mName);
}
2013-04-17 18:56:48 -04:00
void WindowManager::setSelectedEnchantItem(const MWWorld::Ptr& item)
{
mSelectedEnchantItem = item;
mSelectedSpell = ESM::RefId::sEmpty;
const ESM::Enchantment* ench = mStore->get<ESM::Enchantment>().find(item.getClass().getEnchantment(item));
2012-05-23 12:23:35 +02:00
int chargePercent
= static_cast<int>(item.getCellRef().getNormalizedEnchantmentCharge(ench->mData.mCharge) * 100);
2013-04-17 18:56:48 -04:00
mHud->setSelectedEnchantItem(item, chargePercent);
mSpellWindow->setTitle(item.getClass().getName(item));
2013-04-17 18:56:48 -04:00
}
2012-05-23 12:23:35 +02:00
const MWWorld::Ptr& WindowManager::getSelectedEnchantItem() const
{
return mSelectedEnchantItem;
}
2013-04-17 18:56:48 -04:00
void WindowManager::setSelectedWeapon(const MWWorld::Ptr& item)
{
mSelectedWeapon = item;
int durabilityPercent = 100;
if (item.getClass().hasItemHealth(item))
{
durabilityPercent = static_cast<int>(item.getClass().getItemNormalizedHealth(item) * 100);
}
2013-04-17 18:56:48 -04:00
mHud->setSelectedWeapon(item, durabilityPercent);
mInventoryWindow->setTitle(item.getClass().getName(item));
2013-04-17 18:56:48 -04:00
}
2012-05-23 12:23:35 +02:00
const MWWorld::Ptr& WindowManager::getSelectedWeapon() const
{
return mSelectedWeapon;
}
2013-04-17 18:56:48 -04:00
void WindowManager::unsetSelectedSpell()
{
mSelectedSpell = ESM::RefId::sEmpty;
mSelectedEnchantItem = MWWorld::Ptr();
2013-04-17 18:56:48 -04:00
mHud->unsetSelectedSpell();
MWWorld::Player* player = &MWBase::Environment::get().getWorld()->getPlayer();
if (player->getDrawState() == MWMechanics::DrawState::Spell)
player->setDrawState(MWMechanics::DrawState::Nothing);
2013-04-17 18:56:48 -04:00
mSpellWindow->setTitle("#{sNone}");
}
2012-05-23 12:23:35 +02:00
2013-04-17 18:56:48 -04:00
void WindowManager::unsetSelectedWeapon()
{
mSelectedWeapon = MWWorld::Ptr();
2013-04-17 18:56:48 -04:00
mHud->unsetSelectedWeapon();
mInventoryWindow->setTitle("#{sSkillHandtohand}");
}
2012-05-23 12:23:35 +02:00
2013-04-17 18:56:48 -04:00
void WindowManager::getMousePosition(int& x, int& y)
{
const MyGUI::IntPoint& pos = MyGUI::InputManager::getInstance().getMousePosition();
x = pos.left;
y = pos.top;
}
2013-04-17 18:56:48 -04:00
void WindowManager::getMousePosition(float& x, float& y)
{
2013-04-17 18:56:48 -04:00
const MyGUI::IntPoint& pos = MyGUI::InputManager::getInstance().getMousePosition();
x = static_cast<float>(pos.left);
y = static_cast<float>(pos.top);
2013-04-17 18:56:48 -04:00
const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize();
x /= viewSize.width;
y /= viewSize.height;
}
2013-04-17 18:56:48 -04:00
bool WindowManager::getWorldMouseOver()
{
return mHud->getWorldMouseOver();
}
float WindowManager::getScalingFactor() const
{
return mScalingFactor;
}
2013-04-17 18:56:48 -04:00
void WindowManager::executeInConsole(const std::string& path)
{
2015-04-24 21:55:30 +02:00
mConsole->executeFile(path);
2013-04-17 18:56:48 -04:00
}
2013-04-17 18:56:48 -04:00
MWGui::InventoryWindow* WindowManager::getInventoryWindow()
{
return mInventoryWindow;
}
MWGui::CountDialog* WindowManager::getCountDialog()
{
return mCountDialog;
}
MWGui::ConfirmationDialog* WindowManager::getConfirmationDialog()
{
return mConfirmationDialog;
}
MWGui::TradeWindow* WindowManager::getTradeWindow()
{
return mTradeWindow;
}
2022-05-13 18:58:00 -07:00
MWGui::PostProcessorHud* WindowManager::getPostProcessorHud()
{
return mPostProcessorHud;
}
2013-04-17 18:56:48 -04:00
void WindowManager::useItem(const MWWorld::Ptr& item, bool bypassBeastRestrictions)
{
if (mInventoryWindow)
mInventoryWindow->useItem(item, bypassBeastRestrictions);
}
2013-04-17 18:56:48 -04:00
bool WindowManager::isAllowed(GuiWindow wnd) const
{
return (mAllowed & wnd) != 0;
2013-04-17 18:56:48 -04:00
}
2013-04-17 18:56:48 -04:00
void WindowManager::allow(GuiWindow wnd)
{
mAllowed = (GuiWindow)(mAllowed | wnd);
2013-04-17 18:56:48 -04:00
if (wnd & GW_Inventory)
{
mBookWindow->setInventoryAllowed(true);
mScrollWindow->setInventoryAllowed(true);
}
2013-04-17 18:56:48 -04:00
updateVisible();
}
2013-04-17 18:56:48 -04:00
void WindowManager::disallowAll()
{
mAllowed = GW_None;
2017-09-23 23:09:41 +02:00
mRestAllowed = false;
2013-04-17 18:56:48 -04:00
mBookWindow->setInventoryAllowed(false);
mScrollWindow->setInventoryAllowed(false);
2013-04-17 18:56:48 -04:00
updateVisible();
}
2013-04-17 18:56:48 -04:00
void WindowManager::toggleVisible(GuiWindow wnd)
{
if (getMode() != GM_Inventory)
return;
std::string settingName;
switch (wnd)
{
case GW_Inventory:
settingName = "inventory";
break;
case GW_Map:
settingName = "map";
break;
case GW_Magic:
settingName = "spells";
break;
case GW_Stats:
settingName = "stats";
break;
default:
break;
}
if (!settingName.empty())
{
settingName += " hidden";
bool hidden = Settings::Manager::getBool(settingName, "Windows");
Settings::Manager::setBool(settingName, "Windows", !hidden);
}
2013-08-05 23:15:26 +02:00
mShown = (GuiWindow)(mShown ^ wnd);
updateVisible();
}
void WindowManager::forceHide(GuiWindow wnd)
{
mForceHidden = (GuiWindow)(mForceHidden | wnd);
updateVisible();
}
void WindowManager::unsetForceHide(GuiWindow wnd)
{
mForceHidden = (GuiWindow)(mForceHidden & ~wnd);
2013-04-17 18:56:48 -04:00
updateVisible();
}
2013-04-17 18:56:48 -04:00
bool WindowManager::isGuiMode() const
{
2022-05-13 18:58:00 -07:00
return !mGuiModes.empty() || isConsoleMode() || (mPostProcessorHud && mPostProcessorHud->isVisible())
|| (mMessageBoxManager && mMessageBoxManager->isInteractiveMessageBox());
2013-04-17 18:56:48 -04:00
}
2012-07-30 12:37:46 +02:00
2013-04-17 18:56:48 -04:00
bool WindowManager::isConsoleMode() const
{
return mConsole && mConsole->isVisible();
2013-04-17 18:56:48 -04:00
}
bool WindowManager::isPostProcessorHudVisible() const
{
return mPostProcessorHud->isVisible();
}
2013-04-17 18:56:48 -04:00
MWGui::GuiMode WindowManager::getMode() const
{
if (mGuiModes.empty())
return GM_None;
return mGuiModes.back();
}
2013-04-17 18:56:48 -04:00
void WindowManager::disallowMouse()
{
mInputBlocker->setVisible(true);
}
2013-04-17 18:56:48 -04:00
void WindowManager::allowMouse()
{
mInputBlocker->setVisible(!isGuiMode());
}
2013-04-17 18:56:48 -04:00
void WindowManager::notifyInputActionBound()
{
mSettingsWindow->updateControlsBox();
allowMouse();
}
bool WindowManager::containsMode(GuiMode mode) const
{
if (mGuiModes.empty())
return false;
return std::find(mGuiModes.begin(), mGuiModes.end(), mode) != mGuiModes.end();
}
2013-04-17 18:56:48 -04:00
void WindowManager::showCrosshair(bool show)
{
if (mHud)
mHud->setCrosshairVisible(show && mCrosshairEnabled);
2013-04-17 18:56:48 -04:00
}
void WindowManager::updateActivatedQuickKey()
{
mQuickKeysMenu->updateActivatedQuickKey();
}
2013-04-17 18:56:48 -04:00
void WindowManager::activateQuickKey(int index)
{
mQuickKeysMenu->activateQuickKey(index);
}
2013-04-17 18:56:48 -04:00
bool WindowManager::getSubtitlesEnabled()
{
return mSubtitlesEnabled;
}
bool WindowManager::toggleHud()
2014-06-20 18:49:19 +02:00
{
mHudEnabled = !mHudEnabled;
2014-06-20 18:49:19 +02:00
updateVisible();
2021-05-25 21:04:05 +02:00
mMessageBoxManager->setVisible(mHudEnabled);
return mHudEnabled;
2014-06-20 18:49:19 +02:00
}
2013-04-29 17:19:20 +02:00
bool WindowManager::getRestEnabled()
{
// Enable rest dialogue if character creation finished
if (mRestAllowed == false && MWBase::Environment::get().getWorld()->getGlobalFloat("chargenstate") == -1)
2013-04-29 17:19:20 +02:00
mRestAllowed = true;
return mRestAllowed;
}
2012-08-13 01:26:15 +02:00
2013-04-17 18:56:48 -04:00
bool WindowManager::getPlayerSleeping()
{
return mWaitDialog->getSleeping();
}
2012-08-27 19:18:55 +02:00
2013-04-17 18:56:48 -04:00
void WindowManager::wakeUpPlayer()
{
mWaitDialog->wakeUp();
}
2013-04-17 18:56:48 -04:00
void WindowManager::addVisitedLocation(const std::string& name, int x, int y)
{
mMap->addVisitedLocation(name, x, y);
}
2013-04-17 18:56:48 -04:00
const Translation::Storage& WindowManager::getTranslationDataStorage() const
{
return mTranslationDataStorage;
}
2012-09-29 09:41:34 +02:00
2013-04-17 18:56:48 -04:00
void WindowManager::changePointer(const std::string& name)
{
2013-11-27 18:45:46 +01:00
MyGUI::PointerManager::getInstance().setPointer(name);
onCursorChange(name);
2013-04-17 18:56:48 -04:00
}
2013-04-17 18:56:48 -04:00
void WindowManager::showSoulgemDialog(MWWorld::Ptr item)
{
mSoulgemDialog->show(item);
updateVisible();
2013-04-17 18:56:48 -04:00
}
2012-10-17 18:03:02 +02:00
2013-05-15 17:54:18 +02:00
void WindowManager::updatePlayer()
{
2015-04-24 21:55:30 +02:00
mInventoryWindow->updatePlayer();
2015-08-21 21:12:39 +12:00
const MWWorld::Ptr player = MWMechanics::getPlayer();
if (player.getClass().getNpcStats(player).isWerewolf())
{
setWerewolfOverlay(true);
forceHide((GuiWindow)(MWGui::GW_Inventory | MWGui::GW_Magic));
}
2013-05-15 17:54:18 +02:00
}
// Remove this wrapper once onKeyFocusChanged call is rendered unnecessary
void WindowManager::setKeyFocusWidget(MyGUI::Widget* widget)
{
MyGUI::InputManager::getInstance().setKeyFocusWidget(widget);
onKeyFocusChanged(widget);
}
void WindowManager::onKeyFocusChanged(MyGUI::Widget* widget)
{
if (widget && widget->castType<MyGUI::EditBox>(false))
SDL_StartTextInput();
else
SDL_StopTextInput();
}
2013-07-30 06:00:20 +02:00
void WindowManager::setEnemy(const MWWorld::Ptr& enemy)
{
mHud->setEnemy(enemy);
}
int WindowManager::getMessagesCount() const
{
int count = 0;
if (mMessageBoxManager)
count = mMessageBoxManager->getMessagesCount();
return count;
}
Loading::Listener* WindowManager::getLoadingScreen()
{
2015-05-03 16:58:05 +02:00
return mLoadingScreen;
}
bool WindowManager::getCursorVisible()
{
2017-09-26 17:44:35 +02:00
return mCursorVisible && mCursorActive;
}
2015-05-01 02:09:57 +02:00
void WindowManager::trackWindow(Layout* layout, const std::string& name)
2013-12-03 18:42:35 +01:00
{
std::string settingName = name;
2013-12-03 18:42:35 +01:00
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
bool isMaximized = Settings::Manager::getBool(name + " maximized", "Windows");
if (isMaximized)
settingName += " maximized";
MyGUI::IntPoint pos(
static_cast<int>(Settings::Manager::getFloat(settingName + " x", "Windows") * viewSize.width),
static_cast<int>(Settings::Manager::getFloat(settingName + " y", "Windows") * viewSize.height));
MyGUI::IntSize size(
static_cast<int>(Settings::Manager::getFloat(settingName + " w", "Windows") * viewSize.width),
static_cast<int>(Settings::Manager::getFloat(settingName + " h", "Windows") * viewSize.height));
2013-12-03 18:42:35 +01:00
layout->mMainWidget->setPosition(pos);
layout->mMainWidget->setSize(size);
2016-03-05 20:00:51 +01:00
MyGUI::Window* window = layout->mMainWidget->castType<MyGUI::Window>();
2013-12-03 18:42:35 +01:00
window->eventWindowChangeCoord += MyGUI::newDelegate(this, &WindowManager::onWindowChangeCoord);
mTrackedWindows[window] = name;
}
void WindowManager::toggleMaximized(Layout* layout)
{
MyGUI::Window* window = layout->mMainWidget->castType<MyGUI::Window>();
std::string setting = mTrackedWindows[window];
if (setting.empty())
return;
bool maximized = !Settings::Manager::getBool(setting + " maximized", "Windows");
if (maximized)
setting += " maximized";
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
float x = Settings::Manager::getFloat(setting + " x", "Windows") * float(viewSize.width);
float y = Settings::Manager::getFloat(setting + " y", "Windows") * float(viewSize.height);
float w = Settings::Manager::getFloat(setting + " w", "Windows") * float(viewSize.width);
float h = Settings::Manager::getFloat(setting + " h", "Windows") * float(viewSize.height);
window->setCoord(x, y, w, h);
Settings::Manager::setBool(mTrackedWindows[window] + " maximized", "Windows", maximized);
}
2013-12-03 18:42:35 +01:00
void WindowManager::onWindowChangeCoord(MyGUI::Window* _sender)
{
std::string setting = mTrackedWindows[_sender];
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
float x = _sender->getPosition().left / float(viewSize.width);
float y = _sender->getPosition().top / float(viewSize.height);
float w = _sender->getSize().width / float(viewSize.width);
float h = _sender->getSize().height / float(viewSize.height);
Settings::Manager::setFloat(setting + " x", "Windows", x);
Settings::Manager::setFloat(setting + " y", "Windows", y);
Settings::Manager::setFloat(setting + " w", "Windows", w);
Settings::Manager::setFloat(setting + " h", "Windows", h);
bool maximized = Settings::Manager::getBool(setting + " maximized", "Windows");
if (maximized)
Settings::Manager::setBool(setting + " maximized", "Windows", false);
2013-12-03 18:42:35 +01:00
}
void WindowManager::clear()
{
mPlayerBounty = -1;
2022-08-31 21:07:59 +02:00
for (const auto& window : mWindows)
2017-09-23 22:16:56 +02:00
window->clear();
2015-06-01 21:41:13 +02:00
if (mLocalMapRender)
mLocalMapRender->clear();
mMessageBoxManager->clear();
2018-11-13 10:00:12 +04:00
mToolTips->clear();
mSelectedSpell = ESM::RefId::sEmpty;
mCustomMarkers.clear();
mForceHidden = GW_None;
2017-09-23 23:09:41 +02:00
mRestAllowed = true;
2017-09-23 22:16:56 +02:00
while (!mGuiModes.empty())
popGuiMode();
updateVisible();
}
void WindowManager::write(ESM::ESMWriter& writer, Loading::Listener& progress)
2014-01-25 18:20:17 +01:00
{
mMap->write(writer, progress);
mQuickKeysMenu->write(writer);
2014-05-12 21:04:02 +02:00
if (!mSelectedSpell.empty())
{
writer.startRecord(ESM::REC_ASPL);
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID Slowly going through all the changes to make, still hundreds of errors a lot of functions/structures use std::string or stringview to designate an ID. So it takes time Continues slowly replacing ids. There are technically more and more compilation errors I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type Continue moving forward, changes to the stores slowly moving along Starting to see the fruit of those changes. still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type. More replacements. Things are starting to get easier I can see more and more often the issue is that the function is awaiting a RefId, but is given a string there is less need to go down functions and to fix a long list of them. Still moving forward, and for the first time error count is going down! Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably Cells are back to using string for the name, haven't fixed everything yet. Many other changes Under the bar of 400 compilation errors. more good progress <100 compile errors! More progress Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string some more progress on other fronts Mostly game settings clean one error opened a lot of other errors. Down to 18, but more will prbably appear only link errors left?? Fixed link errors OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
writer.writeHNString("ID__", mSelectedSpell.getRefIdString());
2014-05-12 21:04:02 +02:00
writer.endRecord(ESM::REC_ASPL);
}
for (CustomMarkerCollection::ContainerType::const_iterator it = mCustomMarkers.begin();
it != mCustomMarkers.end(); ++it)
{
writer.startRecord(ESM::REC_MARK);
it->second.save(writer);
writer.endRecord(ESM::REC_MARK);
}
2014-01-25 18:20:17 +01:00
}
2015-01-22 19:04:59 +01:00
void WindowManager::readRecord(ESM::ESMReader& reader, uint32_t type)
2014-01-25 18:20:17 +01:00
{
if (type == ESM::REC_GMAP)
mMap->readRecord(reader, type);
else if (type == ESM::REC_KEYS)
mQuickKeysMenu->readRecord(reader, type);
2014-05-12 21:04:02 +02:00
else if (type == ESM::REC_ASPL)
{
reader.getSubNameIs("ID__");
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID Slowly going through all the changes to make, still hundreds of errors a lot of functions/structures use std::string or stringview to designate an ID. So it takes time Continues slowly replacing ids. There are technically more and more compilation errors I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type Continue moving forward, changes to the stores slowly moving along Starting to see the fruit of those changes. still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type. More replacements. Things are starting to get easier I can see more and more often the issue is that the function is awaiting a RefId, but is given a string there is less need to go down functions and to fix a long list of them. Still moving forward, and for the first time error count is going down! Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably Cells are back to using string for the name, haven't fixed everything yet. Many other changes Under the bar of 400 compilation errors. more good progress <100 compile errors! More progress Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string some more progress on other fronts Mostly game settings clean one error opened a lot of other errors. Down to 18, but more will prbably appear only link errors left?? Fixed link errors OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
ESM::RefId spell = reader.getRefId();
if (mStore->get<ESM::Spell>().search(spell))
mSelectedSpell = spell;
2014-05-12 21:04:02 +02:00
}
else if (type == ESM::REC_MARK)
{
ESM::CustomMarker marker;
marker.load(reader);
mCustomMarkers.addMarker(marker, false);
}
}
int WindowManager::countSavedGameRecords() const
{
return 1 // Global map
2014-05-12 21:04:02 +02:00
+ 1 // QuickKeysMenu
+ mCustomMarkers.size() + (!mSelectedSpell.empty() ? 1 : 0);
2014-01-25 18:20:17 +01:00
}
bool WindowManager::isSavingAllowed() const
{
return !MyGUI::InputManager::getInstance().isModalAny()
&& !isConsoleMode()
// TODO: remove this, once we have properly serialized the state of open windows
2017-09-23 15:06:11 +02:00
&& (!isGuiMode() || (mGuiModes.size() == 1 && (getMode() == GM_MainMenu || getMode() == GM_Rest)));
}
2014-01-25 18:20:17 +01:00
2022-08-28 17:20:49 +02:00
void WindowManager::playVideo(std::string_view name, bool allowSkipping, bool overrideSounds)
{
2022-08-28 17:20:49 +02:00
mVideoWidget->playVideo("video\\" + std::string{ name });
mVideoWidget->eventKeyButtonPressed.clear();
mVideoBackground->eventKeyButtonPressed.clear();
if (allowSkipping)
{
mVideoWidget->eventKeyButtonPressed += MyGUI::newDelegate(this, &WindowManager::onVideoKeyPressed);
mVideoBackground->eventKeyButtonPressed += MyGUI::newDelegate(this, &WindowManager::onVideoKeyPressed);
}
enableScene(false);
MyGUI::IntSize screenSize = MyGUI::RenderManager::getInstance().getViewSize();
sizeVideo(screenSize.width, screenSize.height);
MyGUI::Widget* oldKeyFocus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
setKeyFocusWidget(mVideoWidget);
mVideoBackground->setVisible(true);
bool cursorWasVisible = mCursorVisible;
setCursorVisible(false);
if (overrideSounds && mVideoWidget->hasAudioStream())
MWBase::Environment::get().getSoundManager()->pauseSounds(
MWSound::VideoPlayback, ~MWSound::Type::Movie & MWSound::Type::Mask);
Misc::FrameRateLimiter frameRateLimiter
= Misc::makeFrameRateLimiter(MWBase::Environment::get().getFrameRateLimit());
while (mVideoWidget->update() && !MWBase::Environment::get().getStateManager()->hasQuitRequest())
{
const double dt
= std::chrono::duration_cast<std::chrono::duration<double>>(frameRateLimiter.getLastFrameDuration())
.count();
MWBase::Environment::get().getInputManager()->update(dt, true, false);
if (!mWindowVisible)
{
mVideoWidget->pause();
2020-06-25 21:46:07 +02:00
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
else
{
if (mVideoWidget->isPaused())
mVideoWidget->resume();
mViewer->eventTraversal();
mViewer->updateTraversal();
mViewer->renderingTraversals();
}
// at the time this function is called we are in the middle of a frame,
// so out of order calls are necessary to get a correct frameNumber for the next frame.
// refer to the advance() and frame() order in Engine::go()
mViewer->advance(mViewer->getFrameStamp()->getSimulationTime());
frameRateLimiter.limit();
}
mVideoWidget->stop();
MWBase::Environment::get().getSoundManager()->resumeSounds(MWSound::VideoPlayback);
setKeyFocusWidget(oldKeyFocus);
setCursorVisible(cursorWasVisible);
// Restore normal rendering
updateVisible();
mVideoBackground->setVisible(false);
}
void WindowManager::sizeVideo(int screenWidth, int screenHeight)
{
// Use black bars to correct aspect ratio
bool stretch = Settings::Manager::getBool("stretch menu background", "GUI");
mVideoBackground->setSize(screenWidth, screenHeight);
mVideoWidget->autoResize(stretch);
}
2015-03-11 20:04:25 +01:00
void WindowManager::exitCurrentModal()
{
2015-03-11 20:04:25 +01:00
if (!mCurrentModals.empty())
2017-09-23 12:18:39 +02:00
{
WindowModal* window = mCurrentModals.back();
if (!window->exit())
2017-09-23 12:18:39 +02:00
return;
window->setVisible(false);
2017-09-23 12:18:39 +02:00
}
}
void WindowManager::addCurrentModal(WindowModal* input)
{
if (mCurrentModals.empty())
mKeyboardNavigation->saveFocus(getMode());
mCurrentModals.push_back(input);
mKeyboardNavigation->restoreFocus(-1);
mKeyboardNavigation->setModalWindow(input->mMainWidget);
mKeyboardNavigation->setDefaultFocus(input->mMainWidget, input->getDefaultKeyFocus());
}
void WindowManager::removeCurrentModal(WindowModal* input)
{
2014-09-26 17:12:48 +02:00
if (!mCurrentModals.empty())
{
if (input == mCurrentModals.back())
{
mCurrentModals.pop_back();
mKeyboardNavigation->saveFocus(-1);
}
else
{
auto found = std::find(mCurrentModals.begin(), mCurrentModals.end(), input);
if (found != mCurrentModals.end())
mCurrentModals.erase(found);
else
2018-08-14 23:05:43 +04:00
Log(Debug::Warning) << "Warning: can't find modal window " << input;
}
}
if (mCurrentModals.empty())
{
2018-10-09 10:21:12 +04:00
mKeyboardNavigation->setModalWindow(nullptr);
mKeyboardNavigation->restoreFocus(getMode());
}
else
mKeyboardNavigation->setModalWindow(mCurrentModals.back()->mMainWidget);
}
void WindowManager::onVideoKeyPressed(MyGUI::Widget* _sender, MyGUI::KeyCode _key, MyGUI::Char _char)
{
if (_key == MyGUI::KeyCode::Escape)
mVideoWidget->stop();
}
void WindowManager::updatePinnedWindows()
{
mInventoryWindow->setPinned(Settings::Manager::getBool("inventory pin", "Windows"));
if (Settings::Manager::getBool("inventory hidden", "Windows"))
mShown = (GuiWindow)(mShown ^ GW_Inventory);
mMap->setPinned(Settings::Manager::getBool("map pin", "Windows"));
if (Settings::Manager::getBool("map hidden", "Windows"))
mShown = (GuiWindow)(mShown ^ GW_Map);
mSpellWindow->setPinned(Settings::Manager::getBool("spells pin", "Windows"));
if (Settings::Manager::getBool("spells hidden", "Windows"))
mShown = (GuiWindow)(mShown ^ GW_Magic);
mStatsWindow->setPinned(Settings::Manager::getBool("stats pin", "Windows"));
if (Settings::Manager::getBool("stats hidden", "Windows"))
mShown = (GuiWindow)(mShown ^ GW_Stats);
}
void WindowManager::pinWindow(GuiWindow window)
{
switch (window)
{
case GW_Inventory:
mInventoryWindow->setPinned(true);
break;
case GW_Map:
mMap->setPinned(true);
break;
case GW_Magic:
mSpellWindow->setPinned(true);
break;
case GW_Stats:
mStatsWindow->setPinned(true);
break;
default:
break;
}
updateVisible();
}
void WindowManager::fadeScreenIn(const float time, bool clearQueue, float delay)
{
if (clearQueue)
mScreenFader->clearQueue();
mScreenFader->fadeOut(time, delay);
}
void WindowManager::fadeScreenOut(const float time, bool clearQueue, float delay)
{
if (clearQueue)
mScreenFader->clearQueue();
mScreenFader->fadeIn(time, delay);
}
void WindowManager::fadeScreenTo(const int percent, const float time, bool clearQueue, float delay)
{
if (clearQueue)
mScreenFader->clearQueue();
mScreenFader->fadeTo(percent, time, delay);
}
void WindowManager::setBlindness(const int percent)
{
mBlindnessFader->notifyAlphaChanged(percent / 100.f);
}
void WindowManager::activateHitOverlay(bool interrupt)
{
if (!mHitFaderEnabled)
return;
if (!interrupt && !mHitFader->isEmpty())
return;
mHitFader->clearQueue();
mHitFader->fadeTo(100, 0.0f);
mHitFader->fadeTo(0, 0.5f);
}
void WindowManager::setWerewolfOverlay(bool set)
{
2014-10-05 19:53:36 +02:00
if (!mWerewolfOverlayEnabled)
return;
if (mWerewolfFader)
mWerewolfFader->notifyAlphaChanged(set ? 1.0f : 0.0f);
}
void WindowManager::onClipboardChanged(const std::string& _type, const std::string& _data)
{
if (_type == "Text")
SDL_SetClipboardText(MyGUI::TextIterator::getOnlyText(MyGUI::UString(_data)).asUTF8().c_str());
}
void WindowManager::onClipboardRequested(const std::string& _type, std::string& _data)
{
if (_type != "Text")
return;
2020-11-13 11:39:47 +04:00
char* text = nullptr;
text = SDL_GetClipboardText();
if (text)
_data = MyGUI::TextIterator::toTagsString(text);
SDL_free(text);
}
void WindowManager::toggleConsole()
{
bool visible = mConsole->isVisible();
if (!visible && !mGuiModes.empty())
mKeyboardNavigation->saveFocus(mGuiModes.back());
mConsole->setVisible(!visible);
if (visible && !mGuiModes.empty())
mKeyboardNavigation->restoreFocus(mGuiModes.back());
updateVisible();
}
void WindowManager::toggleDebugWindow()
{
mDebugWindow->setVisible(!mDebugWindow->isVisible());
}
2022-05-13 18:58:00 -07:00
void WindowManager::togglePostProcessorHud()
{
if (!MWBase::Environment::get().getWorld()->getPostProcessor()->isEnabled())
{
messageBox("Postprocessor is not enabled.");
2022-05-13 18:58:00 -07:00
return;
}
2022-05-13 18:58:00 -07:00
bool visible = mPostProcessorHud->isVisible();
if (!visible && !mGuiModes.empty())
mKeyboardNavigation->saveFocus(mGuiModes.back());
mPostProcessorHud->setVisible(!visible);
if (visible && !mGuiModes.empty())
mKeyboardNavigation->restoreFocus(mGuiModes.back());
updateVisible();
}
void WindowManager::cycleSpell(bool next)
{
if (!isGuiMode())
mSpellWindow->cycle(next);
}
void WindowManager::cycleWeapon(bool next)
{
if (!isGuiMode())
mInventoryWindow->cycle(next);
}
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID Slowly going through all the changes to make, still hundreds of errors a lot of functions/structures use std::string or stringview to designate an ID. So it takes time Continues slowly replacing ids. There are technically more and more compilation errors I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type Continue moving forward, changes to the stores slowly moving along Starting to see the fruit of those changes. still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type. More replacements. Things are starting to get easier I can see more and more often the issue is that the function is awaiting a RefId, but is given a string there is less need to go down functions and to fix a long list of them. Still moving forward, and for the first time error count is going down! Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably Cells are back to using string for the name, haven't fixed everything yet. Many other changes Under the bar of 400 compilation errors. more good progress <100 compile errors! More progress Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string some more progress on other fronts Mostly game settings clean one error opened a lot of other errors. Down to 18, but more will prbably appear only link errors left?? Fixed link errors OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
void WindowManager::playSound(const ESM::RefId& soundId, float volume, float pitch)
{
if (soundId.empty())
return;
2022-07-03 12:51:28 +00:00
MWBase::Environment::get().getSoundManager()->playSound(
soundId, volume, pitch, MWSound::Type::Sfx, MWSound::PlayMode::NoEnvNoScaling);
2015-03-11 20:04:25 +01:00
}
void WindowManager::updateSpellWindow()
{
if (mSpellWindow)
mSpellWindow->updateSpells();
}
void WindowManager::setConsoleSelectedObject(const MWWorld::Ptr& object)
2015-03-11 20:33:55 +01:00
{
mConsole->setSelectedObject(object);
2015-03-11 20:33:55 +01:00
}
2022-11-26 21:25:18 +01:00
MWWorld::Ptr WindowManager::getConsoleSelectedObject() const
{
return mConsole->getSelectedObject();
}
2022-04-09 23:07:57 +02:00
void WindowManager::printToConsole(const std::string& msg, std::string_view color)
{
mConsole->print(msg, color);
}
void WindowManager::setConsoleMode(const std::string& mode)
{
mConsole->setConsoleMode(mode);
}
void WindowManager::createCursors()
{
MyGUI::ResourceManager::EnumeratorPtr enumerator = MyGUI::ResourceManager::getInstance().getEnumerator();
while (enumerator.next())
{
MyGUI::IResource* resource = enumerator.current().second;
2016-03-05 20:00:51 +01:00
ResourceImageSetPointerFix* imgSetPointer = resource->castType<ResourceImageSetPointerFix>(false);
if (!imgSetPointer)
continue;
std::string tex_name = imgSetPointer->getImageSet()->getIndexInfo(0, 0).texture;
osg::ref_ptr<osg::Image> image = mResourceSystem->getImageManager()->getImage(tex_name);
if (image.valid())
{
// everything looks good, send it to the cursor manager
Uint8 hotspot_x = imgSetPointer->getHotSpot().left;
Uint8 hotspot_y = imgSetPointer->getHotSpot().top;
int rotation = imgSetPointer->getRotation();
MyGUI::IntSize pointerSize = imgSetPointer->getSize();
mCursorManager->createCursor(imgSetPointer->getResourceName(), rotation, image, hotspot_x, hotspot_y,
pointerSize.width, pointerSize.height);
}
}
}
2015-05-02 18:06:54 +02:00
void WindowManager::createTextures()
{
{
MyGUI::ITexture* tex = MyGUI::RenderManager::getInstance().createTexture("white");
2015-05-02 18:06:54 +02:00
tex->createManual(8, 8, MyGUI::TextureUsage::Write, MyGUI::PixelFormat::R8G8B8);
unsigned char* data = reinterpret_cast<unsigned char*>(tex->lock(MyGUI::TextureUsage::Write));
for (int x = 0; x < 8; ++x)
for (int y = 0; y < 8; ++y)
{
*(data++) = 255;
*(data++) = 255;
*(data++) = 255;
}
tex->unlock();
}
{
MyGUI::ITexture* tex = MyGUI::RenderManager::getInstance().createTexture("black");
2015-05-02 18:06:54 +02:00
tex->createManual(8, 8, MyGUI::TextureUsage::Write, MyGUI::PixelFormat::R8G8B8);
unsigned char* data = reinterpret_cast<unsigned char*>(tex->lock(MyGUI::TextureUsage::Write));
for (int x = 0; x < 8; ++x)
for (int y = 0; y < 8; ++y)
{
*(data++) = 0;
*(data++) = 0;
*(data++) = 0;
}
tex->unlock();
}
{
MyGUI::ITexture* tex = MyGUI::RenderManager::getInstance().createTexture("transparent");
2015-05-02 18:06:54 +02:00
tex->createManual(8, 8, MyGUI::TextureUsage::Write, MyGUI::PixelFormat::R8G8B8A8);
setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI"));
}
}
void WindowManager::setMenuTransparency(float value)
{
MyGUI::ITexture* tex = MyGUI::RenderManager::getInstance().getTexture("transparent");
2015-05-02 18:06:54 +02:00
unsigned char* data = reinterpret_cast<unsigned char*>(tex->lock(MyGUI::TextureUsage::Write));
for (int x = 0; x < 8; ++x)
for (int y = 0; y < 8; ++y)
{
*(data++) = 255;
*(data++) = 255;
*(data++) = 255;
*(data++) = static_cast<unsigned char>(value * 255);
}
tex->unlock();
}
void WindowManager::addCell(MWWorld::CellStore* cell)
{
mLocalMapRender->addCell(cell);
}
2015-05-26 16:40:44 +02:00
void WindowManager::removeCell(MWWorld::CellStore* cell)
{
mLocalMapRender->removeCell(cell);
}
void WindowManager::writeFog(MWWorld::CellStore* cell)
{
mLocalMapRender->saveFogOfWar(cell);
}
2017-07-24 13:25:01 +02:00
const MWGui::TextColours& WindowManager::getTextColours()
{
return mTextColours;
}
bool WindowManager::injectKeyPress(MyGUI::KeyCode key, unsigned int text, bool repeat)
{
if (!mKeyboardNavigation->injectKeyPress(key, text, repeat))
{
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
bool widgetActive = MyGUI::InputManager::getInstance().injectKeyPress(key, text);
if (!widgetActive || !focus)
return false;
// FIXME: MyGUI doesn't allow widgets to state if a given key was actually used, so make a guess
if (focus->getTypeName().find("Button") != std::string::npos)
{
switch (key.getValue())
{
case MyGUI::KeyCode::ArrowDown:
case MyGUI::KeyCode::ArrowUp:
case MyGUI::KeyCode::ArrowLeft:
case MyGUI::KeyCode::ArrowRight:
case MyGUI::KeyCode::Return:
case MyGUI::KeyCode::NumpadEnter:
case MyGUI::KeyCode::Space:
return true;
default:
return false;
}
}
return false;
}
else
return true;
}
2018-09-10 12:55:00 +04:00
bool WindowManager::injectKeyRelease(MyGUI::KeyCode key)
{
return MyGUI::InputManager::getInstance().injectKeyRelease(key);
}
void WindowManager::GuiModeState::update(bool visible)
{
2022-08-31 21:07:59 +02:00
for (const auto& window : mWindows)
window->setVisible(visible);
}
2020-06-05 18:22:53 +04:00
void WindowManager::watchActor(const MWWorld::Ptr& ptr)
{
mStatsWatcher->watchActor(ptr);
}
MWWorld::Ptr WindowManager::getWatchedActor() const
{
return mStatsWatcher->getWatchedActor();
}
2021-07-07 18:48:25 +02:00
const std::string& WindowManager::getVersionDescription() const
{
return mVersionDescription;
}
void WindowManager::handleScheduledMessageBoxes()
{
const auto scheduledMessageBoxes = mScheduledMessageBoxes.lock();
for (const ScheduledMessageBox& v : *scheduledMessageBoxes)
messageBox(v.mMessage, v.mShowInDialogueMode);
scheduledMessageBoxes->clear();
}
void WindowManager::onDeleteCustomData(const MWWorld::Ptr& ptr)
{
2022-08-31 21:07:59 +02:00
for (const auto& window : mWindows)
window->onDeleteCustomData(ptr);
}
void WindowManager::asyncPrepareSaveMap()
{
mMap->asyncPrepareSaveMap();
}
}