committed by
GitHub
102 changed files with 2382 additions and 980 deletions
@ -1,108 +1,195 @@ |
|||
<UserControl xmlns="https://github.com/avaloniaui" |
|||
xmlns:pages="clr-namespace:ControlCatalog.Pages" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
x:Class="ControlCatalog.MainView"> |
|||
<UserControl x:Class="ControlCatalog.MainView" |
|||
xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:controls="clr-namespace:ControlSamples;assembly=ControlSamples" |
|||
xmlns:pages="clr-namespace:ControlCatalog.Pages" |
|||
xmlns:models="clr-namespace:ControlCatalog.Models"> |
|||
<Grid> |
|||
<Grid.Styles> |
|||
<Style Selector="TextBlock.h2"> |
|||
<Setter Property="TextWrapping" Value="Wrap"/> |
|||
<Setter Property="MaxWidth" Value="400"/> |
|||
<Setter Property="HorizontalAlignment" Value="Left"/> |
|||
</Style> |
|||
</Grid.Styles> |
|||
<TabControl Classes="sidebar" Name="Sidebar"> |
|||
<TabItem Header="Acrylic"><pages:AcrylicPage/></TabItem> |
|||
<TabItem Header="AutoCompleteBox"><pages:AutoCompleteBoxPage/></TabItem> |
|||
<TabItem Header="Border"><pages:BorderPage/></TabItem> |
|||
<TabItem Header="Button"><pages:ButtonPage/></TabItem> |
|||
<TabItem Header="ButtonSpinner"><pages:ButtonSpinnerPage/></TabItem> |
|||
<TabItem Header="Calendar"><pages:CalendarPage/></TabItem> |
|||
<TabItem Header="Canvas"><pages:CanvasPage/></TabItem> |
|||
<TabItem Header="Carousel"><pages:CarouselPage/></TabItem> |
|||
<TabItem Header="CheckBox"><pages:CheckBoxPage/></TabItem> |
|||
<TabItem Header="ComboBox"><pages:ComboBoxPage/></TabItem> |
|||
<Style Selector="TextBlock.h2"> |
|||
<Setter Property="TextWrapping" Value="Wrap" /> |
|||
<Setter Property="MaxWidth" Value="400" /> |
|||
<Setter Property="HorizontalAlignment" Value="Left" /> |
|||
</Style> |
|||
</Grid.Styles> |
|||
<controls:HamburgerMenu Name="Sidebar"> |
|||
<TabItem Header="Acrylic"> |
|||
<pages:AcrylicPage /> |
|||
</TabItem> |
|||
<TabItem Header="AutoCompleteBox"> |
|||
<pages:AutoCompleteBoxPage /> |
|||
</TabItem> |
|||
<TabItem Header="Border"> |
|||
<pages:BorderPage /> |
|||
</TabItem> |
|||
<TabItem Header="Button"> |
|||
<pages:ButtonPage /> |
|||
</TabItem> |
|||
<TabItem Header="ButtonSpinner"> |
|||
<pages:ButtonSpinnerPage /> |
|||
</TabItem> |
|||
<TabItem Header="Calendar"> |
|||
<pages:CalendarPage /> |
|||
</TabItem> |
|||
<TabItem Header="Canvas"> |
|||
<pages:CanvasPage /> |
|||
</TabItem> |
|||
<TabItem Header="Carousel"> |
|||
<pages:CarouselPage /> |
|||
</TabItem> |
|||
<TabItem Header="CheckBox"> |
|||
<pages:CheckBoxPage /> |
|||
</TabItem> |
|||
<TabItem Header="ComboBox"> |
|||
<pages:ComboBoxPage /> |
|||
</TabItem> |
|||
<TabItem Header="ContextFlyout"> |
|||
<pages:ContextFlyoutPage/> |
|||
<pages:ContextFlyoutPage /> |
|||
</TabItem> |
|||
<TabItem Header="ContextMenu"><pages:ContextMenuPage/></TabItem> |
|||
<TabItem Header="Cursor" |
|||
ScrollViewer.VerticalScrollBarVisibility="Disabled"> |
|||
<pages:CursorPage/> |
|||
<TabItem Header="ContextMenu"> |
|||
<pages:ContextMenuPage /> |
|||
</TabItem> |
|||
<TabItem Header="DataGrid" |
|||
ScrollViewer.VerticalScrollBarVisibility="Disabled" |
|||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"> |
|||
<pages:DataGridPage/> |
|||
<TabItem Header="Cursor" ScrollViewer.VerticalScrollBarVisibility="Disabled"> |
|||
<pages:CursorPage /> |
|||
</TabItem> |
|||
<TabItem Header="DataGrid" |
|||
ScrollViewer.HorizontalScrollBarVisibility="Disabled" |
|||
ScrollViewer.VerticalScrollBarVisibility="Disabled"> |
|||
<pages:DataGridPage /> |
|||
</TabItem> |
|||
<TabItem Header="Date/Time Picker"> |
|||
<pages:DateTimePickerPage/> |
|||
<pages:DateTimePickerPage /> |
|||
</TabItem> |
|||
<TabItem Header="CalendarDatePicker"> |
|||
<pages:CalendarDatePickerPage/></TabItem> |
|||
<TabItem Header="Drag+Drop"><pages:DragAndDropPage/></TabItem> |
|||
<TabItem Header="Expander"><pages:ExpanderPage/></TabItem> |
|||
<pages:CalendarDatePickerPage /> |
|||
</TabItem> |
|||
<TabItem Header="Drag+Drop"> |
|||
<pages:DragAndDropPage /> |
|||
</TabItem> |
|||
<TabItem Header="Expander"> |
|||
<pages:ExpanderPage /> |
|||
</TabItem> |
|||
<TabItem Header="Flyouts"> |
|||
<pages:FlyoutsPage /> |
|||
</TabItem> |
|||
<TabItem Header="Image" |
|||
ScrollViewer.VerticalScrollBarVisibility="Disabled" |
|||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"> |
|||
<pages:ImagePage/> |
|||
ScrollViewer.HorizontalScrollBarVisibility="Disabled" |
|||
ScrollViewer.VerticalScrollBarVisibility="Disabled"> |
|||
<pages:ImagePage /> |
|||
</TabItem> |
|||
<TabItem Header="ItemsRepeater" |
|||
ScrollViewer.VerticalScrollBarVisibility="Disabled" |
|||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"> |
|||
<pages:ItemsRepeaterPage/> |
|||
</TabItem> |
|||
<TabItem Header="Label"><pages:LabelsPage/></TabItem> |
|||
<TabItem Header="LayoutTransformControl"><pages:LayoutTransformControlPage/></TabItem> |
|||
<TabItem Header="ListBox" |
|||
ScrollViewer.HorizontalScrollBarVisibility="Disabled" |
|||
ScrollViewer.VerticalScrollBarVisibility="Disabled"> |
|||
<pages:ListBoxPage/> |
|||
</TabItem> |
|||
<TabItem Header="Menu"><pages:MenuPage/></TabItem> |
|||
<TabItem Header="Notifications"><pages:NotificationsPage/></TabItem> |
|||
<TabItem Header="NumericUpDown"><pages:NumericUpDownPage/></TabItem> |
|||
<TabItem Header="OpenGL"><pages:OpenGlPage/></TabItem> |
|||
<TabItem Header="Pointers (Touch)"><pages:PointersPage/></TabItem> |
|||
<TabItem Header="ProgressBar"><pages:ProgressBarPage/></TabItem> |
|||
<TabItem Header="RadioButton"><pages:RadioButtonPage/></TabItem> |
|||
<TabItem Header="RelativePanel"><pages:RelativePanelPage/></TabItem> |
|||
<TabItem Header="ScrollViewer"><pages:ScrollViewerPage/></TabItem> |
|||
<TabItem Header="Slider"><pages:SliderPage/></TabItem> |
|||
<TabItem Header="SplitView"><pages:SplitViewPage/></TabItem> |
|||
<TabItem Header="TabControl"><pages:TabControlPage/></TabItem> |
|||
<TabItem Header="TabStrip"><pages:TabStripPage/></TabItem> |
|||
<TabItem Header="TextBox"><pages:TextBoxPage/></TabItem> |
|||
<TabItem Header="TextBlock"><pages:TextBlockPage/></TabItem> |
|||
<TabItem Header="ToggleSwitch"><pages:ToggleSwitchPage/></TabItem> |
|||
<TabItem Header="ToolTip"><pages:ToolTipPage/></TabItem> |
|||
<TabItem Header="TreeView"><pages:TreeViewPage/></TabItem> |
|||
<TabItem Header="Viewbox"><pages:ViewboxPage/></TabItem> |
|||
<TabItem Header="Window Customizations"><pages:WindowCustomizationsPage/></TabItem> |
|||
<TabControl.Tag> |
|||
<StackPanel Width="115" Spacing="4" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="8"> |
|||
<ComboBox x:Name="Decorations" SelectedIndex="0"> |
|||
<ComboBoxItem>No Decorations</ComboBoxItem> |
|||
<ComboBoxItem>Border Only</ComboBoxItem> |
|||
<ComboBoxItem>Full Decorations</ComboBoxItem> |
|||
</ComboBox> |
|||
<ComboBox x:Name="Themes" SelectedIndex="0"> |
|||
<ComboBoxItem>Fluent - Light</ComboBoxItem> |
|||
<ComboBoxItem>Fluent - Dark</ComboBoxItem> |
|||
<ComboBoxItem>Simple - Light</ComboBoxItem> |
|||
<ComboBoxItem>Simple - Dark</ComboBoxItem> |
|||
</ComboBox> |
|||
<ComboBox x:Name="TransparencyLevels" SelectedIndex="{Binding TransparencyLevel}"> |
|||
<ComboBoxItem>None</ComboBoxItem> |
|||
<ComboBoxItem>Transparent</ComboBoxItem> |
|||
<ComboBoxItem>Blur</ComboBoxItem> |
|||
<ComboBoxItem>AcrylicBlur</ComboBoxItem> |
|||
<ComboBoxItem>Mica</ComboBoxItem> |
|||
</ComboBox> |
|||
<ComboBox Items="{Binding WindowStates}" SelectedItem="{Binding WindowState}" /> |
|||
</StackPanel> |
|||
</TabControl.Tag> |
|||
</TabControl> |
|||
<pages:ItemsRepeaterPage /> |
|||
</TabItem> |
|||
<TabItem Header="Label"> |
|||
<pages:LabelsPage /> |
|||
</TabItem> |
|||
<TabItem Header="LayoutTransformControl"> |
|||
<pages:LayoutTransformControlPage /> |
|||
</TabItem> |
|||
<TabItem Header="ListBox" ScrollViewer.VerticalScrollBarVisibility="Disabled"> |
|||
<pages:ListBoxPage /> |
|||
</TabItem> |
|||
<TabItem Header="Menu"> |
|||
<pages:MenuPage /> |
|||
</TabItem> |
|||
<TabItem Header="Notifications"> |
|||
<pages:NotificationsPage /> |
|||
</TabItem> |
|||
<TabItem Header="NumericUpDown"> |
|||
<pages:NumericUpDownPage /> |
|||
</TabItem> |
|||
<TabItem Header="OpenGL"> |
|||
<pages:OpenGlPage /> |
|||
</TabItem> |
|||
<TabItem Header="Pointers (Touch)"> |
|||
<pages:PointersPage /> |
|||
</TabItem> |
|||
<TabItem Header="ProgressBar"> |
|||
<pages:ProgressBarPage /> |
|||
</TabItem> |
|||
<TabItem Header="RadioButton"> |
|||
<pages:RadioButtonPage /> |
|||
</TabItem> |
|||
<TabItem Header="RelativePanel"> |
|||
<pages:RelativePanelPage /> |
|||
</TabItem> |
|||
<TabItem Header="ScrollViewer"> |
|||
<pages:ScrollViewerPage /> |
|||
</TabItem> |
|||
<TabItem Header="Slider"> |
|||
<pages:SliderPage /> |
|||
</TabItem> |
|||
<TabItem Header="SplitView"> |
|||
<pages:SplitViewPage /> |
|||
</TabItem> |
|||
<TabItem Header="TabControl"> |
|||
<pages:TabControlPage /> |
|||
</TabItem> |
|||
<TabItem Header="TabStrip"> |
|||
<pages:TabStripPage /> |
|||
</TabItem> |
|||
<TabItem Header="TextBox"> |
|||
<pages:TextBoxPage /> |
|||
</TabItem> |
|||
<TabItem Header="TextBlock"> |
|||
<pages:TextBlockPage /> |
|||
</TabItem> |
|||
<TabItem Header="ToggleSwitch"> |
|||
<pages:ToggleSwitchPage /> |
|||
</TabItem> |
|||
<TabItem Header="ToolTip"> |
|||
<pages:ToolTipPage /> |
|||
</TabItem> |
|||
<TabItem Header="TreeView"> |
|||
<pages:TreeViewPage /> |
|||
</TabItem> |
|||
<TabItem Header="Viewbox"> |
|||
<pages:ViewboxPage /> |
|||
</TabItem> |
|||
<TabItem Header="Window Customizations"> |
|||
<pages:WindowCustomizationsPage /> |
|||
</TabItem> |
|||
<FlyoutBase.AttachedFlyout> |
|||
<Flyout> |
|||
<StackPanel Width="152" Spacing="8"> |
|||
<ComboBox x:Name="Decorations" |
|||
HorizontalAlignment="Stretch" |
|||
SelectedIndex="0"> |
|||
<ComboBox.Items> |
|||
<SystemDecorations>None</SystemDecorations> |
|||
<SystemDecorations>BorderOnly</SystemDecorations> |
|||
<SystemDecorations>Full</SystemDecorations> |
|||
</ComboBox.Items> |
|||
</ComboBox> |
|||
<ComboBox x:Name="Themes" |
|||
HorizontalAlignment="Stretch" |
|||
SelectedIndex="0"> |
|||
<ComboBox.Items> |
|||
<models:CatalogTheme>FluentLight</models:CatalogTheme> |
|||
<models:CatalogTheme>FluentDark</models:CatalogTheme> |
|||
<models:CatalogTheme>DefaultLight</models:CatalogTheme> |
|||
<models:CatalogTheme>DefaultDark</models:CatalogTheme> |
|||
</ComboBox.Items> |
|||
</ComboBox> |
|||
<ComboBox x:Name="TransparencyLevels" |
|||
HorizontalAlignment="Stretch" |
|||
SelectedIndex="{Binding TransparencyLevel}"> |
|||
<ComboBox.Items> |
|||
<WindowTransparencyLevel>None</WindowTransparencyLevel> |
|||
<WindowTransparencyLevel>Transparent</WindowTransparencyLevel> |
|||
<WindowTransparencyLevel>Blur</WindowTransparencyLevel> |
|||
<WindowTransparencyLevel>AcrylicBlur</WindowTransparencyLevel> |
|||
<WindowTransparencyLevel>Mica</WindowTransparencyLevel> |
|||
</ComboBox.Items> |
|||
</ComboBox> |
|||
<ComboBox HorizontalAlignment="Stretch" |
|||
Items="{Binding WindowStates}" |
|||
SelectedItem="{Binding WindowState}" /> |
|||
</StackPanel> |
|||
</Flyout> |
|||
</FlyoutBase.AttachedFlyout> |
|||
</controls:HamburgerMenu> |
|||
</Grid> |
|||
</UserControl> |
|||
|
|||
@ -0,0 +1,14 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
|
|||
namespace ControlCatalog.Models |
|||
{ |
|||
public enum CatalogTheme |
|||
{ |
|||
FluentLight, |
|||
FluentDark, |
|||
DefaultLight, |
|||
DefaultDark |
|||
} |
|||
} |
|||
@ -1,139 +1,165 @@ |
|||
<UserControl xmlns="https://github.com/avaloniaui" |
|||
<UserControl x:Class="ControlCatalog.Pages.AcrylicPage" |
|||
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.AcrylicPage"> |
|||
<Border Padding="20" HorizontalAlignment="Center"> |
|||
<StackPanel Spacing="20"> |
|||
d:DesignHeight="800" |
|||
d:DesignWidth="400" |
|||
mc:Ignorable="d"> |
|||
<UserControl.Styles> |
|||
<Style Selector="ExperimentalAcrylicBorder"> |
|||
<Setter Property="CornerRadius" Value="5" /> |
|||
<Setter Property="MaxWidth" Value="660" /> |
|||
</Style> |
|||
<Style Selector="TextBlock"> |
|||
<Setter Property="VerticalAlignment" Value="Center" /> |
|||
<Setter Property="Foreground" Value="Black" /> |
|||
</Style> |
|||
<Style Selector="Slider"> |
|||
<Setter Property="Margin" Value="8,0" /> |
|||
<Setter Property="Minimum" Value="0" /> |
|||
<Setter Property="Maximum" Value="1" /> |
|||
<Setter Property="LargeChange" Value="0.2" /> |
|||
<Setter Property="SmallChange" Value="0.1" /> |
|||
</Style> |
|||
</UserControl.Styles> |
|||
<StackPanel Spacing="20"> |
|||
|
|||
<ExperimentalAcrylicBorder Width="660" CornerRadius="5"> |
|||
<ExperimentalAcrylicBorder> |
|||
<ExperimentalAcrylicBorder.Material> |
|||
<ExperimentalAcrylicMaterial BackgroundSource="Digger" TintColor="White" /> |
|||
</ExperimentalAcrylicBorder.Material> |
|||
<Grid Margin="20,10" |
|||
ColumnDefinitions="Auto,*,Auto" |
|||
RowDefinitions="Auto,Auto"> |
|||
<TextBlock Grid.Row="0" |
|||
Grid.Column="0" |
|||
Text="TintOpacity" /> |
|||
<Slider Name="TintOpacitySlider" |
|||
Grid.Row="0" |
|||
Grid.Column="1" |
|||
Value="0.9" /> |
|||
<TextBlock Grid.Row="0" |
|||
Grid.Column="2" |
|||
Text="{Binding #TintOpacitySlider.Value, StringFormat=\{0:0.#\}}" /> |
|||
<TextBlock Grid.Row="1" |
|||
Grid.Column="0" |
|||
Text="MaterialOpacity" /> |
|||
<Slider Name="MaterialOpacitySlider" |
|||
Grid.Row="1" |
|||
Grid.Column="1" |
|||
Value="0.8" /> |
|||
<TextBlock Grid.Row="1" |
|||
Grid.Column="2" |
|||
Text="{Binding #MaterialOpacitySlider.Value, StringFormat=\{0:0.#\}}" /> |
|||
</Grid> |
|||
</ExperimentalAcrylicBorder> |
|||
|
|||
<UniformGrid x:Name="BordersGrid" |
|||
HorizontalAlignment="Stretch" |
|||
MaxWidth="660" |
|||
Columns="3"> |
|||
<UniformGrid.Styles> |
|||
<Style Selector="ExperimentalAcrylicBorder"> |
|||
<Setter Property="Height" Value="{Binding $self.Bounds.Width}" /> |
|||
<Setter Property="Margin" Value="10" /> |
|||
<Setter Property="MaxWidth" Value="200" /> |
|||
</Style> |
|||
</UniformGrid.Styles> |
|||
<ExperimentalAcrylicBorder> |
|||
<ExperimentalAcrylicBorder.Material> |
|||
<ExperimentalAcrylicMaterial |
|||
TintColor="White" |
|||
BackgroundSource="Digger" /> |
|||
<ExperimentalAcrylicMaterial BackgroundSource="Digger" |
|||
MaterialOpacity="{Binding #MaterialOpacitySlider.Value}" |
|||
TintColor="#FF0000" |
|||
TintOpacity="{Binding #TintOpacitySlider.Value}" /> |
|||
</ExperimentalAcrylicBorder.Material> |
|||
<StackPanel Spacing="5" Margin="40 10"> |
|||
<StackPanel Orientation="Horizontal"> |
|||
<TextBlock Text="TintOpacity" Foreground="Black" /> |
|||
<Slider Name="TintOpacitySlider" Minimum="0" Maximum="1" Value="0.9" SmallChange="0.1" LargeChange="0.2" Width="400" /> |
|||
<TextBlock Text="{Binding #TintOpacitySlider.Value, StringFormat=\{0:0.#\}}" Foreground="Black" /> |
|||
</StackPanel> |
|||
<StackPanel Orientation="Horizontal"> |
|||
<TextBlock Text="MaterialOpacity" Foreground="Black" /> |
|||
<Slider Name="MaterialOpacitySlider" Minimum="0" Maximum="1" Value="0.8" SmallChange="0.1" LargeChange="0.2" Width="400" /> |
|||
<TextBlock Text="{Binding #MaterialOpacitySlider.Value, StringFormat=\{0:0.#\}}" Foreground="Black" /> |
|||
</StackPanel> |
|||
</StackPanel> |
|||
</ExperimentalAcrylicBorder> |
|||
|
|||
<ExperimentalAcrylicBorder> |
|||
<ExperimentalAcrylicBorder.Material> |
|||
<ExperimentalAcrylicMaterial BackgroundSource="Digger" |
|||
MaterialOpacity="{Binding #MaterialOpacitySlider.Value}" |
|||
TintColor="#00FF00" |
|||
TintOpacity="{Binding #TintOpacitySlider.Value}" /> |
|||
</ExperimentalAcrylicBorder.Material> |
|||
</ExperimentalAcrylicBorder> |
|||
|
|||
<StackPanel Orientation="Horizontal" Spacing="20"> |
|||
<ExperimentalAcrylicBorder Height="200" Width="200" CornerRadius="5"> |
|||
<ExperimentalAcrylicBorder.Material> |
|||
<ExperimentalAcrylicMaterial |
|||
TintColor="#FF0000" |
|||
TintOpacity="{Binding #TintOpacitySlider.Value}" |
|||
MaterialOpacity="{Binding #MaterialOpacitySlider.Value}" |
|||
BackgroundSource="Digger" /> |
|||
</ExperimentalAcrylicBorder.Material> |
|||
</ExperimentalAcrylicBorder> |
|||
|
|||
<ExperimentalAcrylicBorder Height="200" Width="200" CornerRadius="5"> |
|||
<ExperimentalAcrylicBorder.Material> |
|||
<ExperimentalAcrylicMaterial |
|||
TintColor="#00FF00" |
|||
TintOpacity="{Binding #TintOpacitySlider.Value}" |
|||
MaterialOpacity="{Binding #MaterialOpacitySlider.Value}" |
|||
BackgroundSource="Digger" /> |
|||
</ExperimentalAcrylicBorder.Material> |
|||
</ExperimentalAcrylicBorder> |
|||
|
|||
<ExperimentalAcrylicBorder Height="200" Width="200" CornerRadius="5"> |
|||
<ExperimentalAcrylicBorder.Material> |
|||
<ExperimentalAcrylicMaterial |
|||
TintColor="#000000" |
|||
TintOpacity="{Binding #TintOpacitySlider.Value}" |
|||
MaterialOpacity="{Binding #MaterialOpacitySlider.Value}" |
|||
BackgroundSource="Digger" /> |
|||
</ExperimentalAcrylicBorder.Material> |
|||
</ExperimentalAcrylicBorder> |
|||
</StackPanel> |
|||
|
|||
<ExperimentalAcrylicBorder> |
|||
<ExperimentalAcrylicBorder.Material> |
|||
<ExperimentalAcrylicMaterial BackgroundSource="Digger" |
|||
MaterialOpacity="{Binding #MaterialOpacitySlider.Value}" |
|||
TintColor="#000000" |
|||
TintOpacity="{Binding #TintOpacitySlider.Value}" /> |
|||
</ExperimentalAcrylicBorder.Material> |
|||
</ExperimentalAcrylicBorder> |
|||
|
|||
<StackPanel Orientation="Horizontal" Spacing="20"> |
|||
<ExperimentalAcrylicBorder Height="200" Width="200" CornerRadius="5"> |
|||
<ExperimentalAcrylicBorder.Material> |
|||
<ExperimentalAcrylicMaterial |
|||
TintColor="#0000FF" |
|||
TintOpacity="{Binding #TintOpacitySlider.Value}" |
|||
MaterialOpacity="{Binding #MaterialOpacitySlider.Value}" |
|||
BackgroundSource="Digger" /> |
|||
</ExperimentalAcrylicBorder.Material> |
|||
</ExperimentalAcrylicBorder> |
|||
<ExperimentalAcrylicBorder> |
|||
<ExperimentalAcrylicBorder.Material> |
|||
<ExperimentalAcrylicMaterial BackgroundSource="Digger" |
|||
MaterialOpacity="{Binding #MaterialOpacitySlider.Value}" |
|||
TintColor="#0000FF" |
|||
TintOpacity="{Binding #TintOpacitySlider.Value}" /> |
|||
</ExperimentalAcrylicBorder.Material> |
|||
</ExperimentalAcrylicBorder> |
|||
|
|||
<ExperimentalAcrylicBorder Height="200" Width="200" CornerRadius="5"> |
|||
<ExperimentalAcrylicBorder.Material> |
|||
<ExperimentalAcrylicMaterial |
|||
TintColor="#FFFF00" |
|||
TintOpacity="{Binding #TintOpacitySlider.Value}" |
|||
MaterialOpacity="{Binding #MaterialOpacitySlider.Value}" |
|||
BackgroundSource="Digger" /> |
|||
</ExperimentalAcrylicBorder.Material> |
|||
</ExperimentalAcrylicBorder> |
|||
<ExperimentalAcrylicBorder> |
|||
<ExperimentalAcrylicBorder.Material> |
|||
<ExperimentalAcrylicMaterial BackgroundSource="Digger" |
|||
MaterialOpacity="{Binding #MaterialOpacitySlider.Value}" |
|||
TintColor="#FFFF00" |
|||
TintOpacity="{Binding #TintOpacitySlider.Value}" /> |
|||
</ExperimentalAcrylicBorder.Material> |
|||
</ExperimentalAcrylicBorder> |
|||
|
|||
<ExperimentalAcrylicBorder Height="200" Width="200" CornerRadius="5"> |
|||
<ExperimentalAcrylicBorder.Material> |
|||
<ExperimentalAcrylicMaterial |
|||
TintColor="#000000" |
|||
TintOpacity="{Binding #TintOpacitySlider.Value}" |
|||
MaterialOpacity="{Binding #MaterialOpacitySlider.Value}" |
|||
BackgroundSource="Digger" /> |
|||
</ExperimentalAcrylicBorder.Material> |
|||
</ExperimentalAcrylicBorder> |
|||
</StackPanel> |
|||
<ExperimentalAcrylicBorder> |
|||
<ExperimentalAcrylicBorder.Material> |
|||
<ExperimentalAcrylicMaterial BackgroundSource="Digger" |
|||
MaterialOpacity="{Binding #MaterialOpacitySlider.Value}" |
|||
TintColor="#000000" |
|||
TintOpacity="{Binding #TintOpacitySlider.Value}" /> |
|||
</ExperimentalAcrylicBorder.Material> |
|||
</ExperimentalAcrylicBorder> |
|||
|
|||
<StackPanel Orientation="Horizontal" Spacing="20"> |
|||
<ExperimentalAcrylicBorder Height="200" Width="200" CornerRadius="5"> |
|||
<ExperimentalAcrylicBorder.Material> |
|||
<ExperimentalAcrylicMaterial |
|||
TintColor="White" |
|||
TintOpacity="{Binding #TintOpacitySlider.Value}" |
|||
MaterialOpacity="{Binding #MaterialOpacitySlider.Value}" |
|||
BackgroundSource="Digger" /> |
|||
</ExperimentalAcrylicBorder.Material> |
|||
</ExperimentalAcrylicBorder> |
|||
|
|||
<ExperimentalAcrylicBorder Height="200" Width="200" CornerRadius="5"> |
|||
<ExperimentalAcrylicBorder.Material> |
|||
<ExperimentalAcrylicMaterial |
|||
TintColor="#3c3c3c" |
|||
TintOpacity="{Binding #TintOpacitySlider.Value}" |
|||
MaterialOpacity="{Binding #MaterialOpacitySlider.Value}" |
|||
BackgroundSource="Digger" /> |
|||
</ExperimentalAcrylicBorder.Material> |
|||
</ExperimentalAcrylicBorder> |
|||
<ExperimentalAcrylicBorder> |
|||
<ExperimentalAcrylicBorder.Material> |
|||
<ExperimentalAcrylicMaterial BackgroundSource="Digger" |
|||
MaterialOpacity="{Binding #MaterialOpacitySlider.Value}" |
|||
TintColor="White" |
|||
TintOpacity="{Binding #TintOpacitySlider.Value}" /> |
|||
</ExperimentalAcrylicBorder.Material> |
|||
</ExperimentalAcrylicBorder> |
|||
|
|||
<ExperimentalAcrylicBorder Height="200" Width="200" CornerRadius="5"> |
|||
<ExperimentalAcrylicBorder.Material> |
|||
<ExperimentalAcrylicMaterial |
|||
TintColor="White" |
|||
TintOpacity="{Binding #TintOpacitySlider.Value}" |
|||
MaterialOpacity="{Binding #MaterialOpacitySlider.Value}" |
|||
BackgroundSource="Digger" /> |
|||
</ExperimentalAcrylicBorder.Material> |
|||
</ExperimentalAcrylicBorder> |
|||
</StackPanel> |
|||
<ExperimentalAcrylicBorder> |
|||
<ExperimentalAcrylicBorder.Material> |
|||
<ExperimentalAcrylicMaterial BackgroundSource="Digger" |
|||
MaterialOpacity="{Binding #MaterialOpacitySlider.Value}" |
|||
TintColor="#3c3c3c" |
|||
TintOpacity="{Binding #TintOpacitySlider.Value}" /> |
|||
</ExperimentalAcrylicBorder.Material> |
|||
</ExperimentalAcrylicBorder> |
|||
|
|||
<ExperimentalAcrylicBorder Height="200" Width="660" CornerRadius="5"> |
|||
<ExperimentalAcrylicBorder> |
|||
<ExperimentalAcrylicBorder.Material> |
|||
<ExperimentalAcrylicMaterial |
|||
TintColor="Red" |
|||
TintOpacity="{Binding #TintOpacitySlider.Value}" |
|||
MaterialOpacity="{Binding #MaterialOpacitySlider.Value}" |
|||
BackgroundSource="Digger" /> |
|||
<ExperimentalAcrylicMaterial BackgroundSource="Digger" |
|||
MaterialOpacity="{Binding #MaterialOpacitySlider.Value}" |
|||
TintColor="White" |
|||
TintOpacity="{Binding #TintOpacitySlider.Value}" /> |
|||
</ExperimentalAcrylicBorder.Material> |
|||
</ExperimentalAcrylicBorder> |
|||
</StackPanel> |
|||
</Border> |
|||
|
|||
</UniformGrid> |
|||
|
|||
|
|||
<ExperimentalAcrylicBorder Width="{Binding #BordersGrid.Bounds.Width}" |
|||
Height="160"> |
|||
<ExperimentalAcrylicBorder.Material> |
|||
<ExperimentalAcrylicMaterial BackgroundSource="Digger" |
|||
MaterialOpacity="{Binding #MaterialOpacitySlider.Value}" |
|||
TintColor="Red" |
|||
TintOpacity="{Binding #TintOpacitySlider.Value}" /> |
|||
</ExperimentalAcrylicBorder.Material> |
|||
</ExperimentalAcrylicBorder> |
|||
</StackPanel> |
|||
|
|||
</UserControl> |
|||
|
|||
@ -1,73 +1,72 @@ |
|||
<UserControl xmlns="https://github.com/avaloniaui" |
|||
<UserControl x:Class="ControlCatalog.Pages.AutoCompleteBoxPage" |
|||
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" |
|||
xmlns:sys="clr-namespace:System;assembly=netstandard" |
|||
x:Class="ControlCatalog.Pages.AutoCompleteBoxPage"> |
|||
<StackPanel Orientation="Vertical" Spacing="4"> |
|||
<TextBlock Classes="h1">AutoCompleteBox</TextBlock> |
|||
d:DesignHeight="600" |
|||
d:DesignWidth="400"> |
|||
<StackPanel Orientation="Vertical" |
|||
Spacing="4" |
|||
MaxWidth="660"> |
|||
<TextBlock Classes="h2">A control into which the user can input text</TextBlock> |
|||
|
|||
<StackPanel Orientation="Horizontal" |
|||
Margin="0,16,0,0" |
|||
HorizontalAlignment="Center" |
|||
Spacing="8"> |
|||
<StackPanel Orientation="Vertical"> |
|||
<TextBlock Text="MinimumPrefixLength: 1"/> |
|||
<AutoCompleteBox Width="200" |
|||
Margin="0,0,0,8" |
|||
MinimumPrefixLength="1"/> |
|||
<TextBlock Text="MinimumPrefixLength: 3"/> |
|||
<AutoCompleteBox Width="200" |
|||
Margin="0,0,0,8" |
|||
MinimumPrefixLength="3"/> |
|||
<TextBlock Text="MinimumPopulateDelay: 1 Second"/> |
|||
<AutoCompleteBox Width="200" |
|||
Margin="0,0,0,8" |
|||
MinimumPopulateDelay="1"/> |
|||
<TextBlock Text="MaxDropDownHeight: 60"/> |
|||
<AutoCompleteBox Width="200" |
|||
Margin="0,0,0,8" |
|||
MaxDropDownHeight="60"/> |
|||
<AutoCompleteBox Width="200" |
|||
Margin="0,0,0,8" |
|||
Watermark="Watermark"/> |
|||
<TextBlock Text="Disabled"/> |
|||
<AutoCompleteBox Width="200" |
|||
IsEnabled="False"/> |
|||
<UniformGrid Margin="-8,0" |
|||
Columns="2"> |
|||
<UniformGrid.Styles> |
|||
<Style Selector="StackPanel"> |
|||
<Setter Property="Margin" Value="8" /> |
|||
</Style> |
|||
</UniformGrid.Styles> |
|||
<StackPanel> |
|||
<TextBlock Text="MinimumPrefixLength: 1" /> |
|||
<AutoCompleteBox MinimumPrefixLength="1" /> |
|||
</StackPanel> |
|||
<StackPanel> |
|||
<TextBlock Text="MinimumPrefixLength: 3" /> |
|||
<AutoCompleteBox MinimumPrefixLength="3" /> |
|||
</StackPanel> |
|||
<StackPanel> |
|||
<TextBlock Text="MinimumPopulateDelay: 1s" /> |
|||
<AutoCompleteBox MinimumPopulateDelay="1" /> |
|||
</StackPanel> |
|||
<StackPanel> |
|||
<TextBlock Text="MaxDropDownHeight: 60" /> |
|||
<AutoCompleteBox MaxDropDownHeight="60" /> |
|||
</StackPanel> |
|||
<StackPanel> |
|||
<TextBlock Text="Watermark" /> |
|||
<AutoCompleteBox Watermark="Hello World" /> |
|||
</StackPanel> |
|||
<StackPanel> |
|||
<TextBlock Text="Disabled" /> |
|||
<AutoCompleteBox IsEnabled="False" /> |
|||
</StackPanel> |
|||
|
|||
|
|||
<StackPanel Orientation="Vertical"> |
|||
|
|||
<TextBlock Text="ValueMemberBinding"/> |
|||
<AutoCompleteBox Width="200" |
|||
Margin="0,0,0,8" |
|||
ValueMemberBinding="{Binding Capital}"/> |
|||
<TextBlock Text="Multi-Binding"/> |
|||
<AutoCompleteBox Name="MultiBindingBox" |
|||
Width="200" |
|||
Margin="0,0,0,8" |
|||
FilterMode="Contains"/> |
|||
<TextBlock Text="Async Populate"/> |
|||
<AutoCompleteBox Name="AsyncBox" |
|||
Width="200" |
|||
Margin="0,0,0,8" |
|||
FilterMode="None"/> |
|||
<TextBlock Text="Custom Autocomplete"/> |
|||
<AutoCompleteBox Name="CustomAutocompleteBox" |
|||
Width="200" |
|||
Margin="0,0,0,8" |
|||
FilterMode="None"/> |
|||
|
|||
<TextBlock Text="With Validation Errors"/> |
|||
<AutoCompleteBox Name="ValidationErrors" |
|||
Width="200" |
|||
Margin="0,0,0,8" |
|||
FilterMode="None"> |
|||
<DataValidationErrors.Error> |
|||
<sys:Exception /> |
|||
</DataValidationErrors.Error> |
|||
</AutoCompleteBox> |
|||
<StackPanel> |
|||
<TextBlock Text="ValueMemberBinding" /> |
|||
<AutoCompleteBox ValueMemberBinding="{Binding Capital}" /> |
|||
</StackPanel> |
|||
<StackPanel> |
|||
<TextBlock Text="Multi-Binding" /> |
|||
<AutoCompleteBox Name="MultiBindingBox" FilterMode="Contains" /> |
|||
</StackPanel> |
|||
<StackPanel> |
|||
<TextBlock Text="Async Populate" /> |
|||
<AutoCompleteBox Name="AsyncBox" FilterMode="None" /> |
|||
</StackPanel> |
|||
<StackPanel> |
|||
<TextBlock Text="Custom Autocomplete" /> |
|||
<AutoCompleteBox Name="CustomAutocompleteBox" FilterMode="None" /> |
|||
</StackPanel> |
|||
</UniformGrid> |
|||
<StackPanel> |
|||
<TextBlock Text="With Validation Errors" /> |
|||
<AutoCompleteBox Name="ValidationErrors" FilterMode="None"> |
|||
<DataValidationErrors.Error> |
|||
<sys:Exception /> |
|||
</DataValidationErrors.Error> |
|||
</AutoCompleteBox> |
|||
</StackPanel> |
|||
</StackPanel> |
|||
</UserControl> |
|||
|
|||
@ -1,32 +1,45 @@ |
|||
<UserControl xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
x:Class="ControlCatalog.Pages.DragAndDropPage"> |
|||
<StackPanel Orientation="Vertical" Spacing="4"> |
|||
<TextBlock Classes="h1">Drag+Drop</TextBlock> |
|||
<TextBlock Classes="h2">Example of Drag+Drop capabilities</TextBlock> |
|||
<UserControl x:Class="ControlCatalog.Pages.DragAndDropPage" |
|||
xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
|||
<StackPanel Orientation="Vertical" Spacing="4"> |
|||
<TextBlock Classes="h2">Example of Drag+Drop capabilities</TextBlock> |
|||
|
|||
<StackPanel Orientation="Horizontal" |
|||
Margin="0,16,0,0" |
|||
HorizontalAlignment="Center" |
|||
Spacing="16"> |
|||
<StackPanel> |
|||
<Border BorderBrush="{DynamicResource SystemAccentColor}" BorderThickness="2" Padding="16" Name="DragMeText"> |
|||
<TextBlock Name="DragStateText">Drag Me</TextBlock> |
|||
</Border> |
|||
<Border BorderBrush="{DynamicResource SystemAccentColor}" BorderThickness="2" Padding="16" Name="DragMeCustom"> |
|||
<TextBlock Name="DragStateCustom">Drag Me (custom)</TextBlock> |
|||
</Border> |
|||
<TextBlock Name="DropState"></TextBlock> |
|||
</StackPanel> |
|||
<WrapPanel HorizontalAlignment="Center"> |
|||
<StackPanel Margin="8" |
|||
MaxWidth="160"> |
|||
<Border Name="DragMeText" |
|||
Padding="16" |
|||
BorderBrush="{DynamicResource SystemAccentColor}" |
|||
BorderThickness="2"> |
|||
<TextBlock Name="DragStateText" TextWrapping="Wrap">Drag Me</TextBlock> |
|||
</Border> |
|||
<Border Name="DragMeCustom" |
|||
Padding="16" |
|||
BorderBrush="{DynamicResource SystemAccentColor}" |
|||
BorderThickness="2"> |
|||
<TextBlock Name="DragStateCustom" TextWrapping="Wrap">Drag Me (custom)</TextBlock> |
|||
</Border> |
|||
<TextBlock Name="DropState" TextWrapping="Wrap" /> |
|||
</StackPanel> |
|||
|
|||
<Border Background="{DynamicResource SystemAccentColorDark1}" Padding="16" |
|||
DragDrop.AllowDrop="True" Name="CopyTarget"> |
|||
<TextBlock>Drop some text or files here (Copy)</TextBlock> |
|||
</Border> |
|||
<Border Background="{DynamicResource SystemAccentColorDark1}" Padding="16" |
|||
DragDrop.AllowDrop="True" Name="MoveTarget"> |
|||
<TextBlock>Drop some text or files here (Move)</TextBlock> |
|||
</Border> |
|||
</StackPanel> |
|||
</StackPanel> |
|||
<StackPanel Margin="8" |
|||
Orientation="Horizontal" |
|||
Spacing="16"> |
|||
<Border Name="CopyTarget" |
|||
Padding="16" |
|||
MaxWidth="260" |
|||
Background="{DynamicResource SystemAccentColorDark1}" |
|||
DragDrop.AllowDrop="True"> |
|||
<TextBlock TextWrapping="Wrap">Drop some text or files here (Copy)</TextBlock> |
|||
</Border> |
|||
<Border Name="MoveTarget" |
|||
Padding="16" |
|||
MaxWidth="260" |
|||
Background="{DynamicResource SystemAccentColorDark1}" |
|||
DragDrop.AllowDrop="True"> |
|||
<TextBlock TextWrapping="Wrap">Drop some text or files here (Move)</TextBlock> |
|||
</Border> |
|||
</StackPanel> |
|||
</WrapPanel> |
|||
</StackPanel> |
|||
</UserControl> |
|||
|
|||
@ -1,84 +0,0 @@ |
|||
<Styles xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
> |
|||
<Design.PreviewWith> |
|||
<Border Padding="20"> |
|||
<TabControl Classes="sidebar"> |
|||
<TabItem Header="Item1"/> |
|||
<TabItem Header="Item2"/> |
|||
</TabControl> |
|||
</Border> |
|||
</Design.PreviewWith> |
|||
<Style Selector="TabControl.sidebar"> |
|||
<Setter Property="TabStripPlacement" Value="Left"/> |
|||
<Setter Property="Padding" Value="8 0 0 0"/> |
|||
<Setter Property="Background" Value="{DynamicResource SystemAccentColor}"/> |
|||
<Setter Property="Template"> |
|||
<ControlTemplate> |
|||
<Border |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
BorderThickness="{TemplateBinding BorderThickness}"> |
|||
<DockPanel> |
|||
<ScrollViewer |
|||
Name="PART_ScrollViewer" |
|||
HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}" |
|||
VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}" |
|||
Background="{TemplateBinding Background}" |
|||
DockPanel.Dock="Left"> |
|||
<ItemsPresenter |
|||
Name="PART_ItemsPresenter" |
|||
Items="{TemplateBinding Items}" |
|||
ItemsPanel="{TemplateBinding ItemsPanel}" |
|||
ItemTemplate="{TemplateBinding ItemTemplate}"> |
|||
</ItemsPresenter> |
|||
</ScrollViewer> |
|||
<ContentControl Content="{TemplateBinding Tag}" HorizontalContentAlignment="Right" DockPanel.Dock="Bottom"/> |
|||
<ScrollViewer |
|||
HorizontalScrollBarVisibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SelectedItem.(ScrollViewer.HorizontalScrollBarVisibility)}" |
|||
VerticalScrollBarVisibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SelectedItem.(ScrollViewer.VerticalScrollBarVisibility)}"> |
|||
<ContentPresenter |
|||
Name="PART_SelectedContentHost" |
|||
Margin="{TemplateBinding Padding}" |
|||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" |
|||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" |
|||
Content="{TemplateBinding SelectedContent}" |
|||
ContentTemplate="{TemplateBinding SelectedContentTemplate}"> |
|||
</ContentPresenter> |
|||
</ScrollViewer> |
|||
</DockPanel> |
|||
</Border> |
|||
</ControlTemplate> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style Selector="TabControl.sidebar > TabItem"> |
|||
<Setter Property="BorderThickness" Value="0"/> |
|||
<Setter Property="Foreground" Value="White"/> |
|||
<Setter Property="FontSize" Value="14"/> |
|||
<Setter Property="Margin" Value="0"/> |
|||
<Setter Property="Padding" Value="16"/> |
|||
<Setter Property="Opacity" Value="0.5"/> |
|||
<Setter Property="Transitions"> |
|||
<Transitions> |
|||
<DoubleTransition Property="Opacity" Duration="0:0:0.150"/> |
|||
</Transitions> |
|||
</Setter> |
|||
<Setter Property="(ScrollViewer.HorizontalScrollBarVisibility)" Value="Auto"/> |
|||
<Setter Property="(ScrollViewer.VerticalScrollBarVisibility)" Value="Auto"/> |
|||
</Style> |
|||
<Style Selector="TabControl.sidebar > TabItem:selected /template/ Border#PART_SelectedPipe"> |
|||
<Setter Property="IsVisible" Value="False" /> |
|||
</Style> |
|||
<Style Selector="TabControl.sidebar > TabItem:pointerover"> |
|||
<Setter Property="Opacity" Value="1"/> |
|||
</Style> |
|||
<Style Selector="TabControl.sidebar > TabItem:pointerover"> |
|||
<Setter Property="Background" Value="{DynamicResource SystemAccentColorLight2}"/> |
|||
</Style> |
|||
<Style Selector="TabControl.sidebar > TabItem:selected"> |
|||
<Setter Property="Opacity" Value="1"/> |
|||
</Style> |
|||
<Style Selector="TabControl.sidebar > TabItem:selected"> |
|||
<Setter Property="Background" Value="{DynamicResource SystemAccentColorLight1}"/> |
|||
</Style> |
|||
</Styles> |
|||
@ -1,9 +1,8 @@ |
|||
<Application |
|||
xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
x:Class="RenderDemo.App"> |
|||
<Application.Styles> |
|||
<FluentTheme/> |
|||
<StyleInclude Source="avares://RenderDemo/SideBar.xaml"/> |
|||
</Application.Styles> |
|||
<Application x:Class="RenderDemo.App" |
|||
xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
|||
<Application.Styles> |
|||
<FluentTheme /> |
|||
<StyleInclude Source="avares://ControlSamples/HamburgerMenu/HamburgerMenu.xaml" /> |
|||
</Application.Styles> |
|||
</Application> |
|||
|
|||
@ -1,68 +1,67 @@ |
|||
<Window xmlns="https://github.com/avaloniaui" |
|||
<Window x:Class="RenderDemo.MainWindow" |
|||
xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
x:Class="RenderDemo.MainWindow" |
|||
Title="AvaloniaUI Rendering Test" |
|||
xmlns:controls="clr-namespace:ControlSamples;assembly=ControlSamples" |
|||
xmlns:pages="clr-namespace:RenderDemo.Pages" |
|||
Title="AvaloniaUI Rendering Test" |
|||
Width="{Binding Width, Mode=TwoWay}" |
|||
Height="{Binding Height, Mode=TwoWay}"> |
|||
<DockPanel> |
|||
<Menu DockPanel.Dock="Top"> |
|||
<MenuItem Header="Rendering"> |
|||
<MenuItem Header="Draw Dirty Rects" Command="{Binding ToggleDrawDirtyRects}"> |
|||
<MenuItem.Icon> |
|||
<CheckBox BorderThickness="0" |
|||
IsHitTestVisible="False" |
|||
IsChecked="{Binding DrawDirtyRects}"/> |
|||
</MenuItem.Icon> |
|||
<controls:HamburgerMenu ExpandedModeThresholdWidth="760"> |
|||
<FlyoutBase.AttachedFlyout> |
|||
<MenuFlyout> |
|||
<MenuItem Header="Rendering"> |
|||
<MenuItem Command="{Binding ToggleDrawDirtyRects}" Header="Draw Dirty Rects"> |
|||
<MenuItem.Icon> |
|||
<CheckBox BorderThickness="0" |
|||
IsChecked="{Binding DrawDirtyRects}" |
|||
IsHitTestVisible="False" /> |
|||
</MenuItem.Icon> |
|||
</MenuItem> |
|||
<MenuItem Command="{Binding ToggleDrawFps}" Header="Draw FPS"> |
|||
<MenuItem.Icon> |
|||
<CheckBox BorderThickness="0" |
|||
IsChecked="{Binding DrawFps}" |
|||
IsHitTestVisible="False" /> |
|||
</MenuItem.Icon> |
|||
</MenuItem> |
|||
</MenuItem> |
|||
<MenuItem Header="Draw FPS" |
|||
Command="{Binding ToggleDrawFps}"> |
|||
<MenuItem.Icon> |
|||
<CheckBox BorderThickness="0" |
|||
IsHitTestVisible="False" |
|||
IsChecked="{Binding DrawFps}"/> |
|||
</MenuItem.Icon> |
|||
<MenuItem Header="Tests"> |
|||
<MenuItem Command="{Binding ResizeWindow}" Header="Resize window" /> |
|||
</MenuItem> |
|||
</MenuItem> |
|||
<MenuItem Header="Tests"> |
|||
<MenuItem Header="Resize window" |
|||
Command="{Binding ResizeWindow}"/> |
|||
</MenuItem> |
|||
</Menu> |
|||
<TabControl Classes="sidebar"> |
|||
<TabItem Header="Animations"> |
|||
<pages:AnimationsPage/> |
|||
</TabItem> |
|||
<TabItem Header="Transitions"> |
|||
<pages:TransitionsPage/> |
|||
</TabItem> |
|||
<TabItem Header="Custom Animator"> |
|||
<pages:CustomAnimatorPage/> |
|||
</TabItem> |
|||
<TabItem Header="Clipping"> |
|||
<pages:ClippingPage/> |
|||
</TabItem> |
|||
<TabItem Header="Drawing"> |
|||
<pages:DrawingPage/> |
|||
</TabItem> |
|||
<TabItem Header="SkCanvas"> |
|||
<pages:CustomSkiaPage/> |
|||
</TabItem> |
|||
<TabItem Header="RenderTargetBitmap"> |
|||
<pages:RenderTargetBitmapPage/> |
|||
</TabItem> |
|||
<TabItem Header="WriteableBitmap"> |
|||
<pages:WriteableBitmapPage/> |
|||
</TabItem> |
|||
<TabItem Header="GlyphRun"> |
|||
<pages:GlyphRunPage/> |
|||
</TabItem> |
|||
<TabItem Header="LineBounds"> |
|||
<pages:LineBoundsPage /> |
|||
</TabItem> |
|||
<TabItem Header="Path Measurement"> |
|||
<pages:PathMeasurementPage /> |
|||
</TabItem> |
|||
</TabControl> |
|||
</DockPanel> |
|||
</MenuFlyout> |
|||
</FlyoutBase.AttachedFlyout> |
|||
<TabItem Header="Animations"> |
|||
<pages:AnimationsPage /> |
|||
</TabItem> |
|||
<TabItem Header="Transitions"> |
|||
<pages:TransitionsPage /> |
|||
</TabItem> |
|||
<TabItem Header="Custom Animator"> |
|||
<pages:CustomAnimatorPage /> |
|||
</TabItem> |
|||
<TabItem Header="Clipping"> |
|||
<pages:ClippingPage /> |
|||
</TabItem> |
|||
<TabItem Header="Drawing"> |
|||
<pages:DrawingPage /> |
|||
</TabItem> |
|||
<TabItem Header="SkCanvas"> |
|||
<pages:CustomSkiaPage /> |
|||
</TabItem> |
|||
<TabItem Header="RenderTargetBitmap"> |
|||
<pages:RenderTargetBitmapPage /> |
|||
</TabItem> |
|||
<TabItem Header="WriteableBitmap"> |
|||
<pages:WriteableBitmapPage /> |
|||
</TabItem> |
|||
<TabItem Header="GlyphRun"> |
|||
<pages:GlyphRunPage /> |
|||
</TabItem> |
|||
<TabItem Header="LineBounds"> |
|||
<pages:LineBoundsPage /> |
|||
</TabItem> |
|||
<TabItem Header="Path Measurement"> |
|||
<pages:PathMeasurementPage /> |
|||
</TabItem> |
|||
</controls:HamburgerMenu> |
|||
</Window> |
|||
|
|||
@ -1,67 +0,0 @@ |
|||
<Styles xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
|||
<Style Selector="TabControl.sidebar"> |
|||
<Setter Property="TabStripPlacement" Value="Left"/> |
|||
<Setter Property="Padding" Value="8 0 0 0"/> |
|||
<Setter Property="Background" Value="{DynamicResource SystemAccentColor}"/> |
|||
<Setter Property="Template"> |
|||
<ControlTemplate> |
|||
<Border |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
BorderThickness="{TemplateBinding BorderThickness}"> |
|||
<DockPanel> |
|||
<ScrollViewer |
|||
Name="PART_ScrollViewer" |
|||
HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}" |
|||
VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}" |
|||
Background="{TemplateBinding Background}"> |
|||
<ItemsPresenter |
|||
Name="PART_ItemsPresenter" |
|||
Items="{TemplateBinding Items}" |
|||
ItemsPanel="{TemplateBinding ItemsPanel}" |
|||
ItemTemplate="{TemplateBinding ItemTemplate}"> |
|||
</ItemsPresenter> |
|||
</ScrollViewer> |
|||
<ContentPresenter |
|||
Name="PART_SelectedContentHost" |
|||
Margin="{TemplateBinding Padding}" |
|||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" |
|||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" |
|||
Content="{TemplateBinding SelectedContent}" |
|||
ContentTemplate="{TemplateBinding SelectedContentTemplate}"> |
|||
</ContentPresenter> |
|||
</DockPanel> |
|||
</Border> |
|||
</ControlTemplate> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style Selector="TabControl.sidebar > TabItem"> |
|||
<Setter Property="BorderThickness" Value="0"/> |
|||
<Setter Property="Foreground" Value="White"/> |
|||
<Setter Property="FontSize" Value="14"/> |
|||
<Setter Property="Margin" Value="0"/> |
|||
<Setter Property="Padding" Value="16"/> |
|||
<Setter Property="Opacity" Value="0.5"/> |
|||
<Setter Property="Transitions"> |
|||
<Transitions> |
|||
<DoubleTransition Property="Opacity" Duration="0:0:0.150"/> |
|||
</Transitions> |
|||
</Setter> |
|||
</Style> |
|||
<Style Selector="TabControl.sidebar > TabItem:selected /template/ Border#PART_SelectedPipe"> |
|||
<Setter Property="IsVisible" Value="False" /> |
|||
</Style> |
|||
<Style Selector="TabControl.sidebar > TabItem:pointerover"> |
|||
<Setter Property="Opacity" Value="1"/> |
|||
</Style> |
|||
<Style Selector="TabControl.sidebar > TabItem:pointerover /template/ Border#PART_LayoutRoot"> |
|||
<Setter Property="Background" Value="{DynamicResource SystemAccentColorLight2}"/> |
|||
</Style> |
|||
<Style Selector="TabControl.sidebar > TabItem:selected"> |
|||
<Setter Property="Opacity" Value="1"/> |
|||
</Style> |
|||
<Style Selector="TabControl.sidebar > TabItem:selected /template/ Border#PART_LayoutRoot"> |
|||
<Setter Property="Background" Value="{DynamicResource SystemAccentColorLight1}"/> |
|||
</Style> |
|||
</Styles> |
|||
@ -0,0 +1,23 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<Nullable>enable</Nullable> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<Compile Update="**\*.xaml.cs"> |
|||
<DependentUpon>%(Filename)</DependentUpon> |
|||
</Compile> |
|||
<AvaloniaResource Include="**\*.xaml"> |
|||
<SubType>Designer</SubType> |
|||
</AvaloniaResource> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\packages\Avalonia\Avalonia.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<Import Project="..\..\build\BuildTargets.targets" /> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,77 @@ |
|||
using Avalonia; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Controls.Primitives; |
|||
using Avalonia.Media; |
|||
|
|||
namespace ControlSamples |
|||
{ |
|||
public class HamburgerMenu : TabControl |
|||
{ |
|||
private SplitView? _splitView; |
|||
|
|||
public static readonly StyledProperty<IBrush?> PaneBackgroundProperty = |
|||
SplitView.PaneBackgroundProperty.AddOwner<HamburgerMenu>(); |
|||
|
|||
public IBrush? PaneBackground |
|||
{ |
|||
get => GetValue(PaneBackgroundProperty); |
|||
set => SetValue(PaneBackgroundProperty, value); |
|||
} |
|||
|
|||
public static readonly StyledProperty<IBrush?> ContentBackgroundProperty = |
|||
AvaloniaProperty.Register<HamburgerMenu, IBrush?>(nameof(ContentBackground)); |
|||
|
|||
public IBrush? ContentBackground |
|||
{ |
|||
get => GetValue(ContentBackgroundProperty); |
|||
set => SetValue(ContentBackgroundProperty, value); |
|||
} |
|||
|
|||
public static readonly StyledProperty<int> ExpandedModeThresholdWidthProperty = |
|||
AvaloniaProperty.Register<HamburgerMenu, int>(nameof(ExpandedModeThresholdWidth), 1008); |
|||
|
|||
public int ExpandedModeThresholdWidth |
|||
{ |
|||
get => GetValue(ExpandedModeThresholdWidthProperty); |
|||
set => SetValue(ExpandedModeThresholdWidthProperty, value); |
|||
} |
|||
|
|||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e) |
|||
{ |
|||
base.OnApplyTemplate(e); |
|||
|
|||
_splitView = e.NameScope.Find<SplitView>("PART_NavigationPane"); |
|||
} |
|||
|
|||
protected override void OnPropertyChanged<T>(AvaloniaPropertyChangedEventArgs<T> change) |
|||
{ |
|||
base.OnPropertyChanged(change); |
|||
|
|||
if (change.Property == BoundsProperty && _splitView is not null) |
|||
{ |
|||
var oldBounds = change.OldValue.GetValueOrDefault<Rect>(); |
|||
var newBounds = change.NewValue.GetValueOrDefault<Rect>(); |
|||
EnsureSplitViewMode(oldBounds, newBounds); |
|||
} |
|||
} |
|||
|
|||
private void EnsureSplitViewMode(Rect oldBounds, Rect newBounds) |
|||
{ |
|||
if (_splitView is not null) |
|||
{ |
|||
var threshold = ExpandedModeThresholdWidth; |
|||
|
|||
if (newBounds.Width >= threshold && oldBounds.Width < threshold) |
|||
{ |
|||
_splitView.DisplayMode = SplitViewDisplayMode.Inline; |
|||
_splitView.IsPaneOpen = true; |
|||
} |
|||
else if (newBounds.Width < threshold && oldBounds.Width >= threshold) |
|||
{ |
|||
_splitView.DisplayMode = SplitViewDisplayMode.Overlay; |
|||
_splitView.IsPaneOpen = false; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,242 @@ |
|||
<Styles xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:catalog="using:ControlSamples"> |
|||
<Design.PreviewWith> |
|||
<Border Width="400" |
|||
Height="150"> |
|||
<catalog:HamburgerMenu> |
|||
<FlyoutBase.AttachedFlyout> |
|||
<Flyout> |
|||
<TextBox Text="Hello World" /> |
|||
</Flyout> |
|||
</FlyoutBase.AttachedFlyout> |
|||
<TabItem Header="Item1" IsSelected="True"> |
|||
<UserControl> |
|||
<Border Height="400" Background="Green" /> |
|||
</UserControl> |
|||
</TabItem> |
|||
<TabItem Header="Item2" /> |
|||
</catalog:HamburgerMenu> |
|||
</Border> |
|||
</Design.PreviewWith> |
|||
|
|||
<Styles.Resources> |
|||
<x:Double x:Key="PaneCompactWidth">40</x:Double> |
|||
<x:Double x:Key="PaneExpandWidth">200</x:Double> |
|||
<x:Double x:Key="HeaderHeight">36</x:Double> |
|||
<x:Double x:Key="NavigationItemHeight">36</x:Double> |
|||
<x:Double x:Key="HamburgerMenuButtonHeight">32</x:Double> |
|||
<Thickness x:Key="HeaderMarginCollapsedPane">12,0,0,0</Thickness> |
|||
<Thickness x:Key="HeaderMarginExpandedPane">52,0,0,0</Thickness> |
|||
<Thickness x:Key="HeaderMarginExpandedOverlayPane">212,0,0,0</Thickness> |
|||
<BoxShadows x:Key="NavigationItemShadow">1 1 1 1 #2000, 0 0 1 1 #2fff</BoxShadows> |
|||
<BoxShadows x:Key="NavigationContentShadow">0 0 1 1 #2000</BoxShadows> |
|||
</Styles.Resources> |
|||
|
|||
<!-- HamburgerMenu --> |
|||
<Style Selector="catalog|HamburgerMenu"> |
|||
<Setter Property="Padding" Value="12 8 4 0" /> |
|||
<Setter Property="PaneBackground" Value="{DynamicResource SystemChromeMediumColor}" /> |
|||
<Setter Property="Background" Value="{DynamicResource SystemChromeMediumColor}" /> |
|||
<Setter Property="ContentBackground" Value="{DynamicResource SystemAltHighColor}" /> |
|||
<Setter Property="Template"> |
|||
<ControlTemplate> |
|||
<Panel Background="{TemplateBinding PaneBackground}"> |
|||
<SplitView x:Name="PART_NavigationPane" |
|||
CompactPaneLength="{StaticResource PaneCompactWidth}" |
|||
DisplayMode="Inline" |
|||
IsPaneOpen="True" |
|||
OpenPaneLength="{StaticResource PaneExpandWidth}"> |
|||
<SplitView.Pane> |
|||
<Grid Margin="0,0,1,5" RowDefinitions="Auto, *, Auto"> |
|||
<Panel Height="{StaticResource HeaderHeight}" /> |
|||
<ScrollViewer x:Name="PART_ScrollViewer" |
|||
Grid.Row="1" |
|||
HorizontalAlignment="Stretch" |
|||
HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}" |
|||
VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}"> |
|||
<ItemsPresenter Name="PART_ItemsPresenter" |
|||
HorizontalAlignment="Stretch" |
|||
ItemTemplate="{TemplateBinding ItemTemplate}" |
|||
Items="{TemplateBinding Items}" |
|||
ItemsPanel="{TemplateBinding ItemsPanel}"> |
|||
<ItemsPresenter.ItemsPanel> |
|||
<ItemsPanelTemplate> |
|||
<StackPanel x:Name="HamburgerItemsPanel" |
|||
Margin="0,2" Orientation="Vertical" /> |
|||
</ItemsPanelTemplate> |
|||
</ItemsPresenter.ItemsPanel> |
|||
</ItemsPresenter> |
|||
</ScrollViewer> |
|||
<Button x:Name="SettingsButton" |
|||
Grid.Row="2" |
|||
Classes="NavigationButton" |
|||
Content="Settings" |
|||
Flyout="{TemplateBinding (FlyoutBase.AttachedFlyout)}" |
|||
IsVisible="{Binding $parent[TabControl].(FlyoutBase.AttachedFlyout), Converter={x:Static ObjectConverters.IsNotNull}}" /> |
|||
</Grid> |
|||
</SplitView.Pane> |
|||
<SplitView.Content> |
|||
<DockPanel> |
|||
<Border Height="{StaticResource HeaderHeight}" DockPanel.Dock="Top"> |
|||
<TextBlock x:Name="HeaderHolder" |
|||
VerticalAlignment="Center" |
|||
Classes="h1" |
|||
Text="{Binding $parent[TabControl].SelectedItem.Header, FallbackValue=''}"> |
|||
<TextBlock.Transitions> |
|||
<Transitions> |
|||
<ThicknessTransition Easing="{StaticResource SplitViewPaneAnimationEasing}" |
|||
Property="Margin" |
|||
Duration="{StaticResource SplitViewPaneAnimationCloseDuration}" /> |
|||
</Transitions> |
|||
</TextBlock.Transitions> |
|||
</TextBlock> |
|||
</Border> |
|||
<Border x:Name="BackgroundBorder"> |
|||
<Border.Transitions> |
|||
<Transitions> |
|||
<CornerRadiusTransition Property="CornerRadius" Duration="{StaticResource SplitViewPaneAnimationCloseDuration}" /> |
|||
</Transitions> |
|||
</Border.Transitions> |
|||
<ScrollViewer x:Name="HamburgerContentScroller" |
|||
HorizontalScrollBarVisibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SelectedItem.(ScrollViewer.HorizontalScrollBarVisibility)}" |
|||
VerticalScrollBarVisibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SelectedItem.(ScrollViewer.VerticalScrollBarVisibility)}"> |
|||
<ContentPresenter Name="PART_SelectedContentHost" |
|||
Background="Transparent" |
|||
Padding="{TemplateBinding Padding}" |
|||
Content="{TemplateBinding SelectedContent}" |
|||
ContentTemplate="{TemplateBinding SelectedContentTemplate}" /> |
|||
</ScrollViewer> |
|||
</Border> |
|||
</DockPanel> |
|||
</SplitView.Content> |
|||
</SplitView> |
|||
<ToggleButton x:Name="HamburgerMenuButton" |
|||
Width="{StaticResource PaneCompactWidth}" |
|||
Height="{StaticResource HamburgerMenuButtonHeight}" |
|||
Margin="4,2,0,0" |
|||
Padding="0" |
|||
HorizontalAlignment="Left" |
|||
VerticalAlignment="Top" |
|||
HorizontalContentAlignment="Center" |
|||
Classes="NavigationButton" |
|||
CornerRadius="4" |
|||
IsChecked="{Binding #PART_NavigationPane.IsPaneOpen, Mode=TwoWay}"> |
|||
<PathIcon Data="M3 17h18a1 1 0 0 1 .117 1.993L21 19H3a1 1 0 0 1-.117-1.993L3 17h18H3Zm0-6 18-.002a1 1 0 0 1 .117 1.993l-.117.007L3 13a1 1 0 0 1-.117-1.993L3 11l18-.002L3 11Zm0-6h18a1 1 0 0 1 .117 1.993L21 7H3a1 1 0 0 1-.117-1.993L3 5h18H3Z" Foreground="{TemplateBinding Foreground}" /> |
|||
</ToggleButton> |
|||
</Panel> |
|||
</ControlTemplate> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style Selector="catalog|HamburgerMenu /template/ SplitView TextBlock#HeaderHolder"> |
|||
<Setter Property="Margin" Value="{StaticResource HeaderMarginExpandedPane}" /> |
|||
</Style> |
|||
<Style Selector="catalog|HamburgerMenu /template/ SplitView[IsPaneOpen=True] TextBlock#HeaderHolder"> |
|||
<Setter Property="Margin" Value="{StaticResource HeaderMarginCollapsedPane}" /> |
|||
</Style> |
|||
<Style Selector="catalog|HamburgerMenu /template/ SplitView[DisplayMode=Overlay][IsPaneOpen=True] TextBlock#HeaderHolder"> |
|||
<Setter Property="Margin" Value="{StaticResource HeaderMarginExpandedOverlayPane}" /> |
|||
</Style> |
|||
<Style Selector="catalog|HamburgerMenu /template/ SplitView"> |
|||
<Setter Property="PaneBackground" Value="Transparent" /> |
|||
</Style> |
|||
<Style Selector="catalog|HamburgerMenu /template/ SplitView[DisplayMode=Overlay]"> |
|||
<Setter Property="PaneBackground" Value="{TemplateBinding PaneBackground}" /> |
|||
</Style> |
|||
<Style Selector="catalog|HamburgerMenu /template/ SplitView[DisplayMode=Overlay]"> |
|||
<Setter Property="Background" Value="{Binding $parent[TabControl].ContentBackground}" /> |
|||
</Style> |
|||
<Style Selector="catalog|HamburgerMenu /template/ SplitView[DisplayMode=Inline] Border#BackgroundBorder"> |
|||
<Setter Property="Background" Value="{Binding $parent[TabControl].ContentBackground}" /> |
|||
<Setter Property="BoxShadow" Value="{StaticResource NavigationContentShadow}" /> |
|||
</Style> |
|||
<Style Selector="catalog|HamburgerMenu /template/ SplitView[DisplayMode=Inline][IsPaneOpen=True] Border#BackgroundBorder"> |
|||
<Setter Property="CornerRadius" Value="8 0 0 0" /> |
|||
</Style> |
|||
|
|||
|
|||
<!-- HamburgerMenu TabItem --> |
|||
<Style Selector="catalog|HamburgerMenu > TabItem, :is(Button).NavigationButton"> |
|||
<Setter Property="HorizontalContentAlignment" Value="Stretch" /> |
|||
<Setter Property="VerticalContentAlignment" Value="Center" /> |
|||
<Setter Property="HorizontalAlignment" Value="Stretch" /> |
|||
<Setter Property="VerticalAlignment" Value="Stretch" /> |
|||
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" /> |
|||
<Setter Property="FontWeight" Value="Normal" /> |
|||
<Setter Property="MinHeight" Value="0" /> |
|||
<Setter Property="Height" Value="{StaticResource NavigationItemHeight}" /> |
|||
<Setter Property="Background" Value="Transparent" /> |
|||
<Setter Property="Padding" Value="12,0,4,0" /> |
|||
<Setter Property="Margin" Value="4,0,8,0" /> |
|||
<Setter Property="CornerRadius" Value="8" /> |
|||
<Setter Property="ClipToBounds" Value="False" /> |
|||
</Style> |
|||
<Style Selector="catalog|HamburgerMenu > TabItem"> |
|||
<Setter Property="Template"> |
|||
<ControlTemplate> |
|||
<Border Name="PART_LayoutRoot" |
|||
HorizontalAlignment="{TemplateBinding HorizontalAlignment}" |
|||
Background="{TemplateBinding Background}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
BorderThickness="{TemplateBinding BorderThickness}" |
|||
CornerRadius="{TemplateBinding CornerRadius}"> |
|||
<Panel> |
|||
<Border Name="PART_SelectedPipe" |
|||
Width="{DynamicResource TabItemPipeThickness}" |
|||
Height="{DynamicResource TabItemVerticalPipeHeight}" |
|||
Margin="6,0,0,0" |
|||
HorizontalAlignment="Left" |
|||
VerticalAlignment="Center" |
|||
Background="{DynamicResource TabItemHeaderSelectedPipeFill}" /> |
|||
<ContentPresenter Name="PART_ContentPresenter" |
|||
Padding="{TemplateBinding Padding}" |
|||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" |
|||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" |
|||
Content="{TemplateBinding Header}" |
|||
ContentTemplate="{TemplateBinding HeaderTemplate}" |
|||
TextBlock.FontFamily="{TemplateBinding FontFamily}" |
|||
TextBlock.FontSize="{TemplateBinding FontSize}" |
|||
TextBlock.FontWeight="{TemplateBinding FontWeight}" /> |
|||
</Panel> |
|||
</Border> |
|||
</ControlTemplate> |
|||
</Setter> |
|||
</Style> |
|||
<Style Selector=":is(Button).NavigationButton"> |
|||
<Setter Property="Template"> |
|||
<ControlTemplate> |
|||
<ContentPresenter Name="PART_ContentPresenter" |
|||
Padding="{TemplateBinding Padding}" |
|||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" |
|||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" |
|||
Background="{TemplateBinding Background}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
BorderThickness="{TemplateBinding BorderThickness}" |
|||
Content="{TemplateBinding Content}" |
|||
ContentTemplate="{TemplateBinding ContentTemplate}" |
|||
CornerRadius="{TemplateBinding CornerRadius}" |
|||
TextBlock.FontFamily="{TemplateBinding FontFamily}" |
|||
TextBlock.FontSize="{TemplateBinding FontSize}" |
|||
TextBlock.FontWeight="{TemplateBinding FontWeight}" /> |
|||
</ControlTemplate> |
|||
</Setter> |
|||
</Style> |
|||
<Style Selector="catalog|HamburgerMenu > TabItem /template/ Border#PART_LayoutRoot, :is(Button).NavigationButton /template/ ContentPresenter"> |
|||
<Setter Property="Border.Background" Value="Transparent" /> |
|||
<Setter Property="TextBlock.Foreground" Value="{DynamicResource SystemBaseHighColor}" /> |
|||
</Style> |
|||
<Style Selector="catalog|HamburgerMenu > TabItem:pointerover /template/ Border#PART_LayoutRoot, :is(Button).NavigationButton:pointerover /template/ ContentPresenter"> |
|||
<Setter Property="Border.Background" Value="{DynamicResource SystemChromeLowColor}" /> |
|||
<Setter Property="Border.BoxShadow" Value="{StaticResource NavigationItemShadow}" /> |
|||
<Setter Property="TextBlock.Foreground" Value="{DynamicResource TabItemHeaderForegroundUnselectedPointerOver}" /> |
|||
</Style> |
|||
<Style Selector="catalog|HamburgerMenu > TabItem:pressed /template/ Border#PART_LayoutRoot, :is(Button).NavigationButton:pressed /template/ ContentPresenter"> |
|||
<Setter Property="Border.Background" Value="{DynamicResource SystemChromeLowColor}" /> |
|||
<Setter Property="Border.BoxShadow" Value="{StaticResource NavigationItemShadow}" /> |
|||
<Setter Property="TextBlock.Foreground" Value="{DynamicResource TabItemHeaderForegroundUnselectedPressed}" /> |
|||
</Style> |
|||
<Style Selector=":is(Button).NavigationButton:pressed"> |
|||
<Setter Property="RenderTransform" Value="none" /> |
|||
</Style> |
|||
</Styles> |
|||
@ -0,0 +1,12 @@ |
|||
namespace Avalonia.Controls.Platform |
|||
{ |
|||
/// <summary>
|
|||
/// Native Menu Default Application Commands
|
|||
/// </summary>
|
|||
public interface INativeApplicationCommands |
|||
{ |
|||
void HideApp(); |
|||
void ShowAll(); |
|||
void HideOthers(); |
|||
} |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
namespace Avalonia.Input |
|||
{ |
|||
public class InputMethod |
|||
{ |
|||
/// <summary>
|
|||
/// A dependency property that enables alternative text inputs.
|
|||
/// </summary>
|
|||
public static readonly AvaloniaProperty<bool> IsInputMethodEnabledProperty = |
|||
AvaloniaProperty.RegisterAttached<InputMethod, InputElement, bool>("IsInputMethodEnabled", true); |
|||
|
|||
/// <summary>
|
|||
/// Setter for IsInputMethodEnabled AvaloniaProperty
|
|||
/// </summary>
|
|||
public static void SetIsInputMethodEnabled(InputElement target, bool value) |
|||
{ |
|||
target.SetValue(IsInputMethodEnabledProperty, value); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Getter for IsInputMethodEnabled AvaloniaProperty
|
|||
/// </summary>
|
|||
public static bool GetIsInputMethodEnabled(InputElement target) |
|||
{ |
|||
return target.GetValue<bool>(IsInputMethodEnabledProperty); |
|||
} |
|||
|
|||
private InputMethod() |
|||
{ |
|||
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
using Avalonia.Controls; |
|||
using Avalonia.Controls.Platform; |
|||
using Avalonia.Native.Interop; |
|||
|
|||
namespace Avalonia.Native |
|||
{ |
|||
internal class MacOSNativeMenuCommands : INativeApplicationCommands |
|||
{ |
|||
private readonly IAvnApplicationCommands _commands; |
|||
|
|||
public MacOSNativeMenuCommands(IAvnApplicationCommands commands) |
|||
{ |
|||
_commands = commands; |
|||
} |
|||
|
|||
public void HideApp() |
|||
{ |
|||
_commands.HideApp(); |
|||
} |
|||
|
|||
public void ShowAll() |
|||
{ |
|||
_commands.ShowAll(); |
|||
} |
|||
|
|||
public void HideOthers() |
|||
{ |
|||
_commands.HideOthers(); |
|||
} |
|||
|
|||
|
|||
public static readonly AttachedProperty<bool> IsServicesSubmenuProperty = |
|||
AvaloniaProperty.RegisterAttached<MacOSNativeMenuCommands, NativeMenu, bool>("IsServicesSubmenu", false); |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
namespace Avalonia.Media |
|||
{ |
|||
/// <summary>
|
|||
/// Font fallback definition that is used to override the default fallback lookup of the current <see cref="FontManager"/>
|
|||
/// </summary>
|
|||
public class FontFallback |
|||
{ |
|||
/// <summary>
|
|||
/// Get or set the fallback <see cref="FontFamily"/>
|
|||
/// </summary>
|
|||
public FontFamily FontFamily { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Get or set the <see cref="UnicodeRange"/> that is covered by the fallback.
|
|||
/// </summary>
|
|||
public UnicodeRange UnicodeRange { get; set; } = UnicodeRange.Default; |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Avalonia.Media |
|||
{ |
|||
public class FontManagerOptions |
|||
{ |
|||
public string DefaultFamilyName { get; set; } |
|||
|
|||
public IReadOnlyList<FontFallback> FontFallbacks { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,199 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text.RegularExpressions; |
|||
|
|||
namespace Avalonia.Media |
|||
{ |
|||
/// <summary>
|
|||
/// The <see cref="UnicodeRange"/> descripes a set of Unicode characters.
|
|||
/// </summary>
|
|||
public readonly struct UnicodeRange |
|||
{ |
|||
public static UnicodeRange Default = Parse("0-10FFFD"); |
|||
|
|||
private readonly UnicodeRangeSegment _single; |
|||
private readonly IReadOnlyList<UnicodeRangeSegment> _segments = null; |
|||
|
|||
public UnicodeRange(int start, int end) |
|||
{ |
|||
_single = new UnicodeRangeSegment(start, end); |
|||
} |
|||
|
|||
public UnicodeRange(UnicodeRangeSegment single) |
|||
{ |
|||
_single = single; |
|||
} |
|||
|
|||
public UnicodeRange(IReadOnlyList<UnicodeRangeSegment> segments) |
|||
{ |
|||
if(segments is null || segments.Count == 0) |
|||
{ |
|||
throw new ArgumentException(nameof(segments)); |
|||
} |
|||
|
|||
_single = segments[0]; |
|||
_segments = segments; |
|||
} |
|||
|
|||
internal UnicodeRangeSegment Single => _single; |
|||
|
|||
internal IReadOnlyList<UnicodeRangeSegment> Segments => _segments; |
|||
|
|||
/// <summary>
|
|||
/// Determines if given value is inside the range.
|
|||
/// </summary>
|
|||
/// <param name="value">The value to verify.</param>
|
|||
/// <returns>
|
|||
/// <c>true</c> If given value is inside the range, <c>false</c> otherwise.
|
|||
/// </returns>
|
|||
public bool IsInRange(int value) |
|||
{ |
|||
if(_segments is null) |
|||
{ |
|||
return _single.IsInRange(value); |
|||
} |
|||
|
|||
foreach(var segment in _segments) |
|||
{ |
|||
if (segment.IsInRange(value)) |
|||
{ |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Parses a <see cref="UnicodeRange"/>.
|
|||
/// </summary>
|
|||
/// <param name="s">The string to parse.</param>
|
|||
/// <returns>The parsed <see cref="UnicodeRange"/>.</returns>
|
|||
/// <exception cref="FormatException"></exception>
|
|||
public static UnicodeRange Parse(string s) |
|||
{ |
|||
if (string.IsNullOrEmpty(s)) |
|||
{ |
|||
throw new FormatException("Could not parse specified Unicode range."); |
|||
} |
|||
|
|||
var parts = s.Split(','); |
|||
|
|||
var length = parts.Length; |
|||
|
|||
if(length == 0) |
|||
{ |
|||
throw new FormatException("Could not parse specified Unicode range."); |
|||
} |
|||
|
|||
if(length == 1) |
|||
{ |
|||
return new UnicodeRange(UnicodeRangeSegment.Parse(parts[0])); |
|||
} |
|||
|
|||
var segments = new UnicodeRangeSegment[length]; |
|||
|
|||
for (int i = 0; i < length; i++) |
|||
{ |
|||
segments[i] = UnicodeRangeSegment.Parse(parts[i].Trim()); |
|||
} |
|||
|
|||
return new UnicodeRange(segments); |
|||
} |
|||
} |
|||
|
|||
public readonly struct UnicodeRangeSegment |
|||
{ |
|||
private static Regex s_regex = new Regex(@"^(?:[uU]\+)?(?:([0-9a-fA-F](?:[0-9a-fA-F?]{1,5})?))$"); |
|||
|
|||
public UnicodeRangeSegment(int start, int end) |
|||
{ |
|||
Start = start; |
|||
End = end; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Get the start of the segment.
|
|||
/// </summary>
|
|||
public int Start { get; } |
|||
|
|||
/// <summary>
|
|||
/// Get the end of the segment.
|
|||
/// </summary>
|
|||
public int End { get; } |
|||
|
|||
/// <summary>
|
|||
/// Determines if given value is inside the range segment.
|
|||
/// </summary>
|
|||
/// <param name="value">The value to verify.</param>
|
|||
/// <returns>
|
|||
/// <c>true</c> If given value is inside the range segment, <c>false</c> otherwise.
|
|||
/// </returns>
|
|||
public bool IsInRange(int value) |
|||
{ |
|||
return value - Start <= End - Start; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Parses a <see cref="UnicodeRangeSegment"/>.
|
|||
/// </summary>
|
|||
/// <param name="s">The string to parse.</param>
|
|||
/// <returns>The parsed <see cref="UnicodeRangeSegment"/>.</returns>
|
|||
/// <exception cref="FormatException"></exception>
|
|||
public static UnicodeRangeSegment Parse(string s) |
|||
{ |
|||
if (string.IsNullOrEmpty(s)) |
|||
{ |
|||
throw new FormatException("Could not parse specified Unicode range segment."); |
|||
} |
|||
|
|||
var parts = s.Split('-'); |
|||
|
|||
int start, end; |
|||
|
|||
switch (parts.Length) |
|||
{ |
|||
case 1: |
|||
{ |
|||
//e.g. U+20, U+3F U+30??
|
|||
var single = s_regex.Match(parts[0]); |
|||
|
|||
if (!single.Success) |
|||
{ |
|||
throw new FormatException("Could not parse specified Unicode range segment."); |
|||
} |
|||
|
|||
if (!single.Value.Contains("?")) |
|||
{ |
|||
start = int.Parse(single.Groups[1].Value, System.Globalization.NumberStyles.HexNumber); |
|||
end = start; |
|||
} |
|||
else |
|||
{ |
|||
start = int.Parse(single.Groups[1].Value.Replace('?', '0'), System.Globalization.NumberStyles.HexNumber); |
|||
end = int.Parse(single.Groups[1].Value.Replace('?', 'F'), System.Globalization.NumberStyles.HexNumber); |
|||
} |
|||
break; |
|||
} |
|||
case 2: |
|||
{ |
|||
var first = s_regex.Match(parts[0]); |
|||
var second = s_regex.Match(parts[1]); |
|||
|
|||
if (!first.Success || !second.Success) |
|||
{ |
|||
throw new FormatException("Could not parse specified Unicode range segment."); |
|||
} |
|||
|
|||
start = int.Parse(first.Groups[1].Value, System.Globalization.NumberStyles.HexNumber); |
|||
end = int.Parse(second.Groups[1].Value, System.Globalization.NumberStyles.HexNumber); |
|||
break; |
|||
} |
|||
default: |
|||
throw new FormatException("Could not parse specified Unicode range segment."); |
|||
} |
|||
|
|||
return new UnicodeRangeSegment(start, end); |
|||
} |
|||
} |
|||
} |
|||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,7 @@ |
|||
<Project> |
|||
<PropertyGroup> |
|||
<EmccTotalMemory>16777216</EmccTotalMemory> |
|||
<BlazorEnableTimeZoneSupport>false</BlazorEnableTimeZoneSupport> |
|||
<BlazorWebAssemblyPreserveCollationData>false</BlazorWebAssemblyPreserveCollationData> |
|||
</PropertyGroup> |
|||
</Project> |
|||
@ -0,0 +1,4 @@ |
|||
<Project> |
|||
<Import Project="Microsoft.AspNetCore.StaticWebAssets.props" /> |
|||
<Import Project="Avalonia.Web.Blazor.CompilationTuning.props" /> |
|||
</Project> |
|||
@ -1,78 +0,0 @@ |
|||
using System.Globalization; |
|||
using Avalonia.Media; |
|||
using Avalonia.Platform; |
|||
using Avalonia.Skia; |
|||
using SkiaSharp; |
|||
|
|||
namespace Avalonia.Web.Blazor |
|||
{ |
|||
public class CustomFontManagerImpl : IFontManagerImpl |
|||
{ |
|||
private readonly Typeface[] _customTypefaces; |
|||
private readonly string _defaultFamilyName; |
|||
|
|||
private readonly Typeface _defaultTypeface = |
|||
new Typeface("avares://Avalonia.Web.Blazor/Assets#Noto Mono"); |
|||
private readonly Typeface _italicTypeface = |
|||
new Typeface("avares://Avalonia.Web.Blazor/Assets#Noto Sans"); |
|||
|
|||
public CustomFontManagerImpl() |
|||
{ |
|||
_customTypefaces = new[] { _italicTypeface, _defaultTypeface }; |
|||
_defaultFamilyName = _defaultTypeface.FontFamily.FamilyNames.PrimaryFamilyName; |
|||
} |
|||
|
|||
public string GetDefaultFontFamilyName() |
|||
{ |
|||
return _defaultFamilyName; |
|||
} |
|||
|
|||
public IEnumerable<string> GetInstalledFontFamilyNames(bool checkForUpdates = false) |
|||
{ |
|||
return _customTypefaces.Select(x => x.FontFamily.Name); |
|||
} |
|||
|
|||
public bool TryMatchCharacter(int codepoint, FontStyle fontStyle, FontWeight fontWeight, FontFamily fontFamily, |
|||
CultureInfo culture, out Typeface typeface) |
|||
{ |
|||
foreach (var customTypeface in _customTypefaces) |
|||
{ |
|||
if (customTypeface.GlyphTypeface.GetGlyph((uint)codepoint) == 0) |
|||
{ |
|||
continue; |
|||
} |
|||
|
|||
typeface = new Typeface(customTypeface.FontFamily, fontStyle, fontWeight); |
|||
|
|||
return true; |
|||
} |
|||
|
|||
typeface = _defaultTypeface; |
|||
|
|||
return true; |
|||
} |
|||
|
|||
public IGlyphTypefaceImpl CreateGlyphTypeface(Typeface typeface) |
|||
{ |
|||
SKTypeface skTypeface; |
|||
|
|||
switch (typeface.FontFamily.Name) |
|||
{ |
|||
case "Noto Sans": |
|||
{ |
|||
var typefaceCollection = SKTypefaceCollectionCache.GetOrAddTypefaceCollection(_italicTypeface.FontFamily); |
|||
skTypeface = typefaceCollection.Get(typeface); |
|||
break; |
|||
} |
|||
default: |
|||
{ |
|||
var typefaceCollection = SKTypefaceCollectionCache.GetOrAddTypefaceCollection(_defaultTypeface.FontFamily); |
|||
skTypeface = typefaceCollection.Get(_defaultTypeface); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
return new GlyphTypefaceImpl(skTypeface); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
using System; |
|||
using static Avalonia.Win32.Interop.UnmanagedMethods; |
|||
|
|||
namespace Avalonia.Win32.Input |
|||
{ |
|||
internal struct Imm32CaretManager |
|||
{ |
|||
private bool _isCaretCreated; |
|||
|
|||
public void TryCreate(int _langId, IntPtr hwnd) |
|||
{ |
|||
if (!_isCaretCreated) |
|||
{ |
|||
if (_langId == LANG_ZH || _langId == LANG_JA) |
|||
{ |
|||
_isCaretCreated = CreateCaret(hwnd, IntPtr.Zero, 2, 10); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public void TryMove(int x, int y) |
|||
{ |
|||
if (_isCaretCreated) |
|||
{ |
|||
SetCaretPos(x, y); |
|||
} |
|||
} |
|||
|
|||
public void TryDestroy() |
|||
{ |
|||
if (_isCaretCreated) |
|||
{ |
|||
DestroyCaret(); |
|||
_isCaretCreated = false; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,231 @@ |
|||
using System; |
|||
using Avalonia.Input.TextInput; |
|||
using Avalonia.Threading; |
|||
|
|||
using static Avalonia.Win32.Interop.UnmanagedMethods; |
|||
|
|||
namespace Avalonia.Win32.Input |
|||
{ |
|||
/// <summary>
|
|||
/// A Windows input method editor based on Windows Input Method Manager (IMM32).
|
|||
/// </summary>
|
|||
class Imm32InputMethod : ITextInputMethodImpl |
|||
{ |
|||
public IntPtr HWND { get; private set; } |
|||
private IntPtr _defaultImc; |
|||
private WindowImpl _parent; |
|||
private bool _active; |
|||
private bool _showCompositionWindow; |
|||
private Imm32CaretManager _caretManager = new(); |
|||
private bool _showCandidateList; |
|||
private ushort _langId; |
|||
private const int _caretMargin = 1; |
|||
|
|||
public void SetLanguageAndWindow(WindowImpl parent, IntPtr hwnd, IntPtr HKL) |
|||
{ |
|||
if (HWND != hwnd) |
|||
{ |
|||
_defaultImc = IntPtr.Zero; |
|||
} |
|||
HWND = hwnd; |
|||
_parent = parent; |
|||
_active = false; |
|||
_langId = PRIMARYLANGID(LGID(HKL)); |
|||
_showCompositionWindow = true; |
|||
_showCandidateList = true; |
|||
|
|||
IsComposing = false; |
|||
} |
|||
|
|||
//Dependant on CurrentThread. When Avalonia will support Multiple Dispatchers -
|
|||
//every Dispatcher should have their own InputMethod.
|
|||
public static Imm32InputMethod Current { get; } = new Imm32InputMethod(); |
|||
|
|||
private IntPtr DefaultImc |
|||
{ |
|||
get |
|||
{ |
|||
if (_defaultImc == IntPtr.Zero && |
|||
HWND != IntPtr.Zero) |
|||
{ |
|||
_defaultImc = ImmGetContext(HWND); |
|||
ImmReleaseContext(HWND, _defaultImc); |
|||
} |
|||
|
|||
if (_defaultImc == IntPtr.Zero) |
|||
{ |
|||
_defaultImc = ImmCreateContext(); |
|||
} |
|||
|
|||
return _defaultImc; |
|||
} |
|||
} |
|||
|
|||
public void Reset() |
|||
{ |
|||
if (IsComposing) |
|||
{ |
|||
Dispatcher.UIThread.Post(() => |
|||
{ |
|||
ImmNotifyIME(DefaultImc, NI_COMPOSITIONSTR, CPS_COMPLETE, 0); |
|||
ImmReleaseContext(HWND, DefaultImc); |
|||
IsComposing = false; |
|||
}); |
|||
} |
|||
} |
|||
|
|||
public void SetActive(bool active) |
|||
{ |
|||
_active = active; |
|||
Dispatcher.UIThread.Post(() => |
|||
{ |
|||
if (active) |
|||
{ |
|||
if (DefaultImc != IntPtr.Zero) |
|||
{ |
|||
_caretManager.TryCreate(_langId, HWND); |
|||
// Load the default IME context.
|
|||
// NOTE(hbono)
|
|||
// IMM ignores this call if the IME context is loaded. Therefore, we do
|
|||
// not have to check whether or not the IME context is loaded.
|
|||
ImmAssociateContext(HWND, _defaultImc); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
// A renderer process have moved its input focus to a password input
|
|||
// when there is an ongoing composition, e.g. a user has clicked a
|
|||
// mouse button and selected a password input while composing a text.
|
|||
// For this case, we have to complete the ongoing composition and
|
|||
// clean up the resources attached to this object BEFORE DISABLING THE IME.
|
|||
if (IsComposing) |
|||
{ |
|||
ImmNotifyIME(DefaultImc, NI_COMPOSITIONSTR, CPS_COMPLETE, 0); |
|||
ImmReleaseContext(HWND, DefaultImc); |
|||
IsComposing = false; |
|||
} |
|||
ImmAssociateContext(HWND, IntPtr.Zero); |
|||
_caretManager.TryDestroy(); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public void SetCursorRect(Rect rect) |
|||
{ |
|||
var focused = GetActiveWindow() == HWND; |
|||
if (!focused) |
|||
{ |
|||
return; |
|||
} |
|||
Dispatcher.UIThread.Post(() => |
|||
{ |
|||
IntPtr himc = DefaultImc; |
|||
if (himc == IntPtr.Zero) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
MoveImeWindow(rect, himc); |
|||
ImmReleaseContext(HWND, himc); |
|||
}); |
|||
} |
|||
|
|||
// see: https://chromium.googlesource.com/experimental/chromium/src/+/bf09a5036ccfb77d2277247c66dc55daf41df3fe/chrome/browser/ime_input.cc
|
|||
// see: https://engine.chinmaygarde.com/window__win32_8cc_source.html
|
|||
private void MoveImeWindow(Rect rect, IntPtr himc) |
|||
{ |
|||
var p1 = rect.TopLeft; |
|||
var p2 = rect.BottomRight; |
|||
var s = _parent?.DesktopScaling ?? 1; |
|||
var (x1, y1, x2, y2) = ((int) (p1.X * s), (int) (p1.Y * s), (int) (p2.X * s), (int) (p2.Y * s)); |
|||
|
|||
if (!_showCompositionWindow && |
|||
_langId == LANG_ZH) |
|||
{ |
|||
// Chinese IMEs ignore function calls to ::ImmSetCandidateWindow()
|
|||
// when a user disables TSF (Text Service Framework) and CUAS (Cicero
|
|||
// Unaware Application Support).
|
|||
// On the other hand, when a user enables TSF and CUAS, Chinese IMEs
|
|||
// ignore the position of the current system caret and uses the
|
|||
// parameters given to ::ImmSetCandidateWindow() with its 'dwStyle'
|
|||
// parameter CFS_CANDIDATEPOS.
|
|||
// Therefore, we do not only call ::ImmSetCandidateWindow() but also
|
|||
// set the positions of the temporary system caret.
|
|||
var candidateForm = new CANDIDATEFORM |
|||
{ |
|||
dwIndex = 0, |
|||
dwStyle = CFS_CANDIDATEPOS, |
|||
ptCurrentPos = new POINT {X = x2, Y = y2} |
|||
}; |
|||
ImmSetCandidateWindow(himc, ref candidateForm); |
|||
} |
|||
|
|||
_caretManager.TryMove(x2, y2); |
|||
|
|||
if (_showCompositionWindow) |
|||
{ |
|||
ConfigureCompositionWindow(x1, y1, himc, y2 - y1); |
|||
// Don't need to set the position of candidate window.
|
|||
return; |
|||
} |
|||
|
|||
if (_langId == LANG_KO) |
|||
{ |
|||
// Chinese IMEs and Japanese IMEs require the upper-left corner of
|
|||
// the caret to move the position of their candidate windows.
|
|||
// On the other hand, Korean IMEs require the lower-left corner of the
|
|||
// caret to move their candidate windows.
|
|||
y2 += _caretMargin; |
|||
} |
|||
|
|||
// Need to return here since some Chinese IMEs would stuck if set
|
|||
// candidate window position with CFS_EXCLUDE style.
|
|||
if (_langId == LANG_ZH) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
// Japanese IMEs and Korean IMEs also use the rectangle given to
|
|||
// ::ImmSetCandidateWindow() with its 'dwStyle' parameter CFS_EXCLUDE
|
|||
// to move their candidate windows when a user disables TSF and CUAS.
|
|||
// Therefore, we also set this parameter here.
|
|||
var excludeRectangle = new CANDIDATEFORM |
|||
{ |
|||
dwIndex = 0, |
|||
dwStyle = CFS_EXCLUDE, |
|||
ptCurrentPos = new POINT {X = x1, Y = y1}, |
|||
rcArea = new RECT {left = x1, top = y1, right = x2, bottom = y2 + _caretMargin} |
|||
}; |
|||
ImmSetCandidateWindow(himc, ref excludeRectangle); |
|||
} |
|||
|
|||
private static void ConfigureCompositionWindow(int x1, int y1, IntPtr himc, int height) |
|||
{ |
|||
var compForm = new COMPOSITIONFORM |
|||
{ |
|||
dwStyle = CFS_POINT, |
|||
ptCurrentPos = new POINT {X = x1, Y = y1}, |
|||
}; |
|||
ImmSetCompositionWindow(himc, ref compForm); |
|||
|
|||
var logFont = new LOGFONT() |
|||
{ |
|||
lfHeight = height, |
|||
lfQuality = 5 //CLEARTYPE_QUALITY
|
|||
}; |
|||
ImmSetCompositionFont(himc, ref logFont); |
|||
} |
|||
|
|||
public void SetOptions(TextInputOptionsQueryEventArgs options) |
|||
{ |
|||
// we're skipping this. not usable on windows
|
|||
} |
|||
|
|||
public bool IsComposing { get; set; } |
|||
|
|||
~Imm32InputMethod() |
|||
{ |
|||
_caretManager.TryDestroy(); |
|||
} |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue