136 changed files with 2976 additions and 1076 deletions
@ -0,0 +1,49 @@ |
|||
using System; |
|||
using System.Globalization; |
|||
|
|||
namespace Avalonia.Data.Converters |
|||
{ |
|||
/// <summary>
|
|||
/// A value converter which calls <see cref="string.Format(string, object)"/>
|
|||
/// </summary>
|
|||
public class StringFormatValueConverter : IValueConverter |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="StringFormatValueConverter"/> class.
|
|||
/// </summary>
|
|||
/// <param name="format">The format string.</param>
|
|||
/// <param name="inner">
|
|||
/// An optional inner converter to be called before the format takes place.
|
|||
/// </param>
|
|||
public StringFormatValueConverter(string format, IValueConverter inner) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(format != null); |
|||
|
|||
Format = format; |
|||
Inner = inner; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets an inner value converter which will be called before the string format takes place.
|
|||
/// </summary>
|
|||
public IValueConverter Inner { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the format string.
|
|||
/// </summary>
|
|||
public string Format { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) |
|||
{ |
|||
value = Inner?.Convert(value, targetType, parameter, culture) ?? value; |
|||
return string.Format(culture, Format, value); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) |
|||
{ |
|||
throw new NotSupportedException("Two way bindings are not supported with a string format"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,58 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
|
|||
namespace Avalonia.Utilities |
|||
{ |
|||
/// <summary>
|
|||
/// FIFO Queue optimized for holding zero or one items.
|
|||
/// </summary>
|
|||
/// <typeparam name="T">The type of items held in the queue.</typeparam>
|
|||
public class SingleOrQueue<T> |
|||
{ |
|||
private T _head; |
|||
private Queue<T> _tail; |
|||
|
|||
private Queue<T> Tail => _tail ?? (_tail = new Queue<T>()); |
|||
|
|||
private bool HasTail => _tail != null; |
|||
|
|||
public bool Empty { get; private set; } = true; |
|||
|
|||
public void Enqueue(T value) |
|||
{ |
|||
if (Empty) |
|||
{ |
|||
_head = value; |
|||
} |
|||
else |
|||
{ |
|||
Tail.Enqueue(value); |
|||
} |
|||
|
|||
Empty = false; |
|||
} |
|||
|
|||
public T Dequeue() |
|||
{ |
|||
if (Empty) |
|||
{ |
|||
throw new InvalidOperationException("Cannot dequeue from an empty queue!"); |
|||
} |
|||
|
|||
var result = _head; |
|||
|
|||
if (HasTail && Tail.Count != 0) |
|||
{ |
|||
_head = Tail.Dequeue(); |
|||
} |
|||
else |
|||
{ |
|||
_head = default; |
|||
Empty = true; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
namespace Avalonia.Visuals.Media.Imaging |
|||
{ |
|||
/// <summary>
|
|||
/// Controls the performance and quality of bitmap scaling.
|
|||
/// </summary>
|
|||
public enum BitmapInterpolationMode |
|||
{ |
|||
/// <summary>
|
|||
/// Uses the default behavior of the underling render backend.
|
|||
/// </summary>
|
|||
Default, |
|||
|
|||
/// <summary>
|
|||
/// The best performance but worst image quality.
|
|||
/// </summary>
|
|||
LowQuality, |
|||
|
|||
/// <summary>
|
|||
/// Good performance and decent image quality.
|
|||
/// </summary>
|
|||
MediumQuality, |
|||
|
|||
/// <summary>
|
|||
/// Highest quality but worst performance.
|
|||
/// </summary>
|
|||
HighQuality |
|||
} |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using Avalonia.Visuals.Media.Imaging; |
|||
|
|||
namespace Avalonia.Media |
|||
{ |
|||
public class RenderOptions |
|||
{ |
|||
/// <summary>
|
|||
/// Defines the <see cref="BitmapInterpolationMode"/> property.
|
|||
/// </summary>
|
|||
public static readonly StyledProperty<BitmapInterpolationMode> BitmapInterpolationModeProperty = |
|||
AvaloniaProperty.RegisterAttached<RenderOptions, AvaloniaObject, BitmapInterpolationMode>( |
|||
"BitmapInterpolationMode", |
|||
BitmapInterpolationMode.MediumQuality, |
|||
inherits: true); |
|||
|
|||
/// <summary>
|
|||
/// Gets the value of the BitmapInterpolationMode attached property for a control.
|
|||
/// </summary>
|
|||
/// <param name="element">The control.</param>
|
|||
/// <returns>The control's left coordinate.</returns>
|
|||
public static BitmapInterpolationMode GetBitmapInterpolationMode(AvaloniaObject element) |
|||
{ |
|||
return element.GetValue(BitmapInterpolationModeProperty); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Sets the value of the BitmapInterpolationMode attached property for a control.
|
|||
/// </summary>
|
|||
/// <param name="element">The control.</param>
|
|||
/// <param name="value">The left value.</param>
|
|||
public static void SetBitmapInterpolationMode(AvaloniaObject element, BitmapInterpolationMode value) |
|||
{ |
|||
element.SetValue(BitmapInterpolationModeProperty, value); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,85 @@ |
|||
using System; |
|||
using Avalonia.Data.Core; |
|||
using Avalonia.Markup.Parsers; |
|||
using Avalonia.Utilities; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Parsers |
|||
{ |
|||
internal class PropertyParser |
|||
{ |
|||
public (string ns, string owner, string name) Parse(CharacterReader r) |
|||
{ |
|||
if (r.End) |
|||
{ |
|||
throw new ExpressionParseException(0, "Expected property name."); |
|||
} |
|||
|
|||
var openParens = r.TakeIf('('); |
|||
bool closeParens = false; |
|||
string ns = null; |
|||
string owner = null; |
|||
string name = null; |
|||
|
|||
do |
|||
{ |
|||
var token = r.ParseIdentifier(); |
|||
|
|||
if (token == null) |
|||
{ |
|||
if (r.End) |
|||
{ |
|||
break; |
|||
} |
|||
else |
|||
{ |
|||
if (openParens && !r.End && (closeParens = r.TakeIf(')'))) |
|||
{ |
|||
break; |
|||
} |
|||
else if (openParens) |
|||
{ |
|||
throw new ExpressionParseException(r.Position, $"Expected ')'."); |
|||
} |
|||
|
|||
throw new ExpressionParseException(r.Position, $"Unexpected '{r.Peek}'."); |
|||
} |
|||
} |
|||
else if (!r.End && r.TakeIf(':')) |
|||
{ |
|||
ns = ns == null ? |
|||
token.ToString() : |
|||
throw new ExpressionParseException(r.Position, "Unexpected ':'."); |
|||
} |
|||
else if (!r.End && r.TakeIf('.')) |
|||
{ |
|||
owner = owner == null ? |
|||
token.ToString() : |
|||
throw new ExpressionParseException(r.Position, "Unexpected '.'."); |
|||
} |
|||
else |
|||
{ |
|||
name = token.ToString(); |
|||
} |
|||
} while (!r.End); |
|||
|
|||
if (name == null) |
|||
{ |
|||
throw new ExpressionParseException(0, "Expected property name."); |
|||
} |
|||
else if (openParens && owner == null) |
|||
{ |
|||
throw new ExpressionParseException(1, "Expected property owner."); |
|||
} |
|||
else if (openParens && !closeParens) |
|||
{ |
|||
throw new ExpressionParseException(r.Position, "Expected ')'."); |
|||
} |
|||
else if (!r.End) |
|||
{ |
|||
throw new ExpressionParseException(r.Position, "Expected end of expression."); |
|||
} |
|||
|
|||
return (ns, owner, name); |
|||
} |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue