- Home /
Drawing several BeginArea inside a BeginScrollview (GUILayout) produces an unexpected behaviour
Well, I have a question with a GUILayout.BeginArea within a BeginScrollview.
if (m_searchedItems?.Length > 0)
{
m_scroll = GlobalGUI.BeginScrollView(f_isEditor, m_scroll, viewSize);
for (int y = 0; y < rows; ++y)
{
GUILayout.BeginHorizontal();
for (int x = 0; x < columns; ++x)
{
// Show items thumbnails...
var tTexture = GetThumbnail(item);
Rect? texRect = null;
if (tTexture != null) // Check if the texture is available or it's being requested
texRect = GlobalGUILayout.DrawTexture(tWidth, tHeight, tTexture);
// The method from above returns an Nullable<Rect> of the texture. (https://i.imgur.com/pizrwji.png)
if (texRect.HasValue)
{
// Show title w/ marquee
// .... Code ....
var btnsRect = new Rect(texRect.Value.position + Vector2.up * (tHeight - 26), new Vector2(texRect.Value.width, 21));
// Show buttons
GUILayout.BeginArea(btnsRect, "aaaaa"); // "aaaaa" string is for a test
{
GUILayout.BeginHorizontal();
if (GUILayout.Button(m_infoTexture, GUILayout.Width(21)))
GetInfo(item);
if (GUILayout.Button("Install"))
DoInstall(item);
GUILayout.EndHorizontal();
}
GUILayout.EndArea();
}
}
GUILayout.EndHorizontal();
}
GlobalGUI.EndScrollView(f_isEditor);
}
As you can see, I am trying to show a list of items within said BeginScrollview:
Of course, each must have two buttons to perform actions (line 30 of the code).
But, as you can see, in the image that I have attached, I have blueed the test string "aaaaa" so you can see that it is very highlighted, which gives me to understand that all the BeginArea are being drawn in the same position.
But what worries me most about this is that the buttons aren't displayed.
However, if all this is implemented with the GUI class, instead of the GUILayout class this does not happen.
Which could be the problem?
Answer by Bunny83 · Apr 26, 2019 at 04:13 AM
You have the wrong idea about "GUILayout.BeginArea". BeginArea is actually a GUI method that starts a new layout context and does not belong inside a layouted context. BeginArea block are not layouted themselfs. They are essentially wrappers for GUI.BeginGroup.
So inside a layouted area you never want to use GUILayout.BeginArea. If you need groups inside a layouted area you should use BeginHorizontal / BeginVertical only. If you need to draw things on top of each other you probably should use normal GUI to do this.
I have no idea what the "GlobalGUI" and "GlobalGUILayout" are and what functionality they provide. Keep in mind that during the layout stage the rectangles of the layouted elements are not yet available. If you read GUILayoutUtility.GetLastRect it will return nonsense (a constant value) during the layout phase. That's why you can not nest a GUILayout section inside a GUI section inside a GUILayout section. The layout system can not possibly resolve all the rects in one layout step.
You may want to have a look at my IMGUI crash course (Get a more readable version on github since UA messed up their markdown renderer). Of course the IMGUI system is too complex to cover all topics and all cases in detail. However I might add one day a bit more about the "behind the scenes" of the layout system.