committed by
GitHub
419 changed files with 11376 additions and 2573 deletions
@ -0,0 +1,8 @@ |
|||
blank_issues_enabled: false |
|||
contact_links: |
|||
- name: Questions, Discussions, Ideas |
|||
url: https://github.com/AvaloniaUI/Avalonia/discussions/new |
|||
about: Please ask and answer questions here. |
|||
- name: Avalonia Community Support on Gitter |
|||
url: https://gitter.im/AvaloniaUI/Avalonia |
|||
about: Please ask and answer questions here. |
|||
@ -1,5 +1,5 @@ |
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<ItemGroup> |
|||
<PackageReference Include="ReactiveUI" Version="12.1.1" /> |
|||
<PackageReference Include="ReactiveUI" Version="13.2.10" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
|
|||
@ -1,5 +1,5 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ControlCatalog.Android" android:versionCode="1" android:versionName="1.0" android:installLocation="auto"> |
|||
<uses-sdk android:targetSdkVersion="29" /> |
|||
<uses-sdk android:targetSdkVersion="30" /> |
|||
<application android:label="ControlCatalog.Android"></application> |
|||
</manifest> |
|||
|
After Width: | Height: | Size: 1.3 KiB |
@ -0,0 +1,102 @@ |
|||
<UserControl xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
|||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
|||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" |
|||
x:Class="ControlCatalog.Pages.ContextFlyoutPage"> |
|||
<UserControl.Styles> |
|||
<Style Selector="FlyoutPresenter.NoPadding"> |
|||
<Setter Property="Padding" Value="0" /> |
|||
</Style> |
|||
</UserControl.Styles> |
|||
|
|||
<StackPanel Orientation="Vertical" Spacing="4"> |
|||
<TextBlock Classes="h1">Context Flyout</TextBlock> |
|||
<TextBlock Classes="h2">A right click Flyout that can be applied to any control.</TextBlock> |
|||
|
|||
<StackPanel Orientation="Horizontal" |
|||
Margin="0,16,0,0" |
|||
HorizontalAlignment="Center" |
|||
Spacing="16"> |
|||
<Border Background="{DynamicResource SystemAccentColor}" |
|||
Margin="16" |
|||
Padding="48,48,48,48"> |
|||
<Border.ContextFlyout> |
|||
<MenuFlyout> |
|||
<MenuItem Header="Standard _Menu Item" InputGesture="Ctrl+A" /> |
|||
<MenuItem Header="_Disabled Menu Item" IsEnabled="False" InputGesture="Ctrl+D" /> |
|||
<Separator/> |
|||
<MenuItem Header="Menu with _Submenu"> |
|||
<MenuItem Header="Submenu _1"/> |
|||
<MenuItem Header="Submenu _2"/> |
|||
</MenuItem> |
|||
<MenuItem Header="Menu Item with _Icon" InputGesture="Ctrl+Shift+B"> |
|||
<MenuItem.Icon> |
|||
<Image Source="/Assets/github_icon.png"/> |
|||
</MenuItem.Icon> |
|||
</MenuItem> |
|||
<MenuItem Header="Menu Item with _Checkbox"> |
|||
<MenuItem.Icon> |
|||
<CheckBox BorderThickness="0" IsHitTestVisible="False" IsChecked="True"/> |
|||
</MenuItem.Icon> |
|||
</MenuItem> |
|||
</MenuFlyout> |
|||
</Border.ContextFlyout> |
|||
<TextBlock Text="Defined in XAML"/> |
|||
</Border> |
|||
<Border Background="{DynamicResource SystemAccentColor}" |
|||
Margin="16" |
|||
Padding="48,48,48,48"> |
|||
<Border.ContextMenu> |
|||
<ContextMenu Items="{Binding MenuItems}"> |
|||
<ContextMenu.Styles> |
|||
<Style Selector="MenuItem"> |
|||
<Setter Property="Header" Value="{Binding Header}"/> |
|||
<Setter Property="Items" Value="{Binding Items}"/> |
|||
<Setter Property="Command" Value="{Binding Command}"/> |
|||
<Setter Property="CommandParameter" Value="{Binding CommandParameter}"/> |
|||
</Style> |
|||
</ContextMenu.Styles> |
|||
</ContextMenu> |
|||
</Border.ContextMenu> |
|||
<TextBlock Text="Dynamically Generated"/> |
|||
</Border> |
|||
</StackPanel> |
|||
|
|||
<TextBlock Text="Custom ContextFlyout for TextBox" /> |
|||
|
|||
<TextBox Name="TextBox" Width="150" HorizontalAlignment="Center" ContextMenu="{x:Null}"> |
|||
<TextBox.ContextFlyout> |
|||
<Flyout FlyoutPresenterClasses="NoPadding"> |
|||
<StackPanel Orientation="Horizontal"> |
|||
<StackPanel.Styles> |
|||
<Style Selector="Button"> |
|||
<Setter Property="Background" Value="Transparent" /> |
|||
<Setter Property="Height" Value="40" /> |
|||
<Setter Property="Width" Value="40" /> |
|||
<Setter Property="VerticalContentAlignment" Value="Center" /> |
|||
</Style> |
|||
<Style Selector="Button:disabled /template/ ContentPresenter#PART_ContentPresenter"> |
|||
<Setter Property="Background" Value="Transparent" /> |
|||
<Setter Property="Opacity" Value="0.5" /> |
|||
</Style> |
|||
</StackPanel.Styles> |
|||
<Button Name="CutButton" Command="{Binding $parent[TextBox].Cut}" IsEnabled="{Binding $parent[TextBox].CanCut}"> |
|||
<PathIcon Width="14" Height="14" Data="M5.22774,2.08072 C5.43359778,1.94704 5.7011484,1.98419259 5.86368634,2.15675215 L5.91939,2.22774 L12.5191,12.3904 C12.956,12.1419 13.4614,12.0000019 14,12.0000019 C15.6569,12.0000019 17,13.3431 17,15.0000019 C17,16.6569 15.6569,18.0000019 14,18.0000019 C12.3431,18.0000019 11,16.6569 11,15.0000019 C11,14.3201402 11.226152,13.693011 11.6073785,13.1899092 L11.7401,13.0269 L10,10.3474 L8.25991,13.0269 C8.72078,13.5543 9,14.2446 9,15.0000019 C9,16.6569 7.65685,18.0000019 6,18.0000019 C4.34315,18.0000019 3,16.6569 3,15.0000019 C3,13.3431 4.34315,12.0000019 6,12.0000019 C6.46163143,12.0000019 6.89890041,12.1042536 7.28955831,12.2905296 L7.4809,12.3904 L9.40382,9.42936 L5.08072,2.77238 C4.93033,2.54079 4.99615,2.23112 5.22774,2.08072 Z M14,13 C12.8954,13 12,13.8954 12,15 C12,16.1046 12.8954,17 14,17 C15.1046,17 16,16.1046 16,15 C16,13.8954 15.1046,13 14,13 Z M6,13 C4.89543,13 4,13.8954 4,15 C4,16.1046 4.89543,17 6,17 C7.10457,17 8,16.1046 8,15 C8,13.8954 7.10457,13 6,13 Z M14.7723,2.08072 C15.0039,2.23112 15.0697,2.54079 14.9193,2.77238 L11.1924,8.51133 L10.5962,7.59329 L14.0806,2.22774 C14.231,1.99615 14.5407,1.93033 14.7723,2.08072 Z" /> |
|||
</Button> |
|||
<Button Name="CopyButton" Content="Copy" Command="{Binding $parent[TextBox].Copy}" IsEnabled="{Binding $parent[TextBox].CanCopy}"> |
|||
<PathIcon Width="14" Height="14" Data="M5.50280381,4.62704038 L5.5,6.75 L5.5,17.2542087 C5.5,19.0491342 6.95507456,20.5042087 8.75,20.5042087 L17.3662868,20.5044622 C17.057338,21.3782241 16.2239751,22.0042087 15.2444057,22.0042087 L8.75,22.0042087 C6.12664744,22.0042087 4,19.8775613 4,17.2542087 L4,6.75 C4,5.76928848 4.62744523,4.93512464 5.50280381,4.62704038 Z M17.75,2 C18.9926407,2 20,3.00735931 20,4.25 L20,17.25 C20,18.4926407 18.9926407,19.5 17.75,19.5 L8.75,19.5 C7.50735931,19.5 6.5,18.4926407 6.5,17.25 L6.5,4.25 C6.5,3.00735931 7.50735931,2 8.75,2 L17.75,2 Z M17.75,3.5 L8.75,3.5 C8.33578644,3.5 8,3.83578644 8,4.25 L8,17.25 C8,17.6642136 8.33578644,18 8.75,18 L17.75,18 C18.1642136,18 18.5,17.6642136 18.5,17.25 L18.5,4.25 C18.5,3.83578644 18.1642136,3.5 17.75,3.5 Z" /> |
|||
</Button> |
|||
<Button Name="PasteButton" Content="Paste" Command="{Binding $parent[TextBox].Paste}" IsEnabled="{Binding $parent[TextBox].CanPaste}"> |
|||
<PathIcon Width="14" Height="14" Data="M13.75,2 C14.940864,2 15.9156449,2.92516159 15.9948092,4.09595119 L16,4.25 L16,4.25 C16,4.16530567 15.9953205,4.0817043 15.9862059,3.99944035 L17.75,4 C18.9926407,4 20,5.00735931 20,6.25 L20,19.75 C20,20.9926407 18.9926407,22 17.75,22 L6.25,22 C5.00735931,22 4,20.9926407 4,19.75 L4,6.25 C4,5.00735931 5.00735931,4 6.25,4 L8.01379413,3.99944035 C8.00733496,4.05773764 8.00310309,4.11670658 8.00118552,4.17626017 L8,4.25 C8,3.00735931 9.00735931,2 10.25,2 L13.75,2 Z M13.75,6.5 L10.25,6.5 C9.45594921,6.5 8.75796956,6.08867052 8.357512,5.4674625 L8.37902077,5.50019943 L8.37902077,5.50019943 L6.25,5.5 C5.83578644,5.5 5.5,5.83578644 5.5,6.25 L5.5,19.75 C5.5,20.1642136 5.83578644,20.5 6.25,20.5 L17.75,20.5 C18.1642136,20.5 18.5,20.1642136 18.5,19.75 L18.5,6.25 C18.5,5.83578644 18.1642136,5.5 17.75,5.5 L15.6209792,5.50019943 L15.642488,5.4674625 C15.2420304,6.08867052 14.5440508,6.5 13.75,6.5 Z M13.75,3.5 L10.25,3.5 C9.83578644,3.5 9.5,3.83578644 9.5,4.25 C9.5,4.66421356 9.83578644,5 10.25,5 L13.75,5 C14.1642136,5 14.5,4.66421356 14.5,4.25 C14.5,3.83578644 14.1642136,3.5 13.75,3.5 Z" /> |
|||
</Button> |
|||
<Button Name="ClearButton" Content="Clear" Command="{Binding $parent[TextBox].Clear}"> |
|||
<PathIcon Width="14" Height="14" Data="M3.52499419,3.71761187 L3.61611652,3.61611652 C4.0717282,3.16050485 4.79154862,3.13013074 5.28238813,3.52499419 L5.38388348,3.61611652 L14,12.233 L22.6161165,3.61611652 C23.1042719,3.12796116 23.8957281,3.12796116 24.3838835,3.61611652 C24.8720388,4.10427189 24.8720388,4.89572811 24.3838835,5.38388348 L15.767,14 L24.3838835,22.6161165 C24.8394952,23.0717282 24.8698693,23.7915486 24.4750058,24.2823881 L24.3838835,24.3838835 C23.9282718,24.8394952 23.2084514,24.8698693 22.7176119,24.4750058 L22.6161165,24.3838835 L14,15.767 L5.38388348,24.3838835 C4.89572811,24.8720388 4.10427189,24.8720388 3.61611652,24.3838835 C3.12796116,23.8957281 3.12796116,23.1042719 3.61611652,22.6161165 L12.233,14 L3.61611652,5.38388348 C3.16050485,4.9282718 3.13013074,4.20845138 3.52499419,3.71761187 L3.61611652,3.61611652 L3.52499419,3.71761187 Z" /> |
|||
</Button> |
|||
</StackPanel> |
|||
</Flyout> |
|||
</TextBox.ContextFlyout> |
|||
</TextBox> |
|||
|
|||
</StackPanel> |
|||
</UserControl> |
|||
@ -0,0 +1,45 @@ |
|||
using Avalonia; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Markup.Xaml; |
|||
using ControlCatalog.ViewModels; |
|||
using Avalonia.Interactivity; |
|||
namespace ControlCatalog.Pages |
|||
{ |
|||
public class ContextFlyoutPage : UserControl |
|||
{ |
|||
private TextBox _textBox; |
|||
|
|||
public ContextFlyoutPage() |
|||
{ |
|||
InitializeComponent(); |
|||
|
|||
var vm = new ContextFlyoutPageViewModel(); |
|||
vm.View = this; |
|||
DataContext = vm; |
|||
|
|||
_textBox = this.FindControl<TextBox>("TextBox"); |
|||
|
|||
var cutButton = this.FindControl<Button>("CutButton"); |
|||
cutButton.Click += CloseFlyout; |
|||
|
|||
var copyButton = this.FindControl<Button>("CopyButton"); |
|||
copyButton.Click += CloseFlyout; |
|||
|
|||
var pasteButton = this.FindControl<Button>("PasteButton"); |
|||
pasteButton.Click += CloseFlyout; |
|||
|
|||
var clearButton = this.FindControl<Button>("ClearButton"); |
|||
clearButton.Click += CloseFlyout; |
|||
} |
|||
|
|||
private void CloseFlyout(object sender, RoutedEventArgs e) |
|||
{ |
|||
_textBox.ContextFlyout.Hide(); |
|||
} |
|||
|
|||
private void InitializeComponent() |
|||
{ |
|||
AvaloniaXamlLoader.Load(this); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
<UserControl xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
x:Class="ControlCatalog.Pages.CursorPage"> |
|||
<Grid ColumnDefinitions="*,*" RowDefinitions="Auto,*"> |
|||
<StackPanel Grid.ColumnSpan="2" Orientation="Vertical" Spacing="4"> |
|||
<TextBlock Classes="h1">Cursor</TextBlock> |
|||
<TextBlock Classes="h2">Defines a cursor (mouse pointer)</TextBlock> |
|||
</StackPanel> |
|||
|
|||
<ListBox Grid.Row="1" Items="{Binding StandardCursors}" Margin="0 8 8 8"> |
|||
<ListBox.Styles> |
|||
<Style Selector="ListBoxItem"> |
|||
<Setter Property="Cursor" Value="{Binding Cursor}"/> |
|||
</Style> |
|||
</ListBox.Styles> |
|||
<ListBox.ItemTemplate> |
|||
<DataTemplate> |
|||
<TextBlock Text="{Binding Type}"/> |
|||
</DataTemplate> |
|||
</ListBox.ItemTemplate> |
|||
</ListBox> |
|||
|
|||
<StackPanel Grid.Column="1" Grid.Row="1" Margin="8 8 0 8"> |
|||
<Button Cursor="{Binding CustomCursor}" Margin="0 8" Padding="16"> |
|||
<TextBlock>Custom Cursor</TextBlock> |
|||
</Button> |
|||
</StackPanel> |
|||
</Grid> |
|||
</UserControl> |
|||
@ -0,0 +1,20 @@ |
|||
using Avalonia.Controls; |
|||
using Avalonia.Markup.Xaml; |
|||
using ControlCatalog.ViewModels; |
|||
|
|||
namespace ControlCatalog.Pages |
|||
{ |
|||
public class CursorPage : UserControl |
|||
{ |
|||
public CursorPage() |
|||
{ |
|||
this.InitializeComponent(); |
|||
DataContext = new CursorPageViewModel(); |
|||
} |
|||
|
|||
private void InitializeComponent() |
|||
{ |
|||
AvaloniaXamlLoader.Load(this); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,264 @@ |
|||
<UserControl xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
|||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
|||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="700" |
|||
x:Class="ControlCatalog.Pages.FlyoutsPage"> |
|||
|
|||
<UserControl.Resources> |
|||
<MenuFlyout x:Key="SharedMenuFlyout"> |
|||
<MenuItem Header="Item 1"> |
|||
<MenuItem Header="Subitem 1" /> |
|||
<MenuItem Header="Subitem 2" /> |
|||
<MenuItem Header="Subitem 3" /> |
|||
</MenuItem> |
|||
<MenuItem Header="Item 2" InputGesture="Ctrl+A" /> |
|||
<MenuItem Header="Item 3" /> |
|||
</MenuFlyout> |
|||
<Flyout Placement="Bottom" x:Key="BasicFlyout"> |
|||
<Panel Width="100" Height="100"> |
|||
<TextBlock Text="Flyout Content!" /> |
|||
</Panel> |
|||
</Flyout> |
|||
</UserControl.Resources> |
|||
|
|||
<ScrollViewer HorizontalScrollBarVisibility="Disabled"> |
|||
<StackPanel Spacing="10"> |
|||
<TextBlock FontSize="18" Text="Button with a Flyout" /> |
|||
<StackPanel> |
|||
<Border BorderBrush="{DynamicResource SystemControlHighlightBaseLowBrush}" |
|||
BorderThickness="1" Padding="15"> |
|||
<Button Content="Click Me!" Flyout="{StaticResource BasicFlyout}" /> |
|||
</Border> |
|||
<Panel Background="{DynamicResource SystemControlBackgroundBaseLowBrush}"> |
|||
<TextBlock Name="ButtonFlyoutXamlText" Padding="15" /> |
|||
</Panel> |
|||
</StackPanel> |
|||
|
|||
<TextBlock FontSize="18" Text="MenuFlyout" /> |
|||
<StackPanel> |
|||
<Border BorderBrush="{DynamicResource SystemControlHighlightBaseLowBrush}" |
|||
BorderThickness="1" Padding="15"> |
|||
<Button Content="Click Me!" Flyout="{StaticResource SharedMenuFlyout}" /> |
|||
</Border> |
|||
<Panel Background="{DynamicResource SystemControlBackgroundBaseLowBrush}"> |
|||
<TextBlock Name="MenuFlyoutXamlText" Padding="15" /> |
|||
</Panel> |
|||
</StackPanel> |
|||
|
|||
<TextBlock FontSize="18" Text="Attached Flyouts" /> |
|||
<StackPanel> |
|||
<Border BorderBrush="{DynamicResource SystemControlHighlightBaseLowBrush}" |
|||
BorderThickness="1" Padding="15"> |
|||
<Panel Background="{DynamicResource SystemControlBackgroundBaseLowBrush}" |
|||
HorizontalAlignment="Left" |
|||
Height="100" |
|||
Name="AttachedFlyoutPanel"> |
|||
<FlyoutBase.AttachedFlyout> |
|||
<Flyout> |
|||
<Panel Height="100"> |
|||
<TextBlock Text="Attached Flyout!" |
|||
VerticalAlignment="Center" |
|||
Margin="10"/> |
|||
</Panel> |
|||
</Flyout> |
|||
</FlyoutBase.AttachedFlyout> |
|||
|
|||
<TextBlock Text="Double click panel to launch AttachedFlyout" |
|||
VerticalAlignment="Center" |
|||
Margin="10"/> |
|||
|
|||
</Panel> |
|||
</Border> |
|||
<Panel Background="{DynamicResource SystemControlBackgroundBaseLowBrush}"> |
|||
<TextBlock Name="AttachedFlyoutXamlText" Padding="15" /> |
|||
</Panel> |
|||
</StackPanel> |
|||
|
|||
|
|||
<TextBlock FontSize="18" Text="Sharing Flyouts" /> |
|||
<StackPanel> |
|||
<Border BorderBrush="{DynamicResource SystemControlHighlightBaseLowBrush}" |
|||
BorderThickness="1" Padding="15"> |
|||
<StackPanel Orientation="Horizontal" Spacing="30"> |
|||
<Button Content="Launch Flyout on this button" Flyout="{StaticResource SharedMenuFlyout}"/> |
|||
<Button Content="Launch Flyout on this button" Flyout="{StaticResource SharedMenuFlyout}"/> |
|||
</StackPanel> |
|||
</Border> |
|||
<Panel Background="{DynamicResource SystemControlBackgroundBaseLowBrush}"> |
|||
<TextBlock Name="SharedFlyoutXamlText" Padding="15" /> |
|||
</Panel> |
|||
</StackPanel> |
|||
|
|||
<TextBlock FontSize="18" Text="Flyout Placements" /> |
|||
<StackPanel> |
|||
<Border BorderBrush="{DynamicResource SystemControlHighlightBaseLowBrush}" |
|||
BorderThickness="1" Padding="15"> |
|||
<UniformGrid Columns="3"> |
|||
<UniformGrid.Styles> |
|||
<Style Selector="Button"> |
|||
<Setter Property="Margin" Value="10" /> |
|||
</Style> |
|||
</UniformGrid.Styles> |
|||
<Button Content="Placement=Top"> |
|||
<Button.Flyout> |
|||
<Flyout Placement="Top"> |
|||
<Panel Width="100" Height="100"> |
|||
<TextBlock Text="Flyout Content!" /> |
|||
</Panel> |
|||
</Flyout> |
|||
</Button.Flyout> |
|||
</Button> |
|||
<Button Content="Placement=Bottom"> |
|||
<Button.Flyout> |
|||
<Flyout Placement="Bottom"> |
|||
<Panel Width="100" Height="100"> |
|||
<TextBlock Text="Flyout Content!" /> |
|||
</Panel> |
|||
</Flyout> |
|||
</Button.Flyout> |
|||
</Button> |
|||
<Button Content="Placement=Left"> |
|||
<Button.Flyout> |
|||
<Flyout Placement="Left"> |
|||
<Panel Width="100" Height="100"> |
|||
<TextBlock Text="Flyout Content!" /> |
|||
</Panel> |
|||
</Flyout> |
|||
</Button.Flyout> |
|||
</Button> |
|||
<Button Content="Placement=Right"> |
|||
<Button.Flyout> |
|||
<Flyout Placement="Right"> |
|||
<Panel Width="100" Height="100"> |
|||
<TextBlock Text="Flyout Content!" /> |
|||
</Panel> |
|||
</Flyout> |
|||
</Button.Flyout> |
|||
</Button> |
|||
<Button Content="Placement=TopEdgeAlignedLeft"> |
|||
<Button.Flyout> |
|||
<Flyout Placement="TopEdgeAlignedLeft"> |
|||
<Panel Width="100" Height="100"> |
|||
<TextBlock Text="Flyout Content!" /> |
|||
</Panel> |
|||
</Flyout> |
|||
</Button.Flyout> |
|||
</Button> |
|||
<Button Content="Placement=TopEdgeAlignedRight"> |
|||
<Button.Flyout> |
|||
<Flyout Placement="TopEdgeAlignedRight"> |
|||
<Panel Width="100" Height="100"> |
|||
<TextBlock Text="Flyout Content!" /> |
|||
</Panel> |
|||
</Flyout> |
|||
</Button.Flyout> |
|||
</Button> |
|||
<Button Content="Placement=BottomEdgeAlignedLeft"> |
|||
<Button.Flyout> |
|||
<Flyout Placement="BottomEdgeAlignedLeft"> |
|||
<Panel Width="100" Height="100"> |
|||
<TextBlock Text="Flyout Content!" /> |
|||
</Panel> |
|||
</Flyout> |
|||
</Button.Flyout> |
|||
</Button> |
|||
<Button Content="Placement=BottomEdgeAlignedRight"> |
|||
<Button.Flyout> |
|||
<Flyout Placement="BottomEdgeAlignedRight"> |
|||
<Panel Width="100" Height="100"> |
|||
<TextBlock Text="Flyout Content!" /> |
|||
</Panel> |
|||
</Flyout> |
|||
</Button.Flyout> |
|||
</Button> |
|||
<Button Content="Placement=LeftEdgeAlignedTop"> |
|||
<Button.Flyout> |
|||
<Flyout Placement="LeftEdgeAlignedTop"> |
|||
<Panel Width="100" Height="100"> |
|||
<TextBlock Text="Flyout Content!" /> |
|||
</Panel> |
|||
</Flyout> |
|||
</Button.Flyout> |
|||
</Button> |
|||
<Button Content="Placement=LeftEdgeAlignedBottom"> |
|||
<Button.Flyout> |
|||
<Flyout Placement="LeftEdgeAlignedBottom"> |
|||
<Panel Width="100" Height="100"> |
|||
<TextBlock Text="Flyout Content!" /> |
|||
</Panel> |
|||
</Flyout> |
|||
</Button.Flyout> |
|||
</Button> |
|||
<Button Content="Placement=RightEdgeAlignedBottom"> |
|||
<Button.Flyout> |
|||
<Flyout Placement="RightEdgeAlignedTop"> |
|||
<Panel Width="100" Height="100"> |
|||
<TextBlock Text="Flyout Content!" /> |
|||
</Panel> |
|||
</Flyout> |
|||
</Button.Flyout> |
|||
</Button> |
|||
<Button Content="Placement=RightEdgeAlignedBottom"> |
|||
<Button.Flyout> |
|||
<Flyout Placement="RightEdgeAlignedBottom"> |
|||
<Panel Width="100" Height="100"> |
|||
<TextBlock Text="Flyout Content!" /> |
|||
</Panel> |
|||
</Flyout> |
|||
</Button.Flyout> |
|||
</Button> |
|||
|
|||
</UniformGrid> |
|||
</Border> |
|||
</StackPanel> |
|||
|
|||
<TextBlock FontSize="18" Text="Flyout ShowMode" /> |
|||
<StackPanel> |
|||
<Border BorderBrush="{DynamicResource SystemControlHighlightBaseLowBrush}" |
|||
BorderThickness="1" Padding="15"> |
|||
<WrapPanel Orientation="Horizontal"> |
|||
<WrapPanel.Styles> |
|||
<Style Selector="Button"> |
|||
<Setter Property="Margin" Value="4" /> |
|||
</Style> |
|||
</WrapPanel.Styles> |
|||
<Button Content="ShowMode=Standard (default)"> |
|||
<Button.Flyout> |
|||
<Flyout> |
|||
<StackPanel Width="200"> |
|||
<TextBox /> |
|||
<TextBlock Text="Standard ShowMode attempts to focus the Flyout when its opened" TextWrapping="Wrap"/> |
|||
</StackPanel> |
|||
</Flyout> |
|||
</Button.Flyout> |
|||
</Button> |
|||
<Button Content="ShowMode=Transient"> |
|||
<Button.Flyout> |
|||
<Flyout ShowMode="Transient"> |
|||
<StackPanel Width="200"> |
|||
<TextBox /> |
|||
<TextBlock Text="Transient ShowMode does not focus the Flyout when opened" TextWrapping="Wrap"/> |
|||
</StackPanel> |
|||
</Flyout> |
|||
</Button.Flyout> |
|||
</Button> |
|||
<Button Content="ShowMode=TransientWithDismissOnPointerMoveAway"> |
|||
<Button.Flyout> |
|||
<Flyout ShowMode="TransientWithDismissOnPointerMoveAway"> |
|||
<StackPanel Width="200"> |
|||
<TextBox /> |
|||
<TextBlock Text="Show in Transient mode (no focus), but closes the Flyout when the pointer moves away" TextWrapping="Wrap"/> |
|||
</StackPanel> |
|||
</Flyout> |
|||
</Button.Flyout> |
|||
</Button> |
|||
|
|||
</WrapPanel> |
|||
</Border> |
|||
</StackPanel> |
|||
|
|||
</StackPanel> |
|||
</ScrollViewer> |
|||
|
|||
</UserControl> |
|||
@ -0,0 +1,81 @@ |
|||
using Avalonia.Controls; |
|||
using Avalonia.Controls.Primitives; |
|||
using Avalonia.Markup.Xaml; |
|||
using Avalonia.Interactivity; |
|||
|
|||
namespace ControlCatalog.Pages |
|||
{ |
|||
public class FlyoutsPage : UserControl |
|||
{ |
|||
public FlyoutsPage() |
|||
{ |
|||
InitializeComponent(); |
|||
|
|||
var afp = this.FindControl<Panel>("AttachedFlyoutPanel"); |
|||
if (afp != null) |
|||
{ |
|||
afp.DoubleTapped += Afp_DoubleTapped; |
|||
} |
|||
|
|||
SetXamlTexts(); |
|||
} |
|||
|
|||
private void Afp_DoubleTapped(object sender, RoutedEventArgs e) |
|||
{ |
|||
if (sender is Panel p) |
|||
{ |
|||
FlyoutBase.ShowAttachedFlyout(p); |
|||
} |
|||
} |
|||
|
|||
private void InitializeComponent() |
|||
{ |
|||
AvaloniaXamlLoader.Load(this); |
|||
} |
|||
|
|||
private void SetXamlTexts() |
|||
{ |
|||
var bfxt = this.FindControl<TextBlock>("ButtonFlyoutXamlText"); |
|||
bfxt.Text = "<Button Content=\"Click me!\">\n" + |
|||
" <Button.Flyout>\n" + |
|||
" <Flyout>\n" + |
|||
" <Panel Width=\"100\" Height=\"100\">\n" + |
|||
" <TextBlock Text=\"Flyout Content!\" />\n" + |
|||
" </Panel>\n" + |
|||
" </Flyout>\n" + |
|||
" </Button.Flyout>\n</Button>"; |
|||
|
|||
var mfxt = this.FindControl<TextBlock>("MenuFlyoutXamlText"); |
|||
mfxt.Text = "<Button Content=\"Click me!\">\n" + |
|||
" <Button.Flyout>\n" + |
|||
" <MenuFlyout>\n" + |
|||
" <MenuItem Header=\"Item 1\">\n" + |
|||
" <MenuItem Header=\"Item 2\">\n" + |
|||
" </MenuFlyout>\n" + |
|||
" </Button.Flyout>\n</Button>"; |
|||
|
|||
var afxt = this.FindControl<TextBlock>("AttachedFlyoutXamlText"); |
|||
afxt.Text = "<Panel Name=\"AttachedFlyoutPanel\">\n" + |
|||
" <FlyoutBase.AttachedFlyout>\n" + |
|||
" <Flyout>\n" + |
|||
" <Panel Height=\"100\">\n" + |
|||
" <TextBlock Text=\"Attached Flyout\" />\n" + |
|||
" </Panel>\n" + |
|||
" </Flyout>\n" + |
|||
" </FlyoutBase.AttachedFlyout>\n</Panel>" + |
|||
"\n\n In DoubleTapped handler:\n" + |
|||
"FlyoutBase.ShowAttachedFlyout(AttachedFlyoutPanel);"; |
|||
|
|||
var sfxt = this.FindControl<TextBlock>("SharedFlyoutXamlText"); |
|||
sfxt.Text = "Declare a flyout in Resources:\n" + |
|||
"<Window.Resources>\n" + |
|||
" <Flyout x:Key=\"SharedFlyout\">\n" + |
|||
" <Panel Width=\"100\" Height=\"100\">\n" + |
|||
" <TextBlock Text=\"Flyout Content!\" />\n" + |
|||
" </Panel>\n" + |
|||
" </Flyout>\n</Window.Resources>\n\n" + |
|||
"Then attach the flyout where you want it:\n" + |
|||
"<Button Content=\"Launch Flyout here\" Flyout=\"{StaticResource SharedFlyout}\" />"; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,78 @@ |
|||
using System.Collections.Generic; |
|||
using System.Reactive; |
|||
using System.Threading.Tasks; |
|||
using Avalonia.Controls; |
|||
using Avalonia.VisualTree; |
|||
using MiniMvvm; |
|||
|
|||
namespace ControlCatalog.ViewModels |
|||
{ |
|||
public class ContextFlyoutPageViewModel |
|||
{ |
|||
public Control View { get; set; } |
|||
public ContextFlyoutPageViewModel() |
|||
{ |
|||
OpenCommand = MiniCommand.CreateFromTask(Open); |
|||
SaveCommand = MiniCommand.Create(Save); |
|||
OpenRecentCommand = MiniCommand.Create<string>(OpenRecent); |
|||
|
|||
MenuItems = new[] |
|||
{ |
|||
new MenuItemViewModel { Header = "_Open...", Command = OpenCommand }, |
|||
new MenuItemViewModel { Header = "Save", Command = SaveCommand }, |
|||
new MenuItemViewModel { Header = "-" }, |
|||
new MenuItemViewModel |
|||
{ |
|||
Header = "Recent", |
|||
Items = new[] |
|||
{ |
|||
new MenuItemViewModel |
|||
{ |
|||
Header = "File1.txt", |
|||
Command = OpenRecentCommand, |
|||
CommandParameter = @"c:\foo\File1.txt" |
|||
}, |
|||
new MenuItemViewModel |
|||
{ |
|||
Header = "File2.txt", |
|||
Command = OpenRecentCommand, |
|||
CommandParameter = @"c:\foo\File2.txt" |
|||
}, |
|||
} |
|||
}, |
|||
}; |
|||
} |
|||
|
|||
public IReadOnlyList<MenuItemViewModel> MenuItems { get; set; } |
|||
public MiniCommand OpenCommand { get; } |
|||
public MiniCommand SaveCommand { get; } |
|||
public MiniCommand OpenRecentCommand { get; } |
|||
|
|||
public async Task Open() |
|||
{ |
|||
var window = View?.GetVisualRoot() as Window; |
|||
if (window == null) |
|||
return; |
|||
var dialog = new OpenFileDialog(); |
|||
var result = await dialog.ShowAsync(window); |
|||
|
|||
if (result != null) |
|||
{ |
|||
foreach (var path in result) |
|||
{ |
|||
System.Diagnostics.Debug.WriteLine($"Opened: {path}"); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public void Save() |
|||
{ |
|||
System.Diagnostics.Debug.WriteLine("Save"); |
|||
} |
|||
|
|||
public void OpenRecent(string path) |
|||
{ |
|||
System.Diagnostics.Debug.WriteLine($"Open recent: {path}"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using Avalonia; |
|||
using Avalonia.Input; |
|||
using Avalonia.Media.Imaging; |
|||
using Avalonia.Platform; |
|||
using MiniMvvm; |
|||
|
|||
namespace ControlCatalog.ViewModels |
|||
{ |
|||
public class CursorPageViewModel : ViewModelBase |
|||
{ |
|||
public CursorPageViewModel() |
|||
{ |
|||
StandardCursors = Enum.GetValues(typeof(StandardCursorType)) |
|||
.Cast<StandardCursorType>() |
|||
.Select(x => new StandardCursorModel(x)) |
|||
.ToList(); |
|||
|
|||
var loader = AvaloniaLocator.Current.GetService<IAssetLoader>(); |
|||
var s = loader.Open(new Uri("avares://ControlCatalog/Assets/avalonia-32.png")); |
|||
var bitmap = new Bitmap(s); |
|||
CustomCursor = new Cursor(bitmap, new PixelPoint(16, 16)); |
|||
} |
|||
|
|||
public IEnumerable<StandardCursorModel> StandardCursors { get; } |
|||
|
|||
public Cursor CustomCursor { get; } |
|||
|
|||
public class StandardCursorModel |
|||
{ |
|||
public StandardCursorModel(StandardCursorType type) |
|||
{ |
|||
Type = type; |
|||
Cursor = new Cursor(type); |
|||
} |
|||
|
|||
public StandardCursorType Type { get; } |
|||
|
|||
public Cursor Cursor { get; } |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,89 @@ |
|||
using System; |
|||
using System.Diagnostics; |
|||
using System.Drawing.Drawing2D; |
|||
using System.Security.Cryptography; |
|||
using Avalonia; |
|||
using Avalonia.Controls; |
|||
using Avalonia.LogicalTree; |
|||
using Avalonia.Media; |
|||
using Avalonia.Media.Imaging; |
|||
using Avalonia.Media.Immutable; |
|||
using Avalonia.Threading; |
|||
using Avalonia.Visuals.Media.Imaging; |
|||
|
|||
namespace RenderDemo.Pages |
|||
{ |
|||
public class PathMeasurementPage : Control |
|||
{ |
|||
static PathMeasurementPage() |
|||
{ |
|||
AffectsRender<PathMeasurementPage>(BoundsProperty); |
|||
} |
|||
|
|||
private RenderTargetBitmap _bitmap; |
|||
|
|||
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) |
|||
{ |
|||
_bitmap = new RenderTargetBitmap(new PixelSize(500, 500), new Vector(96, 96)); |
|||
base.OnAttachedToLogicalTree(e); |
|||
} |
|||
|
|||
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e) |
|||
{ |
|||
_bitmap.Dispose(); |
|||
_bitmap = null; |
|||
base.OnDetachedFromLogicalTree(e); |
|||
} |
|||
|
|||
readonly IPen strokePen = new ImmutablePen(Brushes.DarkBlue, 10d, null, PenLineCap.Round, PenLineJoin.Round); |
|||
readonly IPen strokePen1 = new ImmutablePen(Brushes.Purple, 10d, null, PenLineCap.Round, PenLineJoin.Round); |
|||
readonly IPen strokePen2 = new ImmutablePen(Brushes.Green, 10d, null, PenLineCap.Round, PenLineJoin.Round); |
|||
readonly IPen strokePen3 = new ImmutablePen(Brushes.LightBlue, 10d, null, PenLineCap.Round, PenLineJoin.Round); |
|||
readonly IPen strokePen4 = new ImmutablePen(Brushes.Red, 1d, null, PenLineCap.Round, PenLineJoin.Round); |
|||
|
|||
public override void Render(DrawingContext context) |
|||
{ |
|||
using (var ctxi = _bitmap.CreateDrawingContext(null)) |
|||
using (var bitmapCtx = new DrawingContext(ctxi, false)) |
|||
{ |
|||
ctxi.Clear(default); |
|||
|
|||
var basePath = new PathGeometry(); |
|||
|
|||
using (var basePathCtx = basePath.Open()) |
|||
{ |
|||
basePathCtx.BeginFigure(new Point(20, 20), false); |
|||
basePathCtx.LineTo(new Point(400, 50)); |
|||
basePathCtx.LineTo(new Point(80, 100)); |
|||
basePathCtx.LineTo(new Point(300, 150)); |
|||
basePathCtx.EndFigure(false); |
|||
} |
|||
|
|||
bitmapCtx.DrawGeometry(null, strokePen, basePath); |
|||
|
|||
|
|||
var length = basePath.PlatformImpl.ContourLength; |
|||
|
|||
if (basePath.PlatformImpl.TryGetSegment(length * 0.05, length * 0.2, true, out var dst1)) |
|||
bitmapCtx.DrawGeometry(null, strokePen1, dst1); |
|||
|
|||
if (basePath.PlatformImpl.TryGetSegment(length * 0.2, length * 0.8, true, out var dst2)) |
|||
bitmapCtx.DrawGeometry(null, strokePen2, dst2); |
|||
|
|||
if (basePath.PlatformImpl.TryGetSegment(length * 0.8, length * 0.95, true, out var dst3)) |
|||
bitmapCtx.DrawGeometry(null, strokePen3, dst3); |
|||
|
|||
var pathBounds = basePath.GetRenderBounds(strokePen); |
|||
|
|||
bitmapCtx.DrawRectangle(null, strokePen4, pathBounds); |
|||
} |
|||
|
|||
|
|||
context.DrawImage(_bitmap, |
|||
new Rect(0, 0, 500, 500), |
|||
new Rect(0, 0, 500, 500)); |
|||
|
|||
base.Render(context); |
|||
} |
|||
} |
|||
} |
|||
@ -1,47 +0,0 @@ |
|||
using Android.App; |
|||
using Android.OS; |
|||
|
|||
namespace Avalonia.Android |
|||
{ |
|||
internal class ActivityTracker : Java.Lang.Object, global::Android.App.Application.IActivityLifecycleCallbacks |
|||
{ |
|||
public static Activity Current { get; private set; } |
|||
public void OnActivityCreated(Activity activity, Bundle savedInstanceState) |
|||
{ |
|||
Current = activity; |
|||
} |
|||
|
|||
public void OnActivityDestroyed(Activity activity) |
|||
{ |
|||
if (Current == activity) |
|||
Current = null; |
|||
} |
|||
|
|||
public void OnActivityPaused(Activity activity) |
|||
{ |
|||
if (Current == activity) |
|||
Current = null; |
|||
} |
|||
|
|||
public void OnActivityResumed(Activity activity) |
|||
{ |
|||
Current = activity; |
|||
} |
|||
|
|||
public void OnActivitySaveInstanceState(Activity activity, Bundle outState) |
|||
{ |
|||
Current = activity; |
|||
} |
|||
|
|||
public void OnActivityStarted(Activity activity) |
|||
{ |
|||
Current = activity; |
|||
} |
|||
|
|||
public void OnActivityStopped(Activity activity) |
|||
{ |
|||
if (Current == activity) |
|||
Current = null; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,96 @@ |
|||
using System; |
|||
using Android.Content; |
|||
using Android.Runtime; |
|||
using Android.Views; |
|||
using Android.Views.InputMethods; |
|||
using Avalonia.Input; |
|||
using Avalonia.Input.TextInput; |
|||
|
|||
namespace Avalonia.Android |
|||
{ |
|||
class AndroidInputMethod<TView> : ITextInputMethodImpl |
|||
where TView: View, IInitEditorInfo |
|||
{ |
|||
private readonly TView _host; |
|||
private readonly InputMethodManager _imm; |
|||
private IInputElement _inputElement; |
|||
|
|||
public AndroidInputMethod(TView host) |
|||
{ |
|||
if (host.OnCheckIsTextEditor() == false) |
|||
throw new InvalidOperationException("Host should return true from OnCheckIsTextEditor()"); |
|||
|
|||
_host = host; |
|||
_imm = host.Context.GetSystemService(Context.InputMethodService).JavaCast<InputMethodManager>(); |
|||
|
|||
_host.Focusable = true; |
|||
_host.FocusableInTouchMode = true; |
|||
_host.ViewTreeObserver.AddOnGlobalLayoutListener(new SoftKeyboardListner(_host)); |
|||
} |
|||
|
|||
public void Reset() |
|||
{ |
|||
_imm.RestartInput(_host); |
|||
} |
|||
|
|||
public void SetActive(bool active) |
|||
{ |
|||
if (active) |
|||
{ |
|||
_host.RequestFocus(); |
|||
Reset(); |
|||
_imm.ShowSoftInput(_host, ShowFlags.Implicit); |
|||
} |
|||
else |
|||
_imm.HideSoftInputFromWindow(_host.WindowToken, HideSoftInputFlags.None); |
|||
} |
|||
|
|||
public void SetCursorRect(Rect rect) |
|||
{ |
|||
} |
|||
|
|||
public void SetOptions(TextInputOptionsQueryEventArgs options) |
|||
{ |
|||
if (_inputElement != null) |
|||
{ |
|||
_inputElement.PointerReleased -= RestoreSoftKeyboard; |
|||
} |
|||
|
|||
_inputElement = options.Source as InputElement; |
|||
|
|||
if (_inputElement == null) |
|||
{ |
|||
_imm.HideSoftInputFromWindow(_host.WindowToken, HideSoftInputFlags.None); |
|||
} |
|||
|
|||
_host.InitEditorInfo((outAttrs) => |
|||
{ |
|||
outAttrs.InputType = options.ContentType switch |
|||
{ |
|||
TextInputContentType.Email => global::Android.Text.InputTypes.TextVariationEmailAddress, |
|||
TextInputContentType.Number => global::Android.Text.InputTypes.ClassNumber, |
|||
TextInputContentType.Password => global::Android.Text.InputTypes.TextVariationPassword, |
|||
TextInputContentType.Phone => global::Android.Text.InputTypes.ClassPhone, |
|||
TextInputContentType.Url => global::Android.Text.InputTypes.TextVariationUri, |
|||
_ => global::Android.Text.InputTypes.ClassText |
|||
}; |
|||
|
|||
if (options.AutoCapitalization) |
|||
{ |
|||
outAttrs.InitialCapsMode = global::Android.Text.CapitalizationMode.Sentences; |
|||
outAttrs.InputType |= global::Android.Text.InputTypes.TextFlagCapSentences; |
|||
} |
|||
|
|||
if (options.Multiline) |
|||
outAttrs.InputType |= global::Android.Text.InputTypes.TextFlagMultiLine; |
|||
}); |
|||
|
|||
//_inputElement.PointerReleased += RestoreSoftKeyboard;
|
|||
} |
|||
|
|||
private void RestoreSoftKeyboard(object sender, PointerReleasedEventArgs e) |
|||
{ |
|||
_imm.ShowSoftInput(_host, ShowFlags.Implicit); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,101 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Reactive.Disposables; |
|||
using System.Threading.Tasks; |
|||
|
|||
using Android.OS; |
|||
using Android.Views; |
|||
|
|||
using Avalonia.Rendering; |
|||
|
|||
using Java.Lang; |
|||
|
|||
namespace Avalonia.Android |
|||
{ |
|||
internal sealed class ChoreographerTimer : Java.Lang.Object, IRenderTimer, Choreographer.IFrameCallback |
|||
{ |
|||
private readonly object _lock = new object(); |
|||
|
|||
private readonly Thread _thread; |
|||
private readonly TaskCompletionSource<Choreographer> _choreographer = new TaskCompletionSource<Choreographer>(); |
|||
|
|||
private readonly ISet<AvaloniaView> _views = new HashSet<AvaloniaView>(); |
|||
|
|||
private Action<TimeSpan> _tick; |
|||
private int _count; |
|||
|
|||
public ChoreographerTimer() |
|||
{ |
|||
_thread = new Thread(Loop); |
|||
_thread.Start(); |
|||
} |
|||
|
|||
public event Action<TimeSpan> Tick |
|||
{ |
|||
add |
|||
{ |
|||
lock (_lock) |
|||
{ |
|||
_tick += value; |
|||
_count++; |
|||
|
|||
if (_count == 1) |
|||
{ |
|||
_choreographer.Task.Result.PostFrameCallback(this); |
|||
} |
|||
} |
|||
} |
|||
remove |
|||
{ |
|||
lock (_lock) |
|||
{ |
|||
_tick -= value; |
|||
_count--; |
|||
} |
|||
} |
|||
} |
|||
|
|||
internal IDisposable SubscribeView(AvaloniaView view) |
|||
{ |
|||
lock (_lock) |
|||
{ |
|||
_views.Add(view); |
|||
|
|||
if (_views.Count == 1) |
|||
{ |
|||
_choreographer.Task.Result.PostFrameCallback(this); |
|||
} |
|||
} |
|||
|
|||
return Disposable.Create( |
|||
() => |
|||
{ |
|||
lock (_lock) |
|||
{ |
|||
_views.Remove(view); |
|||
} |
|||
} |
|||
); |
|||
} |
|||
|
|||
private void Loop() |
|||
{ |
|||
Looper.Prepare(); |
|||
_choreographer.SetResult(Choreographer.Instance); |
|||
Looper.Loop(); |
|||
} |
|||
|
|||
public void DoFrame(long frameTimeNanos) |
|||
{ |
|||
_tick?.Invoke(TimeSpan.FromTicks(frameTimeNanos / 100)); |
|||
|
|||
lock (_lock) |
|||
{ |
|||
if (_count > 0 && _views.Count > 0) |
|||
{ |
|||
Choreographer.Instance.PostFrameCallback(this); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,12 +1,21 @@ |
|||
using System; |
|||
using Avalonia.Input; |
|||
using Avalonia.Platform; |
|||
|
|||
namespace Avalonia.Android |
|||
{ |
|||
internal class CursorFactory : IStandardCursorFactory |
|||
internal class CursorFactory : ICursorFactory |
|||
{ |
|||
public IPlatformHandle GetCursor(StandardCursorType cursorType) |
|||
=> new PlatformHandle(IntPtr.Zero, "ZeroCursor"); |
|||
public ICursorImpl CreateCursor(IBitmapImpl cursor, PixelPoint hotSpot) => CursorImpl.ZeroCursor; |
|||
|
|||
public ICursorImpl GetCursor(StandardCursorType cursorType) => CursorImpl.ZeroCursor; |
|||
|
|||
private sealed class CursorImpl : ICursorImpl |
|||
{ |
|||
public static CursorImpl ZeroCursor { get; } = new CursorImpl(); |
|||
|
|||
private CursorImpl() { } |
|||
|
|||
public void Dispose() { } |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,12 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
using Android.Views.InputMethods; |
|||
|
|||
namespace Avalonia.Android |
|||
{ |
|||
interface IInitEditorInfo |
|||
{ |
|||
void InitEditorInfo(Action<EditorInfo> init); |
|||
} |
|||
} |
|||
@ -1,23 +1,30 @@ |
|||
using Avalonia.OpenGL.Egl; |
|||
using System; |
|||
|
|||
using Avalonia.OpenGL.Egl; |
|||
using Avalonia.OpenGL.Surfaces; |
|||
|
|||
namespace Avalonia.Android.OpenGL |
|||
{ |
|||
internal sealed class GlRenderTarget : EglPlatformSurfaceRenderTargetBase |
|||
internal sealed class GlRenderTarget : EglPlatformSurfaceRenderTargetBase, IGlPlatformSurfaceRenderTargetWithCorruptionInfo |
|||
{ |
|||
private readonly EglGlPlatformSurfaceBase.IEglWindowGlPlatformSurfaceInfo _info; |
|||
private readonly EglSurface _surface; |
|||
private readonly IntPtr _handle; |
|||
|
|||
public GlRenderTarget( |
|||
EglPlatformOpenGlInterface egl, |
|||
EglGlPlatformSurfaceBase.IEglWindowGlPlatformSurfaceInfo info, |
|||
EglSurface surface) |
|||
EglSurface surface, |
|||
IntPtr handle) |
|||
: base(egl) |
|||
{ |
|||
_info = info; |
|||
_surface = surface; |
|||
_handle = handle; |
|||
} |
|||
|
|||
public bool IsCorrupted => _handle != _info.Handle; |
|||
|
|||
public override IGlPlatformSurfaceRenderingSession BeginDraw() => BeginDraw(_surface, _info); |
|||
} |
|||
} |
|||
|
|||
@ -1,14 +0,0 @@ |
|||
using Avalonia.Input; |
|||
|
|||
namespace Avalonia.Android.Platform.Input |
|||
{ |
|||
public class AndroidMouseDevice : MouseDevice |
|||
{ |
|||
public static AndroidMouseDevice Instance { get; } = new AndroidMouseDevice(); |
|||
|
|||
public AndroidMouseDevice() |
|||
{ |
|||
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,42 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
using Android.Content; |
|||
using Android.OS; |
|||
using Android.Util; |
|||
using Android.Views; |
|||
using Avalonia.Input; |
|||
|
|||
namespace Avalonia.Android |
|||
{ |
|||
class SoftKeyboardListner : Java.Lang.Object, ViewTreeObserver.IOnGlobalLayoutListener |
|||
{ |
|||
private const int DefaultKeyboardHeightDP = 100; |
|||
private static readonly int EstimatedKeyboardDP = DefaultKeyboardHeightDP + (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop ? 48 : 0); |
|||
|
|||
private readonly View _host; |
|||
private bool _wasKeyboard; |
|||
|
|||
public SoftKeyboardListner(View view) |
|||
{ |
|||
_host = view; |
|||
} |
|||
|
|||
public void OnGlobalLayout() |
|||
{ |
|||
int estimatedKeyboardHeight = (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, |
|||
EstimatedKeyboardDP, _host.Resources.DisplayMetrics); |
|||
|
|||
var rect = new global::Android.Graphics.Rect(); |
|||
_host.GetWindowVisibleDisplayFrame(rect); |
|||
|
|||
int heightDiff = _host.RootView.Height - (rect.Bottom - rect.Top); |
|||
var isKeyboard = heightDiff >= estimatedKeyboardHeight; |
|||
|
|||
if (_wasKeyboard && !isKeyboard) |
|||
KeyboardDevice.Instance.SetFocusedElement(null, NavigationMethod.Unspecified, KeyModifiers.None); |
|||
|
|||
_wasKeyboard = isKeyboard; |
|||
} |
|||
} |
|||
} |
|||
@ -1,11 +0,0 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<configuration> |
|||
<runtime> |
|||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> |
|||
<dependentAssembly> |
|||
<assemblyIdentity name="System.Runtime.InteropServices.WindowsRuntime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> |
|||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" /> |
|||
</dependentAssembly> |
|||
</assemblyBinding> |
|||
</runtime> |
|||
</configuration> |
|||
@ -1,6 +1,6 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="Avalonia.AndroidTestApplication" android:versionCode="1" android:versionName="1.0" android:installLocation="auto"> |
|||
<uses-sdk android:targetSdkVersion="29" /> |
|||
<uses-sdk android:targetSdkVersion="30" /> |
|||
<application android:label="Avalonia.AndroidTestApplication" android:icon="@drawable/Icon" android:hardwareAccelerated="true"></application> |
|||
<uses-permission android:name="android.permission.INTERNET" /> |
|||
</manifest> |
|||
@ -0,0 +1,8 @@ |
|||
namespace Avalonia.PropertyStore |
|||
{ |
|||
internal interface IBatchUpdate |
|||
{ |
|||
void BeginBatchUpdate(); |
|||
void EndBatchUpdate(); |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using System; |
|||
using XamlX.Transform; |
|||
|
|||
namespace Avalonia.Build.Tasks |
|||
{ |
|||
public class DeterministicIdGenerator : IXamlIdentifierGenerator |
|||
{ |
|||
private int _nextId = 1; |
|||
|
|||
public string GenerateIdentifierPart() => (_nextId++).ToString(); |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
Compat issues with assembly Avalonia.Controls: |
|||
InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Controls.INativeMenuExporterEventsImplBridge.RaiseClosed()' is present in the implementation but not in the contract. |
|||
InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Controls.INativeMenuExporterEventsImplBridge.RaiseOpening()' is present in the implementation but not in the contract. |
|||
MembersMustExist : Member 'public void Avalonia.Controls.Embedding.Offscreen.OffscreenTopLevelImplBase.SetCursor(Avalonia.Platform.IPlatformHandle)' does not exist in the implementation but it does exist in the contract. |
|||
MembersMustExist : Member 'public Avalonia.AvaloniaProperty Avalonia.AvaloniaProperty Avalonia.Controls.Notifications.NotificationCard.CloseOnClickProperty' does not exist in the implementation but it does exist in the contract. |
|||
EnumValuesMustMatch : Enum value 'Avalonia.Platform.ExtendClientAreaChromeHints Avalonia.Platform.ExtendClientAreaChromeHints.Default' is (System.Int32)2 in the implementation but (System.Int32)1 in the contract. |
|||
InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Platform.ITopLevelImpl.SetCursor(Avalonia.Platform.ICursorImpl)' is present in the implementation but not in the contract. |
|||
InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Platform.ITopLevelImpl.SetCursor(Avalonia.Platform.IPlatformHandle)' is present in the contract but not in the implementation. |
|||
MembersMustExist : Member 'public void Avalonia.Platform.ITopLevelImpl.SetCursor(Avalonia.Platform.IPlatformHandle)' does not exist in the implementation but it does exist in the contract. |
|||
Total Issues: 7 |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue