可拖动分割条在 Unity3D 的编辑器结构中一般都属于最外层结构,因为它是基于 GUI 组件,计算位置的时候必须要很精确,所以跟Layout 流式布局混编会比较乱。这里也推荐作为最外层结构使用。

可拖动的分割条

DEMO

下面是我写的一个演示例子 你可以在Unity中直接运行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
//
// Copyright 2017 KeyleXiao.
// Contact : Keyle_xiao@hotmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

using UnityEditor;
using UnityEngine;

namespace SmartDataViewer.Editor
{

public class ExportWizard:EditorWindow
{
[MenuItem("SmartDataViewer/ExportWizard")]
static public void OpenView()
{
var w = CreateInstance<ExportWizard >();

w.minSize = new Vector2(350,250);
w.maxSize = w.minSize;
Vector2 pos =new Vector2( Screen.width/2-w.minSize.x,Screen.height/2-w.minSize.y);
w.position = new Rect(pos,w.minSize);

w.ShowUtility();
}


private object rawData { get; set; }

public void InitRawData(object data)
{
rawData = data;
}



private Vector2 scrollPos = Vector2.zero;
float currentScrollViewWidth;
bool resize = false;
Rect cursorChangeRect;

void OnEnable(){
this.position = new Rect(200,200,400,300);
currentScrollViewWidth = this.position.width/2;
cursorChangeRect = new Rect(currentScrollViewWidth,0,4f,this.position.height);
}

void OnGUI(){
GUILayout.BeginHorizontal();

scrollPos = GUILayout.BeginScrollView(scrollPos,GUILayout.Width(currentScrollViewWidth));
for(int i=0;i<20;i++)
GUILayout.Label("test content");
GUILayout.EndScrollView();

ResizeScrollView();

GUILayout.Label("right part");
GUILayout.EndHorizontal();
Repaint();
}

private void ResizeScrollView(){
GUI.DrawTexture(cursorChangeRect,EditorGUIUtility.whiteTexture);
EditorGUIUtility.AddCursorRect(cursorChangeRect,MouseCursor.ResizeHorizontal);

if( Event.current.type == EventType.MouseDown && cursorChangeRect.Contains(Event.current.mousePosition)){
resize = true;
}
if(resize){
currentScrollViewWidth = Event.current.mousePosition.x;
cursorChangeRect.Set(currentScrollViewWidth,cursorChangeRect.y,cursorChangeRect.width,cursorChangeRect.height);
}
if(Event.current.type == EventType.MouseUp)
resize = false;
}


}
}

解析

这里的GUI仅仅是做了一个表现,最核心的其实是 cursorChangeRect 因为你即使不要这个 GUI 也能在这个 Rect 的位置进行拖动。

1
GUI.DrawTexture(cursorChangeRect,EditorGUIUtility.whiteTexture);

在鼠标移动的同时将鼠标当前 x 轴的位置赋前面的一个layout,就会推动后面一个layout. (流式布局)