Browse Source

Merge pull request #2368 from AvaloniaUI/platform-options

Refactored platform options (not tested)
pull/2400/head
Steven Kirk 7 years ago
committed by GitHub
parent
commit
4da4fefec9
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      samples/interop/Direct3DInteropSample/Program.cs
  2. 21
      src/Avalonia.Controls/AppBuilderBase.cs
  3. 65
      src/Avalonia.Native/AvaloniaNativePlatform.cs
  4. 32
      src/Avalonia.Native/AvaloniaNativePlatformExtensions.cs
  5. 2
      src/Avalonia.Native/PopupImpl.cs
  6. 2
      src/Avalonia.Native/WindowImpl.cs
  7. 4
      src/Avalonia.Native/WindowImplBase.cs
  8. 6
      src/Avalonia.X11/X11Platform.cs
  9. 20
      src/Windows/Avalonia.Win32/Win32Platform.cs

4
samples/interop/Direct3DInteropSample/Program.cs

@ -11,7 +11,9 @@ namespace Direct3DInteropSample
{ {
static void Main(string[] args) static void Main(string[] args)
{ {
AppBuilder.Configure<App>().UseWin32(deferredRendering: false).UseDirect2D1().Start<MainWindow>(); AppBuilder.Configure<App>()
.With(new Win32PlatformOptions {UseDeferredRendering = false})
.UseWin32().UseDirect2D1().Start<MainWindow>();
} }
} }
} }

21
src/Avalonia.Controls/AppBuilderBase.cs

@ -15,6 +15,7 @@ namespace Avalonia.Controls
public abstract class AppBuilderBase<TAppBuilder> where TAppBuilder : AppBuilderBase<TAppBuilder>, new() public abstract class AppBuilderBase<TAppBuilder> where TAppBuilder : AppBuilderBase<TAppBuilder>, new()
{ {
private static bool s_setupWasAlreadyCalled; private static bool s_setupWasAlreadyCalled;
private Action _optionsInitializers;
/// <summary> /// <summary>
/// Gets or sets the <see cref="IRuntimePlatform"/> instance. /// Gets or sets the <see cref="IRuntimePlatform"/> instance.
@ -249,6 +250,24 @@ namespace Avalonia.Controls
Delegate.Combine(moduleInitializers.ToArray()).DynamicInvoke(); Delegate.Combine(moduleInitializers.ToArray()).DynamicInvoke();
} }
/// <summary>
/// Configures platform-specific options
/// </summary>
public TAppBuilder With<T>(T options)
{
_optionsInitializers += () => { AvaloniaLocator.CurrentMutable.Bind<T>().ToConstant(options); };
return Self;
}
/// <summary>
/// Configures platform-specific options
/// </summary>
public TAppBuilder With<T>(Func<T> options)
{
_optionsInitializers += () => { AvaloniaLocator.CurrentMutable.Bind<T>().ToFunc(options); };
return Self;
}
/// <summary> /// <summary>
/// Sets up the platform-speciic services for the <see cref="Application"/>. /// Sets up the platform-speciic services for the <see cref="Application"/>.
/// </summary> /// </summary>
@ -280,7 +299,7 @@ namespace Avalonia.Controls
} }
s_setupWasAlreadyCalled = true; s_setupWasAlreadyCalled = true;
_optionsInitializers?.Invoke();
RuntimePlatformServicesInitializer(); RuntimePlatformServicesInitializer();
WindowingSubsystemInitializer(); WindowingSubsystemInitializer();
RenderingSubsystemInitializer(); RenderingSubsystemInitializer();

65
src/Avalonia.Native/AvaloniaNativePlatform.cs

@ -16,6 +16,7 @@ namespace Avalonia.Native
class AvaloniaNativePlatform : IPlatformSettings, IWindowingPlatform class AvaloniaNativePlatform : IPlatformSettings, IWindowingPlatform
{ {
private readonly IAvaloniaNativeFactory _factory; private readonly IAvaloniaNativeFactory _factory;
private AvaloniaNativePlatformOptions _options;
[DllImport("libAvaloniaNative")] [DllImport("libAvaloniaNative")]
static extern IntPtr CreateAvaloniaNative(); static extern IntPtr CreateAvaloniaNative();
@ -27,29 +28,31 @@ namespace Avalonia.Native
public TimeSpan DoubleClickTime => TimeSpan.FromMilliseconds(500); //TODO public TimeSpan DoubleClickTime => TimeSpan.FromMilliseconds(500); //TODO
public static void Initialize(IntPtr factory, Action<AvaloniaNativeOptions> configure) public static void Initialize(IntPtr factory, AvaloniaNativePlatformOptions options)
{ {
new AvaloniaNativePlatform(new IAvaloniaNativeFactory(factory)) new AvaloniaNativePlatform(new IAvaloniaNativeFactory(factory))
.DoInitialize(configure); .DoInitialize(options);
} }
delegate IntPtr CreateAvaloniaNativeDelegate(); delegate IntPtr CreateAvaloniaNativeDelegate();
public static void Initialize(string library, Action<AvaloniaNativeOptions> configure) public static void Initialize(AvaloniaNativePlatformOptions options)
{ {
var loader = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) if (options.AvaloniaNativeLibraryPath != null)
? (IDynLoader)new Win32Loader() : new UnixLoader(); {
var lib = loader.LoadLibrary(library); var loader = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
var proc = loader.GetProcAddress(lib, "CreateAvaloniaNative", false); (IDynLoader)new Win32Loader() :
var d = Marshal.GetDelegateForFunctionPointer<CreateAvaloniaNativeDelegate>(proc); new UnixLoader();
var lib = loader.LoadLibrary(options.AvaloniaNativeLibraryPath);
var proc = loader.GetProcAddress(lib, "CreateAvaloniaNative", false);
var d = Marshal.GetDelegateForFunctionPointer<CreateAvaloniaNativeDelegate>(proc);
Initialize(d(), configure);
}
public static void Initialize(Action<AvaloniaNativeOptions> configure) Initialize(d(), options);
{ }
Initialize(CreateAvaloniaNative(), configure); else
Initialize(CreateAvaloniaNative(), options);
} }
private AvaloniaNativePlatform(IAvaloniaNativeFactory factory) private AvaloniaNativePlatform(IAvaloniaNativeFactory factory)
@ -57,14 +60,20 @@ namespace Avalonia.Native
_factory = factory; _factory = factory;
} }
void DoInitialize(Action<AvaloniaNativeOptions> configure) void DoInitialize(AvaloniaNativePlatformOptions options)
{ {
var opts = new AvaloniaNativeOptions(_factory); _options = options;
configure?.Invoke(opts);
_factory.Initialize(); _factory.Initialize();
if (_factory.MacOptions != null)
{
var macOpts = AvaloniaLocator.Current.GetService<MacOSPlatformOptions>();
if (macOpts != null)
_factory.MacOptions.ShowInDock = macOpts.ShowInDock ? 1 : 0;
}
AvaloniaLocator.CurrentMutable AvaloniaLocator.CurrentMutable
.Bind<IPlatformThreadingInterface>().ToConstant(new PlatformThreadingInterface(_factory.CreatePlatformThreadingInterface())) .Bind<IPlatformThreadingInterface>()
.ToConstant(new PlatformThreadingInterface(_factory.CreatePlatformThreadingInterface()))
.Bind<IStandardCursorFactory>().ToConstant(new CursorFactory(_factory.CreateCursorFactory())) .Bind<IStandardCursorFactory>().ToConstant(new CursorFactory(_factory.CreateCursorFactory()))
.Bind<IPlatformIconLoader>().ToSingleton<IconLoader>() .Bind<IPlatformIconLoader>().ToSingleton<IconLoader>()
.Bind<IKeyboardDevice>().ToConstant(KeyboardDevice) .Bind<IKeyboardDevice>().ToConstant(KeyboardDevice)
@ -76,13 +85,13 @@ namespace Avalonia.Native
.Bind<IRenderTimer>().ToConstant(new DefaultRenderTimer(60)) .Bind<IRenderTimer>().ToConstant(new DefaultRenderTimer(60))
.Bind<ISystemDialogImpl>().ToConstant(new SystemDialogs(_factory.CreateSystemDialogs())) .Bind<ISystemDialogImpl>().ToConstant(new SystemDialogs(_factory.CreateSystemDialogs()))
.Bind<IWindowingPlatformGlFeature>().ToConstant(new GlPlatformFeature(_factory.ObtainGlFeature())) .Bind<IWindowingPlatformGlFeature>().ToConstant(new GlPlatformFeature(_factory.ObtainGlFeature()))
.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration(InputModifiers.Windows)) .Bind<PlatformHotkeyConfiguration>()
.Bind<AvaloniaNativeOptions>().ToConstant(opts); .ToConstant(new PlatformHotkeyConfiguration(InputModifiers.Windows));
} }
public IWindowImpl CreateWindow() public IWindowImpl CreateWindow()
{ {
return new WindowImpl(_factory); return new WindowImpl(_factory, _options);
} }
public IEmbeddableWindowImpl CreateEmbeddableWindow() public IEmbeddableWindowImpl CreateEmbeddableWindow()
@ -92,7 +101,7 @@ namespace Avalonia.Native
public IPopupImpl CreatePopup() public IPopupImpl CreatePopup()
{ {
return new PopupImpl(_factory); return new PopupImpl(_factory, _options);
} }
} }
@ -116,18 +125,4 @@ namespace Avalonia.Native
} }
} }
} }
public class AvaloniaNativeOptions
{
public AvaloniaNativeMacOptions MacOptions { get; set; }
public bool UseDeferredRendering { get; set; } = true;
public bool UseGpu { get; set; } = true;
internal AvaloniaNativeOptions(IAvaloniaNativeFactory factory)
{
var mac = factory.GetMacOptions();
if (mac != null)
MacOptions = new AvaloniaNativeMacOptions(mac);
}
}
} }

32
src/Avalonia.Native/AvaloniaNativePlatformExtensions.cs

@ -9,21 +9,27 @@ namespace Avalonia
{ {
public static class AvaloniaNativePlatformExtensions public static class AvaloniaNativePlatformExtensions
{ {
public static T UseAvaloniaNative<T>(this T builder, public static T UseAvaloniaNative<T>(this T builder)
string libraryPath = null, where T : AppBuilderBase<T>, new()
Action<AvaloniaNativeOptions> configure = null)
where T : AppBuilderBase<T>, new()
{ {
if (libraryPath == null) builder.UseWindowingSubsystem(() =>
{ AvaloniaNativePlatform.Initialize(
builder.UseWindowingSubsystem(() => AvaloniaNativePlatform.Initialize(configure)); AvaloniaLocator.Current.GetService<AvaloniaNativePlatformOptions>() ??
} new AvaloniaNativePlatformOptions()));
else
{
builder.UseWindowingSubsystem(() => AvaloniaNativePlatform.Initialize(libraryPath, configure));
}
return builder; return builder;
} }
} }
public class AvaloniaNativePlatformOptions
{
public bool UseDeferredRendering { get; set; } = true;
public bool UseGpu { get; set; } = true;
public string AvaloniaNativeLibraryPath { get; set; }
}
// ReSharper disable once InconsistentNaming
public class MacOSPlatformOptions
{
public bool ShowInDock { get; set; } = true;
}
} }

2
src/Avalonia.Native/PopupImpl.cs

@ -9,7 +9,7 @@ namespace Avalonia.Native
{ {
public class PopupImpl : WindowBaseImpl, IPopupImpl public class PopupImpl : WindowBaseImpl, IPopupImpl
{ {
public PopupImpl(IAvaloniaNativeFactory factory) public PopupImpl(IAvaloniaNativeFactory factory, AvaloniaNativePlatformOptions opts) : base(opts)
{ {
using (var e = new PopupEvents(this)) using (var e = new PopupEvents(this))
{ {

2
src/Avalonia.Native/WindowImpl.cs

@ -12,7 +12,7 @@ namespace Avalonia.Native
public class WindowImpl : WindowBaseImpl, IWindowImpl public class WindowImpl : WindowBaseImpl, IWindowImpl
{ {
IAvnWindow _native; IAvnWindow _native;
public WindowImpl(IAvaloniaNativeFactory factory) public WindowImpl(IAvaloniaNativeFactory factory, AvaloniaNativePlatformOptions opts) : base(opts)
{ {
using (var e = new WindowEvents(this)) using (var e = new WindowEvents(this))
{ {

4
src/Avalonia.Native/WindowImplBase.cs

@ -31,10 +31,8 @@ namespace Avalonia.Native
private double _savedScaling; private double _savedScaling;
private GlPlatformSurface _glSurface; private GlPlatformSurface _glSurface;
public WindowBaseImpl() public WindowBaseImpl(AvaloniaNativePlatformOptions opts)
{ {
var opts = AvaloniaLocator.Current.GetService<AvaloniaNativeOptions>();
_gpu = opts.UseGpu; _gpu = opts.UseGpu;
_deferredRendering = opts.UseDeferredRendering; _deferredRendering = opts.UseDeferredRendering;

6
src/Avalonia.X11/X11Platform.cs

@ -94,9 +94,11 @@ namespace Avalonia
} }
public static class AvaloniaX11PlatformExtensions public static class AvaloniaX11PlatformExtensions
{ {
public static T UseX11<T>(this T builder, X11PlatformOptions options = null) where T : AppBuilderBase<T>, new() public static T UseX11<T>(this T builder) where T : AppBuilderBase<T>, new()
{ {
builder.UseWindowingSubsystem(() => new AvaloniaX11Platform().Initialize(options ?? new X11PlatformOptions())); builder.UseWindowingSubsystem(() =>
new AvaloniaX11Platform().Initialize(AvaloniaLocator.Current.GetService<X11PlatformOptions>() ??
new X11PlatformOptions()));
return builder; return builder;
} }

20
src/Windows/Avalonia.Win32/Win32Platform.cs

@ -26,15 +26,21 @@ namespace Avalonia
public static class Win32ApplicationExtensions public static class Win32ApplicationExtensions
{ {
public static T UseWin32<T>( public static T UseWin32<T>(
this T builder, this T builder)
bool deferredRendering = true, bool allowEgl = false)
where T : AppBuilderBase<T>, new() where T : AppBuilderBase<T>, new()
{ {
return builder.UseWindowingSubsystem( return builder.UseWindowingSubsystem(
() => Win32.Win32Platform.Initialize(deferredRendering, allowEgl), () => Win32.Win32Platform.Initialize(
AvaloniaLocator.Current.GetService<Win32PlatformOptions>() ?? new Win32PlatformOptions()),
"Win32"); "Win32");
} }
} }
public class Win32PlatformOptions
{
public bool UseDeferredRendering { get; set; } = true;
public bool AllowEglInitialization { get; set; }
}
} }
namespace Avalonia.Win32 namespace Avalonia.Win32
@ -63,10 +69,10 @@ namespace Avalonia.Win32
public static void Initialize() public static void Initialize()
{ {
Initialize(true); Initialize(new Win32PlatformOptions());
} }
public static void Initialize(bool deferredRendering = true, bool allowEgl = false) public static void Initialize(Win32PlatformOptions options)
{ {
AvaloniaLocator.CurrentMutable AvaloniaLocator.CurrentMutable
.Bind<IClipboard>().ToSingleton<ClipboardImpl>() .Bind<IClipboard>().ToSingleton<ClipboardImpl>()
@ -80,9 +86,9 @@ namespace Avalonia.Win32
.Bind<IWindowingPlatform>().ToConstant(s_instance) .Bind<IWindowingPlatform>().ToConstant(s_instance)
.Bind<PlatformHotkeyConfiguration>().ToSingleton<PlatformHotkeyConfiguration>() .Bind<PlatformHotkeyConfiguration>().ToSingleton<PlatformHotkeyConfiguration>()
.Bind<IPlatformIconLoader>().ToConstant(s_instance); .Bind<IPlatformIconLoader>().ToConstant(s_instance);
if (allowEgl) if (options.AllowEglInitialization)
Win32GlManager.Initialize(); Win32GlManager.Initialize();
UseDeferredRendering = deferredRendering; UseDeferredRendering = options.UseDeferredRendering;
_uiThread = Thread.CurrentThread; _uiThread = Thread.CurrentThread;
if (OleContext.Current != null) if (OleContext.Current != null)

Loading…
Cancel
Save