- Home /
Editor - GUILayout.BeginArea does not expand ScrollView
I'm trying to write a node-based editor with some draggable panels in it, a bit like https://www.youtube.com/watch?v=gHTJmGGH92w
The problem I'm having is that when I resize the editor I'd like the area which contains the nodes to scroll but I can't get it to work :( If I place an Area inside a ScrollView it doesn't expand the scroll area to accomodate it (like in my image above) if the ScrollView is say 500 x 500 pixels and I place an Area at position 700,700 with a width of 100 x 100 then I'd expect the scroll area to expand to 800 x 800 but it doesn't :( The only way I found to get around it is to place a hacky Label inside with size 800 x 800.
Consider the following code for a basic editor window. The window should contain a fixed area at position (600,500) with width and height 64 pixels, inside a scrollable area of size (500,400):
public class TestEditor : EditorWindow
{
Vector2 scrollPos = Vector2.zero;
[MenuItem("Window/Test")]
public static void Init()
{
var window = EditorWindow.GetWindow(typeof(TestEditor));
window.ShowTab();
}
void OnGUI()
{
scrollPos = GUILayout.BeginScrollView(scrollPos, true, true, GUILayout.Width(500), GUILayout.Height(400));
{
GUILayout.BeginArea(new Rect(600, 500, 64, 64), GUI.skin.GetStyle("box"));
GUILayout.EndArea();
}
GUILayout.EndScrollView();
}
}
The problem is that the ScrollView doesn't seem to acknowledge the existence of the Area inside it.. the horizontal scrollbar stays fixed at 500 pixels, and the vertical one is fixed at 400 pixels though it has around 10 pixels of scrollable area. I would expect the scrollable area to expand to include the Area (I'm aiming to be able to drag the area around but constrain it to a scrollable panel).
Is there any way I can make this work without some dodgy hack?
Any ideas? Its a bit of a showstopper at the moment
Thanks in advance :)
This is driving me nuts... the only workaround I've found is to add a blank Label with a fixed height and width which I'll have to keep updating as the Areas are dragged around. It seems like a bug to me.
Answer by Symo7 · Oct 10, 2015 at 01:29 PM
I finally fixed this using the Label idea above. Using this.position it will adjust properly when the window is resized -
float width = this.position.width
float height = this.position.height;
float viewWidth = 1024;
float viewHeight = 768;
scrollPos = GUILayout.BeginScrollView(scrollPos, GUILayout.Width(width), GUILayout.Height(height));
{
GUILayout.Label("", GUILayout.Width(viewWidth), GUILayout.Height(viewHeight));
PaintNodes();
}
GUILayout.EndScrollView();
From your given code it's not clear how you actually draw your nodes. However i guess that they at least have a fix position within the scrollarea. In that case using GUILayout is the problem. When you use GUILayout, the system will positioning it's containing elements automatically. BeginArea is not ment to be nested. BeginArea actually starts a new layout area. That area itself is not "layouted" since it has a fix position and size.
So you might want to use GUI.BeginScrollView ins$$anonymous$$d. I once made a node based editor in Unity. I didn't use a ScrollView at all. I simply used a single GUI.BeginGroup and each node was a GUILayout.BeginArea. The position was actually represented by gameobjects. I first used custom classes, but since i wanted boundless zoo$$anonymous$$g and scrolling it was way easier to use the Transform hierarchy. That way you can simply pan the workspace gameobject (which is the top parent) around.
Btw: It seems you don't have any menu elements outside your scrollview. If you want to add those when using a GUI.BeginScrollView, you can simply do it like this:
void OnGUI()
{
GUILayout.BeginVertical();
DrawLayouted$$anonymous$$enu();
Rect workArea = GUILayoutUtility.GetRect(10, 10000, 10, 10000);
scrollPos = GUI.BeginScrollView(workArea, scrollPos, viewSize, true, true);
DrawNodes();
GUI,EndScrollView();
GUILayout.EndVertical;
}
Here "viewSize" would be your desired virtual view area. "workArea" (the visible area) will be calculated by the layoutsystem. You could specify fix sized rects, based on content or, like i did here, specify a $$anonymous$$ and max size. In that case it's size is calculated from the "left over space" that is shared between all variable sized elements in the same group. If it's the only element with variable size it will use as much as available.
All GUILayout methods actually use some version of GUILayoutUtility.GetRect and then call the equivalent GUI.XXX method with the returned Rect. The layout system simply has been built around the normal gui element methods.
Thanks - I stripped the actual node drawing out for simplicity but they are drawn using BeginArea / EndArea, didn't know they couldn't be nested inside other things, but makes sense from your description (but not from the Unity docs :( ). I will try using GUI ins$$anonymous$$d of GUILayout,.. The Label trick works pretty well though (even with a toolbar above it) but it is a bit of a hack.
For the work area, I take the list of Area nodes and work out the furthest right / bottom edge and make that the area size.
Your answer
![](https://koobas.hobune.stream/wayback/20220612040004im_/https://answers.unity.com/themes/thub/images/avi.jpg)