mirror of
https://github.com/Zelda64Recomp/Zelda64Recomp
synced 2026-05-28 08:26:00 -04:00
Cont/kb/mouse focus priorities and behaviors reworked (#15)
* ensure focus after cont/kb input + enable mouse on SDL_QUIT + force focus to prompt while open * only force prompt focus if mouse is not active * default kb input, mouse click switches to kb focused input
This commit is contained in:
+61
-6
@@ -786,6 +786,7 @@ struct UIContext {
|
||||
public:
|
||||
bool mouse_is_active_initialized = false;
|
||||
bool mouse_is_active = false;
|
||||
bool cont_is_active = false;
|
||||
bool await_stick_return_x = false;
|
||||
bool await_stick_return_y = false;
|
||||
int last_active_mouse_position[2] = {0, 0};
|
||||
@@ -929,11 +930,25 @@ struct UIContext {
|
||||
}
|
||||
}
|
||||
|
||||
void update_focus(bool mouse_moved) {
|
||||
void update_focus(bool mouse_moved, bool non_mouse_interacted) {
|
||||
if (current_document == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cont_is_active || non_mouse_interacted) {
|
||||
if (non_mouse_interacted) {
|
||||
auto focusedEl = current_document->GetFocusLeafNode();
|
||||
Rml::Variant* ti = focusedEl == nullptr ? nullptr : focusedEl->GetAttribute("tab-index");
|
||||
if (focusedEl == nullptr || RecompRml::CanFocusElement(focusedEl) != RecompRml::CanFocus::Yes) {
|
||||
Rml::Element* element = find_autofocus_element(current_document);
|
||||
if (element != nullptr) {
|
||||
element->Focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If there was mouse motion, get the current hovered element (or its target if it points to one) and focus that if applicable.
|
||||
if (mouse_is_active) {
|
||||
if (mouse_is_active_changed) {
|
||||
@@ -1034,14 +1049,38 @@ struct UIContext {
|
||||
}
|
||||
wasShowingPrompt = ctx->open;
|
||||
|
||||
if (!ctx->shouldFocus) return;
|
||||
if (!ctx->open) {
|
||||
return;
|
||||
}
|
||||
|
||||
Rml::Element* focused = current_document->GetFocusLeafNode();
|
||||
if (focused) focused->Blur();
|
||||
// Check if unfocused or current focus isn't either prompt button
|
||||
if (mouse_is_active == false) {
|
||||
if (
|
||||
focused == nullptr || (
|
||||
focused != current_document->GetElementById("prompt__cancel-button") &&
|
||||
focused != current_document->GetElementById("prompt__confirm-button")
|
||||
)
|
||||
) {
|
||||
ctx->shouldFocus = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ctx->shouldFocus) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (focused != nullptr) {
|
||||
focused->Blur();
|
||||
}
|
||||
|
||||
Rml::Element *targetButton = current_document->GetElementById(
|
||||
ctx->focusOnCancel ? "prompt__cancel-button" : "prompt__confirm-button");
|
||||
|
||||
if (targetButton == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
targetButton->Focus(true);
|
||||
|
||||
ctx->shouldFocus = false;
|
||||
@@ -1189,6 +1228,19 @@ void apply_background_input_mode() {
|
||||
last_input_mode = cur_input_mode;
|
||||
}
|
||||
|
||||
bool recomp::get_cont_active() {
|
||||
return ui_context->rml.cont_is_active;
|
||||
}
|
||||
|
||||
void recomp::set_cont_active(bool active) {
|
||||
ui_context->rml.cont_is_active = active;
|
||||
}
|
||||
|
||||
void recomp::activate_mouse() {
|
||||
ui_context->rml.update_primary_input(true, false);
|
||||
ui_context->rml.update_focus(true, false);
|
||||
}
|
||||
|
||||
void draw_hook(RT64::RenderCommandList* command_list, RT64::RenderFramebuffer* swap_chain_framebuffer) {
|
||||
std::lock_guard lock {ui_context_mutex};
|
||||
|
||||
@@ -1231,6 +1283,7 @@ void draw_hook(RT64::RenderCommandList* command_list, RT64::RenderFramebuffer* s
|
||||
SDL_Event cur_event{};
|
||||
|
||||
bool mouse_moved = false;
|
||||
bool mouse_clicked = false;
|
||||
bool non_mouse_interacted = false;
|
||||
bool cont_interacted = false;
|
||||
bool kb_interacted = false;
|
||||
@@ -1269,6 +1322,7 @@ void draw_hook(RT64::RenderCommandList* command_list, RT64::RenderFramebuffer* s
|
||||
// fallthrough
|
||||
case SDL_EventType::SDL_MOUSEBUTTONDOWN:
|
||||
mouse_moved = true;
|
||||
mouse_clicked = true;
|
||||
break;
|
||||
|
||||
case SDL_EventType::SDL_CONTROLLERBUTTONDOWN: {
|
||||
@@ -1342,9 +1396,10 @@ void draw_hook(RT64::RenderCommandList* command_list, RT64::RenderFramebuffer* s
|
||||
}
|
||||
} // end dequeue event loop
|
||||
|
||||
if (cont_interacted || kb_interacted) {
|
||||
recomp::set_cont_or_kb(cont_interacted);
|
||||
if (cont_interacted || kb_interacted || mouse_clicked) {
|
||||
recomp::set_cont_active(cont_interacted);
|
||||
}
|
||||
recomp::config_menu_set_cont_or_kb(ui_context->rml.cont_is_active);
|
||||
|
||||
recomp::InputField scanned_field = recomp::get_scanned_input();
|
||||
if (scanned_field != recomp::InputField{}) {
|
||||
@@ -1352,7 +1407,7 @@ void draw_hook(RT64::RenderCommandList* command_list, RT64::RenderFramebuffer* s
|
||||
}
|
||||
|
||||
ui_context->rml.update_primary_input(mouse_moved, non_mouse_interacted);
|
||||
ui_context->rml.update_focus(mouse_moved);
|
||||
ui_context->rml.update_focus(mouse_moved, non_mouse_interacted);
|
||||
|
||||
if (cur_menu != recomp::Menu::None) {
|
||||
int width = swap_chain_framebuffer->getWidth();
|
||||
|
||||
Reference in New Issue
Block a user