From d303e6e96ceedb47ddf5a45c3f8cbf3f709c3425 Mon Sep 17 00:00:00 2001 From: Aparajita Fishman Date: Tue, 8 Mar 2011 17:39:59 -0500 Subject: [PATCH] Initial commit before testing. --- AppKit/CPFont.j | 187 +- AppKit/CPTabView.j | 8 + Tests/Manual/FontEnhancements/AppController.j | 32 + Tests/Manual/FontEnhancements/Info.plist | 10 + Tests/Manual/FontEnhancements/Jakefile | 94 + .../FontEnhancements/Resources/MainMenu.xib | 3148 +++++++++++++++++ .../FontEnhancements/Resources/spinner.gif | Bin 0 -> 1849 bytes .../Manual/FontEnhancements/index-debug.html | 103 + Tests/Manual/FontEnhancements/index.html | 77 + Tests/Manual/FontEnhancements/main.j | 18 + Tools/nib2cib/Converter+Mac.j | 22 +- Tools/nib2cib/Converter.j | 62 +- Tools/nib2cib/NSAppKit.j | 2 +- Tools/nib2cib/NSButton.j | 7 +- Tools/nib2cib/NSColor.j | 2 +- Tools/nib2cib/NSCustomResource.j | 4 +- Tools/nib2cib/NSFont.j | 49 +- Tools/nib2cib/NSIBObjectData.j | 2 +- Tools/nib2cib/NSMatrix.j | 1 + Tools/nib2cib/NSNibConnector.j | 8 +- Tools/nib2cib/NSTabView.j | 1 + Tools/nib2cib/NSTableColumn.j | 2 +- Tools/nib2cib/NSTextField.j | 2 +- Tools/nib2cib/NSView.j | 13 +- Tools/nib2cib/main.j | 299 +- 25 files changed, 4054 insertions(+), 99 deletions(-) create mode 100644 Tests/Manual/FontEnhancements/AppController.j create mode 100644 Tests/Manual/FontEnhancements/Info.plist create mode 100644 Tests/Manual/FontEnhancements/Jakefile create mode 100644 Tests/Manual/FontEnhancements/Resources/MainMenu.xib create mode 100644 Tests/Manual/FontEnhancements/Resources/spinner.gif create mode 100644 Tests/Manual/FontEnhancements/index-debug.html create mode 100644 Tests/Manual/FontEnhancements/index.html create mode 100644 Tests/Manual/FontEnhancements/main.j diff --git a/AppKit/CPFont.j b/AppKit/CPFont.j index 517ae1b28..f398508dd 100644 --- a/AppKit/CPFont.j +++ b/AppKit/CPFont.j @@ -26,13 +26,15 @@ @import "CPView.j" -var _CPFonts = {}, - _CPFontSystemFontFace = @"Arial, sans-serif", - _CPWrapRegExp = new RegExp("\\s*,\\s*", "g"); +var _CPFonts = {}, + _CPFontSystemFontFace = @"Arial", + _CPFontSystemFontSize = 12, + _CPFontFallbackFaces = [@"Arial", @"sans-serif"], + _CPFontStripRegExp = new RegExp("(^\\s*[\"']?|[\"']?\\s*$)", "g"), + _CPFontStripPropertiesRegExp = new RegExp("^(italic |bold )*\\d+px "); -#define _CPCreateCSSString(aName, aSize, isBold) (isBold ? @"bold " : @"") + ROUND(aSize) + @"px " + ((aName === _CPFontSystemFontFace) ? aName : (@"\"" + aName.replace(_CPWrapRegExp, '", "') + @"\", " + _CPFontSystemFontFace)) -#define _CPCachedFont(aName, aSize, isBold) _CPFonts[_CPCreateCSSString(aName, aSize, isBold)] +#define _CPCachedFont(aName, aSize, isBold, isItalic) _CPFonts[_CPFontCreateCSSString(aName, aSize, isBold, isItalic)] /*! @ingroup appkit @@ -47,78 +49,157 @@ var _CPFonts = {}, float _ascender; float _descender; float _lineHeight; - BOOL _isBold; + BOOL _isBold @accessors(readonly, getter=isBold); + BOOL _isItalic @accessors(readonly, getter=isItalic); CPString _cssString; } + (void)initialize { - var systemFont = [[CPBundle bundleForClass:[CPView class]] objectForInfoDictionaryKey:"CPSystemFontFace"]; + var systemFontFace = [[CPBundle mainBundle] objectForInfoDictionaryKey:@"CPSystemFontFace"]; - if (systemFont) - _CPFontSystemFontFace = systemFont; + if (!systemFontFace) + systemFontFace = [[CPBundle bundleForClass:[CPView class]] objectForInfoDictionaryKey:@"CPSystemFontFace"]; + + if (systemFontFace) + _CPFontSystemFontFace = systemFontFace; + + var systemFontSize = [[CPBundle mainBundle] objectForInfoDictionaryKey:@"CPSystemFontSize"]; + + if (!systemFontSize) + systemFontSize = [[CPBundle bundleForClass:[CPView class]] objectForInfoDictionaryKey:@"CPSystemFontSize"]; + + if (systemFontSize) + _CPFontSystemFontSize = systemFontSize; +} + +/*! + Returns the default system font face, which may consist of several comma-separated family names. +*/ ++ (CPString)systemFontFace +{ + return _CPFontSystemFontFace; +} + +/*! + Sets the default system font face, which may consist of several comma-separated family names. +*/ ++ (CPString)setSystemFontFace:(CPString)aFace +{ + + _CPFontSystemFontFace = aFace; +} + +/*! + Returns the default system font size. +*/ ++ (float)systemFontSize +{ + return _CPFontSystemFontSize; +} + +/*! + Sets the default system font size. +*/ ++ (float)setSystemFontSize:(float)size +{ + if (size > 0) + _CPFontSystemFontSize = size; } /*! Returns a font with the specified name and size. @param aName the name of the font - @param aSize the size of the font (in points) + @param aSize the size of the font (in px) @return the requested font */ + (CPFont)fontWithName:(CPString)aName size:(float)aSize { - return _CPCachedFont(aName, aSize, NO) || [[CPFont alloc] _initWithName:aName size:aSize bold:NO]; + return _CPCachedFont(aName, aSize, NO, NO) || [[CPFont alloc] _initWithName:aName size:aSize bold:NO italic:NO]; +} + +/*! + Returns a font with the specified name, size and style. + @param aName the name of the font + @param aSize the size of the font (in px) + @param italic whether the font should be italicized + @return the requested font +*/ ++ (CPFont)fontWithName:(CPString)aName size:(float)aSize italic:(BOOL)italic +{ + return _CPCachedFont(aName, aSize, NO, NO) || [[CPFont alloc] _initWithName:aName size:aSize bold:NO italic:italic]; } /*! Returns a bold font with the specified name and size. @param aName the name of the font - @param aSize the size of the font (in points) + @param aSize the size of the font (in px) @return the requested bold font */ + (CPFont)boldFontWithName:(CPString)aName size:(float)aSize { - return _CPCachedFont(aName, aSize, YES) || [[CPFont alloc] _initWithName:aName size:aSize bold:YES]; + return _CPCachedFont(aName, aSize, YES, NO) || [[CPFont alloc] _initWithName:aName size:aSize bold:YES italic:NO]; +} + +/*! + Returns a bold font with the specified name, size and style. + @param aName the name of the font + @param aSize the size of the font (in px) + @param italic whether the font should be italicized + @return the requested font +*/ ++ (CPFont)boldFontWithName:(CPString)aName size:(float)aSize italic:(BOOL)italic +{ + return _CPCachedFont(aName, aSize, NO, NO) || [[CPFont alloc] _initWithName:aName size:aSize bold:YES italic:italic]; } /*! Returns the system font scaled to the specified size - @param aSize the size of the font (in points) + @param aSize the size of the font (in px) @return the requested system font */ + (CPFont)systemFontOfSize:(CPSize)aSize { - return _CPCachedFont(_CPFontSystemFontFace, aSize, NO) || [[CPFont alloc] _initWithName:_CPFontSystemFontFace size:aSize bold:NO]; + return _CPCachedFont(_CPFontSystemFontFace, aSize, NO, NO) || [[CPFont alloc] _initWithName:_CPFontSystemFontFace size:aSize bold:NO italic:NO]; } /*! Returns the bold system font scaled to the specified size - @param aSize the size of the font (in points) + @param aSize the size of the font (in px) @return the requested bold system font */ + (CPFont)boldSystemFontOfSize:(CPSize)aSize { - return _CPCachedFont(_CPFontSystemFontFace, aSize, YES) || [[CPFont alloc] _initWithName:_CPFontSystemFontFace size:aSize bold:YES]; + return _CPCachedFont(_CPFontSystemFontFace, aSize, YES, NO) || [[CPFont alloc] _initWithName:_CPFontSystemFontFace size:aSize bold:YES italic:NO]; } /* FIXME Font Descriptor @ignore */ - (id)_initWithName:(CPString)aName size:(float)aSize bold:(BOOL)isBold +{ + return [self _initWithName:aName size:aSize bold:isBold italic:NO]; +} + +- (id)_initWithName:(CPString)aName size:(float)aSize bold:(BOOL)isBold italic:(BOOL)isItalic { self = [super init]; if (self) { - _name = aName; + // Normalize all of the names + var names = _CPFontNormalizedNames(aName); + + _name = names[0]; _size = aSize; _ascender = 0; _descender = 0; _lineHeight = 0; _isBold = isBold; + _isItalic = isItalic; - _cssString = _CPCreateCSSString(_name, _size, _isBold); + _cssString = _CPFontCreateCSSString(names, _size, _isBold, _isItalic); _CPFonts[_cssString] = self; } @@ -139,7 +220,7 @@ var _CPFonts = {}, /*! Returns the bottom y coordinate (in CSS px), offset from the baseline, of the receiver's longest descender. - Thus, if the longest descender extends 2 points below the baseline, descender will return –2. + Thus, if the longest descender extends 2 px below the baseline, descender will return –2. */ - (float)descender { @@ -188,12 +269,17 @@ var _CPFonts = {}, - (BOOL)isEqual:(id)anObject { - return [anObject isKindOfClass:[CPFont class]] && [anObject cssString] === [self cssString]; + return [anObject isKindOfClass:[CPFont class]] && [anObject cssString] === _cssString; } - (CPString)description { - return [CPString stringWithFormat:@"%@ %@ %f pt.", [super description], [self familyName], [self size]]; + return [CPString stringWithFormat:@"%@ %@", [super description], [self cssString]]; +} + +- (id)copy +{ + return [[CPFont alloc] _initWithName:_name size:_size bold:_isBold italic:_isItalic]; } - (void)_getMetrics @@ -207,9 +293,10 @@ var _CPFonts = {}, @end -var CPFontNameKey = @"CPFontNameKey", - CPFontSizeKey = @"CPFontSizeKey", - CPFontIsBoldKey = @"CPFontIsBoldKey"; +var CPFontNameKey = @"CPFontNameKey", + CPFontSizeKey = @"CPFontSizeKey", + CPFontIsBoldKey = @"CPFontIsBoldKey", + CPFontIsItalicKey = @"CPFontIsItalicKey"; @implementation CPFont (CPCoding) @@ -220,9 +307,12 @@ var CPFontNameKey = @"CPFontNameKey", */ - (id)initWithCoder:(CPCoder)aCoder { - return [self _initWithName:[aCoder decodeObjectForKey:CPFontNameKey] - size:[aCoder decodeFloatForKey:CPFontSizeKey] - bold:[aCoder decodeBoolForKey:CPFontIsBoldKey]]; + var fontName = [aCoder decodeObjectForKey:CPFontNameKey], + size = [aCoder decodeFloatForKey:CPFontSizeKey], + isBold = [aCoder decodeBoolForKey:CPFontIsBoldKey], + isItalic = [aCoder decodeBoolForKey:CPFontIsItalicKey]; + + return [self _initWithName:fontName size:size bold:isBold italic:isItalic]; } /*! @@ -231,9 +321,48 @@ var CPFontNameKey = @"CPFontNameKey", */ - (void)encodeWithCoder:(CPCoder)aCoder { - [aCoder encodeObject:_name forKey:CPFontNameKey]; + var name = _cssString.replace(_CPFontStripPropertiesRegExp, ""); + + [aCoder encodeObject:name forKey:CPFontNameKey]; [aCoder encodeFloat:_size forKey:CPFontSizeKey]; [aCoder encodeBool:_isBold forKey:CPFontIsBoldKey]; + [aCoder encodeBool:_isItalic forKey:CPFontIsItalicKey]; } @end + + +var _CPFontCreateCSSString = function(aName, aSize, isBold, isItalic) +{ + // aName might be a string or an array of preprocessed names + var names = typeof(aName) === "string" ? _CPFontNormalizedNames(aName) : aName, + properties = (isItalic ? "italic " : "") + (isBold ? "bold " : "") + aSize + "px ", + fallbackFaces = _CPFontFallbackFaces.slice(0); + + // Remove the standard fallback names from the names passed in + for (var i = 0; i < fallbackFaces.length; ) + { + for (var j = 0; j < names.length; ++j) + { + if (fallbackFaces[i].toLowerCase() === names[j].toLowerCase()) + { + fallbackFaces.splice(i, 1); + continue; + } + } + + ++i; + } + + return properties + '"' + names.concat(fallbackFaces).join("\", \"") + '"'; +}; + +var _CPFontNormalizedNames = function(aName) +{ + var names = aName.split(","); + + for (var i = 0; i < names.length; ++i) + names[i] = names[i].replace(_CPFontStripRegExp, ""); + + return names; +}; diff --git a/AppKit/CPTabView.j b/AppKit/CPTabView.j index 7ed7b2af6..c48defb31 100644 --- a/AppKit/CPTabView.j +++ b/AppKit/CPTabView.j @@ -26,6 +26,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1, CPNumber _selectedIndex; CPTabViewType _type; + CPFont _font; id _delegate; unsigned _delegateSelectors; @@ -415,6 +416,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1, var CPTabViewItemsKey = "CPTabViewItemsKey", CPTabViewSelectedItemKey = "CPTabViewSelectedItemKey", CPTabViewTypeKey = "CPTabViewTypeKey", + CPTabViewFontKey = "CPTabViewFontKey", CPTabViewDelegateKey = "CPTabViewDelegateKey"; @implementation CPTabView (CPCoding) @@ -425,18 +427,23 @@ var CPTabViewItemsKey = "CPTabViewItemsKey", { [self _init]; + _font = [aCoder decodeObjectForKey:CPTabViewFontKey]; + [_tabs setFont:_font]; + _items = [aCoder decodeObjectForKey:CPTabViewItemsKey]; [self _updateItems]; [self _repositionTabs]; var selected = [aCoder decodeObjectForKey:CPTabViewSelectedItemKey]; + if (selected) [self selectTabViewItem:selected]; [self setDelegate:[aCoder decodeObjectForKey:CPTabViewDelegateKey]]; [self setTabViewType:[aCoder decodeIntForKey:CPTabViewTypeKey]]; + } return self; @@ -450,6 +457,7 @@ var CPTabViewItemsKey = "CPTabViewItemsKey", [aCoder encodeObject:[self selectedTabViewItem] forKey:CPTabViewSelectedItemKey]; [aCoder encodeInt:_type forKey:CPTabViewTypeKey]; + [aCoder encodeObject:_font forKey:CPTabViewFontKey]; [aCoder encodeConditionalObject:_delegate forKey:CPTabViewDelegateKey]; } diff --git a/Tests/Manual/FontEnhancements/AppController.j b/Tests/Manual/FontEnhancements/AppController.j new file mode 100644 index 000000000..21fd6492d --- /dev/null +++ b/Tests/Manual/FontEnhancements/AppController.j @@ -0,0 +1,32 @@ +/* + * AppController.j + * FontEnhancements + * + * Created by aparajita on March 8, 2011. + * Copyright 2011, Victory-Heart Productions All rights reserved. + */ + +@import + + +@implementation AppController : CPObject +{ + CPWindow theWindow; //this "outlet" is connected automatically by the Cib +} + +- (void)applicationDidFinishLaunching:(CPNotification)aNotification +{ + +} + +- (void)awakeFromCib +{ + // This is called when the cib is done loading. + // You can implement this method on any object instantiated from a Cib. + // It's a useful hook for setting up current UI values, and other things. + + // In this case, we want the window from Cib to become our full browser window + [theWindow setFullPlatformWindow:YES]; +} + +@end diff --git a/Tests/Manual/FontEnhancements/Info.plist b/Tests/Manual/FontEnhancements/Info.plist new file mode 100644 index 000000000..d4176fb32 --- /dev/null +++ b/Tests/Manual/FontEnhancements/Info.plist @@ -0,0 +1,10 @@ + + + + + Main cib file base name + MainMenu.cib + CPBundleName + FontEnhancements + + diff --git a/Tests/Manual/FontEnhancements/Jakefile b/Tests/Manual/FontEnhancements/Jakefile new file mode 100644 index 000000000..3587748f5 --- /dev/null +++ b/Tests/Manual/FontEnhancements/Jakefile @@ -0,0 +1,94 @@ +/* + * Jakefile + * FontEnhancements + * + * Created by aparajita on March 8, 2011. + * Copyright 2011, Victory-Heart Productions All rights reserved. + */ + +var ENV = require("system").env, + FILE = require("file"), + JAKE = require("jake"), + task = JAKE.task, + FileList = JAKE.FileList, + app = require("cappuccino/jake").app, + configuration = ENV["CONFIG"] || ENV["CONFIGURATION"] || ENV["c"] || "Debug", + OS = require("os"); + +app ("FontEnhancements", function(task) +{ + task.setBuildIntermediatesPath(FILE.join("Build", "FontEnhancements.build", configuration)); + task.setBuildPath(FILE.join("Build", configuration)); + + task.setProductName("FontEnhancements"); + task.setIdentifier("com.aparajitaworld.FontEnhancements"); + task.setVersion("1.0"); + task.setAuthor("Victory-Heart Productions"); + task.setEmail("feedback @nospam@ yourcompany.com"); + task.setSummary("FontEnhancements"); + task.setSources((new FileList("**/*.j")).exclude(FILE.join("Build", "**"))); + task.setResources(new FileList("Resources/**")); + task.setIndexFilePath("index.html"); + task.setInfoPlistPath("Info.plist"); + task.setNib2CibFlags("-R Resources/"); + + if (configuration === "Debug") + task.setCompilerFlags("-DDEBUG -g"); + else + task.setCompilerFlags("-O"); +}); + +task ("default", ["FontEnhancements"], function() +{ + printResults(configuration); +}); + +task ("build", ["default"]); + +task ("debug", function() +{ + ENV["CONFIGURATION"] = "Debug"; + JAKE.subjake(["."], "build", ENV); +}); + +task ("release", function() +{ + ENV["CONFIGURATION"] = "Release"; + JAKE.subjake(["."], "build", ENV); +}); + +task ("run", ["debug"], function() +{ + OS.system(["open", FILE.join("Build", "Debug", "FontEnhancements", "index.html")]); +}); + +task ("run-release", ["release"], function() +{ + OS.system(["open", FILE.join("Build", "Release", "FontEnhancements", "index.html")]); +}); + +task ("deploy", ["release"], function() +{ + FILE.mkdirs(FILE.join("Build", "Deployment", "FontEnhancements")); + OS.system(["press", "-f", FILE.join("Build", "Release", "FontEnhancements"), FILE.join("Build", "Deployment", "FontEnhancements")]); + printResults("Deployment") +}); + +task ("desktop", ["release"], function() +{ + FILE.mkdirs(FILE.join("Build", "Desktop", "FontEnhancements")); + require("cappuccino/nativehost").buildNativeHost(FILE.join("Build", "Release", "FontEnhancements"), FILE.join("Build", "Desktop", "FontEnhancements", "FontEnhancements.app")); + printResults("Desktop") +}); + +task ("run-desktop", ["desktop"], function() +{ + OS.system([FILE.join("Build", "Desktop", "FontEnhancements", "FontEnhancements.app", "Contents", "MacOS", "NativeHost"), "-i"]); +}); + +function printResults(configuration) +{ + print("----------------------------"); + print(configuration+" app built at path: "+FILE.join("Build", configuration, "FontEnhancements")); + print("----------------------------"); +} diff --git a/Tests/Manual/FontEnhancements/Resources/MainMenu.xib b/Tests/Manual/FontEnhancements/Resources/MainMenu.xib new file mode 100644 index 000000000..e9ae190c4 --- /dev/null +++ b/Tests/Manual/FontEnhancements/Resources/MainMenu.xib @@ -0,0 +1,3148 @@ + + + + 1050 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilder.CocoaPlugin + + + YES + + YES + + + YES + + + + YES + + NSApplication + + + FirstResponder + + + NSApplication + + + AMainMenu + + YES + + + NewApplication + + 1048576 + 2147483647 + + NSImage + NSMenuCheckmark + + + NSImage + NSMenuMixedState + + submenuAction: + + NewApplication + + YES + + + About NewApplication + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + UHJlZmVyZW5jZXPigKY + , + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Services + + 1048576 + 2147483647 + + + submenuAction: + + Services + + YES + + _NSServicesMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Hide NewApplication + h + 1048576 + 2147483647 + + + + + + Hide Others + h + 1572864 + 2147483647 + + + + + + Show All + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Quit NewApplication + q + 1048576 + 2147483647 + + + + + _NSAppleMenu + + + + + File + + 1048576 + 2147483647 + + + submenuAction: + + File + + YES + + + New + n + 1048576 + 2147483647 + + + + + + T3BlbuKApg + o + 1048576 + 2147483647 + + + + + + Open Recent + + 1048576 + 2147483647 + + + submenuAction: + + Open Recent + + YES + + + Clear Menu + + 1048576 + 2147483647 + + + + + _NSRecentDocumentsMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Close + w + 1048576 + 2147483647 + + + + + + Save + s + 1048576 + 2147483647 + + + + + + U2F2ZSBBc+KApg + S + 1179648 + 2147483647 + + + + + + Revert to Saved + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Page Setup... + P + 1179648 + 2147483647 + + + + + + + UHJpbnTigKY + p + 1048576 + 2147483647 + + + + + + + + + Edit + + 1048576 + 2147483647 + + + submenuAction: + + Edit + + YES + + + Undo + z + 1048576 + 2147483647 + + + + + + Redo + Z + 1179648 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Cut + x + 1048576 + 2147483647 + + + + + + Copy + c + 1048576 + 2147483647 + + + + + + Paste + v + 1048576 + 2147483647 + + + + + + Delete + + 1048576 + 2147483647 + + + + + + Select All + a + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Find + + 1048576 + 2147483647 + + + submenuAction: + + Find + + YES + + + RmluZOKApg + f + 1048576 + 2147483647 + + + 1 + + + + Find Next + g + 1048576 + 2147483647 + + + 2 + + + + Find Previous + G + 1179648 + 2147483647 + + + 3 + + + + Use Selection for Find + e + 1048576 + 2147483647 + + + 7 + + + + Jump to Selection + j + 1048576 + 2147483647 + + + + + + + + + Spelling and Grammar + + 1048576 + 2147483647 + + + submenuAction: + + Spelling and Grammar + + YES + + + U2hvdyBTcGVsbGluZ+KApg + : + 1048576 + 2147483647 + + + + + + Check Spelling + ; + 1048576 + 2147483647 + + + + + + Check Spelling While Typing + + 1048576 + 2147483647 + + + + + + Check Grammar With Spelling + + 1048576 + 2147483647 + + + + + + + + + Substitutions + + 1048576 + 2147483647 + + + submenuAction: + + Substitutions + + YES + + + Smart Copy/Paste + f + 1048576 + 2147483647 + + + 1 + + + + Smart Quotes + g + 1048576 + 2147483647 + + + 2 + + + + Smart Links + G + 1179648 + 2147483647 + + + 3 + + + + + + + Speech + + 1048576 + 2147483647 + + + submenuAction: + + Speech + + YES + + + Start Speaking + + 1048576 + 2147483647 + + + + + + Stop Speaking + + 1048576 + 2147483647 + + + + + + + + + + + + Format + + 2147483647 + + + submenuAction: + + Format + + YES + + + Font + + 2147483647 + + + submenuAction: + + Font + + YES + + + Show Fonts + t + 1048576 + 2147483647 + + + + + + Bold + b + 1048576 + 2147483647 + + + 2 + + + + Italic + i + 1048576 + 2147483647 + + + 1 + + + + Underline + u + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Bigger + + + 1048576 + 2147483647 + + + 3 + + + + Smaller + - + 1048576 + 2147483647 + + + 4 + + + + YES + YES + + + 2147483647 + + + + + + Kern + + 2147483647 + + + submenuAction: + + Kern + + YES + + + Use Default + + 2147483647 + + + + + + Use None + + 2147483647 + + + + + + Tighten + + 2147483647 + + + + + + Loosen + + 2147483647 + + + + + + + + + Ligature + + 2147483647 + + + submenuAction: + + Ligature + + YES + + + Use Default + + 2147483647 + + + + + + Use None + + 2147483647 + + + + + + Use All + + 2147483647 + + + + + + + + + Baseline + + 2147483647 + + + submenuAction: + + Baseline + + YES + + + Use Default + + 2147483647 + + + + + + Superscript + + 2147483647 + + + + + + Subscript + + 2147483647 + + + + + + Raise + + 2147483647 + + + + + + Lower + + 2147483647 + + + + + + + + + YES + YES + + + 2147483647 + + + + + + Show Colors + C + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Copy Style + c + 1572864 + 2147483647 + + + + + + Paste Style + v + 1572864 + 2147483647 + + + + + _NSFontMenu + + + + + Text + + 2147483647 + + + submenuAction: + + Text + + YES + + + Align Left + { + 1048576 + 2147483647 + + + + + + Center + | + 1048576 + 2147483647 + + + + + + Justify + + 2147483647 + + + + + + Align Right + } + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Show Ruler + + 2147483647 + + + + + + Copy Ruler + c + 1310720 + 2147483647 + + + + + + Paste Ruler + v + 1310720 + 2147483647 + + + + + + + + + + + + View + + 1048576 + 2147483647 + + + submenuAction: + + View + + YES + + + Show Toolbar + t + 1572864 + 2147483647 + + + + + + Q3VzdG9taXplIFRvb2xiYXLigKY + + 1048576 + 2147483647 + + + + + + + + + Window + + 1048576 + 2147483647 + + + submenuAction: + + Window + + YES + + + Minimize + m + 1048576 + 2147483647 + + + + + + Zoom + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Bring All to Front + + 1048576 + 2147483647 + + + + + _NSWindowsMenu + + + + + Help + + 1048576 + 2147483647 + + + submenuAction: + + Help + + YES + + + NewApplication Help + ? + 1048576 + 2147483647 + + + + + + + + _NSMainMenu + + + 7 + 2 + {{335, 390}, {480, 360}} + 1946157056 + Window + NSWindow + + {3.40282e+38, 3.40282e+38} + + + 256 + + YES + + + 301 + {{192, 143}, {96, 21}} + + YES + + -2080244224 + 0 + + + Helvetica + 1.200000e+01 + 16 + + + 1.000000e+02 + 0.000000e+00 + 5.000000e+01 + 0.000000e+00 + 0 + 1 + NO + NO + + + + + 301 + {{192, 191}, {96, 22}} + + YES + + -1804468671 + 272630784 + + + LucidaGrande + 1.300000e+01 + 1044 + + + YES + + 6 + System + textBackgroundColor + + 3 + MQA + + + + 6 + System + textColor + + 3 + MAA + + + + + + {480, 360} + + + {{0, 0}, {1440, 878}} + {3.40282e+38, 3.40282e+38} + + + AppController + + + + + YES + + + performMiniaturize: + + + + 37 + + + + arrangeInFront: + + + + 39 + + + + print: + + + + 86 + + + + runPageLayout: + + + + 87 + + + + clearRecentDocuments: + + + + 127 + + + + orderFrontStandardAboutPanel: + + + + 142 + + + + performClose: + + + + 193 + + + + toggleContinuousSpellChecking: + + + + 222 + + + + undo: + + + + 223 + + + + copy: + + + + 224 + + + + checkSpelling: + + + + 225 + + + + paste: + + + + 226 + + + + stopSpeaking: + + + + 227 + + + + cut: + + + + 228 + + + + showGuessPanel: + + + + 230 + + + + redo: + + + + 231 + + + + selectAll: + + + + 232 + + + + startSpeaking: + + + + 233 + + + + delete: + + + + 235 + + + + performZoom: + + + + 240 + + + + performFindPanelAction: + + + + 241 + + + + centerSelectionInVisibleArea: + + + + 245 + + + + toggleGrammarChecking: + + + + 347 + + + + toggleSmartInsertDelete: + + + + 355 + + + + toggleAutomaticQuoteSubstitution: + + + + 356 + + + + toggleAutomaticLinkDetection: + + + + 357 + + + + showHelp: + + + + 360 + + + + saveDocument: + + + + 362 + + + + saveDocumentAs: + + + + 363 + + + + revertDocumentToSaved: + + + + 364 + + + + runToolbarCustomizationPalette: + + + + 365 + + + + toggleToolbarShown: + + + + 366 + + + + hide: + + + + 367 + + + + hideOtherApplications: + + + + 368 + + + + unhideAllApplications: + + + + 370 + + + + newDocument: + + + + 373 + + + + openDocument: + + + + 374 + + + + raiseBaseline: + + + + 426 + + + + lowerBaseline: + + + + 427 + + + + copyFont: + + + + 428 + + + + subscript: + + + + 429 + + + + superscript: + + + + 430 + + + + tightenKerning: + + + + 431 + + + + underline: + + + + 432 + + + + orderFrontColorPanel: + + + + 433 + + + + useAllLigatures: + + + + 434 + + + + loosenKerning: + + + + 435 + + + + pasteFont: + + + + 436 + + + + unscript: + + + + 437 + + + + useStandardKerning: + + + + 438 + + + + useStandardLigatures: + + + + 439 + + + + turnOffLigatures: + + + + 440 + + + + turnOffKerning: + + + + 441 + + + + alignLeft: + + + + 442 + + + + alignJustified: + + + + 443 + + + + copyRuler: + + + + 444 + + + + alignCenter: + + + + 445 + + + + toggleRuler: + + + + 446 + + + + alignRight: + + + + 447 + + + + pasteRuler: + + + + 448 + + + + terminate: + + + + 449 + + + + delegate + + + + 451 + + + + takeDoubleValueFrom: + + + + 458 + + + + theWindow + + + + 459 + + + + + YES + + 0 + + YES + + + + + + -2 + + + RmlsZSdzIE93bmVyA + + + -1 + + + First Responder + + + -3 + + + Application + + + 29 + + + YES + + + + + + + + + + MainMenu + + + 19 + + + YES + + + + + + 56 + + + YES + + + + + + 103 + + + YES + + + + 1 + + + 217 + + + YES + + + + + + 83 + + + YES + + + + + + 81 + + + YES + + + + + + + + + + + + + + + + 75 + + + 3 + + + 80 + + + 8 + + + 78 + + + 6 + + + 72 + + + + + 82 + + + 9 + + + 124 + + + YES + + + + + + 77 + + + 5 + + + 73 + + + 1 + + + 79 + + + 7 + + + 112 + + + 10 + + + 74 + + + 2 + + + 125 + + + YES + + + + + + 126 + + + + + 205 + + + YES + + + + + + + + + + + + + + + + + + 202 + + + + + 198 + + + + + 207 + + + + + 214 + + + + + 199 + + + + + 203 + + + + + 197 + + + + + 206 + + + + + 215 + + + + + 218 + + + YES + + + + + + 216 + + + YES + + + + + + 200 + + + YES + + + + + + + + + 219 + + + + + 201 + + + + + 204 + + + + + 220 + + + YES + + + + + + + + + + 213 + + + + + 210 + + + + + 221 + + + + + 208 + + + + + 209 + + + + + 106 + + + YES + + + + 2 + + + 111 + + + + + 57 + + + YES + + + + + + + + + + + + + + + + 58 + + + + + 134 + + + + + 150 + + + + + 136 + + + 1111 + + + 144 + + + + + 129 + + + 121 + + + 143 + + + + + 236 + + + + + 131 + + + YES + + + + + + 149 + + + + + 145 + + + + + 130 + + + + + 24 + + + YES + + + + + + + + + 92 + + + + + 5 + + + + + 239 + + + + + 23 + + + + + 295 + + + YES + + + + + + 296 + + + YES + + + + + + + 297 + + + + + 298 + + + + + 211 + + + YES + + + + + + 212 + + + YES + + + + + + + 195 + + + + + 196 + + + + + 346 + + + + + 348 + + + YES + + + + + + 349 + + + YES + + + + + + + + 350 + + + + + 351 + + + + + 354 + + + + + 371 + + + YES + + + + + + 372 + + + YES + + + + + + + 375 + + + YES + + + + + + 376 + + + YES + + + + + + + 377 + + + YES + + + + + + 378 + + + YES + + + + + + 379 + + + YES + + + + + + + + + + + + + 380 + + + + + 381 + + + + + 382 + + + + + 383 + + + + + 384 + + + + + 385 + + + + + 386 + + + + + 387 + + + + + 388 + + + YES + + + + + + + + + + + + + + + + + + + + + 389 + + + + + 390 + + + + + 391 + + + + + 392 + + + + + 393 + + + + + 394 + + + + + 395 + + + + + 396 + + + + + 397 + + + YES + + + + + + 398 + + + YES + + + + + + 399 + + + YES + + + + + + 400 + + + + + 401 + + + + + 402 + + + + + 403 + + + + + 404 + + + + + 405 + + + YES + + + + + + + + + + 406 + + + + + 407 + + + + + 408 + + + + + 409 + + + + + 410 + + + + + 411 + + + YES + + + + + + + + 412 + + + + + 413 + + + + + 414 + + + + + 415 + + + YES + + + + + + + + + 416 + + + + + 417 + + + + + 418 + + + + + 419 + + + + + 450 + + + + + 452 + + + YES + + + + + + 453 + + + + + 456 + + + YES + + + + + + 457 + + + + + + + YES + + YES + -1.IBPluginDependency + -2.IBPluginDependency + -3.IBPluginDependency + 103.IBPluginDependency + 103.ImportedFromIB2 + 106.IBPluginDependency + 106.ImportedFromIB2 + 106.editorWindowContentRectSynchronizationRect + 111.IBPluginDependency + 111.ImportedFromIB2 + 112.IBPluginDependency + 112.ImportedFromIB2 + 124.IBPluginDependency + 124.ImportedFromIB2 + 125.IBPluginDependency + 125.ImportedFromIB2 + 125.editorWindowContentRectSynchronizationRect + 126.IBPluginDependency + 126.ImportedFromIB2 + 129.IBPluginDependency + 129.ImportedFromIB2 + 130.IBPluginDependency + 130.ImportedFromIB2 + 130.editorWindowContentRectSynchronizationRect + 131.IBPluginDependency + 131.ImportedFromIB2 + 134.IBPluginDependency + 134.ImportedFromIB2 + 136.IBPluginDependency + 136.ImportedFromIB2 + 143.IBPluginDependency + 143.ImportedFromIB2 + 144.IBPluginDependency + 144.ImportedFromIB2 + 145.IBPluginDependency + 145.ImportedFromIB2 + 149.IBPluginDependency + 149.ImportedFromIB2 + 150.IBPluginDependency + 150.ImportedFromIB2 + 19.IBPluginDependency + 19.ImportedFromIB2 + 195.IBPluginDependency + 195.ImportedFromIB2 + 196.IBPluginDependency + 196.ImportedFromIB2 + 197.IBPluginDependency + 197.ImportedFromIB2 + 198.IBPluginDependency + 198.ImportedFromIB2 + 199.IBPluginDependency + 199.ImportedFromIB2 + 200.IBPluginDependency + 200.ImportedFromIB2 + 200.editorWindowContentRectSynchronizationRect + 201.IBPluginDependency + 201.ImportedFromIB2 + 202.IBPluginDependency + 202.ImportedFromIB2 + 203.IBPluginDependency + 203.ImportedFromIB2 + 204.IBPluginDependency + 204.ImportedFromIB2 + 205.IBPluginDependency + 205.ImportedFromIB2 + 205.editorWindowContentRectSynchronizationRect + 206.IBPluginDependency + 206.ImportedFromIB2 + 207.IBPluginDependency + 207.ImportedFromIB2 + 208.IBPluginDependency + 208.ImportedFromIB2 + 209.IBPluginDependency + 209.ImportedFromIB2 + 210.IBPluginDependency + 210.ImportedFromIB2 + 211.IBPluginDependency + 211.ImportedFromIB2 + 212.IBPluginDependency + 212.ImportedFromIB2 + 212.editorWindowContentRectSynchronizationRect + 213.IBPluginDependency + 213.ImportedFromIB2 + 214.IBPluginDependency + 214.ImportedFromIB2 + 215.IBPluginDependency + 215.ImportedFromIB2 + 216.IBPluginDependency + 216.ImportedFromIB2 + 217.IBPluginDependency + 217.ImportedFromIB2 + 218.IBPluginDependency + 218.ImportedFromIB2 + 219.IBPluginDependency + 219.ImportedFromIB2 + 220.IBPluginDependency + 220.ImportedFromIB2 + 220.editorWindowContentRectSynchronizationRect + 221.IBPluginDependency + 221.ImportedFromIB2 + 23.IBPluginDependency + 23.ImportedFromIB2 + 236.IBPluginDependency + 236.ImportedFromIB2 + 239.IBPluginDependency + 239.ImportedFromIB2 + 24.IBPluginDependency + 24.ImportedFromIB2 + 24.editorWindowContentRectSynchronizationRect + 29.IBEditorWindowLastContentRect + 29.IBPluginDependency + 29.ImportedFromIB2 + 29.WindowOrigin + 29.editorWindowContentRectSynchronizationRect + 295.IBPluginDependency + 296.IBPluginDependency + 296.editorWindowContentRectSynchronizationRect + 297.IBPluginDependency + 298.IBPluginDependency + 346.IBPluginDependency + 346.ImportedFromIB2 + 348.IBPluginDependency + 348.ImportedFromIB2 + 349.IBPluginDependency + 349.ImportedFromIB2 + 349.editorWindowContentRectSynchronizationRect + 350.IBPluginDependency + 350.ImportedFromIB2 + 351.IBPluginDependency + 351.ImportedFromIB2 + 354.IBPluginDependency + 354.ImportedFromIB2 + 371.IBEditorWindowLastContentRect + 371.IBWindowTemplateEditedContentRect + 371.NSWindowTemplate.visibleAtLaunch + 371.editorWindowContentRectSynchronizationRect + 371.windowTemplate.maxSize + 372.IBPluginDependency + 375.IBPluginDependency + 376.IBEditorWindowLastContentRect + 376.IBPluginDependency + 377.IBPluginDependency + 378.IBPluginDependency + 379.IBPluginDependency + 380.IBPluginDependency + 381.IBPluginDependency + 382.IBPluginDependency + 383.IBPluginDependency + 384.IBPluginDependency + 385.IBPluginDependency + 386.IBPluginDependency + 387.IBPluginDependency + 388.IBEditorWindowLastContentRect + 388.IBPluginDependency + 389.IBPluginDependency + 390.IBPluginDependency + 391.IBPluginDependency + 392.IBPluginDependency + 393.IBPluginDependency + 394.IBPluginDependency + 395.IBPluginDependency + 396.IBPluginDependency + 397.IBPluginDependency + 398.IBPluginDependency + 399.IBPluginDependency + 400.IBPluginDependency + 401.IBPluginDependency + 402.IBPluginDependency + 403.IBPluginDependency + 404.IBPluginDependency + 405.IBPluginDependency + 406.IBPluginDependency + 407.IBPluginDependency + 408.IBPluginDependency + 409.IBPluginDependency + 410.IBPluginDependency + 411.IBPluginDependency + 412.IBPluginDependency + 413.IBPluginDependency + 414.IBPluginDependency + 415.IBPluginDependency + 416.IBPluginDependency + 417.IBPluginDependency + 418.IBPluginDependency + 419.IBPluginDependency + 450.IBPluginDependency + 452.IBPluginDependency + 453.IBPluginDependency + 456.IBPluginDependency + 457.IBPluginDependency + 5.IBPluginDependency + 5.ImportedFromIB2 + 56.IBPluginDependency + 56.ImportedFromIB2 + 57.IBEditorWindowLastContentRect + 57.IBPluginDependency + 57.ImportedFromIB2 + 57.editorWindowContentRectSynchronizationRect + 58.IBPluginDependency + 58.ImportedFromIB2 + 72.IBPluginDependency + 72.ImportedFromIB2 + 73.IBPluginDependency + 73.ImportedFromIB2 + 74.IBPluginDependency + 74.ImportedFromIB2 + 75.IBPluginDependency + 75.ImportedFromIB2 + 77.IBPluginDependency + 77.ImportedFromIB2 + 78.IBPluginDependency + 78.ImportedFromIB2 + 79.IBPluginDependency + 79.ImportedFromIB2 + 80.IBPluginDependency + 80.ImportedFromIB2 + 81.IBPluginDependency + 81.ImportedFromIB2 + 81.editorWindowContentRectSynchronizationRect + 82.IBPluginDependency + 82.ImportedFromIB2 + 83.IBPluginDependency + 83.ImportedFromIB2 + 92.IBPluginDependency + 92.ImportedFromIB2 + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{596, 852}, {216, 23}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{522, 812}, {146, 23}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{436, 809}, {64, 6}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{608, 612}, {275, 83}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{187, 434}, {243, 243}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{608, 612}, {167, 43}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{608, 612}, {241, 103}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{525, 802}, {197, 73}} + {{143, 285}, {478, 20}} + com.apple.InterfaceBuilder.CocoaPlugin + + {74, 862} + {{6, 978}, {478, 20}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{475, 832}, {234, 43}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{608, 612}, {215, 63}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{303, 221}, {480, 360}} + {{303, 221}, {480, 360}} + + {{33, 99}, {480, 360}} + {3.40282e+38, 3.40282e+38} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{437, 242}, {86, 43}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{523, 2}, {178, 283}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{155, 102}, {245, 183}} + com.apple.InterfaceBuilder.CocoaPlugin + + {{23, 794}, {245, 183}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{145, 474}, {199, 203}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 459 + + + + YES + + AppController + + theWindow + NSWindow + + + IBUserSource + + + + + + 0 + ../adsfsdf.xcodeproj + 3 + + diff --git a/Tests/Manual/FontEnhancements/Resources/spinner.gif b/Tests/Manual/FontEnhancements/Resources/spinner.gif new file mode 100644 index 0000000000000000000000000000000000000000..06dbc2bc21dddcf0e09b566d5b211aee89570f52 GIT binary patch literal 1849 zcma*odr(tX9tZHtz31lM+(&Y`A`Ou`NeG&R#DrIfV%?hng21vs6v>ooRQQFbk7E_K!V( z{?5!fpZWgIZ%*d6t%i*j24bL}AZUJm9)h6R*;%L4IWse3G#VWaN1#$zSSXcBhlYlH zJ|D}n{r&w2f+Qp)SS*&n?*G4}{}!h?td_mjU6Kad-rW*QwWYCUk7d^e+sjpZAn6kT z5rM;`{~_}-wm+L@%+E;JphLm}C3WzQAQD0wBoY|rOTQX{(@pp-WAA8Iw0HKl|15j) zhGh(SFWu#5zUCw^T!}C~eC}~?{xG-r7ugQC>taC+|L^xr&a%{#cgUOZXIM&v?)k^2 z1i5%0!U00wq)r4vlAwXBA_m5J5WNeuBm-XJQ5pG4GD%vc|K){+TJ{AkHqN@SJKczX zU}QRd9n*_bf^h94)6Ctv{CUfz_;qs#RDuQ$DR%y1&5G-a6rhf*4Y zl+UOD1*GE{GQ7vv;c-tTIMkz0ovO>9j%b5hpa@a*CBJ#W!0@ndSwF|%hMkdFtXiU) z`BEp+yhkt8ZY>tg&uyH@%^%K4jDrbA;et&vnnzZ3z22@e6<27z2Vk13kb7OtISyxv z(XoO-LNQCZe3lfzc%*pNqU<9T+p~teThOEB+~e&U0mC|zS{Q)dJZ)!^1f7L(zg*L> z*vSW%?dR~@@0(}x6-V^A`~ImD;)NaBUnP8;RH=bS2@pk`wp>>8r&jGjmGPy%1BW}v zoPo}ca$~bze@efc3kapuEVW1!%teOZT3j2Tw5=hjiAf02d}7dL0oFC%@=RXp5Ow#% z@a>+AM|YWt$n&e`>sB-32gBcuTi>R>*|8@lp`y6thc7ydyqDsuUn~YzZf|{-R@-3y zL#wx{Ii}xxL_csiW*LBn0-A$>zp4WOmkf6=ilrjlW?-l9+bCd7|i?*b5NTmy<<6NZ0T8$SN@mwdC2f z6jqK=N@bS@!=YSj%>h0}*4p+%0HbTIrE$w7UMT6+AZZ&DAo*qZAAi(OtNbIfl#Dw^ zJWeiCp~zi#&t6x}m9)O^eR4HiLV3QA<<0>HZ8%$^lrSE94Wb}=+MM^!b>n#5&-JQR zkr-CEu9C;_F*7DqDisulV6Pmg$nFL0TPn%~*m^-`Z3^BgU(sNpnx%nW(!eV9A&FvI zHL3X3lw8Wji^6=8KbQDE-e%b?svdFxxdh$8r97@7$ojeI`6AL8Ob6QC$qh&>ZWVDX1F{0vJnT%%mE;GveKWR%C} zM&4d;Jf3s9|HAA)yVUPo`Aq;0do#)uHSXi5*QF*)x@MVVHr+cN)uMZ__F|&Ta#p8d z53TOKtce!PJUuie8UWol-S(`c2nH?UGqJP{!4RR4u$LCfn)q-hj0^f=h(VYy)T6eN zhRO!ja-aDBTcgeyP(8Ua4IdiOog^*CQa?R(cP#9AgL9`j>EX-6Yf1lzX(!~``M1XC zNmM<4<6d~wWZ$Xrk0K}UteTrq@LBBk#MsjkK;pbuVhe)NI7(7Pf(l?lxC7=1Z7Pzl zMbS;nV4NI5_N{1$P)&XC)huOGQ+h^zpYUZfb*1n6>!`#*b3y52LGmi+<4sY5jyD#- zw&$d}DTguLAfnRtjrM*JfqtHqUu6rQoU=g%1E9xk%;)TDm^2<8n-0IhTsQFaek)MY}>PK4;nBk=ow4pF>vzkO& gna%Org-kgQCf=+BeMi^RbuY;YE~rTjend;_cdi8t>i_@% literal 0 HcmV?d00001 diff --git a/Tests/Manual/FontEnhancements/index-debug.html b/Tests/Manual/FontEnhancements/index-debug.html new file mode 100644 index 000000000..6c54166f5 --- /dev/null +++ b/Tests/Manual/FontEnhancements/index-debug.html @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + FontEnhancements + + + + + + + + + + + + + + +
+
+ + + +
+
+ + + diff --git a/Tests/Manual/FontEnhancements/index.html b/Tests/Manual/FontEnhancements/index.html new file mode 100644 index 000000000..ed9c90214 --- /dev/null +++ b/Tests/Manual/FontEnhancements/index.html @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + FontEnhancements + + + + + + + + + + + + +
+
+ + + +
+
+ + + diff --git a/Tests/Manual/FontEnhancements/main.j b/Tests/Manual/FontEnhancements/main.j new file mode 100644 index 000000000..0f1d27072 --- /dev/null +++ b/Tests/Manual/FontEnhancements/main.j @@ -0,0 +1,18 @@ +/* + * AppController.j + * FontEnhancements + * + * Created by aparajita on March 8, 2011. + * Copyright 2011, Victory-Heart Productions All rights reserved. + */ + +@import +@import + +@import "AppController.j" + + +function main(args, namedArgs) +{ + CPApplicationMain(args, namedArgs); +} diff --git a/Tools/nib2cib/Converter+Mac.j b/Tools/nib2cib/Converter+Mac.j index ccf3d71c2..d820b8f67 100644 --- a/Tools/nib2cib/Converter+Mac.j +++ b/Tools/nib2cib/Converter+Mac.j @@ -32,7 +32,7 @@ var unarchiver = [[Nib2CibKeyedUnarchiver alloc] initForReadingWithData:data resourcesPath:aResourcesPath], objectData = [unarchiver decodeObjectForKey:@"IB.objectdata"]; - // Perform a bit of post-processing on views since all CP views are flipped. + // Perform a bit of post-processing on fonts and views since all CP views are flipped. // It's better to do this here (instead of say, in NSView::initWithCoder:), // because at this point all the objects an mappings are stabilized. var objects = [unarchiver allObjects], @@ -42,6 +42,26 @@ { var object = objects[count]; + if ([object respondsToSelector:@selector(font)] && + [object respondsToSelector:@selector(setFont:)] && + [object font] != nil) + { + var nibFont = [object font], + cibFont = nil; + + if ([object respondsToSelector:@selector(cibFontForNibFont)]) + cibFont = [object cibFontForNibFont]; + else + cibFont = [NSFont cibFontForNibFont:[object font]]; + + if (![cibFont isEqual:nibFont]) + { + [object setFont:cibFont]; + + CPLog.debug("%s: substituted <%s> for <%fpx %s>", [object className], cibFont ? [cibFont cssString] : "theme default", [nibFont size], [nibFont familyName]); + } + } + if (![object isKindOfClass:[CPView class]]) continue; diff --git a/Tools/nib2cib/Converter.j b/Tools/nib2cib/Converter.j index edf1780de..1e9f3fd6c 100644 --- a/Tools/nib2cib/Converter.j +++ b/Tools/nib2cib/Converter.j @@ -18,35 +18,55 @@ * 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 -@import +@import +@import +@import var FILE = require("file"), - OS = require("os"); + OS = require("os"), + SharedConverter = nil; -NibFormatUndetermined = 0, -NibFormatMac = 1, -NibFormatIPhone = 2; +NibFormatUndetermined = 0, +NibFormatMac = 1, +NibFormatIPhone = 2; -ConverterConversionException = @"ConverterConversionException"; +ConverterModeLegacy = 0; +ConverterModeNew = 1; + +ConverterConversionException = @"ConverterConversionException"; @implementation Converter : CPObject { - NibFormat format @accessors; - CPString inputPath @accessors; - CPString outputPath @accessors; - CPString resourcesPath @accessors; + CPString inputPath @accessors(readonly); + CPString outputPath @accessors; + CPString resourcesPath @accessors; + ConverterLayoutMode layoutMode @accessors(readonly); + NibFormat format @accessors(readonly); + CPTheme theme @accessors(readonly); } -- (id)init ++ (Converter)sharedConverter +{ + if (!SharedConverter) + SharedConverter = [[Converter alloc] init]; + + return SharedConverter; +} + +- (id)initWithInputPath:(CPString)aPath format:(NibFormat)nibFormat layoutMode:(ConverterLayoutMode)aLayoutMode theme:(CPTheme)aTheme { self = [super init]; if (self) - [self setFormat:NibFormatUndetermined]; + { + inputPath = aPath; + format = nibFormat; + layoutMode = aLayoutMode; + theme = aTheme; + } return self; } @@ -87,8 +107,9 @@ ConverterConversionException = @"ConverterConversionException"; outputPath = inputPath.substr(0, inputPath.length - FILE.extension(inputPath).length) + ".cib"; FILE.write(outputPath, [convertedData rawString], { charset:"UTF-8" }); + CPLog.info("Conversion successful"); } - catch(anException) + catch (anException) { CPLog.fatal(anException); } @@ -96,17 +117,19 @@ ConverterConversionException = @"ConverterConversionException"; - (CPData)CPCompliantNibDataAtFilePath:(CPString)aFilePath { + CPLog.info("Converting Xib file to plist..."); + // Compile xib or nib to make sure we have a non-new format nib. var temporaryNibFilePath = FILE.join("/tmp", FILE.basename(aFilePath) + ".tmp.nib"); if (OS.popen(["/usr/bin/ibtool", aFilePath, "--compile", temporaryNibFilePath]).wait() === 1) - throw "Could not compile file at " + aFilePath; + throw "Could not compile file: " + aFilePath; // Convert from binary plist to XML plist var temporaryPlistFilePath = FILE.join("/tmp", FILE.basename(aFilePath) + ".tmp.plist"); if (OS.popen(["/usr/bin/plutil", "-convert", "xml1", temporaryNibFilePath, "-o", temporaryPlistFilePath]).wait() === 1) - throw "Could not convert to xml plist for file at " + aFilePath; + throw "Could not convert to xml plist for file: " + aFilePath; if (!FILE.isReadable(temporaryPlistFilePath)) [CPException raise:ConverterConversionException reason:@"Unable to convert nib file."]; @@ -121,8 +144,9 @@ ConverterConversionException = @"ConverterConversionException"; else plistContents = plistContents.replace(/\\s*CF\$UID\s*\<\/key\>/g, "CP$UID"); - plistContents = plistContents.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F]<\/string>/g, function(c) { - CPLog.warn("Warning: Converting character 0x"+c.charCodeAt(8).toString(16)+" to base64 representation"); + plistContents = plistContents.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F]<\/string>/g, function(c) + { + CPLog.warn("Warning: converting character 0x" + c.charCodeAt(8).toString(16) + " to base64 representation"); return ""+CFData.encodeBase64String(c.charAt(8))+""; }); diff --git a/Tools/nib2cib/NSAppKit.j b/Tools/nib2cib/NSAppKit.j index 1d9b3aa28..1003a954e 100644 --- a/Tools/nib2cib/NSAppKit.j +++ b/Tools/nib2cib/NSAppKit.j @@ -83,7 +83,7 @@ function CP_NSMapClassName(aClassName) if (CPClassFromString(mappedClassName)) { - CPLog.info("Mapping " + aClassName + " to " + mappedClassName); + CPLog.debug("NSAppKit: mapping " + aClassName + " to " + mappedClassName); return mappedClassName; } diff --git a/Tools/nib2cib/NSButton.j b/Tools/nib2cib/NSButton.j index d2958aab0..542a4b3b8 100644 --- a/Tools/nib2cib/NSButton.j +++ b/Tools/nib2cib/NSButton.j @@ -32,6 +32,7 @@ var _CPButtonBezelStyleHeights = {}; + _CPButtonBezelStyleHeights[CPRoundedBezelStyle] = 18; _CPButtonBezelStyleHeights[CPTexturedRoundedBezelStyle] = 20; _CPButtonBezelStyleHeights[CPHUDBezelStyle] = 20; @@ -100,18 +101,18 @@ var NSButtonIsBorderedMask = 0x00800000, case CPHelpButtonBezelStyle: case CPCircularBezelStyle: case CPDisclosureBezelStyle: - CPLog.warn("Unsupported bezel style: " + _bezelStyle); + CPLog.warn("NSButton [%s]: unsupported bezel style: %d", _title == null ? "" : '"' + _title + '"', _bezelStyle); _bezelStyle = CPHUDBezelStyle; break; // error: default: - CPLog.error("Unknown bezel style: " + _bezelStyle); + CPLog.warn("NSButton [%s]: unknown bezel style: %d", _title == null ? "" : '"' + _title + '"', _bezelStyle); _bezelStyle = CPHUDBezelStyle; } if ([cell isBordered]) { - CPLog.info("Adjusting CPButton height from " +_frame.size.height+ " / " + _bounds.size.height+" to " + CPButtonDefaultHeight); + CPLog.debug("NSButton [%s]: adjusting height from %d to %d", _title == null ? "" : '"' + _title + '"', _frame.size.height, CPButtonDefaultHeight); _frame.size.height = CPButtonDefaultHeight; _frame.origin.y += 4.0; _bounds.size.height = CPButtonDefaultHeight; diff --git a/Tools/nib2cib/NSColor.j b/Tools/nib2cib/NSColor.j index fb71f241a..1023d96d0 100644 --- a/Tools/nib2cib/NSColor.j +++ b/Tools/nib2cib/NSColor.j @@ -119,7 +119,7 @@ var NSUnknownColorSpaceModel = -1, } break; default: - CPLog(@"-[%@ %s] unknown color space %d", isa, _cmd, colorSpace); + CPLog.warn(@"-[%@ %s] unknown color space %d", isa, _cmd, colorSpace); result = [CPColor blackColor]; break; } diff --git a/Tools/nib2cib/NSCustomResource.j b/Tools/nib2cib/NSCustomResource.j index 3a108ac0c..46afc017c 100644 --- a/Tools/nib2cib/NSCustomResource.j +++ b/Tools/nib2cib/NSCustomResource.j @@ -41,13 +41,13 @@ var FILE = require("file"); var size = CGSizeMakeZero(); if (![[aCoder resourcesPath] length]) - CPLog.warn("*** WARNING: Resources found in nib, but no resources path specified with -R option."); + CPLog.warn("Resources found in nib, but no resources path specified with -R option."); else { var resourcePath = [aCoder resourcePathForName:_resourceName]; if (!resourcePath) - CPLog.warn("*** WARNING: Resource named " + _resourceName + " not found in supplied resources path."); + CPLog.warn("Resource named " + _resourceName + " not found in the supplied resources path."); else size = imageSize(FILE.join(FILE.cwd(), resourcePath)); diff --git a/Tools/nib2cib/NSFont.j b/Tools/nib2cib/NSFont.j index a08990d11..93433eecf 100644 --- a/Tools/nib2cib/NSFont.j +++ b/Tools/nib2cib/NSFont.j @@ -22,35 +22,56 @@ @import +var OS = require("os"), + fontinfo = require("fontinfo").fontinfo; + +var IBDefaultFontFace = @"Lucida Grande", + IBDefaultFontSize = 13.0; @implementation CPFont (NSCoding) - (id)NS_initWithCoder:(CPCoder)aCoder { - var isBold = NO, - fontName = [aCoder decodeObjectForKey:@"NSName"], - size = [aCoder decodeDoubleForKey:@"NSSize"]; + var name = [aCoder decodeObjectForKey:@"NSName"], + size = [aCoder decodeDoubleForKey:@"NSSize"], + isBold = false, + isItalic = false, + info = fontinfo(name, size); - if (fontName === "LucidaGrande" && size === 13) + if (info) { - CPLog.debug("Removing default IB font: <"+fontName+", "+size+"> for theme default font."); - return nil; + name = info.familyName; + isBold = info.bold; + isItalic = info.italic; } - // FIXME: Is this alwasy true? - if (fontName.indexOf("-Bold") === fontName.length - "-Bold".length) - isBold = YES; - - if (fontName === "LucidaGrande" || fontName === "LucidaGrande-Bold") - fontName = "Arial"; - - return [self _initWithName:fontName size:size bold:isBold]; + return [self _initWithName:name size:size bold:isBold italic:isItalic]; } @end @implementation NSFont : CPFont + ++ (void)initialize { + CPLog.debug("NSFont: default IB font: %s %f", IBDefaultFontFace, IBDefaultFontSize); +} + ++ (id)cibFontForNibFont:(CPFont)aFont +{ + var name = [aFont familyName]; + + if (name === IBDefaultFontFace) + { + var size = [aFont size]; + + if (size === IBDefaultFontSize) + return nil; + else + return [[CPFont alloc] _initWithName:[CPFont systemFontFace] size:size bold:[aFont isBold] italic:[aFont isItalic]]; + } + + return [aFont copy]; } - (id)initWithCoder:(CPCoder)aCoder diff --git a/Tools/nib2cib/NSIBObjectData.j b/Tools/nib2cib/NSIBObjectData.j index 6ac46a872..94c2c7025 100644 --- a/Tools/nib2cib/NSIBObjectData.j +++ b/Tools/nib2cib/NSIBObjectData.j @@ -127,7 +127,7 @@ children.forEach(function(aChild) { - CPLog.info("Promoted " + aChild + " to child of " + parent); + CPLog.debug("NSIBObjectData: promoted " + aChild + " to child of " + parent); _objectsKeys.push(aChild); _objectsValues.push(parent); }); diff --git a/Tools/nib2cib/NSMatrix.j b/Tools/nib2cib/NSMatrix.j index 100c66277..2ec0a0ef5 100644 --- a/Tools/nib2cib/NSMatrix.j +++ b/Tools/nib2cib/NSMatrix.j @@ -45,6 +45,7 @@ var NSMatrixRadioModeMask = 0x40000000, [cellView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable]; [cellView setTitle:[cell title]]; [cellView setBackgroundColor:[CPColor clearColor]]; // the IB default + [cellView setFont:[cell font]]; [cellView setObjectValue:[cell objectValue]]; [view addSubview:cellView]; diff --git a/Tools/nib2cib/NSNibConnector.j b/Tools/nib2cib/NSNibConnector.j index 67aca8c7f..04bb9c7ee 100644 --- a/Tools/nib2cib/NSNibConnector.j +++ b/Tools/nib2cib/NSNibConnector.j @@ -43,17 +43,17 @@ NIB_CONNECTION_EQUIVALENCY_TABLE = {}; if (sourceUID in NIB_CONNECTION_EQUIVALENCY_TABLE) { - CPLog.trace("Swapped object: "+_source+" for object: "+NIB_CONNECTION_EQUIVALENCY_TABLE[sourceUID]); + CPLog.debug("NSNibConnector: swapped object: " + _source + " for object: " + NIB_CONNECTION_EQUIVALENCY_TABLE[sourceUID]); _source = NIB_CONNECTION_EQUIVALENCY_TABLE[sourceUID]; } if (destinationUID in NIB_CONNECTION_EQUIVALENCY_TABLE) { - CPLog.trace("Swapped object: "+_destination+" for object: "+NIB_CONNECTION_EQUIVALENCY_TABLE[destinationUID]); + CPLog.debug("NSNibConnector: swapped object: " + _destination + " for object: " + NIB_CONNECTION_EQUIVALENCY_TABLE[destinationUID]); _destination = NIB_CONNECTION_EQUIVALENCY_TABLE[destinationUID]; } - CPLog.debug(@"Connection: " + [_source description] + " " + [_destination description] + " " + _label); + CPLog.debug(@"NSNibConnector: connection: " + [_source description] + " " + [_destination description] + " " + _label); } return self; @@ -144,7 +144,7 @@ var NSTramsformers = [CPSet setWithObjects: [_options setObject:NSValue forKey:CPKey]; } - CPLog.debug(@"Binding Connector: " + [_binding description] + " to: " + _destination + " " + [_keyPath description] + " " + [_options description]); + CPLog.debug(@"NSNibConnector: binding connector: " + [_binding description] + " to: " + _destination + " " + [_keyPath description] + " " + [_options description]); } return self; diff --git a/Tools/nib2cib/NSTabView.j b/Tools/nib2cib/NSTabView.j index d47b61cd1..920cee8f9 100644 --- a/Tools/nib2cib/NSTabView.j +++ b/Tools/nib2cib/NSTabView.j @@ -37,6 +37,7 @@ _items = [aCoder decodeObjectForKey:@"NSTabViewItems"]; _selectedIndex = [_items indexOfObject:[aCoder decodeObjectForKey:@"NSSelectedTabViewItem"]]; + _font = [aCoder decodeObjectForKey:@"NSFont"]; //_delegate = [aCoder decodeObjectForKey:@""]; diff --git a/Tools/nib2cib/NSTableColumn.j b/Tools/nib2cib/NSTableColumn.j index 7791446a6..b935d22dc 100644 --- a/Tools/nib2cib/NSTableColumn.j +++ b/Tools/nib2cib/NSTableColumn.j @@ -50,7 +50,7 @@ selectedFont = nil; if (!font) - font = [CPFont systemFontOfSize:12.0]; + font = [CPFont systemFontOfSize:[CPFont systemFontSize]]; var selectedFont = [CPFont boldFontWithName:[font familyName] size:[font size]]; diff --git a/Tools/nib2cib/NSTextField.j b/Tools/nib2cib/NSTextField.j index d4dea04fa..732ddf429 100644 --- a/Tools/nib2cib/NSTextField.j +++ b/Tools/nib2cib/NSTextField.j @@ -72,7 +72,7 @@ [self setFrameSize:CGSizeMake(frame.size.width + 7.0, frame.size.height + 7.0)]; } - CPLog.debug([self stringValue] + " => isBordered=" + [self isBordered] + ", isBezeled=" + [self isBezeled] + ", bezelStyle=" + [self bezelStyle] + "("+[cell stringValue]+", " + [cell placeholderString] + ")"); + CPLog.debug("NSTextField: title=\"" + [self stringValue] + "\", placeholder=" + ([cell placeholderString] == null ? "" : '"' + [cell placeholderString] + '"') + ", isBordered=" + [self isBordered] + ", isBezeled=" + [self isBezeled] + ", bezelStyle=" + [self bezelStyle]); } return self; diff --git a/Tools/nib2cib/NSView.j b/Tools/nib2cib/NSView.j index da27b7dce..7adaef735 100644 --- a/Tools/nib2cib/NSView.j +++ b/Tools/nib2cib/NSView.j @@ -30,6 +30,17 @@ var NSViewAutoresizingMask = 0x3F, NSViewAutoresizesSubviewsMask = 1 << 8, NSViewHiddenMask = 1 << 31; +NSViewAlignLayoutMinValue = 1000; +NSViewAlignLayoutBaselineLeft = 1000; +NSViewAlignLayoutTopLeft = 2000; +NSViewAlignLayoutTop = 3000; +NSViewAlignLayoutTopRight = 4000; +NSViewAlignLayoutBaselineRight = 5000; +NSViewAlignLayoutBottomRight = 6000; +NSViewAlignLayoutBottom = 7000; +NSViewAlignLayoutBottomLeft = 8000; +NSViewAlignLayoutMaxValue = 8000; + @implementation CPView (NSCoding) - (id)NS_initWithCoder:(CPCoder)aCoder @@ -84,8 +95,6 @@ var NSViewAutoresizingMask = 0x3F, @end @implementation NSView : CPView -{ -} - (id)initWithCoder:(CPCoder)aCoder { diff --git a/Tools/nib2cib/main.j b/Tools/nib2cib/main.j index 96cdc83c2..c58958533 100644 --- a/Tools/nib2cib/main.j +++ b/Tools/nib2cib/main.j @@ -18,11 +18,11 @@ * 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 - -@import +@import +@import @import "NSFoundation.j" @import "NSAppKit.j" @@ -30,8 +30,12 @@ @import "Nib2CibKeyedUnarchiver.j" @import "Converter.j" -var FILE = require("file"); -var OS = require("os"); +var FILE = require("file"), + OS = require("os"), + SYS = require("system"), + + DefaultTheme = "Aristo", + BuildTypes = ["Debug", "Release"]; var parser = new (require("narwhal/args").Parser)(); @@ -50,6 +54,19 @@ parser.option("--mac", "format") .def(NibFormatUndetermined) .help("Set format to Mac"); +parser.option("--legacy", "conversionMode") + .set(ConverterModeLegacy) + .def(ConverterModeNew) + .help("Use legacy code that does not preserve view positioning/sizing"); + +parser.option("-t", "--theme-dir", "themeDir") + .set() + .help("A .build directory to use for theme attribute values"); + +parser.option("--config", "configFile") + .set() + .help("A path to an Info.plist file from which the system font and/or size can be retrieved"); + // parser.option("--iphone", "format") // .set(NibFormatIPhone) // .help("Set format to iPhone"); @@ -62,6 +79,10 @@ parser.option("-q", "--quiet", "quiet") .set(true) .help("No output"); +parser.option("--version", "showVersion") + .set(true) + .help("Show the version of nib2cib and quit"); + parser.helpful(); function loadFrameworks(frameworkPaths, aCallback) @@ -83,39 +104,76 @@ function loadFrameworks(frameworkPaths, aCallback) aCallback(); } +function logFormatter(aString, aLevel, aTitle) +{ + return CPLogColorize(aString, aLevel); +} + function main(args) { var options = parser.parse(args, null, null, true); - if (options.args.length < 1 || options.args.length > 2) + if (options.args.length > 2) { parser.printUsage(options); - OS.exit(1); + OS.exit(0); } if (options.quiet) {} else if (options.verbose === 0) - CPLogRegister(CPLogPrint, "warn"); + CPLogRegister(CPLogPrint, "warn", logFormatter); else if (options.verbose === 1) - CPLogRegister(CPLogPrint, "info"); + CPLogRegister(CPLogPrint, "info", logFormatter); else - CPLogRegister(CPLogPrint); + CPLogRegister(CPLogPrint, null, logFormatter); - CPLog.debug("Input: " + options.args[0]); - CPLog.debug("Output: " + (options.args[1] || "")); - CPLog.debug("Format: " + ["Auto","Mac","iPhone"][options.format]); - CPLog.debug("Resources: " + (options.resources || "")); - CPLog.debug("Frameworks: " + options.frameworks); + printVersion(); - var converter = [[Converter alloc] init]; + if (options.showVersion) + OS.exit(0); + + var inputFile = options.args[0]; + + if (!FILE.exists(inputFile)) + fail("No such file: " + FILE.canonical(inputFile)); + + if (options.layoutMode === ConverterModeNew && !haveFontInfo()) + fail("The fontinfo package is not installed, please install it."); + + var configPath = setSystemFontAndSize(options.configFile || "", inputFile), + themeName = "", + themeDir = options.themeDir || ""; + + if (themeDir) + themeName = FILE.basename(themeDir, FILE.extension(themeDir)); + + themeName = themeName || getDefaultThemeName(); + + if (!themeName) + fail("Could not determine the theme name."); + + var theme = loadTheme(themeName, themeDir); + + CPLog.info("\n-------------------------------------------------------------"); + CPLog.info("Input : " + FILE.canonical(inputFile)); + CPLog.info("Output : " + (options.args[1] || "")); + CPLog.info("Format : " + ["Auto", "Mac", "iPhone"][options.format]); + CPLog.info("Resources : " + (options.resources || "")); + CPLog.info("Frameworks : " + options.frameworks); + CPLog.info("Layout Mode : " + (options.layoutMode === ConverterModeLegacy ? "legacy" : "new")); + CPLog.info("Theme : " + themeName); + CPLog.info("Config file : " + (configPath || "")); + CPLog.info("System Font : " + [CPFont systemFontSize] + "px " + [CPFont systemFontFace]); + CPLog.info("-------------------------------------------------------------\n"); + + var converter = [[Converter alloc] initWithInputPath:inputFile + format:options.format + layoutMode:options.layoutMode + theme:theme]; if (options.resources) [converter setResourcesPath:options.resources]; - [converter setFormat:options.format]; - - [converter setInputPath:options.args[0]]; - if (options.args.length > 1) [converter setOutputPath:options.args[1]]; @@ -124,3 +182,204 @@ function main(args) [converter convert]; }); } + +function getDefaultThemeName() +{ + var themeName = nil, + cappBuild = SYS.env["CAPP_BUILD"]; + + if (cappBuild) + { + for (var i = 0; i < BuildTypes.length; ++i) + { + var path = FILE.join(cappBuild, BuildTypes[i], "AppKit", "Info.plist"); + themeName = themeNameFromPropertyList(path); + + if (themeName) + break; + } + } + + return themeName || DefaultTheme; +} + +function themeNameFromPropertyList(path) +{ + if (!FILE.exists(path)) + return nil; + + var themeName = nil, + plist = CFPropertyList.readPropertyListFromFile(path); + + if (plist) + themeName = plist.valueForKey("CPDefaultTheme"); + + return themeName; +} + +function loadTheme(themeName, themeDir) +{ + if (!themeDir) + { + cappBuild = SYS.env["CAPP_BUILD"]; + + if (!cappBuild) + fail("Could not find $CAPP_BUILD, exiting."); + + var baseThemeName = themeName, + pos = themeName.indexOf("-"); + + if (pos > 0) + baseThemeName = themeName.substr(0, pos); + + themeDir = FILE.join(cappBuild, baseThemeName + ".build"); + } + + if (!FILE.isDirectory(themeDir)) + fail("No such theme directory: " + themeDir); + + var themePath = null; + + for (var i = 0; i < BuildTypes.length; ++i) + { + var path = FILE.join(themeDir, BuildTypes[i], "Browser.environment/Resources", themeName + ".keyedtheme"); + + if (FILE.exists(path)) + { + themePath = path; + break; + } + } + + if (!themePath) + fail("Could not find the keyed theme data for: " + themeName); + + themePath = FILE.canonical(themePath); + var plist = FILE.read(themePath); + + if (!plist) + fail("Could not read the keyed theme at: " + themePath); + + // The .keyedtheme file has a header that is data I don't need. Strip it off. + var m = plist.match(/^t;\d+;/); + + if (!m || m.length === 0) + fail("Invalid keyed theme data at: " + themePath); + + plist = plist.substr(m[0].length); + plist = CFPropertyList.propertyListFromString(plist); + + var data = [CPData dataWithPlistObject:plist], + theme = [CPKeyedUnarchiver unarchiveObjectWithData:data]; + + if (!theme) + fail("Could not unarchive the theme at: " + themePath); + + CPLog.debug("Loaded theme: " + themePath); + return theme; +} + +function haveFontInfo() +{ + try + { + var fontinfo = require("fontinfo").fontinfo; + } + catch (e) + { + return false; + } + + return true; +} + +function setSystemFontAndSize(configFile, inputFile) +{ + var configPath = null; + + // First see if the user passed a config file path + if (configFile) + { + var path = FILE.canonical(configFile); + + if (!FILE.exists(path)) + fail("Cannot find the config file: " + path); + + configPath = path; + } + else + { + // See if we can find an Info.plist in the parent directory of the input file, + // if the input file's directory is "Resources". + var path = FILE.canonical(FILE.dirname(inputFile)); + + if (FILE.basename(path) === "Resources") + { + path = FILE.join(FILE.dirname(path), "Info.plist"); + + if (FILE.exists(path)) + configPath = path; + } + } + + if (configPath) + { + var plist = FILE.read(configPath); + + if (!plist) + fail("Could not read the Info.plist at: " + configPath); + + plist = CFPropertyList.propertyListFromString(plist); + + if (!plist) + fail("Could not parse the Info.plist at: " + configPath); + + var systemFontFace = plist.valueForKey("CPSystemFontFace"); + + if (systemFontFace) + [CPFont setSystemFontFace:systemFontFace]; + + var systemFontSize = plist.valueForKey("CPSystemFontSize"); + + if (systemFontSize) + [CPFont setSystemFontSize:parseFloat(systemFontSize, 10)]; + } + + return configPath; +} + +function printVersion() +{ + // SYS.args[0] has the path to the nib2cib binary, from that we can get + // to the lib/nib2cib directory which the Info.plist for nib2cib. + var path = FILE.dirname(FILE.dirname(SYS.args[0])); + + if (FILE.basename(path) === "narwhal") + path = FILE.join(path, "packages", "cappuccino"); + + path = FILE.join(path, "lib", "nib2cib", "Info.plist"); + + if (FILE.exists(path)) + { + var plist = FILE.read(path); + + if (!plist) + return; + + plist = CFPropertyList.propertyListFromString(plist); + + if (!plist) + return; + + var version = plist.valueForKey("CPBundleVersion"); + + if (version) + print("nib2cib v" + version); + } +} + +function fail(message) +{ + CPLog.error(message); + OS.exit(1); +}