Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Navigate programatically #4

Closed
pakjiddat opened this issue Oct 17, 2024 · 4 comments
Closed

Navigate programatically #4

pakjiddat opened this issue Oct 17, 2024 · 4 comments

Comments

@pakjiddat
Copy link

When I press the Tab button, the cursor moves to the next form field. The Tab button works fine. However, I would like the navigation to work on the click of a button. Please see below screenshot. When I click the button, the cursor should be on the top most text field. When I click the button again, the cursor should move to the dropdown. When I click the button again the cursor should move to the bottom text field.

screenshot-1

I called this function in the button click handler: EasyTabIntegration.Globally.Navigate();, but it did not work. When I click on the button, the cursor moves to the top most text field. When I click on the button again, the cursor stays on the top most text field.

Thanks

@dav-sea
Copy link
Owner

dav-sea commented Oct 17, 2024

Hello 👋

It seems that at the moment of clicking on the button, unity makes this button as current (This can be checked in the button click handler via EventSystem.current.currentSelectedGameObject), accordingly, Navigate will switch to the next element relative to this button, in this case it is a text field on top.

An event about changing the current in EventSystem object would help a lot, but I didn't find anything suitable.

Nevertheless, your task can be solved very simply if you save the currently selected object separately from the EventSystem. Then you can define the next one via EasyTabIntegration.Globally.Solver.GetNext(current).

In the generalized case, you will need to save the currently selected object to a temporary field. For example, like this script for button:

HandlerForButton.cs
    private GameObject _current;
    
    void Start() { 
        GetComponent<Button>().onClick.AddListener(() =>
        {
            var easyTabSolver = new EasyTabSolver();
            var next = easyTabSolver.GetNext(_current);
            if(next && next.TryGetComponent(out Selectable nextSelectable))
                nextSelectable.Select();
        });
    }

    void Update() {
        var eventSystemCurrent = EventSystem.current.currentSelectedGameObject;
        if(eventSystemCurrent == gameObject) // gameObject is this button
            return;

        _current = eventSystemCurrent;
    }

If you need to exclude a button from navigation, you can do this by hanging the EasyTab component on it and changing SelectableRecognition to AsNotSelectable

Result:
demo

I hope my answer was helpful.

@pakjiddat
Copy link
Author

pakjiddat commented Oct 18, 2024

Hello

I attached the script you provided to the button object. I wanted to exclude the button from navigation so I attached EasyTab script to the button and set the SelectableRecognition property to AsNotSelectable. The navigation worked perfectly.

However I wanted the first text field to have focus set. I created a gameObject and attached the following script to it:


using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class SetFocus : MonoBehaviour
{
    public InputField myInputField;

    void Start()
    {
        // Set focus on the input field at the start of the scene
        SetInputFieldFocus();
    }

    void SetInputFieldFocus()
    {
        // Check if the input field is not already selected
        if (myInputField != null)
        {
            // Set the input field as the selected object in the EventSystem
            EventSystem.current.SetSelectedGameObject(myInputField.gameObject);

            // Optionally, activate the input field to immediately show the cursor
            myInputField.ActivateInputField();
        }
    }
}

I also attached the first text field to the above script from the inspector. After this, the first text field was focused.

Thank you very much for your help

@dav-sea
Copy link
Owner

dav-sea commented Oct 18, 2024

You may also want to use FirstSelected in the EventSystem component to select a inputfield at the start

image

@pakjiddat
Copy link
Author

Setting FirstSelected in EventSystem component allows setting input field that should have focus at the start. If I do this, then I dont need to use the SetFocus class that I posted. Thanks.

@dav-sea dav-sea closed this as completed Oct 18, 2024
@dav-sea dav-sea pinned this issue Dec 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants