public static UnmaskedView CreateInstanceForEditorWindow <T>(IList <GUIControlSelector> unmaskedControls = null) where T : EditorWindow { UnmaskedView result = new UnmaskedView(); result.m_SelectorType = SelectorType.EditorWindow; result.m_EditorWindowType.type = typeof(T); if (unmaskedControls != null) { result.m_UnmaskedControls.AddRange(unmaskedControls); } return(result); }
internal static UnmaskedView CreateInstanceForGUIView <T>(IList <GUIControlSelector> unmaskedControls = null) { if (!GUIViewProxy.IsAssignableFrom(typeof(T))) { throw new InvalidOperationException("Type must be assignable to GUIView"); } UnmaskedView result = new UnmaskedView(); result.m_SelectorType = SelectorType.GUIView; result.m_ViewType.type = typeof(T); if (unmaskedControls != null) { result.m_UnmaskedControls.AddRange(unmaskedControls); } return(result); }
private static IEnumerable <GUIViewProxy> GetMatchingViews( UnmaskedView unmaskedView, List <GUIViewProxy> allViews, Dictionary <GUIViewProxy, HashSet <EditorWindow> > viewsWithWindows ) { var matchingViews = new HashSet <GUIViewProxy>(new GUIViewProxyComparer()); switch (unmaskedView.m_SelectorType) { case SelectorType.EditorWindow: var targetEditorWindowType = unmaskedView.editorWindowType; if (targetEditorWindowType == null) { throw new ArgumentException( string.Format( "Specified unmasked view does not refer to a known EditorWindow type:\n{0}", JsonUtility.ToJson(unmaskedView, true) ), "unmaskedView" ); } if (targetEditorWindowType != null) { // make sure desired window is in current layout // TODO: allow trainer to specify desired dock area if window doesn't yet exist? // var window = EditorWindow.GetWindow(targetEditorWindowType); var window = Resources.FindObjectsOfTypeAll(targetEditorWindowType).Cast <EditorWindow>().ToArray().FirstOrDefault(); if (window == null || window.GetParent() == null) { return(matchingViews); } window.Show(); if (!allViews.Contains(window.GetParent())) { allViews.Add(window.GetParent()); } foreach (var view in allViews) { if (!view.IsActualViewAssignableTo(targetEditorWindowType)) { continue; } HashSet <EditorWindow> windows; if (!viewsWithWindows.TryGetValue(view, out windows)) { viewsWithWindows[view] = windows = new HashSet <EditorWindow>(); } windows.Add(window); matchingViews.Add(view); } } break; case SelectorType.GUIView: var targetViewType = unmaskedView.m_ViewType.type; if (targetViewType == null) { throw new ArgumentException( string.Format( "Specified unmasked view does not refer to a known GUIView type:\n{0}", JsonUtility.ToJson(unmaskedView, true) ), "unmaskedView" ); } if (targetViewType != null) { foreach (var view in allViews) { if (view.IsGUIViewAssignableTo(targetViewType)) { matchingViews.Add(view); } } } break; } if (matchingViews.Count == 0) { throw new ArgumentException( string.Format( "Specified unmasked view refers to a view that could not be found:\n{0}", JsonUtility.ToJson(unmaskedView, true) ), "unmaskedView" ); } return(matchingViews); }
private void ApplyMaskingSettings(bool applyMask) { MaskingManager.Unmask(); if (!applyMask || !maskingEnabled || m_CurrentTutorial == null || m_CurrentTutorial.currentPage == null || IsParentNull()) { InternalEditorUtility.RepaintAllViews(); return; } var maskingSettings = m_CurrentTutorial.currentPage.currentMaskingSettings; try { if (maskingSettings != null && maskingSettings.enabled) { var unmaskedViews = UnmaskedView.GetViewsAndRects(maskingSettings.unmaskedViews); if (m_CurrentTutorial.currentPageIndex <= m_FarthestPageCompleted) { unmaskedViews = new UnmaskedView.MaskData(); } UnmaskedView.MaskData highlightedViews; // if the current page contains no instructions, assume unmasked views should be highlighted because they are called out in narrative text if (unmaskedViews.Count > 0 && !m_CurrentTutorial.currentPage.paragraphs.Any(p => p.type == ParagraphType.Instruction)) { highlightedViews = (UnmaskedView.MaskData)unmaskedViews.Clone(); } // otherwise, if the current page is completed, highlight this window else if (canMoveToNextPage) { highlightedViews = new UnmaskedView.MaskData(); highlightedViews.AddParent(this); } // otherwise, highlight manually specified control rects if there are any else { var unmaskedControls = new List <GUIControlSelector>(); var unmaskedViewsWithControlsSpecified = maskingSettings.unmaskedViews.Where(v => v.GetUnmaskedControls(unmaskedControls) > 0).ToArray(); // if there are no manually specified control rects, highlight all unmasked views highlightedViews = UnmaskedView.GetViewsAndRects( unmaskedViewsWithControlsSpecified.Length == 0 ? maskingSettings.unmaskedViews : unmaskedViewsWithControlsSpecified ); } // ensure tutorial window's HostView and tooltips are not masked unmaskedViews.AddParent(this); unmaskedViews.AddTooltipViews(); // tooltip views should not be highlighted highlightedViews.RemoveTooltipViews(); MaskingManager.Mask( unmaskedViews, m_Styles == null ? Color.magenta * new Color(1f, 1f, 1f, 0.8f) : m_Styles.maskingColor, highlightedViews, m_Styles == null ? Color.cyan * new Color(1f, 1f, 1f, 0.8f) : m_Styles.highlightColor, m_Styles == null ? 3f : m_Styles.highlightThickness ); } } catch (ArgumentException e) { if (ProjectMode.IsAuthoringMode()) { Debug.LogException(e, m_CurrentTutorial.currentPage); } else { Console.WriteLine(StackTraceUtility.ExtractStringFromException(e)); } } finally { InternalEditorUtility.RepaintAllViews(); } }
void ApplyMaskingSettings(bool applyMask) { // TODO IsParentNull() probably not needed anymore as TutorialWindow is always parented in the current design & layout. if (!applyMask || !maskingEnabled || currentTutorial == null || currentTutorial.currentPage == null || IsParentNull() || TutorialManager.IsLoadingLayout) { MaskingManager.Unmask(); InternalEditorUtility.RepaintAllViews(); return; } MaskingSettings maskingSettings = currentTutorial.currentPage.currentMaskingSettings; try { if (maskingSettings == null || !maskingSettings.enabled) { MaskingManager.Unmask(); } else { bool foundAncestorProperty; var unmaskedViews = UnmaskedView.GetViewsAndRects(maskingSettings.unmaskedViews, out foundAncestorProperty); if (foundAncestorProperty) { // Keep updating mask when target property is not unfolded QueueMaskUpdate(); } if (currentTutorial.currentPageIndex <= m_FarthestPageCompleted) { unmaskedViews = new UnmaskedView.MaskData(); } UnmaskedView.MaskData highlightedViews; // if the current page contains no instructions, assume unmasked views should be highlighted because they are called out in narrative text if (unmaskedViews.Count > 0 && !currentTutorial.currentPage.paragraphs.Any(p => p.type == ParagraphType.Instruction)) { highlightedViews = (UnmaskedView.MaskData)unmaskedViews.Clone(); } else if (canMoveToNextPage) // otherwise, if the current page is completed, highlight this window { highlightedViews = new UnmaskedView.MaskData(); highlightedViews.AddParentFullyUnmasked(this); } else // otherwise, highlight manually specified control rects if there are any { var unmaskedControls = new List <GUIControlSelector>(); var unmaskedViewsWithControlsSpecified = maskingSettings.unmaskedViews.Where(v => v.GetUnmaskedControls(unmaskedControls) > 0).ToArray(); // if there are no manually specified control rects, highlight all unmasked views highlightedViews = UnmaskedView.GetViewsAndRects( unmaskedViewsWithControlsSpecified.Length == 0 ? maskingSettings.unmaskedViews : unmaskedViewsWithControlsSpecified ); } // ensure tutorial window's HostView and tooltips are not masked unmaskedViews.AddParentFullyUnmasked(this); unmaskedViews.AddTooltipViews(); // tooltip views should not be highlighted highlightedViews.RemoveTooltipViews(); MaskingManager.Mask( unmaskedViews, styles == null ? Color.magenta * new Color(1f, 1f, 1f, 0.8f) : styles.MaskingColor, highlightedViews, styles == null ? Color.cyan * new Color(1f, 1f, 1f, 0.8f) : styles.HighlightColor, styles == null ? new Color(1, 1, 1, 0.5f) : styles.BlockedInteractionColor, styles == null ? 3f : styles.HighlightThickness ); } } catch (ArgumentException e) { if (s_AuthoringMode) { Debug.LogException(e, currentTutorial.currentPage); } else { Console.WriteLine(StackTraceUtility.ExtractStringFromException(e)); } MaskingManager.Unmask(); } finally { InternalEditorUtility.RepaintAllViews(); } }
private static IEnumerable <GUIViewProxy> GetMatchingViews( UnmaskedView unmaskedView, List <GUIViewProxy> allViews, Dictionary <GUIViewProxy, HashSet <EditorWindow> > viewsWithWindows) { var matchingViews = new HashSet <GUIViewProxy>(new GUIViewProxyComparer()); switch (unmaskedView.m_SelectorType) { case SelectorType.EditorWindow: var targetEditorWindowType = unmaskedView.editorWindowType; if (targetEditorWindowType == null) { throw new ArgumentException( $"Specified unmasked view does not refer to a known EditorWindow type:\n{JsonUtility.ToJson(unmaskedView, true)}", "unmaskedView" ); } if (targetEditorWindowType != null) { // make sure desired window is in current layout // TODO: allow trainer to specify desired dock area if window doesn't yet exist? // var window = EditorWindow.GetWindow(targetEditorWindowType); var window = Resources.FindObjectsOfTypeAll(targetEditorWindowType).Cast <EditorWindow>().ToArray().FirstOrDefault(); if (window == null || window.GetParent() == null) { return(matchingViews); } // Postpone showing window until next editor update // GetMatchingViews could be called in response to window closing s_EditorWindowsToShow.Push(window); if (!allViews.Contains(window.GetParent())) { allViews.Add(window.GetParent()); } foreach (var view in allViews) { if (!view.IsActualViewAssignableTo(targetEditorWindowType)) { continue; } HashSet <EditorWindow> windows; if (!viewsWithWindows.TryGetValue(view, out windows)) { viewsWithWindows[view] = windows = new HashSet <EditorWindow>(); } windows.Add(window); matchingViews.Add(view); } } break; case SelectorType.GUIView: var targetViewType = unmaskedView.m_ViewType.type; if (targetViewType == null) { throw new ArgumentException( $"Specified unmasked view does not refer to a known GUIView type:\n{JsonUtility.ToJson(unmaskedView, true)}", "unmaskedView" ); } if (targetViewType != null) { foreach (var view in allViews) { if (view.IsGUIViewAssignableTo(targetViewType)) { matchingViews.Add(view); } } } break; } // TODO Not necessarily exception worthy. We are using a "delayed masking" occasionally, e.g. when switching // to Play mode and we want to unmask Game view which is not yet visible (in the background tab by defaul). //if (matchingViews.Count == 0) //{ // throw new ArgumentException( // $"Specified unmasked view refers to a view that could not be found:\n{JsonUtility.ToJson(unmaskedView, true)}" // , "unmaskedView" // ); //} return(matchingViews); }