mirror of
https://github.com/Mr-Wiseguy/Zelda64Recomp.git
synced 2024-11-22 12:59:14 +01:00
mouse-active/inactive ui modes + focus handling
This commit is contained in:
parent
c370f9011e
commit
03af2919e9
File diff suppressed because one or more lines are too long
@ -5,7 +5,7 @@
|
|||||||
color: $color-text-dim;
|
color: $color-text-dim;
|
||||||
border-color: rgba($base-col, 0.8);
|
border-color: rgba($base-col, 0.8);
|
||||||
|
|
||||||
&:focus {
|
&:focus, &:hover {
|
||||||
color: $color-text;
|
color: $color-text;
|
||||||
border-color: $base-col;
|
border-color: $base-col;
|
||||||
background-color: rgba($base-col, 0.3);
|
background-color: rgba($base-col, 0.3);
|
||||||
|
@ -115,7 +115,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus + .config-option__tab-label {
|
&:focus + .config-option__tab-label,
|
||||||
|
&:hover + .config-option__tab-label {
|
||||||
color: $color-text;
|
color: $color-text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,12 +37,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:focus, &:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
color: $color-text;
|
color: $color-text;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,6 @@ body
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
color: $color-text;
|
color: $color-text;
|
||||||
font-family: $font-stack;
|
font-family: $font-stack;
|
||||||
|
|
||||||
&[disable-mouse] {
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.rmlui-window {
|
.rmlui-window {
|
||||||
@ -26,6 +22,10 @@ body
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: none;
|
transition: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:not([mouse-active]) {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*, *:before, *:after {
|
*, *:before, *:after {
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
padding: space(12) space(4);
|
padding: space(12) space(4);
|
||||||
background-color: rgba(0, 0, 0, 0);
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
|
||||||
|
&:focus:not(:disabled, [disabled]),
|
||||||
&:focus-visible:not(:disabled, [disabled]),
|
&:focus-visible:not(:disabled, [disabled]),
|
||||||
&:hover:not(:disabled, [disabled]) {
|
&:hover:not(:disabled, [disabled]) {
|
||||||
@include set-color($color-text);
|
@include set-color($color-text);
|
||||||
@ -116,11 +117,7 @@
|
|||||||
background-color: $color-white-a5;
|
background-color: $color-white-a5;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover:not(:focus) {
|
&:hover, &:focus {
|
||||||
@include border($color-white-a80);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover:focus, &:focus {
|
|
||||||
@include border($color-white-a80);
|
@include border($color-white-a80);
|
||||||
background-color: $color-white-a20;
|
background-color: $color-white-a20;
|
||||||
}
|
}
|
||||||
|
@ -770,6 +770,8 @@ struct UIContext {
|
|||||||
std::unordered_map<recomp::Menu, Rml::ElementDocument*> documents;
|
std::unordered_map<recomp::Menu, Rml::ElementDocument*> documents;
|
||||||
Rml::ElementDocument* current_document;
|
Rml::ElementDocument* current_document;
|
||||||
Rml::Element* prev_focused;
|
Rml::Element* prev_focused;
|
||||||
|
bool mouse_is_active = true;
|
||||||
|
bool mouse_is_active_changed = false;
|
||||||
public:
|
public:
|
||||||
std::unique_ptr<SystemInterface_SDL> system_interface;
|
std::unique_ptr<SystemInterface_SDL> system_interface;
|
||||||
std::unique_ptr<RmlRenderInterface_RT64> render_interface;
|
std::unique_ptr<RmlRenderInterface_RT64> render_interface;
|
||||||
@ -862,43 +864,73 @@ struct UIContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update_primary_input(bool mouse_moved, bool non_mouse_interacted) {
|
||||||
|
if (current_document == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mouse_is_active_changed = false;
|
||||||
|
if (non_mouse_interacted) {
|
||||||
|
// controller newly interacted with
|
||||||
|
if (mouse_is_active) {
|
||||||
|
mouse_is_active = false;
|
||||||
|
mouse_is_active_changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mouse_moved) {
|
||||||
|
// mouse newly interacted with
|
||||||
|
if (!mouse_is_active) {
|
||||||
|
mouse_is_active = true;
|
||||||
|
mouse_is_active_changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Figure out why this only works if the mouse is moving
|
||||||
|
SDL_ShowCursor(mouse_is_active ? SDL_ENABLE : SDL_DISABLE);
|
||||||
|
|
||||||
|
Rml::Element* window_el = current_document->GetElementById("window");
|
||||||
|
if (window_el != nullptr) {
|
||||||
|
if (mouse_is_active) {
|
||||||
|
if (!window_el->HasAttribute("mouse-active")) {
|
||||||
|
window_el->SetAttribute("mouse-active", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (window_el->HasAttribute("mouse-active")) {
|
||||||
|
window_el->RemoveAttribute("mouse-active");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void update_focus(bool mouse_moved) {
|
void update_focus(bool mouse_moved) {
|
||||||
if (current_document == nullptr) {
|
if (current_document == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Rml::Element* focused = current_document->GetFocusLeafNode();
|
|
||||||
|
|
||||||
// If there was mouse motion, get the current hovered element (or its target if it points to one) and focus that if applicable.
|
// 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_moved) {
|
if (mouse_is_active) {
|
||||||
Rml::Element* hovered = context->GetHoverElement();
|
if (mouse_is_active_changed) {
|
||||||
if (hovered) {
|
Rml::Element* focused = current_document->GetFocusLeafNode();
|
||||||
Rml::Element* hover_target = get_target(current_document, hovered);
|
if (focused) focused->Blur();
|
||||||
if (hover_target && can_focus(hover_target)) {
|
} else if (mouse_moved) {
|
||||||
hover_target->Focus();
|
Rml::Element* hovered = context->GetHoverElement();
|
||||||
}
|
if (hovered) {
|
||||||
}
|
Rml::Element* hover_target = get_target(current_document, hovered);
|
||||||
}
|
if (hover_target && can_focus(hover_target)) {
|
||||||
|
// hover_target->Focus();
|
||||||
// Revert focus to the previous element if focused on anything without a tab index.
|
prev_focused = hover_target;
|
||||||
// This should prevent the user from losing focus on something that has no navigation.
|
|
||||||
if (focused && !can_focus(focused)) {
|
|
||||||
// If the previously focused element is still accepting focus, return focus to it.
|
|
||||||
if (prev_focused && can_focus(prev_focused)) {
|
|
||||||
prev_focused->Focus();
|
|
||||||
}
|
|
||||||
// Otherwise, check if the currently focused element has a "nav-return" attribute and focus that attribute's value if so.
|
|
||||||
else {
|
|
||||||
Rml::Variant* nav_return = focused->GetAttribute("nav-return");
|
|
||||||
if (nav_return && nav_return->GetType() == Rml::Variant::STRING) {
|
|
||||||
Rml::Element* return_element = current_document->GetElementById(nav_return->Get<std::string>());
|
|
||||||
if (return_element) {
|
|
||||||
return_element->Focus();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
prev_focused = current_document->GetFocusLeafNode();
|
if (!mouse_is_active) {
|
||||||
|
if (!prev_focused) {
|
||||||
|
// get current focus and set to prev
|
||||||
|
prev_focused = current_document->GetFocusLeafNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mouse_is_active_changed && prev_focused && can_focus(prev_focused)) {
|
||||||
|
prev_focused->Focus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1037,6 +1069,7 @@ void draw_hook(RT64::RenderCommandList* command_list, RT64::RenderFramebuffer* s
|
|||||||
SDL_Event cur_event{};
|
SDL_Event cur_event{};
|
||||||
|
|
||||||
bool mouse_moved = false;
|
bool mouse_moved = false;
|
||||||
|
bool non_mouse_interacted = false;
|
||||||
|
|
||||||
while (recomp::try_deque_event(cur_event)) {
|
while (recomp::try_deque_event(cur_event)) {
|
||||||
// Scale coordinates for mouse and window events based on the UI scale
|
// Scale coordinates for mouse and window events based on the UI scale
|
||||||
@ -1066,14 +1099,28 @@ void draw_hook(RT64::RenderCommandList* command_list, RT64::RenderFramebuffer* s
|
|||||||
|
|
||||||
// Send events to RmlUi if a menu is open.
|
// Send events to RmlUi if a menu is open.
|
||||||
if (cur_menu != recomp::Menu::None) {
|
if (cur_menu != recomp::Menu::None) {
|
||||||
RmlSDL::InputEventHandler(ui_context->rml.context, cur_event);
|
|
||||||
// Implement some additional behavior for specific events on top of what RmlUi normally does with them.
|
// Implement some additional behavior for specific events on top of what RmlUi normally does with them.
|
||||||
switch (cur_event.type) {
|
switch (cur_event.type) {
|
||||||
case SDL_EventType::SDL_MOUSEMOTION:
|
case SDL_EventType::SDL_MOUSEMOTION:
|
||||||
mouse_moved = true;
|
mouse_moved = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SDL_EventType::SDL_CONTROLLERBUTTONDOWN:
|
||||||
|
case SDL_EventType::SDL_KEYDOWN:
|
||||||
|
non_mouse_interacted = true;
|
||||||
|
break;
|
||||||
|
case SDL_EventType::SDL_CONTROLLERAXISMOTION:
|
||||||
|
SDL_ControllerAxisEvent* axis_event = &cur_event.caxis;
|
||||||
|
float axis_value = axis_event->value * (1 / 32768.0f);
|
||||||
|
if (fabsf(axis_value) > 0.2f) {
|
||||||
|
non_mouse_interacted = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RmlSDL::InputEventHandler(ui_context->rml.context, cur_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no menu is open and the game has been started and either the escape key or select button are pressed, open the config menu.
|
// If no menu is open and the game has been started and either the escape key or select button are pressed, open the config menu.
|
||||||
if (cur_menu == recomp::Menu::None && ultramodern::is_game_started()) {
|
if (cur_menu == recomp::Menu::None && ultramodern::is_game_started()) {
|
||||||
bool open_config = false;
|
bool open_config = false;
|
||||||
@ -1104,6 +1151,7 @@ void draw_hook(RT64::RenderCommandList* command_list, RT64::RenderFramebuffer* s
|
|||||||
recomp::finish_scanning_input(scanned_field);
|
recomp::finish_scanning_input(scanned_field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
if (cur_menu != recomp::Menu::None) {
|
if (cur_menu != recomp::Menu::None) {
|
||||||
|
Loading…
Reference in New Issue
Block a user