- Home /
Using GUI.FocusControl on TextField selects all text
I'm attempting to work around the "deselect control when adding new GUI elements".... behavior.
I go the reselection to work fine, but when I reselect the TextField with GUI.FosucControl, the cursor position is lost, and the text in the TextField is all selected.
Is there anyway to automatically set the cursor position and current selection data, so that when I do refresh, the user is unaware?
(Alternatively, a way to keep focus on the control while creating new GUI elements would work fine as well.)
I've also been trying to find a solution to this. Any assistance would be great! :)
I've also been trying to find a solution to this. Any assistance would be great! :)
Well, I can't give you an answer... ultimately I had to rewrite the TextField behavior from scratch.
Answer by fabr.IQ · Feb 25, 2013 at 07:22 PM
Here's what I did:
private int lastCursorPos = 0;
private int lastSelectCursorPos = 0;
private bool needsRefocus = false;
void OnGUI()
{
GUI.SetNextControlName("myTextField");
Text = GUI.TextField(textRect, Text, maxLength);
TextEditor te = (TextEditor)GUIUtility.GetStateObject(typeof(TextEditor), GUIUtility.keyboardControl);
if (needsRefocus)
{
needsRefocus = false;
GUI.FocusControl("myTextField");
//needs to be redefined after setting the FocusControl
te = (TextEditor)GUIUtility.GetStateObject(typeof(TextEditor), GUIUtility.keyboardControl);
if (te != null)
{
//these two lines prevent a "select all" effect on the textfield which seems to be the default GUI.FocusControl behavior
te.pos = lastCursorPos; //set cursor position
te.selectPos = lastSelectCursorPos; //set selection cursor position
}
}
if (te != null)
{
lastCursorPos = te.pos; //get cursor position on each update
lastSelectCursorPos = te.selectPos; //get selection cursor position on each update
}
}
Your solution almost worked for me. I was not aware of the TextEditor or GUIUtility things.
basically i had to replace your 2 lines that set the cursur to the end by these two lines
te.SelectNone();
te.$$anonymous$$oveTextEnd();
then it worked for me
Thanks, a combination of everyones answers and replies helped me fix my problem :)
Answer by TheDemiurge · Mar 02, 2016 at 02:11 AM
Old question, I know, but I found that the answer above did not work exactly, not for Unity5.3.x anyway. My solution is to first focus on the control I want, and only then draw the control itself.
Example code:
// the following code will attempt to focus on the first control ("My Text") as long as the user hasn't focused on the second control
// all this inside OnGUI ()
TextEditor te;
GUI.SetNextControlName ( "My Text" );
// this first part checks if nothing is focused, and focuses on the My Text control
if ( GUI.GetNameOfFocusedControl () != "My Text" && GUI.GetNameOfFocusedControl () != "Other Text" )
{
GUI.FocusControl ( "My Text" );
}
myText = GUILayout.TextField ( myText );
GUI.SetNextControlName ( "Other Text" );
myOtherText = GUILayout.TextField ( myOtherText );
// this one is for when tabbing between the two controls
if ( GUI.GetNameOfFocusedControl () == "My Text" )
{
te = GUIUtility.GetStateObject ( TextEditor, GUIUtility.keyboardControl );
if ( GUI.GetNameOfFocusedControl () != lastFocusedControl )
{
te.cursorIndex = lastTextPosition;
te.selectIndex = lastTextSelectPosition;
} else
{
lastTextPosition = te.cursorIndex;
lastTextSelectPosition = te.selectIndex;
}
}
lastFocusedControl = GUI.GetNameOfFocusedControl ();
Answer by banniandoko · Nov 17, 2016 at 12:09 PM
GUI.FocusControl("MyTextField");
editor = (TextEditor)GUIUtility.GetStateObject(typeof(TextEditor), GUIUtility.keyboardControl);
editor.OnFocus();
editor.cursorIndex = 0 ; //CursorStartPosition;
editor.selectIndex = 56; //cursor selected end position.. it will selecting the text from 0 to 56 (cursorindex)
Answer by THplusplusx · May 24, 2017 at 07:38 AM
This snippet should prevent auto-select-all for any text based input field (tested with TextArea and IntField).
private T WithoutSelectAll<T>(Func<T> guiCall)
{
bool preventSelection = (Event.current.type == EventType.MouseDown);
Color oldCursorColor = GUI.skin.settings.cursorColor;
if (preventSelection)
GUI.skin.settings.cursorColor = new Color(0, 0, 0, 0);
T value = guiCall();
if (preventSelection)
GUI.skin.settings.cursorColor = oldCursorColor;
return value;
}
Use like:
int foo;
string bar;
foo = WithoutSelectAll(() => GUI.IntField("foo", foo));
bar = WithoutSelectAll(() => EditorGUILayout.TextArea(bar));
Your answer
Follow this Question
Related Questions
TextField not getting focus on iOS 1 Answer
TextField, Event.current, Input.GetKey, and GUI.FocusControl locking 1 Answer
GUI.FocusControl & GUI.SetNextControlName doesn't work 2 Answers
Text fields where text will scale along with resolution. 1 Answer
GUI custom textfield cursor rendering 2 Answers