Skip to content

Commit

Permalink
UI Focus system WIP (#943)
Browse files Browse the repository at this point in the history
  • Loading branch information
Xottab-DUTY committed May 23, 2024
1 parent 1dcf546 commit 6e3a069
Show file tree
Hide file tree
Showing 18 changed files with 364 additions and 19 deletions.
6 changes: 4 additions & 2 deletions res/gamedata/scripts/ui_main_menu.script
Original file line number Diff line number Diff line change
Expand Up @@ -356,20 +356,22 @@ function main_menu:OnKeyboard(dik, keyboard_action) --virtual function
) then
self.OnButton_return_game() --' xStream 02.2008
-- console:execute("main_menu off") --' xStream 02.2008
return true
end
end

-- if dik == DIK_keys.DIK_S then
-- self:OnButton_load_spawn()

-- return true
-- else
if dik == DIK_keys.DIK_Q then
self:OnMessageQuitWin()
return true
end

end

return true
return false
end

function main_menu:OnMenuReloaded()
Expand Down
36 changes: 22 additions & 14 deletions src/xrGame/UIDialogHolder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ void CDialogHolder::StartMenu(CUIDialogWnd* pDialog, bool bDoHideIndicators)
CurrentGameUI()->ShowGameIndicators(false);
}
}
SetFocused(nullptr);
pDialog->SetHolder(this);

if (pDialog->NeedCursor())
Expand Down Expand Up @@ -303,6 +304,25 @@ bool CDialogHolder::IR_UIOnKeyboardPress(int dik)
return (false);
}
}

/*if (const auto focused = GetFocused())
{
CUIWindow* target{};
switch (GetBindedAction(dik, EKeyContext::UI))
{
case kUI_MOVE_LEFT: target = FindClosestFocusable(focused, FocusDirection::Left); break;
case kUI_MOVE_RIGHT: target = FindClosestFocusable(focused, FocusDirection::Right); break;
case kUI_MOVE_UP: target = FindClosestFocusable(focused, FocusDirection::Up); break;
case kUI_MOVE_DOWN: target = FindClosestFocusable(focused, FocusDirection::Down); break;
}
if (target)
{
SetFocused(target);
GetUICursor().WarpToWindow(target, true);
}
}*/

return true;
}

Expand Down Expand Up @@ -444,13 +464,7 @@ bool CDialogHolder::IR_UIOnControllerPress(int dik, float x, float y)
if (TIR->OnControllerAction(dik, x, y, WINDOW_KEY_PRESSED))
return true;

if (GetUICursor().IsVisible() && IsBinded(kLOOK_AROUND, dik))
{
GetUICursor().UpdateCursorPosition(int(std::round(x)), int(std::round(y)));
Fvector2 cPos = GetUICursor().GetCursorPosition();
TIR->OnMouseAction(cPos.x, cPos.y, WINDOW_MOUSE_MOVE);
}
else if (!TIR->StopAnyMove() && g_pGameLevel)
if (!TIR->StopAnyMove() && g_pGameLevel)
{
IGameObject* O = Level().CurrentEntity();
if (O)
Expand Down Expand Up @@ -510,13 +524,7 @@ bool CDialogHolder::IR_UIOnControllerHold(int dik, float x, float y)
if (TIR->OnControllerAction(dik, x, y, WINDOW_KEY_HOLD))
return true;

if (GetUICursor().IsVisible() && IsBinded(kLOOK_AROUND, dik))
{
GetUICursor().UpdateCursorPosition(int(std::round(x)), int(std::round(y)));
Fvector2 cPos = GetUICursor().GetCursorPosition();
TIR->OnMouseAction(cPos.x, cPos.y, WINDOW_MOUSE_MOVE);
}
else if (!TIR->StopAnyMove() && g_pGameLevel)
if (!TIR->StopAnyMove() && g_pGameLevel)
{
IGameObject* O = Level().CurrentEntity();
if (O)
Expand Down
3 changes: 2 additions & 1 deletion src/xrGame/UIDialogHolder.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "xrCore/_flags.h"
#include "xrEngine/pure.h"
#include "xrUICore/ui_debug.h"
#include "xrUICore/ui_focus.h"

#include <SDL.h>

Expand Down Expand Up @@ -32,7 +33,7 @@ class recvItem
Flags8 m_flags;
};

class CDialogHolder : public pureFrame, public CUIDebuggable
class CDialogHolder : public pureFrame, public CUIDebuggable, public CUIFocusSystem
{
// dialogs
xr_vector<recvItem> m_input_receivers;
Expand Down
13 changes: 11 additions & 2 deletions src/xrGame/ui/UIDialogWnd.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,17 @@ class CUIDialogWnd : public CUIWindow
bool OnKeyboardAction(int dik, EUIMessages keyboard_action) override;
bool OnControllerAction(int axis, float x, float y, EUIMessages controller_action) override;

CDialogHolder* GetHolder() { return m_pParentHolder; }
void SetHolder(CDialogHolder* h) { m_pParentHolder = h; }
CDialogHolder* GetHolder() const { return m_pParentHolder; }

void SetHolder(CDialogHolder* h)
{
if (m_pParentHolder)
m_pParentHolder->UnregisterFocusable(this);
m_pParentHolder = h;
}

CUIFocusSystem* GetCurrentFocusSystem() const override { return GetHolder(); }

virtual bool StopAnyMove() { return true; }
virtual bool NeedCursor() const { return true; }
virtual bool NeedCenterCursor() const { return true; }
Expand Down
1 change: 1 addition & 0 deletions src/xrGame/ui/UIMMShniaga.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ void CUIMMShniaga::OnBtnClick()

bool CUIMMShniaga::OnKeyboardAction(int dik, EUIMessages keyboard_action)
{
return false;
if (IsBinded(kQUIT, dik))
{
if (m_page != epi_main)
Expand Down
1 change: 1 addition & 0 deletions src/xrUICore/Buttons/UIButton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

CUIButton::CUIButton() : CUIStatic("CUIButton")
{
m_bFocusValuable = true;
m_eButtonState = BUTTON_NORMAL;
m_bIsSwitch = false;

Expand Down
2 changes: 2 additions & 0 deletions src/xrUICore/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ target_sources(xrUICore PRIVATE
ui_debug.cpp
ui_debug.h
ui_defs.h
ui_focus.cpp
ui_focus.h
ui_styles.cpp
ui_styles.h
uiabstract.h
Expand Down
2 changes: 2 additions & 0 deletions src/xrUICore/ComboBox/UIComboBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

CUIComboBox::CUIComboBox() : CUIWindow("CUIComboBox")
{
m_bFocusValuable = true;

AttachChild(&m_frameLine);
AttachChild(&m_text);

Expand Down
1 change: 1 addition & 0 deletions src/xrUICore/Cursor/UICursor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ void CUICursor::Show()

void CUICursor::Hide()
{
return;
bVisible = false;
m_become_visible_time = 0;
m_pause_autohide = false;
Expand Down
2 changes: 2 additions & 0 deletions src/xrUICore/EditBox/UICustomEdit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

CUICustomEdit::CUICustomEdit() : CUIStatic("CUICustomEdit")
{
m_bFocusValuable = true;

m_editor_control = xr_new<text_editor::line_edit_control>(EDIT_BUF_SIZE);
Init(EDIT_BUF_SIZE);

Expand Down
2 changes: 2 additions & 0 deletions src/xrUICore/TrackBar/UITrackBar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ CUITrackBar::CUITrackBar()
: m_b_invert(false), m_b_is_float(true), m_b_bound_already_set(false), m_f_val(0), m_f_max(1), m_f_min(0),
m_f_step(0.01f), m_f_opt_backup_value(0)
{
m_bFocusValuable = true;

m_pSlider = xr_new<CUI3tButton>();
AttachChild(m_pSlider);
m_pSlider->SetAutoDelete(true);
Expand Down
25 changes: 25 additions & 0 deletions src/xrUICore/Windows/UIWindow.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "pch.hpp"

#include "UIWindow.h"

#include "ui_focus.h"
#include "Cursor/UICursor.h"

CUIWindow::CUIWindow(pcstr window_name) : m_windowName(window_name)
Expand Down Expand Up @@ -41,6 +43,25 @@ void CUIWindow::Draw(float x, float y)

void CUIWindow::Update()
{
/*if (auto* focusSystem = GetCurrentFocusSystem())
{
const bool valuable = IsFocusValuable();
const bool registered = focusSystem->IsRegistered(this);
if (valuable)
{
if (!registered)
focusSystem->RegisterFocusable(this);
if (!focusSystem->GetFocused())
focusSystem->SetFocused(this);
}
else if (!valuable && registered)
{
if (focusSystem->GetFocused() == this)
focusSystem->SetFocused(nullptr);
focusSystem->UnregisterFocusable(this);
}
}*/

bool cursor_on_window = false;
if (GetUICursor().IsVisible())
{
Expand Down Expand Up @@ -551,6 +572,10 @@ bool CUIWindow::FillDebugTree(const CUIDebugState& debugState)
rnd.seed((s32)(intptr_t)this);
color = color_rgba(rnd.randI(255), rnd.randI(255), rnd.randI(255), 255);
}
else if (GetCurrentFocusSystem() && GetCurrentFocusSystem()->GetFocused() == this)
color = color_rgba(200, 150, 200, 255);
else if (IsFocusValuable())
color = color_rgba(255, 0, 255, 255);

const auto draw_list = hovered ? ImGui::GetForegroundDrawList() : ImGui::GetBackgroundDrawList();
draw_list->AddRect((const ImVec2&)rect.lt, (const ImVec2&)rect.rb, color);
Expand Down
29 changes: 29 additions & 0 deletions src/xrUICore/Windows/UIWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include "xrUICore/uiabstract.h"
#include "xrUICore/ui_debug.h"

class CUIFocusSystem;

class XRUICORE_API CUIWindow : public CUISimpleWindow, public CUIDebuggable
{
public:
Expand Down Expand Up @@ -81,16 +83,41 @@ class XRUICORE_API CUIWindow : public CUISimpleWindow, public CUIDebuggable

virtual void Enable(bool status) { m_bIsEnabled = status; }

void SetFocusValuable(bool valuable) { m_bFocusValuable = valuable; }

[[nodiscard]]
bool IsEnabled() const { return m_bIsEnabled; }

[[nodiscard]]
bool IsFocusValuable() const
{
if (!m_bFocusValuable)
return false;

bool ok;
for (auto it = this; ; it = it->GetParent())
{
ok = it->IsShown() && it->IsEnabled();
if (!ok || !it->GetParent())
break;
}
return ok;
}

//убрать/показать окно и его дочерние окна
virtual void Show(bool status)
{
SetVisible(status);
Enable(status);
}

virtual CUIFocusSystem* GetCurrentFocusSystem() const
{
if (m_pParentWnd)
return m_pParentWnd->GetCurrentFocusSystem();
return nullptr;
}

[[nodiscard]]
virtual bool IsShown() const { return GetVisible(); }

Expand Down Expand Up @@ -197,6 +224,8 @@ class XRUICORE_API CUIWindow : public CUISimpleWindow, public CUIDebuggable
// Если курсор над окном
bool m_bCursorOverWindow{};
bool m_bCustomDraw{};

bool m_bFocusValuable{};
};

XRUICORE_API bool fit_in_rect(CUIWindow* w, Frect const& vis_rect, float border = 0.0f, float dx16pos = 0.0f);
31 changes: 31 additions & 0 deletions src/xrUICore/Windows/UIWindow_script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "ScrollView/UIScrollView.h"
#include "Hint/UIHint.h"
#include "Cursor/UICursor.h"
#include "ui_focus.h"
#include "ui_styles.h"

#include "xrScriptEngine/ScriptExporter.hpp"
Expand Down Expand Up @@ -69,6 +70,34 @@ SCRIPT_EXPORT(UIStyleManager, (),
];
});

SCRIPT_EXPORT(CUIFocusSystem, (),
{
using namespace luabind;
using namespace luabind::policy;

module(luaState)
[
class_<FocusDirection>("FocusDirection")
.enum_("direction")
[
value("Same", (int)FocusDirection::Same),
value("Up", (int)FocusDirection::Up),
value("Down", (int)FocusDirection::Down),
value("Left", (int)FocusDirection::Left),
value("Right", (int)FocusDirection::Right),
value("UpperLeft", (int)FocusDirection::UpperLeft),
value("UpperRight", (int)FocusDirection::UpperRight),
value("LowerLeft", (int)FocusDirection::LowerLeft),
value("LowerRight", (int)FocusDirection::LowerRight)
],
class_<CUIFocusSystem>("CUIFocusSystem")
.def("RegisterFocusable", &CUIFocusSystem::RegisterFocusable)
.def("UnregisterFocusable", &CUIFocusSystem::UnregisterFocusable)
.def("IsRegistered", &CUIFocusSystem::IsRegistered)
.def("FindClosestFocusable", &CUIFocusSystem::FindClosestFocusable)
];
});

SCRIPT_EXPORT(CUITextureMaster, (),
{
using namespace luabind;
Expand Down Expand Up @@ -184,6 +213,8 @@ SCRIPT_EXPORT(CUIWindow, (),
.def("SetFont", &CUIWindow::SetFont)
.def("GetFont", &CUIWindow::GetFont)

.def("GetCurrentFocusSystem", &CUIWindow::GetCurrentFocusSystem)

.def("WindowName", +[](CUIWindow* self) -> pcstr { return self->WindowName().c_str(); })
.def("SetWindowName", &CUIWindow::SetWindowName),

Expand Down
Loading

0 comments on commit 6e3a069

Please sign in to comment.