Borodar.ReorderableList.ReorderableListControl.DrawListContainerAndItems C# (CSharp) Method

DrawListContainerAndItems() private method

Draw list container and items.
private DrawListContainerAndItems ( Rect position, IReorderableListAdaptor adaptor ) : void
position UnityEngine.Rect Position of list control in GUI.
adaptor IReorderableListAdaptor Reorderable list adaptor.
return void
        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();
        }