public NodeItemList(string title, string buttonWord, IList list, int itemHeight, Action <VisualElement> makeItem, Action <VisualElement, int> bindItem, Func <object> itemCreationCallback)
        {
            text = title;
            AddToClassList("node-item-list");

            VisualElement buttonsContainer = new VisualElement();

            buttonsContainer.AddToClassList("node-item-list__buttons-container");
            Add(buttonsContainer);

            Button addButton = new Button(() =>
            {
                List.itemsSource.Add(itemCreationCallback());
                List.Refresh();
            })
            {
                text = $"Add {buttonWord}"
            };

            addButton.AddToClassList("node-item-list__add-button");
            buttonsContainer.Add(addButton);

            Button removeButton = new Button(() =>
            {
                if (List.selectedItem == null)
                {
                    return;
                }

                int firstIndex = List.selectedIndex;
                int indexFixer = 0;

                foreach (int index in List.selectedIndices)
                {
                    List.itemsSource.RemoveAt(index - indexFixer);
                    indexFixer++;
                }

                List.selectedIndex = Mathf.Min(firstIndex, List.itemsSource.Count - 1);
                List.Refresh();
            })
            {
                text = $"Remove {buttonWord}"
            };

            removeButton.AddToClassList("node-item-list__remove-button");
            buttonsContainer.Add(removeButton);

            VisualElement listContainer = new VisualElement();

            listContainer.AddToClassList("node-item-list__list-container");
            listContainer.RegisterCallback <MouseDownEvent>(e => e.StopPropagation());
            Add(listContainer);

            List = new ResizableListView(list, itemHeight, () =>
            {
                VisualElement container = new VisualElement();
                container.AddToClassList("node-item-list__item");

                makeItem(container);

                return(container);
            }, bindItem);
            List.selectionType = SelectionType.Multiple;
            List.reorderable   = true;
            List.AddToClassList("node-item-list__list");
            listContainer.Add(List);
        }
        public TransitionInspector()
        {
            text = "Transition";

            _scrollView = new ScrollView(ScrollViewMode.Vertical);
            _scrollView.AddToClassList("content");
            Add(_scrollView);

            Foldout transitionsFoldout = new Foldout()
            {
                value = true, text = "Transitions"
            };

            transitionsFoldout.RegisterValueChangedCallback(e => e.StopPropagation());
            _scrollView.Add(transitionsFoldout);

            _transitions            = new ResizableListView();
            _transitions.name       = "Transitions";
            _transitions.itemHeight = 20;
            _transitions.makeItem   = () =>
            {
                VisualElement container = new VisualElement();

                Label label = new Label()
                {
                    pickingMode = PickingMode.Ignore
                };
                Button removeButton = new Button()
                {
                    text = "X"
                };

                container.Add(label);
                container.Add(removeButton);

                return(container);
            };
            _transitions.bindItem = (item, index) =>
            {
                void Remove()
                {
                    _connection.RemoveTransition(index);
                }

                item.Q <Label>().text = $"{((IStateNode)_connection.Source).Name} >>> {((StateNodeUI)_connection.Destination).Name}";
                Button removeButton = item.Q <Button>();
                removeButton.clicked -= Remove;
                removeButton.clicked += Remove;
            };
            _transitions.onSelectionChange += selection =>
            {
                _selectedTransition = (TransitionInfo)selection.First();
                BindTransitionFields(_selectedTransition);
            };
            _transitions.selectionType = SelectionType.Single;
            _transitions.reorderable   = true;

            transitionsFoldout.Add(_transitions);

            DurationTypeField = new EnumField("Duration Type", DurationType.Fixed);
            DurationTypeField.RegisterValueChangedCallback(e =>
            {
                _selectedTransition.DurationType = (DurationType)e.newValue;
                DurationField.label = (DurationType)e.newValue == DurationType.Fixed ? "Duration (s)" : "Duration (%)";
            });
            _scrollView.Add(DurationTypeField);

            DurationField = new FloatField("Duration (s)");
            DurationField.RegisterValueChangedCallback(e => _selectedTransition.Duration = e.newValue);
            _scrollView.Add(DurationField);

            OffsetTypeField = new EnumField("Offset Type", DurationType.Fixed);
            OffsetTypeField.RegisterValueChangedCallback(e =>
            {
                _selectedTransition.OffsetType = (DurationType)e.newValue;
                OffsetField.label = (DurationType)e.newValue == DurationType.Fixed ? "Offset (s)" : "Offset (%)";
            });
            _scrollView.Add(OffsetTypeField);

            OffsetField = new FloatField("Offset (s)");
            OffsetField.RegisterValueChangedCallback(e => _selectedTransition.Offset = e.newValue);
            _scrollView.Add(OffsetField);

            InterruptionSourceField = new EnumField("Interruption Source", TransitionInterruptionSource.None);
            InterruptionSourceField.RegisterValueChangedCallback(e =>
            {
                TransitionInterruptionSource interruptionSource = (TransitionInterruptionSource)e.newValue;
                _selectedTransition.InterruptionSource          = interruptionSource;

                if (interruptionSource == TransitionInterruptionSource.None || interruptionSource == TransitionInterruptionSource.NextState)
                {
                    OrderedInterruptionToggle.style.display = DisplayStyle.None;
                }
                else
                {
                    OrderedInterruptionToggle.style.display = DisplayStyle.Flex;
                }
            });
            _scrollView.Add(InterruptionSourceField);

            OrderedInterruptionToggle = new Toggle("Ordered Interruption");
            OrderedInterruptionToggle.RegisterValueChangedCallback(e =>
            {
                _selectedTransition.OrderedInterruption = e.newValue;
                e.StopPropagation();
            });
            OrderedInterruptionToggle.style.display = DisplayStyle.None;
            _scrollView.Add(OrderedInterruptionToggle);

            InterruptableByAnyStateToggle = new Toggle("Interruptable By Any State");
            InterruptableByAnyStateToggle.RegisterValueChangedCallback(e =>
            {
                _selectedTransition.InterruptableByAnyState = e.newValue;
                e.StopPropagation();
            });
            _scrollView.Add(InterruptableByAnyStateToggle);

            PlayAfterTransitionToggle = new Toggle("Play After Transition");
            PlayAfterTransitionToggle.RegisterValueChangedCallback(e =>
            {
                _selectedTransition.PlayAfterTransition = e.newValue;
                e.StopPropagation();
            });
            _scrollView.Add(PlayAfterTransitionToggle);

            Foldout conditionsFoldout = new Foldout()
            {
                value = true, text = "Conditions"
            };

            conditionsFoldout.RegisterValueChangedCallback(e => e.StopPropagation());
            _scrollView.Add(conditionsFoldout);

            VisualElement conditionListButtons = new VisualElement();

            conditionListButtons.style.flexDirection = FlexDirection.Row;
            conditionsFoldout.Add(conditionListButtons);

            Button removeConditionButton = new Button(() =>
            {
                if (_conditions.selectedItem == null)
                {
                    return;
                }

                int firstIndex = _conditions.selectedIndex;
                int indexFixer = 0;

                foreach (var index in _conditions.selectedIndices)
                {
                    _selectedTransition.Conditions.RemoveAt(index - indexFixer);
                    indexFixer++;
                }

                _conditions.Refresh();
                _conditions.selectedIndex = Mathf.Min(firstIndex, _selectedTransition.Conditions.Count - 1);
            })
            {
                text = "Remove Condition"
            };

            conditionListButtons.Add(removeConditionButton);

            Button addConditionButton = new Button(() =>
            {
                _selectedTransition.Conditions.Add(new TransitionInfoCondition());
                _conditions.Refresh();
            })
            {
                text = "Add Condition"
            };

            conditionListButtons.Add(addConditionButton);

            _conditions            = new ResizableListView();
            _conditions.name       = "Conditions";
            _conditions.itemHeight = 25;
            _conditions.makeItem   = () =>
            {
                TransitionConditionUI transitionCondition = new TransitionConditionUI();

                return(transitionCondition);
            };
            _conditions.bindItem = (item, index) =>
            {
                ((TransitionConditionUI)item).Bind(_selectedTransition.Conditions[index]);
            };
            _conditions.selectionType = SelectionType.Multiple;
            _conditions.reorderable   = true;
            conditionsFoldout.Add(_conditions);

            RegisterCallback <ChangeEvent <bool> >(e => ToggleInClassList("expanded"));
        }