Browse Source

Merge branch 'master' into box-shadow

pull/3871/head
danwalmsley 6 years ago
committed by GitHub
parent
commit
5e7a827d11
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      samples/ControlCatalog/Pages/DialogsPage.xaml
  2. 14
      samples/ControlCatalog/Pages/DialogsPage.xaml.cs
  3. 12
      src/Avalonia.Dialogs/ManagedFileChooserViewModel.cs
  4. 20
      src/Avalonia.Dialogs/ManagedFileDialogExtensions.cs
  5. 7
      src/Avalonia.Dialogs/ManagedFileDialogOptions.cs
  6. 18
      src/Avalonia.Visuals/Rendering/SceneGraph/Scene.cs
  7. 20
      src/Avalonia.Visuals/Rendering/SceneGraph/SceneLayers.cs
  8. 25
      src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs
  9. 4
      src/Avalonia.X11/X11Window.cs
  10. 2
      src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
  11. 2
      src/Skia/Avalonia.Skia/SkiaOptions.cs

1
samples/ControlCatalog/Pages/DialogsPage.xaml

@ -6,6 +6,7 @@
<Button Name="OpenFile">Open File</Button>
<Button Name="SaveFile">Save File</Button>
<Button Name="SelectFolder">Select Folder</Button>
<Button Name="OpenBoth">Select Both</Button>
<Button Name="DecoratedWindow">Decorated window</Button>
<Button Name="DecoratedWindowDialog">Decorated window (dialog)</Button>
<Button Name="Dialog">Dialog</Button>

14
samples/ControlCatalog/Pages/DialogsPage.xaml.cs

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Avalonia.Controls;
using Avalonia.Dialogs;
using Avalonia.Markup.Xaml;
#pragma warning disable 4014
@ -58,6 +59,19 @@ namespace ControlCatalog.Pages
Title = "Select folder",
}.ShowAsync(GetWindow());
};
this.FindControl<Button>("OpenBoth").Click += async delegate
{
var res = await new OpenFileDialog()
{
Title = "Select both",
AllowMultiple = true
}.ShowManagedAsync(GetWindow(), new ManagedFileDialogOptions
{
AllowDirectorySelection = true
});
if (res != null)
Console.WriteLine("Selected: \n" + string.Join("\n", res));
};
this.FindControl<Button>("DecoratedWindow").Click += delegate
{
new DecoratedWindow().Show();

12
src/Avalonia.Dialogs/ManagedFileChooserViewModel.cs

@ -14,6 +14,7 @@ namespace Avalonia.Dialogs
{
internal class ManagedFileChooserViewModel : InternalViewModelBase
{
private readonly ManagedFileDialogOptions _options;
public event Action CancelRequested;
public event Action<string[]> CompleteRequested;
@ -103,8 +104,9 @@ namespace Avalonia.Dialogs
QuickLinks.AddRange(quickSources.GetAllItems().Select(i => new ManagedFileChooserItemViewModel(i)));
}
public ManagedFileChooserViewModel(FileSystemDialog dialog)
public ManagedFileChooserViewModel(FileSystemDialog dialog, ManagedFileDialogOptions options)
{
_options = options;
_disposables = new CompositeDisposable();
var quickSources = AvaloniaLocator.Current
@ -202,10 +204,12 @@ namespace Avalonia.Dialogs
}
else
{
var invalidItems = SelectedItems.Where(i => i.ItemType == ManagedFileChooserItemType.Folder).ToList();
foreach (var item in invalidItems)
if (!_options.AllowDirectorySelection)
{
SelectedItems.Remove(item);
var invalidItems = SelectedItems.Where(i => i.ItemType == ManagedFileChooserItemType.Folder)
.ToList();
foreach (var item in invalidItems)
SelectedItems.Remove(item);
}
if (!_selectingDirectory)

20
src/Avalonia.Dialogs/ManagedFileDialogExtensions.cs

@ -9,13 +9,15 @@ namespace Avalonia.Dialogs
{
private class ManagedSystemDialogImpl<T> : ISystemDialogImpl where T : Window, new()
{
async Task<string[]> Show(SystemDialog d, Window parent)
async Task<string[]> Show(SystemDialog d, Window parent, ManagedFileDialogOptions options = null)
{
var model = new ManagedFileChooserViewModel((FileSystemDialog)d);
var model = new ManagedFileChooserViewModel((FileSystemDialog)d,
options ?? new ManagedFileDialogOptions());
var dialog = new T
{
Content = new ManagedFileChooser(),
Title = d.Title,
DataContext = model
};
@ -44,6 +46,11 @@ namespace Avalonia.Dialogs
{
return (await Show(dialog, parent))?.FirstOrDefault();
}
public async Task<string[]> ShowFileDialogAsync(FileDialog dialog, Window parent, ManagedFileDialogOptions options)
{
return await Show(dialog, parent, options);
}
}
public static TAppBuilder UseManagedSystemDialogs<TAppBuilder>(this TAppBuilder builder)
@ -61,5 +68,14 @@ namespace Avalonia.Dialogs
AvaloniaLocator.CurrentMutable.Bind<ISystemDialogImpl>().ToSingleton<ManagedSystemDialogImpl<TWindow>>());
return builder;
}
public static Task<string[]> ShowManagedAsync(this OpenFileDialog dialog, Window parent,
ManagedFileDialogOptions options = null) => ShowManagedAsync<Window>(dialog, parent, options);
public static Task<string[]> ShowManagedAsync<TWindow>(this OpenFileDialog dialog, Window parent,
ManagedFileDialogOptions options = null) where TWindow : Window, new()
{
return new ManagedSystemDialogImpl<TWindow>().ShowFileDialogAsync(dialog, parent, options);
}
}
}

7
src/Avalonia.Dialogs/ManagedFileDialogOptions.cs

@ -0,0 +1,7 @@
namespace Avalonia.Dialogs
{
public class ManagedFileDialogOptions
{
public bool AllowDirectorySelection { get; set; }
}
}

18
src/Avalonia.Visuals/Rendering/SceneGraph/Scene.cs

@ -12,7 +12,7 @@ namespace Avalonia.Rendering.SceneGraph
/// </summary>
public class Scene : IDisposable
{
private Dictionary<IVisual, IVisualNode> _index;
private readonly Dictionary<IVisual, IVisualNode> _index;
/// <summary>
/// Initializes a new instance of the <see cref="Scene"/> class.
@ -83,7 +83,7 @@ namespace Avalonia.Rendering.SceneGraph
/// <returns>The cloned scene.</returns>
public Scene CloneScene()
{
var index = new Dictionary<IVisual, IVisualNode>();
var index = new Dictionary<IVisual, IVisualNode>(_index.Count);
var root = Clone((VisualNode)Root, null, index);
var result = new Scene(root, index, Layers.Clone(), Generation + 1)
@ -162,9 +162,19 @@ namespace Avalonia.Rendering.SceneGraph
index.Add(result.Visual, result);
foreach (var child in source.Children)
var children = source.Children;
var childrenCount = children.Count;
if (childrenCount > 0)
{
result.AddChild(Clone((VisualNode)child, result, index));
result.TryPreallocateChildren(childrenCount);
for (var i = 0; i < childrenCount; i++)
{
var child = children[i];
result.AddChild(Clone((VisualNode)child, result, index));
}
}
return result;

20
src/Avalonia.Visuals/Rendering/SceneGraph/SceneLayers.cs

@ -11,16 +11,28 @@ namespace Avalonia.Rendering.SceneGraph
public class SceneLayers : IEnumerable<SceneLayer>
{
private readonly IVisual _root;
private readonly List<SceneLayer> _inner = new List<SceneLayer>();
private readonly Dictionary<IVisual, SceneLayer> _index = new Dictionary<IVisual, SceneLayer>();
private readonly List<SceneLayer> _inner;
private readonly Dictionary<IVisual, SceneLayer> _index;
/// <summary>
/// Initializes a new instance of the <see cref="SceneLayers"/> class.
/// </summary>
/// <param name="root">The scene's root visual.</param>
public SceneLayers(IVisual root)
public SceneLayers(IVisual root) : this(root, 0)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="SceneLayers"/> class.
/// </summary>
/// <param name="root">The scene's root visual.</param>
/// <param name="capacity">Initial layer capacity.</param>
public SceneLayers(IVisual root, int capacity)
{
_root = root;
_inner = new List<SceneLayer>(capacity);
_index = new Dictionary<IVisual, SceneLayer>(capacity);
}
/// <summary>
@ -84,7 +96,7 @@ namespace Avalonia.Rendering.SceneGraph
/// <returns>The cloned layers.</returns>
public SceneLayers Clone()
{
var result = new SceneLayers(_root);
var result = new SceneLayers(_root, Count);
foreach (var src in _inner)
{

25
src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs

@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Disposables;
using Avalonia.Collections;
using Avalonia.Media;
using Avalonia.Platform;
using Avalonia.Utilities;
@ -349,6 +349,11 @@ namespace Avalonia.Rendering.SceneGraph
context.Transform = transformRestore;
}
internal void TryPreallocateChildren(int count)
{
EnsureChildrenCreated(count);
}
private Rect CalculateBounds()
{
var result = new Rect();
@ -362,11 +367,11 @@ namespace Avalonia.Rendering.SceneGraph
return result;
}
private void EnsureChildrenCreated()
private void EnsureChildrenCreated(int capacity = 0)
{
if (_children == null)
{
_children = new List<IVisualNode>();
_children = new List<IVisualNode>(capacity);
}
}
@ -383,7 +388,15 @@ namespace Avalonia.Rendering.SceneGraph
}
else if (_drawOperationsCloned)
{
_drawOperations = new List<IRef<IDrawOperation>>(_drawOperations.Select(op => op.Clone()));
var oldDrawOperations = _drawOperations;
_drawOperations = new List<IRef<IDrawOperation>>(oldDrawOperations.Count);
foreach (var drawOperation in oldDrawOperations)
{
_drawOperations.Add(drawOperation.Clone());
}
_drawOperationsRefCounter.Dispose();
_drawOperationsRefCounter = RefCountable.Create(CreateDisposeDrawOperations(_drawOperations));
_drawOperationsCloned = false;
@ -399,9 +412,9 @@ namespace Avalonia.Rendering.SceneGraph
/// <returns>Disposable for given draw operations.</returns>
private static IDisposable CreateDisposeDrawOperations(List<IRef<IDrawOperation>> drawOperations)
{
return Disposable.Create(() =>
return Disposable.Create(drawOperations, operations =>
{
foreach (var operation in drawOperations)
foreach (var operation in operations)
{
operation.Dispose();
}

4
src/Avalonia.X11/X11Window.cs

@ -328,7 +328,9 @@ namespace Avalonia.X11
}
else if (ev.type == XEventName.UnmapNotify)
_mapped = false;
else if (ev.type == XEventName.Expose)
else if (ev.type == XEventName.Expose ||
(ev.type == XEventName.VisibilityNotify &&
ev.VisibilityEvent.state < 2))
{
if (!_triggeredExpose)
{

2
src/Skia/Avalonia.Skia/PlatformRenderInterface.cs

@ -18,7 +18,7 @@ namespace Avalonia.Skia
private GRContext GrContext { get; }
public PlatformRenderInterface(ICustomSkiaGpu customSkiaGpu, long maxResourceBytes = 100000000)
public PlatformRenderInterface(ICustomSkiaGpu customSkiaGpu, long maxResourceBytes = 100663296)
{
if (customSkiaGpu != null)
{

2
src/Skia/Avalonia.Skia/SkiaOptions.cs

@ -10,7 +10,7 @@ namespace Avalonia
{
public SkiaOptions()
{
MaxGpuResourceSizeBytes = 512000000;
MaxGpuResourceSizeBytes = 100663296; // Value taken from skia.
}
/// <summary>
/// Custom gpu factory to use. Can be used to customize behavior of Skia renderer.

Loading…
Cancel
Save