| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377 |
- using System.Linq;
- namespace SRDebugger.UI.Tabs
- {
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using Controls;
- using Controls.Data;
- using Internal;
- using Other;
- using Services;
- using SRF;
- using UnityEngine;
- using UnityEngine.UI;
- public class OptionsTabController : SRMonoBehaviourEx
- {
- private class CategoryInstance
- {
- public CategoryGroup CategoryGroup { get; private set; }
- public readonly List<OptionsControlBase> Options = new List<OptionsControlBase>();
- public CategoryInstance(CategoryGroup group)
- {
- CategoryGroup = group;
- }
- }
- private readonly List<OptionsControlBase> _controls = new List<OptionsControlBase>();
- private readonly List<CategoryInstance> _categories = new List<CategoryInstance>();
- private readonly Dictionary<OptionDefinition, OptionsControlBase> _options =
- new Dictionary<OptionDefinition, OptionsControlBase>();
- private bool _queueRefresh;
- private bool _selectionModeEnabled;
- private Canvas _optionCanvas;
- [RequiredField] public ActionControl ActionControlPrefab;
- [RequiredField] public CategoryGroup CategoryGroupPrefab;
- [RequiredField] public RectTransform ContentContainer;
- [RequiredField] public GameObject NoOptionsNotice;
- [RequiredField] public Toggle PinButton;
- [RequiredField] public GameObject PinPromptSpacer;
- [RequiredField] public GameObject PinPromptText;
- protected override void Start()
- {
- base.Start();
- PinButton.onValueChanged.AddListener(SetSelectionModeEnabled);
- PinPromptText.SetActive(false);
- //PinPromptSpacer.SetActive(false);
- Populate();
- _optionCanvas = GetComponent<Canvas>();
- Service.Options.OptionsUpdated += OnOptionsUpdated;
- Service.PinnedUI.OptionPinStateChanged += OnOptionPinnedStateChanged;
- }
- protected override void OnDestroy()
- {
- if (Service.Options != null)
- {
- Service.Options.OptionsUpdated -= OnOptionsUpdated;
- }
- if (Service.PinnedUI != null)
- {
- Service.PinnedUI.OptionPinStateChanged -= OnOptionPinnedStateChanged;
- }
- base.OnDestroy();
- }
- private void OnOptionPinnedStateChanged(OptionDefinition optionDefinition, bool isPinned)
- {
- if (_options.ContainsKey(optionDefinition))
- {
- _options[optionDefinition].IsSelected = isPinned;
- }
- }
- private void OnOptionsUpdated(object sender, EventArgs eventArgs)
- {
- Clear();
- Populate();
- }
- protected override void OnEnable()
- {
- base.OnEnable();
- Service.Panel.VisibilityChanged += PanelOnVisibilityChanged;
- }
- protected override void OnDisable()
- {
- // Always end pinning mode when tabbing away
- SetSelectionModeEnabled(false);
- if (Service.Panel != null)
- {
- Service.Panel.VisibilityChanged -= PanelOnVisibilityChanged;
- }
- base.OnDisable();
- }
- protected override void Update()
- {
- base.Update();
- if (_queueRefresh)
- {
- _queueRefresh = false;
- Refresh();
- }
- }
- private void PanelOnVisibilityChanged(IDebugPanelService debugPanelService, bool b)
- {
- // Always end pinning mode when panel is closed
- if (!b)
- {
- SetSelectionModeEnabled(false);
- // Refresh bindings for all pinned controls
- Refresh();
- }
- else if (b && CachedGameObject.activeInHierarchy)
- {
- // If the panel is visible, and this tab is active (selected), refresh all the data bindings
- Refresh();
- }
- if (_optionCanvas != null)
- {
- _optionCanvas.enabled = b;
- }
- }
- public void SetSelectionModeEnabled(bool isEnabled)
- {
- if (_selectionModeEnabled == isEnabled)
- {
- return;
- }
- _selectionModeEnabled = isEnabled;
- PinButton.isOn = isEnabled;
- PinPromptText.SetActive(isEnabled);
- //PinPromptSpacer.SetActive(isEnabled);
- foreach (var kv in _options)
- {
- kv.Value.SelectionModeEnabled = isEnabled;
- // Set IsSelected if entering selection mode.
- if (isEnabled)
- {
- kv.Value.IsSelected = Service.PinnedUI.HasPinned(kv.Key);
- }
- }
- foreach (var cat in _categories)
- {
- cat.CategoryGroup.SelectionModeEnabled = isEnabled;
- }
- RefreshCategorySelection();
- // Return if entering selection mode
- if (isEnabled)
- {
- return;
- }
- }
- private void Refresh()
- {
- for (var i = 0; i < _options.Count; i++)
- {
- _controls[i].Refresh();
- _controls[i].SelectionModeEnabled = _selectionModeEnabled;
- _controls[i].IsSelected = Service.PinnedUI.HasPinned(_controls[i].Option);
- }
- }
- private void CommitPinnedOptions()
- {
- foreach (var kv in _options)
- {
- var control = kv.Value;
- if (control.IsSelected && !Service.PinnedUI.HasPinned(kv.Key))
- {
- Service.PinnedUI.Pin(kv.Key);
- }
- else if (!control.IsSelected && Service.PinnedUI.HasPinned(kv.Key))
- {
- Service.PinnedUI.Unpin(kv.Key);
- }
- }
- }
- private bool _isTogglingCategory;
- private void RefreshCategorySelection()
- {
- _isTogglingCategory = true;
- foreach (var cat in _categories)
- {
- var allSelected = true;
- for (var i = 0; i < cat.Options.Count; i++)
- {
- if (!cat.Options[i].IsSelected)
- {
- allSelected = false;
- break;
- }
- }
- cat.CategoryGroup.IsSelected = allSelected;
- }
- _isTogglingCategory = false;
- }
- private void OnOptionSelectionToggle(bool selected)
- {
- if (!_isTogglingCategory)
- {
- RefreshCategorySelection();
- CommitPinnedOptions();
- }
- }
- /// <summary>
- /// When a category mode selection is changed.
- /// </summary>
- /// <param name="category"></param>
- /// <param name="selected"></param>
- private void OnCategorySelectionToggle(CategoryInstance category, bool selected)
- {
- _isTogglingCategory = true;
- for (var i = 0; i < category.Options.Count; i++)
- {
- category.Options[i].IsSelected = selected;
- }
- _isTogglingCategory = false;
- CommitPinnedOptions();
- }
- #region Initialisation
- protected void Populate()
- {
- var sortedOptions = new Dictionary<string, List<OptionDefinition>>();
- foreach (var option in Service.Options.Options)
- {
- if (!OptionControlFactory.CanCreateControl(option))
- {
- if (option.IsProperty)
- {
- Debug.LogError("[SRDebugger.OptionsTab] Unsupported property type: {0} (on property {1})".Fmt(option.Property.PropertyType, option.Property));
- }
- else
- {
- Debug.LogError("[SRDebugger.OptionsTab] Unsupported method signature: {0}".Fmt(option.Name));
- }
- continue;
- }
- // Find a properly list for that category, or create a new one
- List<OptionDefinition> memberList;
- if (!sortedOptions.TryGetValue(option.Category, out memberList))
- {
- memberList = new List<OptionDefinition>();
- sortedOptions.Add(option.Category, memberList);
- }
- memberList.Add(option);
- }
- var hasCreated = false;
- foreach (var kv in sortedOptions.OrderBy(p => p.Key))
- {
- if (kv.Value.Count == 0)
- {
- continue;
- }
- hasCreated = true;
- CreateCategory(kv.Key, kv.Value);
- }
- if (hasCreated)
- {
- NoOptionsNotice.SetActive(false);
- }
-
- RefreshCategorySelection();
- }
- protected void CreateCategory(string title, List<OptionDefinition> options)
- {
- options.Sort((d1, d2) => d1.SortPriority.CompareTo(d2.SortPriority));
- var groupInstance = SRInstantiate.Instantiate(CategoryGroupPrefab);
- var categoryInstance = new CategoryInstance(groupInstance);
- _categories.Add(categoryInstance);
- groupInstance.CachedTransform.SetParent(ContentContainer, false);
- groupInstance.Header.text = title;
- groupInstance.SelectionModeEnabled = _selectionModeEnabled;
- categoryInstance.CategoryGroup.SelectionToggle.onValueChanged.AddListener(
- b => OnCategorySelectionToggle(categoryInstance, b));
- foreach (var option in options)
- {
- var control = OptionControlFactory.CreateControl(option, title);
- if (control == null)
- {
- Debug.LogError("[SRDebugger.OptionsTab] Failed to create option control for {0}".Fmt(option.Name));
- continue;
- }
- categoryInstance.Options.Add(control);
- control.CachedTransform.SetParent(groupInstance.Container, false);
- control.IsSelected = Service.PinnedUI.HasPinned(option);
- control.SelectionModeEnabled = _selectionModeEnabled;
- control.SelectionModeToggle.onValueChanged.AddListener(OnOptionSelectionToggle);
- _options.Add(option, control);
- _controls.Add(control);
- }
- }
- void Clear()
- {
- foreach (var categoryInstance in _categories)
- {
- Destroy(categoryInstance.CategoryGroup.gameObject);
- }
- _categories.Clear();
- _controls.Clear();
- _options.Clear();
- }
- #endregion
- }
- }
|