Skip to content

Instantly share code, notes, and snippets.

@paulb39
Created March 25, 2020 02:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paulb39/5f5375e75333274fc165ffc6b0bd8d5d to your computer and use it in GitHub Desktop.
Save paulb39/5f5375e75333274fc165ffc6b0bd8d5d to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine.Windows;
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Graphics.Display;
using Windows.Storage;
using Windows.UI;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
using UnityPlayer;
namespace test_18_uwp
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
//private WinRTBridge.WinRTBridge _bridge;
//private AppCallbacks m_AppCallbacks;
private SplashScreen splash;
private Rect splashImageRect;
private WindowSizeChangedEventHandler onResizeHandler;
private bool isPhone = false;
public MainPage()
{
this.InitializeComponent();
//NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Required;
NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Disabled;
//AppCallbacks appCallbacks = AppCallbacks.Instance;
// Setup scripting bridge
//_bridge = new WinRTBridge.WinRTBridge();
var m_AppCallbacks = new AppCallbacks();
m_AppCallbacks.SetBridge(Constants._bridge);
bool isWindowsHolographic = false;
#if UNITY_HOLOGRAPHIC
// If application was exported as Holographic check if the device actually supports it,
// otherwise we treat this as a normal XAML application
isWindowsHolographic = AppCallbacks.IsMixedRealitySupported();
#endif
if (isWindowsHolographic)
{
m_AppCallbacks.InitializeViewManager(Window.Current.CoreWindow);
}
else
{
m_AppCallbacks.RenderingStarted += () => { RemoveSplashScreen(); };
if (Windows.Foundation.Metadata.ApiInformation.IsApiContractPresent("Windows.Phone.PhoneContract", 1))
isPhone = true;
m_AppCallbacks.SetSwapChainPanel(GetSwapChainPanel());
m_AppCallbacks.SetCoreWindowEvents(Window.Current.CoreWindow);
m_AppCallbacks.InitializeD3DXAML();
splash = ((App)App.Current).splashScreen;
GetSplashBackgroundColor();
OnResize();
onResizeHandler = new WindowSizeChangedEventHandler((o, e) => OnResize());
Window.Current.SizeChanged += onResizeHandler;
m_AppCallbacks.Initialized += OnInitialized;
}
}
private void OnInitialized()
{
AppCallbacks.Instance.InvokeOnAppThread(() =>
{
SetEventCallback(UnityToXAMLEventCallback);
}, false);
}
public static void SetEventCallback(UnityEvent e)
{
// Get the object the communication class is attached to.
UnityEngine.GameObject gameObject = UnityEngine.GameObject.Find("Main Camera");
if (gameObject != null)
{
// Create an event object on that class so we can send events.
var bh = gameObject.GetComponent<ButtonHandlers>();
if (bh != null)
{
bh.unityButtonEvent = new ButtonHandlers.OnEvent(e);
}
}
else
{
throw new Exception("Camera not found, have you exported the correct scene?");
}
}
public delegate void UnityEvent(object arg);
/// <param name="arg"></param>
public void UnityToXAMLEventCallback(object arg)
{
AppCallbacks.Instance.InvokeOnUIThread(new UnityPlayer.AppCallbackItem(() =>
{
// Ensure this runs on the UI Thread so we can update the UX
this.Frame.Navigate(typeof(DashPage), null);
}
), false);
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached. The Parameter
/// property is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
splash = (SplashScreen)e.Parameter;
OnResize();
}
private void OnResize()
{
if (splash != null)
{
splashImageRect = splash.ImageLocation;
PositionImage();
}
}
private void PositionImage()
{
var inverseScaleX = 1.0f;
var inverseScaleY = 1.0f;
if (isPhone)
{
inverseScaleX = inverseScaleX / DXSwapChainPanel.CompositionScaleX;
inverseScaleY = inverseScaleY / DXSwapChainPanel.CompositionScaleY;
}
ExtendedSplashImage.SetValue(Canvas.LeftProperty, splashImageRect.X * inverseScaleX);
ExtendedSplashImage.SetValue(Canvas.TopProperty, splashImageRect.Y * inverseScaleY);
ExtendedSplashImage.Height = splashImageRect.Height * inverseScaleY;
ExtendedSplashImage.Width = splashImageRect.Width * inverseScaleX;
}
private async void GetSplashBackgroundColor()
{
try
{
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///AppxManifest.xml"));
string manifest = await FileIO.ReadTextAsync(file);
int idx = manifest.IndexOf("SplashScreen");
manifest = manifest.Substring(idx);
idx = manifest.IndexOf("BackgroundColor");
if (idx < 0) // background is optional
return;
manifest = manifest.Substring(idx);
idx = manifest.IndexOf("\"");
manifest = manifest.Substring(idx + 1);
idx = manifest.IndexOf("\"");
manifest = manifest.Substring(0, idx);
int value = 0;
bool transparent = false;
if (manifest.Equals("transparent"))
transparent = true;
else if (manifest[0] == '#') // color value starts with #
value = Convert.ToInt32(manifest.Substring(1), 16) & 0x00FFFFFF;
else
return; // at this point the value is 'red', 'blue' or similar, Unity does not set such, so it's up to user to fix here as well
byte r = (byte)(value >> 16);
byte g = (byte)((value & 0x0000FF00) >> 8);
byte b = (byte)(value & 0x000000FF);
await CoreWindow.GetForCurrentThread().Dispatcher.RunAsync(CoreDispatcherPriority.High, delegate()
{
byte a = (byte)(transparent ? 0x00 : 0xFF);
ExtendedSplashGrid.Background = new SolidColorBrush(Color.FromArgb(a, r, g, b));
});
}
catch (Exception)
{}
}
public SwapChainPanel GetSwapChainPanel()
{
return DXSwapChainPanel;
}
public void RemoveSplashScreen()
{
DXSwapChainPanel.Children.Remove(ExtendedSplashGrid);
if (onResizeHandler != null)
{
Window.Current.SizeChanged -= onResizeHandler;
onResizeHandler = null;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment