private int DrawItem(Rect area, TreeViewItem item, int index, int depth) { bool selected = selection.Contains(item.Tag); Rect itemRegion = new Rect(0, (index * TreeViewItem.HEIGHT) - (scroll * TreeViewItem.HEIGHT), area.width, TreeViewItem.HEIGHT * item.Count); if (ItemDrawBackground != null) { ItemDrawBackground(item, itemRegion); } item.DrawBackground(itemRegion, depth, selected); if (ItemDraw != null) { ItemDraw(item, itemRegion); } if (Event.current.type == EventType.MouseDown) { if (Event.current.button == 0) { if (Event.current.clickCount == 1 && SelectionClicked != null) { SelectionClicked(); } if (Event.current.clickCount == 2 && SelectionDoubleClicked != null) { SelectionDoubleClicked(); } } else if (Event.current.button == 1) { if (SelectionRightClicked != null) { SelectionRightClicked(); } } if (!item.Editing && Event.current.button == 0) { if (item.Items.Count > 0) { Rect openRegion = new Rect(itemRegion.x + (depth * TreeViewItem.HEIGHT / 2), itemRegion.y, TreeViewItem.HEIGHT, TreeViewItem.HEIGHT); if (openRegion.Contains(Event.current.mousePosition)) { item.Open = !item.Open; Event.current.Use(); repaint = true; } } if (Event.current.type != EventType.Used && item.Enabled && item.Selectable) { Rect mouseRegion = new Rect(itemRegion.x, itemRegion.y, itemRegion.width, TreeViewItem.HEIGHT); if (mouseRegion.Contains(Event.current.mousePosition)) { Select(index, item.Tag); Event.current.Use(); } if (selection.Contains(item.Tag)) { Dragged = true; } } } } else if (Event.current.type == EventType.MouseUp) { dragging = false; Dragged = false; } else if (Event.current.type == EventType.MouseDrag && Dragged) { Rect mouseRegion = new Rect(itemRegion.x, itemRegion.y, itemRegion.width, TreeViewItem.HEIGHT); if (mouseRegion.Contains(Event.current.mousePosition)) { DragAndDrop.PrepareStartDrag(); List <UnityEngine.Object> objs = new List <UnityEngine.Object>(); foreach (object o in selection) { if (o is UnityEngine.Object) { objs.Add(o as UnityEngine.Object); } } DragDropWrapper wrapper = new DragDropWrapper("TreeView", selection); DragAndDrop.objectReferences = objs.ToArray(); DragAndDrop.SetGenericData("TreeView", wrapper); DragAndDrop.StartDrag("TreeView"); DragAndDrop.visualMode = DragAndDropVisualMode.Move; dragging = true; Dragged = false; mayEdit = false; if (item.Editing) { item.Editing = false; } Event.current.Use(); } } else if (Event.current.type == EventType.DragUpdated && CanDrop) { Rect mouseRegion = new Rect(itemRegion.x, itemRegion.y + 1, itemRegion.width, TreeViewItem.HEIGHT - 2); if (mouseRegion.Contains(Event.current.mousePosition) && !selection.Contains(item.Tag)) { item.Highlighted = true; item.InBetween = false; } else { item.Highlighted = false; if (canDropInBetween) { Rect inBetweenRect = new Rect(itemRegion.x, itemRegion.y - 1, itemRegion.width, 2); if (inBetweenRect.Contains(Event.current.mousePosition)) { item.InBetween = true; } else { item.InBetween = false; } } } repaint = true; } else if (Event.current.type == EventType.DragPerform && CanDrop) { dragging = false; if (item.Highlighted || item.InBetween) { target = item.Tag; inBetween = item.InBetween; Event.current.Use(); } } else { Rect mouseRegion = new Rect(itemRegion.x, itemRegion.y, itemRegion.width, TreeViewItem.HEIGHT); if (mouseRegion.Contains(Event.current.mousePosition)) { mouseHover = index; } } if (mayEdit && index == mouseHover) { mayEdit = false; Dragged = false; item.Editing = true; } item.Draw(itemRegion, depth, selected); index++; if (item.Open) { foreach (TreeViewItem child in item.VisibleItems) { index = DrawItem(area, child, index, depth + 1); } } return(index); }
public bool Draw(Rect region) { height = region.height; float visibleCount = height / TreeViewItem.HEIGHT; int count = Count; if (visibleCount < count) { if (Event.current != null && Event.current.type == EventType.ScrollWheel && region.Contains(Event.current.mousePosition)) { scroll += Event.current.delta.y; scroll = Mathf.Clamp(scroll, 0, count); repaint = true; } float half = SCROLLBAR_WIDTH / 2; Rect scrollbar; if (scrollbarRight) { scrollbar = new Rect(region.xMax - half, region.y, SCROLLBAR_WIDTH, region.height); } else { scrollbar = new Rect(region.xMin, region.y, SCROLLBAR_WIDTH, region.height); } scroll = GUI.VerticalScrollbar(scrollbar, scroll, visibleCount, 0, count); if (scrollbarRight) { region = new Rect(region.x, region.y, region.width - half, region.height); } else { region = new Rect(region.x + half, region.y, region.width - half, region.height); } } GUILayout.BeginArea(region); int index = 0; foreach (TreeViewItem item in visibleItems) { index = DrawItem(region, item, index, 0); } GUILayout.EndArea(); // Outside the list of object if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && region.Contains(Event.current.mousePosition)) { if (!AlwaysSelect && OutsideClickUnselect) { selection.Clear(); if (SelectionChanged != null) { SelectionChanged(); } } } else if (Event.current.type == EventType.DragUpdated && CanDrop) { object data = DragAndDrop.GetGenericData("TreeView"); if (data != null && data is DragDropWrapper) { DragDropWrapper wrapper = data as DragDropWrapper; if (wrapper.Type == "TreeView") { DragAndDrop.visualMode = DragAndDropVisualMode.Move; if (new Rect(region.x, region.y, region.width, TreeViewItem.HEIGHT).Contains(Event.current.mousePosition)) { timer = EditorApplication.timeSinceStartup + DRAG_SCROLL_DELAY; scroll = Mathf.Clamp(scroll - 1, 0, count); } else if (new Rect(region.x, region.yMax - TreeViewItem.HEIGHT, region.width, TreeViewItem.HEIGHT).Contains(Event.current.mousePosition)) { timer = EditorApplication.timeSinceStartup + DRAG_SCROLL_DELAY; scroll = Mathf.Clamp(scroll + 1, 0, count); } } } } else if (CanDrop && (Event.current.type == EventType.DragPerform || (target != null && CanDropOnSelf))) { if (DragDropped != null) { DragDropped(this, new DragEventArgs(target, inBetween, selection.ToArray())); } target = null; Event.current.Use(); TurnOffHighlight(visibleItems); } else if (Event.current.type == EventType.DragExited) { TurnOffHighlight(visibleItems); } if (repaint) { repaint = false; return(true); } else { return(false); } }