Implement supporting core layout methods on NSView

This commit is contained in:
Benjamin Johnson 2023-02-19 15:00:01 +11:00
parent 72b05b514a
commit 571ad7a613
4 changed files with 213 additions and 1 deletions

View file

@ -29,8 +29,9 @@
#import <Foundation/NSGeometry.h>
#import <Foundation/NSKeyedArchiver.h>
#import <AppKit/NSLayoutAnchor.h>
#import <AppKit/NSView.h>
@class NSControl, NSView, NSAnimation, NSArray, NSMutableArray, NSDictionary;
@class NSControl, NSAnimation, NSArray, NSMutableArray, NSDictionary;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_10, GS_API_LATEST)
@ -166,6 +167,40 @@ APPKIT_EXPORT_CLASS
@end
@interface NSView (NSConstraintBasedCompatibility)
#if GS_HAS_DECLARED_PROPERTIES
@property BOOL translatesAutoresizingMaskIntoConstraints;
#else
- (BOOL) translatesAutoresizingMaskIntoConstraints;
- (void) setTranslatesAutoresizingMaskIntoConstraints: (BOOL)translatesAutoresizingMaskIntoConstraints;
#endif
@end
@interface NSView (NSConstraintBasedLayoutCoreMethods)
- (void) updateConstraints;
- (void) updateConstraintsForSubtreeIfNeeded;
#if GS_HAS_DECLARED_PROPERTIES
@property BOOL needsUpdateConstraints;
#else
- (BOOL) needsUpdateConstraints;
- (void) setNeedsUpdateConstraints: (BOOL)needsUpdateConstraints;
#endif
@end
@interface NSView (NSConstraintBasedLayoutInstallingConstraints)
- (void) addConstraint: (NSLayoutConstraint *)constraint;
- (void) addConstraints: (NSArray*)constraints;
@end
#if defined(__cplusplus)
}
#endif

View file

@ -179,6 +179,7 @@ PACKAGE_SCOPE
BOOL _renew_gstate;
BOOL _is_hidden;
BOOL _in_live_resize;
BOOL _needsLayout;
NSUInteger _autoresizingMask;
NSFocusRingType _focusRingType;
@ -641,6 +642,22 @@ PACKAGE_SCOPE
#endif
#endif
/**
* Layout
*/
#if OS_API_VERSION(MAC_OS_X_VERSION_10_7, GS_API_LATEST)
- (void) layoutSubtreeIfNeeded;
- (void) layout;
#if GS_HAS_DECLARED_PROPERTIES
@property (nonatomic) BOOL needsLayout;
#else
-(BOOL) needsLayout;
-(void) setNeedsLayout: (BOOL)needsLayout;
#endif
#endif
@end

View file

@ -32,6 +32,8 @@
#import "AppKit/NSLayoutConstraint.h"
#import "AppKit/NSWindow.h"
#import "AppKit/NSApplication.h"
#import "NSAutoresizingMaskLayoutConstraint.h"
#import "GSFastEnumeration.h"
#import "GSAutoLayoutVFLParser.h"
static NSMutableArray *activeConstraints = nil;
@ -612,3 +614,116 @@ static NSMutableArray *activeConstraints = nil;
}
@end
@implementation NSView (NSConstraintBasedCompatibility)
NSString static const *translatesAutoresizingMaskKey
= @"NSConstraintBasedCompatibility.translatesAutoresizingMaskKey";
- (void) setTranslatesAutoresizingMaskIntoConstraints: (BOOL)translate
{
NSValue *value = [NSValue valueWithBytes: &translate objCType: @encode (BOOL)];
objc_setAssociatedObject(self, &translatesAutoresizingMaskKey, value,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL) translatesAutoresizingMaskIntoConstraints
{
NSValue *value
= objc_getAssociatedObject(self, &translatesAutoresizingMaskKey);
if (value == nil)
{
return YES;
}
BOOL translate;
[value getValue:&translate];
return translate;
}
@end
@implementation NSView (NSConstraintBasedLayoutCoreMethods)
NSString static const *needsUpdateConstraintsKey
= @"NSConstraintBasedLayoutCoreMethods.needsUpdateConstraintsKey";
- (void) updateConstraintsForSubtreeIfNeeded
{
NSArray *subviews = [self subviews];
FOR_IN (NSView *, subview, subviews)
[subview updateConstraintsForSubtreeIfNeeded];
END_FOR_IN (subviews);
if ([self needsUpdateConstraints])
{
[self updateConstraints];
}
}
- (void) updateConstraints
{
if ([self translatesAutoresizingMaskIntoConstraints] &&
[self superview] != nil)
{
NSArray *autoresizingConstraints = [NSAutoresizingMaskLayoutConstraint
constraintsWithAutoresizingMask: [self autoresizingMask]
subitem: self
frame: [self frame]
superitem: [self superview]
bounds: [[self superview] bounds]];
[self addConstraints:autoresizingConstraints];
}
[self _setNeedsUpdateConstraints:NO];
}
- (void)_setNeedsUpdateConstraints: (BOOL) needsUpdateConstraints
{
NSValue *value = [NSValue valueWithBytes: &needsUpdateConstraints
objCType: @encode (BOOL)];
objc_setAssociatedObject (self, &needsUpdateConstraintsKey, value,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void) setNeedsUpdateConstraints: (BOOL)needsUpdateConstraints
{
if (!needsUpdateConstraints)
{
return;
}
[self _setNeedsUpdateConstraints:YES];
}
- (BOOL) needsUpdateConstraints
{
NSValue *needsUpdateConstraintsValue
= objc_getAssociatedObject (self, &needsUpdateConstraintsKey);
if (needsUpdateConstraintsValue == nil)
{
return YES;
}
BOOL needsUpdateConstraints;
[needsUpdateConstraintsValue getValue:&needsUpdateConstraints];
return needsUpdateConstraints;
}
@end
@implementation NSView (NSConstraintBasedLayoutInstallingConstraints)
- (void) addConstraint: (NSLayoutConstraint *)constraint
{
// FIXME: Implement adding constraint to layout engine
}
- (void) addConstraints: (NSArray*)constraints
{
FOR_IN (NSLayoutConstraint*, constraint, constraints)
[self addConstraint: constraint];
END_FOR_IN (constraints);
}
@end

View file

@ -62,6 +62,7 @@
#import "AppKit/NSFont.h"
#import "AppKit/NSGraphics.h"
#import "AppKit/NSKeyValueBinding.h"
#import "AppKit/NSLayoutConstraint.h"
#import "AppKit/NSMenu.h"
#import "AppKit/NSPasteboard.h"
#import "AppKit/NSPrintInfo.h"
@ -76,6 +77,7 @@
#import "GNUstepGUI/GSNibLoading.h"
#import "GSToolTips.h"
#import "GSBindingHelpers.h"
#import "GSFastEnumeration.h"
#import "GSGuiPrivate.h"
#import "NSViewPrivate.h"
@ -5129,6 +5131,49 @@ static NSView* findByTag(NSView *view, NSInteger aTag, NSUInteger *level)
return;
}
/**
* Layout
*/
- (void) layout
{
// FIXME: Implement asking layout engine for the alignment rect of each subview and set the alignment rect of each sub view
}
- (void) layoutSubtreeIfNeeded
{
[self updateConstraintsForSubtreeIfNeeded];
[self _layoutViewAndSubViews];
}
- (void) _layoutViewAndSubViews
{
if (_needsLayout)
{
[self layout];
_needsLayout = NO;
}
NSArray *subviews = [self subviews];
FOR_IN (NSView *, subview, subviews)
[subview _layoutViewAndSubViews];
END_FOR_IN (subviews);
}
- (void) setNeedsLayout: (BOOL) needsLayout
{
if (!needsLayout)
{
return;
}
_needsLayout = needsLayout;
}
- (BOOL) needsLayout
{
return _needsLayout;
}
@end
@implementation NSView (__NSViewPrivateMethods__)