OldBlueWater/BlueWater/Assets/Doozy/Editor/Signals/Layouts/StreamsConsoleWindowLayout.cs

297 lines
12 KiB
C#

// Copyright (c) 2015 - 2023 Doozy Entertainment. All Rights Reserved.
// This code can only be used under the standard Unity Asset Store End User License Agreement
// A Copy of the EULA APPENDIX 1 is available at http://unity3d.com/company/legal/as_terms
using System.Collections.Generic;
using System.Linq;
using Doozy.Editor.EditorUI;
using Doozy.Editor.EditorUI.Components;
using Doozy.Editor.EditorUI.ScriptableObjects.Colors;
using Doozy.Editor.EditorUI.Utils;
using Doozy.Runtime.Signals;
using Doozy.Runtime.UIElements.Extensions;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable UnusedMember.Local
namespace Doozy.Editor.Signals.Layouts
{
public sealed class StreamsConsoleWindowLayout : FluidWindowLayout
{
public override Color accentColor => EditorColors.Signals.Stream;
public override EditorSelectableColorInfo selectableAccentColor => EditorSelectableColors.Signals.Stream;
public override List<Texture2D> animatedIconTextures => EditorSpriteSheets.Signals.Icons.SignalStream;
private static Color signalColor => EditorColors.Signals.Signal;
private static EditorSelectableColorInfo signalSelectableColor => EditorSelectableColors.Signals.Signal;
private static Color streamColor => EditorColors.Signals.Stream;
private static EditorSelectableColorInfo streamSelectableColor => EditorSelectableColors.Signals.Stream;
private static IEnumerable<Texture2D> signalTextures => EditorSpriteSheets.Signals.Icons.Signal;
private static IEnumerable<Texture2D> streamTextures => EditorSpriteSheets.Signals.Icons.SignalStream;
private static IEnumerable<Texture2D> filterTextures => EditorSpriteSheets.EditorUI.Icons.Filter;
private VisualElement consolePinnedRows { get; set; }
private ScrollView consoleScrollableContainer { get; set; }
private List<StreamsConsoleRow> consoleRows { get; set; }
private FluidPlaceholder placeholderOffline { get; set; }
private FluidPlaceholder placeholderNoStreams { get; set; }
#region Filter
private ScrollView filtersScrollView { get; set; }
private Filter streamSignalProviderFilter { get; set; }
private Filter streamProviderGameObjectFilter { get; set; }
private Filter streamCategoryFilter { get; set; }
private Filter streamNameFilter { get; set; }
private Filter streamInfoMessageFilter { get; set; }
private Filter streamGuidFilter { get; set; }
private bool showGuid { get; set; }
private List<Filter> filters { get; set; }
public void ClearFilters()
{
foreach (Filter filter in filters)
filter.Clear();
}
private void FiltersUpdated(string pattern)
{
foreach (StreamsConsoleRow consoleRow in consoleRows)
ApplyFilter(consoleRow);
}
private void ApplyFilter(StreamsConsoleRow consoleRow)
{
consoleRow.streamGuidContainer.SetStyleDisplay(showGuid ? DisplayStyle.Flex : DisplayStyle.None);
consoleRow.ClearFilter();
consoleRow.ApplyFilter(streamSignalProviderFilter, consoleRow.streamSignalProviderLabel.text);
if (consoleRow.isHiddenByFilter) return;
consoleRow.ApplyFilter(streamProviderGameObjectFilter, consoleRow.streamSignalProviderGameObjectLabel.text);
if (consoleRow.isHiddenByFilter) return;
consoleRow.ApplyFilter(streamCategoryFilter, consoleRow.streamCategoryLabel.text);
if (consoleRow.isHiddenByFilter) return;
consoleRow.ApplyFilter(streamNameFilter, consoleRow.streamNameLabel.text);
if (consoleRow.isHiddenByFilter) return;
consoleRow.ApplyFilter(streamInfoMessageFilter, consoleRow.streamInfoMessageLabel.text);
if (consoleRow.isHiddenByFilter) return;
consoleRow.ApplyFilter(streamGuidFilter, consoleRow.streamGuidLabel.text);
}
#endregion
private bool initialized { get; set; }
public StreamsConsoleWindowLayout()
{
AddHeader("Streams Console", "Realtime Streams Visualizer", animatedIconTextures);
Initialize();
}
private void Initialize()
{
if (!initialized)
{
filtersScrollView = new ScrollView().SetStyleAlignSelf(Align.Stretch);
sideMenu.toolbarContainer
.SetStyleDisplay(DisplayStyle.Flex)
.SetStyleFlexGrow(1)
.AddChild(filtersScrollView);
sideMenu.buttonsScrollViewContainer
.SetStyleDisplay(DisplayStyle.None);
sideMenu
.RemoveSearch()
.SetMenuLevel(FluidSideMenu.MenuLevel.Level_2)
.SetMenuInfo("Filters", filterTextures)
.HideToolbarWhenCollapsed(true)
.IsCollapsable(true)
.CollapseMenu(false)
.SetAccentColor(selectableAccentColor);
placeholderOffline =
FluidPlaceholder
.Get("Signals is offline", EditorSpriteSheets.Signals.Placeholders.OfflineSignal)
.SetStyleFlexGrow(1)
.Hide();
placeholderNoStreams =
FluidPlaceholder
.Get("No active streams detected", EditorSpriteSheets.Signals.Placeholders.OnlineSignal)
.SetStyleFlexGrow(1)
.Hide();
consolePinnedRows = new VisualElement().SetStyleMarginBottom(6).SetStyleFlexShrink(0).SetStyleDisplay(DisplayStyle.None);
consoleScrollableContainer = new ScrollView() { viewDataKey = nameof(consoleScrollableContainer) };
consoleRows = new List<StreamsConsoleRow>();
SignalsService.OnStreamAdded += AddStream;
SignalsService.OnStreamRemoved += RemoveStream;
EditorApplication.playModeStateChanged += state => UpdatePlayModeDependentElements();
filters = new List<Filter>
{
(streamSignalProviderFilter = new Filter().SetOnPatternChanged(FiltersUpdated)),
(streamProviderGameObjectFilter = new Filter().SetOnPatternChanged(FiltersUpdated)),
(streamCategoryFilter = new Filter().SetOnPatternChanged(FiltersUpdated)),
(streamNameFilter = new Filter().SetOnPatternChanged(FiltersUpdated)),
(streamInfoMessageFilter = new Filter().SetOnPatternChanged(FiltersUpdated)),
(streamGuidFilter = new Filter().SetOnPatternChanged(FiltersUpdated))
};
FluidField GetFilterField(string labelText, Filter filter)
{
TextField textField = new TextField().ResetLayout();
FluidButton buttonClear =
FluidButton.Get(EditorSpriteSheets.EditorUI.Icons.Clear)
.SetElementSize(ElementSize.Tiny)
.SetStyleAlignSelf(Align.FlexEnd)
.SetOnClick(() => textField.value = string.Empty);
textField.RegisterValueChangedCallback(evt => filter.SetPattern(evt.newValue));
FluidField field =
FluidField.Get(labelText)
.SetStyleFlexGrow(1)
.SetStyleMinWidth(60)
.ClearBackground()
.SetElementSize(ElementSize.Small)
.AddFieldContent(textField)
.AddInfoElement(buttonClear);
field.infoContainer.SetStyleJustifyContent(Justify.FlexEnd);
return field;
}
FluidContainer streamFiltersContainer =
FluidContainer.Get()
.SetStyleMargins(DesignUtils.k_Spacing2X, DesignUtils.k_Spacing, DesignUtils.k_Spacing2X, 0)
.SetIcon(filterTextures)
.SetLabelText("Stream Filters")
.SetAccentColor(streamColor)
.AddToFluidContent(GetFilterField("Stream Provider", streamSignalProviderFilter))
.AddToFluidContent(GetFilterField("Provider GameObject", streamProviderGameObjectFilter))
.AddToFluidContent(GetFilterField("Stream Category", streamCategoryFilter))
.AddToFluidContent(GetFilterField("Stream Name", streamNameFilter))
.AddToFluidContent(GetFilterField("Stream Info Message", streamInfoMessageFilter))
.AddToFluidContent(GetFilterField("Stream Key (Guid)", streamGuidFilter));
filtersScrollView.contentContainer
.AddChild(streamFiltersContainer);
content.Clear();
content
.AddChild(consolePinnedRows)
.AddChild(placeholderOffline)
.AddChild(placeholderNoStreams)
.AddChild(consoleScrollableContainer);
initialized = true;
}
if (consoleRows.Count > 0)
foreach (StreamsConsoleRow row in consoleRows)
row.Dispose();
consoleRows.Clear();
consoleScrollableContainer.Clear();
foreach (SignalStream stream in SignalsService.Streams.Values)
AddStream(stream);
UpdatePlayModeDependentElements();
}
private void UpdatePlayModeDependentElements()
{
consolePinnedRows.SetStyleDisplay(EditorApplication.isPlaying && consolePinnedRows.childCount > 0 ? DisplayStyle.Flex : DisplayStyle.None);
consoleScrollableContainer.SetStyleDisplay(EditorApplication.isPlaying ? DisplayStyle.Flex : DisplayStyle.None);
placeholderOffline.Toggle(!EditorApplication.isPlaying);
placeholderNoStreams.Toggle(EditorApplication.isPlaying && consoleRows.Count == 0);
}
private void OnRowPinned(StreamsConsoleRow pinnedRow)
{
pinnedRow.RemoveFromHierarchy();
if (pinnedRow.pinned)
{
consolePinnedRows.Insert(0, pinnedRow);
consolePinnedRows.SetStyleDisplay(DisplayStyle.Flex);
return;
}
consoleScrollableContainer.Insert(0, pinnedRow);
UpdatePlayModeDependentElements();
}
public override void OnDestroy()
{
base.OnDestroy();
SignalsService.OnStreamAdded -= AddStream;
SignalsService.OnStreamRemoved -= RemoveStream;
placeholderOffline?.Recycle();
placeholderNoStreams?.Recycle();
foreach (StreamsConsoleRow row in consoleRows)
row?.Dispose();
}
private void AddStream(SignalStream stream)
{
Clean();
var row = StreamsConsoleRow.Get(stream);
consoleRows.Insert(0, row);
consoleScrollableContainer.AddChild(row);
row.OnPinned += OnRowPinned;
Sort();
UpdatePlayModeDependentElements();
}
private void RemoveStream(SignalStream stream)
{
Clean();
StreamsConsoleRow row = GetRow(stream);
if (row == null) return;
consoleRows.Remove(row);
row.OnPinned -= OnRowPinned;
row.Recycle();
UpdatePlayModeDependentElements();
}
private void Clean()
{
for (int i = consoleRows.Count - 1; i >= 0; i--)
{
StreamsConsoleRow row = consoleRows[i];
SignalStream stream = row?.stream;
bool isValid = row != null & stream != null & SignalsService.Streams.Values.Contains(stream);
if (isValid) continue;
consoleRows.RemoveAt(i);
row?.Recycle();
}
}
private void Sort()
{
consoleRows = consoleRows
.OrderBy(sv => sv.stream.category)
.ThenBy(sv => sv.stream.name)
.ToList();
}
private StreamsConsoleRow GetRow(SignalStream stream) =>
stream == null ? null : consoleRows.FirstOrDefault(row => row.stream == stream);
}
}