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:
parent
77e17743f7
commit
f055ccf5ba
9 changed files with 181 additions and 6 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
BIN
files/data/textures/omw_menu_icon_active.dds
Normal file
BIN
files/data/textures/omw_menu_icon_active.dds
Normal file
Binary file not shown.
Loading…
Reference in a new issue