1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-12-08 01:34:34 +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_InputManager.h>
#include <components/settings/values.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/scriptmanager.hpp"
@ -88,8 +90,13 @@ namespace MWGui
name += MWGui::ToolTips::getSoulString(object.getCellRef());
dialog->openCountDialog(name, "#{sTake}", count);
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
dragItem(nullptr, count);
}
@ -105,6 +112,30 @@ namespace MWGui
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()
{
if (!mModel)
@ -320,4 +351,51 @@ namespace MWGui
if (mModel && mModel->usesContainer(ptr))
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 onBackgroundSelected();
void dragItem(MyGUI::Widget* sender, int count);
void takeItem(MyGUI::Widget* sender, int count);
void dropItem();
void onCloseButtonClicked(MyGUI::Widget* _sender);
void onTakeAllButtonClicked(MyGUI::Widget* _sender);
@ -64,6 +65,10 @@ namespace MWGui
bool onTakeItem(const ItemStack& item, int count);
void onReferenceUnavailable() override;
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
bool onControllerThumbstickEvent(const SDL_ControllerAxisEvent& arg) override;
bool mUsingGamepadGuiCursor = false;
};
}
#endif // CONTAINER_H

View file

@ -7,6 +7,8 @@
#include <MyGUI_ImageBox.h>
#include <MyGUI_ScrollView.h>
#include <components/settings/values.hpp>
#include "itemmodel.hpp"
#include "itemwidget.hpp"
@ -46,13 +48,14 @@ namespace MWGui
MyGUI::Widget* dragArea = mScrollView->getChildAt(0);
int maxHeight = mScrollView->getHeight();
int rows = maxHeight / 42;
rows = std::max(rows, 1);
bool showScrollbar = int(std::ceil(dragArea->getChildCount() / float(rows))) > mScrollView->getWidth() / 42;
mRows = maxHeight / 42;
mRows = std::max(mRows, 1);
mItemCount = dragArea->getChildCount();
bool showScrollbar = int(std::ceil(mItemCount / float(mRows))) > mScrollView->getWidth() / 42;
if (showScrollbar)
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);
@ -60,7 +63,7 @@ namespace MWGui
y += 42;
if (y > maxHeight - 42 && i < dragArea->getChildCount() - 1)
if (y > maxHeight - 42 && i < mItemCount - 1)
{
x += 42;
y = 0;
@ -70,6 +73,13 @@ namespace MWGui
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
// scrollbar is hidden
mScrollView->setVisibleVScroll(false);
@ -122,6 +132,11 @@ namespace MWGui
void ItemView::resetScrollBars()
{
mScrollView->setViewOffset(MyGUI::IntPoint(0, 0));
if (Settings::gui().mControllerMenus)
{
updateControllerFocus(mControllerFocus, 0);
mControllerFocus = 0;
}
}
void ItemView::onSelectedItem(MyGUI::Widget* sender)
@ -165,4 +180,50 @@ namespace MWGui
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
#include <MyGUI_Widget.h>
#include <SDL.h>
#include "itemmodel.hpp"
@ -31,6 +32,10 @@ namespace MWGui
void resetScrollBars();
int getControllerFocus() { return mControllerFocus; }
int getItemCount() { return mItemCount; }
void onControllerButtonEvent(const SDL_ControllerButtonEvent& arg);
private:
void initialiseOverride() override;
@ -45,6 +50,11 @@ namespace MWGui
std::unique_ptr<ItemModel> mModel;
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)
, mItemShadow(nullptr)
, mFrame(nullptr)
, mControllerBorder(nullptr)
, mText(nullptr)
{
}
@ -82,10 +83,22 @@ namespace MWGui
assignWidget(mText, "Text");
if (mText)
mText->setNeedMouseFocus(false);
if (Settings::gui().mControllerMenus)
{
assignWidget(mControllerBorder, "ControllerBorder");
if (mControllerBorder)
mControllerBorder->setNeedMouseFocus(false);
}
Base::initialiseOverride();
}
void ItemWidget::setControllerFocus(bool focus)
{
if (mControllerBorder)
mControllerBorder->setVisible(focus);
}
void ItemWidget::setCount(int count)
{
if (!mText)

View file

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

View file

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

View file

@ -144,6 +144,10 @@
<Property key="Alpha" value="0.5"/>
</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>
</Resource>

Binary file not shown.