Replaced combo boxes with list box dialogues to help navigate certain elements better in VR.

pull/615/head
madsbuvi 4 years ago
parent 00d6dc3a86
commit a0a7e6b5aa

@ -249,7 +249,7 @@ if(BUILD_OPENMW_VR)
add_openmw_dir (mwvr add_openmw_dir (mwvr
openxraction openxractionset openxrdebug openxrinput openxrmanager openxrmanagerimpl openxrplatform openxrswapchain openxrswapchainimage openxrswapchainimpl openxraction openxractionset openxrdebug openxrinput openxrmanager openxrmanagerimpl openxrplatform openxrswapchain openxrswapchainimage openxrswapchainimpl
realisticcombat realisticcombat
vranimation vrcamera vrenvironment vrframebuffer vrgui vrinputmanager vrinput vrmetamenu vrsession vrshadow vrtypes vrview vrviewer vrvirtualkeyboard vranimation vrcamera vrenvironment vrframebuffer vrgui vrinputmanager vrinput vrlistbox vrmetamenu vrsession vrshadow vrtypes vrview vrviewer vrvirtualkeyboard
) )
openmw_add_executable(openmw_vr openmw_add_executable(openmw_vr

@ -27,6 +27,10 @@
#include "itemwidget.hpp" #include "itemwidget.hpp"
#include "widgets.hpp" #include "widgets.hpp"
#ifdef USE_OPENXR
#include "../mwvr/vrlistbox.hpp"
#endif
namespace MWGui namespace MWGui
{ {
AlchemyWindow::AlchemyWindow() AlchemyWindow::AlchemyWindow()
@ -34,6 +38,9 @@ namespace MWGui
, mCurrentFilter(FilterType::ByName) , mCurrentFilter(FilterType::ByName)
, mModel(nullptr) , mModel(nullptr)
, mSortModel(nullptr) , mSortModel(nullptr)
, mFilterCombo(nullptr)
, mFilterEdit(nullptr)
, mFilterButton(nullptr)
, mAlchemy(new MWMechanics::Alchemy()) , mAlchemy(new MWMechanics::Alchemy())
, mApparatus (4) , mApparatus (4)
, mIngredients (4) , mIngredients (4)
@ -54,8 +61,31 @@ namespace MWGui
getWidget(mDecreaseButton, "DecreaseButton"); getWidget(mDecreaseButton, "DecreaseButton");
getWidget(mNameEdit, "NameEdit"); getWidget(mNameEdit, "NameEdit");
getWidget(mItemView, "ItemView"); getWidget(mItemView, "ItemView");
getWidget(mFilterValue, "FilterValue"); getWidget(mFilterCombo, "FilterValue");
getWidget(mFilterType, "FilterType"); getWidget(mFilterType, "FilterType");
getWidget(mFilterEdit, "FilterEdit");
getWidget(mFilterButton, "FilterButton");
if (MWBase::Environment::get().getVrMode())
{
#ifdef USE_OPENXR
mFilterListBox = new MWVR::VrListBox();
#endif
mFilterCombo->setVisible(false);
mFilterCombo->setUserString("Hidden", "true");
}
else
{
mFilterButton->setVisible(false);
mFilterButton->setUserString("Hidden", "true");
mFilterEdit->setVisible(false);
mFilterEdit->setUserString("Hidden", "true");
}
mFilterButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onFilterButtonClicked);
mFilterEdit->eventEditTextChange += MyGUI::newDelegate(this, &AlchemyWindow::onFilterEdited);
mFilterCombo->eventComboChangePosition += MyGUI::newDelegate(this, &AlchemyWindow::onFilterChanged);
mFilterCombo->eventEditTextChange += MyGUI::newDelegate(this, &AlchemyWindow::onFilterEdited);
mBrewCountEdit->eventValueChanged += MyGUI::newDelegate(this, &AlchemyWindow::onCountValueChanged); mBrewCountEdit->eventValueChanged += MyGUI::newDelegate(this, &AlchemyWindow::onCountValueChanged);
mBrewCountEdit->eventEditSelectAccept += MyGUI::newDelegate(this, &AlchemyWindow::onAccept); mBrewCountEdit->eventEditSelectAccept += MyGUI::newDelegate(this, &AlchemyWindow::onAccept);
@ -78,8 +108,7 @@ namespace MWGui
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCancelButtonClicked); mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCancelButtonClicked);
mNameEdit->eventEditSelectAccept += MyGUI::newDelegate(this, &AlchemyWindow::onAccept); mNameEdit->eventEditSelectAccept += MyGUI::newDelegate(this, &AlchemyWindow::onAccept);
mFilterValue->eventComboChangePosition += MyGUI::newDelegate(this, &AlchemyWindow::onFilterChanged);
mFilterValue->eventEditTextChange += MyGUI::newDelegate(this, &AlchemyWindow::onFilterEdited);
mFilterType->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::switchFilterType); mFilterType->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::switchFilterType);
center(); center();
@ -160,7 +189,8 @@ namespace MWGui
else else
mCurrentFilter = FilterType::ByEffect; mCurrentFilter = FilterType::ByEffect;
updateFilters(); updateFilters();
mFilterValue->clearIndexSelected(); mFilterCombo->clearIndexSelected();
mFilterEdit->setCaption("");
updateFilters(); updateFilters();
} }
@ -183,39 +213,44 @@ namespace MWGui
} }
mSortModel->setNameFilter({}); mSortModel->setNameFilter({});
mSortModel->setEffectFilter({}); mSortModel->setEffectFilter({});
mFilterValue->clearIndexSelected(); mFilterCombo->clearIndexSelected();
mFilterEdit->setCaption("");
updateFilters(); updateFilters();
mItemView->update(); mItemView->update();
} }
void AlchemyWindow::updateFilters() void AlchemyWindow::updateFilters()
{ {
std::set<std::string> itemNames, itemEffects; mItemEffects.clear();
mItemNames.clear();
for (size_t i = 0; i < mModel->getItemCount(); ++i) for (size_t i = 0; i < mModel->getItemCount(); ++i)
{ {
MWWorld::Ptr item = mModel->getItem(i).mBase; MWWorld::Ptr item = mModel->getItem(i).mBase;
if (item.getTypeName() != typeid(ESM::Ingredient).name()) if (item.getTypeName() != typeid(ESM::Ingredient).name())
continue; continue;
itemNames.insert(item.getClass().getName(item)); mItemNames.insert(item.getClass().getName(item));
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
auto const alchemySkill = player.getClass().getSkill(player, ESM::Skill::Alchemy); auto const alchemySkill = player.getClass().getSkill(player, ESM::Skill::Alchemy);
auto const effects = MWMechanics::Alchemy::effectsDescription(item, alchemySkill); auto const effects = MWMechanics::Alchemy::effectsDescription(item, alchemySkill);
itemEffects.insert(effects.begin(), effects.end()); mItemEffects.insert(effects.begin(), effects.end());
} }
mFilterValue->removeAllItems(); mFilterCombo->removeAllItems();
auto const addItems = [&](auto const& container) for (auto const& item : items())
{ {
for (auto const& item : container) mFilterCombo->addItem(item);
mFilterValue->addItem(item); }
}; }
const std::set<std::string>& AlchemyWindow::items()
{
switch (mCurrentFilter) switch (mCurrentFilter)
{ {
case FilterType::ByName: addItems(itemNames); break; case FilterType::ByName: return mItemNames; break;
case FilterType::ByEffect: addItems(itemEffects); break; case FilterType::ByEffect: return mItemEffects; break;
} }
} }
@ -242,6 +277,20 @@ namespace MWGui
applyFilter(_sender->getCaption()); applyFilter(_sender->getCaption());
} }
void AlchemyWindow::onFilterButtonClicked(MyGUI::Widget* _sender)
{
#ifdef USE_OPENXR
mFilterListBox->open(mFilterCombo, [this](std::size_t index) {
if (index != MyGUI::ITEM_NONE)
{
auto filter = mFilterCombo->getItemNameAt(index);
mFilterEdit->setCaption(filter);
applyFilter(filter);
}
});
#endif
}
void AlchemyWindow::onOpen() void AlchemyWindow::onOpen()
{ {
mAlchemy->clear(); mAlchemy->clear();

@ -6,6 +6,7 @@
#include <MyGUI_ControllerItem.h> #include <MyGUI_ControllerItem.h>
#include <MyGUI_ComboBox.h> #include <MyGUI_ComboBox.h>
#include <MyGUI_ListBox.h>
#include <components/widgets/box.hpp> #include <components/widgets/box.hpp>
#include <components/widgets/numericeditbox.hpp> #include <components/widgets/numericeditbox.hpp>
@ -17,6 +18,11 @@ namespace MWMechanics
class Alchemy; class Alchemy;
} }
namespace MWVR
{
class VrListBox;
}
namespace MWGui namespace MWGui
{ {
class ItemView; class ItemView;
@ -54,10 +60,16 @@ namespace MWGui
MyGUI::Button* mIncreaseButton; MyGUI::Button* mIncreaseButton;
MyGUI::Button* mDecreaseButton; MyGUI::Button* mDecreaseButton;
Gui::AutoSizedButton* mFilterType; Gui::AutoSizedButton* mFilterType;
MyGUI::ComboBox* mFilterValue; MyGUI::ComboBox* mFilterCombo;
MyGUI::EditBox* mFilterEdit;
MyGUI::Button* mFilterButton;
MWVR::VrListBox* mFilterListBox;
MyGUI::EditBox* mNameEdit; MyGUI::EditBox* mNameEdit;
Gui::NumericEditBox* mBrewCountEdit; Gui::NumericEditBox* mBrewCountEdit;
std::set<std::string> mItemNames;
std::set<std::string> mItemEffects;
void onCancelButtonClicked(MyGUI::Widget* _sender); void onCancelButtonClicked(MyGUI::Widget* _sender);
void onCreateButtonClicked(MyGUI::Widget* _sender); void onCreateButtonClicked(MyGUI::Widget* _sender);
void onIngredientSelected(MyGUI::Widget* _sender); void onIngredientSelected(MyGUI::Widget* _sender);
@ -72,8 +84,10 @@ namespace MWGui
void initFilter(); void initFilter();
void onFilterChanged(MyGUI::ComboBox* _sender, size_t _index); void onFilterChanged(MyGUI::ComboBox* _sender, size_t _index);
void onFilterEdited(MyGUI::EditBox* _sender); void onFilterEdited(MyGUI::EditBox* _sender);
void onFilterButtonClicked(MyGUI::Widget* _sender);
void switchFilterType(MyGUI::Widget* _sender); void switchFilterType(MyGUI::Widget* _sender);
void updateFilters(); void updateFilters();
const std::set<std::string>& items();
void addRepeatController(MyGUI::Widget* widget); void addRepeatController(MyGUI::Widget* widget);

@ -30,6 +30,10 @@
#include "../mwstate/character.hpp" #include "../mwstate/character.hpp"
#ifdef USE_OPENXR
#include "../mwvr/vrlistbox.hpp"
#endif
#include "confirmationdialog.hpp" #include "confirmationdialog.hpp"
namespace MWGui namespace MWGui
@ -41,7 +45,6 @@ namespace MWGui
, mCurrentSlot(nullptr) , mCurrentSlot(nullptr)
{ {
getWidget(mScreenshot, "Screenshot"); getWidget(mScreenshot, "Screenshot");
getWidget(mCharacterSelection, "SelectCharacter");
getWidget(mInfoText, "InfoText"); getWidget(mInfoText, "InfoText");
getWidget(mOkButton, "OkButton"); getWidget(mOkButton, "OkButton");
getWidget(mCancelButton, "CancelButton"); getWidget(mCancelButton, "CancelButton");
@ -49,11 +52,28 @@ namespace MWGui
getWidget(mSaveList, "SaveList"); getWidget(mSaveList, "SaveList");
getWidget(mSaveNameEdit, "SaveNameEdit"); getWidget(mSaveNameEdit, "SaveNameEdit");
getWidget(mSpacer, "Spacer"); getWidget(mSpacer, "Spacer");
getWidget(mCharacterSelection, "SelectCharacter");
getWidget(mCharacterSelectionButton, "SelectCharacterButton");
if (MWBase::Environment::get().getVrMode())
{
#ifdef USE_OPENXR
mCharacterSelectionListBox = new MWVR::VrListBox();
#endif
mCharacterSelection->setVisible(false);
mCharacterSelection->setUserString("Hidden", "true");
}
else
{
mCharacterSelectionButton->setVisible(false);
mCharacterSelectionButton->setUserString("Hidden", "true");
}
mCharacterSelectionButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SaveGameDialog::onCharacterSelectionButtonClicked);
mCharacterSelection->eventComboChangePosition += MyGUI::newDelegate(this, &SaveGameDialog::onCharacterSelected);
mCharacterSelection->eventComboAccept += MyGUI::newDelegate(this, &SaveGameDialog::onCharacterAccept);
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SaveGameDialog::onOkButtonClicked); mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SaveGameDialog::onOkButtonClicked);
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SaveGameDialog::onCancelButtonClicked); mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SaveGameDialog::onCancelButtonClicked);
mDeleteButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SaveGameDialog::onDeleteButtonClicked); mDeleteButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SaveGameDialog::onDeleteButtonClicked);
mCharacterSelection->eventComboChangePosition += MyGUI::newDelegate(this, &SaveGameDialog::onCharacterSelected);
mCharacterSelection->eventComboAccept += MyGUI::newDelegate(this, &SaveGameDialog::onCharacterAccept);
mSaveList->eventListChangePosition += MyGUI::newDelegate(this, &SaveGameDialog::onSlotSelected); mSaveList->eventListChangePosition += MyGUI::newDelegate(this, &SaveGameDialog::onSlotSelected);
mSaveList->eventListMouseItemActivate += MyGUI::newDelegate(this, &SaveGameDialog::onSlotMouseClick); mSaveList->eventListMouseItemActivate += MyGUI::newDelegate(this, &SaveGameDialog::onSlotMouseClick);
mSaveList->eventListSelectAccept += MyGUI::newDelegate(this, &SaveGameDialog::onSlotActivated); mSaveList->eventListSelectAccept += MyGUI::newDelegate(this, &SaveGameDialog::onSlotActivated);
@ -147,11 +167,15 @@ namespace MWGui
if (mSaving) if (mSaving)
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveNameEdit); MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveNameEdit);
else else
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveList); if (MWBase::Environment::get().getVrMode())
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCharacterSelectionButton);
else
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveList);
center(); center();
mCharacterSelection->setCaption(""); mCharacterSelection->setCaption("");
mCharacterSelectionButton->setCaption("");
mCharacterSelection->removeAllItems(); mCharacterSelection->removeAllItems();
mCurrentCharacter = nullptr; mCurrentCharacter = nullptr;
mCurrentSlot = nullptr; mCurrentSlot = nullptr;
@ -209,6 +233,8 @@ namespace MWGui
mCharacterSelection->setIndexSelected(selectedIndex); mCharacterSelection->setIndexSelected(selectedIndex);
if (selectedIndex == MyGUI::ITEM_NONE) if (selectedIndex == MyGUI::ITEM_NONE)
mCharacterSelection->setCaption("Select Character ..."); mCharacterSelection->setCaption("Select Character ...");
else
mCharacterSelectionButton->setCaption(mCharacterSelection->getCaption());
fillSaveList(); fillSaveList();
@ -218,8 +244,17 @@ namespace MWGui
{ {
mSaving = !load; mSaving = !load;
mSaveNameEdit->setVisible(!load); mSaveNameEdit->setVisible(!load);
mCharacterSelection->setUserString("Hidden", load ? "false" : "true");
mCharacterSelection->setVisible(load); if (MWBase::Environment::get().getVrMode())
{
mCharacterSelectionButton->setUserString("Hidden", load ? "false" : "true");
mCharacterSelectionButton->setVisible(load);
}
else
{
mCharacterSelection->setUserString("Hidden", load ? "false" : "true");
mCharacterSelection->setVisible(load);
}
mSpacer->setUserString("Hidden", load ? "false" : "true"); mSpacer->setUserString("Hidden", load ? "false" : "true");
mDeleteButton->setUserString("Hidden", load ? "false" : "true"); mDeleteButton->setUserString("Hidden", load ? "false" : "true");
@ -244,6 +279,21 @@ namespace MWGui
confirmDeleteSave(); confirmDeleteSave();
} }
void SaveGameDialog::onCharacterSelectionButtonClicked(MyGUI::Widget* sender)
{
#ifdef USE_OPENXR
mCharacterSelectionListBox->open(mCharacterSelection, [this](std::size_t index) {
if (index != MyGUI::ITEM_NONE)
{
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveList);
auto caption = mCharacterSelection->getItemNameAt(index);
mCharacterSelectionButton->setCaption(caption);
onCharacterSelected(mCharacterSelection, index);
}
});
#endif
}
void SaveGameDialog::onConfirmationGiven() void SaveGameDialog::onConfirmationGiven()
{ {
accept(true); accept(true);

@ -11,6 +11,11 @@ namespace MWState
struct Slot; struct Slot;
} }
namespace MWVR
{
class VrListBox;
}
namespace MWGui namespace MWGui
{ {
@ -31,6 +36,7 @@ namespace MWGui
void onCancelButtonClicked (MyGUI::Widget* sender); void onCancelButtonClicked (MyGUI::Widget* sender);
void onOkButtonClicked (MyGUI::Widget* sender); void onOkButtonClicked (MyGUI::Widget* sender);
void onDeleteButtonClicked (MyGUI::Widget* sender); void onDeleteButtonClicked (MyGUI::Widget* sender);
void onCharacterSelectionButtonClicked(MyGUI::Widget* sender);
void onCharacterSelected (MyGUI::ComboBox* sender, size_t pos); void onCharacterSelected (MyGUI::ComboBox* sender, size_t pos);
void onCharacterAccept(MyGUI::ComboBox* sender, size_t pos); void onCharacterAccept(MyGUI::ComboBox* sender, size_t pos);
// Slot selected (mouse click or arrow keys) // Slot selected (mouse click or arrow keys)
@ -57,6 +63,8 @@ namespace MWGui
bool mSaving; bool mSaving;
MyGUI::ComboBox* mCharacterSelection; MyGUI::ComboBox* mCharacterSelection;
MWVR::VrListBox* mCharacterSelectionListBox;
MyGUI::Button* mCharacterSelectionButton;
MyGUI::EditBox* mInfoText; MyGUI::EditBox* mInfoText;
MyGUI::Button* mOkButton; MyGUI::Button* mOkButton;
MyGUI::Button* mCancelButton; MyGUI::Button* mCancelButton;

@ -548,6 +548,7 @@ namespace MWVR
LayerConfig videoPlayerConfig = createDefaultConfig(4, true, SizingMode::Fixed); LayerConfig videoPlayerConfig = createDefaultConfig(4, true, SizingMode::Fixed);
LayerConfig messageBoxConfig = createDefaultConfig(6, false, SizingMode::Auto);; LayerConfig messageBoxConfig = createDefaultConfig(6, false, SizingMode::Auto);;
LayerConfig notificationConfig = createDefaultConfig(7, false, SizingMode::Fixed); LayerConfig notificationConfig = createDefaultConfig(7, false, SizingMode::Fixed);
LayerConfig listBoxConfig = createDefaultConfig(10, true);
LayerConfig statsWindowConfig = createSideBySideConfig(0); LayerConfig statsWindowConfig = createSideBySideConfig(0);
LayerConfig inventoryWindowConfig = createSideBySideConfig(1); LayerConfig inventoryWindowConfig = createSideBySideConfig(1);
@ -624,6 +625,7 @@ namespace MWVR
{"DialogueWindow", dialogueWindowConfig}, {"DialogueWindow", dialogueWindowConfig},
{"MessageBox", messageBoxConfig}, {"MessageBox", messageBoxConfig},
{"Windows", defaultWindowsConfig}, {"Windows", defaultWindowsConfig},
{"ListBox", listBoxConfig},
{"MainMenu", mainMenuConfig}, {"MainMenu", mainMenuConfig},
{"Notification", notificationConfig}, {"Notification", notificationConfig},
{"InputBlocker", videoPlayerConfig}, {"InputBlocker", videoPlayerConfig},

@ -534,8 +534,7 @@ namespace MWVR
vrGuiManager->updateTracking(); vrGuiManager->updateTracking();
break; break;
case A_MenuSelect: case A_MenuSelect:
if (!wm->injectKeyPress(MyGUI::KeyCode::Return, 0, false)) wm->injectKeyPress(MyGUI::KeyCode::Return, 0, false);
executeAction(MWInput::A_Activate);
break; break;
case A_MenuBack: case A_MenuBack:
if (MyGUI::InputManager::getInstance().isModalAny()) if (MyGUI::InputManager::getInstance().isModalAny())
@ -559,6 +558,9 @@ namespace MWVR
mBindingsManager->ics().getChannel(MWInput::A_Use)->setValue(0.f); mBindingsManager->ics().getChannel(MWInput::A_Use)->setValue(0.f);
pointActivation(false); pointActivation(false);
break; break;
case A_MenuSelect:
wm->injectKeyRelease(MyGUI::KeyCode::Return);
break;
default: default:
break; break;
} }

@ -0,0 +1,89 @@
#include "vrlistbox.hpp"
#include <MyGUI_InputManager.h>
#include <MyGUI_LayerManager.h>
#include <MyGUI_ComboBox.h>
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/statemanager.hpp"
namespace MWVR
{
VrListBox::VrListBox()
: WindowModal("openmw_vr_listbox.layout")
, mOK(nullptr)
, mCancel(nullptr)
, mListBox(nullptr)
, mIndex(MyGUI::ITEM_NONE)
, mCallback()
{
getWidget(mOK, "OkButton");
getWidget(mCancel, "CancelButton");
getWidget(mListBox, "ListBox");
mOK->eventMouseButtonClick += MyGUI::newDelegate(this, &VrListBox::onOKButtonClicked);
mCancel->eventMouseButtonClick += MyGUI::newDelegate(this, &VrListBox::onCancelButtonClicked);
mListBox->eventListChangePosition += MyGUI::newDelegate(this, &VrListBox::onItemChanged);
mListBox->eventListSelectAccept += MyGUI::newDelegate(this, &VrListBox::onListAccept);
}
VrListBox::~VrListBox()
{
}
void VrListBox::open(MyGUI::ComboBox* comboBox, Callback callback)
{
mCallback = callback;
mIndex = MyGUI::ITEM_NONE;
mListBox->removeAllItems();
mListBox->setIndexSelected(MyGUI::ITEM_NONE);
for (unsigned i = 0; i < comboBox->getItemCount(); i++)
mListBox->addItem(comboBox->getItemNameAt(i));
mListBox->setItemSelect(comboBox->getIndexSelected());
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mListBox);
center();
setVisible(true);
}
void VrListBox::close()
{
setVisible(false);
}
void VrListBox::onItemChanged(MyGUI::ListBox* _sender, size_t _index)
{
mIndex = _index;
}
void VrListBox::onCancelButtonClicked(MyGUI::Widget* sender)
{
close();
if (mCallback)
mCallback(MyGUI::ITEM_NONE);
}
void VrListBox::onOKButtonClicked(MyGUI::Widget* sender)
{
accept(mIndex);
}
void VrListBox::onListAccept(MyGUI::ListBox* sender, size_t pos)
{
accept(pos);
}
void VrListBox::accept(size_t index)
{
close();
if (mCallback)
mCallback(index);
}
}

@ -0,0 +1,47 @@
#ifndef OPENMW_GAME_MWVR_LISTBOX_H
#define OPENMW_GAME_MWVR_LISTBOX_H
#include "../mwgui/windowbase.hpp"
#include <MyGUI_Button.h>
#include <MyGUI_ListBox.h>
#include "components/widgets/virtualkeyboardmanager.hpp"
#include <set>
#include <memory>
namespace Gui
{
class VirtualKeyboardManager;
}
namespace MWVR
{
//! A simple dialogue that presents a list of choices. Used as an alternative to combo boxes in VR.
class VrListBox : public MWGui::WindowModal
{
public:
using Callback = std::function<void(std::size_t)>;
VrListBox();
~VrListBox();
void open(MyGUI::ComboBox* comboBox, Callback callback);
void close();
private:
void onItemChanged(MyGUI::ListBox* _sender, size_t _index);
void onCancelButtonClicked(MyGUI::Widget* sender);
void onOKButtonClicked(MyGUI::Widget* sender);
void onListAccept(MyGUI::ListBox* sender, size_t pos);
void accept(size_t index);
MyGUI::Widget* mCancel;
MyGUI::Widget* mOK;
MyGUI::ListBox* mListBox;
std::size_t mIndex;
Callback mCallback;
};
}
#endif

@ -85,7 +85,8 @@ namespace MWVR
void VrVirtualKeyboard::delegateOnSetFocus(MyGUI::Widget* _sender, MyGUI::Widget* _old) void VrVirtualKeyboard::delegateOnSetFocus(MyGUI::Widget* _sender, MyGUI::Widget* _old)
{ {
open(static_cast<MyGUI::EditBox*>(_sender)); if (_sender->getUserString("VirtualKeyboard") != "false")
open(static_cast<MyGUI::EditBox*>(_sender));
} }
void VrVirtualKeyboard::delegateOnLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new) void VrVirtualKeyboard::delegateOnLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new)

@ -488,11 +488,10 @@ namespace Gui
} }
EditBox::EditBox(bool shouldSupportVirtualKeyboard) EditBox::EditBox()
: mVirtualKeyboardRegistered(false) : mVirtualKeyboardRegistered(false)
{ {
if (shouldSupportVirtualKeyboard) registerVirtualKeyboard();
registerVirtualKeyboard();
} }
EditBox::~EditBox() EditBox::~EditBox()
{ {
@ -500,14 +499,11 @@ namespace Gui
} }
void EditBox::registerVirtualKeyboard() void EditBox::registerVirtualKeyboard()
{ {
if (!mVirtualKeyboardRegistered) auto* vkm = Gui::VirtualKeyboardManager::getInstancePtr();
if (vkm)
{ {
auto* vkm = Gui::VirtualKeyboardManager::getInstancePtr(); vkm->registerEditBox(this);
if (vkm) mVirtualKeyboardRegistered = true;
{
vkm->registerEditBox(this);
mVirtualKeyboardRegistered = true;
}
} }
} }
void EditBox::unregisterVirtualKeyboard() void EditBox::unregisterVirtualKeyboard()

@ -26,7 +26,7 @@ namespace Gui
MYGUI_RTTI_DERIVED( EditBox ) MYGUI_RTTI_DERIVED( EditBox )
/// @param supportsVirtualKeyboard If true, VR mode will spawn a virtual keyboard whenever this widget is focused. /// @param supportsVirtualKeyboard If true, VR mode will spawn a virtual keyboard whenever this widget is focused.
EditBox(bool shouldSupportVirtualKeyboard = true); EditBox();
~EditBox(); ~EditBox();
private: private:

@ -99,6 +99,7 @@ set(MYGUI_FILES
openmw_trade_window_vr.layout openmw_trade_window_vr.layout
openmw_trainingwindow.layout openmw_trainingwindow.layout
openmw_travel_window.layout openmw_travel_window.layout
openmw_vr_listbox.layout
openmw_vr_virtual_keyboard.layout openmw_vr_virtual_keyboard.layout
openmw_wait_dialog.layout openmw_wait_dialog.layout
openmw_wait_dialog_progressbar.layout openmw_wait_dialog_progressbar.layout

@ -83,6 +83,12 @@
<UserString key="HStretch" value="true"/> <UserString key="HStretch" value="true"/>
<Property key="ModeDrop" value="false"/> <Property key="ModeDrop" value="false"/>
</Widget> </Widget>
<Widget type="EditBox" skin="MW_TextEdit" position="0 2 0 24" name="FilterEdit">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" position="10 2 1 1" name="FilterButton">
<Property key="Caption" value="List"/> <!-- default value, can be either sIngredients or sMagicEffects -->
</Widget>
</Widget> </Widget>

@ -18,6 +18,7 @@
<Property key="Size" value="600 520"/> <Property key="Size" value="600 520"/>
</Layer> </Layer>
<Layer name="Windows" overlapped="true" pick="true"/> <Layer name="Windows" overlapped="true" pick="true"/>
<Layer name="ListBox" overlapped="true" pick="true"/>
<Layer name="Debug" overlapped="true" pick="true"/> <Layer name="Debug" overlapped="true" pick="true"/>
<Layer name="Notification" overlapped="false" pick="false"/> <Layer name="Notification" overlapped="false" pick="false"/>
<Layer name="Tooltip" overlapped="true" pick="true"/> <Layer name="Tooltip" overlapped="true" pick="true"/>

@ -21,6 +21,11 @@
<UserString key="HStretch" value="true"/> <UserString key="HStretch" value="true"/>
</Widget> </Widget>
<Widget type="AutoSizedButton" skin="MW_Button" position="0 0 200 24" name="SelectCharacterButton">
<Property key="Caption" value="Select Character"/>
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="ListBox" skin="MW_List" position="0 0 200 200" name="SaveList"> <Widget type="ListBox" skin="MW_List" position="0 0 200 200" name="SaveList">
<UserString key="HStretch" value="true"/> <UserString key="HStretch" value="true"/>

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layout">
<Widget type="VBox" skin="MW_DialogNoTransp" layer="ListBox" position="0 0 500 300" name="_Main" align="Center">
<Property key="Spacing" value="8"/>
<Property key="Padding" value="8"/>
<Widget type="ListBox" skin="MW_List" position="0 0 200 400" name="ListBox">
<UserString key="HStretch" value="true"/>
<UserString key="VStretch" value="true"/>
</Widget>
<Widget type="HBox" skin="">
<Property key="Padding" value="8"/>
<UserString key="HStretch" value="true"/>
<UserString key="VStretch" value="true"/>
<Widget type="AutoSizedButton" skin="MW_Button" name="OkButton">
<Property key="Caption" value="#{sOk}"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="CancelButton">
<Property key="Caption" value="#{sCancel}"/>
</Widget>
</Widget>
</Widget>
</MyGUI>
Loading…
Cancel
Save