Skip to content

Commit

Permalink
Support full gamepad interaction in talk window (#943)
Browse files Browse the repository at this point in the history
  • Loading branch information
Xottab-DUTY committed Jan 11, 2025
1 parent 4416a19 commit ff8e092
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/xrEngine/xr_level_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1036,7 +1036,7 @@ class CCC_DefControls : public CCC_UnBindAll

// Talk:
{ kTALK_SWITCH_TO_TRADE, { SDL_SCANCODE_X, SDL_SCANCODE_UNKNOWN, XR_CONTROLLER_BUTTON_X } },
{ kTALK_LOG_SCROLL, { SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, XR_CONTROLLER_AXIS_RIGHT } },
{ kTALK_LOG_SCROLL, { SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, XR_CONTROLLER_AXIS_LEFT } },
{ kTALK_LOG_SCROLL_UP, { SDL_SCANCODE_E, SDL_SCANCODE_PAGEUP, XR_CONTROLLER_AXIS_TRIGGER_LEFT } },
{ kTALK_LOG_SCROLL_DOWN, { SDL_SCANCODE_Q, SDL_SCANCODE_PAGEDOWN, XR_CONTROLLER_AXIS_TRIGGER_RIGHT } },

Expand Down
83 changes: 83 additions & 0 deletions src/xrGame/ui/UITalkDialogWnd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,89 @@ void CUITalkDialogWnd::TryScrollAnswersList(bool down)
UIAnswersList->ScrollBar()->TryScrollInc();
}

void CUITalkDialogWnd::FocusOnNextQuestion(bool next, bool loop) const
{
auto& focus = UI().Focus();

const auto focused = focus.GetFocused();

if (auto questionItem = focused ? dynamic_cast<CUIQuestionItem*>(focused->GetParent()) : nullptr)
{
const Fvector2 vec = focused->GetAbsoluteCenterPos();
const auto direction = next ? FocusDirection::Down : FocusDirection::Up;
const auto [target, direct] = focus.FindClosestFocusable(vec, direction);

questionItem = target ? dynamic_cast<CUIQuestionItem*>(target->GetParent()) : nullptr;

if (questionItem)
{
focus.SetFocused(target);
GetUICursor().WarpToWindow(target);
}
else if (loop)
{
if (next)
FocusOnFirstQuestion();
else
FocusOnLastQuestion();
}
return;
}

// Failed to find something, let's try first
FocusOnFirstQuestion();
}

void CUITalkDialogWnd::FocusOnFirstQuestion() const
{
const auto questions = UIQuestionsList->Items();
if (questions.empty())
return;

const auto questionItem = dynamic_cast<CUIQuestionItem*>(questions.front());
if (!questionItem)
return;

UI().Focus().SetFocused(questionItem->m_text);
UI().GetUICursor().WarpToWindow(questionItem->m_text);
}

void CUITalkDialogWnd::FocusOnLastQuestion() const
{
const auto questions = UIQuestionsList->Items();
if (questions.empty())
return;

const auto questionItem = dynamic_cast<CUIQuestionItem*>(questions.back());
if (!questionItem)
return;

UI().Focus().SetFocused(questionItem->m_text);
UI().GetUICursor().WarpToWindow(questionItem->m_text);
}

bool CUITalkDialogWnd::OnKeyboardAction(int dik, EUIMessages keyboard_action)
{
if (CUIWindow::OnKeyboardAction(dik, keyboard_action))
return true;

if (keyboard_action == WINDOW_KEY_PRESSED)
{
const auto focused = UIQuestionsList->CursorOverWindow() ? UI().Focus().GetFocused() : nullptr;

if (focused && IsBinded(kUI_ACCEPT, dik, EKeyContext::UI))
{
if (const auto questionItem = dynamic_cast<CUIQuestionItem*>(focused->GetParent()))
{
questionItem->OnTextClicked(nullptr, nullptr);
return true;
}
}
}

return false;
}

void CUIQuestionItem::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) { CUIWndCallback::OnEvent(pWnd, msg, pData); }
CUIQuestionItem::CUIQuestionItem(CUIXml* xml_doc, LPCSTR path)
: CUIWindow("CUIQuestionItem")
Expand Down
5 changes: 5 additions & 0 deletions src/xrGame/ui/UITalkDialogWnd.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ class CUITalkDialogWnd final : public CUIWindow, public CUIWndCallback
void UpdateButtonsLayout(bool b_disable_break, bool trade_enabled);

void TryScrollAnswersList(bool down);
void FocusOnNextQuestion(bool next, bool loop) const;
void FocusOnFirstQuestion() const;
void FocusOnLastQuestion() const;

bool OnKeyboardAction(int dik, EUIMessages keyboard_action) override;

private:
// List of questions we can ask the character
Expand Down
58 changes: 50 additions & 8 deletions src/xrGame/ui/UITalkWnd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ void CUITalkWnd::UpdateQuestions()
UpdateQuestions();
}
}

UITalkDialogWnd->FocusOnFirstQuestion();

m_bNeedToUpdateQuestions = false;
}

Expand Down Expand Up @@ -355,9 +358,8 @@ bool CUITalkWnd::OnKeyboardAction(int dik, EUIMessages keyboard_action)
return true;
}
}
switch (GetBindedAction(dik, EKeyContext::Talk))
else if (IsBinded(kTALK_SWITCH_TO_TRADE, dik, EKeyContext::Talk))
{
case kTALK_SWITCH_TO_TRADE:
if (!m_pOthersInvOwner->NeedOsoznanieMode())
{
if (UITalkDialogWnd->mechanic_mode)
Expand All @@ -366,7 +368,6 @@ bool CUITalkWnd::OnKeyboardAction(int dik, EUIMessages keyboard_action)
SwitchToTrade();
return true;
}
break;
}
}
else if (keyboard_action == WINDOW_KEY_HOLD)
Expand All @@ -375,27 +376,68 @@ bool CUITalkWnd::OnKeyboardAction(int dik, EUIMessages keyboard_action)
{
case kTALK_LOG_SCROLL_UP:
UITalkDialogWnd->TryScrollAnswersList(false);
break;
return true;
case kTALK_LOG_SCROLL_DOWN:
UITalkDialogWnd->TryScrollAnswersList(true);
break;
return true;
}
}

if (keyboard_action == WINDOW_KEY_PRESSED || keyboard_action == WINDOW_KEY_HOLD)
{
switch (GetBindedAction(dik, EKeyContext::UI))
{
case kUI_MOVE_LEFT:
case kUI_MOVE_RIGHT:
// Suppress focus system activation
return true;

case kUI_MOVE_UP:
UITalkDialogWnd->FocusOnNextQuestion(false, keyboard_action != WINDOW_KEY_HOLD);
return true;

case kUI_MOVE_DOWN:
UITalkDialogWnd->FocusOnNextQuestion(true, keyboard_action != WINDOW_KEY_HOLD);
return true;
} // switch (GetBindedAction(dik, EKeyContext::UI))
}

return inherited::OnKeyboardAction(dik, keyboard_action);
}

bool CUITalkWnd::OnControllerAction(int axis, float x, float y, EUIMessages controller_action)
{
if (controller_action == WINDOW_KEY_PRESSED)
if (controller_action == WINDOW_KEY_HOLD)
{
switch (GetBindedAction(axis, EKeyContext::Talk))
{
default:
return OnKeyboardAction(axis, controller_action);
case kTALK_LOG_SCROLL:
if (y > 0)
UITalkDialogWnd->TryScrollAnswersList(false);
else
UITalkDialogWnd->TryScrollAnswersList(true);
return true;
}
}

if (controller_action == WINDOW_KEY_PRESSED || controller_action == WINDOW_KEY_HOLD)
{
switch (GetBindedAction(axis, EKeyContext::UI))
{
case kUI_MOVE_LEFT:
case kUI_MOVE_RIGHT:
// Suppress focus system activation
return true;

case kUI_MOVE:
if (y > 0)
UITalkDialogWnd->FocusOnNextQuestion(true, controller_action != WINDOW_KEY_HOLD);
else
UITalkDialogWnd->FocusOnNextQuestion(false, controller_action != WINDOW_KEY_HOLD);
return true;
} // switch (GetBindedAction(axis, EKeyContext::UI))
}

return inherited::OnControllerAction(axis, x, y, controller_action);
}

Expand Down

0 comments on commit ff8e092

Please sign in to comment.