Merge pull request #112 from gnustep/NSPopover_branch

This commit is contained in:
Gregory Casamento 2021-10-03 05:22:52 -04:00 committed by GitHub
commit 23f8529b19
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 239 additions and 29 deletions

View file

@ -1,3 +1,16 @@
2021-10-02 Gregory John Casamento <greg.casamento@gmail.com>
* Source/GSToolTips.m: Use RELEASE and AUTORELEASE macros where
appropriate. Minor fixes.
* Source/NSPopover.m: Add code to draw an outline outside of the
view. Add GSPopoverPanel and GSPopoverView private classes.
2021-09-30 Gregory John Casamento <greg.casamento@gmail.com>
* Source/NSPopover.m: Fix an issue with NSPopover loading the
model (nib/xib/gorm) when it is loaded by a setContentViewController:
in an non-storyboard based application.
2021-09-29 Gregory John Casamento <greg.casamento@gmail.com>
* TextConverters/RTF/RTFConsumer.m: Improve error message for

View file

@ -60,7 +60,7 @@ enum {
typedef NSInteger NSPopoverBehavior;
/* Forward declarations */
@class NSViewController, NSWindow, NSView, NSNotification;
@class NSViewController, NSPanel, NSView, NSNotification;
@protocol NSPopoverDelegate;
/* Class */
@ -75,29 +75,108 @@ typedef NSInteger NSPopoverBehavior;
NSRect _positioningRect;
BOOL _shown;
NSWindow *_realWindow;
NSPanel *_realPanel;
}
/* Properties */
/**
* Sets the animate flag. If YES then the popover will animate when it appears or disappears.
*/
- (void)setAnimates:(BOOL)flag;
/**
* Returns current value of the animate flag.
*/
- (BOOL)animates;
/**
* Sets ths appearance of the popover. Minimal is the default. HUD is not supported.
*/
- (void)setAppearance: (NSPopoverAppearance)value;
/**
* Returns the current appearance setting.
*/
- (NSPopoverAppearance)appearance;
/**
* Sets current popup behavior. Valid settings are:
* NSPopupBehaviorApplicationDefined, NSPopupBehaviorTransient,
* NSPopupBehaviorSemiTransient.
*/
- (void)setBehavior:(NSPopoverBehavior)value;
/**
* Returns current behavior setting
*/
- (NSPopoverBehavior)behavior;
/**
* Accepts an NSSize value for the current content size.
*/
- (void)setContentSize:(NSSize)value;
/**
* Returns an NSSize representing the size of the NSPopover content view.
*/
- (NSSize)contentSize;
/**
* Sets the contentViewController. If in a storyboard this is automatically set
* but if this is in a model that is NOT a storyboard (nib, xib, gorm, etc) then there must be
* a model with the same name as the class name of the contentViewController. Also,
* This model must have the "view" outlet set to the view that will be shown
* in the popup, if both of these conditions are not met, then the code will
* throw an NSInternalInconsistency exception to report the issue back to the
* user.
*/
- (void)setContentViewController:(NSViewController *)controller;
/**
* Returns the current contentViewController.
*/
- (NSViewController *)contentViewController;
/**
* Set delegate
*/
- (void)setDelegate:(id)value;
/**
* Return delegate
*/
- (id)delegate;
/**
* Set relative position of the popup to the view it is associated with.
*/
- (void)setPositioningRect:(NSRect)value;
/**
* Return the NSRect.
*/
- (NSRect)positioningRect;
/**
* Is the popover being shown.
*/
- (BOOL)isShown;
/* Methods */
/**
* Close the popover.
*/
- (void)close;
/**
* Close the popover as an IBAction.
*/
- (IBAction)performClose:(id)sender;
/**
* Show the popover relative to the specified rect on the edge specified.
*/
- (void)showRelativeToRect:(NSRect)positioningRect
ofView:(NSView *)positioningView
preferredEdge:(NSRectEdge)preferredEdge;

View file

@ -174,7 +174,7 @@
- (id) initWithContentRect: (NSRect)contentRect
styleMask: (NSUInteger)aStyle
backing: (NSBackingStoreType)bufferingType
defer: (BOOL)flag;
defer: (BOOL)flag
{
self = [super initWithContentRect: contentRect
styleMask: aStyle
@ -182,7 +182,7 @@
defer: flag];
if (self)
{
[self setContentView: [[[GSTTView alloc] initWithFrame: contentRect] autorelease]];
[self setContentView: AUTORELEASE([[GSTTView alloc] initWithFrame: contentRect])];
}
return self;
}
@ -452,7 +452,7 @@ static BOOL restoreMouseMoved;
{
((NSViewPtr)view)->_rFlags.has_trkrects = 0;
}
[indexes release];
RELEASE(indexes);
}
- (void) removeToolTip: (NSToolTipTag)tag

View file

@ -34,13 +34,104 @@
#import "AppKit/NSPopover.h"
#import "AppKit/NSViewController.h"
#import "AppKit/NSView.h"
#import "AppKit/NSWindow.h"
#import "AppKit/NSPanel.h"
#import "AppKit/NSNibLoading.h"
#import "AppKit/NSStoryboard.h"
#import "AppKit/NSGraphics.h"
// Popover private classes
@interface GSPopoverView : NSView
@end
@implementation GSPopoverView
- (instancetype) initWithFrame: (NSRect)frame
{
self = [super initWithFrame: frame];
if (self)
{
[self setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
}
return self;
}
- (void) drawRect: (NSRect)dirtyRect
{
NSRectEdge sides[] = {NSMinXEdge, NSMaxYEdge, NSMaxXEdge, NSMinYEdge};
NSColor *black = [NSColor blackColor];
NSColor *white = [NSColor whiteColor];
NSColor *colors[] = {white, white, black, black};
NSRect bounds = [self bounds];
[super drawRect: dirtyRect];
NSDrawColorTiledRects(bounds, bounds, sides, colors, 4);
}
@end
@interface GSPopoverPanel : NSPanel
@end
@implementation GSPopoverPanel
- (id) initWithContentRect: (NSRect)contentRect
styleMask: (NSUInteger)aStyle
backing: (NSBackingStoreType)bufferingType
defer: (BOOL)flag
{
self = [super initWithContentRect: contentRect
styleMask: aStyle
backing: bufferingType
defer: flag];
if (self)
{
[super setContentView: AUTORELEASE([[GSPopoverView alloc]
initWithFrame: contentRect])];
}
return self;
}
- (void) orderOut: (id)sender
{
[super orderOut: sender];
[self close];
}
- (BOOL) canBecomeKeyWindow
{
return NO;
}
- (BOOL) canBecomeMainWindow
{
return NO;
}
- (void) setContentView: (NSView *)view
{
[[super contentView] addSubview: view];
}
- (NSView *) contentView
{
NSArray *subviews = [[super contentView] subviews];
if ([subviews count] == 0)
{
return nil;
}
return [subviews objectAtIndex: 0];
}
@end
/* Class */
@implementation NSPopover
/* Properties */
- (void) setAnimates: (BOOL)flag
{
_animates = flag;
@ -83,6 +174,25 @@
- (void) setContentViewController: (NSViewController *)controller
{
if ([NSStoryboard mainStoryboard] == nil)
{
NSString *controllerClassName = NSStringFromClass([controller class]);
BOOL loaded = [NSBundle loadNibNamed: controllerClassName
owner: controller];
if (!loaded)
{
[NSException raise: NSInternalInconsistencyException
format: @"Could not load controller %@", controllerClassName];
}
else
{
if ([controller view] == nil)
{
[NSException raise: NSInternalInconsistencyException
format: @"Loaded controller named %@, but view is not set", controllerClassName];
}
}
}
ASSIGN(_contentViewController, controller);
}
@ -117,16 +227,17 @@
}
/* Methods */
- (void) close
{
[_realWindow close];
[_realWindow setDelegate:nil];
[_realPanel close];
[_realPanel setDelegate:nil];
}
- (IBAction) performClose: (id)sender
{
[_realWindow performClose:sender];
[_realWindow setDelegate:nil];
[_realPanel performClose:sender];
[_realPanel setDelegate:nil];
}
- (void) showRelativeToRect: (NSRect)positioningRect
@ -137,18 +248,29 @@
NSRect screenRect;
NSRect windowFrame;
NSRect viewFrame;
[_contentViewController loadView];
view = [_contentViewController view];
viewFrame = [view frame];
_realWindow = [[NSWindow alloc] initWithContentRect: viewFrame
styleMask: NSBorderlessWindowMask
backing: NSBackingStoreRetained
defer: NO];
if (!_realPanel)
{
_realPanel = [[GSPopoverPanel alloc] initWithContentRect: viewFrame
styleMask: NSBorderlessWindowMask
backing: NSBackingStoreRetained
defer: NO];
[_realPanel setBackgroundColor: [NSColor darkGrayColor]];
[_realPanel setReleasedWhenClosed: YES];
[_realPanel setExcludedFromWindowsMenu: YES];
[_realPanel setLevel: NSPopUpMenuWindowLevel];
[_realPanel setAutodisplay: NO];
[_realPanel setDelegate: self];
[_realPanel setContentView: view];
}
screenRect = [[positioningView window] convertRectToScreen:positioningRect];
windowFrame = [_realWindow frame];
windowFrame = [_realPanel frame];
windowFrame.origin = screenRect.origin;
if(NSMinXEdge == preferredEdge)
@ -168,18 +290,13 @@
windowFrame.origin.x += viewFrame.size.width;
}
[_realWindow setFrame: windowFrame display: YES];
NSLog(@"Showing relative to in window %@",NSStringFromRect(positioningRect));
NSLog(@"Showing relative to in screen %@",NSStringFromRect(screenRect));
// [_realWindow setBackgroundColor:[NSColor clearColor]];
// [_realWindow setOpaque:NO];
// [_realWindow setLevel:NSFloatingWindowLevel];
// [_realWindow setAlphaValue:0.0];
[[_realWindow contentView] addSubview: view];
[_realWindow setDelegate: self];
[_realWindow makeKeyAndOrderFront:self];
[_realPanel setFrame: windowFrame display: YES];
[_realPanel makeKeyAndOrderFront:self];
NSDebugLog(@"Showing relative to in window %@",NSStringFromRect(positioningRect));
NSDebugLog(@"Showing relative to in screen %@",NSStringFromRect(screenRect));
_shown = YES;
}
- (BOOL) windowShouldClose: (id)sender
@ -249,4 +366,5 @@
[coder encodeObject:_contentViewController];
}
}
@end