00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 @import <Foundation/CPObject.j>
00024
00025
00026 var ItemSizes = { },
00027 ThemedObjects = { },
00028 BackgroundColors = { },
00029
00030 LightCheckersColor = nil,
00031 DarkCheckersColor = nil,
00032 WindowBackgroundColor = nil;
00033
00034 @implementation BKThemeDescriptor : CPObject
00035 {
00036 }
00037
00038 + (CPArray)allThemeDescriptorClasses
00039 {
00040
00041 var themeDescriptorClasses = [];
00042
00043 for (candidate in window)
00044 {
00045 var theClass = objj_getClass(candidate),
00046 theClassName = class_getName(theClass);
00047
00048 if (theClassName === "BKThemeDescriptor")
00049 continue;
00050
00051 var index = theClassName.indexOf("ThemeDescriptor");
00052
00053 if ((index >= 0) && (index === theClassName.length - "ThemeDescriptor".length))
00054 themeDescriptorClasses.push(theClass);
00055 }
00056
00057 [themeDescriptorClasses sortUsingSelector:@selector(compare:)];
00058
00059 return themeDescriptorClasses;
00060 }
00061
00062 + (CPColor)lightCheckersColor
00063 {
00064 if (!LightCheckersColor)
00065 LightCheckersColor = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[BKThemeDescriptor class]] pathForResource:@"light-checkers.png"] size:CGSizeMake(12.0, 12.0)]];
00066
00067 return LightCheckersColor;
00068 }
00069
00070 + (CPColor)darkCheckersColor
00071 {
00072 if (!DarkCheckersColor)
00073 DarkCheckersColor = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[BKThemeDescriptor class]] pathForResource:@"dark-checkers.png"] size:CGSizeMake(12.0, 12.0)]];
00074
00075 return DarkCheckersColor;
00076 }
00077
00078 + (CPColor)windowBackgroundColor
00079 {
00080 return [_CPStandardWindowView bodyBackgroundColor];
00081 }
00082
00083 + (CPColor)defaultShowcaseBackgroundColor
00084 {
00085 return [_CPStandardWindowView bodyBackgroundColor];
00086 }
00087
00088 + (CPColor)showcaseBackgroundColor
00089 {
00090 var className = [self className];
00091
00092 if (!BackgroundColors[className])
00093 BackgroundColors[className] = [self defaultShowcaseBackgroundColor];
00094
00095 return BackgroundColors[className];
00096 }
00097
00098 + (void)setShowcaseBackgroundColor:(CPColor)aColor
00099 {
00100 BackgroundColors[[self className]] = aColor;
00101 }
00102
00103 + (CGSize)itemSize
00104 {
00105 var className = [self className];
00106
00107 if (!ItemSizes[className])
00108 [self calculateThemedObjectTemplates];
00109
00110 return CGSizeMakeCopy(ItemSizes[className]);
00111 }
00112
00113 + (CPArray)themedObjectTemplates
00114 {
00115 var className = [self className];
00116
00117 if (!ThemedObjects[className])
00118 [self calculateThemedObjectTemplates];
00119
00120 return ThemedObjects[className];
00121 }
00122
00123 + (void)calculateThemedObjectTemplates
00124 {
00125 var templates = [],
00126 itemSize = CGSizeMake(0.0, 0.0),
00127 methods = class_copyMethodList([self class].isa),
00128 index = 0,
00129 count = [methods count];
00130
00131 for (; index < count; ++index)
00132 {
00133 var method = methods[index],
00134 selector = method_getName(method);
00135
00136 if (selector.indexOf("themed") !== 0)
00137 continue;
00138
00139 var impl = method_getImplementation(method),
00140 object = impl(self, selector);
00141
00142 if (!object)
00143 continue;
00144
00145 var template = [[BKThemedObjectTemplate alloc] init];
00146
00147 [template setValue:object forKey:@"themedObject"];
00148 [template setValue:BKLabelFromIdentifier(selector) forKey:@"label"];
00149
00150 [templates addObject:template];
00151
00152 if ([object isKindOfClass:[CPView class]])
00153 {
00154 var size = [object frame].size,
00155 labelWidth = [[template valueForKey:@"label"] sizeWithFont:[CPFont boldSystemFontOfSize:12.0]].width + 20.0;
00156
00157 if (size.width > itemSize.width)
00158 itemSize.width = size.width;
00159
00160 if (labelWidth > itemSize.width)
00161 itemSize.width = labelWidth;
00162
00163 if (size.height > itemSize.height)
00164 itemSize.height = size.height;
00165 }
00166 }
00167
00168 var className = [self className];
00169
00170 ItemSizes[className] = itemSize;
00171 ThemedObjects[className] = templates;
00172 }
00173
00174 + (int)compare:(BKThemeDescriptor)aThemeDescriptor
00175 {
00176 return [[self themeName] compare:[aThemeDescriptor themeName]];
00177 }
00178
00179 @end
00180
00181 function BKLabelFromIdentifier(anIdentifier)
00182 {
00183 var string = anIdentifier.substr("themed".length);
00184 index = 0,
00185 count = string.length,
00186 label = "",
00187 lastCapital = null,
00188 isLeadingCapital = YES;
00189
00190 for (; index < count; ++index)
00191 {
00192 var character = string.charAt(index),
00193 isCapital = /^[A-Z]/.test(character);
00194
00195 if (isCapital)
00196 {
00197 if (!isLeadingCapital)
00198 {
00199 if (lastCapital === null)
00200 label += ' ' + character.toLowerCase();
00201 else
00202 label += character;
00203 }
00204
00205 lastCapital = character;
00206 }
00207 else
00208 {
00209 if (isLeadingCapital && lastCapital !== null)
00210 label += lastCapital;
00211
00212 label += character;
00213
00214 lastCapital = null;
00215 isLeadingCapital = NO;
00216 }
00217 }
00218
00219 return label;
00220 }
00221