From 6dce55581a32c9a790e6421f83529e639f90eb87 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Fri, 27 Jan 2017 11:46:40 +0000 Subject: [PATCH] [MacOS] Context actions (#727) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * [MacOS] Add ContextActions * [MacOS] Implement ContextActions --- Xamarin.Forms.Platform.MacOS/Cells/CellNSView.cs | 115 ++++++++++++++++----- .../Cells/NSTableViewCellStyle.cs | 3 +- .../Cells/ViewCellNSView.cs | 9 +- .../Renderers/ListViewRenderer.cs | 2 +- 4 files changed, 98 insertions(+), 31 deletions(-) diff --git a/Xamarin.Forms.Platform.MacOS/Cells/CellNSView.cs b/Xamarin.Forms.Platform.MacOS/Cells/CellNSView.cs index 1ba964e..08043ce 100644 --- a/Xamarin.Forms.Platform.MacOS/Cells/CellNSView.cs +++ b/Xamarin.Forms.Platform.MacOS/Cells/CellNSView.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.ComponentModel; using AppKit; using CoreGraphics; @@ -11,6 +12,7 @@ namespace Xamarin.Forms.Platform.MacOS static readonly CGColor s_defaultHeaderViewsBackground = NSColor.LightGray.CGColor; Cell _cell; readonly NSTableViewCellStyle _style; + NSView _contexActionsTrackingView; public Action PropertyChanged; @@ -29,7 +31,7 @@ namespace Xamarin.Forms.Platform.MacOS public NSView AccessoryView { get; private set; } - public Element Element => Cell; + public virtual Element Element => Cell; public Cell Cell { @@ -92,14 +94,26 @@ namespace Xamarin.Forms.Platform.MacOS nfloat labelHeights = availableHeight; nfloat labelWidth = availableWidth - imageWidth - accessoryViewWidth; - if (!string.IsNullOrEmpty(DetailTextLabel?.StringValue)) + if (DetailTextLabel != null) { - labelHeights = availableHeight / 2; - DetailTextLabel.CenterTextVertically(new CGRect(imageWidth + padding, 0, labelWidth, labelHeights)); + + if (!string.IsNullOrEmpty(DetailTextLabel?.StringValue)) + { + labelHeights = availableHeight / 2; + DetailTextLabel.CenterTextVertically(new CGRect(imageWidth + padding, 0, labelWidth, labelHeights)); + } } - TextLabel.CenterTextVertically(new CGRect(imageWidth + padding, availableHeight - labelHeights, labelWidth, + TextLabel?.CenterTextVertically(new CGRect(imageWidth + padding, availableHeight - labelHeights, labelWidth, labelHeights)); + + var topNSView = Subviews.LastOrDefault(); + if (_contexActionsTrackingView != topNSView) + { + _contexActionsTrackingView.RemoveFromSuperview(); + _contexActionsTrackingView.Frame = Frame; + AddSubview(_contexActionsTrackingView, NSWindowOrderingMode.Above, Subviews.LastOrDefault()); + } base.Layout(); } @@ -129,39 +143,86 @@ namespace Xamarin.Forms.Platform.MacOS void CreateUI() { var style = _style; - - AddSubview(TextLabel = new NSTextField + if (style != NSTableViewCellStyle.Empty) { - Bordered = false, - Selectable = false, - Editable = false, - Font = NSFont.LabelFontOfSize(NSFont.SystemFontSize) - }); - - TextLabel.Cell.BackgroundColor = s_defaultChildViewsBackground; - - if (style == NSTableViewCellStyle.Image || style == NSTableViewCellStyle.Subtitle || - style == NSTableViewCellStyle.ImageSubtitle) - { - AddSubview(DetailTextLabel = new NSTextField + AddSubview(TextLabel = new NSTextField { Bordered = false, Selectable = false, Editable = false, - Font = NSFont.LabelFontOfSize(NSFont.SmallSystemFontSize) + Font = NSFont.LabelFontOfSize(NSFont.SystemFontSize) }); - DetailTextLabel.Cell.BackgroundColor = s_defaultChildViewsBackground; + + TextLabel.Cell.BackgroundColor = s_defaultChildViewsBackground; + + if (style == NSTableViewCellStyle.Image || style == NSTableViewCellStyle.Subtitle || + style == NSTableViewCellStyle.ImageSubtitle) + { + AddSubview(DetailTextLabel = new NSTextField + { + Bordered = false, + Selectable = false, + Editable = false, + Font = NSFont.LabelFontOfSize(NSFont.SmallSystemFontSize) + }); + DetailTextLabel.Cell.BackgroundColor = s_defaultChildViewsBackground; + } + + if (style == NSTableViewCellStyle.Image || style == NSTableViewCellStyle.ImageSubtitle) + AddSubview(ImageView = new NSImageView()); + + if (style == NSTableViewCellStyle.Value1 || style == NSTableViewCellStyle.Value2) + { + var accessoryView = new NSView { WantsLayer = true }; + accessoryView.Layer.BackgroundColor = s_defaultChildViewsBackground.CGColor; + AddSubview(AccessoryView = accessoryView); + } } + AddSubview(_contexActionsTrackingView = new TrackingClickNSView()); + } + } + + class TrackingClickNSView : NSView + { + public override void RightMouseDown(NSEvent theEvent) + { + HandleContextActions(theEvent); - if (style == NSTableViewCellStyle.Image || style == NSTableViewCellStyle.ImageSubtitle) - AddSubview(ImageView = new NSImageView()); + base.RightMouseDown(theEvent); + } - if (style == NSTableViewCellStyle.Value1 || style == NSTableViewCellStyle.Value2) + void HandleContextActions(NSEvent theEvent) + { + var contextActionCell = (Superview as INativeElementView).Element as Cell; + var contextActionsCount = contextActionCell.ContextActions.Count; + if (contextActionsCount > 0) { - var accessoryView = new NSView { WantsLayer = true }; - accessoryView.Layer.BackgroundColor = s_defaultChildViewsBackground.CGColor; - AddSubview(AccessoryView = accessoryView); + NSMenu menu = new NSMenu(); + for (int i = 0; i < contextActionsCount; i++) + { + var contextAction = contextActionCell.ContextActions[i]; + var nsMenuItem = GetNSMenuItem(i, contextAction); + menu.AddItem(nsMenuItem); + } + + NSMenu.PopUpContextMenu(menu, theEvent, this); } } + + static NSMenuItem GetNSMenuItem(int i, MenuItem contextAction) + { + var menuItem = new NSMenuItem(contextAction.Text ?? ""); + menuItem.Tag = i; + menuItem.Enabled = contextAction.IsEnabled; + if (menuItem.Enabled) + menuItem.Activated += (sender, e) => + { + ((IMenuItemController)contextAction).Activate(); + }; + if (!string.IsNullOrEmpty(contextAction.Icon)) + menuItem.Image = new NSImage(contextAction.Icon); + + return menuItem; + } } } \ No newline at end of file diff --git a/Xamarin.Forms.Platform.MacOS/Cells/NSTableViewCellStyle.cs b/Xamarin.Forms.Platform.MacOS/Cells/NSTableViewCellStyle.cs index 3e0235d..72472ea 100644 --- a/Xamarin.Forms.Platform.MacOS/Cells/NSTableViewCellStyle.cs +++ b/Xamarin.Forms.Platform.MacOS/Cells/NSTableViewCellStyle.cs @@ -7,6 +7,7 @@ Value2, Subtitle, Image, - ImageSubtitle + ImageSubtitle, + Empty } } \ No newline at end of file diff --git a/Xamarin.Forms.Platform.MacOS/Cells/ViewCellNSView.cs b/Xamarin.Forms.Platform.MacOS/Cells/ViewCellNSView.cs index 0dd766a..6b342c2 100644 --- a/Xamarin.Forms.Platform.MacOS/Cells/ViewCellNSView.cs +++ b/Xamarin.Forms.Platform.MacOS/Cells/ViewCellNSView.cs @@ -4,13 +4,18 @@ using RectangleF = CoreGraphics.CGRect; namespace Xamarin.Forms.Platform.MacOS { - public class ViewCellNSView : NSView, INativeElementView + internal class ViewCellNSView : CellNSView { + public ViewCellNSView() : base(NSTableViewCellStyle.Empty) + { + + } + WeakReference _rendererRef; ViewCell _viewCell; - public Element Element => ViewCell; + public override Element Element => ViewCell; public ViewCell ViewCell { diff --git a/Xamarin.Forms.Platform.MacOS/Renderers/ListViewRenderer.cs b/Xamarin.Forms.Platform.MacOS/Renderers/ListViewRenderer.cs index 08265b3..2c80dec 100644 --- a/Xamarin.Forms.Platform.MacOS/Renderers/ListViewRenderer.cs +++ b/Xamarin.Forms.Platform.MacOS/Renderers/ListViewRenderer.cs @@ -20,7 +20,7 @@ namespace Xamarin.Forms.Platform.MacOS ITemplatedItemsView TemplatedItemsView => Element; - public const int DefaultRowHeight = 16; + public const int DefaultRowHeight = 44; public NSTableView NativeTableView => _table; -- 2.7.4