Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Checking for GUI focus

Discussion in 'Immediate Mode GUI (IMGUI)' started by CoherentInk, Mar 6, 2008.

  1. CoherentInk

    CoherentInk

    Joined:
    Jul 16, 2006
    Posts:
    216
    Is there a way to check to see if a GUI object (window, text field, etc) has focus? I don't need to know what item specifically, I just need to know if any GUI object has focus.

    I'm looking for a way to do this so that I can determine whether I should be catching Input keypresses for commands or for typing in a text field.

    I've tried a generic test with GUIUtility.keyboardControl but once a field gets focus, I can't get it to focus on anything but other windows, which means that my script isn't processing any commands.
    Code (csharp):
    1. void Update () {
    2.     if (GUIUtility.keyboardControl == 0) {
    3.         // process keystrokes as commands
    4.     }
    5. }
    I'd like to avoid this if at all possible as it would be better if the Input simply ignored keystrokes until focus moved away from a text field or other GUI element. I also can't get it to focus on anything but text fields at the moment either, but that's another issue...

    Any suggestions?
     
  2. SWGraham

    SWGraham

    Joined:
    Mar 10, 2008
    Posts:
    49
    Wow, this is totally my question too. I have in-game chat, and when I click on the chat text field to type, every key also makes it to the InputManager and makes my guy jump and run and flip. If Input.GetButtonDown would just say False when a text box had focus I'd be delighted, but I'd settle for being able to ask if my text box has focus so I can add in a " !TextBoxHasFocus" to my own command handlers.
     
  3. SWGraham

    SWGraham

    Joined:
    Mar 10, 2008
    Posts:
    49
    Oh, and to clarify, GUIUtility.keyboardControl == 0 didn't work because while it is indeed non-zero while a text entry has focus, it doesn't go back to zero [Edit: because it won't give up focus when you click somewhere else].
     
  4. shaun

    shaun

    Joined:
    Mar 23, 2007
    Posts:
    728
    I was having a similar issues. I found that I could solve my problems with text entry controls by using GUI.DoTextField, which is the method used by the TextField and TextArea. The point is, it accepts an int as the control ID, which you can keep track of using GUIUtility.GetControlID and assigning it to your own local variable.
    Also, GUIUtility.keyboardControl can be set to 0 to remove the focus from all text fields, or to assign it to your favorite field.

    Code (csharp):
    1.     //C#
    2.     public int curKeyboardControl;
    3.     private GUIContent myText1 = new GUIContent("Test Field");
    4.     private GUIContent myText2 = new GUIContent("Test Field1");
    5.     private GUIContent myText3 = new GUIContent("Test Field2");
    6.     private bool DoRemoveFocus = false;
    7.     void OnGUI()
    8.     {
    9.         if (DoRemoveFocus)
    10.         {
    11.             GUIUtility.keyboardControl = 0;
    12.             DoRemoveFocus = false;
    13.         }
    14.         curKeyboardControl = GUIUtility.keyboardControl;
    15.         GUI.Label(new Rect(310, 10, 100, 100), "Current\nKeyCtrl: " + curKeyboardControl.ToString(),"box");
    16.         if (GUI.Button(new Rect(410, 10, 100, 100), "Remove Focus")) DoRemoveFocus = true;
    17.         int TextField1ID = GUIUtility.GetControlID(FocusType.Keyboard);
    18.         GUI.DoTextField(new Rect(10, 10, 100, 100), TextField1ID, myText1, true, 200, "TextArea");
    19.         int TextField2ID = GUIUtility.GetControlID(FocusType.Keyboard);
    20.         GUI.DoTextField(new Rect(110, 10, 100, 100), TextField2ID, myText2, true, 200, "TextArea");
    21.         int TextField3ID = GUIUtility.GetControlID(FocusType.Keyboard);
    22.         GUI.DoTextField(new Rect(210, 10, 100, 100), TextField3ID, myText3, true, 200, "TextArea");
    23.     }
    btw you must give a GUIContent variable to the DoTextField because its passed by ref, otherwise you can't edit your text, and then its not really a textfield.
     
    forestrf likes this.
  5. SWGraham

    SWGraham

    Joined:
    Mar 10, 2008
    Posts:
    49
    How about this for hack-fu:

    Code (csharp):
    1. if( Input.GetMouseButtonDown( 0 )  GUIUtility.hotControl == 0 )
    2.             GUIUtility.keyboardControl = 0;
    3.  
    So that's "If the mouse is pressed and no widget that accepts input is the target of that press, then clear who has focus." Now I can click in a text field and type, and then when I click out of the text field it coughs up the focus. Now my game commands can check keyboardControl for non-zero and choose to not do anything while you are typing. I think that applies to the OP's problem too. Maybe not entirely. Still good fields to know about.
     
  6. shaun

    shaun

    Joined:
    Mar 23, 2007
    Posts:
    728
    Nice solution. I needed to figure out if a button or textfield in a particular form had focus (to do those nice "Enter Password Here" kind of textfields) which is probably overkill here. For simple GUI, hack-fu rocks.
     
  7. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,307
    That looks cool - focus handling in UnityGUI has been giving me quite a bad time recently (I need to be able to focus and unfocus textfields on clicks and key-presses).

    Is there any way to use DoTextField with GUILayout? That would solve quite a few issues for me...
     
  8. shaun

    shaun

    Joined:
    Mar 23, 2007
    Posts:
    728
    Haven't tested it, but try:

    Code (csharp):
    1. GUI.DoTextField(GUILayoutUtility.GetRect(content, style, options), id, content, multiline, length, style);
    The layouting system should pass the correct Rect back, in theory.
     
  9. Michael-Ryan

    Michael-Ryan

    Joined:
    Apr 10, 2009
    Posts:
    184
    I'm curious. How did you determine DoTextField was used by those text controls?

    After reading this post, I used Google to search the entire unity3d.com site for "DoTextField" and it only turned up a few forum posts, including this one.

    Are there scripts for all the runtime classes that can be examined? If so, where are they?
     
  10. shaun

    shaun

    Joined:
    Mar 23, 2007
    Posts:
    728
    Hi,

    By reflecting the UnityEngine.dll and analyzing the GUI classes there.

    http://www.red-gate.com/products/reflector/

    Best regards
    Shaun
     
  11. Veehmot

    Veehmot

    Joined:
    Oct 26, 2008
    Posts:
    27
    Sorry to revive this old thread, but DoText is now protected. Is there any workaround to this? Should we create a new class inherited from GUI?