More improvements to the Mac OS X TextField.Invalid() popover.

This commit is contained in:
Pietro Gagliardi 2014-08-27 16:01:47 -04:00
parent 7a83e3b577
commit 554c67371f
3 changed files with 41 additions and 11 deletions

View File

@ -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)

View File

@ -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

View File

@ -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];
}];
}