Fixed: Modern Cocoa behavior, new theme parameters, Aristo3 CSS theme ready for CPTabView (#2936)

This commit is contained in:
Didier Korthoudt
2020-11-20 08:33:56 +01:00
committed by GitHub
parent b67384cdd1
commit 1107195ab6
2 changed files with 113 additions and 6 deletions
+107 -6
View File
@@ -79,6 +79,20 @@ var CPTabViewDidSelectTabViewItemSelector = 1 << 1,
unsigned _delegateSelectors;
}
+ (CPString)defaultThemeClass
{
return @"tab-view";
}
+ (CPDictionary)themeAttributes
{
return @{
@"nib2cib-adjustment-frame": [CPNull null],
@"should-center-on-border": NO,
@"box-content-inset": CGInsetMakeZero()
};
}
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
@@ -95,14 +109,18 @@ var CPTabViewDidSelectTabViewItemSelector = 1 << 1,
{
_tabs = [[_CPSegmentedControl alloc] initWithFrame:CGRectMakeZero()];
[_tabs setTabView:self];
[_tabs setHitTests:NO];
[_tabs setSegments:[CPArray array]];
[_tabs setAction:@selector(_reflectSelectedTab:)];
[_tabs setTarget:self];
var height = [_tabs valueForThemeAttribute:@"min-size"].height;
[_tabs setFrameSize:CGSizeMake(0, height)];
_box = [[_CPTabViewBox alloc] initWithFrame:[self bounds]];
[_box setTabView:self];
[self setBackgroundColor:[CPColor colorWithCalibratedWhite:0.95 alpha:1.0]];
[_box setContentInset:[self currentValueForThemeAttribute:@"box-content-inset"]];
[_box setContentViewMargins:CGSizeMakeZero()];
[self addSubview:_box];
[self addSubview:_tabs];
@@ -463,10 +481,10 @@ var CPTabViewDidSelectTabViewItemSelector = 1 << 1,
{
var aFrame = [self frame],
segmentedHeight = CGRectGetHeight([_tabs frame]),
origin = _type === CPTopTabsBezelBorder ? segmentedHeight / 2 : 0;
borderWidth = [self currentValueForThemeAttribute:@"should-center-on-border"] ? [_box borderWidth] : 0,
origin = _type === CPTopTabsBezelBorder ? (segmentedHeight - borderWidth) / 2 : 0;
[_box setFrame:CGRectMake(0, origin, CGRectGetWidth(aFrame),
CGRectGetHeight(aFrame) - segmentedHeight / 2)];
[_box setFrame:CGRectMake(0, origin, CGRectGetWidth(aFrame), CGRectGetHeight(aFrame) - (segmentedHeight - borderWidth) / 2)];
[self _repositionTabs];
}
@@ -526,6 +544,11 @@ var CPTabViewDidSelectTabViewItemSelector = 1 << 1,
return [_box backgroundColor];
}
- (void)mouseDown:(CPEvent)anEvent
{
[_tabs trackSegment:anEvent];
}
- (void)_repositionTabs
{
var horizontalCenterOfSelf = CGRectGetWidth([self bounds]) / 2,
@@ -542,6 +565,11 @@ var CPTabViewDidSelectTabViewItemSelector = 1 << 1,
[_box setContentView:aView];
}
- (void)_reflectSelectedTab:(id)aSender
{
[self selectTabViewItemAtIndex:[_tabs selectedSegment]];
}
// DELEGATE METHODS
- (BOOL)_sendDelegateShouldSelectTabViewItem:(CPTabViewItem)aTabViewItem
@@ -858,15 +886,48 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
@end
#pragma mark -
@implementation CPTabView (CSSTheming)
#pragma mark Override
- (void)_setThemeIncludingDescendants:(CPTheme)aTheme
{
[self setTheme:aTheme];
[[self subviews] makeObjectsPerformSelector:@selector(_setThemeIncludingDescendants:) withObject:aTheme];
// Items must also perform this (without this, only the selected item does)
for (var i = 0, allItems = [self items], count = allItems.length; i < count; i++)
if (allItems[i] != _selectedTabViewItem)
[[allItems[i] view] _setThemeIncludingDescendants:aTheme];
}
@end
#pragma mark -
@implementation _CPTabViewBox : CPBox
{
CPTabView _tabView @accessors(property=tabView);
CPTabView _tabView @accessors(property=tabView);
CGInset _contentInset @accessors(property=contentInset);
}
#pragma mark -
#pragma mark Override
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
{
[self setBoxType:CPBoxPrimary];
}
return self;
}
- (CPView)hitTest:(CGPoint)aPoint
{
// Here we check if we have clicked on the segmentedControl of the tabView or not
@@ -879,6 +940,46 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
return [super hitTest:aPoint];
}
// Some CPBox overrides because CPTabView use of CPBox differs from legacy CPBox regarding layout.
- (void)setContentView:(CPView)aView
{
if (aView === _contentView)
return;
if (_contentInset)
[aView setFrame:CGRectInsetByInset([self bounds], _contentInset)];
[aView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
// A nil contentView is allowed (tested in Cocoa 2013-02-22).
if (!aView)
[_contentView removeFromSuperview];
else if (_contentView)
[_boxView replaceSubview:_contentView with:aView];
else
[_boxView addSubview:aView];
_contentView = aView;
[self refreshDisplay];
}
- (void)sizeToFit
{
var offset = [self _titleHeightOffset],
size = [self frameSize];
[_boxView setFrame:CGRectMake(0, offset[1], size.width, size.height - offset[0])];
if (!_contentView)
return;
var boxSize = [_boxView frameSize];
if (_contentInset)
[_contentView setFrame:CGRectMake(_contentInset.left, _contentInset.top, boxSize.width - _contentInset.left - _contentInset.right, boxSize.height - _contentInset.top - _contentInset.bottom)];
}
@end
# pragma mark -
@@ -914,7 +1015,7 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
{
[self setSelected:YES forSegment:_trackingSegment];
_selectedSegment = _trackingSegment;
[_tabView selectTabViewItemAtIndex:_selectedSegment];
[self sendAction:[self action] to:[self target]];
}
[self drawSegmentBezel:_trackingSegment highlight:NO];
+6
View File
@@ -49,6 +49,12 @@
return self;
}
- (void)awakeFromNib
{
// We have to call _adjustNib2CibSize here as during NS_initWithCoder, view is not totally loaded.
[self _adjustNib2CibSize];
}
@end
@implementation NSTabView : CPTabView