Merge pull request #116 from gnustep/TP_NSSplitView_branch

This commit is contained in:
Gregory Casamento 2021-11-18 10:01:23 -05:00 committed by GitHub
commit 9f62b46c7b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 183 additions and 44 deletions

View file

@ -1,3 +1,10 @@
2021-11-15 Gregory John Casamento <greg.casamento@gmail.com>
* Headers/AppKit/NSSplitView.h
* Source/NSSplitView.m: Incorporate and refactor changes to NSSplitView
to support Think, Thin, and PaneSplitter NSSplitViewDividerStyle
settings.
2021-11-15 Gregory John Casamento <greg.casamento@gmail.com>
* Source/NSView.m: Add cast to id in case nil is not "id". This

View file

@ -57,6 +57,8 @@ typedef NSInteger NSSplitViewDividerStyle;
BOOL _isVertical;
BOOL _never_displayed_before;
BOOL _is_pane_splitter;
BOOL _arrangesAllSubviews;
NSSplitViewDividerStyle _dividerStyle;
}
- (void) setDelegate: (id)anObject;

View file

@ -45,6 +45,7 @@
#import <Foundation/NSUserDefaults.h>
#import "AppKit/NSApplication.h"
#import "AppKit/NSBezierPath.h"
#import "AppKit/NSColor.h"
#import "AppKit/NSCursor.h"
#import "AppKit/NSEvent.h"
@ -60,6 +61,7 @@ static NSNotificationCenter *nc = nil;
+ (void) initialize
{
[self setVersion: 1];
nc = [NSNotificationCenter defaultCenter];
}
@ -70,8 +72,9 @@ static NSNotificationCenter *nc = nil;
{
if ((self = [super initWithFrame: frameRect]) != nil)
{
_dividerStyle = NSSplitViewDividerStyleThick;
_dividerWidth = [self dividerThickness];
_draggedBarWidth = 8; // default bigger than dividerThickness
_draggedBarWidth = _dividerWidth + 2;
_isVertical = NO;
ASSIGN(_dividerColor, [NSColor controlShadowColor]);
ASSIGN(_dimpleImage, [NSImage imageNamed: @"common_Dimple"]);
@ -83,6 +86,31 @@ static NSNotificationCenter *nc = nil;
return self;
}
- (NSRect) _dividerRectForIndex: (NSUInteger)index
{
const SEL selector = @selector(splitView:effectiveRect:forDrawnRect:ofDividerAtIndex:);
NSRect rect = [[[self subviews] objectAtIndex: index] frame];
if (_isVertical == NO)
{
rect.origin.y = NSMaxY (rect);
rect.size.height = _dividerWidth;
}
else
{
rect.origin.x = NSMaxX (rect);
rect.size.width = _dividerWidth;
}
rect = NSIntersectionRect(rect, [self visibleRect]);
// Check with delegate for hit rect...
if (_delegate && [_delegate respondsToSelector: selector])
{
rect = [_delegate splitView: self effectiveRect: rect forDrawnRect: rect ofDividerAtIndex: index];
}
return rect;
}
- (void) dealloc
{
RELEASE(_backgroundColor);
@ -172,8 +200,8 @@ static NSNotificationCenter *nc = nil;
* It is only used in the non-live resize mode.
*/
- (BOOL) _drawHighlightedDividerWithSize: (NSRect) r
andOldSize: (NSRect) oldRect
isLit: (BOOL) lit
andOldSize: (NSRect) oldRect
isLit: (BOOL) lit
{
if (NSEqualRects(r, oldRect) == YES)
{
@ -402,8 +430,9 @@ static NSNotificationCenter *nc = nil;
- (void) mouseDown: (NSEvent*)theEvent
{
NSApplication *app = [NSApplication sharedApplication];
NSPoint p = NSZeroPoint,
op = NSZeroPoint;
NSPoint p = NSZeroPoint;
NSPoint op = NSZeroPoint;
NSPoint poffset = NSZeroPoint;
NSEvent *e;
NSRect r, r1, bigRect, vis;
id v = nil, prev = nil;
@ -453,7 +482,23 @@ static NSNotificationCenter *nc = nil;
{
NSDebugLLog(@"NSSplitView",
@"NSSplitView got mouseDown in subview area");
return;
// If this is the first view then we're done...
if (i == 0)
return;
// Otherwise, check whether the delegate wants a larger rectangle
// for the divider grab area that may overlap the view and validate
// the point within that area...
r = [self _dividerRectForIndex: i - 1];
if (NSPointInRect(p, r) == NO)
return;
// Capture the offset for use during the resize loop below...
poffset = NSMakePoint(r.origin.x - p.x, r.origin.y - p.y);
// Force the view processing below to select this view...
p = r.origin;
}
if (_isVertical == NO)
{
@ -712,7 +757,8 @@ static NSNotificationCenter *nc = nil;
if ((_isVertical == YES && p.x != op.x)
|| (_isVertical == NO && p.y != op.y))
{
[self _resize: v withOldSplitView: prev withFrame: r fromPoint: p
NSPoint point = NSMakePoint(p.x+poffset.x, p.y+poffset.y);
[self _resize: v withOldSplitView: prev withFrame: r fromPoint: point
withBigRect: bigRect divHorizontal: divHorizontal
divVertical: divVertical];
[_window invalidateCursorRectsForView: self];
@ -979,7 +1025,15 @@ static NSNotificationCenter *nc = nil;
* dividerThickness (or, without need for subclassing, invoke
* setDimpleImage:resetDividerThickness:YES below)
*/
return 6;
if (_dividerStyle == NSSplitViewDividerStyleThin)
return 1;
if (_dividerStyle == NSSplitViewDividerStyleThick)
return 6;
if (_dividerStyle == NSSplitViewDividerStylePaneSplitter)
return 6;
NSWarnMLog(@"unsupported divider style: %ld", (long)_dividerStyle);
return 0;
}
static inline NSPoint centerSizeInRect(NSSize innerSize, NSRect outerRect)
@ -990,7 +1044,7 @@ static inline NSPoint centerSizeInRect(NSSize innerSize, NSRect outerRect)
return p;
}
- (void) drawDividerInRect: (NSRect)aRect
- (void) drawThickDividerInRect: (NSRect)aRect
{
NSPoint dimpleOrigin;
NSSize dimpleSize;
@ -1016,6 +1070,34 @@ static inline NSPoint centerSizeInRect(NSSize innerSize, NSRect outerRect)
operation: NSCompositeSourceOver];
}
- (void) drawThinDividerInRect: (NSRect) aRect
{
CGFloat lineWidth = (_isVertical ? aRect.size.width : aRect.size.height);
NSPoint startPoint = aRect.origin;
NSPoint endPoint = NSMakePoint(NSMaxX(aRect), NSMinY(aRect));
NSBezierPath *path = [NSBezierPath bezierPath];
if (_isVertical)
{
endPoint = NSMakePoint(NSMinX(aRect), NSMaxY(aRect));
}
[path setLineWidth: lineWidth];
[path moveToPoint: startPoint];
[path lineToPoint: endPoint];
[path stroke];
}
- (void) drawDividerInRect: (NSRect)aRect
{
if (_dividerStyle == NSSplitViewDividerStyleThin)
[self drawThinDividerInRect: aRect];
else if (_dividerStyle == NSSplitViewDividerStyleThick)
[self drawThickDividerInRect: aRect];
else if (_dividerStyle == NSSplitViewDividerStylePaneSplitter)
[self drawThickDividerInRect: aRect];
}
/* Vertical splitview has a vertical split bar */
- (void) setVertical: (BOOL)flag
{
@ -1301,7 +1383,6 @@ static inline NSPoint centerSizeInRect(NSSize innerSize, NSRect outerRect)
NSArray *subs = [self subviews];
NSUInteger i;
const NSUInteger count = [subs count];
const NSRect visibleRect = [self visibleRect];
NSCursor *cursor;
if (_isVertical)
@ -1315,20 +1396,7 @@ static inline NSPoint centerSizeInRect(NSSize innerSize, NSRect outerRect)
for (i = 0; (i + 1) < count; i++)
{
NSView *v = [subs objectAtIndex: i];
NSRect divRect = [v frame];
if (_isVertical == NO)
{
divRect.origin.y = NSMaxY (divRect);
divRect.size.height = _dividerWidth;
}
else
{
divRect.origin.x = NSMaxX (divRect);
divRect.size.width = _dividerWidth;
}
divRect = NSIntersectionRect(divRect, visibleRect);
NSRect divRect = [self _dividerRectForIndex: i];
if (!NSEqualRects(NSZeroRect, divRect))
{
[self addCursorRect: divRect cursor: cursor];
@ -1343,13 +1411,21 @@ static inline NSPoint centerSizeInRect(NSSize innerSize, NSRect outerRect)
- (NSSplitViewDividerStyle) dividerStyle
{
// FIXME
return NSSplitViewDividerStyleThick;
return _dividerStyle;
}
- (void) setDividerStyle: (NSSplitViewDividerStyle)dividerStyle
{
// FIXME
_dividerStyle = dividerStyle;
_dividerWidth = [self dividerThickness];
_draggedBarWidth = _dividerWidth + 2; // default bigger than dividerThickness
ASSIGN(_dividerColor, [NSColor controlShadowColor]);
ASSIGN(_dimpleImage, [NSImage imageNamed: @"common_Dimple"]);
_never_displayed_before = YES;
_is_pane_splitter = (dividerStyle == NSSplitViewDividerStylePaneSplitter);
[self setNeedsDisplay: YES];
}
/*
@ -1363,12 +1439,10 @@ static inline NSPoint centerSizeInRect(NSSize innerSize, NSRect outerRect)
{
[aCoder encodeBool: _isVertical forKey: @"NSIsVertical"];
[aCoder encodeObject: _autosaveName forKey: @"NSAutosaveName"];
[aCoder encodeInteger: _dividerStyle forKey: @"NSDividerStyle"];
}
else
{
// FIXME: No idea why this as encode as int
int draggedBarWidth = _draggedBarWidth;
/*
* Encode objects we don't own.
*/
@ -1384,8 +1458,13 @@ static inline NSPoint centerSizeInRect(NSSize innerSize, NSRect outerRect)
/*
* Encode the rest of the ivar data.
*/
[aCoder encodeValueOfObjCType: @encode(int) at: &draggedBarWidth];
[aCoder encodeValueOfObjCType: @encode(CGFloat) at: &_draggedBarWidth];
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &_isVertical];
/*
* Encode Divider style
*/
encode_NSInteger(aCoder, &_dividerStyle);
}
}
@ -1412,14 +1491,12 @@ static inline NSPoint centerSizeInRect(NSSize innerSize, NSRect outerRect)
[self setAutosaveName: [aDecoder decodeObjectForKey: @"NSAutosaveName"]];
}
_dividerWidth = [self dividerThickness];
_draggedBarWidth = 8; // default bigger than dividerThickness
ASSIGN(_dividerColor, [NSColor controlShadowColor]);
ASSIGN(_dimpleImage, [NSImage imageNamed: @"common_Dimple"]);
_never_displayed_before = YES;
_is_pane_splitter = YES;
if ([aDecoder containsValueForKey: @"NSDividerStyle"])
{
[self setDividerStyle: [aDecoder decodeIntegerForKey: @"NSDividerStyle"]];
}
[self setAutoresizesSubviews: YES];
while((subview = [en nextObject]) != nil)
{
[subview setAutoresizesSubviews: YES];
@ -1427,8 +1504,7 @@ static inline NSPoint centerSizeInRect(NSSize innerSize, NSRect outerRect)
}
else
{
// FIXME: No idea why this as encode as int
int draggedBarWidth;
int version = [aDecoder versionForClassName: @"NSSplitView"];
// Decode objects that we don't retain.
[self setDelegate: [aDecoder decodeObject]];
@ -1442,12 +1518,20 @@ static inline NSPoint centerSizeInRect(NSSize innerSize, NSRect outerRect)
[aDecoder decodeValueOfObjCType: @encode(id) at: &_dividerColor];
// Decode non-object data.
[aDecoder decodeValueOfObjCType: @encode(int) at: &draggedBarWidth];
_draggedBarWidth = draggedBarWidth;
[aDecoder decodeValueOfObjCType: @encode(CGFloat) at: &_draggedBarWidth];
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_isVertical];
_dividerWidth = [self dividerThickness];
_never_displayed_before = YES;
if (version >= 1)
{
decode_NSInteger(aDecoder, &_dividerStyle);
[self setDividerStyle: _dividerStyle];
}
else
{
_dividerStyle = NSSplitViewDividerStyleThick;
}
[self setDividerStyle: _dividerStyle];
}
return self;
@ -1509,4 +1593,50 @@ static inline NSPoint centerSizeInRect(NSSize innerSize, NSRect outerRect)
ASSIGN(_dividerColor, aColor);
}
// NSStackView processing for arranged subviews and seems to be based
// on auto layout constraints...
- (NSArray *) arrangedSubviews
{
// needs to be an attribute that holds the arranged subviews...
return [self subviews];
}
- (BOOL) arrangesAllSubviews
{
return _arrangesAllSubviews;
}
- (void) setArrangesAllSubviews: (BOOL) flag
{
// processing...
_arrangesAllSubviews = flag;
}
- (void) addArrangedSubview: (NSView *)view
{
[self addSubview: view];
}
- (void)insertArrangedSubview: (NSView *)view atIndex: (NSInteger)index
{
// needs to be removed to the internal attribute that holds the arranged subviews...
if ((index < 0) || (index >= [[self arrangedSubviews] count]))
{
[self addArrangedSubview: view];
}
else
{
NSView *v = [[self subviews] objectAtIndex: index];
[self addSubview: view
positioned: NSWindowBelow
relativeTo: v];
}
}
- (void) removeArrangedSubview: (NSView *)view
{
// needs to be removed to the internal attribute that holds the arranged subviews...
[view removeFromSuperview];
}
@end