NEW: Initial support for CPAppearance

This patch adds the `CPAppearance` class and uses it where needed.
There is nearly no impact, but in `_CPPopoverWindowView` where the
`CPPopoverAppearance` needs to be converted to a `CPAppearance` object

nib2cib support has also been added.

*This patch brings no new functionality.*
This commit is contained in:
Antoine Mercadal
2015-08-13 19:56:10 -07:00
parent 3d79799450
commit 6d67d30aee
8 changed files with 240 additions and 9 deletions
+2 -1
View File
@@ -26,6 +26,7 @@
@import "CPAccordionView.j"
@import "CPAlert.j"
@import "CPAnimation.j"
@import "CPAppearance.j"
@import "CPApplication.j"
@import "CPArrayController.j"
@import "CPBezierPath.j"
@@ -109,4 +110,4 @@
@import "CPWebView.j"
@import "CPWindow.j"
@import "CPWindowController.j"
@import "CPWorkspace.j"
@import "CPWorkspace.j"
+148
View File
@@ -0,0 +1,148 @@
/*
* CPAppearance.j
* AppKit
*
* Created by Antoine Mercadal.
* Copyright 2015, Cappuccino Project.
*
* 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.1 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, Boston, MA 02110-1301 USA
*/
@import <Foundation/Foundation.j>
CPAppearanceNameAqua = @"CPAppearanceNameAqua";
CPAppearanceNameLightContent = @"CPAppearanceNameLightContent";
CPAppearanceNameVibrantDark = @"CPAppearanceNameVibrantDark";
CPAppearanceNameVibrantLight = @"CPAppearanceNameVibrantLight";
var _CPAppearanceCurrent = nil,
_CPAppearancesRegistry = @{};
@protocol CPAppearanceCustomization <CPObject>
@required
- (CPAppearance)appearance;
- (void)setAppearance:(CPAppearance)appearance;
- (CPAppearance)effectiveAppearance;
- (void)setEffectiveAppearance:(CPAppearance)appearance;
@end
/*!
@ingroup appkit
A CPAppareance represents the appearance of an to a subset of UI elements.
This is a very lightweight implementation of the NSAppearance system, but
We are using it for compliance, and especially for the CPVisualEffectView
*/
@implementation CPAppearance : CPObject
{
BOOL _allowsVibrancy @accessors(property=allowsVibrancy);
CPString _name;
}
#pragma mark -
#pragma mark Class Methods
/*! Returns the current default CPAppearance
*/
+ (CPAppearance)currentAppearance
{
if (!_CPAppearanceCurrent)
_CPAppearanceCurrent = [CPAppearance appearanceNamed:CPAppearanceNameAqua];
return _CPAppearanceCurrent;
}
/*! Sets the current default CPAppearance
@param appearance the new current appearance
*/
+ (void)setCurrentAppearance:(CPAppearance)anAppearance
{
_CPAppearanceCurrent = anAppearance;
}
/*! Returns the CPAppearance object with the given name
@param name the name of the appearance
*/
+ (CPAppearance)appearanceNamed:(CPString)aName
{
if (![_CPAppearancesRegistry containsKey:aName])
{
[_CPAppearancesRegistry setObject:[[CPAppearance alloc] initWithAppearanceNamed:aName bundle:nil]
forKey:aName];
}
return [_CPAppearancesRegistry objectForKey:aName];
}
#pragma mark -
#pragma mark Initialization
/*! Creates a CPAppearance object initialized to the specified appearance file in the specified bundle
This method does actually nothing special. It just creates a default appearance object
*/
- initWithAppearanceNamed:(CPString)aName bundle:(CPBundle)bundle
{
if (self = [super init])
{
_name = aName;
_allowsVibrancy = YES;
if ([_CPAppearancesRegistry containsKey:aName])
[CPException raise:CPInternalInconsistencyException reason:"Appearance with name '" + aName + "' is already declared."];
[_CPAppearancesRegistry setObject:self forKey:aName];
}
return self;
}
#pragma mark -
#pragma mark Implementation
- (CPString)description
{
return @"<CPAppearance @" + [self UID] + @" name: " + _name + ">";
}
#pragma mark -
#pragma mark CPCoding
- (id)initWithCoder:(CPCoder)aCoder
{
if (self = [super init])
{
_name = [aCoder decodeObjectForKey:@"_name"];
_allowsVibrancy = [aCoder decodeBoolForKey:@"_allowsVibrancy"];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_name forKey:@"_name"];
[aCoder encodeBool:_allowsVibrancy forKey:@"_allowsVibrancy"];
}
@end
+27 -2
View File
@@ -26,6 +26,7 @@
@import "CGAffineTransform.j"
@import "CGGeometry.j"
@import "CPAppearance.j"
@import "CPColor.j"
@import "CPGraphicsContext.j"
@import "CPResponder.j"
@@ -131,7 +132,6 @@ var CPViewFlags = { },
var CPViewHighDPIDrawingEnabled = YES;
/*!
@ingroup appkit
@class CPView
@@ -240,6 +240,9 @@ var CPViewHighDPIDrawingEnabled = YES;
BOOL _toolTipInstalled;
BOOL _isObserving;
BOOL _allowsVibrancy @accessors(property=allowsVibrancy);
CPAppearance _appearance @accessors(property=appearance);
}
/*
@@ -3511,6 +3514,24 @@ setBoundsOrigin:
@end
@implementation CPView (Appeatance)
/*! Returns the received appearance if any, or ask the superview and returns it.
*/
- (CPAppearance)effectiveAppearance
{
if (_appearance)
return _appearance;
if (_superview)
return [_superview appearance];
return nil;
}
@end
var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
CPViewAutoresizesSubviewsKey = @"CPViewAutoresizesSubviews",
CPViewBackgroundColorKey = @"CPViewBackgroundColor",
@@ -3531,7 +3552,8 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
CPReuseIdentifierKey = @"CPReuseIdentifierKey",
CPViewScaleKey = @"CPViewScaleKey",
CPViewSizeScaleKey = @"CPViewSizeScaleKey",
CPViewIsScaledKey = @"CPViewIsScaledKey";
CPViewIsScaledKey = @"CPViewIsScaledKey",
CPViewAppearanceKey = @"CPViewAppearanceKey";
@implementation CPView (CPCoding)
@@ -3646,6 +3668,8 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
_themeAttributes[attributeName] = CPThemeAttributeDecode(aCoder, attributeName, attributes[count], _theme, themeClass);
}
_appearance = [aCoder decodeObjectForKey:CPViewAppearanceKey];
[self setNeedsDisplay:YES];
[self setNeedsLayout];
}
@@ -3734,6 +3758,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
[aCoder encodeSize:[self scaleSize] forKey:CPViewScaleKey];
[aCoder encodeSize:[self _hierarchyScaleSize] forKey:CPViewSizeScaleKey];
[aCoder encodeBool:_isScaled forKey:CPViewIsScaledKey];
[aCoder encodeObject:_appearance forKey:CPViewAppearanceKey];
}
@end
+2 -4
View File
@@ -26,7 +26,6 @@
@import "CGGradient.j"
@import "_CPWindowView.j"
@global CPPopoverAppearanceMinimal
var _CPPopoverWindowViewDefaultCursorSize = CGSizeMake(16, 10);
@@ -39,7 +38,6 @@ var _CPPopoverWindowViewDefaultCursorSize = CGSizeMake(16, 10);
{
float _arrowOffsetX @accessors(property=arrowOffsetX);
float _arrowOffsetY @accessors(property=arrowOffsetY);
int _appearance @accessors(property=appearance);
unsigned _preferredEdge @accessors(property=preferredEdge);
CGSize _cursorSize;
@@ -123,7 +121,7 @@ var _CPPopoverWindowViewDefaultCursorSize = CGSizeMake(16, 10);
{
_arrowOffsetX = 0.0;
_arrowOffsetY = 0.0;
_appearance = CPPopoverAppearanceMinimal;
_appearance = [CPAppearance appearanceNamed:CPAppearanceNameVibrantLight];
_cursorSize = CGSizeMakeCopy(_CPPopoverWindowViewDefaultCursorSize);
}
@@ -168,7 +166,7 @@ var _CPPopoverWindowViewDefaultCursorSize = CGSizeMake(16, 10);
gradient,
frame = [self bounds];
if (_appearance == CPPopoverAppearanceMinimal)
if ([_appearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameVibrantLight]])
{
gradient = [self valueForThemeAttribute:@"background-gradient"];
strokeColor = [self valueForThemeAttribute:@"stroke-color"];
+6 -1
View File
@@ -141,7 +141,12 @@ var _CPPopoverWindow_shouldClose_ = 1 << 4,
if (_appearance === anAppearance)
return;
[_windowView setAppearance:anAppearance];
_appearance = anAppearance;
var appearanceName = _appearance == CPPopoverAppearanceMinimal ? CPAppearanceNameVibrantLight : CPAppearanceNameVibrantDark,
viewAppearance = [CPAppearance appearanceNamed:appearanceName];
[_windowView setAppearance:viewAppearance];
}
- (void)setStyleMask:(unsigned)aStyleMask
+1
View File
@@ -88,6 +88,7 @@
@import "NSSortDescriptor.j"
@import "NSPopover.j"
@import "NSProgressIndicator.j"
@import "NSAppearance.j"
function CP_NSMapClassName(aClassName)
+52
View File
@@ -0,0 +1,52 @@
/*
* NSAppearance.j
* nib2cib
*
* Created by Antoine Mercadal.
* Copyright 2015, Cappuccino Project
*
* 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.1 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, Boston, MA 02110-1301 USA
*/
@import <AppKit/CPAppearance.j>
@implementation CPAppearance (NSCoding)
- (id)NS_initWithCoder:(CPCoder)aCoder
{
if (self = [super init])
{
_name = [aCoder decodeObjectForKey:@"NSAppearanceName"].replace(/^NS/, "CP");
}
return self;
}
@end
@implementation NSAppearance : CPAppearance
- (id)initWithCoder:(CPCoder)aCoder
{
return [self NS_initWithCoder:aCoder];
}
- (Class)classForKeyedArchiver
{
return [CPAppearance class];
}
@end
+2 -1
View File
@@ -604,5 +604,6 @@ var NSClasses = {
"NSWindow" : YES,
"NSWindowController" : YES,
"NSWorkspace" : YES,
"NSPopover": YES
"NSPopover": YES,
"NSAppearance" : YES
};