private static void CopyMaskData(UnmaskedView.MaskData maskData, Dictionary <GUIViewProxy, MaskViewData> viewsAndResources) { viewsAndResources.Clear(); foreach (var unmaskedView in maskData.m_MaskData) { if (unmaskedView.Key == null) { continue; } var maskViewData = unmaskedView.Value; var unmaskedRegions = maskViewData.rects == null ? new List <Rect>(1) : maskViewData.rects.ToList(); if (unmaskedRegions.Count == 0) { unmaskedRegions.Add(new Rect(0f, 0f, unmaskedView.Key.position.width, unmaskedView.Key.position.height)); } viewsAndResources[unmaskedView.Key] = new MaskViewData() { maskType = maskViewData.maskType, rects = unmaskedRegions }; } }
void Mask() { var styles = m_Styles; var maskingColor = styles?.maskingColor ?? Color.magenta * new Color(1f, 1f, 1f, 0.8f); var highlightColor = styles?.highlightColor ?? Color.cyan * new Color(1f, 1f, 1f, 0.8f); var blockedInteractionColor = styles?.blockedInteractionColor ?? new Color(1, 1, 1, 0.5f); var highlightThickness = styles?.highlightThickness ?? 3f; var unmaskedViews = new UnmaskedView.MaskData(); unmaskedViews.AddParentFullyUnmasked(this); var highlightedViews = new UnmaskedView.MaskData(); MaskingManager.Mask( unmaskedViews, maskingColor, highlightedViews, highlightColor, blockedInteractionColor, highlightThickness ); MaskingEnabled = true; }
public static void Mask( UnmaskedView.MaskData unmaskedViewsAndRegionsMaskData, Color maskColor, UnmaskedView.MaskData highlightedRegionsMaskData, Color highlightColor, Color blockedInteractionsColor, float highlightThickness ) { Unmask(); CopyMaskData(unmaskedViewsAndRegionsMaskData, s_UnmaskedViews); CopyMaskData(highlightedRegionsMaskData, s_HighlightedViews); List <GUIViewProxy> views = new List <GUIViewProxy>(); GUIViewDebuggerHelperProxy.GetViews(views); foreach (var view in views) { if (!view.isValid) { continue; } MaskViewData maskViewData; var viewRect = new Rect(0, 0, view.position.width, view.position.height); // mask everything except the unmasked view rects if (s_UnmaskedViews.TryGetValue(view, out maskViewData)) { List <Rect> rects = maskViewData.rects; var maskedRects = GetNegativeSpaceRects(viewRect, rects); foreach (var rect in maskedRects) { var mask = new VisualElement(); mask.style.backgroundColor = maskColor; mask.SetLayout(rect); AddMaskToView(view, mask); s_Masks.Add(mask); } if (maskViewData.maskType == MaskType.BlockInteractions) { foreach (var rect in rects) { var mask = new VisualElement(); mask.style.backgroundColor = blockedInteractionsColor; mask.SetLayout(rect); AddMaskToView(view, mask); s_Masks.Add(mask); } } } // mask the whole view else { var mask = new VisualElement(); mask.style.backgroundColor = maskColor; mask.SetLayout(viewRect); AddMaskToView(view, mask); s_Masks.Add(mask); } if (s_HighlightedViews.TryGetValue(view, out maskViewData)) { var rects = maskViewData.rects; // unclip highlight to apply as "outer stroke" if it is being applied to some control(s) in the view var unclip = rects.Count > 1 || rects[0] != viewRect; var borderRadius = 5.0f; foreach (var rect in rects) { var highlighter = new VisualElement(); #if UNITY_2019_3_OR_NEWER highlighter.style.borderLeftColor = highlightColor; highlighter.style.borderRightColor = highlightColor; highlighter.style.borderTopColor = highlightColor; highlighter.style.borderBottomColor = highlightColor; #else highlighter.style.borderColor = highlightColor; #endif highlighter.style.borderLeftWidth = highlightThickness; highlighter.style.borderRightWidth = highlightThickness; highlighter.style.borderTopWidth = highlightThickness; highlighter.style.borderBottomWidth = highlightThickness; highlighter.style.borderBottomLeftRadius = borderRadius; highlighter.style.borderTopLeftRadius = borderRadius; highlighter.style.borderBottomRightRadius = borderRadius; highlighter.style.borderTopRightRadius = borderRadius; highlighter.pickingMode = PickingMode.Ignore; var layout = rect; if (unclip) { layout.xMin -= highlightThickness; layout.xMax += highlightThickness; layout.yMin -= highlightThickness; layout.yMax += highlightThickness; } highlighter.SetLayout(layout); UIElementsHelper.Add(UIElementsHelper.GetVisualTree(view), highlighter); s_Highlighters.Add(highlighter); } } } s_LastHighlightTime = EditorApplication.timeSinceStartup; }
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(); } }