1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-12-09 10:04:30 +00:00

Update item view to allow controller support; test it in Container menu

This commit is contained in:
Andrew Lanzone 2025-05-14 02:31:32 -07:00
parent 77e17743f7
commit f055ccf5ba
9 changed files with 181 additions and 6 deletions

View file

@ -3,6 +3,8 @@
#include <MyGUI_Button.h> #include <MyGUI_Button.h>
#include <MyGUI_InputManager.h> #include <MyGUI_InputManager.h>
#include <components/settings/values.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/scriptmanager.hpp" #include "../mwbase/scriptmanager.hpp"
@ -88,8 +90,13 @@ namespace MWGui
name += MWGui::ToolTips::getSoulString(object.getCellRef()); name += MWGui::ToolTips::getSoulString(object.getCellRef());
dialog->openCountDialog(name, "#{sTake}", count); dialog->openCountDialog(name, "#{sTake}", count);
dialog->eventOkClicked.clear(); dialog->eventOkClicked.clear();
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerWindow::dragItem); if (Settings::gui().mControllerMenus && !mUsingGamepadGuiCursor)
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerWindow::takeItem);
else
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerWindow::dragItem);
} }
else if (Settings::gui().mControllerMenus && !mUsingGamepadGuiCursor)
takeItem(nullptr, count);
else else
dragItem(nullptr, count); dragItem(nullptr, count);
} }
@ -105,6 +112,30 @@ namespace MWGui
mDragAndDrop->startDrag(mSelectedItem, mSortModel, mModel, mItemView, count); mDragAndDrop->startDrag(mSelectedItem, mSortModel, mModel, mItemView, count);
} }
void ContainerWindow::takeItem(MyGUI::Widget* sender, int count)
{
if (!mModel)
return;
const ItemStack& item = mModel->getItem(mSelectedItem);
if (!onTakeItem(item, count))
return;
MWGui::InventoryWindow* inventoryWindow
= MWBase::Environment::get().getWindowManager()->getInventoryWindow();
ItemModel* playerModel = inventoryWindow->getModel();
mModel->moveItem(item, count, playerModel);
inventoryWindow->updateItemView();
mItemView->update();
// play the item's sound
MWWorld::Ptr itemBase = item.mBase;
const ESM::RefId& sound = itemBase.getClass().getUpSoundId(itemBase);
MWBase::Environment::get().getWindowManager()->playSound(sound);
}
void ContainerWindow::dropItem() void ContainerWindow::dropItem()
{ {
if (!mModel) if (!mModel)
@ -320,4 +351,51 @@ namespace MWGui
if (mModel && mModel->usesContainer(ptr)) if (mModel && mModel->usesContainer(ptr))
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container); MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
} }
bool ContainerWindow::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)
{
if (arg.button == SDL_CONTROLLER_BUTTON_A)
{
if (mUsingGamepadGuiCursor)
return false;
int index = mItemView->getControllerFocus();
if (index >= 0 && index < mItemView->getItemCount())
{
onItemSelected(index);
}
}
else if (arg.button == SDL_CONTROLLER_BUTTON_B)
{
onCloseButtonClicked(mCloseButton);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_X)
{
onTakeAllButtonClicked(mTakeButton);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_LEFTSHOULDER)
{
if (mDisposeCorpseButton->getVisible())
onDisposeCorpseButtonClicked(mDisposeCorpseButton);
}
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP ||
arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN ||
arg.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT ||
arg.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT)
{
mItemView->onControllerButtonEvent(arg);
mUsingGamepadGuiCursor = false;
}
return true;
}
bool ContainerWindow::onControllerThumbstickEvent(const SDL_ControllerAxisEvent& arg)
{
if (arg.axis == SDL_CONTROLLER_AXIS_LEFTX || arg.axis == SDL_CONTROLLER_AXIS_LEFTY)
{
mUsingGamepadGuiCursor = true;
}
return false;
}
} }

View file

@ -55,6 +55,7 @@ namespace MWGui
void onItemSelected(int index); void onItemSelected(int index);
void onBackgroundSelected(); void onBackgroundSelected();
void dragItem(MyGUI::Widget* sender, int count); void dragItem(MyGUI::Widget* sender, int count);
void takeItem(MyGUI::Widget* sender, int count);
void dropItem(); void dropItem();
void onCloseButtonClicked(MyGUI::Widget* _sender); void onCloseButtonClicked(MyGUI::Widget* _sender);
void onTakeAllButtonClicked(MyGUI::Widget* _sender); void onTakeAllButtonClicked(MyGUI::Widget* _sender);
@ -64,6 +65,10 @@ namespace MWGui
bool onTakeItem(const ItemStack& item, int count); bool onTakeItem(const ItemStack& item, int count);
void onReferenceUnavailable() override; void onReferenceUnavailable() override;
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
bool onControllerThumbstickEvent(const SDL_ControllerAxisEvent& arg) override;
bool mUsingGamepadGuiCursor = false;
}; };
} }
#endif // CONTAINER_H #endif // CONTAINER_H

View file

@ -7,6 +7,8 @@
#include <MyGUI_ImageBox.h> #include <MyGUI_ImageBox.h>
#include <MyGUI_ScrollView.h> #include <MyGUI_ScrollView.h>
#include <components/settings/values.hpp>
#include "itemmodel.hpp" #include "itemmodel.hpp"
#include "itemwidget.hpp" #include "itemwidget.hpp"
@ -46,13 +48,14 @@ namespace MWGui
MyGUI::Widget* dragArea = mScrollView->getChildAt(0); MyGUI::Widget* dragArea = mScrollView->getChildAt(0);
int maxHeight = mScrollView->getHeight(); int maxHeight = mScrollView->getHeight();
int rows = maxHeight / 42; mRows = maxHeight / 42;
rows = std::max(rows, 1); mRows = std::max(mRows, 1);
bool showScrollbar = int(std::ceil(dragArea->getChildCount() / float(rows))) > mScrollView->getWidth() / 42; mItemCount = dragArea->getChildCount();
bool showScrollbar = int(std::ceil(mItemCount / float(mRows))) > mScrollView->getWidth() / 42;
if (showScrollbar) if (showScrollbar)
maxHeight -= 18; maxHeight -= 18;
for (unsigned int i = 0; i < dragArea->getChildCount(); ++i) for (unsigned int i = 0; i < mItemCount; ++i)
{ {
MyGUI::Widget* w = dragArea->getChildAt(i); MyGUI::Widget* w = dragArea->getChildAt(i);
@ -60,7 +63,7 @@ namespace MWGui
y += 42; y += 42;
if (y > maxHeight - 42 && i < dragArea->getChildCount() - 1) if (y > maxHeight - 42 && i < mItemCount - 1)
{ {
x += 42; x += 42;
y = 0; y = 0;
@ -70,6 +73,13 @@ namespace MWGui
MyGUI::IntSize size = MyGUI::IntSize(std::max(mScrollView->getSize().width, x), mScrollView->getSize().height); MyGUI::IntSize size = MyGUI::IntSize(std::max(mScrollView->getSize().width, x), mScrollView->getSize().height);
if (Settings::gui().mControllerMenus)
{
if (mControllerFocus >= mItemCount)
mControllerFocus = mItemCount - 1;
updateControllerFocus(-1, mControllerFocus);
}
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the
// scrollbar is hidden // scrollbar is hidden
mScrollView->setVisibleVScroll(false); mScrollView->setVisibleVScroll(false);
@ -122,6 +132,11 @@ namespace MWGui
void ItemView::resetScrollBars() void ItemView::resetScrollBars()
{ {
mScrollView->setViewOffset(MyGUI::IntPoint(0, 0)); mScrollView->setViewOffset(MyGUI::IntPoint(0, 0));
if (Settings::gui().mControllerMenus)
{
updateControllerFocus(mControllerFocus, 0);
mControllerFocus = 0;
}
} }
void ItemView::onSelectedItem(MyGUI::Widget* sender) void ItemView::onSelectedItem(MyGUI::Widget* sender)
@ -165,4 +180,50 @@ namespace MWGui
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::ItemView>("Widget"); MyGUI::FactoryManager::getInstance().registerFactory<MWGui::ItemView>("Widget");
} }
void ItemView::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)
{
if (!mItemCount)
return;
int prevFocus = mControllerFocus;
if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP && mControllerFocus % mRows != 0)
mControllerFocus--;
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN && mControllerFocus % mRows != mRows - 1)
mControllerFocus++;
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT && mControllerFocus >= mRows)
mControllerFocus -= mRows;
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT && mControllerFocus + mRows < mItemCount)
mControllerFocus += mRows;
if (mControllerFocus < 0)
mControllerFocus = 0;
else if (mControllerFocus >= mItemCount - 1)
mControllerFocus = mItemCount - 1;
if (prevFocus != mControllerFocus)
updateControllerFocus(prevFocus, mControllerFocus);
}
void ItemView::updateControllerFocus(int _prevFocus, int _newFocus)
{
if (!mItemCount)
return;
MyGUI::Widget* dragArea = mScrollView->getChildAt(0);
if (_prevFocus >= 0 && _prevFocus < mItemCount)
{
ItemWidget* prev = (ItemWidget *)dragArea->getChildAt(_prevFocus);
if (prev)
prev->setControllerFocus(false);
}
if (_newFocus >= 0 && _newFocus < mItemCount)
{
ItemWidget* focused = (ItemWidget *)dragArea->getChildAt(_newFocus);
if (focused)
focused->setControllerFocus(true);
}
}
} }

View file

@ -2,6 +2,7 @@
#define MWGUI_ITEMVIEW_H #define MWGUI_ITEMVIEW_H
#include <MyGUI_Widget.h> #include <MyGUI_Widget.h>
#include <SDL.h>
#include "itemmodel.hpp" #include "itemmodel.hpp"
@ -31,6 +32,10 @@ namespace MWGui
void resetScrollBars(); void resetScrollBars();
int getControllerFocus() { return mControllerFocus; }
int getItemCount() { return mItemCount; }
void onControllerButtonEvent(const SDL_ControllerButtonEvent& arg);
private: private:
void initialiseOverride() override; void initialiseOverride() override;
@ -45,6 +50,11 @@ namespace MWGui
std::unique_ptr<ItemModel> mModel; std::unique_ptr<ItemModel> mModel;
MyGUI::ScrollView* mScrollView; MyGUI::ScrollView* mScrollView;
int mItemCount = 0;
int mRows;
int mControllerFocus = 0;
void updateControllerFocus(int prevFocus, int newFocus);
}; };
} }

View file

@ -58,6 +58,7 @@ namespace MWGui
: mItem(nullptr) : mItem(nullptr)
, mItemShadow(nullptr) , mItemShadow(nullptr)
, mFrame(nullptr) , mFrame(nullptr)
, mControllerBorder(nullptr)
, mText(nullptr) , mText(nullptr)
{ {
} }
@ -82,10 +83,22 @@ namespace MWGui
assignWidget(mText, "Text"); assignWidget(mText, "Text");
if (mText) if (mText)
mText->setNeedMouseFocus(false); mText->setNeedMouseFocus(false);
if (Settings::gui().mControllerMenus)
{
assignWidget(mControllerBorder, "ControllerBorder");
if (mControllerBorder)
mControllerBorder->setNeedMouseFocus(false);
}
Base::initialiseOverride(); Base::initialiseOverride();
} }
void ItemWidget::setControllerFocus(bool focus)
{
if (mControllerBorder)
mControllerBorder->setVisible(focus);
}
void ItemWidget::setCount(int count) void ItemWidget::setCount(int count)
{ {
if (!mText) if (!mText)

View file

@ -40,12 +40,15 @@ namespace MWGui
void setIcon(const MWWorld::Ptr& ptr); void setIcon(const MWWorld::Ptr& ptr);
void setFrame(const std::string& frame, const MyGUI::IntCoord& coord); void setFrame(const std::string& frame, const MyGUI::IntCoord& coord);
void setControllerFocus(bool focus);
protected: protected:
void initialiseOverride() override; void initialiseOverride() override;
MyGUI::ImageBox* mItem; MyGUI::ImageBox* mItem;
MyGUI::ImageBox* mItemShadow; MyGUI::ImageBox* mItemShadow;
MyGUI::ImageBox* mFrame; MyGUI::ImageBox* mFrame;
MyGUI::ImageBox* mControllerBorder;
MyGUI::TextBox* mText; MyGUI::TextBox* mText;
std::string mCurrentIcon; std::string mCurrentIcon;

View file

@ -9,6 +9,7 @@ set(BUILTIN_DATA_FILES
textures/omw_menu_scroll_right.dds textures/omw_menu_scroll_right.dds
textures/omw_menu_scroll_center_h.dds textures/omw_menu_scroll_center_h.dds
textures/omw_menu_scroll_center_v.dds textures/omw_menu_scroll_center_v.dds
textures/omw_menu_icon_active.dds
textures/omw/water_nm.png textures/omw/water_nm.png
fonts/DejaVuFontLicense.txt fonts/DejaVuFontLicense.txt

View file

@ -144,6 +144,10 @@
<Property key="Alpha" value="0.5"/> <Property key="Alpha" value="0.5"/>
</Widget> </Widget>
</Widget> </Widget>
<Widget type="ImageBox" skin="ImageBox" position="0 0 42 42" align="Stretch" name="ControllerBorder">
<Property key="ImageTexture" value="textures\omw_menu_icon_active.dds"/>
<Property key="Visible" value="false"/>
</Widget>
</Widget> </Widget>
</Resource> </Resource>

Binary file not shown.