mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-23 07:00:46 +00:00
Merge pull request #112 from gnustep/NSPopover_branch
This commit is contained in:
commit
23f8529b19
4 changed files with 239 additions and 29 deletions
13
ChangeLog
13
ChangeLog
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue