From dbc8a5c1c0feb663c8a1bf61e3d5132c3f4a5104 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 18 Jan 2025 05:46:33 +0300 Subject: [PATCH] Proper gamepad interaction in PDA (#943) This is huge. Mainly for the map page, ranking and log pages can be missing something. --- .../key_binding_registrator_script.cpp | 1 - src/xrEngine/xr_level_controller.cpp | 2 - src/xrEngine/xr_level_controller.h | 1 - src/xrGame/ui/UIMapFilters.cpp | 208 ++++++++++-------- src/xrGame/ui/UIMapFilters.h | 18 +- src/xrGame/ui/UIPdaWnd.cpp | 20 +- src/xrGame/ui/UIPdaWnd.h | 1 + src/xrGame/ui/UISecondTaskWnd.cpp | 82 ++++++- src/xrGame/ui/UISecondTaskWnd.h | 5 +- src/xrGame/ui/UITaskWnd.cpp | 86 +++++--- src/xrGame/ui/UITaskWnd.h | 24 +- src/xrUICore/UIMessages.h | 1 - 12 files changed, 278 insertions(+), 171 deletions(-) diff --git a/src/xrEngine/key_binding_registrator_script.cpp b/src/xrEngine/key_binding_registrator_script.cpp index 0e1096eddb8..88910861f13 100644 --- a/src/xrEngine/key_binding_registrator_script.cpp +++ b/src/xrEngine/key_binding_registrator_script.cpp @@ -204,7 +204,6 @@ SCRIPT_EXPORT(KeyBindings, (), value("kPDA_MAP_SHOW_LEGEND", int(kPDA_MAP_SHOW_LEGEND)), value("kPDA_FILTER_TOGGLE", int(kPDA_FILTER_TOGGLE)), - value("kPDA_TASKS_TOGGLE", int(kPDA_TASKS_TOGGLE)), // Talk: value("kTALK_SWITCH_TO_TRADE", int(kTALK_SWITCH_TO_TRADE)), diff --git a/src/xrEngine/xr_level_controller.cpp b/src/xrEngine/xr_level_controller.cpp index 443afbe9622..0fde881a535 100644 --- a/src/xrEngine/xr_level_controller.cpp +++ b/src/xrEngine/xr_level_controller.cpp @@ -201,7 +201,6 @@ game_action actions[] = { "pda_map_show_legend", kPDA_MAP_SHOW_LEGEND, _sp, EKeyContext::PDA }, { "pda_filter_toggle", kPDA_FILTER_TOGGLE, _sp, EKeyContext::PDA }, - { "pda_tasks_toggle", kPDA_TASKS_TOGGLE, _sp, EKeyContext::PDA }, // Talk: { "talk_switch_to_trade", kTALK_SWITCH_TO_TRADE, _sp, EKeyContext::Talk }, @@ -1038,7 +1037,6 @@ class CCC_DefControls : public CCC_UnBindAll { kPDA_MAP_SHOW_LEGEND, { SDL_SCANCODE_V, SDL_SCANCODE_KP_MULTIPLY, XR_CONTROLLER_BUTTON_INVALID } }, { kPDA_FILTER_TOGGLE, { SDL_SCANCODE_B, SDL_SCANCODE_UNKNOWN, XR_CONTROLLER_BUTTON_Y } }, - { kPDA_TASKS_TOGGLE, { SDL_SCANCODE_TAB, SDL_SCANCODE_UNKNOWN, XR_CONTROLLER_BUTTON_X } }, // Talk: { kTALK_SWITCH_TO_TRADE, { SDL_SCANCODE_X, SDL_SCANCODE_UNKNOWN, XR_CONTROLLER_BUTTON_X } }, diff --git a/src/xrEngine/xr_level_controller.h b/src/xrEngine/xr_level_controller.h index ac25eb63b77..ca04bc06236 100644 --- a/src/xrEngine/xr_level_controller.h +++ b/src/xrEngine/xr_level_controller.h @@ -182,7 +182,6 @@ enum EGameActions : u32 kPDA_MAP_SHOW_LEGEND, kPDA_FILTER_TOGGLE, - kPDA_TASKS_TOGGLE, // Talk: kTALK_SWITCH_TO_TRADE, // _OR_UPGRADE diff --git a/src/xrGame/ui/UIMapFilters.cpp b/src/xrGame/ui/UIMapFilters.cpp index 77c68f11b14..d37d4880249 100644 --- a/src/xrGame/ui/UIMapFilters.cpp +++ b/src/xrGame/ui/UIMapFilters.cpp @@ -8,14 +8,10 @@ CUIMapFilters::CUIMapFilters() : CUIWindow("Map locations filters") {} bool CUIMapFilters::Init(CUIXml& xml) { - if (!CUIXmlInit::InitWindow(xml, "filters_wnd", 0, this, false)) - { - if (const auto parent = GetParent()) - { - SetWndPos(parent->GetWndPos()); - SetWndSize(parent->GetWndSize()); - } - } + bool result = false; + + const bool convertPosToOurs = !CUIXmlInit::InitWindow(xml, "filters_wnd", 0, this, false); + constexpr std::tuple filters[] = { { Treasures, "filter_treasures" }, @@ -28,94 +24,144 @@ bool CUIMapFilters::Init(CUIXml& xml) { auto& filter = m_filters[filter_id]; filter = UIHelper::CreateCheck(xml, filter_section, this, false); - if (filter) + if (!filter) + continue; + + filter->SetMessageTarget(this); + filter->SetWindowName(filter_section); + filter->SetCheck(true); + + result = true; + } + + if (result && convertPosToOurs) + { + // Adjust this window rect first + Frect rect{ type_max, type_max, 0, 0 }; + + for (const auto filter : m_filters) { - filter->SetMessageTarget(this); - filter->SetWindowName(filter_section); - filter->SetCheck(true); + if (!filter) + continue; + rect.lt.min(filter->GetWndPos()); + Frect filterRect; + filter->GetWndRect(filterRect); + rect.rb.max(filterRect.rb); + } + + SetWndRect(rect); + + // Adjust filters positions + for (const auto filter : m_filters) + { + if (!filter) + continue; + Fvector2 ourAbsPos; + GetAbsolutePos(ourAbsPos); + const Fvector2& pos = filter->GetWndPos(); + filter->SetWndPos({ pos.x - ourAbsPos.x, pos.y - ourAbsPos.y }); } - m_filters_state[filter_id] = true; } - return true; + return result; } void CUIMapFilters::Reset() { inherited::Reset(); - SelectFilter(false); + Activate(false); } -bool CUIMapFilters::OnKeyboardAction(int dik, EUIMessages keyboard_action) +bool CUIMapFilters::Activate(bool activate) { - if (const auto filter = GetSelectedFilter()) + m_activated = activate; + + auto& focus = UI().Focus(); + if (activate) { - if (keyboard_action != WINDOW_KEY_PRESSED) - return true; // intercept all + GetMessageTarget()->SetKeyboardCapture(this, true); + focus.LockToWindow(this); + focus.SetFocused(m_filters[0]); + } + else + { + if (GetMessageTarget()->GetKeyboardCapturer() == this) + GetMessageTarget()->SetKeyboardCapture(nullptr, true); + if (focus.GetLocker() == this) + focus.Unlock(); + GetMessageTarget()->SendMessage(GetMessageTarget(), WINDOW_KEYBOARD_CAPTURE_LOST, this); + } + return true; +} - switch (GetBindedAction(dik, EKeyContext::UI)) +bool CUIMapFilters::OnKeyboardAction(int dik, EUIMessages keyboard_action) +{ + if (!m_activated) + { + if (IsBinded(kPDA_FILTER_TOGGLE, dik, EKeyContext::PDA)) { - case kUI_BACK: - SelectFilter(false); + Activate(true); return true; + } + return false; + } - case kUI_ACCEPT: - filter->OnMouseDown(MOUSE_1); - return true; + if (inherited::OnKeyboardAction(dik, keyboard_action)) + return true; - case kUI_MOVE_LEFT: - case kUI_MOVE_DOWN: - SelectFilter(true, false); - return true; + auto action = GetBindedAction(dik, EKeyContext::UI); + if (action == kNOTBINDED) + action = GetBindedAction(dik); - case kUI_MOVE_RIGHT: - case kUI_MOVE_UP: - SelectFilter(true, true); - return true; + switch (action) + { + case kQUIT: + case kUI_BACK: + Activate(false); + return true; + + case kENTER: + case kUI_ACCEPT: + if (keyboard_action == WINDOW_KEY_PRESSED) + { + if (const auto filter = GetSelectedFilter()) + filter->OnMouseDown(MOUSE_1); } - } - return inherited::OnKeyboardAction(dik, keyboard_action); -} + return true; -bool CUIMapFilters::OnControllerAction(int axis, float x, float y, EUIMessages controller_action) -{ - switch (GetBindedAction(axis, EKeyContext::UI)) - { - default: - return OnKeyboardAction(axis, controller_action); - case kUI_MOVE: - if (GetSelectedFilter()) - return true; // just screw it for now + case kUI_ACTION_1: + case kUI_ACTION_2: + return true; // intercept } - return inherited::OnControllerAction(axis, x, y, controller_action); + + return false; } void CUIMapFilters::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) { - // This cycle could be implemented through CUIWndCallback, - // but we don't need it too much here - for (u32 i = 0; i < Filter_Count; ++i) + if (msg == BUTTON_CLICKED) { - if (m_filters[i] == pWnd && msg == BUTTON_CLICKED) + // This cycle could be implemented through CUIWndCallback, + // but we don't need it too much here + for (const auto filter : m_filters) { - m_filters_state[i] = m_filters[i]->GetCheck(); - GetMessageTarget()->SendMessage(this, PDA_TASK_RELOAD_FILTERS, nullptr); - return; + if (filter == pWnd) + { + GetMessageTarget()->SendMessage(this, PDA_TASK_RELOAD_FILTERS, nullptr); + return; + } } } - if (msg == PDA_TASK_SELECT_FILTERS) + else if (msg == WINDOW_KEYBOARD_CAPTURE_LOST && pWnd == GetMessageTarget()) { - SelectFilter(!GetSelectedFilter()); + if (m_activated) + Activate(false); return; } - if (msg == WINDOW_KEYBOARD_CAPTURE_LOST && pWnd == GetMessageTarget()) + else if (msg == WINDOW_FOCUS_LOST && pWnd == this) { - SelectFilter(false); - return; - } - if (msg == WINDOW_FOCUS_LOST && pWnd == this) - { - SelectFilter(false); + if (m_activated) + Activate(false); return; } inherited::SendMessage(pWnd, msg, pData); @@ -123,43 +169,19 @@ void CUIMapFilters::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) CUICheckButton* CUIMapFilters::GetSelectedFilter() const { - if (m_selected_filter == -1) - return nullptr; - return m_filters[m_selected_filter]; + auto focused = UI().Focus().GetFocused(); + if (IsChild(focused)) + return static_cast(focused); + return nullptr; } -void CUIMapFilters::SelectFilter(bool select, bool next /*= true*/) +bool CUIMapFilters::IsFilterEnabled(eSpotsFilter filter) const { - auto& cursor = GetUICursor(); - - if (!select) - { - m_selected_filter = -1; - cursor.WarpToWindow(nullptr); - } - else - { - if (next) - { - if (m_selected_filter < int(m_filters.size() - 1)) - m_selected_filter++; - else - m_selected_filter = 0; - } - else // prev - { - if (m_selected_filter > 0) - m_selected_filter--; - else - m_selected_filter = int(m_filters.size() - 1); - } - cursor.WarpToWindow(m_filters[m_selected_filter]); - } + return m_filters[filter] && m_filters[filter]->GetCheck(); } -void CUIMapFilters::SetFilterEnabled(eSpotsFilter filter, bool enable) +void CUIMapFilters::SetFilterEnabled(eSpotsFilter filter, bool enable) const { - m_filters_state[filter] = enable; if (m_filters[filter]) m_filters[filter]->SetCheck(enable); } diff --git a/src/xrGame/ui/UIMapFilters.h b/src/xrGame/ui/UIMapFilters.h index abc1c215c67..0b2c917974e 100644 --- a/src/xrGame/ui/UIMapFilters.h +++ b/src/xrGame/ui/UIMapFilters.h @@ -21,33 +21,29 @@ class CUIMapFilters final : public CUIWindow private: std::array m_filters{}; - std::array m_filters_state{}; - int m_selected_filter{ -1 }; + bool m_activated{}; public: CUIMapFilters(); bool Init(CUIXml& xml); - pcstr GetDebugType() override { return "CUIMapFilters"; } - void Reset() override; + bool Activate(bool activate); + bool OnKeyboardAction(int dik, EUIMessages keyboard_action) override; - bool OnControllerAction(int axis, float x, float y, EUIMessages controller_action) override; void SendMessage(CUIWindow* pWnd, s16 msg, void* pData) override; [[nodiscard]] - bool IsFilterEnabled(eSpotsFilter filter) const - { - return m_filters_state[filter]; - } + bool IsFilterEnabled(eSpotsFilter filter) const; + + void SetFilterEnabled(eSpotsFilter filter, bool enable) const; - void SetFilterEnabled(eSpotsFilter filter, bool enable); + pcstr GetDebugType() override { return "CUIMapFilters"; } private: CUICheckButton* GetSelectedFilter() const; - void SelectFilter(bool select, bool next = true); }; diff --git a/src/xrGame/ui/UIPdaWnd.cpp b/src/xrGame/ui/UIPdaWnd.cpp index 8056e37cabf..9e9a1484237 100644 --- a/src/xrGame/ui/UIPdaWnd.cpp +++ b/src/xrGame/ui/UIPdaWnd.cpp @@ -92,6 +92,10 @@ void CUIPdaWnd::Init() } m_btn_close = UIHelper::Create3tButton(uiXml, "close_button", this); + m_btn_close->SetAccelerator(kQUIT, false, 2); + m_btn_close->SetAccelerator(kUI_BACK, false, 3); + UI().Focus().UnregisterFocusable(m_btn_close); + m_hint_wnd = UIHelper::CreateHint(uiXml, "hint_wnd"); if (IsGameTypeSingle()) @@ -175,8 +179,6 @@ void CUIPdaWnd::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) { const auto& id = UITabControl->GetActiveId(); SetActiveSubdialog(id); - if (pInput->IsCurrentInputTypeController()) - UI().GetUICursor().WarpToWindow(UITabControl->GetButtonById(id)); } break; } @@ -249,6 +251,7 @@ void CUIPdaWnd::SetActiveSubdialog(const shared_str& section) { if (UIMainPdaFrame->IsChild(m_pActiveDialog)) UIMainPdaFrame->DetachChild(m_pActiveDialog); + UIMainPdaFrame->SetKeyboardCapture(nullptr, true); m_pActiveDialog->Show(false); } @@ -290,6 +293,7 @@ void CUIPdaWnd::SetActiveSubdialog(const shared_str& section) { if (!UIMainPdaFrame->IsChild(m_pActiveDialog)) UIMainPdaFrame->AttachChild(m_pActiveDialog); + UIMainPdaFrame->SetKeyboardCapture(m_pActiveDialog, true); m_pActiveDialog->Show(true); m_sActiveSection = section; SetActiveCaption(); @@ -440,13 +444,13 @@ bool CUIPdaWnd::OnKeyboardAction(int dik, EUIMessages keyboard_action) if (inherited::OnKeyboardAction(dik, keyboard_action)) return true; - switch (GetBindedAction(dik, EKeyContext::UI)) - { - case kUI_BACK: - if (WINDOW_KEY_PRESSED == keyboard_action) - HideDialog(); + return false; +} + +bool CUIPdaWnd::OnControllerAction(int axis, float x, float y, EUIMessages controller_action) +{ + if (inherited::OnControllerAction(axis, x, y, controller_action)) return true; - } return false; } diff --git a/src/xrGame/ui/UIPdaWnd.h b/src/xrGame/ui/UIPdaWnd.h index dac3f76be33..5b12385142f 100644 --- a/src/xrGame/ui/UIPdaWnd.h +++ b/src/xrGame/ui/UIPdaWnd.h @@ -69,6 +69,7 @@ class CUIPdaWnd final : public CUIDialogWnd return true; } // always true because StopAnyMove() == false virtual bool OnKeyboardAction(int dik, EUIMessages keyboard_action); + bool OnControllerAction(int axis, float x, float y, EUIMessages controller_action) override; UIHint* get_hint_wnd() const { return m_hint_wnd; } void DrawHint(); diff --git a/src/xrGame/ui/UISecondTaskWnd.cpp b/src/xrGame/ui/UISecondTaskWnd.cpp index 580df5cf850..447b1ae06be 100644 --- a/src/xrGame/ui/UISecondTaskWnd.cpp +++ b/src/xrGame/ui/UISecondTaskWnd.cpp @@ -40,10 +40,14 @@ void UITaskListWnd::init_from_xml(CUIXml& xml, LPCSTR path) m_background = UIHelper::CreateFrameWindow(xml, "background_frame", this); m_caption = UIHelper::CreateStatic(xml, "t_caption", this); // m_counter = UIHelper::CreateStatic( xml, "t_counter", this ); + m_bt_close = UIHelper::Create3tButton(xml, "btn_close", this); + m_bt_close->SetAccelerator(kQUIT, false, 2); + m_bt_close->SetAccelerator(kUI_BACK, false, 3); Register(m_bt_close); - AddCallback(m_bt_close, BUTTON_DOWN, CUIWndCallback::void_function(this, &UITaskListWnd::OnBtnClose)); + AddCallback(m_bt_close, BUTTON_CLICKED, CUIWndCallback::void_function(this, &UITaskListWnd::OnBtnClose)); + UI().Focus().UnregisterFocusable(m_bt_close); m_list = xr_new(); m_list->SetAutoDelete(true); @@ -80,22 +84,40 @@ void UITaskListWnd::OnMouseScroll(float iDirection) m_list->ScrollBar()->TryScrollInc(); } -bool UITaskListWnd::OnKeyboardAction(int dik, EUIMessages keyboard_action) -{ - return inherited::OnKeyboardAction(dik, keyboard_action); -} - -bool UITaskListWnd::OnControllerAction(int axis, float x, float y, EUIMessages controller_action) -{ - return inherited::OnControllerAction(axis, x, y, controller_action); -} - void UITaskListWnd::Show(bool status) { inherited::Show(status); - GetMessageTarget()->SendMessage(this, PDA_TASK_HIDE_HINT, nullptr); + + auto& focus = UI().Focus(); + if (status) + { UpdateList(); + GetMessageTarget()->SetKeyboardCapture(this, true); + focus.LockToWindow(this); + + if (m_list->Empty()) + { + focus.SetFocused(nullptr); + UI().GetUICursor().WarpToWindow(m_list, true); + } + else + { + const auto item = static_cast(m_list->Items()[0]); + item->Focus(); + } + } + else + { + if (GetMessageTarget()->GetKeyboardCapturer() == this) + GetMessageTarget()->SetKeyboardCapture(nullptr, true); + if (focus.GetLocker() == this) + focus.Unlock(); + GetMessageTarget()->SendMessage(GetMessageTarget(), WINDOW_KEYBOARD_CAPTURE_LOST, this); + } + + GetMessageTarget()->SendMessage(this, PDA_TASK_HIDE_HINT, nullptr); + Enable(status); // hack to prevent m_bt_close intercepting quit from PDA itself } void UITaskListWnd::OnFocusReceive() @@ -208,6 +230,10 @@ bool UITaskListWndItem::init_task(CGameTask* task, UITaskListWnd* parent) m_color_states[stt_unread] = CUIXmlInit::GetColor(xml, "second_task_wnd:task_item:unread", 0, u32(-1)); m_color_states[stt_read] = CUIXmlInit::GetColor(xml, "second_task_wnd:task_item:read", 0, u32(-1)); update_view(); + + if (m_bt_view) + UI().Focus().UnregisterFocusable(m_bt_view); + UI().Focus().UnregisterFocusable(m_bt_focus); return true; } @@ -346,6 +372,38 @@ bool UITaskListWndItem::OnMouseAction(float x, float y, EUIMessages mouse_action return true; } +bool UITaskListWndItem::OnKeyboardAction(int dik, EUIMessages keyboard_action) +{ + if (inherited::OnKeyboardAction(dik, keyboard_action)) + return true; + + if (CursorOverWindow()) + { + const auto [x, y] = UI().GetUICursor().GetCursorPosition(); + + switch (GetBindedAction(dik, EKeyContext::UI)) + { + case kUI_ACCEPT: + m_name->OnMouseAction(x, y, WINDOW_LBUTTON_DOWN); + return true; + case kUI_ACTION_1: + m_bt_focus->OnMouseAction(x, y, WINDOW_LBUTTON_DOWN); + return true; + case kUI_ACTION_2: + if (m_bt_view) + m_bt_view->OnMouseAction(x, y, WINDOW_LBUTTON_DOWN); + return true; + } + } + + return false; +} + +void UITaskListWndItem::Focus() const +{ + UI().Focus().SetFocused(m_name); +} + void UITaskListWndItem::OnFocusReceive() { inherited::OnFocusReceive(); diff --git a/src/xrGame/ui/UISecondTaskWnd.h b/src/xrGame/ui/UISecondTaskWnd.h index 419ef64708b..9d0d4cee17e 100644 --- a/src/xrGame/ui/UISecondTaskWnd.h +++ b/src/xrGame/ui/UISecondTaskWnd.h @@ -35,8 +35,6 @@ class UITaskListWnd final : public CUIWindow, public CUIWndCallback virtual bool OnMouseAction(float x, float y, EUIMessages mouse_action); virtual void OnMouseScroll(float iDirection); - bool OnKeyboardAction(int dik, EUIMessages keyboard_action) override; - bool OnControllerAction(int axis, float x, float y, EUIMessages controller_action) override; virtual void Show(bool status); virtual void OnFocusReceive(); virtual void OnFocusLost(); @@ -86,6 +84,9 @@ class UITaskListWndItem final : public CUIWindow virtual void Update(); virtual void SendMessage(CUIWindow* pWnd, s16 msg, void* pData); virtual bool OnMouseAction(float x, float y, EUIMessages mouse_action); + bool OnKeyboardAction(int dik, EUIMessages keyboard_action) override; + + void Focus() const; private: void hide_hint(); diff --git a/src/xrGame/ui/UITaskWnd.cpp b/src/xrGame/ui/UITaskWnd.cpp index 656738a4cd7..bd9878a357d 100644 --- a/src/xrGame/ui/UITaskWnd.cpp +++ b/src/xrGame/ui/UITaskWnd.cpp @@ -1,6 +1,7 @@ #include "StdAfx.h" #include "UITaskWnd.h" #include "UIMapWnd.h" +#include "UIMapFilters.h" #include "Common/object_broker.h" #include "UIXmlInit.h" #include "xrUICore/Static/UIStatic.h" @@ -39,9 +40,14 @@ bool CUITaskWnd::Init() std::ignore = UIHelper::CreateFrameLine(xml, "task_split", this, false); - AttachChild(&m_filters); - m_filters.SetMessageTarget(this); - m_filters.Init(xml); + m_filters = xr_new(); + if (!m_filters->Init(xml)) + xr_delete(m_filters); + else + { + AttachChild(m_filters); + m_filters->SetMessageTarget(this); + } m_pMapWnd = xr_new(hint_wnd); m_pMapWnd->SetAutoDelete(false); @@ -84,6 +90,8 @@ bool CUITaskWnd::Init() auto* btnTaskListWnd = UIHelper::Create3tButton(xml, "btn_second_task", this); AddCallback(btnTaskListWnd, BUTTON_CLICKED, CUIWndCallback::void_function(this, &CUITaskWnd::OnShowTaskListWnd)); + btnTaskListWnd->SetAccelerator(kSCORES, false, 2); + btnTaskListWnd->SetAccelerator(kUI_ACTION_1, false, 3); m_second_task_index = UIHelper::CreateStatic(xml, "second_task_index", this, false); @@ -135,36 +143,29 @@ void CUITaskWnd::DrawHint() { m_pMapWnd->DrawHint(); } bool CUITaskWnd::OnKeyboardAction(int dik, EUIMessages keyboard_action) { - if (inherited::OnKeyboardAction(dik, keyboard_action)) - return true; - - if (keyboard_action == WINDOW_KEY_PRESSED) - { - switch (GetBindedAction(dik, EKeyContext::PDA)) - { - case kPDA_FILTER_TOGGLE: - if (m_pKeyboardCapturer == &m_filters) - SetKeyboardCapture(nullptr, false); - else - SetKeyboardCapture(&m_filters, true); - m_filters.SendMessage(this, PDA_TASK_SELECT_FILTERS, nullptr); - return true; - - case kPDA_TASKS_TOGGLE: - if (m_pKeyboardCapturer == m_task_wnd) - SetKeyboardCapture(nullptr, false); - else - SetKeyboardCapture(m_task_wnd, true); - OnShowTaskListWnd(nullptr, nullptr); - return true; - } - } + if (m_pKeyboardCapturer && pInput->IsCurrentInputTypeController()) + return m_pKeyboardCapturer->OnKeyboardAction(dik, keyboard_action); + return inherited::OnKeyboardAction(dik, keyboard_action); +} - return false; +bool CUITaskWnd::OnControllerAction(int axis, float x, float y, EUIMessages controller_action) +{ + if (m_pKeyboardCapturer && pInput->IsCurrentInputTypeController()) + return m_pKeyboardCapturer->OnControllerAction(axis, x, y, controller_action); + return inherited::OnControllerAction(axis, x, y, controller_action); } void CUITaskWnd::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) { + if (msg == WINDOW_KEYBOARD_CAPTURE_LOST && pWnd == this) + { + if ((m_filters && pData == m_filters) || pData == m_task_wnd) + { + if (pInput->IsCurrentInputTypeController()) + UI().GetUICursor().WarpToWindow(m_pMapWnd, true); + return; + } + } if (msg == PDA_TASK_SET_TARGET_MAP && pData) { CGameTask* task = static_cast(pData); @@ -183,7 +184,6 @@ void CUITaskWnd::SendMessage(CUIWindow* pWnd, s16 msg, void* pData) TaskShowMapSpot(task, false); return; } - if (msg == PDA_TASK_SHOW_HINT && pData) { CGameTask* task = static_cast(pData); @@ -321,9 +321,35 @@ void CUITaskWnd::Show_TaskListWnd(bool status) const m_task_wnd->Show(status); } +bool CUITaskWnd::IsTreasuresEnabled() const { return m_filters && m_filters->IsFilterEnabled(CUIMapFilters::Treasures); } +bool CUITaskWnd::IsQuestNpcsEnabled() const { return m_filters && m_filters->IsFilterEnabled(CUIMapFilters::QuestNpcs); } +bool CUITaskWnd::IsSecondaryTasksEnabled() const { return m_filters && m_filters->IsFilterEnabled(CUIMapFilters::SecondaryTasks); } +bool CUITaskWnd::IsPrimaryObjectsEnabled() const { return m_filters && m_filters->IsFilterEnabled(CUIMapFilters::PrimaryObjects); } + +void CUITaskWnd::TreasuresEnabled(bool enable) +{ + if (m_filters) + m_filters->SetFilterEnabled(CUIMapFilters::Treasures, enable); +} +void CUITaskWnd::QuestNpcsEnabled(bool enable) +{ + if (m_filters) + m_filters->SetFilterEnabled(CUIMapFilters::QuestNpcs, enable); +} +void CUITaskWnd::SecondaryTasksEnabled(bool enable) +{ + if (m_filters) + m_filters->SetFilterEnabled(CUIMapFilters::SecondaryTasks, enable); +} +void CUITaskWnd::PrimaryObjectsEnabled(bool enable) +{ + if (m_filters) + m_filters->SetFilterEnabled(CUIMapFilters::PrimaryObjects, enable); +} + bool CUITaskWnd::IsUsingCursorRightNow() const { - return m_pKeyboardCapturer == &m_filters; + return true; } void CUITaskWnd::TaskSetTargetMap(CGameTask* task) const diff --git a/src/xrGame/ui/UITaskWnd.h b/src/xrGame/ui/UITaskWnd.h index afed64c5af0..3535af6747f 100644 --- a/src/xrGame/ui/UITaskWnd.h +++ b/src/xrGame/ui/UITaskWnd.h @@ -4,9 +4,9 @@ #include "xrUICore/Callbacks/UIWndCallback.h" #include "xrCore/Containers/AssociativeVector.hpp" #include "GameTaskDefs.h" -#include "UIMapFilters.h" class CUIMapWnd; +class CUIMapFilters; class CUIStatic; class CGameTask; class CUIXml; @@ -36,7 +36,7 @@ class CUITaskWnd final : public CUIWindow, public CUIWndCallback CUI3tButton* m_btn_focus{}; CUI3tButton* m_btn_focus2{}; - CUIMapFilters m_filters; + CUIMapFilters* m_filters; UITaskListWnd* m_task_wnd{}; UIMapLegend* m_map_legend_wnd{}; @@ -51,6 +51,7 @@ class CUITaskWnd final : public CUIWindow, public CUIWndCallback pcstr GetDebugType() override { return "CUITaskWnd"; } bool OnKeyboardAction(int dik, EUIMessages keyboard_action) override; + bool OnControllerAction(int axis, float x, float y, EUIMessages controller_action) override; virtual void SendMessage(CUIWindow* pWnd, s16 msg, void* pData); bool Init(); virtual void Update(); @@ -63,18 +64,21 @@ class CUITaskWnd final : public CUIWindow, public CUIWndCallback void Show_TaskListWnd(bool status) const; [[nodiscard]] - bool IsTreasuresEnabled() const { return m_filters.IsFilterEnabled(CUIMapFilters::Treasures); } + bool IsTreasuresEnabled() const; + [[nodiscard]] - bool IsQuestNpcsEnabled() const { return m_filters.IsFilterEnabled(CUIMapFilters::QuestNpcs); } + bool IsQuestNpcsEnabled() const; + [[nodiscard]] - bool IsSecondaryTasksEnabled() const { return m_filters.IsFilterEnabled(CUIMapFilters::SecondaryTasks); } + bool IsSecondaryTasksEnabled() const; + [[nodiscard]] - bool IsPrimaryObjectsEnabled() const { return m_filters.IsFilterEnabled(CUIMapFilters::PrimaryObjects); } + bool IsPrimaryObjectsEnabled() const; - void TreasuresEnabled(bool enable) { m_filters.SetFilterEnabled(CUIMapFilters::Treasures, enable); } - void QuestNpcsEnabled(bool enable) { m_filters.SetFilterEnabled(CUIMapFilters::QuestNpcs, enable); } - void SecondaryTasksEnabled(bool enable) { m_filters.SetFilterEnabled(CUIMapFilters::SecondaryTasks, enable); } - void PrimaryObjectsEnabled(bool enable) { m_filters.SetFilterEnabled(CUIMapFilters::PrimaryObjects, enable); } + void TreasuresEnabled(bool enable); + void QuestNpcsEnabled(bool enable); + void SecondaryTasksEnabled(bool enable); + void PrimaryObjectsEnabled(bool enable); bool IsUsingCursorRightNow() const override; diff --git a/src/xrUICore/UIMessages.h b/src/xrUICore/UIMessages.h index 2f0cf89122a..a277a7ab9cc 100644 --- a/src/xrUICore/UIMessages.h +++ b/src/xrUICore/UIMessages.h @@ -91,7 +91,6 @@ enum EUIMessages PDA_TASK_HIDE_MAP_SPOT, PDA_TASK_SHOW_HINT, PDA_TASK_HIDE_HINT, - PDA_TASK_SELECT_FILTERS, PDA_TASK_RELOAD_FILTERS, // CUIInventroyWnd