private static void OnOperationsStateChanged(int[] ids)
        {
            if (!s_Initialized)
            {
                return;
            }
            if (ids.Length == 0)
            {
                return;
            }

            var items = new ProgressItem[ids.Length];
            var i     = 0;

            foreach (var id in ids)
            {
                var item = GetProgressById(id);
                Assert.IsNotNull(item);
                item.Dirty();
                items[i++] = item;
            }
            s_ProgressDirty = true;

            OnUpdated?.Invoke(items);
        }
        private static ProgressItem CreateProgressItem(int id)
        {
            var item = new ProgressItem(id);

            s_ProgressItems.Add(item);
            return(item);
        }
        private DisplayedTask InitializeTask(ProgressItem progressItem, VisualElement parentElement)
        {
            var displayedTask = new DisplayedTask(
                parentElement.Q <Label>("BackgroundTaskNameLabel"),
                parentElement.Q <Label>("ProgressionLabel"),
                parentElement.Q <Label>("BackgroundTaskDescriptionLabel"),
                parentElement.Q <Label>("BackgroundTaskElapsedTimeLabel"),
                parentElement.Q <ProgressBar>("ProgressBar"),
                parentElement.Q <Button>("CancelButton"),
                parentElement.Q <Button>("DeleteButton")
                );

            Assert.IsNotNull(displayedTask.nameLabel);
            Assert.IsNotNull(displayedTask.descriptionLabel);
            Assert.IsNotNull(displayedTask.elapsedTimeLabel);
            Assert.IsNotNull(displayedTask.progressLabel);
            Assert.IsNotNull(displayedTask.progressBar);
            Assert.IsNotNull(displayedTask.cancelButton);
            Assert.IsNotNull(displayedTask.deleteButton);

            displayedTask.cancelButton.RemoveFromClassList("unity-text-element");
            displayedTask.cancelButton.RemoveFromClassList("unity-button");
            displayedTask.deleteButton.RemoveFromClassList("unity-text-element");
            displayedTask.deleteButton.RemoveFromClassList("unity-button");

            displayedTask.cancelButton.userData = progressItem;
            displayedTask.cancelButton.clickable.clickedWithEventInfo += CancelButtonClicked;

            displayedTask.deleteButton.userData = progressItem;
            displayedTask.deleteButton.clickable.clickedWithEventInfo += DeleteButtonClicked;

            UpdateDisplay(displayedTask, progressItem);
            UpdateResponsiveness(displayedTask, progressItem);
            return(displayedTask);
        }
 internal void AddElement(ProgressItem item)
 {
     m_DetailsFoldoutToggle.visible = true;
     SubTaskInitialization(item);
     if (dataSource.running)
     {
         m_DetailsFoldoutToggle.SetValueWithoutNotify(true);
         ToggleDetailsFoldout(ChangeEvent <bool> .GetPooled(false, true));
     }
 }
        public ProgressElement(ProgressItem dataSource)
        {
            rootVisualElement = new TemplateContainer();
            if (s_VisualTreeBackgroundTask == null)
            {
                s_VisualTreeBackgroundTask = EditorGUIUtility.Load(k_UxmlProgressPath) as VisualTreeAsset;
            }

            var task = new VisualElement()
            {
                name = "Task"
            };

            rootVisualElement.Add(task);
            var horizontalLayout = new VisualElement();

            horizontalLayout.style.flexDirection = FlexDirection.Row;
            task.Add(horizontalLayout);
            m_DetailsFoldoutToggle = new Toggle()
            {
                visible = false
            };
            m_DetailsFoldoutToggle.AddToClassList("unity-foldout__toggle");
            m_DetailsFoldoutToggle.RegisterValueChangedCallback(ToggleDetailsFoldout);
            horizontalLayout.Add(m_DetailsFoldoutToggle);
            var parentTask = s_VisualTreeBackgroundTask.CloneTree();

            parentTask.name = "ParentTask";
            horizontalLayout.Add(parentTask);

            var details = new VisualElement()
            {
                name = "Details"
            };

            details.style.display = DisplayStyle.None;
            task.Add(details);

            m_Details           = rootVisualElement.Q <VisualElement>("Details");
            m_DetailsScrollView = new ScrollView();
            m_Details.Add(m_DetailsScrollView);
            m_DetailsScrollView.AddToClassList("details-content");

            this.dataSource = dataSource;

            if (s_VisualTreeSubTask == null)
            {
                s_VisualTreeSubTask = EditorGUIUtility.Load(k_UxmlSubTaskPath) as VisualTreeAsset;
            }

            m_ProgressItemChildren = new List <ProgressItem>();
            m_SubTasks             = new List <DisplayedTask>();

            m_MainTask = InitializeTask(dataSource, rootVisualElement);
        }
        private void SubTaskInitialization(ProgressItem subTaskSource)
        {
            var parentElement = s_VisualTreeBackgroundTask.CloneTree();

            parentElement.name = "SubTask";

            DisplayedTask displayedSubTask = InitializeTask(subTaskSource, parentElement);

            m_ProgressItemChildren.Add(subTaskSource);
            m_SubTasks.Add(displayedSubTask);
            m_DetailsScrollView.Add(parentElement);
        }
        private static void OnOperationStateChanged(int id)
        {
            if (!s_Initialized)
            {
                return;
            }

            ProgressItem item = GetProgressById(id);

            Assert.IsNotNull(item);

            s_ProgressDirty = true;
            item.Dirty();

            OnUpdated?.Invoke(new[] { item });
        }
        private void UpdateDisplay(DisplayedTask task, ProgressItem dataSource)
        {
            task.nameLabel.text = dataSource.name;

            task.descriptionLabel.text = dataSource.description;
            task.SetIndefinite(dataSource.indefinite);

            if (!dataSource.indefinite)
            {
                var p01 = Mathf.Clamp01(dataSource.progress);
                task.progressBar.value = p01 * 100.0f;
                if (task.progressLabel != null)
                {
                    task.progressLabel.text = $"{Mathf.FloorToInt(p01 * 100.0f)}%";
                }

                task.SetProgressStyleFull(dataSource.progress > 0.96f);
            }

            if (dataSource.status == ProgressStatus.Canceled)
            {
                task.descriptionLabel.text += " (Cancelled)";
                UpdateProgressCompletion(task, ProgressWindow.kCanceledIcon);
            }
            else if (dataSource.status == ProgressStatus.Failed)
            {
                task.descriptionLabel.text += " (Failed)";
                UpdateProgressCompletion(task, ProgressWindow.kFailedIcon);
            }
            else if (dataSource.status == ProgressStatus.Succeeded)
            {
                task.progressBar.value = 100;
                task.SetProgressStyleFull(true);
                UpdateProgressCompletion(task, ProgressWindow.kSuccessIcon);
                task.progressLabel.style.unityBackgroundImageTintColor = new StyleColor(Color.green);

                if (m_MainTask == task && m_DetailsFoldoutToggle.value)
                {
                    m_DetailsFoldoutToggle.value = false;
                }
            }

            task.deleteButton.style.display = !dataSource.running ? DisplayStyle.Flex : DisplayStyle.None;
            task.cancelButton.style.display = dataSource.running ? DisplayStyle.Flex : DisplayStyle.None;
            task.cancelButton.visible       = dataSource.cancellable;
        }
        private ProgressElement AddElement(ProgressItem progressItem)
        {
            if (progressItem.parentId >= 0)
            {
                for (int i = 0; i < m_Elements.Count; ++i)
                {
                    if (progressItem.parentId == m_Elements[i].dataSource.id)
                    {
                        m_Elements[i].AddElement(progressItem);
                        return(m_Elements[i]);
                    }
                }
                Assert.IsTrue(true);
            }
            // if parent was not found
            var element = new ProgressElement(progressItem);

            if (m_Elements.Count > 0 && progressItem.status == ProgressStatus.Failed)
            {
                var insertIndex = -1;
                for (int i = 0; i < m_Elements.Count; i++)
                {
                    if ((m_Elements[i].dataSource.status == ProgressStatus.Failed && progressItem.updateTime > m_Elements[i].dataSource.updateTime) ||
                        m_Elements[i].dataSource.status != ProgressStatus.Failed)
                    {
                        insertIndex = i;
                        break;
                    }
                }
                m_Elements.Insert(insertIndex, element);
                m_ScrollView.Insert(insertIndex, element.rootVisualElement);
                if (insertIndex > m_LastParentFailedIndex)
                {
                    m_LastParentFailedIndex = insertIndex;
                }
                return(element);
            }
            else
            {
                m_Elements.Insert(m_LastParentFailedIndex + 1, element);
                m_ScrollView.Insert(m_LastParentFailedIndex + 1, element.rootVisualElement);
            }
            return(element);
        }
 private static void UpdateResponsiveness(DisplayedTask task, ProgressItem dataSource)
 {
     if (dataSource.responding && !task.isResponding)
     {
         task.descriptionLabel.text = dataSource.description;
         if (task.progress.ClassListContains("unity-progress-bar__progress__unresponding"))
         {
             task.progress.RemoveFromClassList("unity-progress-bar__progress__unresponding");
         }
     }
     else if (!dataSource.responding && task.isResponding)
     {
         task.descriptionLabel.text = string.IsNullOrEmpty(dataSource.description) ? "(Not Responding)" : $"{dataSource.description} (Not Responding)";
         if (!task.progress.ClassListContains("unity-progress-bar__progress__unresponding"))
         {
             task.progress.AddToClassList("unity-progress-bar__progress__unresponding");
         }
     }
     task.isResponding = dataSource.responding;
 }
 internal bool TryUpdate(ProgressItem op, int id)
 {
     if (dataSource.id == id)
     {
         dataSource = op;
         UpdateDisplay(m_MainTask, dataSource);
         return(true);
     }
     else
     {
         for (int i = 0; i < m_ProgressItemChildren.Count; ++i)
         {
             if (m_ProgressItemChildren[i].id == id)
             {
                 m_ProgressItemChildren[i] = op;
                 UpdateDisplay(m_SubTasks[i], m_ProgressItemChildren[i]);
                 return(true);
             }
         }
     }
     return(false);
 }