Skip to content

Commit

Permalink
Ability to scroll in scroll views with gamepad (#943)
Browse files Browse the repository at this point in the history
  • Loading branch information
Xottab-DUTY committed Jan 10, 2025
1 parent 002ab6a commit 5c14bfe
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 3 deletions.
26 changes: 24 additions & 2 deletions src/xrUICore/ListWnd/UIListWnd.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include"pch.hpp"
#include "UIListWnd.h"
//.#include "uiscrollbar.h"
#include "Cursor/UICursor.h"
#include "Windows/UIFrameLineWnd.h"

//#define ACTIVE_BACKGROUND "ui\\ui_pop_up_active_back"
Expand Down Expand Up @@ -544,11 +545,11 @@ void CUIListWnd::ScrollToEnd()
UpdateList();
}

void CUIListWnd::ScrollToPos(int position)
void CUIListWnd::ScrollToPos(int position, float center_y_ratio /*= 0.5f*/)
{
if (IsScrollBarEnabled())
{
int pos = position;
int pos = position - iFloor(float(m_iRowNum) * center_y_ratio);
clamp(pos, m_ScrollBar->GetMinRange(), (m_ScrollBar->GetMaxRange() - m_ScrollBar->GetPageSize() / + 1));
m_ScrollBar->SetScrollPos(pos);
m_iFirstShownIndex = m_ScrollBar->GetScrollPos();
Expand All @@ -564,6 +565,27 @@ void CUIListWnd::Update()
m_bUpdateMouseMove = false;
}

if (const auto focused = CursorOverWindow() ? UI().Focus().GetFocused() : nullptr)
{
const auto parentItem = focused->GetWindowBeforeParent(this);

const auto listItem = dynamic_cast<CUIListItem*>(parentItem);
const auto currentSelectedItem = GetItem(GetSelectedItem());

if (listItem && listItem != currentSelectedItem)
{
const auto prevPos = m_iFirstShownIndex;

ScrollToPos(GetItemPos(listItem));

if (prevPos != m_iFirstShownIndex)
{
SendMessage(listItem, BUTTON_CLICKED, nullptr);
UI().GetUICursor().WarpToWindow(focused);
}
}
}

inherited::Update();
if (m_ActiveBackgroundFrame)
m_ActiveBackgroundFrame->Update();
Expand Down
2 changes: 1 addition & 1 deletion src/xrUICore/ListWnd/UIListWnd.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class XRUICORE_API CUIListWnd final : public CUIWindow

void ScrollToBegin();
void ScrollToEnd();
void ScrollToPos(int position);
void ScrollToPos(int position, float center_y_ratio = 0.5f);

IC bool IsActiveBackgroundEnabled() { return m_bActiveBackground; }
void EnableActiveBackground(bool enable);
Expand Down
4 changes: 4 additions & 0 deletions src/xrUICore/ListWnd/UIListWnd_script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ SCRIPT_EXPORT(CUIListWnd, (CUIWindow),
.def("GetSize", &CUIListWnd::GetItemsCount)
.def("ScrollToBegin", &CUIListWnd::ScrollToBegin)
.def("ScrollToEnd", &CUIListWnd::ScrollToEnd)
.def("ScrollToPos", +[](CUIListWnd* self, int position)
{
self->ScrollToPos(position, 0.0f);
})
.def("ScrollToPos", &CUIListWnd::ScrollToPos)
.def("SetWidth", &CUIListWnd::SetWidth)
.def("SetTextColor", &CUIListWnd::SetTextColor)
Expand Down
31 changes: 31 additions & 0 deletions src/xrUICore/ScrollView/UIScrollView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,24 @@ void CUIScrollView::Update()
if (m_flags.test(eNeedRecalc))
RecalcSize();

if (const auto focused = CursorOverWindow() ? UI().Focus().GetFocused() : nullptr)
{
const auto scrollItem = focused->GetWindowBeforeParent(m_pad);

if (scrollItem && GetSelected() != scrollItem)
{
const auto prevPos = GetCurrentScrollPos();

ScrollToWindow(scrollItem);

if (m_flags.test(eItemsSelectabe))
scrollItem->OnMouseDown(MOUSE_1);

if (prevPos != GetCurrentScrollPos())
UI().GetUICursor().WarpToWindow(focused);
}
}

inherited::Update();
}

Expand Down Expand Up @@ -320,6 +338,19 @@ void CUIScrollView::ScrollToEnd()
OnScrollV(nullptr, nullptr);
}

void CUIScrollView::ScrollToWindow(CUIWindow* pWnd, float center_y_ratio /*= 0.5f*/)
{
R_ASSERT2_CURE(pWnd->GetParent() == m_pad, "Requested window to scroll to doesn't belong to the scroll view", return);

if (m_flags.test(eNeedRecalc))
RecalcSize();

const float ratio = GetHeight() * center_y_ratio;
const int pos = iFloor(m_upIndent + pWnd->GetWndPos().y - ratio);

SetScrollPos(pos);
}

void CUIScrollView::SetRightIndention(float val)
{
m_rightIndent = val;
Expand Down
1 change: 1 addition & 0 deletions src/xrUICore/ScrollView/UIScrollView.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class XRUICORE_API CUIScrollView : public CUIWindow, public CUIWndCallback
void Clear();
void ScrollToBegin();
void ScrollToEnd();
void ScrollToWindow(CUIWindow* pWnd, float center_y_ratio = 0.5f);
bool GetVertFlip() const { return !!m_flags.test(eVertFlip); }
bool Empty() const { return m_pad->GetChildWndList().empty(); }

Expand Down
13 changes: 13 additions & 0 deletions src/xrUICore/Windows/UIWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,19 @@ class XRUICORE_API CUIWindow : public CUISimpleWindow, public CUIDebuggable
CUIWindow* GetParent() const { return m_pParentWnd; }
void SetParent(CUIWindow* pNewParent);

[[nodiscard]]
CUIWindow* GetWindowBeforeParent(const CUIWindow* parent)
{
CUIWindow* result = this;
for (CUIWindow* it = GetParent(); it; it = it->GetParent())
{
if (it == parent)
return result;
result = it;
}
return nullptr;
}

//получить окно самого верхнего уровня
[[nodiscard]]
CUIWindow* GetTop()
Expand Down

0 comments on commit 5c14bfe

Please sign in to comment.