Browse Source

Merge branch 'master' into bitmap-versioning

pull/1996/head
Jumar Macato 7 years ago
committed by GitHub
parent
commit
bcf5d1bf7d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .travis.yml
  2. 4
      build.cake
  3. 2
      samples/ControlCatalog/Pages/ButtonPage.xaml
  4. 24
      src/Avalonia.Base/Utilities/MathUtilities.cs
  5. 24
      src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs
  6. 44
      src/Avalonia.ReactiveUI/ReactiveUserControl.cs
  7. 44
      src/Avalonia.ReactiveUI/ReactiveWindow.cs
  8. 28
      src/Avalonia.Themes.Default/Accents/BaseLight.xaml
  9. 4
      src/Avalonia.Themes.Default/Button.xaml
  10. 2
      src/Avalonia.Themes.Default/ButtonSpinner.xaml
  11. 2
      src/Avalonia.Themes.Default/Calendar.xaml
  12. 4
      src/Avalonia.Themes.Default/CalendarButton.xaml
  13. 4
      src/Avalonia.Themes.Default/CalendarDayButton.xaml
  14. 2
      src/Avalonia.Themes.Default/CalendarItem.xaml
  15. 2
      src/Avalonia.Themes.Default/CheckBox.xaml
  16. 4
      src/Avalonia.Themes.Default/ContextMenu.xaml
  17. 2
      src/Avalonia.Themes.Default/DataValidationErrors.xaml
  18. 12
      src/Avalonia.Themes.Default/DatePicker.xaml
  19. 2
      src/Avalonia.Themes.Default/DropDown.xaml
  20. 4
      src/Avalonia.Themes.Default/Expander.xaml
  21. 4
      src/Avalonia.Themes.Default/GridSplitter.xaml
  22. 2
      src/Avalonia.Themes.Default/NumericUpDown.xaml
  23. 2
      src/Avalonia.Themes.Default/RadioButton.xaml
  24. 4
      src/Avalonia.Themes.Default/RepeatButton.xaml
  25. 12
      src/Avalonia.Themes.Default/ScrollBar.xaml
  26. 4
      src/Avalonia.Themes.Default/Slider.xaml
  27. 2
      src/Avalonia.Themes.Default/TabStripItem.xaml
  28. 4
      src/Avalonia.Themes.Default/TextBox.xaml
  29. 6
      src/Avalonia.Themes.Default/ToggleButton.xaml
  30. 2
      src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs
  31. 2
      src/Markup/Avalonia.Markup/Data/MultiBinding.cs
  32. 35
      tests/Avalonia.Controls.UnitTests/ListBoxTests.cs
  33. 31
      tests/Avalonia.Markup.UnitTests/Data/MultiBindingTests.cs
  34. 82
      tests/Avalonia.ReactiveUI.UnitTests/AvaloniaActivationForViewFetcherTest.cs
  35. 2
      tools/packages.config

2
.travis.yml

@ -11,6 +11,8 @@ mono:
- 5.2.0
dotnet: 2.1.200
script:
- sudo apt-get update
- sudo apt-get install castxml
- ./build.sh --target "Travis" --configuration "Release"
notifications:
email: false

4
build.cake

@ -3,8 +3,8 @@
///////////////////////////////////////////////////////////////////////////////
#addin "nuget:?package=NuGet.Core&version=2.14.0"
#tool "nuget:?package=NuGet.CommandLine&version=4.3.0"
#tool "nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2017.1.20170613.162720"
#tool "nuget:?package=NuGet.CommandLine&version=4.7.1"
#tool "nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2018.2.3"
///////////////////////////////////////////////////////////////////////////////
// TOOLS

2
samples/ControlCatalog/Pages/ButtonPage.xaml

@ -18,7 +18,7 @@
<Style>
<Style.Resources>
<SolidColorBrush x:Key="ThemeBorderMidBrush">Red</SolidColorBrush>
<SolidColorBrush x:Key="ThemeControlDarkBrush">DarkRed</SolidColorBrush>
<SolidColorBrush x:Key="ThemeControlHighBrush">DarkRed</SolidColorBrush>
</Style.Resources>
</Style>
</Button.Styles>

24
src/Avalonia.Base/Utilities/MathUtilities.cs

@ -1,7 +1,6 @@
// 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.Utilities
{
/// <summary>
@ -31,5 +30,28 @@ namespace Avalonia.Utilities
return val;
}
}
/// <summary>
/// Clamps a value between a minimum and maximum value.
/// </summary>
/// <param name="val">The value.</param>
/// <param name="min">The minimum value.</param>
/// <param name="max">The maximum value.</param>
/// <returns>The clamped value.</returns>
public static int Clamp(int val, int min, int max)
{
if (val < min)
{
return min;
}
else if (val > max)
{
return max;
}
else
{
return val;
}
}
}
}

24
src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs

@ -76,9 +76,23 @@ namespace Avalonia.Controls.Presenters
var firstIndex = ItemCount - panel.Children.Count;
RecycleContainersForMove(firstIndex - FirstIndex);
panel.PixelOffset = VirtualizingPanel.ScrollDirection == Orientation.Vertical ?
panel.Children[0].Bounds.Height :
panel.Children[0].Bounds.Width;
double pixelOffset;
var child = panel.Children[0];
if (child.IsArrangeValid)
{
pixelOffset = VirtualizingPanel.ScrollDirection == Orientation.Vertical ?
child.Bounds.Height :
child.Bounds.Width;
}
else
{
pixelOffset = VirtualizingPanel.ScrollDirection == Orientation.Vertical ?
child.DesiredSize.Height :
child.DesiredSize.Width;
}
panel.PixelOffset = pixelOffset;
}
}
}
@ -402,6 +416,10 @@ namespace Avalonia.Controls.Presenters
var panel = VirtualizingPanel;
var generator = Owner.ItemContainerGenerator;
var selector = Owner.MemberSelector;
//validate delta it should never overflow last index or generate index < 0
delta = MathUtilities.Clamp(delta, -FirstIndex, ItemCount - FirstIndex - panel.Children.Count);
var sign = delta < 0 ? -1 : 1;
var count = Math.Min(Math.Abs(delta), panel.Children.Count);
var move = count < panel.Children.Count;

44
src/Avalonia.ReactiveUI/ReactiveUserControl.cs

@ -0,0 +1,44 @@
// 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;
using Avalonia.VisualTree;
using Avalonia.Controls;
using ReactiveUI;
namespace Avalonia
{
/// <summary>
/// A ReactiveUI UserControl that implements <see cref="IViewFor{TViewModel}"/>
/// and will activate your ViewModel automatically if it supports activation.
/// </summary>
/// <typeparam name="TViewModel">ViewModel type.</typeparam>
public class ReactiveUserControl<TViewModel> : UserControl, IViewFor<TViewModel> where TViewModel : class
{
public static readonly AvaloniaProperty<TViewModel> ViewModelProperty = AvaloniaProperty
.Register<ReactiveWindow<TViewModel>, TViewModel>(nameof(ViewModel));
/// <summary>
/// Initializes a new instance of the <see cref="ReactiveUserControl{TViewModel}"/> class.
/// </summary>
public ReactiveUserControl()
{
DataContextChanged += (sender, args) => ViewModel = DataContext as TViewModel;
}
/// <summary>
/// The ViewModel.
/// </summary>
public TViewModel ViewModel
{
get => GetValue(ViewModelProperty);
set => SetValue(ViewModelProperty, value);
}
object IViewFor.ViewModel
{
get => ViewModel;
set => ViewModel = (TViewModel)value;
}
}
}

44
src/Avalonia.ReactiveUI/ReactiveWindow.cs

@ -0,0 +1,44 @@
// 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;
using Avalonia.VisualTree;
using Avalonia.Controls;
using ReactiveUI;
namespace Avalonia
{
/// <summary>
/// A ReactiveUI Window that implements <see cref="IViewFor{TViewModel}"/>
/// and will activate your ViewModel automatically if it supports activation.
/// </summary>
/// <typeparam name="TViewModel">ViewModel type.</typeparam>
public class ReactiveWindow<TViewModel> : Window, IViewFor<TViewModel> where TViewModel : class
{
public static readonly AvaloniaProperty<TViewModel> ViewModelProperty = AvaloniaProperty
.Register<ReactiveWindow<TViewModel>, TViewModel>(nameof(ViewModel));
/// <summary>
/// Initializes a new instance of the <see cref="ReactiveWindow{TViewModel}"/> class.
/// </summary>
public ReactiveWindow()
{
DataContextChanged += (sender, args) => ViewModel = DataContext as TViewModel;
}
/// <summary>
/// The ViewModel.
/// </summary>
public TViewModel ViewModel
{
get => GetValue(ViewModelProperty);
set => SetValue(ViewModelProperty, value);
}
object IViewFor.ViewModel
{
get => ViewModel;
set => ViewModel = (TViewModel)value;
}
}
}

28
src/Avalonia.Themes.Default/Accents/BaseLight.xaml

@ -9,34 +9,34 @@
<Color x:Key="ThemeAccentColor4">#33119EDA</Color>
<Color x:Key="ThemeBackgroundColor">#FFFFFFFF</Color>
<Color x:Key="ThemeBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="ThemeBorderLowColor">#FFAAAAAA</Color>
<Color x:Key="ThemeBorderMidColor">#FF888888</Color>
<Color x:Key="ThemeBorderDarkColor">#FF333333</Color>
<Color x:Key="ThemeControlLightColor">#FFFFFFFF</Color>
<Color x:Key="ThemeBorderHighColor">#FF333333</Color>
<Color x:Key="ThemeControlLowColor">#FFFFFFFF</Color>
<Color x:Key="ThemeControlMidColor">#FFAAAAAA</Color>
<Color x:Key="ThemeControlDarkColor">#FF888888</Color>
<Color x:Key="ThemeControlHighColor">#FF888888</Color>
<Color x:Key="ThemeControlHighlightLowColor">#FFF0F0F0</Color>
<Color x:Key="ThemeControlHighlightMidColor">#FFD0D0D0</Color>
<Color x:Key="ThemeControlHighlightDarkColor">#FF808080</Color>
<Color x:Key="ThemeControlHighlightHighColor">#FF808080</Color>
<Color x:Key="ThemeForegroundColor">#FF000000</Color>
<Color x:Key="ThemeForegroundLightColor">#FF808080</Color>
<Color x:Key="ThemeForegroundLowColor">#FF808080</Color>
<Color x:Key="HighlightColor">#FF086F9E</Color>
<Color x:Key="ErrorColor">#FFFF0000</Color>
<Color x:Key="ErrorLightColor">#10FF0000</Color>
<Color x:Key="ErrorLowColor">#10FF0000</Color>
<SolidColorBrush x:Key="ThemeBackgroundBrush" Color="{DynamicResource ThemeBackgroundColor}"></SolidColorBrush>
<SolidColorBrush x:Key="ThemeBorderLightBrush" Color="{DynamicResource ThemeBorderLightColor}"></SolidColorBrush>
<SolidColorBrush x:Key="ThemeBorderLowBrush" Color="{DynamicResource ThemeBorderLowColor}"></SolidColorBrush>
<SolidColorBrush x:Key="ThemeBorderMidBrush" Color="{DynamicResource ThemeBorderMidColor}"></SolidColorBrush>
<SolidColorBrush x:Key="ThemeBorderDarkBrush" Color="{DynamicResource ThemeBorderDarkColor}"></SolidColorBrush>
<SolidColorBrush x:Key="ThemeControlLightBrush" Color="{DynamicResource ThemeControlLightColor}"></SolidColorBrush>
<SolidColorBrush x:Key="ThemeBorderHighBrush" Color="{DynamicResource ThemeBorderHighColor}"></SolidColorBrush>
<SolidColorBrush x:Key="ThemeControlLowBrush" Color="{DynamicResource ThemeControlLowColor}"></SolidColorBrush>
<SolidColorBrush x:Key="ThemeControlMidBrush" Color="{DynamicResource ThemeControlMidColor}"></SolidColorBrush>
<SolidColorBrush x:Key="ThemeControlDarkBrush" Color="{DynamicResource ThemeControlDarkColor}"></SolidColorBrush>
<SolidColorBrush x:Key="ThemeControlHighBrush" Color="{DynamicResource ThemeControlHighColor}"></SolidColorBrush>
<SolidColorBrush x:Key="ThemeControlHighlightLowBrush" Color="{DynamicResource ThemeControlHighlightLowColor}"></SolidColorBrush>
<SolidColorBrush x:Key="ThemeControlHighlightMidBrush" Color="{DynamicResource ThemeControlHighlightMidColor}"></SolidColorBrush>
<SolidColorBrush x:Key="ThemeControlHighlightDarkBrush" Color="{DynamicResource ThemeControlHighlightDarkColor}"></SolidColorBrush>
<SolidColorBrush x:Key="ThemeControlHighlightHighBrush" Color="{DynamicResource ThemeControlHighlightHighColor}"></SolidColorBrush>
<SolidColorBrush x:Key="ThemeForegroundBrush" Color="{DynamicResource ThemeForegroundColor}"></SolidColorBrush>
<SolidColorBrush x:Key="ThemeForegroundLightBrush" Color="{DynamicResource ThemeForegroundLightColor}"></SolidColorBrush>
<SolidColorBrush x:Key="ThemeForegroundLowBrush" Color="{DynamicResource ThemeForegroundLowColor}"></SolidColorBrush>
<SolidColorBrush x:Key="HighlightBrush" Color="{DynamicResource HighlightColor}"></SolidColorBrush>
<SolidColorBrush x:Key="ThemeAccentBrush" Color="{DynamicResource ThemeAccentColor}"></SolidColorBrush>
@ -44,7 +44,7 @@
<SolidColorBrush x:Key="ThemeAccentBrush3" Color="{DynamicResource ThemeAccentColor3}"></SolidColorBrush>
<SolidColorBrush x:Key="ThemeAccentBrush4" Color="{DynamicResource ThemeAccentColor4}"></SolidColorBrush>
<SolidColorBrush x:Key="ErrorBrush" Color="{DynamicResource ErrorColor}"></SolidColorBrush>
<SolidColorBrush x:Key="ErrorLightBrush" Color="{DynamicResource ErrorLightColor}"></SolidColorBrush>
<SolidColorBrush x:Key="ErrorLowBrush" Color="{DynamicResource ErrorLowColor}"></SolidColorBrush>
<Thickness x:Key="ThemeBorderThickness">2</Thickness>
<sys:Double x:Key="ThemeDisabledOpacity">0.5</sys:Double>

4
src/Avalonia.Themes.Default/Button.xaml

@ -1,7 +1,7 @@
<Styles xmlns="https://github.com/avaloniaui">
<Style Selector="Button">
<Setter Property="Background" Value="{DynamicResource ThemeControlMidBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderLightBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderLowBrush}"/>
<Setter Property="BorderThickness" Value="{DynamicResource ThemeBorderThickness}"/>
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundBrush}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
@ -26,7 +26,7 @@
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderMidBrush}"/>
</Style>
<Style Selector="Button:pressed /template/ ContentPresenter">
<Setter Property="Background" Value="{DynamicResource ThemeControlDarkBrush}"/>
<Setter Property="Background" Value="{DynamicResource ThemeControlHighBrush}"/>
</Style>
<Style Selector="Button:disabled">
<Setter Property="Opacity" Value="{DynamicResource ThemeDisabledOpacity}"/>

2
src/Avalonia.Themes.Default/ButtonSpinner.xaml

@ -1,6 +1,6 @@
<Styles xmlns="https://github.com/avaloniaui">
<Style Selector="ButtonSpinner">
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderLightBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderLowBrush}"/>
<Setter Property="BorderThickness" Value="{DynamicResource ThemeBorderThickness}"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>

2
src/Avalonia.Themes.Default/Calendar.xaml

@ -9,7 +9,7 @@
<Style Selector="Calendar">
<!--<Setter Property="Focusable" Value="False" />-->
<Setter Property="BorderThickness" Value="{DynamicResource ThemeBorderThickness}" />
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderDarkBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderHighBrush}" />
<Setter Property="Background" Value="{DynamicResource ThemeBackgroundBrush}" />
<Setter Property="HeaderBackground" Value="{DynamicResource ThemeAccentBrush2}" />
<Setter Property="Template">

4
src/Avalonia.Themes.Default/CalendarButton.xaml

@ -7,7 +7,7 @@
<Styles xmlns="https://github.com/avaloniaui">
<Style Selector="CalendarButton">
<Setter Property="Foreground" Value="{DynamicResource ThemeBorderDarkBrush}" />
<Setter Property="Foreground" Value="{DynamicResource ThemeBorderHighBrush}" />
<Setter Property="Background" Value="{DynamicResource ThemeAccentBrush2}" />
<Setter Property="FontSize" Value="{DynamicResource FontSizeSmall}" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
@ -68,7 +68,7 @@
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundBrush}"/>
</Style>
<Style Selector="CalendarButton:inactive /template/ ContentControl#Content">
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundLightBrush}"/>
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundLowBrush}"/>
</Style>

4
src/Avalonia.Themes.Default/CalendarDayButton.xaml

@ -100,10 +100,10 @@
<Style Selector="CalendarDayButton:inactive /template/ ContentControl#Content">
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundLightBrush}"/>
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundLowBrush}"/>
</Style>
<Style Selector="CalendarDayButton:today /template/ ContentControl#Content">
<Setter Property="Foreground" Value="{DynamicResource ThemeControlLightBrush}"/>
<Setter Property="Foreground" Value="{DynamicResource ThemeControlLowBrush}"/>
</Style>
<Style Selector="CalendarDayButton /template/ Path#BlackoutVisual">

2
src/Avalonia.Themes.Default/CalendarItem.xaml

@ -153,7 +153,7 @@
<Rectangle Name="DisabledVisual"
Stretch="Fill"
Fill="{DynamicResource ThemeControlLightBrush}"
Fill="{DynamicResource ThemeControlLowBrush}"
Opacity="{DynamicResource ThemeDisabledOpacity}"
Margin="0,2,0,2" />

2
src/Avalonia.Themes.Default/CheckBox.xaml

@ -50,7 +50,7 @@
<Setter Property="IsVisible" Value="False"/>
</Style>
<Style Selector="CheckBox:pointerover /template/ Border#border">
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderDarkBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderHighBrush}"/>
</Style>
<Style Selector="CheckBox /template/ Path#checkMark">
<Setter Property="IsVisible" Value="False"/>

4
src/Avalonia.Themes.Default/ContextMenu.xaml

@ -1,8 +1,8 @@
<Style xmlns="https://github.com/avaloniaui" Selector="ContextMenu">
<Setter Property="BorderBrush" Value="Gray"/>
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderMidBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="4,2"/>
<Setter Property="TextBlock.FontSize" Value="12" />
<Setter Property="TextBlock.FontSize" Value="{DynamicResource FontSizeNormal}" />
<Setter Property="TextBlock.FontWeight" Value="Normal" />
<Setter Property="Template">
<ControlTemplate>

2
src/Avalonia.Themes.Default/DataValidationErrors.xaml

@ -24,7 +24,7 @@
Background="Transparent">
<Canvas.Styles>
<Style Selector="ToolTip">
<Setter Property="Background" Value="{DynamicResource ErrorLightBrush}"/>
<Setter Property="Background" Value="{DynamicResource ErrorLowBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource ErrorBrush}"/>
</Style>
</Canvas.Styles>

12
src/Avalonia.Themes.Default/DatePicker.xaml

@ -29,7 +29,7 @@
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0"
Background="{DynamicResource ThemeControlLightBrush}"
Background="{DynamicResource ThemeControlLowBrush}"
ColumnDefinitions="*,*,*,*"
RowDefinitions="23*,19*,19*,19*"
ClipToBounds="False">
@ -47,12 +47,12 @@
Grid.Row="1"
Grid.RowSpan="3"
BorderThickness="1"
BorderBrush="{DynamicResource ThemeBorderDarkBrush}"
BorderBrush="{DynamicResource ThemeBorderHighBrush}"
CornerRadius=".5" />
<Rectangle Grid.ColumnSpan="4"
Grid.RowSpan="1"
StrokeThickness="1"
Stroke="{DynamicResource ThemeBorderDarkBrush}"
Stroke="{DynamicResource ThemeBorderHighBrush}"
Fill="{DynamicResource ThemeAccentBrush}">
</Rectangle>
<TextBlock Margin="0,-1,0,0"
@ -63,13 +63,13 @@
Grid.ColumnSpan="4"
Grid.RowSpan="3"
FontSize="{DynamicResource FontSizeSmall}"
Foreground="{DynamicResource ThemeBorderDarkBrush}">
Foreground="{DynamicResource ThemeBorderHighBrush}">
<TextBlock.Text>
<Binding Source="{x:Static sys:DateTime.Today}" Path="Day"/>
</TextBlock.Text>
</TextBlock>
<Ellipse HorizontalAlignment="Center" VerticalAlignment="Center" Fill="{DynamicResource ThemeControlLightBrush}" StrokeThickness="0" Grid.ColumnSpan="4" Width="3" Height="3"/>
<Ellipse HorizontalAlignment="Center" VerticalAlignment="Center" Fill="{DynamicResource ThemeControlLowBrush}" StrokeThickness="0" Grid.ColumnSpan="4" Width="3" Height="3"/>
</Grid>
</ControlTemplate>
</Setter>
@ -123,7 +123,7 @@
</Style>
<Style Selector="DatePicker:focus /template/ TextBox#PART_TextBox">
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderDarkBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderHighBrush}"/>
</Style>
</Styles>

2
src/Avalonia.Themes.Default/DropDown.xaml

@ -52,6 +52,6 @@
</Setter>
</Style>
<Style Selector="DropDown:pointerover /template/ Border#border">
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderDarkBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderHighBrush}"/>
</Style>
</Styles>

4
src/Avalonia.Themes.Default/Expander.xaml

@ -89,7 +89,7 @@
<Border BorderThickness="1">
<Grid ColumnDefinitions="Auto,Auto">
<Border Grid.Column="0" Width="20" Height="20" HorizontalAlignment="Center" VerticalAlignment="Center">
<Path Fill="Black"
<Path Fill="{DynamicResource ThemeForegroundBrush}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 2 L 4 6 L 0 10 Z" />
@ -108,7 +108,7 @@
</Setter>
</Style>
<Style Selector="Expander /template/ ToggleButton#PART_toggle:pointerover /template/ Border">
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderLightBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderLowBrush}" />
</Style>
<Style Selector="Expander:down:expanded /template/ ToggleButton#PART_toggle /template/ Path">
<Setter Property="RenderTransform">

4
src/Avalonia.Themes.Default/GridSplitter.xaml

@ -1,7 +1,7 @@
<Styles xmlns="https://github.com/avaloniaui">
<Style Selector="GridSplitter:vertical">
<Setter Property="Width" Value="6"/>
<Setter Property="Background" Value="{DynamicResource ThemeControlLightBrush}"/>
<Setter Property="Background" Value="{DynamicResource ThemeControlLowBrush}"/>
<Setter Property="Template">
<ControlTemplate>
<Border Background="{TemplateBinding Background}">
@ -25,7 +25,7 @@
</Style>
<Style Selector="GridSplitter:horizontal">
<Setter Property="Height" Value="6"/>
<Setter Property="Background" Value="{DynamicResource ThemeControlLightBrush}"/>
<Setter Property="Background" Value="{DynamicResource ThemeControlLowBrush}"/>
<Setter Property="Template">
<ControlTemplate>
<Border Background="{TemplateBinding Background}">

2
src/Avalonia.Themes.Default/NumericUpDown.xaml

@ -1,6 +1,6 @@
<Styles xmlns="https://github.com/avaloniaui">
<Style Selector="NumericUpDown">
<Setter Property="TemplatedControl.BorderBrush" Value="{DynamicResource ThemeBorderLightBrush}"/>
<Setter Property="TemplatedControl.BorderBrush" Value="{DynamicResource ThemeBorderLowBrush}"/>
<Setter Property="TemplatedControl.BorderThickness" Value="{DynamicResource ThemeBorderThickness}"/>
<Setter Property="TemplatedControl.Background" Value="{DynamicResource ThemeBackgroundBrush}" />
<Setter Property="TemplatedControl.Foreground" Value="{DynamicResource ThemeForegroundBrush}" />

2
src/Avalonia.Themes.Default/RadioButton.xaml

@ -39,7 +39,7 @@
</Setter>
</Style>
<Style Selector="RadioButton:pointerover /template/ Ellipse#border">
<Setter Property="Stroke" Value="{DynamicResource ThemeBorderDarkBrush}"/>
<Setter Property="Stroke" Value="{DynamicResource ThemeBorderHighBrush}"/>
</Style>
<Style Selector="RadioButton /template/ Ellipse#checkMark">
<Setter Property="IsVisible" Value="False"/>

4
src/Avalonia.Themes.Default/RepeatButton.xaml

@ -3,7 +3,7 @@
<Setter Property="Background"
Value="{DynamicResource ThemeControlMidBrush}" />
<Setter Property="BorderBrush"
Value="{DynamicResource ThemeBorderLightBrush}" />
Value="{DynamicResource ThemeBorderLowBrush}" />
<Setter Property="BorderThickness"
Value="{DynamicResource ThemeBorderThickness}" />
<Setter Property="Foreground"
@ -35,7 +35,7 @@
</Style>
<Style Selector="RepeatButton:pressed /template/ ContentPresenter">
<Setter Property="Background"
Value="{DynamicResource ThemeControlDarkBrush}" />
Value="{DynamicResource ThemeControlHighBrush}" />
</Style>
<Style Selector="RepeatButton:disabled">
<Setter Property="Opacity"

12
src/Avalonia.Themes.Default/ScrollBar.xaml

@ -10,7 +10,7 @@
Grid.Column="0">
<Path Data="M 0,4 C0,4 0,6 0,6 0,6 3.5,2.5 3.5,2.5 3.5,2.5 7,6 7,6 7,6 7,4 7,4 7,4 3.5,0.5 3.5,0.5 3.5,0.5 0,4 0,4 z"
Stretch="Uniform"
Fill="{DynamicResource ThemeForegroundLightBrush}" />
Fill="{DynamicResource ThemeForegroundLowBrush}" />
</RepeatButton>
<Track Grid.Row="1"
Grid.Column="1"
@ -30,7 +30,7 @@
<Thumb Name="thumb">
<Thumb.Template>
<ControlTemplate>
<Border Background="{DynamicResource ThemeControlDarkBrush}" />
<Border Background="{DynamicResource ThemeControlHighBrush}" />
</ControlTemplate>
</Thumb.Template>
</Thumb>
@ -41,7 +41,7 @@
Grid.Column="2">
<Path Data="M 0,2.5 C0,2.5 0,0.5 0,0.5 0,0.5 3.5,4 3.5,4 3.5,4 7,0.5 7,0.5 7,0.5 7,2.5 7,2.5 7,2.5 3.5,6 3.5,6 3.5,6 0,2.5 0,2.5 z"
Stretch="Uniform"
Fill="{DynamicResource ThemeForegroundLightBrush}" />
Fill="{DynamicResource ThemeForegroundLowBrush}" />
</RepeatButton>
</Grid>
</Border>
@ -61,7 +61,7 @@
Grid.Column="0">
<Path Data="M 3.18,7 C3.18,7 5,7 5,7 5,7 1.81,3.5 1.81,3.5 1.81,3.5 5,0 5,0 5,0 3.18,0 3.18,0 3.18,0 0,3.5 0,3.5 0,3.5 3.18,7 3.18,7 z"
Stretch="Uniform"
Fill="{DynamicResource ThemeForegroundLightBrush}" />
Fill="{DynamicResource ThemeForegroundLowBrush}" />
</RepeatButton>
<Track Grid.Row="1"
Grid.Column="1"
@ -81,7 +81,7 @@
<Thumb Name="thumb">
<Thumb.Template>
<ControlTemplate>
<Border Background="{DynamicResource ThemeControlDarkBrush}" />
<Border Background="{DynamicResource ThemeControlHighBrush}" />
</ControlTemplate>
</Thumb.Template>
</Thumb>
@ -92,7 +92,7 @@
Grid.Column="2">
<Path Data="M 1.81,7 C1.81,7 0,7 0,7 0,7 3.18,3.5 3.18,3.5 3.18,3.5 0,0 0,0 0,0 1.81,0 1.81,0 1.81,0 5,3.5 5,3.5 5,3.5 1.81,7 1.81,7 z"
Stretch="Uniform"
Fill="{DynamicResource ThemeForegroundLightBrush}" />
Fill="{DynamicResource ThemeForegroundLowBrush}" />
</RepeatButton>
</Grid>
</Border>

4
src/Avalonia.Themes.Default/Slider.xaml

@ -76,11 +76,11 @@
</Style>
<Style Selector="Slider /template/ Border#TrackBackground">
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderLightBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderLowBrush}"/>
</Style>
<Style Selector="Slider /template/ RepeatButton.repeattrack">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="{DynamicResource ThemeBorderLightBrush}"/>
<Setter Property="Foreground" Value="{DynamicResource ThemeBorderLowBrush}"/>
<Setter Property="Template">
<ControlTemplate>
<Border Background="{TemplateBinding Background}" />

2
src/Avalonia.Themes.Default/TabStripItem.xaml

@ -2,7 +2,7 @@
<Style Selector="TabStripItem">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="FontSize" Value="{DynamicResource FontSizeLarge}"/>
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundLightBrush}"/>
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundLowBrush}"/>
<Setter Property="Template">
<ControlTemplate>
<ContentPresenter Name="PART_ContentPresenter"

4
src/Avalonia.Themes.Default/TextBox.xaml

@ -54,10 +54,10 @@
</Setter>
</Style>
<Style Selector="TextBox:pointerover /template/ Border#border">
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderDarkBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderHighBrush}"/>
</Style>
<Style Selector="TextBox:focus /template/ Border#border">
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderDarkBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderHighBrush}"/>
</Style>
<Style Selector="TextBox:error /template/ Border#border">
<Setter Property="BorderBrush" Value="{DynamicResource ErrorBrush}"/>

6
src/Avalonia.Themes.Default/ToggleButton.xaml

@ -1,7 +1,7 @@
<Styles xmlns="https://github.com/avaloniaui">
<Style Selector="ToggleButton">
<Setter Property="Background" Value="{DynamicResource ThemeControlMidBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderLightBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderLowBrush}"/>
<Setter Property="BorderThickness" Value="{DynamicResource ThemeBorderThickness}"/>
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundBrush}"/>
<Setter Property="Padding" Value="4"/>
@ -23,14 +23,14 @@
</Setter>
</Style>
<Style Selector="ToggleButton:checked /template/ ContentPresenter">
<Setter Property="Background" Value="{DynamicResource ThemeControlDarkBrush}"/>
<Setter Property="Background" Value="{DynamicResource ThemeControlHighBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderMidBrush}"/>
</Style>
<Style Selector="ToggleButton:pointerover /template/ ContentPresenter">
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderMidBrush}"/>
</Style>
<Style Selector="ToggleButton:pressed /template/ ContentPresenter">
<Setter Property="Background" Value="{DynamicResource ThemeControlDarkBrush}"/>
<Setter Property="Background" Value="{DynamicResource ThemeControlHighBrush}"/>
</Style>
<Style Selector="ToggleButton:disabled">
<Setter Property="Opacity" Value="{DynamicResource ThemeDisabledOpacity}"/>

2
src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs

@ -66,7 +66,7 @@ namespace Avalonia.Gtk3
DisplayClassName =
Utf8Buffer.StringFromPtr(Native.GTypeName(Marshal.ReadIntPtr(Marshal.ReadIntPtr(disp))));
using (var utf = new Utf8Buffer("avalonia.app." + Guid.NewGuid()))
using (var utf = new Utf8Buffer($"avalonia.app.a{Guid.NewGuid().ToString("N")}"))
App = Native.GtkApplicationNew(utf, 0);
//Mark current thread as UI thread
s_tlsMarker = true;

2
src/Markup/Avalonia.Markup/Data/MultiBinding.cs

@ -61,7 +61,7 @@ namespace Avalonia.Data
var targetType = targetProperty?.PropertyType ?? typeof(object);
var children = Bindings.Select(x => x.Initiate(target, null));
var input = children.Select(x => x.Subject).CombineLatest().Select(x => ConvertValue(x, targetType));
var input = children.Select(x => x.Observable).CombineLatest().Select(x => ConvertValue(x, targetType));
var mode = Mode == BindingMode.Default ?
targetProperty?.GetMetadata(target.GetType()).DefaultBindingMode : Mode;

35
tests/Avalonia.Controls.UnitTests/ListBoxTests.cs

@ -196,6 +196,41 @@ namespace Avalonia.Controls.UnitTests
target.Presenter.Panel.Children.Cast<ListBoxItem>().Select(x => (string)x.Content));
}
[Fact]
public void ListBox_After_Scroll_IndexOutOfRangeException_Shouldnt_Be_Thrown()
{
var items = Enumerable.Range(0, 11).Select(x => $"{x}").ToArray();
var target = new ListBox
{
Template = ListBoxTemplate(),
Items = items,
ItemTemplate = new FuncDataTemplate<string>(x => new TextBlock { Height = 11 })
};
Prepare(target);
var panel = target.Presenter.Panel as IVirtualizingPanel;
var listBoxItems = panel.Children.OfType<ListBoxItem>();
//virtualization should have created exactly 10 items
Assert.Equal(10, listBoxItems.Count());
Assert.Equal("0", listBoxItems.First().DataContext);
Assert.Equal("9", listBoxItems.Last().DataContext);
//instead pixeloffset > 0 there could be pretty complex sequence for repro
//it involves add/remove/scroll to end multiple actions
//which i can't find so far :(, but this is the simplest way to add it to unit test
panel.PixelOffset = 1;
//here scroll to end -> IndexOutOfRangeException is thrown
target.Scroll.Offset = new Vector(0, 2);
Assert.True(true);
}
private FuncControlTemplate ListBoxTemplate()
{
return new FuncControlTemplate<ListBox>(parent =>

31
tests/Avalonia.Markup.UnitTests/Data/MultiBindingTests.cs

@ -41,6 +41,37 @@ namespace Avalonia.Markup.UnitTests.Data
Assert.Equal("1,2,3", result);
}
[Fact]
public async Task Nested_MultiBinding_Should_Be_Set_Up()
{
var source = new { A = 1, B = 2, C = 3 };
var binding = new MultiBinding
{
Converter = new ConcatConverter(),
Bindings =
{
new Binding { Path = "A" },
new MultiBinding
{
Converter = new ConcatConverter(),
Bindings =
{
new Binding { Path = "B"},
new Binding { Path = "C"}
}
}
}
};
var target = new Mock<IAvaloniaObject>().As<IControl>();
target.Setup(x => x.GetValue(Control.DataContextProperty)).Returns(source);
var observable = binding.Initiate(target.Object, null).Observable;
var result = await observable.Take(1);
Assert.Equal("1,2,3", result);
}
[Fact]
public void Should_Return_FallbackValue_When_Converter_Returns_UnsetValue()
{

82
tests/Avalonia.ReactiveUI.UnitTests/AvaloniaActivationForViewFetcherTest.cs

@ -23,7 +23,8 @@ namespace Avalonia
public TestUserControlWithWhenActivated()
{
this.WhenActivated(disposables => {
this.WhenActivated(disposables =>
{
Active = true;
Disposable
.Create(() => Active = false)
@ -38,7 +39,8 @@ namespace Avalonia
public TestWindowWithWhenActivated()
{
this.WhenActivated(disposables => {
this.WhenActivated(disposables =>
{
Active = true;
Disposable
.Create(() => Active = false)
@ -47,6 +49,42 @@ namespace Avalonia
}
}
public class ActivatableViewModel : ISupportsActivation
{
public ViewModelActivator Activator { get; }
public bool IsActivated { get; private set; }
public ActivatableViewModel()
{
Activator = new ViewModelActivator();
this.WhenActivated(disposables =>
{
IsActivated = true;
Disposable
.Create(() => IsActivated = false)
.DisposeWith(disposables);
});
}
}
public class ActivatableWindow : ReactiveWindow<ActivatableViewModel>
{
public ActivatableWindow() => this.WhenActivated(disposables => { });
}
public class ActivatableUserControl : ReactiveUserControl<ActivatableViewModel>
{
public ActivatableUserControl() => this.WhenActivated(disposables => { });
}
public AvaloniaActivationForViewFetcherTest()
{
Locator.CurrentMutable.RegisterConstant(
new AvaloniaActivationForViewFetcher(),
typeof(IActivationForViewFetcher));
}
[Fact]
public void Visual_Element_Is_Activated_And_Deactivated()
{
@ -86,10 +124,6 @@ namespace Avalonia
[Fact]
public void Activation_For_View_Fetcher_Should_Support_When_Activated()
{
Locator.CurrentMutable.RegisterConstant(
new AvaloniaActivationForViewFetcher(),
typeof(IActivationForViewFetcher));
var userControl = new TestUserControlWithWhenActivated();
Assert.False(userControl.Active);
@ -104,10 +138,6 @@ namespace Avalonia
[Fact]
public void Activation_For_View_Fetcher_Should_Support_Windows()
{
Locator.CurrentMutable.RegisterConstant(
new AvaloniaActivationForViewFetcher(),
typeof(IActivationForViewFetcher));
using (var application = UnitTestApplication.Start(TestServices.MockWindowingPlatform))
{
var window = new TestWindowWithWhenActivated();
@ -120,5 +150,37 @@ namespace Avalonia
Assert.False(window.Active);
}
}
[Fact]
public void Activatable_Window_View_Model_Is_Activated_And_Deactivated()
{
using (var application = UnitTestApplication.Start(TestServices.MockWindowingPlatform))
{
var viewModel = new ActivatableViewModel();
var window = new ActivatableWindow { ViewModel = viewModel };
Assert.False(viewModel.IsActivated);
window.Show();
Assert.True(viewModel.IsActivated);
window.Close();
Assert.False(viewModel.IsActivated);
}
}
[Fact]
public void Activatable_User_Control_View_Model_Is_Activated_And_Deactivated()
{
var root = new TestRoot();
var viewModel = new ActivatableViewModel();
var control = new ActivatableUserControl { ViewModel = viewModel };
Assert.False(viewModel.IsActivated);
root.Child = control;
Assert.True(viewModel.IsActivated);
root.Child = null;
Assert.False(viewModel.IsActivated);
}
}
}

2
tools/packages.config

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Cake" version="0.28.0" />
<package id="Cake" version="0.30.0" />
</packages>

Loading…
Cancel
Save