From 78b3887e4a47e93399ddd0a8b26b248f0e19d5dc Mon Sep 17 00:00:00 2001 From: Didier Korthoudt Date: Fri, 9 Oct 2020 14:29:10 +0200 Subject: [PATCH] New: CSS shadow, new theme parameters and Aristo3 CSS theme ready for CPWindow (#2927) --- AppKit/CPWindow/CPWindow.j | 88 ++++++++++++++++++++++++++------- AppKit/CPWindow/_CPWindowView.j | 53 ++++++++++++++++++-- 2 files changed, 118 insertions(+), 23 deletions(-) diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index 3f1c742d6..0a59d1538 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -193,7 +193,7 @@ var CPWindowActionMessageKeys = [ BOOL _isDocumentEdited; BOOL _isDocumentSaving; - CPImageView _shadowView; + _CPShadowWindowView _shadowView; CPView _windowView; CPView _contentView; @@ -369,6 +369,23 @@ CPTexturedBackgroundWindowMask [_windowView _setWindow:self]; [_windowView setNextResponder:self]; + // CSS Styling +#if PLATFORM(DOM) + var radius; + + if (radius = [_windowView actualValueForThemeAttribute:@"border-top-left-radius"]) + _windowView._DOMElement.style.borderTopLeftRadius = radius; + + if (radius = [_windowView actualValueForThemeAttribute:@"border-top-right-radius"]) + _windowView._DOMElement.style.borderTopRightRadius = radius; + + if (radius = [_windowView actualValueForThemeAttribute:@"border-bottom-left-radius"]) + _windowView._DOMElement.style.borderBottomLeftRadius = radius; + + if (radius = [_windowView actualValueForThemeAttribute:@"border-bottom-right-radius"]) + _windowView._DOMElement.style.borderBottomRightRadius = radius; +#endif + // Size calculation needs _windowView _minSize = [self _calculateMinSizeForProposedSize:CGSizeMake(0.0, 0.0)]; _maxSize = CGSizeMake(1000000.0, 1000000.0); @@ -1410,25 +1427,51 @@ CPTexturedBackgroundWindowMask return; } - - if (_hasShadow && !_shadowView) + + if ([[self actualTheme] isCSSBased]) { - _shadowView = [[_CPShadowWindowView alloc] initWithFrame:CGRectMakeZero()]; - - [_shadowView setWindowView:_windowView]; - [_shadowView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable]; - [_shadowView setNeedsLayout]; - + // When using CSS theming, we get rid of _shadowView and add CSS shadowing directly + // on the _windowView + #if PLATFORM(DOM) - CPDOMDisplayServerInsertBefore(_DOMElement, _shadowView._DOMElement, _windowView._DOMElement); + // We must check that _windowView exists as _updateShadow can be called by + // _setSharesChromeWithPlatformWindow whereas _windowView is not yet created + if (_windowView && _windowView._DOMElement) + { + var currentBoxShadow = _windowView._DOMElement.style.boxShadow; + + if (_hasShadow && (currentBoxShadow.length == 0)) + { + _windowView._DOMElement.style.boxShadow = [_windowView actualValueForThemeAttribute:@"window-shadow-color"]; + } + else if (!_hasShadow && (currentBoxShadow.length > 0)) + { + _windowView._DOMElement.style.boxShadow = ""; + } + } #endif } - else if (!_hasShadow && _shadowView) + else { + if (_hasShadow && !_shadowView) + { + _shadowView = [[_CPShadowWindowView alloc] initWithFrame:CGRectMakeZero()]; + + [_shadowView setWindowView:_windowView]; + [_shadowView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable]; + [_shadowView setNeedsLayout]; + #if PLATFORM(DOM) - CPDOMDisplayServerRemoveChild(_DOMElement, _shadowView._DOMElement); + CPDOMDisplayServerInsertBefore(_DOMElement, _shadowView._DOMElement, _windowView._DOMElement); #endif - _shadowView = nil; + } + else if (!_hasShadow && _shadowView) + { +#if PLATFORM(DOM) + CPDOMDisplayServerRemoveChild(_DOMElement, _shadowView._DOMElement); +#endif + _shadowView = nil; + } } } @@ -2810,7 +2853,7 @@ CPTexturedBackgroundWindowMask contentRect = [_contentView frame], sheetFrame = CGRectMakeCopy([attachedSheet frame]); - sheetFrame.origin.y = CGRectGetMinY(_frame) + CGRectGetMinY(contentRect); + sheetFrame.origin.y = [[attachedSheet _windowView] _sheetVerticalOffset]+ CGRectGetMinY(_frame) + CGRectGetMinY(contentRect); sheetFrame.origin.x = CGRectGetMinX(_frame) + FLOOR((CGRectGetWidth(_frame) - CGRectGetWidth(sheetFrame)) / 2.0); [attachedSheet setFrame:sheetFrame display:YES animate:NO]; @@ -3009,13 +3052,12 @@ CPTexturedBackgroundWindowMask } // The sheet starts hidden just above the top of a clip rect - // TODO : Make properly for the -1 in endY var sheetFrame = [sheet frame], - sheetShadowFrame = sheet._hasShadow ? [sheet._shadowView frame] : sheetFrame, + sheetShadowFrame = [sheet _shadowFrame], frame = [self frame], originX = frame.origin.x + FLOOR((frame.size.width - sheetFrame.size.width) / 2), startFrame = CGRectMake(originX, -sheetShadowFrame.size.height, sheetFrame.size.width, sheetFrame.size.height), - endY = -1 + [_windowView bodyOffset] - [[self contentView] frame].origin.y, + endY = [[sheet _windowView] _sheetVerticalOffset] + [_windowView bodyOffset] - [[self contentView] frame].origin.y, endFrame = CGRectMake(originX, endY, sheetFrame.size.width, sheetFrame.size.height); if (_toolbar && [_windowView showsToolbar] && [self isFullPlatformWindow]) @@ -3054,7 +3096,7 @@ CPTexturedBackgroundWindowMask { var sheet = _sheetContext["sheet"], sheetFrame = [sheet frame], - fullHeight = sheet._hasShadow ? [sheet._shadowView frame].size.height : sheetFrame.size.height, + fullHeight = [sheet _shadowFrame].size.height, endFrame = CGRectMakeCopy(sheetFrame), contentOrigin = [self convertBaseToGlobal:[[self contentView] frame].origin]; @@ -3086,7 +3128,7 @@ CPTexturedBackgroundWindowMask sheetOrigin = CGPointMakeCopy(sheetFrame.origin); [self _removeClipForSheet:sheet]; - [sheet setFrameOrigin:CGPointMake(sheetOrigin.x, [sheet frame].origin.y + sheetOrigin.y)]; + [self _setAttachedSheetFrameOrigin]; // we wanted to close the sheet while it animated in, do that now if (_sheetContext["shouldClose"] === YES) @@ -3133,6 +3175,14 @@ CPTexturedBackgroundWindowMask return _isSheet; } +- (CGRect)_shadowFrame +{ + if (_hasShadow) + return _shadowView ? [_shadowView frame] : [self frame]; + + return [self frame]; +} + // /* Used privately. diff --git a/AppKit/CPWindow/_CPWindowView.j b/AppKit/CPWindow/_CPWindowView.j index 812b09c7e..d3abb5ee5 100644 --- a/AppKit/CPWindow/_CPWindowView.j +++ b/AppKit/CPWindow/_CPWindowView.j @@ -70,12 +70,40 @@ _CPWindowViewResizeSlop = 3; + (CGRect)contentRectForFrameRect:(CGRect)aFrameRect { - return CGRectMakeCopy(aFrameRect); + // First, we have to check if we are compiling a theme or running an application because if working on a theme, + // we can't use theme attributes to determine the inset ! This would be a kind of circular reference... + + var compilingATheme = [[[CPBundle mainBundle] objectForInfoDictionaryKey:@"CPApplicationDelegateClass"] isEqualToString:@"BKShowcaseController"], + frameOutset = compilingATheme ? CGInsetMakeZero() : [[CPTheme defaultTheme] valueForAttributeWithName:@"frame-outset" forClass:_CPWindowView]; + + if (!frameOutset) + // No value found in theme. Get default value. + frameOutset = [[self themeAttributes] objectForKey:@"frame-outset"]; + + if (!frameOutset) + // No value found in defaults. Get default value for _CPWindowView (we know here that the window class is not _CPWindowView) + frameOutset = [[_CPWindowView themeAttributes] objectForKey:@"frame-outset"]; + + return CGRectMake(aFrameRect.origin.x - frameOutset.left, aFrameRect.origin.y - frameOutset.top, aFrameRect.size.width + frameOutset.left + frameOutset.right, aFrameRect.size.height + frameOutset.top + frameOutset.bottom); } + (CGRect)frameRectForContentRect:(CGRect)aContentRect { - return CGRectMakeCopy(aContentRect); + // First, we have to check if we are compiling a theme or running an application because if working on a theme, + // we can't use theme attributes to determine the inset ! This would be a kind of circular reference... + + var compilingATheme = [[[CPBundle mainBundle] objectForInfoDictionaryKey:@"CPApplicationDelegateClass"] isEqualToString:@"BKShowcaseController"], + frameOutset = compilingATheme ? CGInsetMakeZero() : [[CPTheme defaultTheme] valueForAttributeWithName:@"frame-outset" forClass:[self class]]; // _CPWindowView - [self class] + + if (!frameOutset) + // No value found in theme. Get default value. + frameOutset = [[self themeAttributes] objectForKey:@"frame-outset"]; + + if (!frameOutset) + // No value found in theme. Get default value for _CPWindowView + frameOutset = [[_CPWindowView themeAttributes] objectForKey:@"frame-outset"]; + + return CGRectMake(aContentRect.origin.x - frameOutset.left, aContentRect.origin.y - frameOutset.top, aContentRect.size.width + frameOutset.left + frameOutset.right, aContentRect.size.height + frameOutset.top + frameOutset.bottom); } + (CPString)defaultThemeClass @@ -94,6 +122,7 @@ _CPWindowViewResizeSlop = 3; @"resize-indicator": [CPNull null], @"attached-sheet-shadow-color": [CPColor blackColor], @"shadow-height": 8, + @"shadown-horizontal-offset": 0, @"close-image-origin": [CPNull null], @"close-image-size": [CPNull null], @"close-image": [CPNull null], @@ -106,6 +135,17 @@ _CPWindowViewResizeSlop = 3; @"title-alignment": CPCenterTextAlignment, @"title-line-break-mode": CPLineBreakByTruncatingTail, @"title-vertical-alignment": CPTopVerticalTextAlignment, + @"title-margin": 20, + @"border-top-left-radius": @"0px", + @"border-top-right-radius": @"0px", + @"border-bottom-left-radius": @"0px", + @"border-bottom-right-radius": @"0px", + @"minimize-image-origin": [CPNull null], + @"minimize-image-size": [CPNull null], + @"zoom-image-origin": [CPNull null], + @"zoom-image-size": [CPNull null], + @"frame-outset": CGInsetMakeZero(), + @"sheet-vertical-offset": -1 }; } @@ -932,9 +972,14 @@ _CPWindowViewResizeSlop = 3; [self setNeedsLayout]; } -- (CGRect)_shadowViewWidthForParentWindow:(CPWindow)parentWindow +- (int)_sheetVerticalOffset { - var myWidth = [self bounds].size.width, + return [self currentValueForThemeAttribute:@"sheet-vertical-offset"]; +} + +- (int)_shadowViewWidthForParentWindow:(CPWindow)parentWindow +{ + var myWidth = [self bounds].size.width - [self currentValueForThemeAttribute:@"shadown-horizontal-offset"], parentWidth = [[parentWindow contentView] bounds].size.width; return MIN(myWidth, parentWidth);