Search Unity

Focus doesn't seem to work

Discussion in 'UI Toolkit' started by XGT08, May 29, 2020.

  1. XGT08

    XGT08

    Joined:
    Aug 1, 2013
    Posts:
    1,905
    Hello,

    I have a list of items inside a scrollview represented as labels. When I double click an item, I want to be able to rename it, so I registered a handler for the MouseDownEvent event in which I disable the label and enable the text field. All works really well.

    However, I am trying to shift the focus to the text field. This is because when the text field appears, I would like the user to be able to start writing stuff in the text field.

    I tried:
    textField.Focus();
    textField.SelectAll();

    OR

    textField.Focus();
    textField.SelectRange(...);

    However, nothing seems to happen. I need to first click on the text field to give it focus and then I can start writing stuff into it.

    Thanks,
    Andrew
     
  2. silenterus

    silenterus

    Joined:
    Nov 8, 2019
    Posts:
    10
    try
    Code (CSharp):
    1. textField.ElementAt(0).Focus()
    and if this doesn't work try this from you root window
    Code (CSharp):
    1. rootVisualElement.schedule.Execute(() => {
    2.                     testField.ElementAt(0).Focus();
    3.                 });
     
    infotronsim, Rowlan and XGT08 like this.
  3. XGT08

    XGT08

    Joined:
    Aug 1, 2013
    Posts:
    1,905
    Wonderful! It works. The first option works really well for me.

    Amazingly enough, the second option solves another issue I was having with calling ScrollView.ScrollTo(). When processing key events, it seems that it is ignored. Scheduling works though.

    Thanks a lot!
     
  4. CyrilGhys

    CyrilGhys

    Joined:
    Nov 1, 2018
    Posts:
    29
    Hello ! Thanks for the suggestions selenterus

    However this didn't work for me, I had to do the following :
    I actually added one more thing to make it work (focusable), so my VisualElement script looks like this now :

    Code (CSharp):
    1. public Node(Vector2 position)
    2.         {
    3.             // SETUP
    4.             var visualTreeAsset = Resources.Load<VisualTreeAsset>("UI/Node");
    5.             visualTreeAsset.CloneTree(this);
    6.  
    7.             style.left = position.x;
    8.             style.top = position.y;
    9.             this.Q("core").focusable = true;
    10.             this.Q("core").Focus();
    11.             BringToFront();
    12.  
    13.             // CALLBACKS
    14.             RegisterCallback<MouseDownEvent>(evt =>
    15.             {              
    16.                 if ((evt.pressedButtons & 1) == 1)
    17.                 {
    18.                     Debug.Log("Left click on node");
    19.                     this.Q("core").Focus();
    20.                     BringToFront();
    21.                     evt.StopPropagation();
    22.                 }
    23.             });
    24.         }

    "Core" is not the 1st element in my hierarchy, so I assume that when we simply do Focus(), it doesn't propagate through the children ?
    I tried to use delegatesFocus, which sounds like something that could spread Focus() through children, but I got the error "InvalidOperationException: delegatesFocus should only be set on composite roots.". Does anyone know what it meands and how to work our way around ? I tried to do myEditorWindow.delegatesFocus = true but this is the same.
     

    Attached Files:

    silenterus likes this.
  5. silenterus

    silenterus

    Joined:
    Nov 8, 2019
    Posts:
    10
    yeah your option is more reliable
    here's another one that should also work better

    Code (CSharp):
    1.       textField.Q(TextInputBaseField<string>.textInputUssName).Focus();
    2.  
    Not really.
     
    CyrilGhys likes this.
  6. CyrilGhys

    CyrilGhys

    Joined:
    Nov 1, 2018
    Posts:
    29
    Ohhh okay, more info here (useful for me and hopefullt for some other people) :

    So yeah, in order to make an element focusable you have to explicitly say it. And then you don't have to call visualElement.Focus() directly, you have to call it from a AttachToPanelEvent you make your visualElement registered to.

    Thank you @antoine-unity !! (This should be in the documentation though :()
     
    silenterus likes this.
  7. Denis-535

    Denis-535

    Joined:
    Jun 26, 2022
    Posts:
    34
    You can focus the first focusable child via the "delegatesFocus" property.
    Code (CSharp):
    1.  
    2. view.focusable = true;
    3. view.delegatesFocus = true;
    4. view.Focus();
    5. view.focusable = false;
    6.