Browse Source

Refactored platform options

pull/2368/head
Nikita Tsukanov 7 years ago
parent
commit
bbfed1c3a5
  1. 21
      src/Avalonia.Controls/AppBuilderBase.cs
  2. 65
      src/Avalonia.Native/AvaloniaNativePlatform.cs
  3. 32
      src/Avalonia.Native/AvaloniaNativePlatformExtensions.cs
  4. 2
      src/Avalonia.Native/PopupImpl.cs
  5. 2
      src/Avalonia.Native/WindowImpl.cs
  6. 4
      src/Avalonia.Native/WindowImplBase.cs
  7. 6
      src/Avalonia.X11/X11Platform.cs
  8. 20
      src/Windows/Avalonia.Win32/Win32Platform.cs

21
src/Avalonia.Controls/AppBuilderBase.cs

@ -15,6 +15,7 @@ namespace Avalonia.Controls
public abstract class AppBuilderBase<TAppBuilder> where TAppBuilder : AppBuilderBase<TAppBuilder>, new()
{
private static bool s_setupWasAlreadyCalled;
private Action _optionsInitializers;
/// <summary>
/// Gets or sets the <see cref="IRuntimePlatform"/> instance.
@ -249,6 +250,24 @@ namespace Avalonia.Controls
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>
/// Sets up the platform-speciic services for the <see cref="Application"/>.
/// </summary>
@ -280,7 +299,7 @@ namespace Avalonia.Controls
}
s_setupWasAlreadyCalled = true;
_optionsInitializers?.Invoke();
RuntimePlatformServicesInitializer();
WindowingSubsystemInitializer();
RenderingSubsystemInitializer();

65
src/Avalonia.Native/AvaloniaNativePlatform.cs

@ -16,6 +16,7 @@ namespace Avalonia.Native
class AvaloniaNativePlatform : IPlatformSettings, IWindowingPlatform
{
private readonly IAvaloniaNativeFactory _factory;
private AvaloniaNativePlatformOptions _options;
[DllImport("libAvaloniaNative")]
static extern IntPtr CreateAvaloniaNative();
@ -27,29 +28,31 @@ namespace Avalonia.Native
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))
.DoInitialize(configure);
.DoInitialize(options);
}
delegate IntPtr CreateAvaloniaNativeDelegate();
public static void Initialize(string library, Action<AvaloniaNativeOptions> configure)
public static void Initialize(AvaloniaNativePlatformOptions options)
{
var loader = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? (IDynLoader)new Win32Loader() : new UnixLoader();
var lib = loader.LoadLibrary(library);
var proc = loader.GetProcAddress(lib, "CreateAvaloniaNative", false);
var d = Marshal.GetDelegateForFunctionPointer<CreateAvaloniaNativeDelegate>(proc);
if (options.AvaloniaNativeLibraryPath != null)
{
var loader = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
(IDynLoader)new Win32Loader() :
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(CreateAvaloniaNative(), configure);
Initialize(d(), options);
}
else
Initialize(CreateAvaloniaNative(), options);
}
private AvaloniaNativePlatform(IAvaloniaNativeFactory factory)
@ -57,14 +60,20 @@ namespace Avalonia.Native
_factory = factory;
}
void DoInitialize(Action<AvaloniaNativeOptions> configure)
void DoInitialize(AvaloniaNativePlatformOptions options)
{
var opts = new AvaloniaNativeOptions(_factory);
configure?.Invoke(opts);
_options = options;
_factory.Initialize();
if (_factory.MacOptions != null)
{
var macOpts = AvaloniaLocator.Current.GetService<MacOSPlatformOptions>();
if (macOpts != null)
_factory.MacOptions.ShowInDock = macOpts.ShowInDock ? 1 : 0;
}
AvaloniaLocator.CurrentMutable
.Bind<IPlatformThreadingInterface>().ToConstant(new PlatformThreadingInterface(_factory.CreatePlatformThreadingInterface()))
.Bind<IPlatformThreadingInterface>()
.ToConstant(new PlatformThreadingInterface(_factory.CreatePlatformThreadingInterface()))
.Bind<IStandardCursorFactory>().ToConstant(new CursorFactory(_factory.CreateCursorFactory()))
.Bind<IPlatformIconLoader>().ToSingleton<IconLoader>()
.Bind<IKeyboardDevice>().ToConstant(KeyboardDevice)
@ -76,13 +85,13 @@ namespace Avalonia.Native
.Bind<IRenderTimer>().ToConstant(new DefaultRenderTimer(60))
.Bind<ISystemDialogImpl>().ToConstant(new SystemDialogs(_factory.CreateSystemDialogs()))
.Bind<IWindowingPlatformGlFeature>().ToConstant(new GlPlatformFeature(_factory.ObtainGlFeature()))
.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration(InputModifiers.Windows))
.Bind<AvaloniaNativeOptions>().ToConstant(opts);
.Bind<PlatformHotkeyConfiguration>()
.ToConstant(new PlatformHotkeyConfiguration(InputModifiers.Windows));
}
public IWindowImpl CreateWindow()
{
return new WindowImpl(_factory);
return new WindowImpl(_factory, _options);
}
public IEmbeddableWindowImpl CreateEmbeddableWindow()
@ -92,7 +101,7 @@ namespace Avalonia.Native
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 T UseAvaloniaNative<T>(this T builder,
string libraryPath = null,
Action<AvaloniaNativeOptions> configure = null)
where T : AppBuilderBase<T>, new()
public static T UseAvaloniaNative<T>(this T builder)
where T : AppBuilderBase<T>, new()
{
if (libraryPath == null)
{
builder.UseWindowingSubsystem(() => AvaloniaNativePlatform.Initialize(configure));
}
else
{
builder.UseWindowingSubsystem(() => AvaloniaNativePlatform.Initialize(libraryPath, configure));
}
builder.UseWindowingSubsystem(() =>
AvaloniaNativePlatform.Initialize(
AvaloniaLocator.Current.GetService<AvaloniaNativePlatformOptions>() ??
new AvaloniaNativePlatformOptions()));
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 PopupImpl(IAvaloniaNativeFactory factory)
public PopupImpl(IAvaloniaNativeFactory factory, AvaloniaNativePlatformOptions opts) : base(opts)
{
using (var e = new PopupEvents(this))
{

2
src/Avalonia.Native/WindowImpl.cs

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

4
src/Avalonia.Native/WindowImplBase.cs

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

6
src/Avalonia.X11/X11Platform.cs

@ -94,9 +94,11 @@ namespace Avalonia
}
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;
}

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

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

Loading…
Cancel
Save