From 37d2410a51e11f4d258f573fea901c5849cabff8 Mon Sep 17 00:00:00 2001 From: Yoshi Askharoun Date: Fri, 16 Jul 2021 20:17:23 -0500 Subject: [PATCH] Added basic wrapper for Windows.UI.Xaml.Window implementing IRenderWindow --- .../Microsoft/Iris/Render/IRenderEngine.cs | 1 - .../Iris/Render/Internal/RenderEngine.cs | 6 +- .../Iris/Render/Internal/RenderSession.cs | 2 +- UIX.Skia/Microsoft/Iris/Application.cs | 2 +- UIX.Skia/Microsoft/Iris/Session/UISession.cs | 3 +- Xune.Uno/Xune.Uno.Shared/MainPage.xaml.cs | 265 ++++++++++++++++++ 6 files changed, 271 insertions(+), 8 deletions(-) diff --git a/UIX.RenderApi.Skia/Microsoft/Iris/Render/IRenderEngine.cs b/UIX.RenderApi.Skia/Microsoft/Iris/Render/IRenderEngine.cs index 4ec6436..87f8842 100644 --- a/UIX.RenderApi.Skia/Microsoft/Iris/Render/IRenderEngine.cs +++ b/UIX.RenderApi.Skia/Microsoft/Iris/Render/IRenderEngine.cs @@ -11,7 +11,6 @@ namespace Microsoft.Iris.Render public interface IRenderEngine : IRenderObject, IDisposable { void Initialize( - SkiaSharp.SKSurface skSurface, GraphicsDeviceType typeGraphics, GraphicsRenderingQuality renderingQuality, SoundDeviceType typeSound); diff --git a/UIX.RenderApi.Skia/Microsoft/Iris/Render/Internal/RenderEngine.cs b/UIX.RenderApi.Skia/Microsoft/Iris/Render/Internal/RenderEngine.cs index 3d4f7e4..702c043 100644 --- a/UIX.RenderApi.Skia/Microsoft/Iris/Render/Internal/RenderEngine.cs +++ b/UIX.RenderApi.Skia/Microsoft/Iris/Render/Internal/RenderEngine.cs @@ -81,7 +81,6 @@ namespace Microsoft.Iris.Render.Internal } void IRenderEngine.Initialize( - SkiaSharp.SKSurface skSurface, GraphicsDeviceType typeGraphics, GraphicsRenderingQuality renderingQuality, SoundDeviceType typeSound) @@ -90,13 +89,14 @@ namespace Microsoft.Iris.Render.Internal Debug2.Validate(IsSoundDeviceAvailable(typeSound), typeof(InvalidOperationException), "Sound device type not available"); m_typeGraphics = typeGraphics; m_typeSound = typeSound; + m_renderSession.Initialize(); // TODO: Set up input system //m_inputSystem = new InputSystem(this.m_renderSession, this.m_renderWindow); } - IRenderSession IRenderEngine.Session => null;//throw new NotSupportedException("Skia does not use render sessions"); m_renderSession; + IRenderSession IRenderEngine.Session => m_renderSession;//throw new NotSupportedException("Skia does not use render sessions"); m_renderSession; - internal RenderSession Session => null; + internal RenderSession Session => m_renderSession; IRenderWindow IRenderEngine.Window => null; diff --git a/UIX.RenderApi.Skia/Microsoft/Iris/Render/Internal/RenderSession.cs b/UIX.RenderApi.Skia/Microsoft/Iris/Render/Internal/RenderSession.cs index 26eacc4..bb7c2ab 100644 --- a/UIX.RenderApi.Skia/Microsoft/Iris/Render/Internal/RenderSession.cs +++ b/UIX.RenderApi.Skia/Microsoft/Iris/Render/Internal/RenderSession.cs @@ -61,7 +61,7 @@ namespace Microsoft.Iris.Render.Internal } } - IGraphicsDevice IRenderSession.GraphicsDevice => m_renderEngine.Window.GraphicsDevice; + IGraphicsDevice IRenderSession.GraphicsDevice => null;// m_renderEngine.Window.GraphicsDevice; ISoundDevice IRenderSession.SoundDevice => m_renderEngine.SoundDevice; diff --git a/UIX.Skia/Microsoft/Iris/Application.cs b/UIX.Skia/Microsoft/Iris/Application.cs index 0a7fb40..482fcc6 100644 --- a/UIX.Skia/Microsoft/Iris/Application.cs +++ b/UIX.Skia/Microsoft/Iris/Application.cs @@ -175,7 +175,7 @@ namespace Microsoft.Iris default: throw new ArgumentException(InvariantString.Format("Unknown sound type {0}", soundType)); } - s_session.InitializeRenderingDevices(skSurface, graphicsType, (GraphicsRenderingQuality)s_renderingQuality, soundType); + s_session.InitializeRenderingDevices(graphicsType, (GraphicsRenderingQuality)s_renderingQuality, soundType); s_renderingQuality = (RenderingQuality)s_session.RenderSession.GraphicsDevice.RenderingQuality; InitializeCommon(true); if (!s_EnableAnimations) diff --git a/UIX.Skia/Microsoft/Iris/Session/UISession.cs b/UIX.Skia/Microsoft/Iris/Session/UISession.cs index 1bb271f..8df5b42 100644 --- a/UIX.Skia/Microsoft/Iris/Session/UISession.cs +++ b/UIX.Skia/Microsoft/Iris/Session/UISession.cs @@ -76,12 +76,11 @@ namespace Microsoft.Iris.Session } internal void InitializeRenderingDevices( - SKSurface skSurface, GraphicsDeviceType graphicsType, GraphicsRenderingQuality renderingQuality, SoundDeviceType soundType) { - _engine.Initialize(skSurface, graphicsType, renderingQuality, soundType); + _engine.Initialize(graphicsType, renderingQuality, soundType); _effectManager = new EffectManager(_session); _soundManager = new SoundManager(this, _session); _animationManager = new AnimationManager(_session); diff --git a/Xune.Uno/Xune.Uno.Shared/MainPage.xaml.cs b/Xune.Uno/Xune.Uno.Shared/MainPage.xaml.cs index 07cb689..71e65cc 100644 --- a/Xune.Uno/Xune.Uno.Shared/MainPage.xaml.cs +++ b/Xune.Uno/Xune.Uno.Shared/MainPage.xaml.cs @@ -1,3 +1,5 @@ +using Microsoft.Iris.Input; +using Microsoft.Iris.Render; using SkiaSharp; using SkiaSharp.Views.UWP; using System; @@ -10,6 +12,7 @@ using System.Threading.Tasks; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.UI.Core; +using Windows.UI.ViewManagement; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; @@ -48,4 +51,266 @@ namespace Xune.Uno // void*** ptr = (void***)GCHandle.Alloc(new void*[1], GCHandleType.Pinned).AddrOfPinnedObject(); //} } + + public sealed class IrisCoreWindow : IRenderWindow + { + private bool isDragging = false; + private Window XamlWindow { get; set; } + private ApplicationView CurrentView => ApplicationView.GetForCurrentView(); + private Rect VisibleBounds => CurrentView.VisibleBounds; + + public IrisCoreWindow(Window window) + { + XamlWindow = window; + + XamlWindow.SizeChanged += XamlWindow_SizeChanged; + XamlWindow.Activated += XamlWindow_Activated; + XamlWindow.Content.GotFocus += XamlWindowContent_GotFocus; + XamlWindow.Content.LostFocus += XamlWindowContent_LostFocus; + XamlWindow.Closed += XamlWindow_Closed; + XamlWindow.Content.DragStarting += XamlWindowContent_DragStarting; + XamlWindow.Content.DropCompleted += XamlWindowContent_DropCompleted; + if (XamlWindow.Content is FrameworkElement elem) + { + elem.Loaded += XamlWindowContent_Loaded; + } + } + + public int Left => (int)VisibleBounds.Left; + + public int Top => (int)VisibleBounds.Top; + + public int Right => (int)VisibleBounds.Right; + + public int Bottom => (int)VisibleBounds.Bottom; + + public int Width => (int)VisibleBounds.Width; + + public int Height => (int)VisibleBounds.Height; + + public HWND WindowHandle => throw new PlatformNotSupportedException("UWP cannot use HWNDs directly"); + + public Microsoft.Iris.Render.Size ClientSize { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public Microsoft.Iris.Render.Size InitialClientSize { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public FormPlacement InitialPlacement { set => throw new NotImplementedException(); } + + public FormPlacement FinalPlacement => throw new NotImplementedException(); + + public int MinResizeWidth + { + get => (int)ApplicationView.PreferredLaunchViewSize.Width; + set => CurrentView.SetPreferredMinSize(new Windows.Foundation.Size(value, 320)); + } + public int MaxResizeWidth { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public Microsoft.Iris.Render.Point Position { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public string Text + { + get => CurrentView.Title; + set => CurrentView.Title = value; + } + public Cursor Cursor { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public Cursor IdleCursor { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public bool Visible + { + get => XamlWindow.Visible; + set => XamlWindow.Visible = value; + } + + public bool IsLoaded => XamlWindow != null; + + public ColorF BackgroundColor + { + get + { + Windows.UI.Color color = Windows.UI.Colors.Transparent; + if (XamlWindow.Content is FrameworkElement elem && elem.Background is SolidColorBrush brush) + color = brush.Color; + + return new ColorF(color.A / 255, color.R / 255, color.G / 255, color.B / 255); + } + set + { + if (XamlWindow.Content is FrameworkElement elem) + { + elem.Background = new SolidColorBrush(new Windows.UI.Color + { + A = (byte)(value.A * 255), + R = (byte)(value.R * 255), + G = (byte)(value.G * 255), + B = (byte)(value.B * 255), + }); + } + } + } + public bool EnableExternalDragDrop + { + get => XamlWindow.Content.AllowDrop; + set => XamlWindow.Content.AllowDrop = true; + } + public bool IsDragInProgress { get => isDragging; set => throw new NotImplementedException(); } + public IDisplay CurrentDisplay { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public bool FullScreenExclusive + { + get => CurrentView.IsFullScreenMode; + set => CurrentView.TryEnterFullScreenMode(); + } + + public bool ActivationState => XamlWindow.CoreWindow.ActivationMode == CoreWindowActivationMode.ActivatedInForeground; + + public WindowState WindowState + { + get + { + if (CurrentView.ViewMode == ApplicationViewMode.CompactOverlay) + return WindowState.Normal; + else if (XamlWindow.CoreWindow.ActivationMode == CoreWindowActivationMode.ActivatedNotForeground + || XamlWindow.CoreWindow.ActivationMode == CoreWindowActivationMode.Deactivated + || !XamlWindow.Visible) + return WindowState.Minimized; + else if (CurrentView.AdjacentToLeftDisplayEdge && CurrentView.AdjacentToRightDisplayEdge) + return WindowState.Maximized; + + return WindowState.Normal; + } + set + { + switch (value) + { + case WindowState.Normal: + XamlWindow.Visible = true; + CurrentView.TryEnterViewModeAsync(ApplicationViewMode.Default); + break; + case WindowState.Minimized: + XamlWindow.Visible = false; + break; + case WindowState.Maximized: + XamlWindow.Visible = true; + break; + } + } + } + public FormStyleInfo Styles { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public HWND AppNotifyWindow { set => throw new NotImplementedException(); } + + public IVisualContainer VisualRoot => throw new NotImplementedException(); + + public event LocationChangedHandler LocationChangedEvent; + public event SizeChangedHandler SizeChangedEvent; + public event MonitorChangedHandler MonitorChangedEvent; + public event WindowStateChangedHandler WindowStateChangedEvent; + public event SysCommandHandler SysCommandEvent; + public event MouseIdleHandler MouseIdleEvent; + public event ShowHandler ShowEvent; + public event ActivationChangeHandler ActivationChangeEvent; + public event SessionActivateHandler SessionActivateEvent; + public event SessionConnectHandler SessionConnectEvent; + public event SetFocusHandler SetFocusEvent; + public event LoadHandler LoadEvent; + public event CloseHandler CloseEvent; + public event CloseRequestHandler CloseRequestEvent; + public event ForwardMessageHandler ForwardMessageEvent; + + private void XamlWindow_SizeChanged(object sender, WindowSizeChangedEventArgs e) => SizeChangedEvent?.Invoke(); + private void XamlWindow_Activated(object sender, WindowActivatedEventArgs e) + { + ShowEvent?.Invoke(true, e.WindowActivationState == CoreWindowActivationState.CodeActivated); + ActivationChangeEvent?.Invoke(); + } + private void XamlWindowContent_Loaded(object sender, RoutedEventArgs e) => LoadEvent?.Invoke(); + private void XamlWindowContent_GotFocus(object sender, RoutedEventArgs e) => SetFocusEvent?.Invoke(true); + private void XamlWindowContent_LostFocus(object sender, RoutedEventArgs e) => SetFocusEvent?.Invoke(false); + private void XamlWindow_Closed(object sender, CoreWindowEventArgs e) => CloseEvent?.Invoke(); + private void XamlWindowContent_DropCompleted(object sender, DropCompletedEventArgs e) => isDragging = false; + private void XamlWindowContent_DragStarting(UIElement sender, DragStartingEventArgs args) => isDragging = true; + + public void BringToTop() => XamlWindow.Activate(); + + public void ClientToScreen(ref Microsoft.Iris.Render.Point point) + { + throw new NotImplementedException(); + } + + public void Close(FormCloseReason fcrCloseReason) => XamlWindow.Close(); + + public IHwndHostWindow CreateHwndHostWindow() + { + throw new NotImplementedException(); + } + + public void ForceMouseIdle(bool fIdle) + { + throw new NotImplementedException(); + } + + public void Initialize() + { + + } + + public void LockMouseActive(bool fActive) + { + throw new NotImplementedException(); + } + + public void RefreshHitTarget() + { + throw new NotImplementedException(); + } + + public void Restore() + { + throw new NotImplementedException(); + } + + public void ScreenToClient(ref Microsoft.Iris.Render.Point point) + { + throw new NotImplementedException(); + } + + public void SetCapture(IRawInputSite captureSite, bool state) + { + if (state) + XamlWindow.CoreWindow.SetPointerCapture(); + else + XamlWindow.CoreWindow.ReleasePointerCapture(); + } + + public void SetDragDropResult(uint nDragOverResult, uint nDragDropResult) + { + throw new NotImplementedException(); + } + + public void SetEdgeImages(bool fActiveEdges, ShadowEdgePart[] edges) + { + throw new NotImplementedException(); + } + + public void SetIcon(string sModuleName, uint nResourceID, IconFlags nOptions) + { + throw new NotImplementedException(); + } + + public void SetMouseIdleOptions(Microsoft.Iris.Render.Size sizeMouseIdleTolerance, uint nMouseIdleDelay) + { + throw new NotImplementedException(); + } + + public void SetWindowOptions(WindowOptions options, bool enable) + { + + } + + public void TakeFocus() => XamlWindow.Activate(); + + public void TakeForeground(bool fForce) + { + if (fForce) + XamlWindow.Activate(); + } + + public void TemporarilyExitExclusiveMode() + { + throw new NotImplementedException(); + } + } }