From ef0a185e115aebe56fc12d32785e03f050895b4f Mon Sep 17 00:00:00 2001 From: Roman Melnik Date: Fri, 6 Apr 2012 01:17:23 +0300 Subject: [PATCH] Pinnable windows: hide hud elements Hide elements of the HUD (health/magicka/stamina bars, minimap) when the corresponding windows (stats/map) are pinned. Rearrange the remaining hud elements in such cases (like in the original Morrowind). --- apps/openmw/mwgui/layouts.cpp | 57 ++++++++++++++++++++++ apps/openmw/mwgui/layouts.hpp | 16 +++++- apps/openmw/mwgui/map_window.cpp | 12 ++--- apps/openmw/mwgui/map_window.hpp | 7 ++- apps/openmw/mwgui/stats_window.cpp | 5 ++ apps/openmw/mwgui/stats_window.hpp | 3 ++ apps/openmw/mwgui/window_manager.cpp | 10 ++++ apps/openmw/mwgui/window_manager.hpp | 5 ++ apps/openmw/mwgui/window_pinnable_base.cpp | 1 + apps/openmw/mwgui/window_pinnable_base.hpp | 2 + files/mygui/openmw_hud_layout.xml | 28 ++++++----- 11 files changed, 122 insertions(+), 24 deletions(-) diff --git a/apps/openmw/mwgui/layouts.cpp b/apps/openmw/mwgui/layouts.cpp index af068ffae1..0bca3b5340 100644 --- a/apps/openmw/mwgui/layouts.cpp +++ b/apps/openmw/mwgui/layouts.cpp @@ -31,6 +31,11 @@ HUD::HUD(int width, int height, int fpsLevel) , fpscounter(NULL) , trianglecounter(NULL) , batchcounter(NULL) + , hmsBaseLeft(0) + , weapBoxBaseLeft(0) + , spellBoxBaseLeft(0) + , effectBoxBaseRight(0) + , minimapBoxBaseRight(0) { setCoord(0,0, width, height); @@ -38,16 +43,25 @@ HUD::HUD(int width, int height, int fpsLevel) getWidget(health, "Health"); getWidget(magicka, "Magicka"); getWidget(stamina, "Stamina"); + hmsBaseLeft = health->getLeft(); // Item and spell images and status bars + getWidget(weapBox, "WeapBox"); getWidget(weapImage, "WeapImage"); getWidget(weapStatus, "WeapStatus"); + weapBoxBaseLeft = weapBox->getLeft(); + + getWidget(spellBox, "SpellBox"); getWidget(spellImage, "SpellImage"); getWidget(spellStatus, "SpellStatus"); + spellBoxBaseLeft = spellBox->getLeft(); getWidget(effectBox, "EffectBox"); getWidget(effect1, "Effect1"); + effectBoxBaseRight = effectBox->getRight(); + getWidget(minimapBox, "MiniMapBox"); + minimapBoxBaseRight = minimapBox->getRight(); getWidget(minimap, "MiniMap"); getWidget(compass, "Compass"); @@ -163,15 +177,21 @@ void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat& v void HUD::setPlayerDir(const float x, const float y) { + if (!minimapBox->getVisible() || (x == mLastPositionX && y == mLastPositionY)) return; + MyGUI::ISubWidget* main = compass->getSubWidgetMain(); MyGUI::RotatingSkin* rotatingSubskin = main->castType(); rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); float angle = std::atan2(x,y); rotatingSubskin->setAngle(angle); + mLastPositionX = x; + mLastPositionY = y; } void HUD::setPlayerPos(const float x, const float y) { + if (!minimapBox->getVisible() || (x == mLastDirectionX && y == mLastDirectionY)) return; + MyGUI::IntSize size = minimap->getCanvasSize(); MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height); MyGUI::IntCoord viewsize = minimap->getCoord(); @@ -179,6 +199,39 @@ void HUD::setPlayerPos(const float x, const float y) minimap->setViewOffset(pos); compass->setPosition(MyGUI::IntPoint(x*512-16, y*512-16)); + + mLastDirectionX = x; + mLastDirectionY = y; +} + +void HUD::setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible) +{ + int weapDx = 0, spellDx = 0; + if (!hmsVisible) + spellDx = weapDx = weapBoxBaseLeft - hmsBaseLeft; + + if (!weapVisible) + spellDx -= spellBoxBaseLeft - weapBoxBaseLeft; + + health->setVisible(hmsVisible); + stamina->setVisible(hmsVisible); + magicka->setVisible(hmsVisible); + weapBox->setPosition(weapBoxBaseLeft - weapDx, weapBox->getTop()); + weapBox->setVisible(weapVisible); + spellBox->setPosition(spellBoxBaseLeft - spellDx, spellBox->getTop()); + spellBox->setVisible(spellVisible); +} + +void HUD::setBottomRightVisibility(bool effectBoxVisible, bool minimapBoxVisible) +{ + // effect box can have variable width -> variable left coordinate + int effectsDx = 0; + if (!minimapBoxVisible) + effectsDx = minimapBoxBaseRight - effectBoxBaseRight; + + minimapBox->setVisible(minimapBoxVisible); + effectBox->setPosition(effectBoxBaseRight - effectBox->getWidth() + effectsDx, effectBox->getTop()); + effectBox->setVisible(effectBoxVisible); } LocalMapBase::LocalMapBase() @@ -189,6 +242,10 @@ LocalMapBase::LocalMapBase() , mPrefix() , mChanged(true) , mLayout(NULL) + , mLastPositionX(0.0f) + , mLastPositionY(0.0f) + , mLastDirectionX(0.0f) + , mLastDirectionY(0.0f) { } diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index 30bea579c5..42b4a8b9ed 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -48,6 +48,11 @@ namespace MWGui bool mChanged; OEngine::GUI::Layout* mLayout; + + float mLastPositionX; + float mLastPositionY; + float mLastDirectionX; + float mLastDirectionY; }; class HUD : public OEngine::GUI::Layout, public LocalMapBase @@ -66,11 +71,14 @@ namespace MWGui void setBatchCount(size_t count); void setPlayerDir(const float x, const float y); void setPlayerPos(const float x, const float y); + void setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible); + void setBottomRightVisibility(bool effectBoxVisible, bool minimapVisible); MyGUI::ProgressPtr health, magicka, stamina; + MyGUI::Widget *weapBox, *spellBox; MyGUI::ImageBox *weapImage, *spellImage; MyGUI::ProgressPtr weapStatus, spellStatus; - MyGUI::WidgetPtr effectBox; + MyGUI::Widget *effectBox, *minimapBox; MyGUI::ImageBox* effect1; MyGUI::ScrollView* minimap; MyGUI::ImageBox* compass; @@ -80,6 +88,12 @@ namespace MWGui MyGUI::TextBox* fpscounter; MyGUI::TextBox* trianglecounter; MyGUI::TextBox* batchcounter; + + private: + // bottom left elements + int hmsBaseLeft, weapBoxBaseLeft, spellBoxBaseLeft; + // bottom right elements + int minimapBoxBaseRight, effectBoxBaseRight; }; class MainMenu : public OEngine::GUI::Layout diff --git a/apps/openmw/mwgui/map_window.cpp b/apps/openmw/mwgui/map_window.cpp index b4e8aa4d64..0e9d57c3c2 100644 --- a/apps/openmw/mwgui/map_window.cpp +++ b/apps/openmw/mwgui/map_window.cpp @@ -1,7 +1,7 @@ #include "map_window.hpp" +#include "window_manager.hpp" /* #include "../mwmechanics/mechanicsmanager.hpp" -#include "window_manager.hpp" #include #include @@ -14,11 +14,7 @@ using namespace MWGui; MapWindow::MapWindow(WindowManager& parWindowManager) : MWGui::WindowPinnableBase("openmw_map_window_layout.xml", parWindowManager), - mGlobal(false), - mLastPositionX(0.0f), - mLastPositionY(0.0f), - mLastDirectionX(0.0f), - mLastDirectionY(0.0f) + mGlobal(false) { setCoord(500,0,320,300); setText("WorldButton", "World"); @@ -104,3 +100,7 @@ void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender) mButton->setCaption( mGlobal ? "Local" : "World" ); } +void MapWindow::onPinToggled() +{ + mWindowManager.setMinimapVisibility(!mPinned); +} diff --git a/apps/openmw/mwgui/map_window.hpp b/apps/openmw/mwgui/map_window.hpp index cad652bff2..d14221a408 100644 --- a/apps/openmw/mwgui/map_window.hpp +++ b/apps/openmw/mwgui/map_window.hpp @@ -26,10 +26,9 @@ namespace MWGui MyGUI::Button* mButton; MyGUI::IntPoint mLastDragPos; bool mGlobal; - float mLastPositionX; - float mLastPositionY; - float mLastDirectionX; - float mLastDirectionY; + + protected: + virtual void onPinToggled(); }; } #endif diff --git a/apps/openmw/mwgui/stats_window.cpp b/apps/openmw/mwgui/stats_window.cpp index 3ded9713af..675e5141fa 100644 --- a/apps/openmw/mwgui/stats_window.cpp +++ b/apps/openmw/mwgui/stats_window.cpp @@ -381,3 +381,8 @@ void StatsWindow::updateScroller() skillScrollerWidget->setScrollRange(std::max(clientHeight - skillClientWidget->getHeight(), 0)); skillScrollerWidget->setScrollPage(std::max(skillClientWidget->getHeight() - lineHeight, 0)); } + +void StatsWindow::onPinToggled() +{ + mWindowManager.setHMSVisibility(!mPinned); +} diff --git a/apps/openmw/mwgui/stats_window.hpp b/apps/openmw/mwgui/stats_window.hpp index 081a75d56d..f2731e545c 100644 --- a/apps/openmw/mwgui/stats_window.hpp +++ b/apps/openmw/mwgui/stats_window.hpp @@ -74,6 +74,9 @@ namespace MWGui std::string birthSignId; int reputation, bounty; std::vector skillWidgets; //< Skills and other information + + protected: + virtual void onPinToggled(); }; } #endif diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index 4d7b9f9013..8ad71186b7 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -456,3 +456,13 @@ void WindowManager::setPlayerDir(const float x, const float y) map->setPlayerDir(x,y); hud->setPlayerDir(x,y); } + +void WindowManager::setHMSVisibility(bool visible) +{ + hud->setBottomLeftVisibility(visible, hud->weapBox->getVisible(), hud->spellBox->getVisible()); +} + +void WindowManager::setMinimapVisibility(bool visible) +{ + hud->setBottomRightVisibility(hud->effectBox->getVisible(), visible); +} diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index 582f438e8f..e8637f8a2d 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -160,6 +160,11 @@ namespace MWGui void setInteriorMapTexture(const int x, const int y); ///< set the index of the map texture that should be used (for interiors) + // sets the visibility of the hud health/magicka/stamina bars + void setHMSVisibility(bool visible); + // sets the visibility of the hud minimap + void setMinimapVisibility(bool visible); + template void removeDialog(T*& dialog); ///< Casts to OEngine::GUI::Layout and calls removeDialog, then resets pointer to nullptr. void removeDialog(OEngine::GUI::Layout* dialog); ///< Hides dialog and schedules dialog to be deleted. diff --git a/apps/openmw/mwgui/window_pinnable_base.cpp b/apps/openmw/mwgui/window_pinnable_base.cpp index 07f0ea278b..ecdf311c6e 100644 --- a/apps/openmw/mwgui/window_pinnable_base.cpp +++ b/apps/openmw/mwgui/window_pinnable_base.cpp @@ -25,6 +25,7 @@ void WindowPinnableBase::onWindowButtonPressed(MyGUI::Window* sender, const std: if ("PinToggle" == eventName) { mPinned = !mPinned; + onPinToggled(); } eventDone(this); diff --git a/apps/openmw/mwgui/window_pinnable_base.hpp b/apps/openmw/mwgui/window_pinnable_base.hpp index f3cec847fd..8ef38c3867 100644 --- a/apps/openmw/mwgui/window_pinnable_base.hpp +++ b/apps/openmw/mwgui/window_pinnable_base.hpp @@ -17,6 +17,8 @@ namespace MWGui void onWindowButtonPressed(MyGUI::Window* sender, const std::string& eventName); protected: + virtual void onPinToggled() = 0; + bool mPinned; bool mVisible; }; diff --git a/files/mygui/openmw_hud_layout.xml b/files/mygui/openmw_hud_layout.xml index 20370770ef..2dafa72988 100644 --- a/files/mygui/openmw_hud_layout.xml +++ b/files/mygui/openmw_hud_layout.xml @@ -11,22 +11,24 @@ align="Left Bottom" name="Stamina"/> - - + + + + + - - - + + + + + - -