I’d swear there is some sort of function to return the screen postition of a GUI object - such as a button created with GUILayout (in which case you would not know its position since its set automatically by the system).
Does anyone know of anything or have any clever ideas on how to write something?
If you take a look at the code, you can see that I am trying to establish the position of a new window based on the last Rect used. Oddly, the print statement shown indicates that for the first 3 cycles (frames I guess), windowRect evaluates to Rect(0,0,1,1) which I assume is just a system default. Then it cycles back and forth between what I would expect - in this case Rect(10,59,176,15) and the Rect(0,0,1,1). The result is that my new window is displayed at Rect(0,0,1,1).
What’s going on here? Thanks!
static var displayDropDown : boolean = false;
static var dropDownIndex : int;
static var dropDownSelections : String[];
static var windowRect = Rect(300,300,300,300);
static function labeledDropDown (label : String, selectionGridInt : int, selectionStrings : String[])
{
dropDownSelections = selectionStrings;
BeginHorizontal();
Label(label);
GUI.color = Color.white;
if (Button(selectionStrings[selectionGridInt],GUIStyle("dropDownField")))
{
displayDropDown = true;
}
if (Button("",GUIStyle("dropDownArrow")))
{
displayDropDown = true;
}
EndHorizontal();
if (displayDropDown == true)
{
windowRect = GUILayoutUtility.GetLastRect();
print(windowRect);
windowRect = GUILayout.Window(0,windowRect,buildDropDownWindow,"",GUIStyle("dropDownWindow"));
}
if (dropDownIndex!=null)
{
return dropDownIndex;
}
}
static function buildDropDownWindow (windowID : int)
{
for (i=0; i < dropDownSelections.length; i++)
{
if (GUILayout.Button(dropDownSelections[i],GUIStyle("dropDownButton")))
{
dropDownIndex = i;
displayDropDown = false;
}
}
}
Not to thread-hijack, but I’m having an issue with GUILayoutUtility.GetLastRect() as well.
I’m trying to get the location of an element within a scrollview. Specifically I have a scrollview with a list of objects inside it - each object represented as a button with a special style on it. Clicking on each item expands/contracts it (more/less information visible about that object).
Anyway, I’m trying to build a function that will allow my team to open directly to one of the objects in the scrollview. So far it looks like this:
windowFunction(){
if (we have a new scrollposition)
scrollposition.y = our new awesome scroll position
scrollposition = new GUILayout.BeginScrollView(scrollview, false, true)
bigLoopWhichDrawsMyButtons
{
If (buttonYEAH!)
{ do button stuff }
if (I just drew the button I want to open up to)
{ newScrollPosition = GUILayoutUtility.GetLastRect().y; }
}
}
It’s properly resetting the scrollview to the value it receives from GetLastRect() - the problem is GLR() is returning 0,0,1,1 every time. Can it just not be used from inside a scrollview maybe? I was hoping it would return the location of the last rect within that scrollview.
For what its worth, I have a work-around for my problem. Since, in my case, the problem seems to be that GetLastRect() is waffling between the “real” position and what looks like the default (Rect(0,0,1,0)), I am just doing a simple check on the x value of what’s returned and if this is not zero, I lock it down (i.e. dont recalc with each frame).
I’d love to know what’s really going on here. This is not a clean solution in my opinion …
static var displayDropDown : boolean = false;
static var dropDownIndex : int;
static var dropDownSelections : String[];
static var windowRect = Rect(300,300,300,300);
static var rectSet : boolean = false;
static function labeledDropDown (label : String, selectionGridInt : int, selectionStrings : String[])
{
dropDownSelections = selectionStrings;
BeginHorizontal();
Label(label);
GUI.color = Color.white;
if (Button(selectionStrings[selectionGridInt],GUIStyle("dropDownField")))
{
displayDropDown = true;
}
if (Button("",GUIStyle("dropDownArrow")))
{
displayDropDown = true;
}
if (rectSet==false)
{
var tempRect = GUILayoutUtility.GetLastRect();
if (tempRect.x != 0)
{
windowRect = Rect(tempRect.x+15,tempRect.y,1,1);
rectSet = true;
print(windowRect);
}
}
EndHorizontal();
if (displayDropDown == true)
{
windowRect = GUILayout.Window(0,windowRect,buildDropDownWindow,"",GUIStyle("dropDownWindow"));
}
if (dropDownIndex!=null)
{
return dropDownIndex;
}
}
static function buildDropDownWindow (windowID : int)
{
for (i=0; i < dropDownSelections.length; i++)
{
if (GUILayout.Button(dropDownSelections[i],GUIStyle("dropDownButton")))
{
dropDownIndex = i;
displayDropDown = false;
}
}
}
It appears that the value returned by GetLastRect is only correct following a Repaint event. You can check for that in the code with something like the following:-
if (Event.current.type == EventType.Repaint) {
var r = GUILayout.GetLastRect();
...
}