|
| 1 | +/** |
| 2 | + * Copyright (c) 2015-present, Facebook, Inc. |
| 3 | + * |
| 4 | + * This source code is licensed under the MIT license found in the |
| 5 | + * LICENSE file in the root directory of this source tree. |
| 6 | + */ |
| 7 | + |
| 8 | +// TODO(macOS GH#774) |
| 9 | + |
| 10 | +#import "RCTDynamicColor.h" |
| 11 | + |
| 12 | +#define RCT_FORWARD_PROPERTY( PROP, TYPE ) \ |
| 13 | +- (TYPE)PROP { return [[self effectiveColor] PROP]; } |
| 14 | + |
| 15 | +static NSString *const RCTAquaColor = @"aquaColor"; |
| 16 | +static NSString *const RCTDarkAquaColor = @"darkAquaColor"; |
| 17 | + |
| 18 | +@implementation RCTDynamicColor |
| 19 | +{ |
| 20 | + NSColor *_aquaColor; |
| 21 | + NSColor *_darkAquaColor; |
| 22 | +} |
| 23 | + |
| 24 | +- (instancetype)initWithAquaColor:(NSColor *)aquaColor |
| 25 | + darkAquaColor:(NSColor *)darkAquaColor |
| 26 | +{ |
| 27 | + self = [super init]; |
| 28 | + if (self) { |
| 29 | + _aquaColor = [aquaColor copy]; |
| 30 | + _darkAquaColor = [darkAquaColor copy]; |
| 31 | + } |
| 32 | + return self; |
| 33 | +} |
| 34 | + |
| 35 | ++ (BOOL)supportsSecureCoding |
| 36 | +{ |
| 37 | + return YES; |
| 38 | +} |
| 39 | + |
| 40 | +- (instancetype)initWithCoder:(NSCoder *)coder |
| 41 | +{ |
| 42 | + self = [super initWithCoder:coder]; |
| 43 | + if (self) { |
| 44 | + _aquaColor = [coder decodeObjectOfClass:[NSColor class] forKey:RCTAquaColor]; |
| 45 | + _darkAquaColor = [coder decodeObjectOfClass:[NSColor class] forKey:RCTDarkAquaColor]; |
| 46 | + } |
| 47 | + return self; |
| 48 | +} |
| 49 | + |
| 50 | +- (void)encodeWithCoder:(NSCoder *)aCoder |
| 51 | +{ |
| 52 | + [super encodeWithCoder:aCoder]; |
| 53 | + [aCoder encodeObject:_aquaColor forKey:RCTAquaColor]; |
| 54 | + if (_darkAquaColor) { |
| 55 | + [aCoder encodeObject:_darkAquaColor forKey:RCTDarkAquaColor]; |
| 56 | + } |
| 57 | +} |
| 58 | + |
| 59 | +- (NSColor *)effectiveColor |
| 60 | +{ |
| 61 | + NSColor *effectiveColor = _aquaColor; |
| 62 | + NSAppearance *appearance = [NSAppearance currentAppearance] ?: [NSApp effectiveAppearance]; |
| 63 | + |
| 64 | + NSAppearanceName appearanceName = [appearance bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]]; |
| 65 | + |
| 66 | + if (_darkAquaColor != nil && [appearanceName isEqualToString:NSAppearanceNameDarkAqua]) { |
| 67 | + effectiveColor = _darkAquaColor; |
| 68 | + } |
| 69 | + return effectiveColor; |
| 70 | +} |
| 71 | + |
| 72 | +RCT_FORWARD_PROPERTY(colorSpace, NSColorSpace *) |
| 73 | +- (NSColor *)colorUsingColorSpace:(NSColorSpace *)space |
| 74 | +{ |
| 75 | + return [[self effectiveColor] colorUsingColorSpace:space]; |
| 76 | +} |
| 77 | + |
| 78 | +RCT_FORWARD_PROPERTY(colorSpaceName, NSColorSpaceName) |
| 79 | +- (NSColor *)colorUsingColorSpaceName:(NSColorSpaceName)name |
| 80 | +{ |
| 81 | + return [[self effectiveColor] colorUsingColorSpaceName:name]; |
| 82 | +} |
| 83 | + |
| 84 | +RCT_FORWARD_PROPERTY(numberOfComponents, NSInteger) |
| 85 | +- (void)getComponents:(CGFloat *)components |
| 86 | +{ |
| 87 | + return [[self effectiveColor] getComponents:components]; |
| 88 | +} |
| 89 | + |
| 90 | +#pragma mark - RGB colorspace |
| 91 | + |
| 92 | +RCT_FORWARD_PROPERTY(redComponent, CGFloat) |
| 93 | +RCT_FORWARD_PROPERTY(greenComponent, CGFloat) |
| 94 | +RCT_FORWARD_PROPERTY(blueComponent, CGFloat) |
| 95 | + |
| 96 | +- (void)getRed:(nullable CGFloat *)red green:(nullable CGFloat *)green blue:(nullable CGFloat *)blue alpha:(nullable CGFloat *)alpha |
| 97 | +{ |
| 98 | + return [[self effectiveColor] getRed:red green:green blue:blue alpha:alpha]; |
| 99 | +} |
| 100 | + |
| 101 | +#pragma mark - HSB colorspace |
| 102 | + |
| 103 | +RCT_FORWARD_PROPERTY(hueComponent, CGFloat) |
| 104 | +RCT_FORWARD_PROPERTY(saturationComponent, CGFloat) |
| 105 | +RCT_FORWARD_PROPERTY(brightnessComponent, CGFloat) |
| 106 | + |
| 107 | +- (void)getHue:(nullable CGFloat *)hue saturation:(nullable CGFloat *)saturation brightness:(nullable CGFloat *)brightness alpha:(nullable CGFloat *)alpha |
| 108 | +{ |
| 109 | + return [[self effectiveColor] getHue:hue saturation:saturation brightness:brightness alpha:alpha]; |
| 110 | +} |
| 111 | + |
| 112 | +#pragma mark - Gray colorspace |
| 113 | + |
| 114 | +RCT_FORWARD_PROPERTY(whiteComponent, CGFloat) |
| 115 | + |
| 116 | +- (void)getWhite:(CGFloat *)white alpha:(CGFloat *)alpha |
| 117 | +{ |
| 118 | + return [[self effectiveColor] getWhite:white alpha:alpha]; |
| 119 | +} |
| 120 | + |
| 121 | +#pragma mark - CMYK colorspace |
| 122 | + |
| 123 | +RCT_FORWARD_PROPERTY(cyanComponent, CGFloat) |
| 124 | +RCT_FORWARD_PROPERTY(magentaComponent, CGFloat) |
| 125 | +RCT_FORWARD_PROPERTY(yellowComponent, CGFloat) |
| 126 | +RCT_FORWARD_PROPERTY(blackComponent, CGFloat) |
| 127 | + |
| 128 | +- (void)getCyan:(nullable CGFloat *)cyan magenta:(nullable CGFloat *)magenta yellow:(nullable CGFloat *)yellow black:(nullable CGFloat *)black alpha:(nullable CGFloat *)alpha |
| 129 | +{ |
| 130 | + return [[self effectiveColor] getCyan:cyan magenta:magenta yellow:yellow black:black alpha:alpha]; |
| 131 | +} |
| 132 | + |
| 133 | +#pragma mark - Others |
| 134 | + |
| 135 | +RCT_FORWARD_PROPERTY(alphaComponent, CGFloat) |
| 136 | +RCT_FORWARD_PROPERTY(CGColor, CGColorRef) |
| 137 | +RCT_FORWARD_PROPERTY(catalogNameComponent, NSColorListName) |
| 138 | +RCT_FORWARD_PROPERTY(colorNameComponent, NSColorName) |
| 139 | +RCT_FORWARD_PROPERTY(localizedCatalogNameComponent, NSColorListName) |
| 140 | +RCT_FORWARD_PROPERTY(localizedColorNameComponent, NSString *) |
| 141 | + |
| 142 | +- (void)setStroke |
| 143 | +{ |
| 144 | + [[self effectiveColor] setStroke]; |
| 145 | +} |
| 146 | + |
| 147 | +- (void)setFill |
| 148 | +{ |
| 149 | + [[self effectiveColor] setFill]; |
| 150 | +} |
| 151 | + |
| 152 | +- (void)set |
| 153 | +{ |
| 154 | + [[self effectiveColor] set]; |
| 155 | +} |
| 156 | + |
| 157 | +- (nullable NSColor *)highlightWithLevel:(CGFloat)val |
| 158 | +{ |
| 159 | + return [[self effectiveColor] highlightWithLevel:val]; |
| 160 | +} |
| 161 | + |
| 162 | +- (NSColor *)shadowWithLevel:(CGFloat)val |
| 163 | +{ |
| 164 | + return [[self effectiveColor] shadowWithLevel:val]; |
| 165 | +} |
| 166 | + |
| 167 | +- (NSColor *)colorWithAlphaComponent:(CGFloat)alpha |
| 168 | +{ |
| 169 | + return [[self effectiveColor] colorWithAlphaComponent:alpha]; |
| 170 | +} |
| 171 | + |
| 172 | +- (nullable NSColor *)blendedColorWithFraction:(CGFloat)fraction ofColor:(NSColor *)color |
| 173 | +{ |
| 174 | + return [[self effectiveColor] blendedColorWithFraction:fraction ofColor:color]; |
| 175 | +} |
| 176 | + |
| 177 | +- (NSColor *)colorWithSystemEffect:(NSColorSystemEffect)systemEffect NS_AVAILABLE_MAC(10_14) |
| 178 | +{ |
| 179 | + NSColor *aquaColorWithSystemEffect = [_aquaColor colorWithSystemEffect:systemEffect]; |
| 180 | + NSColor *darkAquaColorWithSystemEffect = [_darkAquaColor colorWithSystemEffect:systemEffect]; |
| 181 | + return [[RCTDynamicColor alloc] initWithAquaColor:aquaColorWithSystemEffect darkAquaColor:darkAquaColorWithSystemEffect]; |
| 182 | +} |
| 183 | + |
| 184 | +- (NSUInteger)hash |
| 185 | +{ |
| 186 | + const NSUInteger prime = 31; |
| 187 | + NSUInteger result = 1; |
| 188 | + result = prime * result + [_aquaColor hash]; |
| 189 | + result = prime * result + [_darkAquaColor hash]; |
| 190 | + return result; |
| 191 | +} |
| 192 | + |
| 193 | +- (BOOL)isEqual:(id)other { |
| 194 | + if (other == self) { |
| 195 | + return YES; |
| 196 | + } |
| 197 | + |
| 198 | + return other != nil && [other isKindOfClass:[self class]] && [self isEqualToDynamicColor:other]; |
| 199 | +} |
| 200 | + |
| 201 | +- (BOOL)isEqualToDynamicColor:(RCTDynamicColor *)other { |
| 202 | + if (self == other) { |
| 203 | + return YES; |
| 204 | + } |
| 205 | + |
| 206 | + if ([_aquaColor isNotEqualTo:other->_aquaColor]) { |
| 207 | + return NO; |
| 208 | + } |
| 209 | + |
| 210 | + if ([_darkAquaColor isNotEqualTo:other->_darkAquaColor]) { |
| 211 | + return NO; |
| 212 | + } |
| 213 | + |
| 214 | + return YES; |
| 215 | +} |
| 216 | + |
| 217 | +@end |
0 commit comments