Browse Source

Merge branch 'master' into window-decorations

pull/3539/head
Steven Kirk 6 years ago
committed by GitHub
parent
commit
88f9d4cae2
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      azure-pipelines.yml
  2. 19
      samples/ControlCatalog/Pages/ImagePage.xaml
  3. 33
      samples/ControlCatalog/Pages/ImagePage.xaml.cs
  4. 9
      src/Avalonia.Styling/Styling/Activators/StyleClassActivator.cs
  5. 96
      src/Avalonia.Visuals/Media/Imaging/CroppedBitmap.cs
  6. 1
      src/Avalonia.Visuals/Properties/AssemblyInfo.cs
  7. 10
      src/Avalonia.Visuals/Rendering/DeferredRenderer.cs

8
azure-pipelines.yml

@ -35,16 +35,16 @@ jobs:
vmImage: 'macOS-10.14'
steps:
- task: UseDotNet@2
displayName: 'Use .NET Core SDK 3.1.x'
displayName: 'Use .NET Core SDK 3.1.101'
inputs:
packageType: sdk
version: 3.1.x
version: 3.1.101
- task: UseDotNet@2
displayName: 'Use .NET Core Runtime 3.1.x'
displayName: 'Use .NET Core Runtime 3.1.1'
inputs:
packageType: runtime
version: 3.1.x
version: 3.1.1
- task: CmdLine@2
displayName: 'Install Mono 5.18'

19
samples/ControlCatalog/Pages/ImagePage.xaml

@ -7,7 +7,7 @@
<TextBlock Classes="h2">Displays an image</TextBlock>
</StackPanel>
<Grid ColumnDefinitions="*,*" RowDefinitions="Auto,*" Margin="64">
<Grid ColumnDefinitions="*,*,*" RowDefinitions="Auto,*" Margin="64">
<DockPanel Grid.Column="0" Grid.Row="1" Margin="16">
<TextBlock DockPanel.Dock="Top" Classes="h3" Margin="0 8">Bitmap</TextBlock>
@ -22,6 +22,23 @@
</DockPanel>
<DockPanel Grid.Column="1" Grid.Row="1" Margin="16">
<TextBlock DockPanel.Dock="Top" Classes="h3" Margin="0 8">Crop</TextBlock>
<ComboBox Name="bitmapCrop" DockPanel.Dock="Top" SelectedIndex="2" SelectionChanged="BitmapCropChanged">
<ComboBoxItem>None</ComboBoxItem>
<ComboBoxItem>Center</ComboBoxItem>
<ComboBoxItem>TopLeft</ComboBoxItem>
<ComboBoxItem>TopRight</ComboBoxItem>
<ComboBoxItem>BottomLeft</ComboBoxItem>
<ComboBoxItem>BottomRight</ComboBoxItem>
</ComboBox>
<Image Name="croppedImage">
<Image.Source>
<CroppedBitmap Source="/Assets/delicate-arch-896885_640.jpg" SourceRect="0 0 320 240"/>
</Image.Source>
</Image>
</DockPanel>
<DockPanel Grid.Column="2" Grid.Row="1" Margin="16">
<TextBlock DockPanel.Dock="Top" Classes="h3" Margin="0 8">Drawing</TextBlock>
<ComboBox Name="drawingStretch" DockPanel.Dock="Top" SelectedIndex="2" SelectionChanged="DrawingStretchChanged">
<ComboBoxItem>None</ComboBoxItem>

33
samples/ControlCatalog/Pages/ImagePage.xaml.cs

@ -1,6 +1,10 @@
using System;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
namespace ControlCatalog.Pages
{
@ -8,12 +12,14 @@ namespace ControlCatalog.Pages
{
private readonly Image _bitmapImage;
private readonly Image _drawingImage;
private readonly Image _croppedImage;
public ImagePage()
{
InitializeComponent();
_bitmapImage = this.FindControl<Image>("bitmapImage");
_drawingImage = this.FindControl<Image>("drawingImage");
_croppedImage = this.FindControl<Image>("croppedImage");
}
private void InitializeComponent()
@ -38,5 +44,32 @@ namespace ControlCatalog.Pages
_drawingImage.Stretch = (Stretch)comboxBox.SelectedIndex;
}
}
public void BitmapCropChanged(object sender, SelectionChangedEventArgs e)
{
if (_croppedImage != null)
{
var comboxBox = (ComboBox)sender;
var croppedBitmap = _croppedImage.Source as CroppedBitmap;
croppedBitmap.SourceRect = GetCropRect(comboxBox.SelectedIndex);
}
}
private PixelRect GetCropRect(int index)
{
var bitmapWidth = 640;
var bitmapHeight = 426;
var cropSize = new PixelSize(320, 240);
return index switch
{
1 => new PixelRect(new PixelPoint((bitmapWidth - cropSize.Width) / 2, (bitmapHeight - cropSize.Width) / 2), cropSize),
2 => new PixelRect(new PixelPoint(0, 0), cropSize),
3 => new PixelRect(new PixelPoint(bitmapWidth - cropSize.Width, 0), cropSize),
4 => new PixelRect(new PixelPoint(0, bitmapHeight - cropSize.Height), cropSize),
5 => new PixelRect(new PixelPoint(bitmapWidth - cropSize.Width, bitmapHeight - cropSize.Height), cropSize),
_ => PixelRect.Empty
};
}
}
}

9
src/Avalonia.Styling/Styling/Activators/StyleClassActivator.cs

@ -14,6 +14,7 @@ namespace Avalonia.Styling.Activators
{
private readonly IList<string> _match;
private readonly IAvaloniaReadOnlyList<string> _classes;
private NotifyCollectionChangedEventHandler? _classesChangedHandler;
public StyleClassActivator(IAvaloniaReadOnlyList<string> classes, IList<string> match)
{
@ -21,6 +22,9 @@ namespace Avalonia.Styling.Activators
_match = match;
}
private NotifyCollectionChangedEventHandler ClassesChangedHandler =>
_classesChangedHandler ??= ClassesChanged;
public static bool AreClassesMatching(IReadOnlyList<string> classes, IList<string> toMatch)
{
int remainingMatches = toMatch.Count;
@ -51,16 +55,15 @@ namespace Avalonia.Styling.Activators
return remainingMatches == 0;
}
protected override void Initialize()
{
PublishNext(IsMatching());
_classes.CollectionChanged += ClassesChanged;
_classes.CollectionChanged += ClassesChangedHandler;
}
protected override void Deinitialize()
{
_classes.CollectionChanged -= ClassesChanged;
_classes.CollectionChanged -= ClassesChangedHandler;
}
private void ClassesChanged(object sender, NotifyCollectionChangedEventArgs e)

96
src/Avalonia.Visuals/Media/Imaging/CroppedBitmap.cs

@ -0,0 +1,96 @@
using System;
using Avalonia.Visuals.Media.Imaging;
namespace Avalonia.Media.Imaging
{
/// <summary>
/// Crops a Bitmap.
/// </summary>
public class CroppedBitmap : AvaloniaObject, IImage, IAffectsRender, IDisposable
{
/// <summary>
/// Defines the <see cref="Source"/> property.
/// </summary>
public static readonly StyledProperty<IImage> SourceProperty =
AvaloniaProperty.Register<CroppedBitmap, IImage>(nameof(Source));
/// <summary>
/// Defines the <see cref="SourceRect"/> property.
/// </summary>
public static readonly StyledProperty<PixelRect> SourceRectProperty =
AvaloniaProperty.Register<CroppedBitmap, PixelRect>(nameof(SourceRect));
public event EventHandler Invalidated;
static CroppedBitmap()
{
SourceRectProperty.Changed.AddClassHandler<CroppedBitmap>((x, e) => x.SourceRectChanged(e));
SourceProperty.Changed.AddClassHandler<CroppedBitmap>((x, e) => x.SourceChanged(e));
}
/// <summary>
/// Gets or sets the source for the bitmap.
/// </summary>
public IImage Source
{
get => GetValue(SourceProperty);
set => SetValue(SourceProperty, value);
}
/// <summary>
/// Gets or sets the rectangular area that the bitmap is cropped to.
/// </summary>
public PixelRect SourceRect
{
get => GetValue(SourceRectProperty);
set => SetValue(SourceRectProperty, value);
}
public CroppedBitmap()
{
Source = null;
SourceRect = default;
}
public CroppedBitmap(IImage source, PixelRect sourceRect)
{
Source = source;
SourceRect = sourceRect;
}
private void SourceChanged(AvaloniaPropertyChangedEventArgs e)
{
if (e.NewValue == null)
return;
if (!(e.NewValue is IBitmap))
throw new ArgumentException("Only IBitmap supported as source");
Invalidated?.Invoke(this, e);
}
private void SourceRectChanged(AvaloniaPropertyChangedEventArgs e) => Invalidated?.Invoke(this, e);
public virtual void Dispose()
{
(Source as IBitmap)?.Dispose();
}
public Size Size {
get
{
if (Source == null)
return Size.Empty;
if (SourceRect.IsEmpty)
return Source.Size;
return SourceRect.Size.ToSizeWithDpi((Source as IBitmap).Dpi);
}
}
public void Draw(DrawingContext context, Rect sourceRect, Rect destRect, BitmapInterpolationMode bitmapInterpolationMode)
{
if (Source == null)
return;
var topLeft = SourceRect.TopLeft.ToPointWithDpi((Source as IBitmap).Dpi);
Source.Draw(context, sourceRect.Translate(new Vector(topLeft.X, topLeft.Y)), destRect, bitmapInterpolationMode);
}
}
}

1
src/Avalonia.Visuals/Properties/AssemblyInfo.cs

@ -8,6 +8,7 @@ using Avalonia.Metadata;
[assembly: InternalsVisibleTo("Avalonia.Visuals.UnitTests")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Animation")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Media")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Media.Imaging")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia")]
[assembly: InternalsVisibleTo("Avalonia.Direct2D1.RenderTests")]

10
src/Avalonia.Visuals/Rendering/DeferredRenderer.cs

@ -355,15 +355,21 @@ namespace Avalonia.Rendering
node.BeginRender(context, isLayerRoot);
foreach (var operation in node.DrawOperations)
var drawOperations = node.DrawOperations;
var drawOperationsCount = drawOperations.Count;
for (int i = 0; i < drawOperationsCount; i++)
{
var operation = drawOperations[i];
_currentDraw = operation;
operation.Item.Render(context);
_currentDraw = null;
}
foreach (var child in node.Children)
var children = node.Children;
var childrenCount = children.Count;
for (int i = 0; i < childrenCount; i++)
{
var child = children[i];
Render(context, (VisualNode)child, layer, clipBounds);
}

Loading…
Cancel
Save