mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-22 13:10:59 +00:00
Add code to dismiss popover if another window issmade key. Minor corrections to GSToolTips.m so that it uses the RELEASE/AUTORELEASE macros.
This commit is contained in:
parent
166ea25ef0
commit
87e30f8514
4 changed files with 203 additions and 35 deletions
|
@ -1,3 +1,10 @@
|
|||
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
|
||||
|
|
|
@ -60,7 +60,7 @@ enum {
|
|||
typedef NSInteger NSPopoverBehavior;
|
||||
|
||||
/* Forward declarations */
|
||||
@class NSViewController, NSWindow, NSView, NSNotification;
|
||||
@class NSViewController, NSPanel, NSView, NSNotification;
|
||||
@protocol NSPopoverDelegate;
|
||||
|
||||
/* Class */
|
||||
|
@ -75,7 +75,7 @@ typedef NSInteger NSPopoverBehavior;
|
|||
NSRect _positioningRect;
|
||||
BOOL _shown;
|
||||
|
||||
NSWindow *_realWindow;
|
||||
NSPanel *_realPanel;
|
||||
}
|
||||
|
||||
/* Properties */
|
||||
|
|
|
@ -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,62 +34,195 @@
|
|||
#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 window
|
||||
// Popover private classes
|
||||
|
||||
@interface GSPopoverWindow : NSWindow
|
||||
@interface GSPopoverView : NSView
|
||||
{
|
||||
NSView *_contentView;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation GSPopoverWindow : NSWindow
|
||||
@implementation GSPopoverView
|
||||
|
||||
- (instancetype) initWithFrame: (NSRect)frame
|
||||
{
|
||||
self = [super initWithFrame: frame];
|
||||
if (self)
|
||||
{
|
||||
[self setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) setContentView: (NSView *)view
|
||||
{
|
||||
if (view != nil)
|
||||
{
|
||||
ASSIGN(_contentView, view);
|
||||
[_contentView setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
|
||||
[self addSubview: _contentView];
|
||||
}
|
||||
else
|
||||
{
|
||||
[_contentView removeFromSuperview];
|
||||
}
|
||||
}
|
||||
|
||||
- (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 */
|
||||
|
||||
/**
|
||||
* Sets the animate flag. If YES then the popover will animate when it appears or disappears.
|
||||
*/
|
||||
- (void) setAnimates: (BOOL)flag
|
||||
{
|
||||
_animates = flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current value of the animate flag.
|
||||
*/
|
||||
- (BOOL) animates
|
||||
{
|
||||
return _animates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets ths appearance of the popover. Minimal is the default. HUD is not supported.
|
||||
*/
|
||||
- (void) setAppearance: (NSPopoverAppearance)value
|
||||
{
|
||||
_appearance = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current appearance setting.
|
||||
*/
|
||||
- (NSPopoverAppearance) appearance
|
||||
{
|
||||
return _appearance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets current popup behavior. Valid settings are:
|
||||
* NSPopupBehaviorApplicationDefined, NSPopupBehaviorTransient,
|
||||
* NSPopupBehaviorSemiTransient.
|
||||
*/
|
||||
- (void) setBehavior: (NSPopoverBehavior)value
|
||||
{
|
||||
_behavior = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current behavior setting
|
||||
*/
|
||||
- (NSPopoverBehavior) behavior
|
||||
{
|
||||
return _behavior;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts an NSSize value for the current content size.
|
||||
*/
|
||||
- (void) setContentSize: (NSSize)value
|
||||
{
|
||||
_contentSize = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an NSSize representing the size of the NSPopover content view.
|
||||
*/
|
||||
- (NSSize) contentSize
|
||||
{
|
||||
return _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
|
||||
{
|
||||
if ([NSStoryboard mainStoryboard] == nil)
|
||||
|
@ -114,49 +247,77 @@
|
|||
ASSIGN(_contentViewController, controller);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current contentViewController.
|
||||
*/
|
||||
- (NSViewController *) contentViewController
|
||||
{
|
||||
return _contentViewController;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set delegate
|
||||
*/
|
||||
- (void) setDelegate: (id)value
|
||||
{
|
||||
_delegate = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return delegate
|
||||
*/
|
||||
- (id) delegate
|
||||
{
|
||||
return _delegate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set relative position of the popup to the view it is associated with.
|
||||
*/
|
||||
- (void) setPositioningRect: (NSRect)value
|
||||
{
|
||||
_positioningRect = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the NSRect.
|
||||
*/
|
||||
- (NSRect) positioningRect
|
||||
{
|
||||
return _positioningRect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the popover being shown.
|
||||
*/
|
||||
- (BOOL) isShown
|
||||
{
|
||||
return _shown;
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
/**
|
||||
* Close the popover.
|
||||
*/
|
||||
- (void) close
|
||||
{
|
||||
[_realWindow close];
|
||||
[_realWindow setDelegate:nil];
|
||||
[_realPanel close];
|
||||
[_realPanel setDelegate:nil];
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the popover.
|
||||
*/
|
||||
- (IBAction) performClose: (id)sender
|
||||
{
|
||||
[_realWindow performClose:sender];
|
||||
[_realWindow setDelegate:nil];
|
||||
[_realPanel performClose:sender];
|
||||
[_realPanel setDelegate:nil];
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the popover relative to the specified rect on the edge specified.
|
||||
*/
|
||||
- (void) showRelativeToRect: (NSRect)positioningRect
|
||||
ofView: (NSView *)positioningView
|
||||
preferredEdge: (NSRectEdge)preferredEdge
|
||||
|
@ -170,19 +331,24 @@
|
|||
view = [_contentViewController view];
|
||||
viewFrame = [view frame];
|
||||
|
||||
if (!_realWindow)
|
||||
if (!_realPanel)
|
||||
{
|
||||
_realWindow = [[GSPopoverWindow alloc] initWithContentRect: viewFrame
|
||||
styleMask: NSBorderlessWindowMask
|
||||
backing: NSBackingStoreRetained
|
||||
defer: NO];
|
||||
_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];
|
||||
}
|
||||
|
||||
[_realWindow setDelegate: self];
|
||||
[_realWindow setBackgroundColor: [NSColor darkGrayColor]];
|
||||
|
||||
screenRect = [[positioningView window] convertRectToScreen:positioningRect];
|
||||
windowFrame = [_realWindow frame];
|
||||
windowFrame = [_realPanel frame];
|
||||
windowFrame.origin = screenRect.origin;
|
||||
|
||||
if(NSMinXEdge == preferredEdge)
|
||||
|
@ -202,14 +368,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 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
|
||||
|
@ -231,11 +396,6 @@
|
|||
userInfo:nil];
|
||||
}
|
||||
|
||||
- (void) windowDidResignMain: (NSNotification *)notification
|
||||
{
|
||||
[_realWindow close];
|
||||
}
|
||||
|
||||
- (id) initWithCoder: (NSCoder *)coder
|
||||
{
|
||||
if (nil != (self = [super initWithCoder:coder]))
|
||||
|
@ -284,4 +444,5 @@
|
|||
[coder encodeObject:_contentViewController];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Loading…
Reference in a new issue