diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index d7c61c51a..7f45bdbdd 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -6,6 +6,7 @@ using namespace MyGUI; ToolTips::ToolTips() : Layout("openmw_tooltips.xml") , mGameMode(true) + , mFocusChanged(true) { getWidget(mTextToolTip, "TextToolTip"); getWidget(mTextToolTipBox, "TextToolTipBox"); @@ -27,29 +28,389 @@ void ToolTips::onFrame(float frameDuration) const IntSize &viewSize = RenderManager::getInstance().getViewSize(); - Widget* focus = InputManager::getInstance().getMouseFocusWidget(); - if (focus == 0) return; - - // this the maximum width of the tooltip before it starts word-wrapping - setCoord(0, 0, 300, 300); - - mTextToolTip->setCaption("Focused: " + focus->getName() + "\nType: " + focus->getTypeName()); - const IntSize &textSize = mTextToolTip->getTextSize(); - - IntPoint tooltipPosition = InputManager::getInstance().getMousePosition() + IntPoint(0, 24); - - IntSize size = textSize + IntSize(12, 12); - // make the tooltip stay completely in the viewport - if ((tooltipPosition.left + size.width) > viewSize.width) + if (!mGameMode) { - tooltipPosition.left = viewSize.width - size.width; - } - if ((tooltipPosition.top + size.height) > viewSize.height) - { - tooltipPosition.top = viewSize.height - size.height; - } + mDynamicToolTipBox->setVisible(false); - setCoord(tooltipPosition.left, tooltipPosition.top, size.width, size.height); + Widget* focus = InputManager::getInstance().getMouseFocusWidget(); + if (focus == 0) return; + + // this the maximum width of the tooltip before it starts word-wrapping + setCoord(0, 0, 300, 300); + + mTextToolTip->setCaption("Focused: " + focus->getName() + "\nType: " + focus->getTypeName()); + const IntSize &textSize = mTextToolTip->getTextSize(); + + IntPoint tooltipPosition = InputManager::getInstance().getMousePosition() + IntPoint(0, 24); + + IntSize size = textSize + IntSize(12, 12); + // make the tooltip stay completely in the viewport + if ((tooltipPosition.left + size.width) > viewSize.width) + { + tooltipPosition.left = viewSize.width - size.width; + } + if ((tooltipPosition.top + size.height) > viewSize.height) + { + tooltipPosition.top = viewSize.height - size.height; + } + + setCoord(tooltipPosition.left, tooltipPosition.top, size.width, size.height); + } + else + { + mTextToolTipBox->setVisible(false); + + if (!mFocusObject.isEmpty()) + { + if (mFocusChanged) + { + for (size_t i=0; igetChildCount(); ++i) + { + mDynamicToolTipBox->_destroyChildWidget(mDynamicToolTipBox->getChildAt(i)); + } + + // this the maximum width of the tooltip before it starts word-wrapping + setCoord(0, 0, 300, 300); + + IntSize tooltipSize; + + /// \todo Not sure about levelled lists (ESM::CreateLevList and ESM::ItemLevList). I think + /// they are supposed to spawn a concrete object (Creature or item of any type), so + /// the player wouldn't encounter them and we don't have to handle them here. + + // -------------------- Door ------------------------------- + if (mFocusObject.getTypeName() == typeid(ESM::Door).name()) + { + ESMS::LiveCellRef* ref = mFocusObject.get(); + + EditBox* box = mDynamicToolTipBox->createWidget("MW_TextEdit", IntCoord(0, 0, 300, 300), Align::Stretch, "ToolTip"); + box->setTextAlign(Align::HCenter); + box->setProperty("Static", "true"); + box->setProperty("MultiLine", "true"); + + std::string caption = ref->base->name; + /// \todo If destCell is empty, the teleport target is an exterior cell. In that case we + /// need to fetch that cell (via target position) and retrieve the region name. + if (ref->ref.teleport && (ref->ref.destCell != "")) + { + caption += "\n-"; + caption += "\n"+ref->ref.destCell; + } + box->setCaption(caption); + + /// \todo Lock level, trap (retrieve GMST) + + tooltipSize = box->getTextSize() + IntSize(12,12); + + mDynamicToolTipBox->setVisible(true); + } + + // -------------------- NPC ------------------------------- + else if (mFocusObject.getTypeName() == typeid(ESM::NPC).name()) + { + /// \todo We don't want tooltips for NPCs in combat mode. + ESMS::LiveCellRef* ref = mFocusObject.get(); + + EditBox* box = mDynamicToolTipBox->createWidget("MW_TextEdit", IntCoord(0, 0, 300, 300), Align::Stretch, "ToolTip"); + box->setTextAlign(Align::HCenter); + box->setProperty("Static", "true"); + box->setCaption(ref->base->name); + + tooltipSize = box->getTextSize() + IntSize(12,12); + + mDynamicToolTipBox->setVisible(true); + } + + // -------------------- Creature ------------------------------- + else if (mFocusObject.getTypeName() == typeid(ESM::Creature).name()) + { + ESMS::LiveCellRef* ref = mFocusObject.get(); + + EditBox* box = mDynamicToolTipBox->createWidget("MW_TextEdit", IntCoord(0, 0, 300, 300), Align::Stretch, "ToolTip"); + box->setTextAlign(Align::HCenter); + box->setProperty("Static", "true"); + box->setCaption(ref->base->name); + + /// \todo + + tooltipSize = box->getTextSize() + IntSize(12,12); + + mDynamicToolTipBox->setVisible(true); + } + + // -------------------- CreatureLevList ------------------------------- + else if (mFocusObject.getTypeName() == typeid(ESM::Creature).name()) + { + ESMS::LiveCellRef* ref = mFocusObject.get(); + + EditBox* box = mDynamicToolTipBox->createWidget("MW_TextEdit", IntCoord(0, 0, 300, 300), Align::Stretch, "ToolTip"); + box->setTextAlign(Align::HCenter); + box->setProperty("Static", "true"); + box->setCaption(ref->base->name); + + /// \todo + + tooltipSize = box->getTextSize() + IntSize(12,12); + + mDynamicToolTipBox->setVisible(true); + } + + // -------------------- Container ------------------------------- + else if (mFocusObject.getTypeName() == typeid(ESM::Container).name()) + { + ESMS::LiveCellRef* ref = mFocusObject.get(); + + EditBox* box = mDynamicToolTipBox->createWidget("MW_TextEdit", IntCoord(0, 0, 300, 300), Align::Stretch, "ToolTip"); + box->setTextAlign(Align::HCenter); + box->setProperty("Static", "true"); + box->setCaption(ref->base->name); + + /// \todo Lock level, trap (retrieve GMST) + + tooltipSize = box->getTextSize() + IntSize(12,12); + + mDynamicToolTipBox->setVisible(true); + } + + // -------------------- Potion ------------------------------- + else if (mFocusObject.getTypeName() == typeid(ESM::Potion).name()) + { + ESMS::LiveCellRef* ref = mFocusObject.get(); + + EditBox* box = mDynamicToolTipBox->createWidget("MW_TextEdit", IntCoord(0, 0, 300, 300), Align::Stretch, "ToolTip"); + box->setTextAlign(Align::HCenter); + box->setProperty("Static", "true"); + box->setCaption(ref->base->name); + + /// \todo + + tooltipSize = box->getTextSize() + IntSize(12,12); + + mDynamicToolTipBox->setVisible(true); + } + + // -------------------- Apparatus ------------------------------- + else if (mFocusObject.getTypeName() == typeid(ESM::Apparatus).name()) + { + ESMS::LiveCellRef* ref = mFocusObject.get(); + + EditBox* box = mDynamicToolTipBox->createWidget("MW_TextEdit", IntCoord(0, 0, 300, 300), Align::Stretch, "ToolTip"); + box->setTextAlign(Align::HCenter); + box->setProperty("Static", "true"); + box->setCaption(ref->base->name); + + /// \todo + + tooltipSize = box->getTextSize() + IntSize(12,12); + + mDynamicToolTipBox->setVisible(true); + } + + // -------------------- Armor ------------------------------- + else if (mFocusObject.getTypeName() == typeid(ESM::Armor).name()) + { + ESMS::LiveCellRef* ref = mFocusObject.get(); + + EditBox* box = mDynamicToolTipBox->createWidget("MW_TextEdit", IntCoord(0, 0, 300, 300), Align::Stretch, "ToolTip"); + box->setTextAlign(Align::HCenter); + box->setProperty("Static", "true"); + box->setCaption(ref->base->name); + + /// \todo weight, armor value, value, durability.. + + tooltipSize = box->getTextSize() + IntSize(12,12); + + mDynamicToolTipBox->setVisible(true); + } + + // -------------------- Book ------------------------------- + else if (mFocusObject.getTypeName() == typeid(ESM::Book).name()) + { + ESMS::LiveCellRef* ref = mFocusObject.get(); + + EditBox* box = mDynamicToolTipBox->createWidget("MW_TextEdit", IntCoord(0, 0, 300, 300), Align::Stretch, "ToolTip"); + box->setTextAlign(Align::HCenter); + box->setProperty("Static", "true"); + box->setCaption(ref->base->name); + + /// \todo + + tooltipSize = box->getTextSize() + IntSize(12,12); + + mDynamicToolTipBox->setVisible(true); + } + + // -------------------- Clothing ------------------------------- + else if (mFocusObject.getTypeName() == typeid(ESM::Clothing).name()) + { + ESMS::LiveCellRef* ref = mFocusObject.get(); + + EditBox* box = mDynamicToolTipBox->createWidget("MW_TextEdit", IntCoord(0, 0, 300, 300), Align::Stretch, "ToolTip"); + box->setTextAlign(Align::HCenter); + box->setProperty("Static", "true"); + box->setCaption(ref->base->name); + + /// \todo + + tooltipSize = box->getTextSize() + IntSize(12,12); + + mDynamicToolTipBox->setVisible(true); + } + + // -------------------- Ingredient ------------------------------- + else if (mFocusObject.getTypeName() == typeid(ESM::Ingredient).name()) + { + ESMS::LiveCellRef* ref = mFocusObject.get(); + + EditBox* box = mDynamicToolTipBox->createWidget("MW_TextEdit", IntCoord(0, 0, 300, 300), Align::Stretch, "ToolTip"); + box->setTextAlign(Align::HCenter); + box->setProperty("Static", "true"); + box->setCaption(ref->base->name); + + /// \todo + + tooltipSize = box->getTextSize() + IntSize(12,12); + + mDynamicToolTipBox->setVisible(true); + } + + // -------------------- Light ------------------------------- + else if (mFocusObject.getTypeName() == typeid(ESM::Light).name()) + { + ESMS::LiveCellRef* ref = mFocusObject.get(); + + EditBox* box = mDynamicToolTipBox->createWidget("MW_TextEdit", IntCoord(0, 0, 300, 300), Align::Stretch, "ToolTip"); + box->setTextAlign(Align::HCenter); + box->setProperty("Static", "true"); + box->setCaption(ref->base->name); + + /// \todo + + tooltipSize = box->getTextSize() + IntSize(12,12); + + mDynamicToolTipBox->setVisible(ref->base->name != ""); + } + + // -------------------- Tool ------------------------------- + else if (mFocusObject.getTypeName() == typeid(ESM::Tool).name()) + { + ESMS::LiveCellRef* ref = mFocusObject.get(); + + EditBox* box = mDynamicToolTipBox->createWidget("MW_TextEdit", IntCoord(0, 0, 300, 300), Align::Stretch, "ToolTip"); + box->setTextAlign(Align::HCenter); + box->setProperty("Static", "true"); + box->setCaption(ref->base->name); + + /// \todo + + tooltipSize = box->getTextSize() + IntSize(12,12); + + mDynamicToolTipBox->setVisible(true); + } + + // -------------------- Miscellaneous ------------------------------- + else if (mFocusObject.getTypeName() == typeid(ESM::Miscellaneous).name()) + { + ESMS::LiveCellRef* ref = mFocusObject.get(); + + EditBox* box = mDynamicToolTipBox->createWidget("MW_TextEdit", IntCoord(0, 0, 300, 300), Align::Stretch, "ToolTip"); + box->setTextAlign(Align::HCenter); + box->setProperty("Static", "true"); + box->setCaption(ref->base->name); + + /// \todo + + tooltipSize = box->getTextSize() + IntSize(12,12); + + mDynamicToolTipBox->setVisible(true); + } + + // -------------------- Probe ------------------------------- + else if (mFocusObject.getTypeName() == typeid(ESM::Probe).name()) + { + ESMS::LiveCellRef* ref = mFocusObject.get(); + + EditBox* box = mDynamicToolTipBox->createWidget("MW_TextEdit", IntCoord(0, 0, 300, 300), Align::Stretch, "ToolTip"); + box->setTextAlign(Align::HCenter); + box->setProperty("Static", "true"); + box->setCaption(ref->base->name); + + /// \todo + + tooltipSize = box->getTextSize() + IntSize(12,12); + + mDynamicToolTipBox->setVisible(true); + } + + // -------------------- Repair ------------------------------- + else if (mFocusObject.getTypeName() == typeid(ESM::Repair).name()) + { + ESMS::LiveCellRef* ref = mFocusObject.get(); + + EditBox* box = mDynamicToolTipBox->createWidget("MW_TextEdit", IntCoord(0, 0, 300, 300), Align::Stretch, "ToolTip"); + box->setTextAlign(Align::HCenter); + box->setProperty("Static", "true"); + box->setCaption(ref->base->name); + + /// \todo + + tooltipSize = box->getTextSize() + IntSize(12,12); + + mDynamicToolTipBox->setVisible(true); + } + + // -------------------- Weapon ------------------------------- + else if (mFocusObject.getTypeName() == typeid(ESM::Weapon).name()) + { + ESMS::LiveCellRef* ref = mFocusObject.get(); + + EditBox* box = mDynamicToolTipBox->createWidget("MW_TextEdit", IntCoord(0, 0, 300, 300), Align::Stretch, "ToolTip"); + box->setTextAlign(Align::HCenter); + box->setProperty("Static", "true"); + box->setCaption(ref->base->name); + + /// \todo + + tooltipSize = box->getTextSize() + IntSize(12,12); + + mDynamicToolTipBox->setVisible(true); + } + + // -------------------- Activator ------------------------------- + else if (mFocusObject.getTypeName() == typeid(ESM::Activator).name()) + { + ESMS::LiveCellRef* ref = mFocusObject.get(); + + EditBox* box = mDynamicToolTipBox->createWidget("MW_TextEdit", IntCoord(0, 0, 300, 300), Align::Stretch, "ToolTip"); + box->setTextAlign(Align::HCenter); + box->setProperty("Static", "true"); + box->setCaption(ref->base->name); + + /// \todo + + tooltipSize = box->getTextSize() + IntSize(12,12); + + mDynamicToolTipBox->setVisible(ref->base->name != ""); + } + + else + { + // object without tooltip + mDynamicToolTipBox->setVisible(false); + } + + // adjust tooltip size to fit its content, position it above the crosshair + /// \todo Slide the tooltip along the bounding box of the focused object (like in Morrowind) + setCoord(viewSize.width/2 - (tooltipSize.width)/2.f, + viewSize.height/2 - (tooltipSize.height) - 32, + tooltipSize.width, + tooltipSize.height); + } + mFocusChanged = false; + } + else + mDynamicToolTipBox->setVisible(false); + } } void ToolTips::enterGameMode() @@ -61,3 +422,12 @@ void ToolTips::enterGuiMode() { mGameMode = false; } + +void ToolTips::setFocusObject(const MWWorld::Ptr& focus) +{ + if (focus != mFocusObject) + { + mFocusObject = focus; + mFocusChanged = true; + } +} diff --git a/apps/openmw/mwgui/tooltips.hpp b/apps/openmw/mwgui/tooltips.hpp index aa929ff51..3052abb7a 100644 --- a/apps/openmw/mwgui/tooltips.hpp +++ b/apps/openmw/mwgui/tooltips.hpp @@ -3,6 +3,7 @@ #define MWGUI_TOOLTIPS_H #include +#include "../mwworld/ptr.hpp" namespace MWGui { @@ -16,6 +17,8 @@ namespace MWGui void enterGameMode(); void enterGuiMode(); + void setFocusObject(const MWWorld::Ptr& focus); + void adjustScreen(int screenWidth, int screenHeight); private: @@ -24,6 +27,9 @@ namespace MWGui MyGUI::Widget* mDynamicToolTipBox; + MWWorld::Ptr mFocusObject; + bool mFocusChanged; + bool mGameMode; }; } diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index 1ef5cae42..909be0ac2 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -492,3 +492,8 @@ int WindowManager::toggleFps() Settings::Manager::setInt("fps", "HUD", showFPSLevel); return showFPSLevel; } + +void WindowManager::setFocusObject(const MWWorld::Ptr& focus) +{ + mToolTips->setFocusObject(focus); +} diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index 1cbd8f6a6..d5f0683b8 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -158,6 +158,8 @@ namespace MWGui void setPlayerPos(const float x, const float y); ///< set player position in map space void setPlayerDir(const float x, const float y); ///< set player view direction in map space + void setFocusObject(const MWWorld::Ptr& focus); + void toggleFogOfWar(); int toggleFps(); diff --git a/apps/openmw/mwrender/shadows.cpp b/apps/openmw/mwrender/shadows.cpp index bf5602f43..9a4ae7243 100644 --- a/apps/openmw/mwrender/shadows.cpp +++ b/apps/openmw/mwrender/shadows.cpp @@ -66,7 +66,10 @@ void Shadows::recreate() if (split) { mPSSMSetup = new PSSMShadowCameraSetup(); - mPSSMSetup->setSplitPadding(5); + + // Make sure to keep this in sync with the camera's near clip distance! + mPSSMSetup->setSplitPadding(mRendering->getCamera()->getNearClipDistance()); + mPSSMSetup->calculateSplitPoints(3, mRendering->getCamera()->getNearClipDistance(), mShadowFar); const Real adjustFactors[3] = {64, 64, 64}; diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 1c64039d4..4719a25cf 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -13,6 +13,7 @@ #include "../mwsound/soundmanager.hpp" +#include "../mwgui/window_manager.hpp" #include "ptr.hpp" #include "environment.hpp" @@ -737,6 +738,17 @@ namespace MWWorld mWeatherManager->update (duration); + // inform the GUI about focused object + try + { + mEnvironment.mWindowManager->setFocusObject(getPtrViaHandle(mFacedHandle)); + } + catch (std::runtime_error&) + { + MWWorld::Ptr null; + mEnvironment.mWindowManager->setFocusObject(null); + } + if (!mRendering->occlusionQuerySupported()) { // cast a ray from player to sun to detect if the sun is visible diff --git a/files/mygui/openmw_tooltips.xml b/files/mygui/openmw_tooltips.xml index 76df7b9a7..26fc1eeab 100644 --- a/files/mygui/openmw_tooltips.xml +++ b/files/mygui/openmw_tooltips.xml @@ -1,11 +1,12 @@ - + - - + + + @@ -13,7 +14,8 @@ - + +