void AddDropdownCallbackDelegate(Rect buttonRect, ReorderableList list) { var databases = new[] { ComponentSearcherDatabases.GetBuildStepsDatabase( new HashSet <Type>(BuildStep.GetAvailableTypes(type => !IsShown(type))), GetDisplayName), }; var searcher = new Searcher( databases, new AddBuildSettingsComponentAdapter("Add Build Step")); var editorWindow = EditorWindow.focusedWindow; SearcherWindow.Show( editorWindow, searcher, AddStep, buttonRect.min + Vector2.up * 90.0f, a => { }, new SearcherWindow.Alignment(SearcherWindow.Alignment.Vertical.Top, SearcherWindow.Alignment.Horizontal.Left) ); }
public override VisualElement Build() { var typeField = Assets.LoadVisualTreeAsset(nameof(TypeInspector <T>)).CloneTree(); var label = typeField.Q <Label>("label"); label.text = DisplayName; var input = typeField.Q <VisualElement>("input"); input.RegisterCallback <MouseUpEvent>(mouseUpEvent => { var database = TypeSearcherDatabase.Populate <T>(TypeFilter, TypeNameResolver, TypeCategoryResolver); var searcher = new Searcher(database, new AddTypeSearcherAdapter(SearcherTitle)); var position = input.worldBound.min + Vector2.up * (input.worldBound.height + 19f); var alignment = new SearcherWindow.Alignment(SearcherWindow.Alignment.Vertical.Top, SearcherWindow.Alignment.Horizontal.Left); SearcherWindow.Show(EditorWindow.focusedWindow, searcher, OnTypeSelected, position, null); }); var type = Target?.GetType(); if (type != null) { m_Text = typeField.Q <TextElement>("text"); m_Text.text = TypeNameResolver?.Invoke(type) ?? type.Name; } return(typeField); }
public void OnDropOutsidePort(Edge edge, Vector2 position) { var draggedPort = (edge.output != null ? edge.output.edgeConnector.edgeDragHelper.draggedPort : null) ?? (edge.input != null ? edge.input.edgeConnector.edgeDragHelper.draggedPort : null); m_SearchWindowProvider.connectedPort = (ShaderPort)draggedPort; SearcherWindow.Show(m_editorWindow, (m_SearchWindowProvider as SearcherProvider).LoadSearchWindow(), item => (m_SearchWindowProvider as SearcherProvider).OnSearcherSelectEntry(item, position), position, null); }
public void OnDropOutsidePort(Edge edge, Vector2 position) { var port = edge.output?.edgeConnector.edgeDragHelper.draggedPort ?? edge.input?.edgeConnector.edgeDragHelper.draggedPort; searchWindowProvider.ConnectedPort = port; searchWindowProvider.RegenerateEntries = true; SearcherWindow.Show(editorView.EditorWindow, searchWindowProvider.LoadSearchWindow(), item => searchWindowProvider.OnSelectEntry(item, position), position, null); searchWindowProvider.RegenerateEntries = true; }
public void OnDropOutsidePort(Edge edge, Vector2 position) { var draggedPort = (edge.output != null ? edge.output.edgeConnector.edgeDragHelper.draggedPort : null) ?? (edge.input != null ? edge.input.edgeConnector.edgeDragHelper.draggedPort : null); m_SearchWindowProvider.connectedPort = (ShaderPort)draggedPort; m_SearchWindowProvider.regenerateEntries = true;//need to be sure the entires are relevant to the edge we are dragging SearcherWindow.Show(m_editorWindow, (m_SearchWindowProvider as SearcherProvider).LoadSearchWindow(), item => (m_SearchWindowProvider as SearcherProvider).OnSearcherSelectEntry(item, position), position, null); m_SearchWindowProvider.regenerateEntries = true;//entries no longer necessarily relevant, need to regenerate }
public override VisualElement Build() { var typeField = Assets.LoadVisualTreeAsset(nameof(TypeInspector <T>)).CloneTree(); typeField.AddStyleSheetAndVariant(nameof(TypeInspector <T>)); var label = typeField.Q <Label>("label"); label.text = DisplayName; var input = typeField.Q <VisualElement>("input"); input.RegisterCallback <MouseUpEvent>(mouseUpEvent => { var database = TypeSearcherDatabase.Populate <T>(TypeFilter, TypeNameResolver, TypeCategoryResolver); var searcher = new Searcher(database, new AddTypeSearcherAdapter(SearcherTitle)); var position = input.worldBound.min + Vector2.up * (input.worldBound.height + 19f); var alignment = new SearcherWindow.Alignment(SearcherWindow.Alignment.Vertical.Top, SearcherWindow.Alignment.Horizontal.Left); SearcherWindow.Show(EditorWindow.focusedWindow, searcher, OnTypeSelected, position, null); }); m_HelpBox = typeField.Q <VisualElement>("helpbox"); var icon = m_HelpBox.Q <Image>("icon"); icon.image = EditorGUIUtility.IconContent("d_console.erroricon.sml").image; icon.scaleMode = ScaleMode.ScaleToFit; m_Message = m_HelpBox.Q <Label>("message"); if (!string.IsNullOrEmpty(ErrorMessage)) { m_HelpBox.style.display = DisplayStyle.Flex; m_Message.text = ErrorMessage; } else { m_HelpBox.style.display = DisplayStyle.None; m_Message.text = string.Empty; } var type = Target?.GetType(); if (type != null) { m_Text = typeField.Q <TextElement>("text"); m_Text.text = TypeNameResolver?.Invoke(type) ?? type.Name; } return(typeField); }
// Used to display data that is not meant to be persisted. The database will be overwritten after each call to SearcherWindow.Show(...). internal static void ShowTransientData(EditorWindow host, IEnumerable <SearcherItem> items, ISearcherAdapter adapter, Action <SearcherItem> selectionDelegate, Vector2 pos) { var database = SearcherDatabase.Create(items.ToList(), "", false); var searcher = new Searcher.Searcher(database, adapter); SearcherWindow.Show(host, searcher, x => { host.Focus(); selectionDelegate(x); return(!(Event.current?.modifiers.HasFlag(EventModifiers.Control)).GetValueOrDefault()); }, pos, null); }
void OnRunStepSelectorClicked(EventBase @event) { SearcherWindow.Show( EditorWindow.focusedWindow, new Searcher( TypeSearcherDatabase.GetRunStepDatabase(new HashSet <Type>(RunStep.GetAvailableTypes(type => !IsShown(type)))), new AddTypeSearcherAdapter("Select Run Script")), UpdateRunStep, @event.originalMousePosition + Vector2.up * 35.0f, a => { }, new SearcherWindow.Alignment(SearcherWindow.Alignment.Vertical.Top, SearcherWindow.Alignment.Horizontal.Left) ); }
internal static void ShowCriteria(ComponentQueryDeclarationModel query, string title, Vector2 position, Action <TypeHandle, TypeMember, BinaryOperatorKind> onComponentSelected) { var provider = (EcsSearcherDatabaseProvider)query.GraphModel.Stencil.GetSearcherDatabaseProvider(); var databases = provider.GetCriteriaSearcherDatabases(query); var criteriaAdapter = new SimpleSearcherAdapter(title); var searcher = new Searcher.Searcher(databases, criteriaAdapter); SearcherWindow.Show( EditorWindow.focusedWindow, searcher, item => OnItemSelected(item, onComponentSelected), position, null); }
public static void ShowTypes(Stencil stencil, Vector2 position, Action <TypeHandle, int> callback, SearcherFilter userFilter = null) { var databases = stencil.GetSearcherDatabaseProvider().GetTypesSearcherDatabases(); foreach (var database in databases) { database.MatchFilter = (query, item) => { if (!(item is TypeSearcherItem typeItem)) { return(false); } var filter = stencil.GetSearcherFilterProvider()?.GetTypeSearcherFilter(); var res = true; if (filter != null) { res &= GetFilterResult(filter, typeItem.Data); } if (userFilter != null) { res &= GetFilterResult(userFilter, typeItem.Data); } return(res); }; } var searcher = new Searcher.Searcher(databases, k_TypeAdapter) { SortComparison = k_TypeSort }; SearcherWindow.Show(EditorWindow.focusedWindow, searcher, item => { if (!(item is TypeSearcherItem typeItem)) { return(false); } callback(typeItem.Type, 0); return(true); }, position, null);
void OnRunStepSelectorClicked(EventBase @event) { var database = TypeSearcherDatabase.Populate <RunStep>( type => !type.HasAttribute <HideInInspector>(), type => RunStep.GetName(type), type => RunStep.GetCategory(type)); SearcherWindow.Show( EditorWindow.focusedWindow, new Searcher(database, new AddTypeSearcherAdapter("Select Run Script")), UpdateRunStep, @event.originalMousePosition + Vector2.up * 35.0f, a => { }, new SearcherWindow.Alignment(SearcherWindow.Alignment.Vertical.Top, SearcherWindow.Alignment.Horizontal.Left) ); }
internal static void ShowValues(string title, IEnumerable <string> values, Vector2 position, Action <string, int> callback) { var items = values.Select(v => new SearcherItem(v)).ToList(); var database = SearcherDatabase.Create(items, "", false); var searcher = new Searcher.Searcher(database, new SimpleSearcherAdapter(title)); SearcherWindow.Show(EditorWindow.focusedWindow, searcher, item => { if (item == null) { return(false); } callback(item.Name, item.Id); return(true); }, position, null); }
void AddDropdownCallbackDelegate(Rect buttonRect, ReorderableList list) { var database = TypeSearcherDatabase.Populate <IBuildStep>( type => !type.HasAttribute <HideInInspector>(), type => BuildStep.GetName(type), type => BuildStep.GetCategory(type)); var searcher = new Searcher(database, new AddTypeSearcherAdapter("Add Build Step")); var editorWindow = EditorWindow.focusedWindow; SearcherWindow.Show( editorWindow, searcher, AddStep, buttonRect.min + Vector2.up * 35.0f, a => { }, new SearcherWindow.Alignment(SearcherWindow.Alignment.Vertical.Top, SearcherWindow.Alignment.Horizontal.Left) ); }
void ShowSearcher(MouseDownEvent e) { if (NodeModel is SetVariableNodeModel model) { SearcherWindow.Show(EditorWindow.focusedWindow, ((VSGraphModel)model.GraphModel).GraphVariableModels.Where(g => GraphBuilder.GetVariableType(g) == GraphBuilder.VariableType.Variable) .Select(v => (SearcherItem) new VariableSearcherItem(v)).ToList(), "Pick a variable to set", item => { var variableSearcherItem = (item as VariableSearcherItem); if (variableSearcherItem == null) { return(true); } model.DeclarationModel = variableSearcherItem.declarationModel; model.DefineNode(); Store.Dispatch(new RefreshUIAction(UpdateFlags.GraphTopology)); return(true); }, Event.current.mousePosition); } }
void OnPickTargetButton(EventBase eventBase) { var items = DebuggerTracer.GetTargets(m_Store.GetState().currentTracingFrame, (m_Store.GetState().CurrentGraphModel?.AssetModel as Object)?.GetInstanceID() ?? -1) .Select(x => (SearcherItem) new EntitySearcherItem(x)).ToList(); SearcherWindow.Show(EditorWindow.focusedWindow, items, "Entities", i => { if (i == null) { return(true); } var t = ((EntitySearcherItem)i).Entity; m_Store.GetState().currentTracingTarget = t.EntityIndex; UpdateTracingMenu(); return(true); }, eventBase.originalMousePosition); eventBase.StopPropagation(); eventBase.PreventDefault(); }
void OnPickTargetButton(EventBase eventBase) { State state = m_Store.GetState(); IDebugger debugger = state.CurrentGraphModel.Stencil.Debugger; var targetIndices = debugger.GetDebuggingTargets(state.CurrentGraphModel); var items = targetIndices == null ? null : targetIndices.Select(x => (SearcherItem) new TargetSearcherItem(x, debugger.GetTargetLabel(state.CurrentGraphModel, x))).ToList(); if (items == null || !items.Any()) { items = new List <SearcherItem> { new SearcherItem("<No Object found>") } } ; SearcherWindow.Show(EditorWindow.focusedWindow, items, "Entities", i => { if (i == null || !(i is TargetSearcherItem targetSearcherItem)) { return(true); } state.CurrentTracingTarget = targetSearcherItem.Target; UpdateTracingMenu(); return(true); }, eventBase.originalMousePosition); eventBase.StopPropagation(); eventBase.PreventDefault(); } void OnFrameCounterKeyDown(KeyDownEvent evt) { if (evt.keyCode == KeyCode.Return || evt.keyCode == KeyCode.KeypadEnter) { int frame = m_CurrentFrameTextField.value; frame = Math.Max(0, Math.Min(frame, Time.frameCount)); m_Store.GetState().CurrentTracingFrame = frame; m_Store.GetState().CurrentTracingStep = -1; UpdateTracingMenu(); } }
internal static void ShowEnumValues(string title, Type enumType, Vector2 position, Action <Enum, int> callback) { var items = Enum.GetValues(enumType) .Cast <Enum>() .Select(v => new EnumValuesAdapter.EnumValueSearcherItem(v) as SearcherItem) .ToList(); var database = SearcherDatabase.Create(items, "", false); var searcher = new Searcher.Searcher(database, new EnumValuesAdapter(title)); SearcherWindow.Show(EditorWindow.focusedWindow, searcher, item => { if (item == null) { return(false); } callback(((EnumValuesAdapter.EnumValueSearcherItem)item).value, 0); return(true); }, position, null); }
static void PromptSearcher <T>(List <SearcherDatabase> databases, SearcherFilter filter, ISearcherAdapter adapter, Vector2 position, Action <T> callback) where T : ISearcherItemDataProvider { ApplyDatabasesFilter <T>(databases, filter); var searcher = new Searcher.Searcher(databases, adapter) { SortComparison = k_GraphElementSort }; SearcherWindow.Show(EditorWindow.focusedWindow, searcher, item => { if (item is T dataProvider) { callback(dataProvider); return(true); } return(false); }, position, null); }
private void DumpFrameTrace() { var state = m_Store.GetState(); var currentGraphModel = state?.CurrentGraphModel; var debugger = currentGraphModel?.Stencil?.Debugger; if (state == null || debugger == null) { return; } if (debugger.GetTracingSteps(currentGraphModel, state.CurrentTracingFrame, state.CurrentTracingTarget, out var stepList)) { try { var searcherItems = stepList.Select(MakeStepItem).ToList(); SearcherWindow.Show(EditorWindow.focusedWindow, searcherItems, "Steps", item => { if (item != null) { state.CurrentTracingStep = ((StepSearcherItem)item).Index; } return(true); }, Vector2.zero); } catch (Exception e) { UnityEngine.Debug.LogException(e); } } else { Debug.Log("No frame data"); } SearcherItem MakeStepItem(TracingStep step, int i) { return(new StepSearcherItem(step, i)); } }
static void PromptSearcher <T>(List <SearcherDatabase> databases, SearcherFilter filter, ISearcherAdapter adapter, Vector2 position, Action <T> callback) where T : ISearcherItemDataProvider { ApplyDatabasesFilter <T>(databases, filter); var searcher = new Searcher.Searcher(databases, adapter) { SortComparison = k_GraphElementSort }; var ctx = typeof(T) == typeof(GraphNodeModelSearcherItem) ? SearcherContext.Graph : SearcherContext.Stack; SearcherWindow.Show(EditorWindow.focusedWindow, searcher, item => { if (item is T dataProvider) { callback(dataProvider); return(true); } return(false); }, position, e => AnalyticsDataDelegate(e, ctx)); }
internal static void FindInGraph( EditorWindow host, VSGraphModel graph, Action <FindInGraphAdapter.FindSearcherItem> highlightDelegate, Action <FindInGraphAdapter.FindSearcherItem> selectionDelegate ) { var items = graph.GetAllNodes() .Where(x => !string.IsNullOrEmpty(x.Title)) .Select(MakeFindItems) .ToList(); var database = SearcherDatabase.Create(items, "", false); var searcher = new Searcher.Searcher(database, new FindInGraphAdapter(highlightDelegate)); var position = new Vector2(host.rootVisualElement.layout.center.x, 0); SearcherWindow.Show(host, searcher, item => { selectionDelegate(item as FindInGraphAdapter.FindSearcherItem); return(true); }, position, null, k_FindAlignment); }
public SetVariableNode(SetVariableNodeModel model, Store store, GraphView builderGraphView) : base(model, store, builderGraphView) { // make it clear the ux is not final this.Q("title").style.backgroundColor = new StyleColor(new Color32(147, 15, 109, 255)); this.Q <Label>("title-label").text = "Set "; var pill = new Pill(); var label = pill.Q <Label>("title-label"); label.text = model.DeclarationModel?.Name ?? "<Pick a variable>"; var pillContainer = new VisualElement(); pillContainer.AddToClassList("token"); pillContainer.style.justifyContent = Justify.Center; pillContainer.style.flexGrow = 1; pillContainer.Add(pill); titleContainer.Insert(1, pillContainer); titleContainer.styleSheets.Add(AssetDatabase.LoadAssetAtPath <StyleSheet>(UICreationHelper.templatePath + "Token.uss")); pill.RegisterCallback <MouseDownEvent>(_ => { SearcherWindow.Show(EditorWindow.focusedWindow, ((VSGraphModel)model.GraphModel).GraphVariableModels.Where(g => GraphBuilder.GetVariableType(g) == GraphBuilder.VariableType.Variable) .Select(v => (SearcherItem) new VariableSearcherItem(v)).ToList(), "Pick a variable to set", item => { var variableSearcherItem = (item as VariableSearcherItem); if (variableSearcherItem == null) { return(true); } model.DeclarationModel = variableSearcherItem.declarationModel; model.DefineNode(); store.Dispatch(new RefreshUIAction(UpdateFlags.GraphTopology)); return(true); }, Event.current.mousePosition); }); }
private void ShowSearcher(Vector2 position, int insertIndex, int insertViewIndex) { SearcherWindow.Show(EditorWindow.focusedWindow, searchItems, "Insert Line", item => { if (item is null) { return(true); // Prevent nullref when focus is lost before item is selected. } var lineText = string.Empty; var lineView = default(ScriptLineView); switch (item.Name) { case "Commands": return(false); // Do nothing. case "Comment": lineText = CommentScriptLine.IdentifierLiteral; break; case "Label": lineText = LabelScriptLine.IdentifierLiteral; break; case "Generic Text": var genericTextScriptLine = new GenericTextScriptLine(null, -1, string.Empty, null, true); lineView = new GenericTextLineView(genericTextScriptLine, linesContainer); break; case "Define": lineText = DefineScriptLine.IdentifierLiteral; break; default: lineText = CommandScriptLine.IdentifierLiteral + item.Name; break; } if (lineView is null) { lineView = CreateLineView(lineText, -1, true); } InsertLine(lineView, insertIndex, insertViewIndex); ScriptLineView.SetFocused(lineView); lineView.Q <TextField>().Q <VisualElement>(TextInputBaseField <string> .textInputUssName).Focus(); return(true); }, position); }
public override void Build() { Reset(); var targets = new List <Entity>(); targets.AddRange(Targets.Where(e => e != Entity.Null && EntityManager.Exists(e))); ReSeatTargets(targets); if (targets.Count == 0) { return; } InspectorElement = new EntityInspectorElement(Session, ActualTargets); RootElement.contentContainer.Add(InspectorElement); var addComponentButton = new Button(); addComponentButton.AddToClassList(UssClassNames.AddComponentButton); addComponentButton.text = "Add Component"; addComponentButton.RegisterCallback <MouseUpEvent>(evt => { using (var list = new NativeList <ComponentType>(10, Allocator.TempJob)) using (var map = new NativeHashMap <int, int>(10, Allocator.TempJob)) { var container = new EntityContainer(EntityManager, ActualTargets[0], true); PropertyContainer.Visit(ref container, new CommonComponentsVisitor(ActualTargets, EntityManager, list)); for (var i = 0; i < list.Length; ++i) { map.TryAdd(list[i].TypeIndex, 0); } var databases = new[] { ComponentSearcherDatabases.DynamicPopulateComponents(map), ComponentSearcherDatabases.DynamicPopulateSharedComponents(map), ComponentSearcherDatabases.DynamicPopulateBufferComponents(map), }; var searcher = new Searcher( databases, ComponentSearcherDatabases.SearcherAdapter); var editorWindow = EditorWindow.focusedWindow; var button = evt.target as Button; SearcherWindow.Show( editorWindow, searcher, AddType, button.worldBound.center + Vector2.up * (button.worldBound.height - 10.0f) / 2.0f, a => { }, new SearcherWindow.Alignment(SearcherWindow.Alignment.Vertical.Top, SearcherWindow.Alignment.Horizontal.Center) ); } }); RootElement.contentContainer.Add(addComponentButton); }
VisualElement MakeFieldRow(FieldModel fieldModel) { var field = new BlackboardField(null, fieldModel.Name, fieldModel.Type?.FriendlyName() ?? "<unknown>"); field.userData = fieldModel; var propertyView = new VisualElement(); var fieldRow = new BlackboardRow(field, propertyView) { userData = fieldModel }; fieldRow.expanded = m_ExpandedRows.Contains(fieldModel); field.Add(new Button(() => DeleteField(fieldRow, fieldModel)) { name = "deleteComponentIcon" }); var fieldType = new Button() { text = fieldModel.Type?.FriendlyName() ?? "<unknown>" }; fieldType.clickable.clicked += () => { InitializeTypeItemsAndCache(); // delay init as the type cache seems to have a weird timing issue otherwise SearcherWindow.Show(this, new Searcher.Searcher(new SearcherDatabase(TypeItems), new TypeSearcherAdapter("Pick a type")), item => { PickTypeSearcherItem titem = item as PickTypeSearcherItem; if (titem == null) { return(true); } fieldModel.Type = titem.Type; fieldType.text = titem.Type.FriendlyName(); if (titem.Shared) { SetStructType(CurrentStruct, StructType.SharedComponent); } SetModelDirty(); return(true); }, Event.current.mousePosition, null); }; propertyView.Add(new PropertyRow("Type", fieldType)); var toggle = new Toggle() { value = fieldModel.HideInInspector }; toggle.RegisterValueChangedCallback(e => { fieldModel.HideInInspector = e.newValue; SetModelDirty(); }); propertyView.Add(new PropertyRow("Hide in inspector", toggle)); // TODO ugly if (!fieldModel.Type.IsValueType && fieldModel.Type != typeof(GameObject)) { propertyView.Add(new Label("This is a reference type and requires the component to be a shared component")); } return(fieldRow); }
void OnPickTargetButton(EventBase eventBase) { State state = m_Store.GetState(); IDebugger debugger = state.CurrentGraphModel.Stencil.Debugger; var targetIndices = debugger.GetDebuggingTargets(state.CurrentGraphModel); var items = targetIndices == null ? null : targetIndices.Select(x => (SearcherItem) new TargetSearcherItem(x, debugger.GetTargetLabel(state.CurrentGraphModel, x))).ToList(); if (items == null || !items.Any()) { items = new List <SearcherItem> { new SearcherItem("<No Object found>") } } ; SearcherWindow.Show(EditorWindow.focusedWindow, items, "Entities", i => { if (i == null || !(i is TargetSearcherItem targetSearcherItem)) { return(true); } state.CurrentTracingTarget = targetSearcherItem.Target; UpdateTracingMenu(); return(true); }, eventBase.originalMousePosition); eventBase.StopPropagation(); eventBase.PreventDefault(); } void OnFrameCounterKeyDown(KeyDownEvent evt) { if (evt.keyCode == KeyCode.Return || evt.keyCode == KeyCode.KeypadEnter) { int frame = m_CurrentFrameTextField.value; frame = Math.Max(0, Math.Min(frame, Time.frameCount)); m_Store.GetState().CurrentTracingFrame = frame; m_Store.GetState().CurrentTracingStep = -1; UpdateTracingMenu(); } } void UpdateTracingMenu(bool force = true) { var state = m_Store.GetState(); if (EditorApplication.isPlaying && state.EditorDataModel.TracingEnabled) { m_PickTargetLabel.text = state.CurrentGraphModel?.Stencil?.Debugger?.GetTargetLabel(state.CurrentGraphModel, state.CurrentTracingTarget); m_PickTargetIcon.style.visibility = Visibility.Hidden; m_PickTargetButton.SetEnabled(true); if (EditorApplication.isPaused || !EditorApplication.isPlaying) { m_FirstFrameTracingButton.SetEnabled(true); m_PreviousFrameTracingButton.SetEnabled(true); m_PreviousStepTracingButton.SetEnabled(true); m_NextStepTracingButton.SetEnabled(true); m_NextFrameTracingButton.SetEnabled(true); m_LastFrameTracingButton.SetEnabled(true); m_CurrentFrameTextField.SetEnabled(true); m_TotalFrameLabel.SetEnabled(true); } else { state.CurrentTracingFrame = Time.frameCount; state.CurrentTracingStep = -1; m_FirstFrameTracingButton.SetEnabled(false); m_PreviousFrameTracingButton.SetEnabled(false); m_PreviousStepTracingButton.SetEnabled(false); m_NextStepTracingButton.SetEnabled(false); m_NextFrameTracingButton.SetEnabled(false); m_LastFrameTracingButton.SetEnabled(false); m_CurrentFrameTextField.SetEnabled(false); m_TotalFrameLabel.SetEnabled(false); } if (!m_LastUpdate.IsRunning) { m_LastUpdate.Start(); } if (force || EditorApplication.isPaused || m_LastUpdate.ElapsedMilliseconds > k_UpdateIntervalMs) { m_CurrentFrameTextField.value = state.CurrentTracingFrame; m_TotalFrameLabel.text = $"/{Time.frameCount.ToString()}"; if (state.CurrentTracingStep != -1) { m_TotalFrameLabel.text += $" [{state.CurrentTracingStep}/{state.MaxTracingStep}]"; } m_LastUpdate.Restart(); } } else { m_LastUpdate.Stop(); state.CurrentTracingFrame = Time.frameCount; state.CurrentTracingStep = -1; m_PickTargetLabel.text = ""; m_PickTargetIcon.style.visibility = StyleKeyword.Null; m_CurrentFrameTextField.value = 0; m_PickTargetButton.SetEnabled(false); m_CurrentFrameTextField.SetEnabled(false); m_TotalFrameLabel.text = "/0"; m_TotalFrameLabel.SetEnabled(false); m_FirstFrameTracingButton.SetEnabled(false); m_PreviousFrameTracingButton.SetEnabled(false); m_PreviousStepTracingButton.SetEnabled(false); m_NextStepTracingButton.SetEnabled(false); m_NextFrameTracingButton.SetEnabled(false); m_LastFrameTracingButton.SetEnabled(false); } } void OnFirstFrameTracingButton() { m_Store.GetState().CurrentTracingFrame = 0; m_Store.GetState().CurrentTracingStep = -1; UpdateTracingMenu(); } void OnPreviousFrameTracingButton() { if (m_Store.GetState().CurrentTracingFrame > 0) { m_Store.GetState().CurrentTracingFrame--; m_Store.GetState().CurrentTracingStep = -1; UpdateTracingMenu(); } } void OnPreviousStepTracingButton() { if (m_Store.GetState().CurrentTracingStep > 0) { m_Store.GetState().CurrentTracingStep--; } else { if (m_Store.GetState().CurrentTracingStep == -1) { m_Store.GetState().CurrentTracingStep = m_Store.GetState().MaxTracingStep; } else { if (m_Store.GetState().CurrentTracingFrame > 0) { m_Store.GetState().CurrentTracingFrame--; m_Store.GetState().CurrentTracingStep = m_Store.GetState().MaxTracingStep; } } } UpdateTracingMenu(); } void OnNextStepTracingButton() { if (m_Store.GetState().CurrentTracingStep < m_Store.GetState().MaxTracingStep&& m_Store.GetState().CurrentTracingStep >= 0) { m_Store.GetState().CurrentTracingStep++; } else { if (m_Store.GetState().CurrentTracingStep == -1 && (m_Store.GetState().CurrentTracingFrame < Time.frameCount)) { m_Store.GetState().CurrentTracingStep = 0; } else { if (m_Store.GetState().CurrentTracingFrame < Time.frameCount) { m_Store.GetState().CurrentTracingFrame++; m_Store.GetState().CurrentTracingStep = 0; } } } UpdateTracingMenu(); } void OnNextFrameTracingButton() { if (m_Store.GetState().CurrentTracingFrame < Time.frameCount) { m_Store.GetState().CurrentTracingFrame++; m_Store.GetState().CurrentTracingStep = -1; UpdateTracingMenu(); } } void OnLastFrameTracingButton() { m_Store.GetState().CurrentTracingFrame = Time.frameCount; m_Store.GetState().CurrentTracingStep = -1; UpdateTracingMenu(); } }