using UnityEngine;
namespace E7.NotchSolution
{
///
/// Helper methods for Notch Solution's components.
///
public static class NotchSolutionUtility
{
internal static Rect defaultSafeArea = new Rect(0, 0, 1, 1);
internal static Rect[] defaultCutouts = new Rect[0];
internal static Rect cachedScreenSafeArea;
internal static Rect cachedScreenSafeAreaRelative;
internal static bool safeAreaRelativeCached;
internal static Rect[] cachedScreenCutouts;
internal static Rect[] cachedScreenCutoutsRelative;
internal static bool cutoutsRelativeCached;
///
/// You can use it in any of your component that uses .
///
/// -
/// If true, should trust the values sent to .
///
/// -
/// If false, should trust API because we detected something like
/// [Device Simulator package](https://docs.unity3d.com/Packages/com.unity.device-simulator@latest/) is
/// controlling the value and it is now useful in editor.
///
///
///
public static bool ShouldUseNotchSimulatorValue
{
get
{
#if UNITY_EDITOR
if (NotchSolutionUtilityEditor.UnityDeviceSimulatorActive)
{
return false;
}
return true;
#else
return false;
#endif
}
}
///
/// Calculated from API without caring about simulated value.
/// Note that 2019.3 Unity Device Simulator can mock the so this is not
/// necessary real in editor.
///
// TODO : Cache potential, but many pitfalls awaits so I have not done it.
// - Some first frames (1~3) Unity didn't return a rect that take account of safe area for some reason. If we cache that then we failed.
// - Orientation change requries clearing the cache again. Manually or automatically? How?
internal static Rect ScreenSafeAreaRelative
{
get
{
var absolutePaddings = Screen.safeArea;
cachedScreenSafeAreaRelative = ToScreenRelativeRect(absolutePaddings);
cachedScreenSafeArea = absolutePaddings;
safeAreaRelativeCached = true;
return cachedScreenSafeAreaRelative;
}
}
///
/// Calculated from API without caring about simulated value.
/// Note that 2019.3 Unity Device Simulator can mock the so this is not
/// necessary real in editor.
///
// TODO : Cache potential, but many pitfalls awaits so I have not done it.
// - Some first frames (1~3) Unity didn't return a rect that take account of safe area for some reason.
// If we cache that then we failed.
// - Orientation change requires clearing the cache again. Manually or automatically? How?
internal static Rect[] ScreenCutoutsRelative
{
get
{
var absoluteCutouts = Screen.cutouts;
cachedScreenCutoutsRelative = new Rect[absoluteCutouts.Length];
for (var i = 0; i < absoluteCutouts.Length; i++)
{
cachedScreenCutoutsRelative[i] = ToScreenRelativeRect(absoluteCutouts[i]);
}
cachedScreenCutouts = absoluteCutouts;
cutoutsRelativeCached = true;
return cachedScreenCutoutsRelative;
}
}
internal static ScreenOrientation GetCurrentOrientation()
{
return Screen.width > Screen.height ? ScreenOrientation.Landscape : ScreenOrientation.Portrait;
}
private static Rect ToScreenRelativeRect(Rect absoluteRect)
{
#if UNITY_STANDALONE
var w = absoluteRect.width;
var h = absoluteRect.height;
#else
int w = Screen.currentResolution.width;
int h = Screen.currentResolution.height;
#endif
//Debug.Log($"{w} {h} {Screen.currentResolution} {absoluteRect}");
return new Rect(
absoluteRect.x / w,
absoluteRect.y / h,
absoluteRect.width / w,
absoluteRect.height / h
);
}
}
}