Files
cappuccino/AppKit/Tools/blend/main.j
T

292 lines
8.3 KiB
Plaintext
Executable File

@import <Foundation/Foundation.j>
@import <AppKit/AppKit.j>
@import <AppKit/CPCib.j>
@import <AppKit/CPTheme.j>
@import <BlendKit/BlendKit.j>
var File = require("file");
function main()
{
var index = 0,
count = system.args.length,
outputFilePath = "",
descriptorFiles = [],
resourcesPath = nil,
cibFiles = [],
blendName = "Untitled";
for (; index < count; ++index)
{
var argument = system.args[index];
switch (argument)
{
case "-c":
case "--cib": cibFiles.push(system.args[++index]);
break;
case "-d":
case "-descriptor": descriptorFiles.push(system.args[++index]);
break;
case "-o": outputFilePath = system.args[++index];
break;
case "-R": resourcesPath = system.args[++index];
break;
default: jExtensionIndex = argument.indexOf(".j");
if ((jExtensionIndex > 0) && (jExtensionIndex === argument.length - ".j".length))
descriptorFiles.push(argument);
else
cibFiles.push(argument);
}
}
if (descriptorFiles.length === 0)
return buildBlendFromCibFiles(cibFiles);
objj_import(descriptorFiles, YES, function()
{
var themeDescriptorClasses = BKThemeDescriptorClasses(),
count = [themeDescriptorClasses count];
while (count--)
{
var theClass = themeDescriptorClasses[count],
themeTemplate = [[BKThemeTemplate alloc] init];
[themeTemplate setValue:[theClass themeName] forKey:@"name"];
var objectTemplates = BKThemeObjectTemplatesForClass(theClass),
data = cibDataFromTopLevelObjects(objectTemplates.concat([themeTemplate])),
temporaryCibFile = Packages.java.io.File.createTempFile("temp", ".cib"),
temporaryCibFilePath = String(temporaryCibFile.getAbsolutePath());
File.write(temporaryCibFilePath, [data string], { charset:"UTF8" });
cibFiles.push(temporaryCibFilePath);
}
buildBlendFromCibFiles(cibFiles, outputFilePath, resourcesPath);
});
}
function cibDataFromTopLevelObjects(objects)
{
var data = [CPData data],
archiver = [[CPKeyedArchiver alloc] initForWritingWithMutableData:data],
objectData = [[_CPCibObjectData alloc] init];
objectData._fileOwner = [_CPCibCustomObject new];
objectData._fileOwner._className = @"CPObject";
var index = 0,
count = objects.length;
for (; index < count; ++index)
{
objectData._objectsValues[index] = objectData._fileOwner;
objectData._objectsKeys[index] = objects[index];
}
[archiver encodeObject:objectData forKey:@"CPCibObjectDataKey"];
[archiver finishEncoding];
return data;
}
function getDirectory(aPath)
{
return (aPath).substr(0, (aPath).lastIndexOf('/') + 1)
}
function buildBlendFromCibFiles(cibFiles, outputFilePath, resourcesPath)
{
var resourcesFile = nil;
if (resourcesPath)
resourcesFile = new Packages.java.io.File(resourcesPath);
var count = cibFiles.length,
replacedFiles = [],
staticContent = @"";
while (count--)
{
var theme = themeFromCibFile(new Packages.java.io.File(cibFiles[count])),
// Archive our theme.
filePath = [theme name] + ".keyedtheme",
fileContents = [[CPKeyedArchiver archivedDataWithRootObject:theme] string];
replacedFiles.push(filePath);
staticContent += MARKER_PATH + ';' + filePath.length + ';' + filePath + MARKER_TEXT + ';' + fileContents.length + ';' + fileContents;
}
staticContent = "@STATIC;1.0;" + staticContent;
var blendName = File.basename(outputFilePath),
extension = File.extname(outputFilePath);
if (extension.length)
blendName = blendName.substr(0, blendName.length - extension.length);
var infoDictionary = [CPDictionary dictionary],
staticContentName = blendName + ".sj";
[infoDictionary setObject:blendName forKey:@"CPBundleName"];
[infoDictionary setObject:blendName forKey:@"CPBundleIdentifier"];
[infoDictionary setObject:replacedFiles forKey:@"CPBundleReplacedFiles"];
[infoDictionary setObject:staticContentName forKey:@"CPBundleExecutable"];
var outputFile = new Packages.java.io.File(outputFilePath).getCanonicalFile();
outputFile.mkdirs();
File.write(outputFilePath + "/Info.plist", [CPPropertyListCreate280NorthData(infoDictionary) string], { charset:"UTF8" });
File.write(outputFilePath + '/' + staticContentName, staticContent, { charset:"UTF8" });
if (resourcesPath)
rsync(new Packages.java.io.File(resourcesPath), new Packages.java.io.File(outputFilePath));
}
function themeFromCibFile(aFile)
{
var cib = [[CPCib alloc] initWithContentsOfURL:aFile.getCanonicalPath()],
topLevelObjects = [];
[cib _setAwakenCustomResources:NO];
[cib instantiateCibWithExternalNameTable:[CPDictionary dictionaryWithObject:topLevelObjects forKey:CPCibTopLevelObjects]];
var count = topLevelObjects.length,
theme = nil,
templates = [];
while (count--)
{
var object = topLevelObjects[count];
templates = templates.concat([object blendThemeObjectTemplates]);
if ([object isKindOfClass:[BKThemeTemplate class]])
theme = [[CPTheme alloc] initWithName:[object valueForKey:@"name"]];
}
print("Building " + [theme name] + " theme");
[templates makeObjectsPerformSelector:@selector(blendAddThemedObjectAttributesToTheme:) withObject:theme];
return theme;
}
function rsync(srcFile, dstFile)
{
var src, dst;
if (String(java.lang.System.getenv("OS")).indexOf("Windows") < 0)
{
src = srcFile.getAbsolutePath();
dst = dstFile.getAbsolutePath();
}
else
{
src = exec(["cygpath", "-u", srcFile.getAbsolutePath() + '/']);
dst = exec(["cygpath", "-u", dstFile.getAbsolutePath() + "/Resources"]);
}
if (srcFile.exists())
exec(["rsync", "-avz", src, dst]);
}
function exec(/*Array*/ command, /*Boolean*/ showOutput)
{
var line = "",
output = "",
process = Packages.java.lang.Runtime.getRuntime().exec(command),//jsArrayToJavaArray(command));
reader = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(process.getInputStream()));
while (line = reader.readLine())
{
if (showOutput)
System.out.println(line);
output += line + '\n';
}
reader = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(process.getErrorStream()));
while (line = reader.readLine())
System.out.println(line);
try
{
if (process.waitFor() != 0)
System.err.println("exit value = " + process.exitValue());
}
catch (anException)
{
System.err.println(anException);
}
return output;
}
@implementation CPObject (BlendAdditions)
- (CPArray)blendThemeObjectTemplates
{
var theClass = [self class];
if ([theClass isKindOfClass:[BKThemeObjectTemplate class]])
return [self];
if ([theClass isKindOfClass:[CPView class]])
{
var templates = [],
subviews = [self subviews],
count = [subviews count];
while (count--)
templates = templates.concat([subviews[count] blendThemeObjectTemplates]);
return templates;
}
return [];
}
@end
@implementation BKThemeObjectTemplate (BlendAdditions)
- (void)blendAddThemedObjectAttributesToTheme:(CPTheme)aTheme
{
var themedObject = [self valueForKey:@"themedObject"];
if (!themedObject)
{
var subviews = [self subviews];
if ([subviews count] > 0)
themedObject = subviews[0];
}
if (themedObject)
{
print(" Recording themed properties for " + [themedObject className] + ".");
[aTheme takeThemeFromObject:themedObject];
}
}
@end