diff options
author | Vsevolod Kukol <sevoku@microsoft.com> | 2018-09-20 16:28:14 +0300 |
---|---|---|
committer | Vsevolod Kukol <sevoku@microsoft.com> | 2018-09-20 16:28:14 +0300 |
commit | c298febe71b2d3c22ca808e4d36eeb6dc8965548 (patch) | |
tree | 4cd453f901b5a30d9c0da815cbd639d6733994a6 | |
parent | b1a70b2b9e5cc164343112e7a3c2af65a2bebd57 (diff) |
[Mac] TextEntryBackend code improvements
-rw-r--r-- | Xwt.XamMac/Xwt.Mac/SearchTextEntryBackend.cs | 304 | ||||
-rw-r--r-- | Xwt.XamMac/Xwt.Mac/TextEntryBackend.cs | 92 |
2 files changed, 164 insertions, 232 deletions
diff --git a/Xwt.XamMac/Xwt.Mac/SearchTextEntryBackend.cs b/Xwt.XamMac/Xwt.Mac/SearchTextEntryBackend.cs index e0771391..99f14755 100644 --- a/Xwt.XamMac/Xwt.Mac/SearchTextEntryBackend.cs +++ b/Xwt.XamMac/Xwt.Mac/SearchTextEntryBackend.cs @@ -40,224 +40,156 @@ namespace Xwt.Mac ViewObject = new CustomAlignedContainer(EventSink, ApplicationContext, view) { DrawsBackground = false, ExpandVertically = true }; base.Initialize(); } + } - class CustomSearchTextField : NSSearchField, IViewObject - { - ITextEntryEventSink eventSink; - ApplicationContext context; - #pragma warning disable CS0414 // The private field is assigned but its value is never used - CustomCell cell; - #pragma warning disable CS0414 + class CustomSearchTextField : NSSearchField, IViewObject + { + ITextEntryEventSink eventSink; + ApplicationContext context; + #pragma warning disable CS0414 // The private field is assigned but its value is never used + CustomCell cell; + #pragma warning disable CS0414 - public CustomSearchTextField(ITextEntryEventSink eventSink, ApplicationContext context) + public CustomSearchTextField(ITextEntryEventSink eventSink, ApplicationContext context) + { + this.context = context; + this.eventSink = eventSink; + this.Cell = cell = new CustomCell { - this.context = context; - this.eventSink = eventSink; - this.Cell = cell = new CustomCell - { - Bezeled = true, - Editable = true, - EventSink = eventSink, - Context = context, - }; - } + Bezeled = true, + Editable = true, + EventSink = eventSink, + Context = context, + }; + } - public NSView View + public NSView View + { + get { - get - { - return this; - } + return this; } + } - public ViewBackend Backend { get; set; } + public ViewBackend Backend { get; set; } - public override void DidChange(NSNotification notification) + public override void DidChange(NSNotification notification) + { + base.DidChange(notification); + context.InvokeUserCode(delegate { - base.DidChange(notification); - context.InvokeUserCode(delegate - { - eventSink.OnChanged(); - eventSink.OnSelectionChanged(); - }); - } + eventSink.OnChanged(); + eventSink.OnSelectionChanged(); + }); + } - public override string StringValue + public override string StringValue + { + get { return base.StringValue; } + set { - get { return base.StringValue; } - set + if (base.StringValue != value) { - if (base.StringValue != value) + base.StringValue = value; + context.InvokeUserCode(delegate { - base.StringValue = value; - context.InvokeUserCode(delegate - { - eventSink.OnChanged(); - eventSink.OnSelectionChanged(); - }); - } + eventSink.OnChanged(); + eventSink.OnSelectionChanged(); + }); } } + } - class CustomCell : NSSearchFieldCell + class CustomCell : NSSearchFieldCell + { + NSTextView editor; + NSObject selChangeObserver; + public ApplicationContext Context { - CustomEditor editor; - NSObject selChangeObserver; - public ApplicationContext Context - { - get; set; - } + get; set; + } - public ITextEntryEventSink EventSink - { - get; set; - } + public ITextEntryEventSink EventSink + { + get; set; + } - public CustomCell() - { + public CustomCell() + { - } + } - protected CustomCell(IntPtr ptr) : base(ptr) - { - } + protected CustomCell(IntPtr ptr) : base(ptr) + { + } - /// <summary> - /// Like what happens for the ios designer, AppKit can sometimes clone the native `NSTextFieldCell` using the Copy (NSZone) - /// method. We *need* to ensure we can create a new managed wrapper for the cloned native object so we need the IntPtr - /// constructor. NOTE: By keeping this override in managed we ensure the new wrapper C# object is created ~immediately, - /// which makes it easier to debug issues. - /// </summary> - /// <returns>The copy.</returns> - /// <param name="zone">Zone.</param> - public override NSObject Copy(NSZone zone) - { - // Don't remove this override because the comment on this explains why we need this! - var newCell = (CustomCell)base.Copy(zone); - newCell.editor = editor; - newCell.selChangeObserver = selChangeObserver; - newCell.Context = Context; - newCell.EventSink = EventSink; - return newCell; - } + /// <summary> + /// Like what happens for the ios designer, AppKit can sometimes clone the native `NSTextFieldCell` using the Copy (NSZone) + /// method. We *need* to ensure we can create a new managed wrapper for the cloned native object so we need the IntPtr + /// constructor. NOTE: By keeping this override in managed we ensure the new wrapper C# object is created ~immediately, + /// which makes it easier to debug issues. + /// </summary> + /// <returns>The copy.</returns> + /// <param name="zone">Zone.</param> + public override NSObject Copy(NSZone zone) + { + // Don't remove this override because the comment on this explains why we need this! + var newCell = (CustomCell)base.Copy(zone); + newCell.editor = editor; + newCell.selChangeObserver = selChangeObserver; + newCell.Context = Context; + newCell.EventSink = EventSink; + return newCell; + } - public override NSTextView FieldEditorForView(NSView aControlView) + public override NSTextView FieldEditorForView(NSView aControlView) + { + if (editor == null) { - if (editor == null) + editor = new CustomTextFieldCellEditor { - editor = new CustomEditor - { - Context = this.Context, - EventSink = this.EventSink, - FieldEditor = true, - Editable = true, - }; - selChangeObserver = NSNotificationCenter.DefaultCenter.AddObserver(new NSString("NSTextViewDidChangeSelectionNotification"), HandleSelectionDidChange, editor); - } - return editor; - } - - void HandleSelectionDidChange(NSNotification notif) - { - Context.InvokeUserCode(EventSink.OnSelectionChanged); - } - - public override void DrawInteriorWithFrame(CGRect cellFrame, NSView inView) - { - base.DrawInteriorWithFrame(VerticalCenteredRectForBounds(cellFrame), inView); - } - - public override void EditWithFrame(CGRect aRect, NSView inView, NSText editor, NSObject delegateObject, NSEvent theEvent) - { - base.EditWithFrame(VerticalCenteredRectForBounds(aRect), inView, editor, delegateObject, theEvent); - } - - public override void SelectWithFrame(CGRect aRect, NSView inView, NSText editor, NSObject delegateObject, nint selStart, nint selLength) - { - base.SelectWithFrame(VerticalCenteredRectForBounds(aRect), inView, editor, delegateObject, selStart, selLength); - } - - CGRect VerticalCenteredRectForBounds(CGRect aRect) - { - // multiline entries should always align on top - if (!UsesSingleLineMode) - return aRect; - - var textHeight = CellSizeForBounds(aRect).Height; - var offset = (aRect.Height - textHeight) / 2; - if (offset <= 0) // do nothing if the frame is too small - return aRect; - var rect = new Rectangle(aRect.X, aRect.Y, aRect.Width, aRect.Height).Inflate(0.0, -offset); - return rect.ToCGRect(); - } + Context = this.Context, + EventSink = this.EventSink, + FieldEditor = true, + Editable = true, + }; + selChangeObserver = NSNotificationCenter.DefaultCenter.AddObserver(new NSString("NSTextViewDidChangeSelectionNotification"), HandleSelectionDidChange, editor); + } + return editor; } - class CustomEditor : NSTextView + void HandleSelectionDidChange(NSNotification notif) { - public ApplicationContext Context - { - get; set; - } - - public ITextEntryEventSink EventSink - { - get; set; - } - - public CustomEditor() - { - - } + Context.InvokeUserCode(EventSink.OnSelectionChanged); + } - public override void KeyDown(NSEvent theEvent) - { - Context.InvokeUserCode(delegate - { - EventSink.OnKeyPressed(theEvent.ToXwtKeyEventArgs()); - }); - base.KeyDown(theEvent); - } + public override void DrawInteriorWithFrame(CGRect cellFrame, NSView inView) + { + base.DrawInteriorWithFrame(VerticalCenteredRectForBounds(cellFrame), inView); + } - nint cachedCursorPosition; - public override void KeyUp(NSEvent theEvent) - { - if (cachedCursorPosition != SelectedRange.Location) - { - cachedCursorPosition = SelectedRange.Location; - Context.InvokeUserCode(delegate - { - EventSink.OnSelectionChanged(); - EventSink.OnKeyReleased(theEvent.ToXwtKeyEventArgs()); - }); - } - base.KeyUp(theEvent); - } + public override void EditWithFrame(CGRect aRect, NSView inView, NSText editor, NSObject delegateObject, NSEvent theEvent) + { + base.EditWithFrame(VerticalCenteredRectForBounds(aRect), inView, editor, delegateObject, theEvent); + } - public override bool BecomeFirstResponder() - { - var result = base.BecomeFirstResponder(); - if (result) - { - Context.InvokeUserCode(() => - { - EventSink.OnGotFocus(); - }); - } - return result; - } + public override void SelectWithFrame(CGRect aRect, NSView inView, NSText editor, NSObject delegateObject, nint selStart, nint selLength) + { + base.SelectWithFrame(VerticalCenteredRectForBounds(aRect), inView, editor, delegateObject, selStart, selLength); + } - public override bool ResignFirstResponder() - { - var result = base.ResignFirstResponder(); - if (result) - { - Context.InvokeUserCode(() => - { - EventSink.OnLostFocus(); - }); - } - return result; - } + CGRect VerticalCenteredRectForBounds(CGRect aRect) + { + // multiline entries should always align on top + if (!UsesSingleLineMode) + return aRect; + + var textHeight = CellSizeForBounds(aRect).Height; + var offset = (aRect.Height - textHeight) / 2; + if (offset <= 0) // do nothing if the frame is too small + return aRect; + var rect = new Rectangle(aRect.X, aRect.Y, aRect.Width, aRect.Height).Inflate(0.0, -offset); + return rect.ToCGRect(); } } } diff --git a/Xwt.XamMac/Xwt.Mac/TextEntryBackend.cs b/Xwt.XamMac/Xwt.Mac/TextEntryBackend.cs index 81bc7db9..a466ba2c 100644 --- a/Xwt.XamMac/Xwt.Mac/TextEntryBackend.cs +++ b/Xwt.XamMac/Xwt.Mac/TextEntryBackend.cs @@ -341,7 +341,7 @@ namespace Xwt.Mac class CustomCell : NSTextFieldCell { - CustomEditor editor; + NSTextView editor; NSObject selChangeObserver; public ApplicationContext Context { get; set; @@ -382,7 +382,7 @@ namespace Xwt.Mac public override NSTextView FieldEditorForView (NSView aControlView) { if (editor == null) { - editor = new CustomEditor { + editor = new CustomTextFieldCellEditor { Context = this.Context, EventSink = this.EventSink, FieldEditor = true, @@ -427,64 +427,64 @@ namespace Xwt.Mac return rect.ToCGRect (); } } + } - class CustomEditor : NSTextView + class CustomTextFieldCellEditor : NSTextView + { + public ApplicationContext Context { - public ApplicationContext Context { - get; set; - } - - public ITextEntryEventSink EventSink { - get; set; - } + get; set; + } - public CustomEditor () - { + public ITextEntryEventSink EventSink + { + get; set; + } - } + public override void KeyDown(NSEvent theEvent) + { + Context.InvokeUserCode(delegate { + EventSink.OnKeyPressed(theEvent.ToXwtKeyEventArgs()); + }); + base.KeyDown(theEvent); + } - public override void KeyDown (NSEvent theEvent) + nint cachedCursorPosition; + public override void KeyUp(NSEvent theEvent) + { + if (cachedCursorPosition != SelectedRange.Location) { - Context.InvokeUserCode (delegate { - EventSink.OnKeyPressed (theEvent.ToXwtKeyEventArgs ()); + cachedCursorPosition = SelectedRange.Location; + Context.InvokeUserCode(delegate { + EventSink.OnSelectionChanged(); + EventSink.OnKeyReleased(theEvent.ToXwtKeyEventArgs()); }); - base.KeyDown (theEvent); - } - - nint cachedCursorPosition; - public override void KeyUp (NSEvent theEvent) - { - if (cachedCursorPosition != SelectedRange.Location) { - cachedCursorPosition = SelectedRange.Location; - Context.InvokeUserCode (delegate { - EventSink.OnSelectionChanged (); - EventSink.OnKeyReleased (theEvent.ToXwtKeyEventArgs ()); - }); - } - base.KeyUp (theEvent); } + base.KeyUp(theEvent); + } - public override bool BecomeFirstResponder () + public override bool BecomeFirstResponder() + { + var result = base.BecomeFirstResponder(); + if (result) { - var result = base.BecomeFirstResponder (); - if (result) { - Context.InvokeUserCode (() => { - EventSink.OnGotFocus (); - }); - } - return result; + Context.InvokeUserCode(() => { + EventSink.OnGotFocus(); + }); } + return result; + } - public override bool ResignFirstResponder () + public override bool ResignFirstResponder() + { + var result = base.ResignFirstResponder(); + if (result) { - var result = base.ResignFirstResponder (); - if (result) { - Context.InvokeUserCode (() => { - EventSink.OnLostFocus (); - }); - } - return result; + Context.InvokeUserCode(() => { + EventSink.OnLostFocus(); + }); } + return result; } } } |