mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-08-25 04:57:03 +00:00
Merge pull request #3277 from enquora/CPStackView-build-warnings-cleanup
Fix CPStackView compile errors and add minimal correctness fixes
This commit is contained in:
@@ -93,6 +93,7 @@
|
|||||||
@import "CPSlider.j"
|
@import "CPSlider.j"
|
||||||
@import "CPSound.j"
|
@import "CPSound.j"
|
||||||
@import "CPSplitView.j"
|
@import "CPSplitView.j"
|
||||||
|
@import "CPStackView.j"
|
||||||
@import "CPStepper.j"
|
@import "CPStepper.j"
|
||||||
@import "CPTableColumn.j"
|
@import "CPTableColumn.j"
|
||||||
@import "CPTableView.j"
|
@import "CPTableView.j"
|
||||||
|
|||||||
+135
-18
@@ -20,7 +20,80 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PLACEHOLDER IMPLEMENTATION — READ BEFORE USE OR MODIFICATION.
|
||||||
|
*
|
||||||
|
* This class lays out views by direct, procedural arithmetic. It has no
|
||||||
|
* constraint solver. It cannot compress, expand, or negotiate space among
|
||||||
|
* views the way NSStackView does; it only places views at their existing
|
||||||
|
* frame size, in order, separated by fixed spacing.
|
||||||
|
*
|
||||||
|
* Known, accepted limitations:
|
||||||
|
* - `distribution` is stored but has no effect on layout. Fill,
|
||||||
|
* FillEqually, FillProportionally, and EqualSpacing are unimplemented.
|
||||||
|
* - Center-gravity views are clamped against the Leading edge only; if
|
||||||
|
* Leading + Center + Trailing content overflows the container, Center
|
||||||
|
* views can overlap Trailing views instead of compressing.
|
||||||
|
* - `visibilityPriority:forView:` only supports the two extreme values
|
||||||
|
* (MustHold / NotVisible). Intermediate priorities are accepted but
|
||||||
|
* have no defined effect.
|
||||||
|
* - No guarantee is made of correctness beyond what a single manual
|
||||||
|
* test (Tests/Manual/CPStackViewTest) exercises: orientation, the
|
||||||
|
* three gravity areas, alignment switching, spacing, and hidden-view
|
||||||
|
* detachment. Insertion, removal, custom spacing, and the CPCoding
|
||||||
|
* archive path are implemented but not verified by that test.
|
||||||
|
*
|
||||||
|
* This exists to give AppKit a working CPStackView symbol now, not to be
|
||||||
|
* a durable design. It is expected to be replaced by a constraint-solver
|
||||||
|
* based implementation (Kiwi.js) when time permits. Do not build on its
|
||||||
|
* internal layout algorithm as if it were a stable foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
@import "CPView.j"
|
@import "CPView.j"
|
||||||
|
@import <Foundation/CPMapTable.j>
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
// MARK: Minimal local type definitions
|
||||||
|
//
|
||||||
|
// These types support this file only. They are not shared with the rest
|
||||||
|
// of AppKit. A future constraint-solver based Auto Layout engine will
|
||||||
|
// replace them. Numeric values match the equivalent Cocoa constants
|
||||||
|
// (NSUserInterfaceLayoutOrientation, NSLayoutAttribute) so that a later,
|
||||||
|
// solver-based CPLayoutAttribute can reuse these numbers without a
|
||||||
|
// renumbering pass.
|
||||||
|
|
||||||
|
@typedef CPUserInterfaceLayoutOrientation
|
||||||
|
CPUserInterfaceLayoutOrientationHorizontal = 0;
|
||||||
|
CPUserInterfaceLayoutOrientationVertical = 1;
|
||||||
|
|
||||||
|
@typedef CPLayoutAttribute
|
||||||
|
CPLayoutAttributeLeft = 1;
|
||||||
|
CPLayoutAttributeRight = 2;
|
||||||
|
CPLayoutAttributeTop = 3;
|
||||||
|
CPLayoutAttributeBottom = 4;
|
||||||
|
CPLayoutAttributeLeading = 5;
|
||||||
|
CPLayoutAttributeTrailing = 6;
|
||||||
|
CPLayoutAttributeWidth = 7;
|
||||||
|
CPLayoutAttributeHeight = 8;
|
||||||
|
CPLayoutAttributeCenterX = 9;
|
||||||
|
CPLayoutAttributeCenterY = 10;
|
||||||
|
|
||||||
|
@typedef CPEdgeInsets
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Creates a CPEdgeInsets. Argument order matches Cocoa's NSEdgeInsetsMake
|
||||||
|
(top, left, bottom, right). Storage reuses the existing CGInset struct,
|
||||||
|
whose field order is (top, right, bottom, left).
|
||||||
|
*/
|
||||||
|
function CPEdgeInsetsMake(top, left, bottom, right)
|
||||||
|
{
|
||||||
|
return CGInsetMake(top, right, bottom, left);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CPEdgeInsetsEqualToEdgeInsets(lhsInsets, rhsInsets)
|
||||||
|
{
|
||||||
|
return CGInsetEqualToInset(lhsInsets, rhsInsets);
|
||||||
|
}
|
||||||
|
|
||||||
// Gravity Areas
|
// Gravity Areas
|
||||||
@typedef CPStackViewGravity
|
@typedef CPStackViewGravity
|
||||||
@@ -60,6 +133,7 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
|||||||
{
|
{
|
||||||
CPUserInterfaceLayoutOrientation _orientation;
|
CPUserInterfaceLayoutOrientation _orientation;
|
||||||
CPLayoutAttribute _alignment;
|
CPLayoutAttribute _alignment;
|
||||||
|
CPStackViewDistribution _distribution;
|
||||||
float _spacing;
|
float _spacing;
|
||||||
CPEdgeInsets _edgeInsets;
|
CPEdgeInsets _edgeInsets;
|
||||||
|
|
||||||
@@ -99,6 +173,7 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
|||||||
{
|
{
|
||||||
_orientation = CPUserInterfaceLayoutOrientationHorizontal;
|
_orientation = CPUserInterfaceLayoutOrientationHorizontal;
|
||||||
_alignment = CPLayoutAttributeCenterY; // Default alignment
|
_alignment = CPLayoutAttributeCenterY; // Default alignment
|
||||||
|
_distribution = CPStackViewDistributionGravityAreas;
|
||||||
_spacing = 8.0; // Default Cocoa spacing
|
_spacing = 8.0; // Default Cocoa spacing
|
||||||
_edgeInsets = CPEdgeInsetsMake(0, 0, 0, 0);
|
_edgeInsets = CPEdgeInsetsMake(0, 0, 0, 0);
|
||||||
_detachesHiddenViews = YES;
|
_detachesHiddenViews = YES;
|
||||||
@@ -169,6 +244,27 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
|||||||
[self setNeedsLayout:YES];
|
[self setNeedsLayout:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
The distribution mode for the stack view.
|
||||||
|
@note Not yet applied to layout. All views are laid out at their
|
||||||
|
existing frame size regardless of this value, pending the
|
||||||
|
constraint-solver based layout engine. The value is stored and
|
||||||
|
returned so client code can read back what was set.
|
||||||
|
*/
|
||||||
|
- (CPStackViewDistribution)distribution
|
||||||
|
{
|
||||||
|
return _distribution;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setDistribution:(CPStackViewDistribution)aDistribution
|
||||||
|
{
|
||||||
|
if (_distribution === aDistribution)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_distribution = aDistribution;
|
||||||
|
[self setNeedsLayout:YES];
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
The minimum spacing, in points, between adjacent views in the stack view.
|
The minimum spacing, in points, between adjacent views in the stack view.
|
||||||
*/
|
*/
|
||||||
@@ -233,6 +329,21 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
|||||||
return _viewsLeading; // Leading or Top
|
return _viewsLeading; // Leading or Top
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Rebuilds _arrangedSubviews from the three gravity containers, in
|
||||||
|
Leading, Center, Trailing order. Call after any change to a gravity
|
||||||
|
container so _arrangedSubviews stays a correct, single source of truth
|
||||||
|
for ordering, rather than an incrementally and separately maintained
|
||||||
|
(and error-prone) copy.
|
||||||
|
*/
|
||||||
|
- (void)_rebuildArrangedSubviews
|
||||||
|
{
|
||||||
|
_arrangedSubviews = [[CPMutableArray alloc] init];
|
||||||
|
[_arrangedSubviews addObjectsFromArray:_viewsLeading];
|
||||||
|
[_arrangedSubviews addObjectsFromArray:_viewsCenter];
|
||||||
|
[_arrangedSubviews addObjectsFromArray:_viewsTrailing];
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Adds a view to the end of the stack view gravity area.
|
Adds a view to the end of the stack view gravity area.
|
||||||
*/
|
*/
|
||||||
@@ -245,7 +356,7 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
|||||||
[self removeView:aView];
|
[self removeView:aView];
|
||||||
|
|
||||||
[container addObject:aView];
|
[container addObject:aView];
|
||||||
[_arrangedSubviews addObject:aView];
|
[self _rebuildArrangedSubviews];
|
||||||
|
|
||||||
// Add as actual subview
|
// Add as actual subview
|
||||||
if ([aView superview] !== self)
|
if ([aView superview] !== self)
|
||||||
@@ -269,7 +380,7 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
|||||||
else
|
else
|
||||||
[container insertObject:aView atIndex:index];
|
[container insertObject:aView atIndex:index];
|
||||||
|
|
||||||
[_arrangedSubviews addObject:aView];
|
[self _rebuildArrangedSubviews];
|
||||||
|
|
||||||
if ([aView superview] !== self)
|
if ([aView superview] !== self)
|
||||||
[self addSubview:aView];
|
[self addSubview:aView];
|
||||||
@@ -284,13 +395,9 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
|||||||
{
|
{
|
||||||
var container = [self _containerForGravity:gravity];
|
var container = [self _containerForGravity:gravity];
|
||||||
|
|
||||||
// Remove old views from arranged list and superview
|
// Remove old views from superview
|
||||||
for (var i = 0; i < [container count]; i++)
|
for (var i = 0; i < [container count]; i++)
|
||||||
{
|
[container[i] removeFromSuperview];
|
||||||
var oldView = container[i];
|
|
||||||
[oldView removeFromSuperview];
|
|
||||||
[_arrangedSubviews removeObject:oldView];
|
|
||||||
}
|
|
||||||
|
|
||||||
[container removeAllObjects];
|
[container removeAllObjects];
|
||||||
|
|
||||||
@@ -298,10 +405,10 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
|||||||
{
|
{
|
||||||
var newView = views[i];
|
var newView = views[i];
|
||||||
[container addObject:newView];
|
[container addObject:newView];
|
||||||
[_arrangedSubviews addObject:newView];
|
|
||||||
[self addSubview:newView];
|
[self addSubview:newView];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[self _rebuildArrangedSubviews];
|
||||||
[self setNeedsLayout:YES];
|
[self setNeedsLayout:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,7 +423,7 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
|||||||
[_viewsLeading removeObject:aView];
|
[_viewsLeading removeObject:aView];
|
||||||
[_viewsCenter removeObject:aView];
|
[_viewsCenter removeObject:aView];
|
||||||
[_viewsTrailing removeObject:aView];
|
[_viewsTrailing removeObject:aView];
|
||||||
[_arrangedSubviews removeObject:aView];
|
[self _rebuildArrangedSubviews];
|
||||||
|
|
||||||
[aView removeFromSuperview];
|
[aView removeFromSuperview];
|
||||||
|
|
||||||
@@ -531,6 +638,13 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
|||||||
var limit = (dir === 1) ? count : -1;
|
var limit = (dir === 1) ? count : -1;
|
||||||
var step = (dir === 1) ? 1 : -1;
|
var step = (dir === 1) ? 1 : -1;
|
||||||
|
|
||||||
|
// Spacing is applied as a gap *before* placing an element (except the
|
||||||
|
// first placed one), rather than trailing off the end after the last
|
||||||
|
// element. This keeps the returned cursor at the true content edge,
|
||||||
|
// with no phantom spacing past the final view.
|
||||||
|
var hasPlacedAny = false;
|
||||||
|
var pendingSpacing = 0;
|
||||||
|
|
||||||
for (; i !== limit; i += step)
|
for (; i !== limit; i += step)
|
||||||
{
|
{
|
||||||
var view = views[i];
|
var view = views[i];
|
||||||
@@ -538,6 +652,9 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
|||||||
if (_detachesHiddenViews && [view isHidden])
|
if (_detachesHiddenViews && [view isHidden])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (hasPlacedAny)
|
||||||
|
cursor += (dir === 1) ? pendingSpacing : -pendingSpacing;
|
||||||
|
|
||||||
var viewFrame = [view frame];
|
var viewFrame = [view frame];
|
||||||
var viewSizePrimary = isVert ? CGRectGetHeight(viewFrame) : CGRectGetWidth(viewFrame);
|
var viewSizePrimary = isVert ? CGRectGetHeight(viewFrame) : CGRectGetWidth(viewFrame);
|
||||||
|
|
||||||
@@ -617,11 +734,10 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
|||||||
|
|
||||||
if (dir === 1) {
|
if (dir === 1) {
|
||||||
originY = cursor;
|
originY = cursor;
|
||||||
cursor += sizeH + [self _spacingAfterView:view];
|
cursor += sizeH;
|
||||||
} else {
|
} else {
|
||||||
cursor -= sizeH;
|
cursor -= sizeH;
|
||||||
originY = cursor;
|
originY = cursor;
|
||||||
cursor -= [self _spacingAfterView:view];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -633,15 +749,17 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
|||||||
|
|
||||||
if (dir === 1) {
|
if (dir === 1) {
|
||||||
originX = cursor;
|
originX = cursor;
|
||||||
cursor += sizeW + [self _spacingAfterView:view];
|
cursor += sizeW;
|
||||||
} else {
|
} else {
|
||||||
cursor -= sizeW;
|
cursor -= sizeW;
|
||||||
originX = cursor;
|
originX = cursor;
|
||||||
cursor -= [self _spacingAfterView:view];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[view setFrame:CGRectMake(originX, originY, sizeW, sizeH)];
|
[view setFrame:CGRectMake(originX, originY, sizeW, sizeH)];
|
||||||
|
|
||||||
|
pendingSpacing = [self _spacingAfterView:view];
|
||||||
|
hasPlacedAny = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cursor;
|
return cursor;
|
||||||
@@ -657,6 +775,7 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
|||||||
{
|
{
|
||||||
_orientation = [aCoder decodeIntForKey:@"CPStackViewOrientation"];
|
_orientation = [aCoder decodeIntForKey:@"CPStackViewOrientation"];
|
||||||
_alignment = [aCoder decodeIntForKey:@"CPStackViewAlignment"];
|
_alignment = [aCoder decodeIntForKey:@"CPStackViewAlignment"];
|
||||||
|
_distribution = [aCoder decodeIntForKey:@"CPStackViewDistribution"];
|
||||||
_spacing = [aCoder decodeFloatForKey:@"CPStackViewSpacing"];
|
_spacing = [aCoder decodeFloatForKey:@"CPStackViewSpacing"];
|
||||||
_edgeInsets = [aCoder decodeObjectForKey:@"CPStackViewEdgeInsets"]; // Assuming CPEdgeInsets supports obj coding or manual decode
|
_edgeInsets = [aCoder decodeObjectForKey:@"CPStackViewEdgeInsets"]; // Assuming CPEdgeInsets supports obj coding or manual decode
|
||||||
if (!_edgeInsets) _edgeInsets = CPEdgeInsetsMake(0,0,0,0);
|
if (!_edgeInsets) _edgeInsets = CPEdgeInsetsMake(0,0,0,0);
|
||||||
@@ -668,10 +787,7 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
|||||||
_viewsTrailing = [aCoder decodeObjectForKey:@"CPStackViewViewsTrailing"] || [];
|
_viewsTrailing = [aCoder decodeObjectForKey:@"CPStackViewViewsTrailing"] || [];
|
||||||
|
|
||||||
// Rebuild arranged subviews cache
|
// Rebuild arranged subviews cache
|
||||||
_arrangedSubviews = [[CPMutableArray alloc] init];
|
[self _rebuildArrangedSubviews];
|
||||||
[_arrangedSubviews addObjectsFromArray:_viewsLeading];
|
|
||||||
[_arrangedSubviews addObjectsFromArray:_viewsCenter];
|
|
||||||
[_arrangedSubviews addObjectsFromArray:_viewsTrailing];
|
|
||||||
|
|
||||||
_customSpacings = [aCoder decodeObjectForKey:@"CPStackViewCustomSpacings"] || [[CPMapTable alloc] init];
|
_customSpacings = [aCoder decodeObjectForKey:@"CPStackViewCustomSpacings"] || [[CPMapTable alloc] init];
|
||||||
_visibilityPriorities = [[CPMapTable alloc] init]; // usually not persisted
|
_visibilityPriorities = [[CPMapTable alloc] init]; // usually not persisted
|
||||||
@@ -684,6 +800,7 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
|||||||
[super encodeWithCoder:aCoder];
|
[super encodeWithCoder:aCoder];
|
||||||
[aCoder encodeInt:_orientation forKey:@"CPStackViewOrientation"];
|
[aCoder encodeInt:_orientation forKey:@"CPStackViewOrientation"];
|
||||||
[aCoder encodeInt:_alignment forKey:@"CPStackViewAlignment"];
|
[aCoder encodeInt:_alignment forKey:@"CPStackViewAlignment"];
|
||||||
|
[aCoder encodeInt:_distribution forKey:@"CPStackViewDistribution"];
|
||||||
[aCoder encodeFloat:_spacing forKey:@"CPStackViewSpacing"];
|
[aCoder encodeFloat:_spacing forKey:@"CPStackViewSpacing"];
|
||||||
[aCoder encodeObject:_edgeInsets forKey:@"CPStackViewEdgeInsets"];
|
[aCoder encodeObject:_edgeInsets forKey:@"CPStackViewEdgeInsets"];
|
||||||
[aCoder encodeBool:_detachesHiddenViews forKey:@"CPStackViewDetachesHiddenViews"];
|
[aCoder encodeBool:_detachesHiddenViews forKey:@"CPStackViewDetachesHiddenViews"];
|
||||||
|
|||||||
@@ -1,94 +1,162 @@
|
|||||||
/*
|
/*
|
||||||
* Jakefile
|
* Jakefile
|
||||||
* CPSplitViewTest
|
* CPStackViewTest
|
||||||
*
|
*
|
||||||
* Created by Alexander Ljungberg on January 27, 2012.
|
* Created by You on August 14, 2026.
|
||||||
* Copyright 2012, WireLoad All rights reserved.
|
* Copyright 2026, Your Company All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var ENV = require("system").env,
|
const path = require("path");
|
||||||
FILE = require("file"),
|
const fs = require("fs");
|
||||||
JAKE = require("jake"),
|
|
||||||
|
var ENV = process.env,
|
||||||
task = JAKE.task,
|
task = JAKE.task,
|
||||||
FileList = JAKE.FileList,
|
FileList = JAKE.FileList,
|
||||||
app = require("cappuccino/jake").app,
|
app = CAPPUCCINO.Jake.applicationtask.app,
|
||||||
configuration = ENV["CONFIG"] || ENV["CONFIGURATION"] || ENV["c"] || "Debug",
|
configuration = ENV["CONFIG"] || ENV["CONFIGURATION"] || ENV["c"] || "Debug",
|
||||||
OS = require("os");
|
OS = require("os"),
|
||||||
|
projectName = "CPStackViewTest";
|
||||||
|
|
||||||
app ("CPSplitViewTest", function(task)
|
var buildDir = path.resolve(ENV["BUILD_PATH"] || ENV["CAPP_BUILD"] || "Build");
|
||||||
|
|
||||||
|
app (projectName, function(task)
|
||||||
{
|
{
|
||||||
task.setBuildIntermediatesPath(FILE.join("Build", "CPSplitViewTest.build", configuration));
|
ENV["OBJJ_INCLUDE_PATHS"] = ["Frameworks"];
|
||||||
task.setBuildPath(FILE.join("Build", configuration));
|
|
||||||
|
|
||||||
task.setProductName("CPSplitViewTest");
|
if (configuration === "Debug")
|
||||||
task.setIdentifier("com.yourcompany.CPSplitViewTest");
|
ENV["OBJJ_INCLUDE_PATHS"] = path.join(ENV["OBJJ_INCLUDE_PATHS"], configuration);
|
||||||
|
|
||||||
|
task.setBuildIntermediatesPath(path.join(buildDir, "CPStackViewTest.build", configuration));
|
||||||
|
task.setBuildPath(path.join(buildDir, configuration));
|
||||||
|
|
||||||
|
task.setProductName("CPStackViewTest");
|
||||||
|
task.setIdentifier("com.yourcompany.CPStackViewTest");
|
||||||
task.setVersion("1.0");
|
task.setVersion("1.0");
|
||||||
task.setAuthor("WireLoad");
|
task.setAuthor("Your Company");
|
||||||
task.setEmail("feedback @nospam@ yourcompany.com");
|
task.setEmail("feedback @nospam@ yourcompany.com");
|
||||||
task.setSummary("CPSplitViewTest");
|
task.setSummary("CPStackViewTest");
|
||||||
task.setSources((new FileList("**/*.j")).exclude(FILE.join("Build", "**")));
|
task.setSources(new FileList("**/*.j").exclude(path.join("Build", "**")).exclude(path.join("Frameworks", "Source", "**")));
|
||||||
task.setResources(new FileList("Resources/**"));
|
task.setResources(new FileList("Resources/**"));
|
||||||
task.setIndexFilePath("index.html");
|
task.setIndexFilePath("index.html");
|
||||||
task.setInfoPlistPath("Info.plist");
|
task.setInfoPlistPath("Info.plist");
|
||||||
task.setNib2CibFlags("-R Resources/");
|
|
||||||
|
|
||||||
if (configuration === "Debug")
|
if (configuration === "Debug")
|
||||||
task.setCompilerFlags("-DDEBUG -g");
|
task.setCompilerFlags("-DDEBUG -g -S --inline-msg-send");
|
||||||
else
|
else
|
||||||
task.setCompilerFlags("-O");
|
task.setCompilerFlags("-O2");
|
||||||
});
|
});
|
||||||
|
|
||||||
task ("default", ["CPSplitViewTest"], function()
|
task ("default", [projectName], function()
|
||||||
{
|
{
|
||||||
printResults(configuration);
|
printResults(configuration);
|
||||||
});
|
});
|
||||||
|
|
||||||
task ("build", ["default"]);
|
task ("build", ["default"], function()
|
||||||
|
{
|
||||||
|
updateApplicationSize();
|
||||||
|
});
|
||||||
|
|
||||||
task ("debug", function()
|
task ("debug", function()
|
||||||
{
|
{
|
||||||
ENV["CONFIGURATION"] = "Debug";
|
configuration = ENV["CONFIGURATION"] = "Debug";
|
||||||
JAKE.subjake(["."], "build", ENV);
|
JAKE.subjake(["."], "build", ENV);
|
||||||
});
|
});
|
||||||
|
|
||||||
task ("release", function()
|
task ("release", function()
|
||||||
{
|
{
|
||||||
ENV["CONFIGURATION"] = "Release";
|
configuration = ENV["CONFIGURATION"] = "Release";
|
||||||
JAKE.subjake(["."], "build", ENV);
|
JAKE.subjake(["."], "build", ENV);
|
||||||
});
|
});
|
||||||
|
|
||||||
task ("run", ["debug"], function()
|
|
||||||
{
|
|
||||||
OS.system(["open", FILE.join("Build", "Debug", "CPSplitViewTest", "index.html")]);
|
|
||||||
});
|
|
||||||
|
|
||||||
task ("run-release", ["release"], function()
|
|
||||||
{
|
|
||||||
OS.system(["open", FILE.join("Build", "Release", "CPSplitViewTest", "index.html")]);
|
|
||||||
});
|
|
||||||
|
|
||||||
task ("deploy", ["release"], function()
|
|
||||||
{
|
|
||||||
FILE.mkdirs(FILE.join("Build", "Deployment", "CPSplitViewTest"));
|
|
||||||
OS.system(["press", "-f", FILE.join("Build", "Release", "CPSplitViewTest"), FILE.join("Build", "Deployment", "CPSplitViewTest")]);
|
|
||||||
printResults("Deployment")
|
|
||||||
});
|
|
||||||
|
|
||||||
task ("desktop", ["release"], function()
|
|
||||||
{
|
|
||||||
FILE.mkdirs(FILE.join("Build", "Desktop", "CPSplitViewTest"));
|
|
||||||
require("cappuccino/nativehost").buildNativeHost(FILE.join("Build", "Release", "CPSplitViewTest"), FILE.join("Build", "Desktop", "CPSplitViewTest", "CPSplitViewTest.app"));
|
|
||||||
printResults("Desktop")
|
|
||||||
});
|
|
||||||
|
|
||||||
task ("run-desktop", ["desktop"], function()
|
|
||||||
{
|
|
||||||
OS.system([FILE.join("Build", "Desktop", "CPSplitViewTest", "CPSplitViewTest.app", "Contents", "MacOS", "NativeHost"), "-i"]);
|
|
||||||
});
|
|
||||||
|
|
||||||
function printResults(configuration)
|
function printResults(configuration)
|
||||||
{
|
{
|
||||||
print("----------------------------");
|
console.log("----------------------------");
|
||||||
print(configuration+" app built at path: "+FILE.join("Build", configuration, "CPSplitViewTest"));
|
console.log(configuration+" app built at path: "+path.join(buildDir, configuration, projectName));
|
||||||
print("----------------------------");
|
console.log("----------------------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateApplicationSize()
|
||||||
|
{
|
||||||
|
console.log("Calculating application file sizes...");
|
||||||
|
|
||||||
|
var contents = fs.readFileSync(path.join(buildDir, configuration, projectName, "Info.plist"), { encoding: "utf8" }),
|
||||||
|
format = CFPropertyList.sniffedFormatOfString(contents),
|
||||||
|
plist = CFPropertyList.propertyListFromString(contents),
|
||||||
|
totalBytes = {executable:0, data:0, mhtml:0};
|
||||||
|
|
||||||
|
// Get the size of all framework executables and sprite data
|
||||||
|
var frameworksDir = "Frameworks";
|
||||||
|
|
||||||
|
if (configuration === "Debug")
|
||||||
|
frameworksDir = path.join(frameworksDir, "Debug");
|
||||||
|
|
||||||
|
var frameworks = [];
|
||||||
|
|
||||||
|
if (fs.existsSync(frameworksDir)) {
|
||||||
|
frameworks = fs.readdirSync(frameworksDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
frameworks.forEach(function(framework)
|
||||||
|
{
|
||||||
|
if (framework !== "Source")
|
||||||
|
addBundleFileSizes(path.join(frameworksDir, framework), totalBytes);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Read in the default theme name, and attempt to get its size
|
||||||
|
var themeName = plist.valueForKey("CPDefaultTheme") || "Aristo2",
|
||||||
|
themePath = nil;
|
||||||
|
|
||||||
|
if (themeName === "Aristo" || themeName === "Aristo2")
|
||||||
|
themePath = path.join(frameworksDir, "AppKit", "Resources", themeName + ".blend");
|
||||||
|
else
|
||||||
|
themePath = path.join("Frameworks", "Resources", themeName + ".blend");
|
||||||
|
|
||||||
|
if (fs.existsSync(themePath) && fs.lstatSync(themePath).isDirectory())
|
||||||
|
addBundleFileSizes(themePath, totalBytes);
|
||||||
|
|
||||||
|
// Add sizes for the app
|
||||||
|
addBundleFileSizes(path.join(buildDir, configuration, projectName), totalBytes);
|
||||||
|
|
||||||
|
console.log("Executables: " + totalBytes.executable + ", sprite data: " + totalBytes.data + ", total: " + (totalBytes.executable + totalBytes.data));
|
||||||
|
|
||||||
|
var dict = new CFMutableDictionary();
|
||||||
|
|
||||||
|
dict.setValueForKey("executable", totalBytes.executable);
|
||||||
|
dict.setValueForKey("data", totalBytes.data);
|
||||||
|
dict.setValueForKey("mhtml", totalBytes.mhtml);
|
||||||
|
|
||||||
|
plist.setValueForKey("CPApplicationSize", dict);
|
||||||
|
fs.writeFileSync(path.join(buildDir, configuration, projectName, "Info.plist"), CFPropertyList.stringFromPropertyList(plist, format), { encoding: "utf8" });
|
||||||
|
}
|
||||||
|
|
||||||
|
function addBundleFileSizes(bundlePath, totalBytes)
|
||||||
|
{
|
||||||
|
var bundleName = path.basename(bundlePath),
|
||||||
|
environment = bundleName === "Foundation" ? "Objj" : "Browser",
|
||||||
|
bundlePath = path.join(bundlePath, environment + ".environment");
|
||||||
|
|
||||||
|
if (fs.existsSync(bundlePath) && fs.lstatSync(bundlePath).isDirectory())
|
||||||
|
{
|
||||||
|
var filename = bundleName + ".sj",
|
||||||
|
filePath = path.join(bundlePath, filename);
|
||||||
|
|
||||||
|
if (fs.existsSync(filePath)) {
|
||||||
|
totalBytes.executable += fs.lstatSync(filePath).size;
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath = path.join(bundlePath, "dataURLs.txt");
|
||||||
|
|
||||||
|
if (fs.existsSync(filePath))
|
||||||
|
totalBytes.data += fs.lstatSync(filePath).size;
|
||||||
|
|
||||||
|
filePath = path.join(bundlePath, "MHTMLData.txt");
|
||||||
|
|
||||||
|
if (fs.existsSync(filePath))
|
||||||
|
totalBytes.mhtml += fs.lstatSync(filePath).size;
|
||||||
|
|
||||||
|
filePath = path.join(bundlePath, "MHTMLPaths.txt");
|
||||||
|
|
||||||
|
if (fs.existsSync(filePath))
|
||||||
|
totalBytes.mhtml += fs.lstatSync(filePath).size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user