public override void OnInteractivePreviewGUI(Rect r, GUIStyle background) { var windowLayout = this.target as WindowLayout; WindowLayoutUtilities.DrawLayout(this.selectedIndexAspect, this.selectedIndexInner, this.selectedType, (type, idx, inner) => { this.selectedType = type; this.selectedIndexAspect = idx; this.selectedIndexInner = inner; }, ref this.tabsScrollPosition, windowLayout, r, drawComponents: null); }
public override void OnInteractivePreviewGUI(Rect r, GUIStyle background) { if (this.target is UnityEngine.UI.Windows.WindowTypes.LayoutWindowType layoutWindowType) { var windowLayout = layoutWindowType.layouts.GetActive().windowLayout; WindowLayoutUtilities.DrawLayout(this.selectedIndexAspect, this.selectedIndexInner, this.selectedType, (type, idx, inner) => { this.selectedType = type; this.selectedIndexAspect = idx; this.selectedIndexInner = inner; }, ref this.tabsScrollPosition, windowLayout, r, drawComponents: layoutWindowType); } }
public static bool DrawLayout(float aspect, WindowLayout windowLayout, Rect r, float offset = 20f, HashSet <WindowLayout> used = null, DeviceInfo.ScreenData screenData = default, DeviceInfo.OrientationData orientationData = default, UnityEngine.UI.Windows.WindowTypes.LayoutWindowType drawComponents = null) { if (used.Contains(windowLayout) == true) { return(false); } used.Add(windowLayout); var rSource = r; var rectOffset = r; if (offset > 0f) { rectOffset.x += offset; rectOffset.y += offset; rectOffset.height -= offset * 2f; rectOffset.width -= offset * 2f; var tWidth = rectOffset.height * aspect; if (tWidth > rectOffset.width) { rectOffset.y += rectOffset.height * 0.5f; rectOffset.height = rectOffset.width / aspect; rectOffset.y -= rectOffset.height * 0.5f; } else { rectOffset.x += rectOffset.width * 0.5f; rectOffset.width = rectOffset.height * aspect; rectOffset.x -= rectOffset.width * 0.5f; } } else { GUILayoutExt.DrawRect(rectOffset, new Color(0f, 0f, 0f, 0.4f)); } GUILayoutExt.DrawRect(rectOffset, new Color(0f, 0f, 0f, 0.2f)); GUILayoutExt.DrawBoxNotFilled(rectOffset, 1f, new Color(0.7f, 0.7f, 0.3f, 0.5f)); GUI.BeginClip(r); var resolution = windowLayout.canvasScaler.referenceResolution; /*windowLayout.rectTransform.anchoredPosition = new Vector2(r.x, r.y); * windowLayout.rectTransform.sizeDelta = new Vector2(r.width, r.height); * windowLayout.rectTransform.anchorMin = new Vector2(0.5f, 0.5f); * windowLayout.rectTransform.anchorMax = new Vector2(0.5f, 0.5f); * windowLayout.rectTransform.pivot = new Vector2(0.5f, 0.5f); * windowLayout.rectTransform.localRotation = Quaternion.identity; * windowLayout.rectTransform.localScale = Vector3.one;*/ r = rectOffset; { if (r.width > 0f && r.height > 0f) { Vector2 screenSize = new Vector2(r.width, r.height); var sizeDelta = Vector2.zero; float scaleFactor = 0; switch (windowLayout.canvasScaler.screenMatchMode) { case UnityEngine.UI.CanvasScaler.ScreenMatchMode.MatchWidthOrHeight: { const float kLogBase = 2; // We take the log of the relative width and height before taking the average. // Then we transform it back in the original space. // the reason to transform in and out of logarithmic space is to have better behavior. // If one axis has twice resolution and the other has half, it should even out if widthOrHeight value is at 0.5. // In normal space the average would be (0.5 + 2) / 2 = 1.25 // In logarithmic space the average is (-1 + 1) / 2 = 0 float logWidth = Mathf.Log(screenSize.x / windowLayout.canvasScaler.referenceResolution.x, kLogBase); float logHeight = Mathf.Log(screenSize.y / windowLayout.canvasScaler.referenceResolution.y, kLogBase); float logWeightedAverage = Mathf.Lerp(logWidth, logHeight, windowLayout.canvasScaler.matchWidthOrHeight); scaleFactor = Mathf.Pow(kLogBase, logWeightedAverage); break; } case UnityEngine.UI.CanvasScaler.ScreenMatchMode.Expand: { scaleFactor = Mathf.Min(screenSize.x / windowLayout.canvasScaler.referenceResolution.x, screenSize.y / windowLayout.canvasScaler.referenceResolution.y); break; } case UnityEngine.UI.CanvasScaler.ScreenMatchMode.Shrink: { scaleFactor = Mathf.Max(screenSize.x / windowLayout.canvasScaler.referenceResolution.x, screenSize.y / windowLayout.canvasScaler.referenceResolution.y); break; } } if (scaleFactor > 0f) { sizeDelta = new Vector2(screenSize.x / scaleFactor, screenSize.y / scaleFactor); windowLayout.rectTransform.sizeDelta = sizeDelta; windowLayout.rectTransform.pivot = new Vector2(0.5f, 0.5f); windowLayout.rectTransform.localScale = Vector3.one; resolution = windowLayout.rectTransform.sizeDelta; } } } var labelStyle = new GUIStyle(EditorStyles.label); labelStyle.alignment = TextAnchor.LowerLeft; var isHighlighted = false; var highlightedIndex = -1; var highlightedRect = Rect.zero; for (int i = 0; i < windowLayout.layoutElements.Length; ++i) { var element = windowLayout.layoutElements[i]; if (element == null) { windowLayout.ValidateEditor(); return(false); } var rect = WindowLayoutUtilities.GetRect(windowLayout.rectTransform, element.rectTransform, r, resolution, offset > 0f); if (rect.Contains(Event.current.mousePosition) == true) { if (highlightedIndex >= 0 && highlightedRect.width * highlightedRect.height < rect.width * rect.height) { continue; } highlightedIndex = i; highlightedRect = rect; isHighlighted = true; } } var hasInnerHighlight = false; for (int i = 0; i < windowLayout.layoutElements.Length; ++i) { var element = windowLayout.layoutElements[i]; var rect = WindowLayoutUtilities.GetRect(windowLayout.rectTransform, element.rectTransform, r, resolution, offset > 0f); using (new GUILayoutExt.GUIColorUsing(highlightedIndex < 0 || i == highlightedIndex ? Color.white : new Color(1f, 1f, 1f, 0.6f))) { if (drawComponents != null) { drawComponents.layouts.GetActive().GetLayoutComponentItemByTagId(element.tagId, windowLayout, out var componentItem); var comp = componentItem.component.GetEditorRef <WindowComponent>(); if (comp != null) { WindowLayoutUtilities.DrawComponent(rect, comp, componentItem.localTag); } WindowSystemSidePropertyDrawer.DrawLayoutMode(rect, element.rectTransform); } else { WindowSystemSidePropertyDrawer.DrawLayoutMode(rect, element.rectTransform); } } if (element.innerLayout != null) { hasInnerHighlight = WindowLayoutUtilities.DrawLayout(aspect, element.innerLayout, rect, offset: 0f, used: used, drawComponents: drawComponents); //WindowLayoutUtilities.DrawLayoutElements(highlightedIndex, rect, resolution, element.innerLayout, used); } } if (highlightedIndex >= 0 && hasInnerHighlight == false) { var element = windowLayout.layoutElements[highlightedIndex]; var rect = highlightedRect; var padding = 6f; var color = new Color(1f, 1f, 0f, 0.5f); var content = new GUIContent(element.name); GUI.Label(new Rect(padding, 0f, rSource.width, rSource.height - padding), content, labelStyle); var labelWidth = labelStyle.CalcSize(content).x + 10f; GUILayoutExt.DrawRect(new Rect(padding, rSource.height - 1f - padding, labelWidth, 1f), color); var p1 = new Vector3(labelWidth + padding, rSource.height - 1f - padding); var p2 = new Vector3(rect.x, rect.y); Handles.color = color; Handles.DrawLine(p1, p2); GUILayoutExt.DrawBoxNotFilled(rect, 1f, new Color(1f, 1f, 1f, 0.2f)); } GUI.EndClip(); if (offset > 0f) { if (orientationData.cutouts != null) { var safeArea = new Rect(orientationData.safeArea); safeArea = WindowLayoutUtilities.GetRectYSwapScaled(safeArea, new Vector2(screenData.width, screenData.height), r, rectOffset); GUILayoutExt.DrawBoxNotFilled(safeArea, 1f, Color.magenta); foreach (var rSafe in orientationData.cutouts) { var rSafeRect = WindowLayoutUtilities.GetRectYSwapScaled(rSafe, new Vector2(screenData.width, screenData.height), r, rectOffset); GUI.BeginClip(rSafeRect); if (rSafeRect.width < rSafeRect.height) { for (float step = -rSafeRect.height; step < rSafeRect.height; step += 5f) { var v1 = new Vector3(0f, step); var v2 = new Vector3(rSafeRect.width, step + rSafeRect.width); Handles.color = Color.yellow; Handles.DrawAAPolyLine(2f, v1, v2); } } else { for (float step = -rSafeRect.width; step < rSafeRect.width; step += 5f) { var v1 = new Vector3(step, 0f); var v2 = new Vector3(step + rSafeRect.height, rSafeRect.height); Handles.color = Color.yellow; Handles.DrawAAPolyLine(2f, v1, v2); } } GUI.EndClip(); GUILayoutExt.DrawBoxNotFilled(rSafeRect, 1f, Color.yellow); } } } return(isHighlighted); }
public static void DrawLayout(int selectedIndexAspect, int selectedIndexInner, int selectedType, System.Action <int, int, int> onSet, ref Vector2 tabsScrollPosition, WindowLayout windowLayout, Rect r, UnityEngine.UI.Windows.WindowTypes.LayoutWindowType drawComponents) { var offset = 20f; var aspect = 4f / 3f; DeviceInfo.OrientationData orienData = default; DeviceInfo.ScreenData screenData = default; if (Selection.objects.Length == 1) { if (WindowLayoutUtilities.loadedDevices.Count == 0) { var devices = new List <DeviceInfo>(); var deviceDirectoryPath = System.IO.Path.GetFullPath(System.IO.Path.Combine("Packages", "com.unity.device-simulator", ".DeviceDefinitions")); if (UnityEngine.Windows.Directory.Exists(deviceDirectoryPath) == true) { var deviceDirectory = new System.IO.DirectoryInfo(deviceDirectoryPath); var deviceDefinitions = deviceDirectory.GetFiles("*.device.json"); foreach (var deviceDefinition in deviceDefinitions) { string deviceFileText; using (System.IO.StreamReader sr = deviceDefinition.OpenText()) { deviceFileText = sr.ReadToEnd(); } var deviceInfo = JsonUtility.FromJson <DeviceInfo>(deviceFileText); devices.Add(deviceInfo); } } WindowLayoutUtilities.loadedDevices = devices; } GUILayout.BeginHorizontal(); var selectedName = "Default Aspects"; if (selectedType == 1) { var dInfo = WindowLayoutUtilities.loadedDevices[selectedIndexAspect]; selectedName = dInfo.friendlyName; } if (WindowLayoutUtilities.loadedDevices.Count > 0) { if (GUILayout.Button(selectedName, EditorStyles.toolbarDropDown) == true) { var popup = new Popup(title: "Devices", size: new Vector2(200f, 250f)); popup.autoClose = true; popup.autoHeight = false; popup.Item("Default Aspects", () => { onSet.Invoke(0, 0, 0); }, order: -1); for (var i = 0; i < WindowLayoutUtilities.loadedDevices.Count; ++i) { var idx = i; var deviceInfo = WindowLayoutUtilities.loadedDevices[i]; var screens = deviceInfo.Screens ?? deviceInfo.screens; if (screens != null) { popup.Item(deviceInfo.friendlyName, () => { onSet.Invoke(1, idx, 0); }, order: idx); } } popup.Show(); } } if (selectedType == 0) { var items = new Item[] { new Item() { name = "4:3", value = 4f / 3f }, new Item() { name = "16:9", value = 16f / 9f }, new Item() { name = "16:10", value = 16f / 10f }, new Item() { name = "5:4", value = 5f / 4f }, new Item() { name = "2:1", value = 2f / 1f }, new Item() { name = "3:4", value = 3f / 4f }, new Item() { name = "9:16", value = 9f / 16f }, new Item() { name = "10:16", value = 10f / 16f }, new Item() { name = "4:5", value = 4f / 5f }, new Item() { name = "1:2", value = 1f / 2f }, }; var tabs = items.Select(x => new GUITab(x.name, null)).ToArray(); selectedIndexAspect = GUILayoutExt.DrawTabs(selectedIndexAspect, ref tabsScrollPosition, tabs); aspect = items[selectedIndexAspect].value; } else if (selectedType == 1) { var deviceInfo = WindowLayoutUtilities.loadedDevices[selectedIndexAspect]; var screens = deviceInfo.Screens ?? deviceInfo.screens; var items = new Item[4]; for (int i = 0; i < screens.Length; ++i) { var oris = screens[i].orientations; for (int j = 0; j < oris.Length; ++j) { if (oris[j].orientation == ScreenOrientation.LandscapeRight) { var hData = screens[i]; var w = hData.width; hData.width = hData.height; hData.height = w; items[0] = new Item() { name = "Landscape Right", value = hData.width / (float)hData.height, data = oris[j], screenData = hData }; } else if (oris[j].orientation == ScreenOrientation.Landscape || oris[j].orientation == ScreenOrientation.LandscapeLeft) { var hData = screens[i]; var w = hData.width; hData.width = hData.height; hData.height = w; items[1] = new Item() { name = "Landscape Left", value = hData.width / (float)hData.height, data = oris[j], screenData = hData }; } else if (oris[j].orientation == ScreenOrientation.Portrait) { items[2] = new Item() { name = "Portrait Up", value = screens[i].width / (float)screens[i].height, data = oris[j], screenData = screens[i] }; } else if (oris[j].orientation == ScreenOrientation.PortraitUpsideDown) { items[3] = new Item() { name = "Portrait Down", value = screens[i].width / (float)screens[i].height, data = oris[j], screenData = screens[i] }; } } } var tabs = items.Select(x => new GUITab(x.name, null)).ToArray(); selectedIndexInner = GUILayoutExt.DrawTabs(selectedIndexInner, ref tabsScrollPosition, tabs); aspect = items[selectedIndexInner].value; orienData = items[selectedIndexInner].data; screenData = items[selectedIndexInner].screenData; } GUILayout.EndHorizontal(); } else { offset = 0f; } var used = new HashSet <WindowLayout>(); WindowLayoutUtilities.DrawLayout(aspect, windowLayout, r, offset, used, screenData, orienData, drawComponents); onSet.Invoke(selectedType, selectedIndexAspect, selectedIndexInner); }