From de1cc1d9b78864e5023d958b2d6f9e9aafe444b2 Mon Sep 17 00:00:00 2001 From: Eric Maupin Date: Fri, 13 Sep 2019 10:22:37 -0400 Subject: [Win] AutoResizing mask editor --- .../AutoResizingMaskEditorControl.cs | 116 ++++++++++++++++++++ .../Themes/Resources.xaml | 122 ++++++++++++++++++++- .../Themes/VS.Dark.xaml | 5 + .../Xamarin.PropertyEditing.Windows.csproj | 1 + .../Common/AutoResizingFlags.cs | 19 ++++ .../Properties/Resources.Designer.cs | 66 +++++++++++ Xamarin.PropertyEditing/Properties/Resources.resx | 99 +++++++++++------ .../ViewModels/AutoResizingPropertyViewModel.cs | 60 +++++++++- 8 files changed, 455 insertions(+), 33 deletions(-) create mode 100644 Xamarin.PropertyEditing.Windows/AutoResizingMaskEditorControl.cs create mode 100644 Xamarin.PropertyEditing/Common/AutoResizingFlags.cs 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"> @@ -414,6 +415,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +