public static void TitleAndList(Rect position, string title, IReorderableListAdaptor adaptor, SerializedProperty target) { position.height = 20; Title(position, title); position.y += 20; float totalHeight = 22; for (int i = 0; i < adaptor.Count; i++) { totalHeight += adaptor.GetItemHeight(i); } position.height = totalHeight; ListFieldAbsolute(position, target); }
/// <summary> /// Draw list container and items. /// </summary> /// <param name="position">Position of list control in GUI.</param> /// <param name="controlID">Unique ID of list control.</param> /// <param name="adaptor">Reorderable list adaptor.</param> private void DrawListContainerAndItems(Rect position, int controlID, IReorderableListAdaptor adaptor) { // Get local copy of event information for efficiency. EventType eventType = Event.current.GetTypeForControl(controlID); Vector2 mousePosition = Event.current.mousePosition; //if (Event.current.isMouse) // s_MousePosition = GUIUtility.GUIToScreenPoint(mousePosition); int newTargetIndex = s_TargetIndex; // Position of first item in list. float firstItemY = position.y + ContainerStyle.padding.top; switch (eventType) { case EventType.MouseDown: if (_tracking) { // Cancel drag when other mouse button is pressed. s_TrackingCancelBlockContext = true; Event.current.Use(); } break; case EventType.MouseDrag: if (_tracking) { // Reset target index and adjust when looping through list items. if (mousePosition.y < firstItemY) newTargetIndex = 0; else if (mousePosition.y >= position.yMax) newTargetIndex = adaptor.Count; s_DragItemPosition.y = Mathf.Clamp(mousePosition.y + s_AnchorMouseOffset, firstItemY, position.yMax - s_DragItemPosition.height - 1); } break; case EventType.MouseUp: if (controlID == GUIUtility.hotControl) { // Allow user code to change control over reordering during drag. if (!s_TrackingCancelBlockContext && _allowReordering) AcceptReorderDrag(adaptor); else StopTrackingReorderDrag(); Event.current.Use(); } break; case EventType.KeyDown: if (_tracking && Event.current.keyCode == KeyCode.Escape) { StopTrackingReorderDrag(); Event.current.Use(); } break; case EventType.ExecuteCommand: if (s_ContextControlID == controlID) { int itemIndex = s_ContextItemIndex; try { DoCommand(s_ContextCommandName, itemIndex, adaptor); Event.current.Use(); } finally { s_ContextControlID = 0; s_ContextItemIndex = 0; } } break; case EventType.Repaint: // Draw caption area of list. ContainerStyle.Draw(position, GUIContent.none, false, false, false, false); break; } ReorderableListGUI.IndexOfChangedItem = -1; // Draw list items! Rect itemPosition = new Rect(position.x + 2, firstItemY, position.width - 4, 0); float targetSlotPosition = position.yMax - s_DragItemPosition.height - 1; float lastMidPoint = 0f; float lastHeight = 0f; int count = adaptor.Count; for (int i = 0; i < count; ++i) { itemPosition.y = itemPosition.yMax; itemPosition.height = 0; if (_tracking) { // Does this represent the target index? if (i == s_TargetIndex) { targetSlotPosition = itemPosition.y; itemPosition.y += s_DragItemPosition.height; } // Do not draw item if it is currently being dragged. // Draw later so that it is shown in front of other controls. if (i == s_AnchorIndex) continue; lastMidPoint = itemPosition.y - lastHeight / 2f; } // Update position for current item. itemPosition.height = adaptor.GetItemHeight(i) + 4; lastHeight = itemPosition.height; if (_tracking && eventType == EventType.MouseDrag) { float midpoint = itemPosition.y + itemPosition.height / 2f; if (s_TargetIndex < i) { if (s_DragItemPosition.yMax > lastMidPoint && s_DragItemPosition.yMax < midpoint) newTargetIndex = i; } else if (s_TargetIndex > i) { if (s_DragItemPosition.y > lastMidPoint && s_DragItemPosition.y < midpoint) newTargetIndex = i; } /*if (s_DragItemPosition.y > itemPosition.y && s_DragItemPosition.y <= midpoint) newTargetIndex = i; else if (s_DragItemPosition.yMax > midpoint && s_DragItemPosition.yMax <= itemPosition.yMax) newTargetIndex = i + 1;*/ } // The following may break use of tab key to navigate through controls :/ if ((Flags & ReorderableListFlags.DisableClipping) == 0) { // Clip list item? Performance boost! if (itemPosition.yMax < _visibleRect.y - itemPosition.height) { // Let's try and trick Unity into maintaining tab key support... GUIUtility.GetControlID(FocusType.Keyboard, itemPosition); continue; } if (itemPosition.y > _visibleRect.yMax + itemPosition.height) break; } // Draw list item. DrawListItem(eventType, itemPosition, adaptor, i); // Did list count change (i.e. item removed)? if (adaptor.Count < count) { // We assume that it was this item which was removed, so --i allows us // to process the next item as usual. count = adaptor.Count; --i; continue; } // Event has already been used, skip to next item. if (Event.current.type != EventType.Used) { switch (eventType) { case EventType.MouseDown: if (GUI.enabled && itemPosition.Contains(mousePosition)) { // Remove input focus from control before attempting a context click or drag. GUIUtility.keyboardControl = 0; if (_allowReordering && adaptor.CanDrag(i) && Event.current.button == 0) { s_DragItemPosition = itemPosition; BeginTrackingReorderDrag(controlID, i); s_AnchorMouseOffset = itemPosition.y - mousePosition.y; s_TargetIndex = i; Event.current.Use(); } } break; /* DEBUG case EventType.Repaint: GUI.color = Color.red; GUI.DrawTexture(new Rect(0, lastMidPoint, 10, 1), EditorGUIUtility.whiteTexture); GUI.color = Color.yellow; GUI.DrawTexture(new Rect(5, itemPosition.y + itemPosition.height / 2f, 10, 1), EditorGUIUtility.whiteTexture); GUI.color = Color.white; break; //*/ } } } // Item which is being dragged should be shown on top of other controls! if (IsTrackingControl(controlID)) { lastMidPoint = position.yMax - lastHeight / 2f; if (eventType == EventType.MouseDrag) { if (s_DragItemPosition.yMax >= lastMidPoint) newTargetIndex = count; // Force repaint to occur so that dragging rectangle is visible. s_TargetIndex = newTargetIndex; Event.current.Use(); } DrawFloatingListItem(eventType, adaptor, targetSlotPosition); /* DEBUG if (eventType == EventType.Repaint) { GUI.color = Color.blue; GUI.DrawTexture(new Rect(100, lastMidPoint, 20, 1), EditorGUIUtility.whiteTexture); GUI.color = Color.white; } //*/ } // Fake control to catch input focus if auto focus was not possible. GUIUtility.GetControlID(FocusType.Keyboard); }
/// <summary> /// Calculate height of list control in pixels. /// </summary> /// <param name="adaptor">Reorderable list adaptor.</param> /// <returns> /// Required list height in pixels. /// </returns> public float CalculateListHeight(IReorderableListAdaptor adaptor) { FixStyles(); float totalHeight = ContainerStyle.padding.vertical - 1; // Take list items into consideration. int count = adaptor.Count; for (int i = 0; i < count; ++i) totalHeight += adaptor.GetItemHeight(i); // Add spacing between list items. totalHeight += 4 * count; // Add height of footer buttons. if (HasFooterButtons) totalHeight += FooterButtonStyle.fixedHeight; return totalHeight; }
/// <summary> /// Draw list container and items. /// </summary> /// <param name="position">Position of list control in GUI.</param> /// <param name="adaptor">Reorderable list adaptor.</param> private void DrawListContainerAndItems(Rect position, IReorderableListAdaptor adaptor) { int initialDropTargetNestedCounterValue = s_DropTargetNestedCounter; // Get local copy of event information for efficiency. EventType eventType = Event.current.GetTypeForControl(_controlID); Vector2 mousePosition = Event.current.mousePosition; int newTargetIndex = s_TargetIndex; // Position of first item in list. float firstItemY = position.y + ContainerStyle.padding.top; // Maximum position of dragged item. float dragItemMaxY = (position.yMax - ContainerStyle.padding.bottom) - s_DragItemPosition.height + 1; bool isMouseDragEvent = eventType == EventType.MouseDrag; if (s_SimulateMouseDragControlID == _controlID && eventType == EventType.Repaint) { s_SimulateMouseDragControlID = 0; isMouseDragEvent = true; } if (isMouseDragEvent && _tracking) { // Reset target index and adjust when looping through list items. if (mousePosition.y < firstItemY) newTargetIndex = 0; else if (mousePosition.y >= position.yMax) newTargetIndex = adaptor.Count; s_DragItemPosition.y = Mathf.Clamp(mousePosition.y + s_AnchorMouseOffset, firstItemY, dragItemMaxY); } switch (eventType) { case EventType.MouseDown: if (_tracking) { // Cancel drag when other mouse button is pressed. s_TrackingCancelBlockContext = true; Event.current.Use(); } break; case EventType.MouseUp: if (_controlID == GUIUtility.hotControl) { // Allow user code to change control over reordering during drag. if (!s_TrackingCancelBlockContext && _allowReordering) AcceptReorderDrag(adaptor); else StopTrackingReorderDrag(); Event.current.Use(); } break; case EventType.KeyDown: if (_tracking && Event.current.keyCode == KeyCode.Escape) { StopTrackingReorderDrag(); Event.current.Use(); } break; case EventType.ExecuteCommand: if (s_ContextControlID == _controlID) { int itemIndex = s_ContextItemIndex; try { DoCommand(s_ContextCommandName, itemIndex, adaptor); Event.current.Use(); } finally { s_ContextControlID = 0; s_ContextItemIndex = 0; } } break; case EventType.Repaint: // Draw caption area of list. ContainerStyle.Draw(position, GUIContent.none, false, false, false, false); break; } ReorderableListGUI.IndexOfChangedItem = -1; // Draw list items! Rect itemPosition = new Rect(position.x + ContainerStyle.padding.left, firstItemY, position.width - ContainerStyle.padding.horizontal, 0); float targetSlotPosition = dragItemMaxY; _insertionIndex = 0; _insertionPosition = itemPosition.yMax; float lastMidPoint = 0f; float lastHeight = 0f; int count = adaptor.Count; for (int i = 0; i < count; ++i) { itemPosition.y = itemPosition.yMax; itemPosition.height = 0; lastMidPoint = itemPosition.y - lastHeight / 2f; if (_tracking) { // Does this represent the target index? if (i == s_TargetIndex) { targetSlotPosition = itemPosition.y; itemPosition.y += s_DragItemPosition.height; } // Do not draw item if it is currently being dragged. // Draw later so that it is shown in front of other controls. if (i == s_AnchorIndex) continue; // Update position for current item. itemPosition.height = adaptor.GetItemHeight(i) + 4; lastHeight = itemPosition.height; } else { // Update position for current item. itemPosition.height = adaptor.GetItemHeight(i) + 4; lastHeight = itemPosition.height; // Does this represent the drop insertion index? float midpoint = itemPosition.y + itemPosition.height / 2f; if (mousePosition.y > lastMidPoint && mousePosition.y <= midpoint) { _insertionIndex = i; _insertionPosition = itemPosition.y; } } if (_tracking && isMouseDragEvent) { float midpoint = itemPosition.y + itemPosition.height / 2f; if (s_TargetIndex < i) { if (s_DragItemPosition.yMax > lastMidPoint && s_DragItemPosition.yMax < midpoint) newTargetIndex = i; } else if (s_TargetIndex > i) { if (s_DragItemPosition.y > lastMidPoint && s_DragItemPosition.y < midpoint) newTargetIndex = i; } /*if (s_DragItemPosition.y > itemPosition.y && s_DragItemPosition.y <= midpoint) newTargetIndex = i; else if (s_DragItemPosition.yMax > midpoint && s_DragItemPosition.yMax <= itemPosition.yMax) newTargetIndex = i + 1;*/ } // Draw list item. DrawListItem(itemPosition, adaptor, i); // Did list count change (i.e. item removed)? if (adaptor.Count < count) { // We assume that it was this item which was removed, so --i allows us // to process the next item as usual. count = adaptor.Count; --i; continue; } // Event has already been used, skip to next item. if (Event.current.type != EventType.Used) { switch (eventType) { case EventType.MouseDown: if (GUI.enabled && itemPosition.Contains(mousePosition)) { // Remove input focus from control before attempting a context click or drag. GUIUtility.keyboardControl = 0; if (_allowReordering && adaptor.CanDrag(i) && Event.current.button == 0) { s_DragItemPosition = itemPosition; BeginTrackingReorderDrag(_controlID, i); s_AnchorMouseOffset = itemPosition.y - mousePosition.y; s_TargetIndex = i; Event.current.Use(); } } break; /* DEBUG case EventType.Repaint: GUI.color = Color.red; GUI.DrawTexture(new Rect(0, lastMidPoint, 10, 1), EditorGUIUtility.whiteTexture); GUI.color = Color.yellow; GUI.DrawTexture(new Rect(5, itemPosition.y + itemPosition.height / 2f, 10, 1), EditorGUIUtility.whiteTexture); GUI.color = Color.white; break; //*/ } } } if (HorizontalLineAtEnd) { var horizontalLinePosition = new Rect(itemPosition.x, position.yMax - ContainerStyle.padding.vertical, itemPosition.width, 1); GUIHelper.Separator(horizontalLinePosition, HorizontalLineColor); } lastMidPoint = position.yMax - lastHeight / 2f; // Assume that drop insertion is not allowed at this time; we can change our // mind a little further down ;) _allowDropInsertion = false; // Item which is being dragged should be shown on top of other controls! if (IsTrackingControl(_controlID)) { if (isMouseDragEvent) { if (s_DragItemPosition.yMax >= lastMidPoint) newTargetIndex = count; s_TargetIndex = newTargetIndex; // Force repaint to occur so that dragging rectangle is visible. // But only if this is a real MouseDrag event!! if (eventType == EventType.MouseDrag) Event.current.Use(); } DrawFloatingListItem(adaptor, targetSlotPosition); /* DEBUG if (eventType == EventType.Repaint) { GUI.color = Color.blue; GUI.DrawTexture(new Rect(100, lastMidPoint, 20, 1), EditorGUIUtility.whiteTexture); GUI.color = Color.white; } //*/ } else { // Cannot react to drop insertion if a nested drop target has already reacted! if (s_DropTargetNestedCounter == initialDropTargetNestedCounterValue) { if (Event.current.mousePosition.y >= lastMidPoint) { _insertionIndex = adaptor.Count; _insertionPosition = itemPosition.yMax; } _allowDropInsertion = true; } } // Fake control to catch input focus if auto focus was not possible. GUIUtility.GetControlID(FocusType.Keyboard); if (isMouseDragEvent && (Flags & ReorderableListFlags.DisableAutoScroll) == 0 && IsTrackingControl(_controlID)) AutoScrollTowardsMouse(); }
private void DrawListContainerAndItems(Rect position, int controlID, IReorderableListAdaptor adaptor) { EventType typeForControl = Event.current.GetTypeForControl(controlID); Vector2 mousePosition = Event.current.mousePosition; if (Event.current.isMouse) { ReorderableListControl.s_MousePosition = GUIUtility.GUIToScreenPoint(mousePosition); } int num = ReorderableListControl.s_TargetIndex; float num2 = position.y + (float)this.containerStyle.padding.top; EventType eventType = typeForControl; switch (eventType) { case 0: if (this._tracking) { ReorderableListControl.s_TrackingCancelBlockContext = true; Event.current.Use(); goto IL_1B7; } goto IL_1B7; case EventType.MouseUp: if (controlID == GUIUtility.hotControl) { if (!ReorderableListControl.s_TrackingCancelBlockContext && this._allowReordering) { this.AcceptReorderDrag(adaptor); } else { ReorderableListControl.StopTrackingReorderDrag(); } Event.current.Use(); goto IL_1B7; } goto IL_1B7; case EventType.MouseMove: case EventType.KeyUp: case EventType.ScrollWheel: goto IL_1B7; case EventType.MouseDrag: if (this._tracking) { if (mousePosition.y < num2) { num = 0; } else { if (mousePosition.y >= position.yMax) { num = adaptor.Count; } } ReorderableListControl.s_DragItemPosition.y = Mathf.Clamp(mousePosition.y + ReorderableListControl.s_AnchorMouseOffset, num2, position.yMax - ReorderableListControl.s_DragItemPosition.height - 1f); goto IL_1B7; } goto IL_1B7; case EventType.KeyDown: if (this._tracking && Event.current.keyCode == KeyCode.Escape) { ReorderableListControl.StopTrackingReorderDrag(); Event.current.Use(); goto IL_1B7; } goto IL_1B7; case EventType.Repaint: break; default: { if (eventType != EventType.ExecuteCommand) { goto IL_1B7; } if (ReorderableListControl.s_ContextControlID != controlID) { goto IL_1B7; } int itemIndex = ReorderableListControl.s_ContextItemIndex; try { this.DoCommand(ReorderableListControl.s_ContextCommandName, itemIndex, adaptor); Event.current.Use(); goto IL_1B7; } finally { ReorderableListControl.s_ContextControlID = 0; ReorderableListControl.s_ContextItemIndex = 0; } break; } } this.containerStyle.Draw(position, GUIContent.none, false, false, false, false); IL_1B7: ReorderableListGUI.indexOfChangedItem = -1; Rect rect = new Rect(position.x + 2f, num2, position.width - 4f, 0f); float targetSlotPosition = position.yMax - ReorderableListControl.s_DragItemPosition.height - 1f; float num3 = 0f; float num4 = 0f; int count = adaptor.Count; int i = 0; while (i < count) { rect.y = rect.yMax; rect.height = 0f; if (!this._tracking) { goto IL_286; } if (i == ReorderableListControl.s_TargetIndex) { targetSlotPosition = rect.y; rect.y = rect.y + ReorderableListControl.s_DragItemPosition.height; } if (i != ReorderableListControl.s_AnchorIndex) { num3 = rect.y - num4 / 2f; goto IL_286; } IL_415: i++; continue; IL_286: rect.height = adaptor.GetItemHeight(i) + 4f; num4 = rect.height; if (this._tracking && typeForControl == EventType.MouseDrag) { float num5 = rect.y + rect.height / 2f; if (ReorderableListControl.s_TargetIndex < i) { if (ReorderableListControl.s_DragItemPosition.yMax > num3 && ReorderableListControl.s_DragItemPosition.yMax < num5) { num = i; } } else { if (ReorderableListControl.s_TargetIndex > i && ReorderableListControl.s_DragItemPosition.y > num3 && ReorderableListControl.s_DragItemPosition.y < num5) { num = i; } } } if ((this.flags & ReorderableListFlags.DisableClipping) == (ReorderableListFlags)0) { if (rect.yMax < this._visibleRect.y - rect.height) { GUIUtility.GetControlID(FocusType.Keyboard, rect); goto IL_415; } if (rect.y > this._visibleRect.yMax + rect.height) { break; } } this.DrawListItem(typeForControl, rect, adaptor, i); if (adaptor.Count < count) { count = adaptor.Count; i--; goto IL_415; } if (Event.current.type == EventType.Used) { goto IL_415; } EventType eventType2 = typeForControl; if (eventType2 != 0 || !GUI.enabled || !rect.Contains(mousePosition)) { goto IL_415; } GUIUtility.keyboardControl = 0; if (this._allowReordering && adaptor.CanDrag(i) && Event.current.button == 0) { ReorderableListControl.s_DragItemPosition = rect; ReorderableListControl.BeginTrackingReorderDrag(controlID, i); ReorderableListControl.s_AnchorMouseOffset = rect.y - mousePosition.y; ReorderableListControl.s_TargetIndex = i; Event.current.Use(); goto IL_415; } goto IL_415; } if (ReorderableListControl.IsTrackingControl(controlID)) { num3 = position.yMax - num4 / 2f; if (typeForControl == EventType.MouseDrag) { if (ReorderableListControl.s_DragItemPosition.yMax >= num3) { num = count; } ReorderableListControl.s_TargetIndex = num; Event.current.Use(); } this.DrawFloatingListItem(typeForControl, adaptor, targetSlotPosition); } GUIUtility.GetControlID(FocusType.Keyboard); }
public float CalculateListHeight(IReorderableListAdaptor adaptor) { this.FixStyles(); float num = (float)(this.containerStyle.padding.vertical - 1); int count = adaptor.Count; for (int i = 0; i < count; i++) { num += adaptor.GetItemHeight(i); } num += (float)(4 * count); if (this.hasAddButton) { num += this.addButtonStyle.fixedHeight; } return num; }
public float GetItemHeight(int index) { return(BackingAdaptor.GetItemHeight(MapIndex(index))); }