From f7e0b17b93d870e1b41951acfd0cde25f3bc77b3 Mon Sep 17 00:00:00 2001 From: CartBlanche Date: Sun, 20 Oct 2019 13:16:30 +0100 Subject: [Mac] Make Brush Tabs Navigable. Centralise Tabs code under TabButton class. --- .../Controls/BrushEditorControl.cs | 3 +- .../Controls/ControlExtensions.cs | 4 +- .../Controls/Custom/BrushTabViewController.cs | 23 +++- .../Controls/Custom/ColorComponentEditor.cs | 4 +- .../Custom/ColorComponentTabViewController.cs | 9 ++ .../Controls/Custom/DrawingExtensions.cs | 2 +- .../Custom/EmptyBrushEditorViewController.cs | 17 ++- .../Custom/MaterialBrushEditorViewController.cs | 13 +- .../Controls/Custom/MaterialView.cs | 5 + .../Controls/Custom/NotifyingViewController.cs | 3 + .../Controls/Custom/NumericSpinEditor.cs | 2 +- .../Controls/Custom/NumericTextField.cs | 2 + .../Controls/Custom/ResourceBrushViewController.cs | 33 ++--- .../Controls/Custom/ResourceOutlineView.cs | 3 +- .../Controls/Custom/SolidColorBrushEditor.cs | 37 ++--- .../Custom/SolidColorBrushEditorViewController.cs | 2 +- .../Controls/Custom/TabButton.cs | 76 ++++++++--- .../Controls/Custom/UnderlinedTabViewController.cs | 57 +++++--- .../Controls/Custom/UnderlinedTextField.cs | 149 --------------------- .../RequestResource/RequestResourceView.cs | 3 +- .../Xamarin.PropertyEditing.Mac.csproj | 3 + 21 files changed, 204 insertions(+), 246 deletions(-) delete mode 100644 Xamarin.PropertyEditing.Mac/Controls/Custom/UnderlinedTextField.cs (limited to 'Xamarin.PropertyEditing.Mac') diff --git a/Xamarin.PropertyEditing.Mac/Controls/BrushEditorControl.cs b/Xamarin.PropertyEditing.Mac/Controls/BrushEditorControl.cs index c0e6344..6a8b213 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/BrushEditorControl.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/BrushEditorControl.cs @@ -46,8 +46,7 @@ namespace Xamarin.PropertyEditing.Mac Frame = new CGRect (0, 0, 30, 10) }; - this.popover = new NSPopover { - Behavior = NSPopoverBehavior.Transient, + this.popover = new AutoClosePopOver (hostResources, hostResources.GetVibrantAppearance (EffectiveAppearance)) { ContentViewController = this.brushTabViewController = new BrushTabViewController (hostResources) { PreferredContentSize = new CGSize (550, 363) } diff --git a/Xamarin.PropertyEditing.Mac/Controls/ControlExtensions.cs b/Xamarin.PropertyEditing.Mac/Controls/ControlExtensions.cs index cad49a8..cd51e74 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/ControlExtensions.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/ControlExtensions.cs @@ -26,15 +26,13 @@ namespace Xamarin.PropertyEditing.Mac } }; - var popover = new NSPopover { - Behavior = NSPopoverBehavior.Transient, + var popover = new AutoClosePopOver (hostResources, hostResources.GetVibrantAppearance (source.EffectiveAppearance)) { Delegate = new PopoverDelegate (tcs), ContentViewController = new NSViewController { View = selector, PreferredContentSize = new CoreGraphics.CGSize (360, 335) }, }; - popover.SetAppearance (hostResources.GetVibrantAppearance (source.EffectiveAppearance)); tcs.Task.ContinueWith (t => { // Focus back to the button that popped us up diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/BrushTabViewController.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/BrushTabViewController.cs index 9430e25..c55e2c6 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/Custom/BrushTabViewController.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/BrushTabViewController.cs @@ -24,8 +24,8 @@ namespace Xamarin.PropertyEditing.Mac ContentPadding = new NSEdgeInsets (8, 8, 8, 8); this.filterResource = new NSSearchField { - ControlSize = NSControlSize.Mini, - Font = NSFont.SystemFontOfSize (NSFont.SystemFontSizeForControlSize (NSControlSize.Mini)), + ControlSize = NSControlSize.Small, + Font = NSFont.SystemFontOfSize (NSFont.SystemFontSizeForControlSize (NSControlSize.Small)), PlaceholderString = Properties.Resources.SearchResourcesTitle, }; @@ -107,7 +107,7 @@ namespace Xamarin.PropertyEditing.Mac this.resource.ViewModel = ViewModel; item.ViewController = this.resource; item.ToolTip = Properties.Resources.ResourceBrush; - image = "pe-property-brush-resources-16"; + image = "pe-property-brush-resources-16"; break; case CommonBrushType.Gradient: @@ -158,8 +158,9 @@ namespace Xamarin.PropertyEditing.Mac public override void WillSelect (NSTabView tabView, NSTabViewItem item) { - if (item.ViewController is NotifyingViewController brushController) + if (item.ViewController is NotifyingViewController brushController) { brushController.ViewModel = ViewModel; + } if (this.inhibitSelection) return; @@ -174,13 +175,25 @@ namespace Xamarin.PropertyEditing.Mac ViewModel.SelectedBrushType = ViewModel.BrushTypes[item.Label]; this.filterResource.Hidden = ViewModel.SelectedBrushType != CommonBrushType.Resource; + if (!this.filterResource.Hidden) { + if (Selected is TabButton tb) { + tb.NextKeyView = this.filterResource; + item.View.Window?.MakeFirstResponder (this.filterResource); + if (item.View.Subviews.Length > 1 + && item.View.Subviews[1].Subviews.Length > 0 + && item.View.Subviews[1].Subviews[0] is NSOutlineView rov) { + rov.NextKeyView = this.filterResource.NextKeyView; + this.filterResource.NextKeyView = rov; + } + } + } base.DidSelect (tabView, item); } public override void ViewDidLoad () { - View.Frame = new CGRect (0, 0, 430, 230); + View.Frame = new CGRect (0, 0, NotifyingViewController.PreferredContentSizeWidth, NotifyingViewController.PreferredContentSizeHeight); this.inhibitSelection = true; base.ViewDidLoad (); diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/ColorComponentEditor.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/ColorComponentEditor.cs index 30c43b6..47caf85 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/Custom/ColorComponentEditor.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/ColorComponentEditor.cs @@ -31,11 +31,11 @@ namespace Xamarin.PropertyEditing.Mac Initialize (hostResources); } - private ChannelGroup [] Editors { get; set; } + internal ChannelGroup [] Editors { get; set; } private UnfocusableTextField hexLabel; private NSTextField hexEditor; - class ChannelGroup + internal class ChannelGroup { public UnfocusableTextField Label { get; set; } public ComponentSpinEditor Editor { get; set; } diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/ColorComponentTabViewController.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/ColorComponentTabViewController.cs index 532b9ec..abe4f96 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/Custom/ColorComponentTabViewController.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/ColorComponentTabViewController.cs @@ -68,5 +68,14 @@ namespace Xamarin.PropertyEditing.Mac var controller = item.ViewController as ColorComponentViewController; EditorType = controller.EditorType; } + + public override void ViewDidLayout () + { + base.ViewDidLayout (); + + if (Selected is TabButton tb) { + View.Window?.MakeFirstResponder (tb); + } + } } } diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/DrawingExtensions.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/DrawingExtensions.cs index c8dbbef..988c9cd 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/Custom/DrawingExtensions.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/DrawingExtensions.cs @@ -19,7 +19,7 @@ namespace Xamarin.PropertyEditing.Mac Color0 = c0, Color1 = c1, Width = (float)Math.Min (frame.Height / 2f, 10), - Center = new CIVector (new nfloat [] { 0, 0 }), + Center = new CIVector (new nfloat[] { 0, 0 }), }) { using (var context = new CIContext (null)) { return context.CreateCGImage (board.OutputImage, new CGRect (0, 0, frame.Width, frame.Height)); diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/EmptyBrushEditorViewController.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/EmptyBrushEditorViewController.cs index f355eb9..0c77e8b 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/Custom/EmptyBrushEditorViewController.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/EmptyBrushEditorViewController.cs @@ -4,22 +4,33 @@ using Xamarin.PropertyEditing.ViewModels; namespace Xamarin.PropertyEditing.Mac { - class EmptyBrushEditorViewController : NotifyingViewController + internal class EmptyBrushEditorViewController : NotifyingViewController { public EmptyBrushEditorViewController () { - PreferredContentSize = new CGSize (430, 230); + PreferredContentSize = new CGSize (PreferredContentSizeWidth, PreferredContentSizeHeight); } private NSButton brushEditor; public override void LoadView () { - View = brushEditor = new NSButton { + View = this.brushEditor = new NSButton { Bordered = false, Title = Properties.Resources.NoBrush, Enabled = false }; } + + public override void ViewDidLayout () + { + base.ViewDidLayout (); + + if (ParentViewController is BrushTabViewController pc) { + if (pc.Selected is TabButton tb) { + View.Window?.MakeFirstResponder (tb); + } + } + } } } diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/MaterialBrushEditorViewController.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/MaterialBrushEditorViewController.cs index 5920c75..a9026f7 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/Custom/MaterialBrushEditorViewController.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/MaterialBrushEditorViewController.cs @@ -16,7 +16,7 @@ namespace Xamarin.PropertyEditing.Mac throw new ArgumentNullException (nameof (hostResources)); this.hostResources = hostResources; - PreferredContentSize = new CGSize (430, 230); + PreferredContentSize = new CGSize (PreferredContentSizeWidth, PreferredContentSizeHeight); } public override void OnPropertyChanged (object sender, PropertyChangedEventArgs e) @@ -65,7 +65,7 @@ namespace Xamarin.PropertyEditing.Mac alphaLabel.Cell.LineBreakMode = NSLineBreakMode.Clipping; alphaStack.AddView (alphaLabel, NSStackViewGravity.Trailing); - alphaStack.AddView (alphaSpinEditor, NSStackViewGravity.Trailing); + alphaStack.AddView (this.alphaSpinEditor, NSStackViewGravity.Trailing); stack.AddView (this.materialEditor, NSStackViewGravity.Leading); stack.AddView (alphaStack, NSStackViewGravity.Trailing); @@ -73,6 +73,15 @@ namespace Xamarin.PropertyEditing.Mac View = stack; } + public override void ViewDidLayout () + { + base.ViewDidLayout (); + + if (this.alphaSpinEditor.NumericEditor.CanBecomeKeyView) { + View.Window?.MakeFirstResponder (this.alphaSpinEditor.NumericEditor); + } + } + private readonly IHostResourceProvider hostResources; private MaterialView materialEditor; diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/MaterialView.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/MaterialView.cs index d65aec1..8d35754 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/Custom/MaterialView.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/MaterialView.cs @@ -13,6 +13,11 @@ namespace Xamarin.PropertyEditing.Mac { internal class MaterialView : NotifyingView { + public override bool AcceptsFirstResponder () + { + return false; + } + public override bool IsFlipped => true; public MaterialView () diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/NotifyingViewController.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/NotifyingViewController.cs index c572a27..e79e46f 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/Custom/NotifyingViewController.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/NotifyingViewController.cs @@ -12,6 +12,9 @@ namespace Xamarin.PropertyEditing.Mac { internal class NotifyingViewController : NSViewController, INotifyingListner where T : NotifyingObject { + internal const int PreferredContentSizeWidth = 430; + internal const int PreferredContentSizeHeight = 230; + internal T ViewModel { get => Adaptor.ViewModel; set => Adaptor.ViewModel = value; diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/NumericSpinEditor.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/NumericSpinEditor.cs index e7ddd5d..831dfff 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/Custom/NumericSpinEditor.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/NumericSpinEditor.cs @@ -224,7 +224,7 @@ namespace Xamarin.PropertyEditing.Mac AddSubview (this.incrementButton); AddSubview (this.decrementButton); - this.AddConstraints (new[] { + AddConstraints (new[] { NSLayoutConstraint.Create (this.numericEditor, NSLayoutAttribute.Left, NSLayoutRelation.Equal, this, NSLayoutAttribute.Left, 1f, 0), NSLayoutConstraint.Create (this.numericEditor, NSLayoutAttribute.Height, NSLayoutRelation.Equal, 1f, 18), diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/NumericTextField.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/NumericTextField.cs index 22211fa..4c215b7 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/Custom/NumericTextField.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/NumericTextField.cs @@ -8,6 +8,8 @@ namespace Xamarin.PropertyEditing.Mac { internal class NumericTextField : PropertyTextField { + public override bool CanBecomeKeyView { get { return Enabled; } } + private NSText CachedCurrentEditor { get; set; } diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/ResourceBrushViewController.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/ResourceBrushViewController.cs index cf73e47..3859c10 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/Custom/ResourceBrushViewController.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/ResourceBrushViewController.cs @@ -6,14 +6,15 @@ using Xamarin.PropertyEditing.ViewModels; namespace Xamarin.PropertyEditing.Mac { - internal class ResourceBrushViewController : NotifyingViewController + internal class ResourceBrushViewController + : NotifyingViewController { private ResourceOutlineView resourceSelector; private readonly ResourceBrushPropertyViewDelegate viewDelegate; public ResourceBrushViewController (IHostResourceProvider hostResources) { - PreferredContentSize = new CGSize (430, 230); + PreferredContentSize = new CGSize (PreferredContentSizeWidth, PreferredContentSizeHeight); this.viewDelegate = new ResourceBrushPropertyViewDelegate (hostResources); } @@ -22,15 +23,15 @@ namespace Xamarin.PropertyEditing.Mac { switch (e.PropertyName) { case nameof (BrushPropertyViewModel.Resource): - if (resource == ViewModel.Resource) + if (this.resource == ViewModel.Resource) return; - resource = ViewModel?.Resource; + this.resource = ViewModel?.Resource; UpdateSelection (); break; case nameof (BrushPropertyViewModel.Solid): - if (resourceSelector != null) - resourceSelector.ViewModel = ViewModel?.ResourceSelector; + if (this.resourceSelector != null) + this.resourceSelector.ViewModel = ViewModel?.ResourceSelector; break; case nameof (BrushPropertyViewModel.Value): break; @@ -39,30 +40,30 @@ namespace Xamarin.PropertyEditing.Mac private void UpdateSelection () { - if (resourceSelector == null) + if (this.resourceSelector == null) return; - var source = resourceSelector.DataSource as ResourceDataSource; + var source = this.resourceSelector.DataSource as ResourceDataSource; if (source == null || ViewModel == null) return; nint index = -1; if (ViewModel.Resource != null && source.TryGetFacade (ViewModel?.Resource, out var facade)) { - index = resourceSelector.RowForItem (facade); + index = this.resourceSelector.RowForItem (facade); } if (index < 0) - resourceSelector.DeselectAll (null); + this.resourceSelector.DeselectAll (null); else - resourceSelector.SelectRow (index, false); + this.resourceSelector.SelectRow (index, false); } public override void OnViewModelChanged (BrushPropertyViewModel oldModel) { base.OnViewModelChanged (oldModel); - if (resourceSelector != null) { - viewDelegate.ViewModel = ViewModel; - resourceSelector.ViewModel = ViewModel?.ResourceSelector; + if (this.resourceSelector != null) { + this.viewDelegate.ViewModel = ViewModel; + this.resourceSelector.ViewModel = ViewModel?.ResourceSelector; } } @@ -73,7 +74,7 @@ namespace Xamarin.PropertyEditing.Mac public override void LoadView () { - viewDelegate.ViewModel = ViewModel; + this.viewDelegate.ViewModel = ViewModel; this.resourceSelector = new ResourceOutlineView { Delegate = viewDelegate, }; @@ -88,7 +89,7 @@ namespace Xamarin.PropertyEditing.Mac View = tableContainer; if (ViewModel != null) { - resourceSelector.ViewModel = ViewModel?.ResourceSelector; + this.resourceSelector.ViewModel = ViewModel?.ResourceSelector; } } diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/ResourceOutlineView.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/ResourceOutlineView.cs index 8428b69..7437ae2 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/Custom/ResourceOutlineView.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/ResourceOutlineView.cs @@ -45,8 +45,7 @@ namespace Xamarin.PropertyEditing.Mac HeaderView = null; } - [Export ("validateProposedFirstResponder:forEvent:")] - public bool validateProposedFirstResponder (NSResponder responder, NSEvent ev) + public override bool ValidateProposedFirstResponder (NSResponder responder, NSEvent forEvent) { return true; } diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/SolidColorBrushEditor.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/SolidColorBrushEditor.cs index 4c1398b..40304bc 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/Custom/SolidColorBrushEditor.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/SolidColorBrushEditor.cs @@ -60,13 +60,13 @@ namespace Xamarin.PropertyEditing.Mac }; Layer = new CALayer (); - Layer.AddSublayer (background); - Layer.AddSublayer (shadeLayer); - Layer.AddSublayer (hueLayer); - Layer.AddSublayer (historyLayer); - Layer.AddSublayer (componentBackground); + Layer.AddSublayer (this.background); + Layer.AddSublayer (this.shadeLayer); + Layer.AddSublayer (this.hueLayer); + Layer.AddSublayer (this.historyLayer); + Layer.AddSublayer (this.componentBackground); WantsLayer = true; - AddSubview (componentTabs.View); + AddSubview (this.componentTabs.View); } public override bool AcceptsFirstResponder () => true; @@ -104,9 +104,9 @@ namespace Xamarin.PropertyEditing.Mac for (var c = hit?.ModelLayer; c != null; c = c.SuperLayer) { var active = c as ColorEditorLayer; if (active != null) { - interaction = new EditorInteraction (ViewModel, active); + this.interaction = new EditorInteraction (ViewModel, active); active.UpdateFromLocation ( - interaction, + this.interaction, Layer.ConvertPointToLayer (location, active)); OnPropertyChanged (ViewModel, new PropertyChangedEventArgs (nameof (SolidBrushViewModel.Color))); return; @@ -124,9 +124,9 @@ namespace Xamarin.PropertyEditing.Mac if (diff.X * diff.X < .5 && diff.Y * diff.Y < .5) return; - interaction?.Layer?.UpdateFromLocation ( - interaction, - Layer.ConvertPointToLayer (location, interaction.Layer)); + this.interaction?.Layer?.UpdateFromLocation ( + this.interaction, + Layer.ConvertPointToLayer (location, this.interaction.Layer)); OnPropertyChanged (ViewModel, new PropertyChangedEventArgs (nameof (SolidBrushViewModel.Color))); } @@ -134,14 +134,15 @@ namespace Xamarin.PropertyEditing.Mac public override void MouseUp (NSEvent theEvent) { base.MouseUp (theEvent); - interaction?.Commit (); - interaction = null; + this.interaction?.Commit (); + this.interaction = null; } private bool modelChanged = true; + public override void OnPropertyChanged (object sender, PropertyChangedEventArgs e) { - var inter = interaction ?? new EditorInteraction (ViewModel, null); + var inter = this.interaction ?? new EditorInteraction (ViewModel, null); switch (e.PropertyName) { case nameof (SolidBrushViewModel.Color): @@ -154,9 +155,9 @@ namespace Xamarin.PropertyEditing.Mac public override void OnViewModelChanged (SolidBrushViewModel oldModel) { base.OnViewModelChanged (oldModel); - var inter = interaction ?? new EditorInteraction (ViewModel, null); + var inter = this.interaction ?? new EditorInteraction (ViewModel, null); - componentTabs.ViewModel = ViewModel; + this.componentTabs.ViewModel = ViewModel; foreach (var editor in Layer.Sublayers.OfType ()) { editor.UpdateFromModel (inter); } @@ -165,7 +166,7 @@ namespace Xamarin.PropertyEditing.Mac public override void Layout () { if (this.modelChanged) { - var interx = interaction ?? new EditorInteraction (ViewModel, null); + var interx = this.interaction ?? new EditorInteraction (ViewModel, null); foreach (var editor in Layer.Sublayers.OfType ()) { editor.UpdateFromModel (interx); } @@ -207,7 +208,7 @@ namespace Xamarin.PropertyEditing.Mac var inset = backgroundFrame.Inset (componentPadding, componentPadding); this.componentTabs.View.Frame = inset; - var inter = interaction ?? new EditorInteraction (ViewModel, null); + var inter = this.interaction ?? new EditorInteraction (ViewModel, null); foreach (var editor in Layer.Sublayers.OfType ()) { editor.UpdateFromModel (inter); } diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/SolidColorBrushEditorViewController.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/SolidColorBrushEditorViewController.cs index dee1962..49d6b0a 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/Custom/SolidColorBrushEditorViewController.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/SolidColorBrushEditorViewController.cs @@ -14,7 +14,7 @@ namespace Xamarin.PropertyEditing.Mac throw new ArgumentNullException (nameof (hostResources)); this.hostResources = hostResources; - PreferredContentSize = new CGSize (430, 230); + PreferredContentSize = new CGSize (PreferredContentSizeWidth, PreferredContentSizeHeight); } public override void OnPropertyChanged (object sender, PropertyChangedEventArgs e) diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/TabButton.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/TabButton.cs index 703e944..6a480b4 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/Custom/TabButton.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/TabButton.cs @@ -5,15 +5,21 @@ using Foundation; namespace Xamarin.PropertyEditing.Mac { + internal interface IUnderliningTabView + { + event EventHandler Clicked; + + bool Selected { get; set; } + int LineWidth { get; set; } + } + internal class TabButton - : FocusableButton + : FocusableButton, IUnderliningTabView { - public TabButton (IHostResourceProvider hostResource, string imageName) + public TabButton (IHostResourceProvider hostResource, string imageName = null) { if (hostResource == null) throw new ArgumentNullException (nameof (hostResource)); - if (imageName == null) - throw new ArgumentNullException (nameof (imageName)); Bordered = false; Action = new ObjCRuntime.Selector (ClickedName); @@ -29,20 +35,55 @@ namespace Xamarin.PropertyEditing.Mac public event EventHandler Clicked; - public bool Selected - { - get { return this.selected; } - set - { + public bool Selected { + get => this.selected; + set { + if (this.selected == value) + return; + this.selected = value; + + TitleColor = this.selected ? NSColor.Text : NSColor.DisabledControlText; NeedsDisplay = true; } } - public override CGSize IntrinsicContentSize - { - get - { + private int lineWidth = 2; + public int LineWidth { + get => this.lineWidth; + set { + if (this.lineWidth == value) + return; + + this.lineWidth = value; + NeedsLayout = true; + } + } + + private NSColor titleColor; + protected NSColor TitleColor { + get => this.titleColor; + private set { + if (this.titleColor == value) + return; + + this.titleColor = value; + + // No point changing the text color if there's nothing to change. + if (!string.IsNullOrEmpty (Title)) { + var coloredTitle = new NSMutableAttributedString (Title); + var titleRange = new NSRange (0, coloredTitle.Length); + coloredTitle.AddAttribute (NSStringAttributeKey.ForegroundColor, this.titleColor, titleRange); + var centeredAttribute = new NSMutableParagraphStyle (); + centeredAttribute.Alignment = NSTextAlignment.Center; + coloredTitle.AddAttribute (NSStringAttributeKey.ParagraphStyle, centeredAttribute, titleRange); + AttributedTitle = coloredTitle; + } + } + } + + public override CGSize IntrinsicContentSize { + get { var size = base.IntrinsicContentSize; return new CGSize (size.Width + 2 + 10, size.Height + 2 + 10); } @@ -62,14 +103,15 @@ namespace Xamarin.PropertyEditing.Mac return; NSBezierPath path = new NSBezierPath (); - path.AppendPathWithRect (new CGRect (Bounds.X, Bounds.Height - 2, Bounds.Width, 2)); - (Selected ? NSColor.Text : NSColor.DisabledControlText).Set (); + path.AppendPathWithRect (new CGRect (Bounds.X, Bounds.Height - this.lineWidth, Bounds.Width, this.lineWidth)); + this.titleColor.Set (); path.Fill (); } private void AppearanceChanged () { - Image = this.hostResource.GetNamedImage (this.imageName); + if (!string.IsNullOrEmpty (this.imageName)) + Image = this.hostResource.GetNamedImage (this.imageName); } private readonly string imageName; @@ -84,4 +126,4 @@ namespace Xamarin.PropertyEditing.Mac Clicked?.Invoke (this, EventArgs.Empty); } } -} +} \ No newline at end of file diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/UnderlinedTabViewController.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/UnderlinedTabViewController.cs index 4911171..4b85c39 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/Custom/UnderlinedTabViewController.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/UnderlinedTabViewController.cs @@ -1,5 +1,6 @@ using System; - +using System.Threading; +using System.Threading.Tasks; using AppKit; using CoreGraphics; using Foundation; @@ -44,7 +45,7 @@ namespace Xamarin.PropertyEditing.Mac public override void InsertTabViewItem (NSTabViewItem tabViewItem, nint index) { - this.tabStack.InsertView (GetView (tabViewItem), (nuint)index, NSStackViewGravity.Leading); + this.tabStack.InsertView (GetView (tabViewItem, index), (nuint)index, NSStackViewGravity.Leading); base.InsertTabViewItem (tabViewItem, index); } @@ -52,6 +53,9 @@ namespace Xamarin.PropertyEditing.Mac { int index = (int)TabView.IndexOf (tabViewItem); NSView tabView = this.tabStack.Views[index]; + if (tabView is TabButton tb) { + tb.Clicked -= OnTabButtonClicked; + } this.tabStack.RemoveView (tabView); tabView.Dispose (); @@ -150,8 +154,10 @@ namespace Xamarin.PropertyEditing.Mac Spacing = 1f, }; - protected NSStackView TabStack => this.tabStack; - + protected NSStackView TabStack => this.tabStack; + + internal IUnderliningTabView Selected { get => this.selected; set => this.selected = value; } + private NSEdgeInsets edgeInsets = new NSEdgeInsets (0, 0, 0, 0); private void UpdatePadding() @@ -178,31 +184,38 @@ namespace Xamarin.PropertyEditing.Mac } this.selected = this.tabStack.Views[index] as IUnderliningTabView; - if (this.selected != null) - this.selected.Selected = true; + if (this.selected != null) + this.selected.Selected = true; } - private NSView GetView (NSTabViewItem item) + private NSView GetView (NSTabViewItem item, nint index) { var id = item.Identifier as NSObjectFacade; - NSView tabView; + TabButton tabButton; if (id != null) { - tabView = new UnderlinedImageView (HostResources, ((string)id.Target)) { - Selected = this.tabStack.Views.Length == SelectedTabViewItemIndex, - ToolTip = item.ToolTip - }; - } else { - tabView = new UnderlinedTextField { - BackgroundColor = NSColor.Clear, - Editable = false, - Bezeled = false, - StringValue = item.Label, - Selected = this.tabStack.Views.Length == SelectedTabViewItemIndex, - ToolTip = item.ToolTip - }; + tabButton = new TabButton (HostResources, (string)id.Target); + } else { + tabButton = new TabButton (HostResources) { + ControlSize = NSControlSize.Mini, + Font = NSFont.SystemFontOfSize (NSFont.SystemFontSizeForControlSize (NSControlSize.Mini)), + Title = item.Label, + }; } - return tabView; + tabButton.Tag = index; + tabButton.Selected = this.tabStack.Views.Length == SelectedTabViewItemIndex; + tabButton.ToolTip = item.ToolTip; + tabButton.Clicked += OnTabButtonClicked; + + return tabButton; + } + + private void OnTabButtonClicked (object sender, EventArgs e) + { + if (sender is TabButton tabButton) { + if (SelectedTabViewItemIndex != tabButton.Tag) + SelectedTabViewItemIndex = tabButton.Tag; + } } } } diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/UnderlinedTextField.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/UnderlinedTextField.cs deleted file mode 100644 index 43d2e83..0000000 --- a/Xamarin.PropertyEditing.Mac/Controls/Custom/UnderlinedTextField.cs +++ /dev/null @@ -1,149 +0,0 @@ -using System; -using AppKit; -using CoreGraphics; - -namespace Xamarin.PropertyEditing.Mac -{ - internal interface IUnderliningTabView { - event EventHandler Clicked; - - bool Selected { get; set; } - int LineWidth { get; set; } - } - - internal class UnderlinedImageView : NSImageView, IUnderliningTabView - { - public UnderlinedImageView (IHostResourceProvider hostResources, string name) - { - if (hostResources == null) - throw new ArgumentNullException (nameof (hostResources)); - - this.hostResources = hostResources; - this.name = name; - } - - public event EventHandler Clicked; - - private bool selected; - public bool Selected - { - get => selected; - set { - if (selected == value && Image != null) - return; - - selected = value; - NeedsDisplay = true; - } - } - - private int lineWidth = 2; - public int LineWidth - { - get => lineWidth; - set { - if (this.lineWidth == value) - return; - - this.lineWidth = value; - NeedsLayout = true; - } - } - - public override void DrawRect (CGRect dirtyRect) - { - Image = this.hostResources.GetNamedImage (this.name + ((Selected) ? "~sel" : String.Empty)); - - base.DrawRect (dirtyRect); - if (!Selected) - return; - - NSBezierPath path = new NSBezierPath (); - path.AppendPathWithRect (new CGRect (Bounds.X, Bounds.Top + this.lineWidth, Bounds.Width, this.lineWidth)); - (Selected ? NSColor.Text: NSColor.DisabledControlText).Set (); - path.Fill (); - } - - public override CGSize IntrinsicContentSize - { - get { - var size = base.IntrinsicContentSize; - return new CGSize (size.Width + this.lineWidth + 10, size.Height + this.lineWidth + 10); - } - } - - public override void MouseDown (NSEvent theEvent) - { - Clicked?.Invoke (this, EventArgs.Empty); - base.MouseDown (theEvent); - } - - private readonly IHostResourceProvider hostResources; - private readonly string name; - } - - internal class UnderlinedTextField : NSTextField, IUnderliningTabView - { - public UnderlinedTextField () - { - TranslatesAutoresizingMaskIntoConstraints = false; - AutoresizingMask = NSViewResizingMask.MaxXMargin; - UsesSingleLineMode = true; - Alignment = NSTextAlignment.Center; - } - - public event EventHandler Clicked; - - private bool selected; - public bool Selected - { - get => this.selected; - set - { - this.selected = value; - TextColor = this.selected ? NSColor.Text : NSColor.DisabledControlText; - - ///NeedsDisplay = true; - } - } - - private int lineWidth = 2; - public int LineWidth { - get =>this.lineWidth; - set { - if (this.lineWidth == value) - return; - - this.lineWidth = value; - NeedsLayout = true; - } - } - - public override void MouseDown (NSEvent theEvent) - { - Clicked?.Invoke (this, EventArgs.Empty); - base.MouseDown (theEvent); - } - - public override void DrawRect (CGRect dirtyRect) - { - base.DrawRect (dirtyRect); - if (!Selected) - return; - - NSBezierPath path = new NSBezierPath (); - path.AppendPathWithRect (new CGRect (Bounds.X, Bounds.Bottom - lineWidth, Bounds.Width, lineWidth)); - TextColor.Set (); - path.Fill (); - } - - public override CGSize IntrinsicContentSize - { - get - { - var size = base.IntrinsicContentSize; - return new CGSize (size.Width, size.Height + lineWidth + 3); - } - } - } -} diff --git a/Xamarin.PropertyEditing.Mac/Controls/RequestResource/RequestResourceView.cs b/Xamarin.PropertyEditing.Mac/Controls/RequestResource/RequestResourceView.cs index 798342e..fdc0060 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/RequestResource/RequestResourceView.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/RequestResource/RequestResourceView.cs @@ -12,8 +12,7 @@ namespace Xamarin.PropertyEditing.Mac { internal class FirstResponderTableView : NSTableView { - [Export ("validateProposedFirstResponder:forEvent:")] - public bool validateProposedFirstResponder (NSResponder responder, NSEvent ev) + public override bool ValidateProposedFirstResponder (NSResponder responder, NSEvent forEvent) { return true; } diff --git a/Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj b/Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj index eb49853..0caef7a 100644 --- a/Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj +++ b/Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj @@ -18,6 +18,9 @@ + + + -- cgit v1.2.3