mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-20 09:53:51 +00:00
Drop MyGUI 3.4 requirement. Manage layer and widget focus manually.
This commit is contained in:
parent
02c7e8ed2a
commit
259330ab14
10 changed files with 164 additions and 104 deletions
|
@ -109,7 +109,7 @@ void MWBase::Environment::setVrMode(bool vrMode)
|
||||||
mVrMode = vrMode;
|
mVrMode = vrMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MWBase::Environment::getVrMode(void)
|
bool MWBase::Environment::getVrMode(void) const
|
||||||
{
|
{
|
||||||
return mVrMode;
|
return mVrMode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ namespace MWBase
|
||||||
void limitFrameRate(double dt) const;
|
void limitFrameRate(double dt) const;
|
||||||
|
|
||||||
void setVrMode(bool vrMode);
|
void setVrMode(bool vrMode);
|
||||||
bool getVrMode(void);
|
bool getVrMode(void) const;
|
||||||
|
|
||||||
World *getWorld() const;
|
World *getWorld() const;
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,9 @@
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
|
||||||
|
#include "../mwvr/vrenvironment.hpp"
|
||||||
|
#include "../mwvr/vrgui.hpp"
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -91,6 +94,9 @@ void KeyboardNavigation::_unlinkWidget(MyGUI::Widget *widget)
|
||||||
w.second = nullptr;
|
w.second = nullptr;
|
||||||
if (widget == mCurrentFocus)
|
if (widget == mCurrentFocus)
|
||||||
mCurrentFocus = nullptr;
|
mCurrentFocus = nullptr;
|
||||||
|
|
||||||
|
if (MWBase::Environment::get().getVrMode())
|
||||||
|
MWVR::Environment::get().getGUIManager()->notifyWidgetUnlinked(widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
void styleFocusedButton(MyGUI::Widget* w)
|
void styleFocusedButton(MyGUI::Widget* w)
|
||||||
|
@ -169,6 +175,9 @@ void KeyboardNavigation::setDefaultFocus(MyGUI::Widget *window, MyGUI::Widget *d
|
||||||
void KeyboardNavigation::setModalWindow(MyGUI::Widget *window)
|
void KeyboardNavigation::setModalWindow(MyGUI::Widget *window)
|
||||||
{
|
{
|
||||||
mModalWindow = window;
|
mModalWindow = window;
|
||||||
|
|
||||||
|
if (MWBase::Environment::get().getVrMode())
|
||||||
|
MWVR::Environment::get().getGUIManager()->notifyModalWindow(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyboardNavigation::setEnabled(bool enabled)
|
void KeyboardNavigation::setEnabled(bool enabled)
|
||||||
|
|
|
@ -83,25 +83,6 @@ namespace MWGui
|
||||||
window->setCaptionWithReplacing(title);
|
window->setCaptionWithReplacing(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Layout::setLayerPick(bool pick)
|
|
||||||
{
|
|
||||||
#if MYGUI_VERSION >= MYGUI_DEFINE_VERSION(3,4,0)
|
|
||||||
MyGUI::ILayer* layer = mMainWidget->getLayer();
|
|
||||||
// MyGUI exposes pick on the implementations of ILayer only, but not ILayer itself.
|
|
||||||
auto* oLayer = layer->castType<MyGUI::OverlappedLayer>(false);
|
|
||||||
auto* sLayer = layer->castType<MyGUI::SharedLayer>(false);
|
|
||||||
if (oLayer)
|
|
||||||
oLayer->setPick(pick);
|
|
||||||
if (sLayer)
|
|
||||||
sLayer->setPick(pick);
|
|
||||||
#else
|
|
||||||
#ifdef USE_OPENXR
|
|
||||||
#error "MyGUI version 3.4.0 or greater required to build for VR"
|
|
||||||
#endif
|
|
||||||
throw std::logic_error("Not implemented");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
MyGUI::Widget* Layout::getWidget(const std::string &_name)
|
MyGUI::Widget* Layout::getWidget(const std::string &_name)
|
||||||
{
|
{
|
||||||
for (MyGUI::Widget* widget : mListWindowRoot)
|
for (MyGUI::Widget* widget : mListWindowRoot)
|
||||||
|
|
|
@ -64,9 +64,6 @@ namespace MWGui
|
||||||
// NOTE: this assume that mMainWidget is of type Window.
|
// NOTE: this assume that mMainWidget is of type Window.
|
||||||
void setTitle(const std::string& title);
|
void setTitle(const std::string& title);
|
||||||
|
|
||||||
/// \note Affects the layer, not just the widget.
|
|
||||||
void setLayerPick(bool pick);
|
|
||||||
|
|
||||||
MyGUI::Widget* mMainWidget;
|
MyGUI::Widget* mMainWidget;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -25,6 +25,9 @@
|
||||||
|
|
||||||
#include "itemmodel.hpp"
|
#include "itemmodel.hpp"
|
||||||
|
|
||||||
|
#include "../mwvr/vrenvironment.hpp"
|
||||||
|
#include "../mwvr/vrgui.hpp"
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
std::string ToolTips::sSchoolNames[] = {"#{sSchoolAlteration}", "#{sSchoolConjuration}", "#{sSchoolDestruction}", "#{sSchoolIllusion}", "#{sSchoolMysticism}", "#{sSchoolRestoration}"};
|
std::string ToolTips::sSchoolNames[] = {"#{sSchoolAlteration}", "#{sSchoolConjuration}", "#{sSchoolDestruction}", "#{sSchoolIllusion}", "#{sSchoolMysticism}", "#{sSchoolRestoration}"};
|
||||||
|
@ -156,7 +159,11 @@ namespace MWGui
|
||||||
if (mRemainingDelay > 0)
|
if (mRemainingDelay > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getMouseFocusWidget();
|
MyGUI::Widget* focus = nullptr;
|
||||||
|
if (MWBase::Environment::get().getVrMode())
|
||||||
|
focus = MWVR::Environment::get().getGUIManager()->focusWidget();
|
||||||
|
else
|
||||||
|
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getMouseFocusWidget();
|
||||||
if (focus == 0)
|
if (focus == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -1781,7 +1781,7 @@ namespace MWGui
|
||||||
|
|
||||||
#ifdef USE_OPENXR
|
#ifdef USE_OPENXR
|
||||||
auto* vrGuiManager = MWVR::Environment::get().getGUIManager();
|
auto* vrGuiManager = MWVR::Environment::get().getGUIManager();
|
||||||
vrGuiManager->insertLayer(mVideoBackground->getLayer()->getName());
|
vrGuiManager->insertLayer(mVideoBackground->getLayer());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool cursorWasVisible = mCursorVisible;
|
bool cursorWasVisible = mCursorVisible;
|
||||||
|
@ -1834,7 +1834,7 @@ namespace MWGui
|
||||||
updateVisible();
|
updateVisible();
|
||||||
|
|
||||||
#ifdef USE_OPENXR
|
#ifdef USE_OPENXR
|
||||||
vrGuiManager->removeLayer(mVideoBackground->getLayer()->getName());
|
vrGuiManager->removeLayer(mVideoBackground->getLayer());
|
||||||
#endif
|
#endif
|
||||||
mVideoBackground->setVisible(false);
|
mVideoBackground->setVisible(false);
|
||||||
mVideoEnabled = false;
|
mVideoEnabled = false;
|
||||||
|
|
|
@ -67,6 +67,9 @@ namespace MWInput
|
||||||
|
|
||||||
void MouseManager::mouseMoved(const SDLUtil::MouseMotionEvent &arg)
|
void MouseManager::mouseMoved(const SDLUtil::MouseMotionEvent &arg)
|
||||||
{
|
{
|
||||||
|
if (MWBase::Environment::get().getVrMode())
|
||||||
|
return;
|
||||||
|
|
||||||
mBindingsManager->mouseMoved(arg);
|
mBindingsManager->mouseMoved(arg);
|
||||||
|
|
||||||
MWBase::InputManager* input = MWBase::Environment::get().getInputManager();
|
MWBase::InputManager* input = MWBase::Environment::get().getInputManager();
|
||||||
|
@ -236,6 +239,8 @@ namespace MWInput
|
||||||
|
|
||||||
void MouseManager::injectMouseMove(float xMove, float yMove, float mouseWheelMove)
|
void MouseManager::injectMouseMove(float xMove, float yMove, float mouseWheelMove)
|
||||||
{
|
{
|
||||||
|
if (MWBase::Environment::get().getVrMode())
|
||||||
|
return;
|
||||||
mGuiCursorX += xMove;
|
mGuiCursorX += xMove;
|
||||||
mGuiCursorY += yMove;
|
mGuiCursorY += yMove;
|
||||||
mMouseWheel += mouseWheelMove;
|
mMouseWheel += mouseWheelMove;
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include <MyGUI_InputManager.h>
|
#include <MyGUI_InputManager.h>
|
||||||
#include <MyGUI_WidgetManager.h>
|
#include <MyGUI_WidgetManager.h>
|
||||||
#include <MyGUI_Window.h>
|
#include <MyGUI_Window.h>
|
||||||
|
#include <MyGUI_Button.h>
|
||||||
|
|
||||||
namespace osg
|
namespace osg
|
||||||
{
|
{
|
||||||
|
@ -146,11 +147,12 @@ namespace MWVR
|
||||||
VRGUILayer::VRGUILayer(
|
VRGUILayer::VRGUILayer(
|
||||||
osg::ref_ptr<osg::Group> geometryRoot,
|
osg::ref_ptr<osg::Group> geometryRoot,
|
||||||
osg::ref_ptr<osg::Group> cameraRoot,
|
osg::ref_ptr<osg::Group> cameraRoot,
|
||||||
std::string layerName,
|
MyGUI::ILayer* layer,
|
||||||
LayerConfig config,
|
LayerConfig config,
|
||||||
VRGUIManager* parent)
|
VRGUIManager* parent)
|
||||||
: mConfig(config)
|
: mConfig(config)
|
||||||
, mLayerName(layerName)
|
, mLayerName(layer->getName())
|
||||||
|
, mMyGUILayer(layer)
|
||||||
, mGeometryRoot(geometryRoot)
|
, mGeometryRoot(geometryRoot)
|
||||||
, mCameraRoot(cameraRoot)
|
, mCameraRoot(cameraRoot)
|
||||||
{
|
{
|
||||||
|
@ -468,7 +470,8 @@ namespace MWVR
|
||||||
osg::Vec2(1,1),
|
osg::Vec2(1,1),
|
||||||
sizingMode,
|
sizingMode,
|
||||||
TrackingMode::Menu,
|
TrackingMode::Menu,
|
||||||
extraLayers
|
extraLayers,
|
||||||
|
false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
LayerConfig gDefaultConfig = createDefaultConfig(1);
|
LayerConfig gDefaultConfig = createDefaultConfig(1);
|
||||||
|
@ -493,7 +496,8 @@ namespace MWVR
|
||||||
osg::Vec2(1,1),
|
osg::Vec2(1,1),
|
||||||
SizingMode::Auto,
|
SizingMode::Auto,
|
||||||
TrackingMode::HudLeftHand,
|
TrackingMode::HudLeftHand,
|
||||||
""
|
"",
|
||||||
|
true
|
||||||
};
|
};
|
||||||
|
|
||||||
static const float sSideBySideRadius = 1.f;
|
static const float sSideBySideRadius = 1.f;
|
||||||
|
@ -512,7 +516,8 @@ namespace MWVR
|
||||||
osg::Vec2(0.70f, 0.70f),
|
osg::Vec2(0.70f, 0.70f),
|
||||||
SizingMode::Fixed,
|
SizingMode::Fixed,
|
||||||
gDefaultConfig.trackingMode,
|
gDefaultConfig.trackingMode,
|
||||||
""
|
"",
|
||||||
|
false
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -536,7 +541,8 @@ namespace MWVR
|
||||||
gDefaultConfig.myGUIViewSize,
|
gDefaultConfig.myGUIViewSize,
|
||||||
SizingMode::Auto,
|
SizingMode::Auto,
|
||||||
TrackingMode::HudLeftHand,
|
TrackingMode::HudLeftHand,
|
||||||
""
|
"",
|
||||||
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
LayerConfig gPopupConfig = LayerConfig
|
LayerConfig gPopupConfig = LayerConfig
|
||||||
|
@ -552,7 +558,8 @@ namespace MWVR
|
||||||
gDefaultConfig.myGUIViewSize,
|
gDefaultConfig.myGUIViewSize,
|
||||||
SizingMode::Auto,
|
SizingMode::Auto,
|
||||||
TrackingMode::HudRightHand,
|
TrackingMode::HudRightHand,
|
||||||
""
|
"",
|
||||||
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -601,9 +608,10 @@ namespace MWVR
|
||||||
mSideBySideLayers[i]->setAngle(low + static_cast<float>(i) * sSideBySideAzimuthInterval);
|
mSideBySideLayers[i]->setAngle(low + static_cast<float>(i) * sSideBySideAzimuthInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VRGUIManager::insertLayer(const std::string& name)
|
void VRGUIManager::insertLayer(MyGUI::ILayer* layer)
|
||||||
{
|
{
|
||||||
LayerConfig config = gDefaultConfig;
|
LayerConfig config = gDefaultConfig;
|
||||||
|
const auto& name = layer->getName();
|
||||||
auto configIt = gLayerConfigs.find(name);
|
auto configIt = gLayerConfigs.find(name);
|
||||||
if (configIt != gLayerConfigs.end())
|
if (configIt != gLayerConfigs.end())
|
||||||
{
|
{
|
||||||
|
@ -614,25 +622,25 @@ namespace MWVR
|
||||||
Log(Debug::Warning) << "Layer " << name << " has no configuration, using default";
|
Log(Debug::Warning) << "Layer " << name << " has no configuration, using default";
|
||||||
}
|
}
|
||||||
|
|
||||||
auto layer = std::shared_ptr<VRGUILayer>(new VRGUILayer(
|
auto vrlayer = std::shared_ptr<VRGUILayer>(new VRGUILayer(
|
||||||
mGUIGeometriesRoot,
|
mGUIGeometriesRoot,
|
||||||
mGUICamerasRoot,
|
mGUICamerasRoot,
|
||||||
name,
|
layer,
|
||||||
config,
|
config,
|
||||||
this
|
this
|
||||||
));
|
));
|
||||||
mLayers[name] = layer;
|
mLayers[name] = vrlayer;
|
||||||
|
|
||||||
layer->mGeometry->setUserData(new VRGUILayerUserData(mLayers[name]));
|
vrlayer->mGeometry->setUserData(new VRGUILayerUserData(mLayers[name]));
|
||||||
|
|
||||||
if (config.sideBySide)
|
if (config.sideBySide)
|
||||||
{
|
{
|
||||||
mSideBySideLayers.push_back(layer);
|
mSideBySideLayers.push_back(vrlayer);
|
||||||
updateSideBySideLayers();
|
updateSideBySideLayers();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.trackingMode == TrackingMode::Menu)
|
if (config.trackingMode == TrackingMode::Menu)
|
||||||
layer->updateTracking(mHeadPose);
|
vrlayer->updateTracking(mHeadPose);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VRGUIManager::insertWidget(MWGui::Layout* widget)
|
void VRGUIManager::insertWidget(MWGui::Layout* widget)
|
||||||
|
@ -643,32 +651,24 @@ namespace MWVR
|
||||||
auto it = mLayers.find(name);
|
auto it = mLayers.find(name);
|
||||||
if (it == mLayers.end())
|
if (it == mLayers.end())
|
||||||
{
|
{
|
||||||
insertLayer(name);
|
insertLayer(layer);
|
||||||
it = mLayers.find(name);
|
it = mLayers.find(name);
|
||||||
if (it == mLayers.end())
|
|
||||||
{
|
|
||||||
Log(Debug::Error) << "Failed to insert layer " << name;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
it->second->insertWidget(widget);
|
it->second->insertWidget(widget);
|
||||||
|
|
||||||
if (it->second.get() != mFocusLayer)
|
|
||||||
widget->setLayerPick(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VRGUIManager::removeLayer(const std::string& name)
|
void VRGUIManager::removeLayer(MyGUI::ILayer* layer)
|
||||||
{
|
{
|
||||||
auto it = mLayers.find(name);
|
auto it = mLayers.find(layer->getName());
|
||||||
if (it == mLayers.end())
|
if (it == mLayers.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto layer = it->second;
|
auto vrlayer = it->second;
|
||||||
|
|
||||||
for (auto it2 = mSideBySideLayers.begin(); it2 < mSideBySideLayers.end(); it2++)
|
for (auto it2 = mSideBySideLayers.begin(); it2 < mSideBySideLayers.end(); it2++)
|
||||||
{
|
{
|
||||||
if (*it2 == layer)
|
if (*it2 == vrlayer)
|
||||||
{
|
{
|
||||||
mSideBySideLayers.erase(it2);
|
mSideBySideLayers.erase(it2);
|
||||||
updateSideBySideLayers();
|
updateSideBySideLayers();
|
||||||
|
@ -684,9 +684,8 @@ namespace MWVR
|
||||||
void VRGUIManager::removeWidget(MWGui::Layout* widget)
|
void VRGUIManager::removeWidget(MWGui::Layout* widget)
|
||||||
{
|
{
|
||||||
auto* layer = widget->mMainWidget->getLayer();
|
auto* layer = widget->mMainWidget->getLayer();
|
||||||
auto name = layer->getName();
|
|
||||||
|
|
||||||
auto it = mLayers.find(name);
|
auto it = mLayers.find(layer->getName());
|
||||||
if (it == mLayers.end())
|
if (it == mLayers.end())
|
||||||
{
|
{
|
||||||
//Log(Debug::Warning) << "Tried to remove widget from nonexistent layer " << name;
|
//Log(Debug::Warning) << "Tried to remove widget from nonexistent layer " << name;
|
||||||
|
@ -696,7 +695,7 @@ namespace MWVR
|
||||||
it->second->removeWidget(widget);
|
it->second->removeWidget(widget);
|
||||||
if (it->second->widgetCount() == 0)
|
if (it->second->widgetCount() == 0)
|
||||||
{
|
{
|
||||||
removeLayer(name);
|
removeLayer(layer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -705,14 +704,12 @@ namespace MWVR
|
||||||
auto* layer = widget->mMainWidget->getLayer();
|
auto* layer = widget->mMainWidget->getLayer();
|
||||||
auto name = layer->getName();
|
auto name = layer->getName();
|
||||||
|
|
||||||
Log(Debug::Verbose) << "setVisible (" << name << "): " << visible;
|
|
||||||
if (layerBlacklist.find(name) != layerBlacklist.end())
|
if (layerBlacklist.find(name) != layerBlacklist.end())
|
||||||
{
|
{
|
||||||
Log(Debug::Verbose) << "Blacklisted";
|
Log(Debug::Verbose) << "setVisible (" << name << "): ignored";
|
||||||
// Never pick an invisible layer
|
|
||||||
widget->setLayerPick(false);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Log(Debug::Verbose) << "setVisible (" << name << "): " << visible;
|
||||||
|
|
||||||
if (visible)
|
if (visible)
|
||||||
insertWidget(widget);
|
insertWidget(widget);
|
||||||
|
@ -807,46 +804,111 @@ namespace MWVR
|
||||||
if (layer == mFocusLayer)
|
if (layer == mFocusLayer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (mFocusLayer)
|
setFocusWidget(nullptr);
|
||||||
{
|
|
||||||
mFocusLayer->mWidgets.front()->setLayerPick(false);
|
|
||||||
}
|
|
||||||
mFocusLayer = layer;
|
mFocusLayer = layer;
|
||||||
if (mFocusLayer)
|
|
||||||
{
|
|
||||||
Log(Debug::Verbose) << "Set focus layer to " << mFocusLayer->mWidgets.front()->mMainWidget->getLayer()->getName();
|
|
||||||
mFocusLayer->mWidgets.front()->setLayerPick(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log(Debug::Verbose) << "Set focus layer to null";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VRGUIManager::setFocusWidget(MyGUI::Widget* widget)
|
void VRGUIManager::setFocusWidget(MyGUI::Widget* widget)
|
||||||
{
|
{
|
||||||
// TODO: This relies on MyGUI internal functions and may break on any future version.
|
|
||||||
if (widget == mFocusWidget)
|
if (widget == mFocusWidget)
|
||||||
return;
|
return;
|
||||||
if (mFocusWidget)
|
|
||||||
|
// TODO: This relies on MyGUI internal functions and may break on any future version.
|
||||||
|
if (validateFocusWidget())
|
||||||
mFocusWidget->_riseMouseLostFocus(widget);
|
mFocusWidget->_riseMouseLostFocus(widget);
|
||||||
if (widget)
|
if (widget)
|
||||||
widget->_riseMouseSetFocus(mFocusWidget);
|
widget->_riseMouseSetFocus(mFocusWidget);
|
||||||
mFocusWidget = widget;
|
mFocusWidget = widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VRGUIManager::injectMouseClick(bool onPress)
|
// MyGUI may delete the focusWidget.
|
||||||
|
// Call this and check the result before dereferencing mFocusWidget
|
||||||
|
bool VRGUIManager::validateFocusWidget()
|
||||||
{
|
{
|
||||||
// TODO: This relies on MyGUI internal functions and may break on any future version.
|
|
||||||
if (mFocusWidget)
|
if (mFocusWidget)
|
||||||
{
|
{
|
||||||
if(onPress)
|
auto* cursorWidget = widgetFromGuiCursor(mGuiCursor.x(), mGuiCursor.y());
|
||||||
mFocusWidget->_riseMouseButtonClick();
|
// If the focus widget is no longer seen at the coordinate it was last seen
|
||||||
|
// it may have been deleted by mygui.
|
||||||
|
// In theory, notifyWidgetUnlinked() should catch all cases but doesn't.
|
||||||
|
if (cursorWidget != mFocusWidget)
|
||||||
|
{
|
||||||
|
mFocusWidget = nullptr;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VRGUIManager::focusIsModalWindow()
|
||||||
|
{
|
||||||
|
if (mFocusLayer)
|
||||||
|
for (auto* window : mFocusLayer->mWidgets)
|
||||||
|
if (mModalWindow == window->mMainWidget)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MyGUI::Widget* VRGUIManager::widgetFromGuiCursor(int x, int y)
|
||||||
|
{
|
||||||
|
if (mFocusLayer)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
mFocusLayer->mConfig.ignoreModality
|
||||||
|
|| !mModalWindow
|
||||||
|
|| focusIsModalWindow()
|
||||||
|
)
|
||||||
|
return static_cast<MyGUI::Widget*>(mFocusLayer->mMyGUILayer->getLayerItemByPoint(x, y));
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VRGUIManager::updateGuiCursor(int x, int y)
|
||||||
|
{
|
||||||
|
setFocusWidget(widgetFromGuiCursor(x, y));
|
||||||
|
mGuiCursor.x() = x;
|
||||||
|
mGuiCursor.y() = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VRGUIManager::injectMouseClick(bool onPress)
|
||||||
|
{
|
||||||
|
// TODO: This relies on MyGUI internal functions and may break on any future version.
|
||||||
|
if (validateFocusWidget())
|
||||||
|
{
|
||||||
|
if (onPress)
|
||||||
|
{
|
||||||
|
mFocusWidget->_riseMouseButtonPressed(mGuiCursor.x(), mGuiCursor.y(), MyGUI::MouseButton::Left);
|
||||||
|
|
||||||
|
MyGUI::Button* b = mFocusWidget->castType<MyGUI::Button>(false);
|
||||||
|
if (b && b->getEnabled())
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWindowManager()->playSound("Menu Click");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mFocusWidget->_riseMouseButtonReleased(mGuiCursor.x(), mGuiCursor.y(), MyGUI::MouseButton::Left);
|
||||||
|
mFocusWidget->_riseMouseButtonClick();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VRGUIManager::notifyWidgetUnlinked(MyGUI::Widget* widget)
|
||||||
|
{
|
||||||
|
if (widget == mFocusWidget)
|
||||||
|
{
|
||||||
|
mFocusWidget = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VRGUIManager::notifyModalWindow(MyGUI::Widget* window)
|
||||||
|
{
|
||||||
|
mModalWindow = window;
|
||||||
|
}
|
||||||
|
|
||||||
void VRGUIManager::computeGuiCursor(osg::Vec3 hitPoint)
|
void VRGUIManager::computeGuiCursor(osg::Vec3 hitPoint)
|
||||||
{
|
{
|
||||||
float x = 0;
|
float x = 0;
|
||||||
|
@ -866,26 +928,8 @@ namespace MWVR
|
||||||
y = bottom - height * y;
|
y = bottom - height * y;
|
||||||
}
|
}
|
||||||
|
|
||||||
mGuiCursor.x() = (int)x;
|
|
||||||
mGuiCursor.y() = (int)y;
|
|
||||||
|
|
||||||
MyGUI::InputManager::getInstance().injectMouseMove((int)x, (int)y, 0);
|
|
||||||
MWBase::Environment::get().getWindowManager()->setCursorActive(true);
|
MWBase::Environment::get().getWindowManager()->setCursorActive(true);
|
||||||
|
updateGuiCursor((int)x, (int)y);
|
||||||
// The virtual keyboard must be interactive regardless of modals
|
|
||||||
// This could be generalized with another config entry, but i don't think any other
|
|
||||||
// widgets/layers need it so i'm hardcoding it for the VirtualKeyboard for now.
|
|
||||||
if (
|
|
||||||
mFocusLayer
|
|
||||||
&& mFocusLayer->mLayerName == "VirtualKeyboard"
|
|
||||||
&& MyGUI::InputManager::getInstance().isModalAny())
|
|
||||||
{
|
|
||||||
auto* widget = MyGUI::LayerManager::getInstance().getWidgetFromPoint((int)x, (int)y);
|
|
||||||
setFocusWidget(widget);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
setFocusWidget(nullptr);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef OPENXR_MENU_HPP
|
#ifndef VRGUI_HPP
|
||||||
#define OPENXR_MENU_HPP
|
#define VRGUI_HPP
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
@ -25,6 +25,7 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
class Layout;
|
class Layout;
|
||||||
class WindowBase;
|
class WindowBase;
|
||||||
|
class ILayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct XrCompositionLayerQuad;
|
struct XrCompositionLayerQuad;
|
||||||
|
@ -63,6 +64,7 @@ namespace MWVR
|
||||||
SizingMode sizingMode; //!< How to size the layer
|
SizingMode sizingMode; //!< How to size the layer
|
||||||
TrackingMode trackingMode; //!< Tracking mode
|
TrackingMode trackingMode; //!< Tracking mode
|
||||||
std::string extraLayers; //!< Additional layers to draw (list separated by any non-alphabetic)
|
std::string extraLayers; //!< Additional layers to draw (list separated by any non-alphabetic)
|
||||||
|
bool ignoreModality; //!< Layer input should be enabled even if another modal window is active
|
||||||
|
|
||||||
bool operator<(const LayerConfig& rhs) const { return priority < rhs.priority; }
|
bool operator<(const LayerConfig& rhs) const { return priority < rhs.priority; }
|
||||||
};
|
};
|
||||||
|
@ -78,7 +80,7 @@ namespace MWVR
|
||||||
VRGUILayer(
|
VRGUILayer(
|
||||||
osg::ref_ptr<osg::Group> geometryRoot,
|
osg::ref_ptr<osg::Group> geometryRoot,
|
||||||
osg::ref_ptr<osg::Group> cameraRoot,
|
osg::ref_ptr<osg::Group> cameraRoot,
|
||||||
std::string layerName,
|
MyGUI::ILayer* layer,
|
||||||
LayerConfig config,
|
LayerConfig config,
|
||||||
VRGUIManager* parent);
|
VRGUIManager* parent);
|
||||||
~VRGUILayer();
|
~VRGUILayer();
|
||||||
|
@ -102,6 +104,7 @@ namespace MWVR
|
||||||
Pose mTrackedPose{};
|
Pose mTrackedPose{};
|
||||||
LayerConfig mConfig;
|
LayerConfig mConfig;
|
||||||
std::string mLayerName;
|
std::string mLayerName;
|
||||||
|
MyGUI::ILayer* mMyGUILayer;
|
||||||
std::vector<MWGui::Layout*> mWidgets;
|
std::vector<MWGui::Layout*> mWidgets;
|
||||||
osg::ref_ptr<osg::Group> mGeometryRoot;
|
osg::ref_ptr<osg::Group> mGeometryRoot;
|
||||||
osg::ref_ptr<osg::Geometry> mGeometry{ new osg::Geometry };
|
osg::ref_ptr<osg::Geometry> mGeometry{ new osg::Geometry };
|
||||||
|
@ -139,10 +142,10 @@ namespace MWVR
|
||||||
void setVisible(MWGui::Layout*, bool visible);
|
void setVisible(MWGui::Layout*, bool visible);
|
||||||
|
|
||||||
/// Insert the given layer quad if it isn't already
|
/// Insert the given layer quad if it isn't already
|
||||||
void insertLayer(const std::string& name);
|
void insertLayer(MyGUI::ILayer* layer);
|
||||||
|
|
||||||
/// Remove the given layer quad
|
/// Remove the given layer quad
|
||||||
void removeLayer(const std::string& name);
|
void removeLayer(MyGUI::ILayer* layer);
|
||||||
|
|
||||||
/// Update layer quads based on current camera
|
/// Update layer quads based on current camera
|
||||||
void updateTracking(void);
|
void updateTracking(void);
|
||||||
|
@ -162,6 +165,15 @@ namespace MWVR
|
||||||
/// Inject mouse click if applicable
|
/// Inject mouse click if applicable
|
||||||
bool injectMouseClick(bool onPress);
|
bool injectMouseClick(bool onPress);
|
||||||
|
|
||||||
|
/// Notify VRGUIManager that a widget has been unlinked
|
||||||
|
void notifyWidgetUnlinked(MyGUI::Widget* widget);
|
||||||
|
|
||||||
|
/// Notify VRGUIManager that a window is modal
|
||||||
|
void notifyModalWindow(MyGUI::Widget* window);
|
||||||
|
|
||||||
|
/// Currently focus widget according to VR
|
||||||
|
MyGUI::Widget* focusWidget() { return mFocusWidget; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void computeGuiCursor(osg::Vec3 hitPoint);
|
void computeGuiCursor(osg::Vec3 hitPoint);
|
||||||
void updateSideBySideLayers();
|
void updateSideBySideLayers();
|
||||||
|
@ -169,6 +181,10 @@ namespace MWVR
|
||||||
void removeWidget(MWGui::Layout* widget);
|
void removeWidget(MWGui::Layout* widget);
|
||||||
void setFocusLayer(VRGUILayer* layer);
|
void setFocusLayer(VRGUILayer* layer);
|
||||||
void setFocusWidget(MyGUI::Widget* widget);
|
void setFocusWidget(MyGUI::Widget* widget);
|
||||||
|
bool validateFocusWidget();
|
||||||
|
bool focusIsModalWindow();
|
||||||
|
MyGUI::Widget* widgetFromGuiCursor(int x, int y);
|
||||||
|
void updateGuiCursor(int x, int y);
|
||||||
|
|
||||||
osg::ref_ptr<osgViewer::Viewer> mOsgViewer{ nullptr };
|
osg::ref_ptr<osgViewer::Viewer> mOsgViewer{ nullptr };
|
||||||
|
|
||||||
|
@ -183,6 +199,7 @@ namespace MWVR
|
||||||
osg::Vec2i mGuiCursor{};
|
osg::Vec2i mGuiCursor{};
|
||||||
VRGUILayer* mFocusLayer{ nullptr };
|
VRGUILayer* mFocusLayer{ nullptr };
|
||||||
MyGUI::Widget* mFocusWidget{ nullptr };
|
MyGUI::Widget* mFocusWidget{ nullptr };
|
||||||
|
MyGUI::Widget* mModalWindow{ nullptr };
|
||||||
osg::observer_ptr<osg::Camera> mCamera{ nullptr };
|
osg::observer_ptr<osg::Camera> mCamera{ nullptr };
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue