diff options
author | Eric Maupin <ermaup@microsoft.com> | 2019-09-13 17:22:37 +0300 |
---|---|---|
committer | Eric Maupin <ermaup@microsoft.com> | 2019-10-04 23:19:09 +0300 |
commit | de1cc1d9b78864e5023d958b2d6f9e9aafe444b2 (patch) | |
tree | 00e6a2de8598ef1adecd4e8f6a7a30332ccddd28 /Xamarin.PropertyEditing.Windows | |
parent | 655e2775af7ebe30ed38522c9ec8bc7242244a31 (diff) |
[Win] AutoResizing mask editor
Diffstat (limited to 'Xamarin.PropertyEditing.Windows')
4 files changed, 243 insertions, 1 deletions
diff --git a/Xamarin.PropertyEditing.Windows/AutoResizingMaskEditorControl.cs b/Xamarin.PropertyEditing.Windows/AutoResizingMaskEditorControl.cs new file mode 100644 index 0000000..23ba339 --- /dev/null +++ b/Xamarin.PropertyEditing.Windows/AutoResizingMaskEditorControl.cs @@ -0,0 +1,116 @@ +using System; +using System.ComponentModel; +using System.Windows; +using System.Windows.Automation; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using Xamarin.PropertyEditing.Drawing; +using Xamarin.PropertyEditing.ViewModels; + +namespace Xamarin.PropertyEditing.Windows +{ + [TemplatePart (Name = "sizingButton", Type = typeof(ButtonBase))] + [TemplatePart (Name = "windowRect", Type = typeof (FrameworkElement))] + [TemplatePart (Name = "elementRect", Type = typeof (FrameworkElement))] + internal class AutoResizingMaskEditorControl + : PropertyEditorControl + { + public AutoResizingMaskEditorControl () + { + DataContextChanged += OnDataContextChanged; + } + + public override void OnApplyTemplate () + { + base.OnApplyTemplate (); + + this.sizingButton = GetTemplateChild ("sizingButton") as ButtonBase; + if (this.sizingButton == null) + throw new InvalidOperationException ($"Template for {nameof(AutoResizingMaskEditorControl)} must have a sizingButton"); + + this.window = GetTemplateChild ("windowRect") as FrameworkElement; + if (this.window == null) + throw new InvalidOperationException ($"Template for {nameof(AutoResizingMaskEditorControl)} must have a windowRect"); + + this.elementVisual = GetTemplateChild ("elementRect") as FrameworkElement; + if (this.elementVisual == null) + throw new InvalidOperationException ($"Template for {nameof(AutoResizingMaskEditorControl)} must have a elementRect"); + + this.window.SizeChanged += OnPreviewWindowSizeChanged; + + UpdateSizeName(); + UpdateVisual(); + } + + private AutoResizingPropertyViewModel vm; + private ButtonBase sizingButton; + private FrameworkElement elementVisual, window; + + private void OnDataContextChanged (object sender, DependencyPropertyChangedEventArgs e) + { + if (this.vm != null) { + this.vm.PropertyChanged -= OnViewModelPropertyChanged; + } + + this.vm = e.NewValue as AutoResizingPropertyViewModel; + if (this.vm != null) { + this.vm.PropertyChanged += OnViewModelPropertyChanged; + } + + UpdateSizeName(); + } + + private void OnViewModelPropertyChanged (object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == nameof(AutoResizingPropertyViewModel.WidthSizable) || e.PropertyName == nameof(AutoResizingPropertyViewModel.HeightSizable)) { + UpdateSizeName (); + UpdateVisual(); + } else if (e.PropertyName == nameof(AutoResizingPropertyViewModel.LeftMarginFixed) + || e.PropertyName == nameof(AutoResizingPropertyViewModel.RightMarginFixed) + || e.PropertyName == nameof(AutoResizingPropertyViewModel.TopMarginFixed) + || e.PropertyName == nameof(AutoResizingPropertyViewModel.BottomMarginFixed)) { + UpdateVisual(); + } + } + + private void OnPreviewWindowSizeChanged (object sender, SizeChangedEventArgs e) + { + UpdateVisual (); + } + + private void UpdateVisual () + { + if (this.vm == null) + return; + + var elementRect = this.vm.GetPreviewElementRectangle (new CommonSize (this.window.ActualWidth, this.window.ActualHeight), this.vm.Value); + Canvas.SetLeft (this.elementVisual, elementRect.X); + Canvas.SetTop (this.elementVisual, elementRect.Y); + this.elementVisual.Width = elementRect.Width; + this.elementVisual.Height = elementRect.Height; + } + + private void UpdateSizeName () + { + if (this.sizingButton == null) + return; + + string name = null; + if (this.vm != null) { + string current; + if (!this.vm.HeightSizable && !this.vm.WidthSizable) + current = Properties.Resources.AutoresizingFixedSized; + else if (this.vm.HeightSizable && !this.vm.WidthSizable) + current = Properties.Resources.AutoresizingHeightSizable; + else if (!this.vm.HeightSizable && this.vm.WidthSizable) + current = Properties.Resources.AutoresizingWidthSizable; + else + current = Properties.Resources.AutoresizingWidthHeightSizable; + + name = String.Format (Properties.Resources.AutoresizingSizingName, current); + } + + AutomationProperties.SetName (this.sizingButton, name); + } + } +} diff --git a/Xamarin.PropertyEditing.Windows/Themes/Resources.xaml b/Xamarin.PropertyEditing.Windows/Themes/Resources.xaml index 4a883d6..1996520 100644 --- a/Xamarin.PropertyEditing.Windows/Themes/Resources.xaml +++ b/Xamarin.PropertyEditing.Windows/Themes/Resources.xaml @@ -6,7 +6,8 @@ xmlns:prop="clr-namespace:Xamarin.PropertyEditing.Properties;assembly=Xamarin.PropertyEditing" xmlns:system="clr-namespace:System;assembly=mscorlib" xmlns:vm="clr-namespace:Xamarin.PropertyEditing.ViewModels;assembly=Xamarin.PropertyEditing" - xmlns:pe="clr-namespace:Xamarin.PropertyEditing;assembly=Xamarin.PropertyEditing"> + xmlns:pe="clr-namespace:Xamarin.PropertyEditing;assembly=Xamarin.PropertyEditing" + xmlns:common="clr-namespace:Xamarin.PropertyEditing.Common;assembly=Xamarin.PropertyEditing"> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="MenuButtonStyle.xaml" /> @@ -414,6 +415,125 @@ </Setter> </Style> + <Style TargetType="local:AutoResizingMaskEditorControl"> + <Setter Property="UseLayoutRounding" Value="True" /> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="local:AutoResizingMaskEditorControl"> + <ControlTemplate.Resources> + <Style x:Key="MarginButton" TargetType="ToggleButton"> + <Setter Property="BorderThickness" Value="0" /> + <Setter Property="Foreground" Value="{DynamicResource GuidelineEnabledForegroundBrush}" /> + <Setter Property="Background" Value="Transparent" /> + <Setter Property="RenderTransformOrigin" Value="0.5,0.5" /> + <Setter Property="Padding" Value="0" /> + <Setter Property="VerticalAlignment" Value="Center" /> + <Setter Property="HorizontalAlignment" Value="Center" /> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="ToggleButton"> + <Border BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" Margin="{TemplateBinding Margin}" Padding="{TemplateBinding Padding}" UseLayoutRounding="{TemplateBinding UseLayoutRounding}"> + <Polyline Stroke="{TemplateBinding Foreground}" Points="4,15 4,12 4,15 4,18 4,15 26,15 26,15 26,12 26,15 26,18 26,15" Height="30" Width="30" /> + </Border> + </ControlTemplate> + </Setter.Value> + </Setter> + <Style.Triggers> + <Trigger Property="IsChecked" Value="False"> + <Setter Property="Foreground" Value="{DynamicResource GuidelineDisabledForegroundBrush}" /> + </Trigger> + </Style.Triggers> + </Style> + </ControlTemplate.Resources> + + <Grid VerticalAlignment="Top" Height="100" UseLayoutRounding="{TemplateBinding UseLayoutRounding}"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="Auto"/> + <ColumnDefinition /> + </Grid.ColumnDefinitions> + + <Border Grid.Row="0" Grid.Column="0" BorderBrush="{DynamicResource InputBorderBrush}" BorderThickness="1" Background="{DynamicResource InputBackgroundBrush}"> + <Grid> + <Grid.RowDefinitions> + <RowDefinition /> + <RowDefinition Height="40" /> + <RowDefinition /> + </Grid.RowDefinitions> + <Grid.ColumnDefinitions> + <ColumnDefinition /> + <ColumnDefinition Width="40" /> + <ColumnDefinition /> + </Grid.ColumnDefinitions> + <ToggleButton Style="{StaticResource MarginButton}" AutomationProperties.Name="{x:Static prop:Resources.AutoresizingLeftMarginName}" IsChecked="{Binding LeftMarginFixed,Mode=TwoWay}" Grid.Row="1" Grid.Column="0" /> + <ToggleButton Style="{StaticResource MarginButton}" AutomationProperties.Name="{x:Static prop:Resources.AutoresizingTopMarginName}" IsChecked="{Binding TopMarginFixed,Mode=TwoWay}" Grid.Row="0" Grid.Column="1"> + <ToggleButton.RenderTransform> + <RotateTransform Angle="90" /> + </ToggleButton.RenderTransform> + </ToggleButton> + <ToggleButton Style="{StaticResource MarginButton}" AutomationProperties.Name="{x:Static prop:Resources.AutoresizingRightMarginName}" IsChecked="{Binding RightMarginFixed,Mode=TwoWay}" Grid.Row="1" Grid.Column="2" /> + <ToggleButton Style="{StaticResource MarginButton}" AutomationProperties.Name="{x:Static prop:Resources.AutoresizingBottomMarginName}" IsChecked="{Binding BottomMarginFixed,Mode=TwoWay}" Grid.Row="2" Grid.Column="1"> + <ToggleButton.RenderTransform> + <RotateTransform Angle="90" /> + </ToggleButton.RenderTransform> + </ToggleButton> + + <Button Name="sizingButton" Grid.Row="1" Grid.Column="1" Command="{Binding CycleSizingCommand,Mode=OneTime}" BorderThickness="1" BorderBrush="{DynamicResource GuidelineDisabledForegroundBrush}" Background="Transparent" Content="{Binding}" AutomationProperties.HelpText="{x:Static prop:Resources.AutoresizingSizingHelpText}"> + <Button.ContentTemplate> + <DataTemplate DataType="vm:AutoResizingPropertyViewModel"> + <Grid> + <Polyline Name="widthSizable" Stroke="{DynamicResource GuidelineEnabledForegroundBrush}" Points="0,15 0.2,14.8 0,15 0.2,15.2 0,15 30,15 30,15 29.8,14.8 30,15 29.8,15.2 30,15" Width="30" Height="30" SnapsToDevicePixels="True" /> + <Polyline Name="heightSizable" Stroke="{DynamicResource GuidelineEnabledForegroundBrush}" Points="15,0 14.8,0.2 15,0 15.2,0.2 15,0 15,30 15,30 14.8,29.8 15,30 15.2,29.8 15,30" Width="30" Height="30" SnapsToDevicePixels="True" /> + </Grid> + <DataTemplate.Triggers> + <DataTrigger Binding="{Binding HeightSizable}" Value="False"> + <Setter TargetName="heightSizable" Property="Stroke" Value="{DynamicResource GuidelineDisabledForegroundBrush}" /> + </DataTrigger> + <DataTrigger Binding="{Binding WidthSizable}" Value="False"> + <Setter TargetName="widthSizable" Property="Stroke" Value="{DynamicResource GuidelineDisabledForegroundBrush}" /> + </DataTrigger> + </DataTemplate.Triggers> + </DataTemplate> + </Button.ContentTemplate> + </Button> + </Grid> + </Border> + + <Border Grid.Row="0" Grid.Column="1" BorderBrush="{DynamicResource InputBorderBrush}" BorderThickness="1" Background="{DynamicResource InputBackgroundBrush}" Margin="2,0,0,0"> + <Border Name="osBorder" Margin="2" Background="{DynamicResource ExampleWindowBackgroundBrush}" BorderThickness="0"> + <Grid> + <Grid.RowDefinitions> + <RowDefinition Height="Auto" /> + <RowDefinition /> + </Grid.RowDefinitions> + + <Border Grid.Row="0" BorderThickness="0" Background="{DynamicResource ExampleWindowTitleBackgroundBrush}" Height="4" /> + <Canvas Grid.Row="1" Margin="6,6,0,0"> + <Canvas.Resources> + <Storyboard FillBehavior="Stop" RepeatBehavior="Forever" AutoReverse="True" Duration="0:0:0.5" x:Key="GrowStoryboard" Storyboard.TargetName="windowRect"> + <DoubleAnimation Storyboard.TargetProperty="Width" To="{Binding ElementName=osBorder,Path=ActualWidth}" /> + <DoubleAnimation Storyboard.TargetProperty="Height" To="{Binding ElementName=osBorder,Path=ActualHeight}" /> + </Storyboard> + </Canvas.Resources> + <Canvas.Triggers> + <EventTrigger RoutedEvent="MouseEnter"> + <BeginStoryboard Storyboard="{StaticResource GrowStoryboard}" Name="BeginGrowStoryboard" /> + </EventTrigger> + <EventTrigger RoutedEvent="MouseLeave"> + <RemoveStoryboard BeginStoryboardName="BeginGrowStoryboard" /> + </EventTrigger> + </Canvas.Triggers> + <Rectangle Name="windowRect" Fill="White" Width="30" Height="30" Margin="0" HorizontalAlignment="Left" VerticalAlignment="Top" SnapsToDevicePixels="False" /> + <Rectangle Name="elementRect" Fill="Red" Margin="0" HorizontalAlignment="Left" VerticalAlignment="Top" SnapsToDevicePixels="False" /> + </Canvas> + </Grid> + </Border> + </Border> + </Grid> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + <Style TargetType="local:ObjectEditorControl"> <Setter Property="Template"> <Setter.Value> diff --git a/Xamarin.PropertyEditing.Windows/Themes/VS.Dark.xaml b/Xamarin.PropertyEditing.Windows/Themes/VS.Dark.xaml index cb76cf1..113401b 100644 --- a/Xamarin.PropertyEditing.Windows/Themes/VS.Dark.xaml +++ b/Xamarin.PropertyEditing.Windows/Themes/VS.Dark.xaml @@ -20,6 +20,11 @@ <SolidColorBrush x:Key="VariantBackgroundBrush">#ABABAB</SolidColorBrush> <SolidColorBrush x:Key="VariantLineBrush">#5E5E5E</SolidColorBrush> + <SolidColorBrush x:Key="GuidelineDisabledForegroundBrush">#777777</SolidColorBrush> + <SolidColorBrush x:Key="GuidelineEnabledForegroundBrush">#F56D4F</SolidColorBrush> + <SolidColorBrush x:Key="ExampleWindowTitleBackgroundBrush">#575757</SolidColorBrush> + <SolidColorBrush x:Key="ExampleWindowBackgroundBrush">#7D7D7F</SolidColorBrush> + <SolidColorBrush x:Key="AdvancedExpanderCollapsedForegroundBrush">#F1F1F1</SolidColorBrush> <SolidColorBrush x:Key="AdvancedExpanderMouseOverForegroundBrush">#007ACC</SolidColorBrush> <SolidColorBrush x:Key="AdvancedExpanderMouseOverBorderBrush">#3E3E40</SolidColorBrush> diff --git a/Xamarin.PropertyEditing.Windows/Xamarin.PropertyEditing.Windows.csproj b/Xamarin.PropertyEditing.Windows/Xamarin.PropertyEditing.Windows.csproj index b21e249..fd84130 100644 --- a/Xamarin.PropertyEditing.Windows/Xamarin.PropertyEditing.Windows.csproj +++ b/Xamarin.PropertyEditing.Windows/Xamarin.PropertyEditing.Windows.csproj @@ -53,6 +53,7 @@ <Link>Properties\GlobalAssemblyInfo.cs</Link> </Compile> <Compile Include="ArrangeModeLocalizedConverter.cs" /> + <Compile Include="AutoResizingMaskEditorControl.cs" /> <Compile Include="BoolEditorControl.cs" /> <Compile Include="BoolsToVisibilityConverter.cs" /> <Compile Include="BrushBoxControl.cs" /> |