From 554c67371fb4b5ae774bd5f0bd78e383dc8cc288 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Wed, 27 Aug 2014 16:01:47 -0400 Subject: [PATCH] More improvements to the Mac OS X TextField.Invalid() popover. --- redo/basicctrls_darwin.m | 4 +-- redo/textfield_darwin.go | 1 - redo/warningpopover_darwin.m | 47 ++++++++++++++++++++++++++++++------ 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/redo/basicctrls_darwin.m b/redo/basicctrls_darwin.m index 8ec7f57..e0e5f75 100644 --- a/redo/basicctrls_darwin.m +++ b/redo/basicctrls_darwin.m @@ -178,8 +178,8 @@ id textfieldOpenInvalidPopover(id textfield, char *reason) void textfieldCloseInvalidPopover(id popover) { - [toNSWindow(popover) orderOut:toNSWindow(popover)]; - [toNSWindow(popover) release]; + [toNSWindow(popover) close]; + // don't release; close does that already } id newLabel(void) diff --git a/redo/textfield_darwin.go b/redo/textfield_darwin.go index b1242f7..5c52a38 100644 --- a/redo/textfield_darwin.go +++ b/redo/textfield_darwin.go @@ -47,7 +47,6 @@ func (t *textfield) OnChanged(f func()) { } func (t *textfield) Invalid(reason string) { - // TODO disable animations if reason is still valid if t.invalid != nil { C.textfieldCloseInvalidPopover(t.invalid) t.invalid = nil diff --git a/redo/warningpopover_darwin.m b/redo/warningpopover_darwin.m index f3c9672..f204426 100644 --- a/redo/warningpopover_darwin.m +++ b/redo/warningpopover_darwin.m @@ -7,13 +7,11 @@ // NSPopovers are intended for interactive content, and Apple seems to be diligent in enforcing this rule, as the known techniques for preventing a NSPopover from stealing focus no longer work in 10.9. // Let's just fake it with a window. -// TODO -// - doesn't get hidden properly when asked to order out -// - doesn't get hidden when changing first responders -// - doesn't get hidden when switching between programs/shown again -// - doesn't animate or have a transparent background; probably should - -@interface goWarningPopover : NSWindow +@interface goWarningPopover : NSWindow { +@public + id onBegin; + id onEnd; +} @end @implementation goWarningPopover @@ -30,9 +28,26 @@ [self setExcludedFromWindowsMenu:YES]; [self setMovableByWindowBackground:NO]; [self setLevel:NSPopUpMenuWindowLevel]; + [self setHidesOnDeactivate:YES]; + self->onBegin = nil; + self->onEnd = nil; return self; } +- (void)close +{ + NSLog(@"disposing"); + if (self->onBegin != nil) { + [[NSNotificationCenter defaultCenter] removeObserver:self->onBegin]; + self->onBegin = nil; + } + if (self->onEnd != nil) { + [[NSNotificationCenter defaultCenter] removeObserver:self->onEnd]; + self->onEnd = nil; + } + [super close]; +} + - (BOOL)canBecomeKeyWindow { return NO; @@ -122,8 +137,24 @@ void warningPopoverShow(id popover, id control) NSRect vr; NSPoint vo; - vr = [v convertRect:[v frame] toView:nil]; + // note that the frame is a rect of the superview + vr = [[v superview] convertRect:[v frame] toView:nil]; vo = [[v window] convertRectToScreen:vr].origin; [p setFrameOrigin:NSMakePoint(vo.x, vo.y - [p frame].size.height)]; [p orderFront:p]; + + // auto-show/hide when control gains/loses focus + // TODO this notification is only sent when a character is pressed + p->onBegin = [[NSNotificationCenter defaultCenter] addObserverForName:NSControlTextDidBeginEditingNotification + object:v + queue:nil + usingBlock:^(NSNotification *note){ + [p orderFront:p]; + }]; + p->onEnd = [[NSNotificationCenter defaultCenter] addObserverForName:NSControlTextDidEndEditingNotification + object:v + queue:nil + usingBlock:^(NSNotification *note){ + [p orderOut:p]; + }]; }