Merge pull request #204 from gnustep/NSPopover_issue203

This commit is contained in:
Gregory Casamento 2023-10-09 04:42:46 -04:00 committed by GitHub
commit 090ac31ca3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 206 additions and 144 deletions

View file

@ -45,11 +45,14 @@ APPKIT_EXPORT_CLASS
id _sourceController;
id _destinationController;
NSStoryboardSegueIdentifier _identifier;
NSString *_kind;
NSString *_relationship;
id _popoverAnchorView;
NSPopoverBehavior _popoverBehavior;
NSPopover *_popover;
NSRectEdge _preferredEdge;
GSStoryboardSeguePerformHandler _handler;
}

View file

@ -91,6 +91,17 @@ APPKIT_EXPORT_CLASS
- (void) viewWillLoad;
- (void) viewDidLoad;
- (void) viewWillAppear: (BOOL)animated;
- (void) viewIsAppearing: (BOOL)animated;
- (void) viewDidAppear: (BOOL)animated;
- (void) viewWillDisappear: (BOOL)animated;
- (void) viewDidDisappear: (BOOL)animated;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_10, GS_API_LATEST)
- (void) dismissViewController: (NSViewController *)viewController;
- (void) dismissController: (id)sender;
#endif
@end
#endif // OS_API_VERSION

View file

@ -22,8 +22,8 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
@ -76,18 +76,19 @@
@implementation GSPopoverPanel
- (id) initWithContentRect: (NSRect)contentRect
styleMask: (NSUInteger)aStyle
backing: (NSBackingStoreType)bufferingType
defer: (BOOL)flag
styleMask: (NSUInteger)aStyle
backing: (NSBackingStoreType)bufferingType
defer: (BOOL)flag
{
self = [super initWithContentRect: contentRect
styleMask: aStyle
backing: bufferingType
defer: flag];
styleMask: aStyle
backing: bufferingType
defer: flag];
if (self)
{
[super setContentView: AUTORELEASE([[GSPopoverView alloc]
initWithFrame: contentRect])];
initWithFrame: contentRect])];
[self setReleasedWhenClosed: YES];
}
return self;
}
@ -98,12 +99,12 @@
[self close];
}
- (BOOL) canBecomeKeyWindow
- (BOOL) canBecomeKeyWindow
{
return NO;
}
- (BOOL) canBecomeMainWindow
- (BOOL) canBecomeMainWindow
{
return NO;
}
@ -121,7 +122,7 @@
{
return nil;
}
return [subviews objectAtIndex: 0];
}
@ -180,18 +181,18 @@
BOOL loaded = [NSBundle loadNibNamed: controllerClassName
owner: controller];
if (!loaded)
{
[NSException raise: NSInternalInconsistencyException
format: @"Could not load controller %@", controllerClassName];
}
{
[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];
}
}
{
if ([controller view] == nil)
{
[NSException raise: NSInternalInconsistencyException
format: @"Loaded controller named %@, but view is not set", controllerClassName];
}
}
}
ASSIGN(_contentViewController, controller);
}
@ -231,24 +232,24 @@
- (void) close
{
[_realPanel close];
[_realPanel setDelegate:nil];
_shown = NO;
}
- (IBAction) performClose: (id)sender
{
[_realPanel performClose:sender];
[_realPanel setDelegate:nil];
[_realPanel performClose: sender];
_shown = NO;
}
- (void) showRelativeToRect: (NSRect)positioningRect
ofView: (NSView *)positioningView
preferredEdge: (NSRectEdge)preferredEdge
ofView: (NSView *)positioningView
preferredEdge: (NSRectEdge)preferredEdge
{
NSView *view = nil;
NSRect screenRect;
NSRect windowFrame;
NSRect viewFrame;
[_contentViewController loadView];
view = [_contentViewController view];
viewFrame = [view frame];
@ -259,7 +260,7 @@
styleMask: NSBorderlessWindowMask
backing: NSBackingStoreRetained
defer: NO];
[_realPanel setBackgroundColor: [NSColor darkGrayColor]];
[_realPanel setReleasedWhenClosed: YES];
[_realPanel setExcludedFromWindowsMenu: YES];
@ -268,7 +269,7 @@
[_realPanel setDelegate: self];
[_realPanel setContentView: view];
}
screenRect = [[positioningView window] convertRectToScreen:positioningRect];
windowFrame = [_realPanel frame];
windowFrame.origin = screenRect.origin;
@ -292,10 +293,10 @@
[_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;
}
@ -364,7 +365,7 @@
[coder encodeValueOfObjCType: @encode(CGFloat) at: &_contentSize.width];
[coder encodeValueOfObjCType: @encode(CGFloat) at: &_contentSize.height];
[coder encodeObject:_contentViewController];
}
}
}
@end

View file

@ -1,21 +1,21 @@
/* Implementation of class NSStoryboardSegue
Copyright (C) 2020 Free Software Foundation, Inc.
By: Gregory Casamento
Date: Mon Jan 20 15:57:31 EST 2020
This file is part of the GNUstep Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
@ -71,23 +71,23 @@
_sourceController = controller;
}
+ (instancetype) segueWithIdentifier: (NSStoryboardSegueIdentifier)identifier
source: (id)sourceController
destination: (id)destinationController
performHandler: (GSStoryboardSeguePerformHandler)performHandler
+ (instancetype) segueWithIdentifier: (NSStoryboardSegueIdentifier)identifier
source: (id)sourceController
destination: (id)destinationController
performHandler: (GSStoryboardSeguePerformHandler)performHandler
{
NSStoryboardSegue *segue = [[NSStoryboardSegue alloc] initWithIdentifier: identifier
source: sourceController
destination: destinationController];
source: sourceController
destination: destinationController];
AUTORELEASE(segue);
[segue _setHandler: performHandler];
return segue;
}
- (instancetype) initWithIdentifier: (NSStoryboardSegueIdentifier)identifier
source: (id)sourceController
destination: (id)destinationController
- (instancetype) initWithIdentifier: (NSStoryboardSegueIdentifier)identifier
source: (id)sourceController
destination: (id)destinationController
{
self = [super init];
if (self != nil)
@ -116,41 +116,41 @@
if ([_kind isEqualToString: @"relationship"])
{
if ([_relationship isEqualToString: @"window.shadowedContentViewController"])
{
NSWindow *w = [_sourceController window];
NSView *v = [_destinationController view];
[w setContentView: v];
[w setTitle: [_destinationController title]];
[_sourceController showWindow: self];
}
{
NSWindow *w = [_sourceController window];
NSView *v = [_destinationController view];
[w setContentView: v];
[w setTitle: [_destinationController title]];
[_sourceController showWindow: self];
}
else if ([_relationship isEqualToString: @"splitItems"])
{
NSView *v = [_destinationController view];
NSSplitViewController *svc = (NSSplitViewController *)_sourceController;
[[svc splitView] addSubview: v];
NSUInteger idx = [[[svc splitView] subviews] count] - 1;
NSSplitViewItem *item = [[svc splitViewItems] objectAtIndex: idx];
[item setViewController: _destinationController];
}
{
NSView *v = [_destinationController view];
NSSplitViewController *svc = (NSSplitViewController *)_sourceController;
[[svc splitView] addSubview: v];
NSUInteger idx = [[[svc splitView] subviews] count] - 1;
NSSplitViewItem *item = [[svc splitViewItems] objectAtIndex: idx];
[item setViewController: _destinationController];
}
else if ([_relationship isEqualToString: @"tabItems"])
{
NSTabViewController *tvc = (NSTabViewController *)_sourceController;
NSTabViewItem *item = [NSTabViewItem tabViewItemWithViewController: _destinationController];
[tvc addTabViewItem: item];
}
{
NSTabViewController *tvc = (NSTabViewController *)_sourceController;
NSTabViewItem *item = [NSTabViewItem tabViewItemWithViewController: _destinationController];
[tvc addTabViewItem: item];
}
}
else if ([_kind isEqualToString: @"modal"])
{
NSWindow *w = nil;
if ([_destinationController isKindOfClass: [NSWindowController class]])
{
w = [_destinationController window];
}
{
w = [_destinationController window];
}
else
{
w = [NSWindow windowWithContentViewController: _destinationController];
[w setTitle: [_destinationController title]];
}
{
w = [NSWindow windowWithContentViewController: _destinationController];
[w setTitle: [_destinationController title]];
}
RETAIN(w);
[w center];
[NSApp runModalForWindow: w];
@ -158,28 +158,42 @@
else if ([_kind isEqualToString: @"show"])
{
if ([_destinationController isKindOfClass: [NSWindowController class]])
{
[_destinationController showWindow: _sourceController];
}
{
[_destinationController showWindow: _sourceController];
}
else
{
NSWindow *w = [NSWindow windowWithContentViewController: _destinationController];
[w setTitle: [_destinationController title]];
[w center];
[w orderFrontRegardless];
RETAIN(w);
}
{
NSWindow *w = [NSWindow windowWithContentViewController: _destinationController];
[w setTitle: [_destinationController title]];
[w center];
[w orderFrontRegardless];
RETAIN(w);
}
}
else if ([_kind isEqualToString: @"popover"])
{
NSPopover *po = [[NSPopover alloc] init];
NSRect rect = [_popoverAnchorView frame];
if (_popover == nil)
{
NSPopover *po = [[NSPopover alloc] init];
NSRect rect = [_popoverAnchorView frame];
[po setBehavior: _popoverBehavior];
[po setContentViewController: _destinationController];
[po showRelativeToRect: rect
ofView: _popoverAnchorView
preferredEdge: _preferredEdge];
_popover = po; // weak... since we manually release...
[po setBehavior: _popoverBehavior];
[po setContentViewController: _destinationController];
[po showRelativeToRect: rect
ofView: _popoverAnchorView
preferredEdge: _preferredEdge];
}
else
{
if ([_popover behavior] == NSPopoverBehaviorTransient)
{
[_destinationController dismissController: nil];
[_popover close];
RELEASE(_popover);
_popover = nil;
}
}
}
else if ([_kind isEqualToString: @"sheet"])
{

View file

@ -1,29 +1,29 @@
/*
/*
NSViewController.m
Copyright (C) 2010 Free Software Foundation, Inc.
Author: David Wetzel <dave@turbocat.de>
Date: 2010
This file is part of the GNUstep GUI Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSBundle.h>
@ -42,16 +42,16 @@
@implementation NSViewController
- (id)initWithNibName:(NSString *)nibNameOrNil
bundle:(NSBundle *)nibBundleOrNil
- (id)initWithNibName:(NSString *)nibNameOrNil
bundle:(NSBundle *)nibBundleOrNil
{
self = [super init];
if (self == nil)
return nil;
ASSIGN(_nibName, nibNameOrNil);
ASSIGN(_nibBundle, nibBundleOrNil);
return self;
}
@ -69,7 +69,7 @@
DESTROY(_designNibBundleIdentifier);
DESTROY(view);
DESTROY(_segueMap);
[super dealloc];
}
@ -81,6 +81,26 @@
{
}
- (void) viewWillAppear: (BOOL)animated
{
}
- (void) viewIsAppearing: (BOOL)animated
{
}
- (void) viewDidAppear: (BOOL)animated
{
}
- (void) viewWillDisappear: (BOOL)animated
{
}
- (void) viewDidDisappear: (BOOL)animated
{
}
- (void)setRepresentedObject:(id)representedObject
{
ASSIGN(_representedObject, representedObject);
@ -133,21 +153,23 @@
}
[self viewWillLoad];
[self viewWillAppear: NO];
nib = [[NSNib alloc] initWithNibNamed: [self nibName]
bundle: [self nibBundle]];
bundle: [self nibBundle]];
if ((nib != nil) && [nib instantiateNibWithOwner: self
topLevelObjects: &_topLevelObjects])
topLevelObjects: &_topLevelObjects])
{
_vcFlags.nib_is_loaded = YES;
// FIXME: Need to resolve possible retain cycles here
[self viewDidLoad];
[self viewDidAppear: NO];
}
else
{
if (_nibName != nil)
{
NSLog(@"%@: could not load nib named %@.nib",
[self class], _nibName);
{
NSLog(@"%@: could not load nib named %@.nib",
[self class], _nibName);
}
}
RETAIN(_topLevelObjects);
@ -164,6 +186,45 @@
return _nibBundle;
}
// Dismiss
- (void) dismissViewController: (NSViewController *)viewController
{
[viewController viewDidDisappear: NO];
}
- (void) dismissController: (id)sender
{
[self dismissViewController: self];
}
// NSSeguePerforming methods...
- (void) performSegueWithIdentifier: (NSStoryboardSegueIdentifier)identifier
sender: (id)sender
{
NSStoryboardSegue *segue = [_segueMap objectForKey: identifier];
[self prepareForSegue: segue
sender: sender];
[segue perform];
}
- (void) prepareForSegue: (NSStoryboardSegue *)segue
sender: (id)sender
{
// do nothing in base class method...
}
- (BOOL) shouldPerformSegueWithIdentifier: (NSStoryboardSegueIdentifier)identifier
sender: (id)sender
{
return YES;
}
- (NSString *) description
{
return [NSString stringWithFormat: @"%@ - view = %@", [super description], view];
}
// NSCoding
- (id) initWithCoder: (NSCoder *)aDecoder
{
self = [super initWithCoder: aDecoder];
@ -187,7 +248,7 @@
}
return self;
}
- (void) encodeWithCoder: (NSCoder *)aCoder
{
[super encodeWithCoder: aCoder];
@ -202,33 +263,6 @@
}
}
// NSSeguePerforming methods...
- (void)performSegueWithIdentifier: (NSStoryboardSegueIdentifier)identifier
sender: (id)sender
{
NSStoryboardSegue *segue = [_segueMap objectForKey: identifier];
[self prepareForSegue: segue
sender: sender];
[segue perform];
}
- (void)prepareForSegue: (NSStoryboardSegue *)segue
sender: (id)sender
{
// do nothing in base class method...
}
- (BOOL)shouldPerformSegueWithIdentifier: (NSStoryboardSegueIdentifier)identifier
sender: (id)sender
{
return YES;
}
- (NSString *) description
{
return [NSString stringWithFormat: @"%@ - view = %@", [super description], view];
}
@end
@implementation NSViewController (NSEditorRegistration)
@ -245,9 +279,9 @@
@end
@implementation NSViewController (NSEditor)
- (void)commitEditingWithDelegate:(id)delegate
didCommitSelector:(SEL)didCommitSelector
contextInfo:(void *)contextInfo
- (void)commitEditingWithDelegate:(id)delegate
didCommitSelector:(SEL)didCommitSelector
contextInfo:(void *)contextInfo
{
// Loop over all elements of _editors
id editor = nil;
@ -257,11 +291,11 @@
{
void (*didCommit)(id, SEL, id, BOOL, void*);
didCommit = (void (*)(id, SEL, id, BOOL, void*))[delegate methodForSelector:
didCommit = (void (*)(id, SEL, id, BOOL, void*))[delegate methodForSelector:
didCommitSelector];
didCommit(delegate, didCommitSelector, editor, res, contextInfo);
}
}
- (BOOL)commitEditing
@ -278,4 +312,3 @@
[self notImplemented: _cmd];
}
@end