Compare commits

...
37 Commits
Author SHA1 Message Date
tlrobinsonandFrancisco Ryan Tolmasky I f4f48e4e09 Disable encoding/decoding of plusses in URIs 2009-06-23 17:00:25 -07:00
Francisco Ryan Tolmasky I 4afb8003e6 Updating version strings to 0.7.1.
Reviewed by me.
2009-06-23 17:00:25 -07:00
Francisco Ryan Tolmasky I 5876bcf592 Fix for capitalization issue with circular slider images.
Reviewed by me.
2009-06-23 17:00:25 -07:00
Francisco Ryan Tolmasky I 2486965338 Fix for window returning a direct reference to its frame instead of a copy.
Reviewed by me.
2009-06-23 17:00:25 -07:00
Francisco Ryan Tolmasky I ee830f51d7 Fix for dragged types not working on decoded views.
Reviewed by me.
2009-06-23 17:00:25 -07:00
Francisco Ryan Tolmasky I 343b3e41f3 Made CPImageView accept image drag and drop.
Reviewed by me.

Conflicts:

	AppKit/CPPasteboard.j
2009-06-23 17:00:25 -07:00
Tom RobinsonandFrancisco Ryan Tolmasky I 2474774242 Update Externals to latest. Remove first arg in objj, objjc, and cplutil to match changes to Narwhal. 2009-06-23 17:00:25 -07:00
Francisco Ryan Tolmasky I 3b04b027f8 Fix for image views in toolbar items not displaying their images.
Reviewed by me.
2009-06-13 11:42:23 -07:00
Francisco Ryan Tolmasky I 2beebd4c1e Made class swapping more robust.
Reviewed by me.
2009-06-13 11:42:22 -07:00
Francisco Ryan Tolmasky I 3b9e73faba Added support for custom classes on non-customviews in nib2cib.
Reviewed by me.
2009-06-13 11:42:22 -07:00
Francisco Ryan Tolmasky I 38273e4dab Fix for -description in CPArray containing null or undefined values.
Reviewed by me.
2009-06-13 11:42:22 -07:00
Tom RobinsonandFrancisco Ryan Tolmasky I 787e0c8afd Update to use JSON.{parse,stringify} 2009-06-13 11:42:22 -07:00
Tom RobinsonandFrancisco Ryan Tolmasky I 774ea99319 Update JSON support to json2.js, added in Objective-J. Deprecate CPJSObjectCreateJSON and CPJSObjectCreateWithJSON. 2009-06-13 11:42:22 -07:00
Ross BoucherandFrancisco Ryan Tolmasky I 0ca573c7e6 Update the documentation of methods define with the BRIDGE macro 2009-06-13 11:42:21 -07:00
Ross BoucherandFrancisco Ryan Tolmasky I 751b89237f Fix for VML paths 2009-06-13 11:42:21 -07:00
Ross BoucherandFrancisco Ryan Tolmasky I 41eeb69485 Fix for KAPPA missing in CGPath. Looks like it was auto-merged out. 2009-06-13 11:42:21 -07:00
Francisco Ryan Tolmasky I 18a0e7f0d2 Fix for providing too many image slices breaking CPView.
Reviewed by me.
2009-05-31 13:45:58 -07:00
Nicholas SmallandFrancisco Ryan Tolmasky I ef9053f1ba Fix for undefined key handling.
Reviewed by me.
2009-05-31 01:35:51 -07:00
Francisco Ryan Tolmasky I 8a9b9d4821 Fix for nib2cib's separator menu items not showing up.
Reviewed by me.
2009-05-31 01:35:43 -07:00
Francisco Ryan Tolmasky I 6afaff6d2f Support for new CPEvent mechanism.
Reviewed by me.
2009-05-30 23:19:27 -07:00
Francisco Ryan Tolmasky I 95f594131b Coat tailed CPEvents on native DOM events if they exist, saving the creation of many objects.
Reviewed by me.
2009-05-30 23:17:59 -07:00
Tom RobinsonandFrancisco Ryan Tolmasky I de9ab95b55 Rename plutil back to cputil. Oops. 2009-05-30 13:34:14 -07:00
Tom RobinsonandFrancisco Ryan Tolmasky I ce0c3a9b6e Fixed incorrect variables in regexp-rhino-patch 2009-05-30 13:34:05 -07:00
Tom RobinsonandFrancisco Ryan Tolmasky I 380b0d0e5d Bring back the Rhino regex patch to use native Java regex. 2009-05-30 13:33:54 -07:00
Francisco Ryan Tolmasky I 90e7508700 Fix for Unicode chars being mangled when building.
Closes #146.

Reviewed by me.
2009-05-27 01:36:10 -07:00
Francisco Ryan Tolmasky I fc7b5a86ef Further work on theme showcase.
Reviewed by me.
2009-05-25 15:31:52 -07:00
tlrobinsonandFrancisco Ryan Tolmasky I 26ebd6bf64 When loading modules escape "+" in case they're converted to spaces later.
Updated to latest Narwhal and Jack
2009-05-25 15:31:35 -07:00
Francisco Ryan Tolmasky I 28b387554f Added Demos, Aristo, and WebSite to .gitignore so they can be checked out together and eventually built together.
Reviewed by me.
2009-05-24 16:11:15 -07:00
Francisco Ryan Tolmasky I c4c9528af6 Organized BlendKit classes into their own files and added licensing info.
Reviewed by me.
2009-05-24 15:01:22 -07:00
Francisco Ryan Tolmasky I a90e9c83f4 Fix for typos in CPButton.j.
Closes #139.

Reviewed by me.
2009-05-24 14:27:55 -07:00
Francisco Ryan Tolmasky I 25c145e490 Fix Info.plist name for Aristo blend.
Reviewed by me.
2009-05-24 12:49:25 -07:00
Francisco Ryan Tolmasky I 44dc4f6595 Fix for scroll wheel not working in Firefox 3 and up.
Closes #102.

Reviewed by me.
2009-05-24 12:45:51 -07:00
Francisco Ryan Tolmasky I 83bceaa867 Fix for HUD button misrendered in Aristo theme gallery until pressed for first time.
Closes #141.

Reviewed by me.
2009-05-23 13:04:29 -07:00
Francisco Ryan Tolmasky I f6a731ff91 Updated loading page and removed some unused resources from Aristo blend.
Reviewed by me.
2009-05-23 12:55:20 -07:00
Francisco Ryan Tolmasky I 354fddf6b2 Updated template theme project to use new theme gallery.
Reviewed by me.
2009-05-23 12:43:35 -07:00
Francisco Ryan Tolmasky I aebbdbe0a3 Fixed a few graphics bugs and made the automatically generated theme gallery nicer.
Reviewed by me.
2009-05-23 12:33:24 -07:00
Francisco Ryan Tolmasky I 15bff97388 Fix for MainMenu.cib not displaying images.
Closes #140.

Reviewed by me.
2009-05-22 03:23:08 -07:00
90 changed files with 1892 additions and 700 deletions
+3
View File
@@ -1,3 +1,6 @@
.DS_Store
Frameworks
Build
Demos
Aristo
WebSite
+6 -1
View File
@@ -476,6 +476,11 @@ CPRunContinuesResponse = -1002;
_mainMenu = aMenu;
}
- (void)orderFrontColorPanel:(id)aSender
{
[[CPColorPanel sharedColorPanel] orderFront:self];
}
- (void)orderFrontStandardAboutPanel:(id)aSender
{
[self orderFrontStandardAboutPanelWithOptions:nil];
@@ -841,7 +846,7 @@ var _CPAppBootstrapperActions = nil;
if (mainCibFile)
{
[CPBundle loadCibFile:[mainBundle pathForResource:mainCibFile]
[mainBundle loadCibFile:mainCibFile
externalNameTable:[CPDictionary dictionaryWithObject:CPApp forKey:CPCibOwner]
loadDelegate:self];
+2 -2
View File
@@ -368,7 +368,7 @@ CPButtonStateMixed = CPThemeState("mixed");
- (void)setButtonType:(CPButtonType)aButtonType
{
switch (buttonType)
switch (aButtonType)
{
case CPMomentaryLightButton: [self setHighlightsBy:CPChangeBackgroundCellMask];
[self setShowsStateBy:CPNoCellMask];
@@ -390,7 +390,7 @@ CPButtonStateMixed = CPThemeState("mixed");
[self setShowsStateBy:CPChangeBackgroundCellMask];
break;
case CPToggleButton: [self setHighlightsBy:CPPushInCellMask | NSContentsCellMask];
case CPToggleButton: [self setHighlightsBy:CPPushInCellMask | CPContentsCellMask];
[self setShowsStateBy:CPContentsCellMask];
break;
+1 -1
View File
@@ -491,7 +491,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
var future = new Date();
future.setYear(2019);
[_swatchCookie setValue: CPJSObjectCreateJSON(result) expires:future domain: nil];
[_swatchCookie setValue: JSON.stringify(result) expires:future domain: nil];
}
- (void)setColorPanel:(CPColorPanel)panel
+3 -6
View File
@@ -119,22 +119,19 @@ else if (USER_AGENT.indexOf("KHTML") != -1) // Must follow WebKit check.
}
// Gecko
else if (USER_AGENT.indexOf("Gecko") != -1) // Must follow KHTML check.
else if (USER_AGENT.indexOf("Gecko") !== -1) // Must follow KHTML check.
{
PLATFORM_ENGINE = CPGeckoBrowserEngine;
PLATFORM_FEATURES |= CPJavaScriptCanvasDrawFeature;
var index = USER_AGENT.indexOf("Firefox"),
version = (index == -1) ? 2.0 : parseFloat(USER_AGENT.substring(index + "Firefox".length + 1));
version = (index === -1) ? 2.0 : parseFloat(USER_AGENT.substring(index + "Firefox".length + 1));
if (version >= 3.0)
PLATFORM_FEATURES |= CPCSSRGBAFeature;
var geckoIndex = USER_AGENT.indexOf("Gecko"),
geckoVersion = (geckoIndex === -1) ? 0.0 : parseFloat(USER_AGENT.substring(geckoIndex + "Gecko".length + 1, USER_AGENT.indexOf(' ', geckoIndex)));
if (version < 20061028)
if (version < 3.0)
PLATFORM_FEATURES |= CPJavaScriptMouseWheelValues_8_15;
}
+2
View File
@@ -505,10 +505,12 @@ var CPControlBlackColor = [CPColor blackColor];
}
#define BRIDGE(UPPERCASE, LOWERCASE, ATTRIBUTENAME) \
/*! Sets the value for ATTRIBUTENAME */\
- (void)set##UPPERCASE:(id)aValue\
{\
[self setValue:aValue forThemeAttribute:ATTRIBUTENAME];\
}\
/*! Returns the current value for ATTRIBUTENAME */\
- (id)LOWERCASE\
{\
return [self valueForThemeAttribute:ATTRIBUTENAME];\
+25 -1
View File
@@ -206,6 +206,7 @@ var _CPEventPeriodicEventPeriod = 0,
unsigned _clickCount;
float _pressure;
CPWindow _window;
Number _windowNumber;
CPString _characters;
CPString _charactersIgnoringModifiers
BOOL _isARepeat;
@@ -327,7 +328,7 @@ var _CPEventPeriodicEventPeriod = 0,
_charactersIgnoringModifiers = unmodCharacters;
_isARepeat = isARepeat;
_keyCode = code;
_window = [CPApp windowWithWindowNumber:aWindowNumber];
_windowNumber = aWindowNumber;
}
return self;
@@ -397,6 +398,9 @@ var _CPEventPeriodicEventPeriod = 0,
*/
- (CPWindow)window
{
if (!_window)
_window = [CPApp windowWithWindowNumber:_windowNumber];
return _window;
}
@@ -532,3 +536,23 @@ function _CPEventFirePeriodEvent()
[CPApp sendEvent:[CPEvent otherEventWithType:CPPeriodic location:_CGPointMakeZero() modifierFlags:0 timestamp:0 windowNumber:0 context:nil subtype:0 data1:0 data2:0]];
}
var CPEventClass = [CPEvent class];
function _CPEventFromNativeMouseEvent(aNativeEvent, anEventType, aPoint, modifierFlags, aTimestamp, aWindowNumber, aGraphicsContext, anEventNumber, aClickCount, aPressure)
{
aNativeEvent.isa = CPEventClass;
aNativeEvent._type = anEventType;
aNativeEvent._location = aPoint;
aNativeEvent._modifierFlags = modifierFlags;
aNativeEvent._timestamp = aTimestamp;
aNativeEvent._windowNumber = aWindowNumber;
aNativeEvent._window = nil;
aNativeEvent._context = aGraphicsContext;
aNativeEvent._eventNumber = anEventNumber;
aNativeEvent._clickCount = aClickCount;
aNativeEvent._pressure = aPressure;
return aNativeEvent;
}
+46 -2
View File
@@ -70,7 +70,9 @@ var LEFT_SHADOW_INSET = 3.0,
BOOL _hasShadow;
CPView _shadowView;
BOOL _isEditable;
CGRect _imageRect;
}
@@ -339,11 +341,47 @@ var LEFT_SHADOW_INSET = 3.0,
[[self nextResponder] mouseDown:anEvent];
}
- (void)setEditable:(BOOL)shouldBeEditable
{
if (_isEditable === shouldBeEditable)
return;
_isEditable = shouldBeEditable;
if (_isEditable)
[self registerForDraggedTypes:[CPImagesPboardType]];
else
{
var draggedTypes = [self registeredDraggedTypes];
[self unregisterDraggedTypes];
[draggedTypes removeObjectIdenticalTo:CPImagesPboardType];
[self registerForDraggedTypes:draggedTypes];
}
}
- (BOOL)isEditable
{
return _isEditable;
}
- (void)performDragOperation:(CPDraggingInfo)aSender
{
var images = [CPKeyedUnarchiver unarchiveObjectWithData:[[aSender draggingPasteboard] dataForType:CPImagesPboardType]];
if ([images count])
[self setImage:images[0]];
}
@end
var CPImageViewImageKey = @"CPImageViewImageKey",
CPImageViewImageScalingKey = @"CPImageViewImageScalingKey",
CPImageViewHasShadowKey = @"CPImageViewHasShadowKey";
CPImageViewHasShadowKey = @"CPImageViewHasShadowKey",
CPImageViewIsEditableKey = @"CPImageViewIsEditableKey";
@implementation CPImageView (CPCoding)
@@ -372,6 +410,9 @@ var CPImageViewImageKey = @"CPImageViewImageKey",
[self setHasShadow:[aCoder decodeBoolForKey:CPImageViewHasShadowKey]];
if ([aCoder decodeBoolForKey:CPImageViewIsEditableKey] || NO)
[self setEditable:YES];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
@@ -402,6 +443,9 @@ var CPImageViewImageKey = @"CPImageViewImageKey",
_subviews = actualSubviews;
[aCoder encodeBool:_hasShadow forKey:CPImageViewHasShadowKey];
if (_isEditable)
[aCoder encodeBool:_isEditable forKey:CPImageViewIsEditableKey];
}
@end
+3 -3
View File
@@ -684,13 +684,13 @@ var _CPMenuBarVisible = NO,
[_CPMenuWindow poolMenuWindow:aMenuWindow];
if([aMenuItem isEnabled])
[CPApp sendAction:[aMenuItem action] to:[aMenuItem target] from:aMenuItem];
var delegate = [menu delegate];
if ([delegate respondsToSelector:@selector(menuDidClose:)])
[delegate menuDidClose:menu];
if([aMenuItem isEnabled])
[CPApp sendAction:[aMenuItem action] to:[aMenuItem target] from:aMenuItem];
}
// Managing Display of State Column
+17 -24
View File
@@ -38,6 +38,8 @@
*/
@implementation CPMenuItem : CPObject
{
BOOL _isSeparator;
CPString _title;
//CPAttributedString _attributedTitle;
@@ -89,6 +91,8 @@
if (self)
{
_isSeparator = NO;
_title = aTitle;
_action = anAction;
@@ -479,7 +483,11 @@ CPOffState
*/
+ (CPMenuItem)separatorItem
{
return [[_CPMenuItemSeparator alloc] init];
var separatorItem = [[self alloc] initWithTitle:@"" action:nil keyEquivalent:nil];
separatorItem._isSeparator = YES;
return separatorItem;
}
/*!
@@ -487,7 +495,7 @@ CPOffState
*/
- (BOOL)isSeparatorItem
{
return NO;
return _isSeparator;
}
// Managing the Owning Menu
@@ -731,29 +739,9 @@ CPControlKeyMask
@end
/* @ignore */
@implementation _CPMenuItemSeparator : CPMenuItem
{
}
var CPMenuItemIsSeparatorKey = @"CPMenuItemIsSeparatorKey",
- (id)init
{
self = [super initWithTitle:@"" action:nil keyEquivalent:nil];
if (self)
[self setEnabled:NO];
return self;
}
- (BOOL)isSeparatorItem
{
return YES;
}
@end
var CPMenuItemTitleKey = @"CPMenuItemTitleKey",
CPMenuItemTitleKey = @"CPMenuItemTitleKey",
CPMenuItemTargetKey = @"CPMenuItemTargetKey",
CPMenuItemActionKey = @"CPMenuItemActionKey",
@@ -787,6 +775,8 @@ var CPMenuItemTitleKey = @"CPMenuItemTitleKey",
if (self)
{
_isSeparator = [aCoder containsValueForKey:CPMenuItemIsSeparatorKey] && [aCoder decodeBoolForKey:CPMenuItemIsSeparatorKey];
_title = [aCoder decodeObjectForKey:CPMenuItemTitleKey];
// _font;
@@ -832,6 +822,9 @@ var CPMenuItemTitleKey = @"CPMenuItemTitleKey",
*/
- (void)encodeWithCoder:(CPCoder)aCoder
{
if (_isSeparator)
[aCoder encodeBool:_isSeparator forKey:CPMenuItemIsSeparatorKey];
[aCoder encodeObject:_title forKey:CPMenuItemTitleKey];
[aCoder encodeObject:_target forKey:CPMenuItemTargetKey];
+4
View File
@@ -38,6 +38,10 @@ CPFontPboardType = @"CPFontPboardType";
CPHTMLPboardType = @"CPHTMLPboardType";
CPStringPboardType = @"CPStringPboardType";
CPURLPboardType = @"CPURLPboardType";
CPImagesPboardType = @"CPImagesPboardType";
CPVideosPboardType = @"CPVideosPboardType";
// Deprecated
CPImagePboardType = @"CPImagePboardType";
var CPPasteboards = nil;
+1 -1
View File
@@ -502,7 +502,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
{
if ([self title] === aTitle)
return;
if ([self pullsDown])
{
var items = [_menu itemArray];
+5 -4
View File
@@ -458,15 +458,16 @@ CPToolbarItemVisibilityPriorityUser
[copy setLabel:_label];
[copy setPaletteLabel:_paletteLabel];
[copy setToolTip:[self toolTip]];
[copy setTag:[self tag]];
[copy setTarget:[self target]];
[copy setAction:[self action]];
[copy setEnabled:[self isEnabled]];
[copy setImage:_image];
[copy setAlternateImage:_alternateImage];
[copy setImage:[self image]];
[copy setAlternateImage:[self alternateImage]];
[copy setMinSize:_minSize];
[copy setMaxSize:_maxSize];
+12 -5
View File
@@ -1208,7 +1208,7 @@ var DOMElementPrototype = nil,
amount = 0 - _DOMImageParts.length;
}
if (amount > 0)
while (amount--)
{
@@ -1236,16 +1236,16 @@ var DOMElementPrototype = nil,
else
{
var slices = [patternImage imageSlices],
count = slices.length,
count = MIN(_DOMImageParts.length, slices.length),
frameSize = _frame.size;
while (count--)
{
var image = slices[count],
size = _DOMImageSizes[count] = image ? [image size] : _CGSizeMakeZero();
CPDOMDisplayServerSetStyleSize(_DOMImageParts[count], size.width, size.height);
_DOMImageParts[count].style.background = image ? "url(\"" + [image filename] + "\")" : "";
}
@@ -1469,7 +1469,7 @@ setBoundsOrigin:
*/
- (void)registerForDraggedTypes:(CPArray)pasteboardTypes
{
if (!pasteboardTypes)
if (!pasteboardTypes || ![pasteboardTypes count])
return;
var theWindow = [self window];
@@ -2107,6 +2107,9 @@ setBoundsOrigin:
for (var attributeName in _themeAttributes)
if (_themeAttributes.hasOwnProperty(attributeName))
[_themeAttributes[attributeName] setParentAttribute:[theme _attributeWithName:attributeName forClass:themeClass]];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
- (CPDictionary)_themeAttributeDictionary
@@ -2231,6 +2234,10 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
_subviews = [aCoder decodeObjectForKey:CPViewSubviewsKey] || [];
_superview = [aCoder decodeObjectForKey:CPViewSuperviewKey];
// FIXME: Should we encode/decode this?
_registeredDraggedTypes = [CPSet set];
_registeredDraggedTypesArray = [];
_autoresizingMask = [aCoder decodeIntForKey:CPViewAutoresizingMaskKey] || CPViewNotSizable;
_autoresizesSubviews = ![aCoder containsValueForKey:CPViewAutoresizesSubviewsKey] || [aCoder decodeBoolForKey:CPViewAutoresizesSubviewsKey];
+1 -1
View File
@@ -567,7 +567,7 @@ CPTexturedBackgroundWindowMask
*/
- (CGRect)frame
{
return _frame;
return _CGRectMakeCopy(_frame);
}
/*!
+1
View File
@@ -24,6 +24,7 @@
@import <Foundation/CPURLConnection.j>
@import <Foundation/CPURLRequest.j>
@import "_CPCibClassSwapper.j"
@import "_CPCibCustomObject.j"
@import "_CPCibCustomResource.j"
@import "_CPCibCustomView.j"
+76
View File
@@ -0,0 +1,76 @@
/*
* _CPCibClassSwapper.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* 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 <Foundation/CPObject.j>
@import <Foundation/CPString.j>
var _CPCibClassSwapperClassNameKey = @"_CPCibClassSwapperClassNameKey",
_CPCibClassSwapperOriginalClassNameKey = @"_CPCibClassSwapperOriginalClassNameKey";
@implementation _CPCibClassSwapper : CPObject
{
}
+ (void)allocObjectWithCoder:(CPCoder)aCoder className:(CPString)aClassName
{
// FIXME: Also check class classForClassName:
var theClass = [aCoder classForClassName:aClassName];
if (!theClass)
{
theClass = objj_lookUpClass(aClassName);
if (!theClass)
return nil;
}
return [theClass alloc];
}
+ (id)allocWithCoder:(CPCoder)aCoder
{
if ([aCoder respondsToSelector:@selector(usesOriginalClasses)] && [aCoder usesOriginalClasses])
{
var theClassName = [aCoder decodeObjectForKey:_CPCibClassSwapperOriginalClassNameKey],
object = [self allocObjectWithCoder:aCoder className:theClassName];
}
else
{
var theClassName = [aCoder decodeObjectForKey:_CPCibClassSwapperClassNameKey],
object = [self allocObjectWithCoder:aCoder className:theClassName];
if (!object)
{
CPLog.error("Unable to find class " + theClassName + " in cib file.");
object = [self allocObjectWithCoder:aCoder className:[aCoder decodeObjectForKey:_CPCibClassSwapperOriginalClassNameKey]];
}
}
if (!object)
[CPException raise:CPInvalidArgumentException reason:@"Unable to find class " + theClassName + " in cib file."];
return object;
}
@end
+37 -20
View File
@@ -87,20 +87,20 @@ function CGPathAddArc(aPath, aTransform, x, y, aRadius, aStartAngle, anEndAngle,
var center = _CGPointMake(x, y),
end = _CGPointMake(COS(anEndAngle), SIN(anEndAngle)),
start = _CGPointMake(COS(aStartAngle), SIN(aStartAngle));
end = _CGPointApplyAffineTransform(end, aTransform);
start = _CGPointApplyAffineTransform(start, aTransform);
center = _CGPointApplyAffineTransform(center, aTransform);
x = center.x;
y = center.y;
var oldEndAngle = anEndAngle,
oldStartAngle = aStartAngle;
anEndAngle = ATAN2(end.y - aTransform.ty, end.x - aTransform.tx);
aStartAngle = ATAN2(start.y - aTransform.ty, start.x - aTransform.tx);
// Angles that equal "modulo" 2 pi return as equal after transforming them,
// so we have to make sure to make them different again if they were different
// to start out with. It's the difference between no circle and a full circle.
@@ -109,7 +109,7 @@ function CGPathAddArc(aPath, aTransform, x, y, aRadius, aStartAngle, anEndAngle,
anEndAngle = anEndAngle - PI2;
else
aStartAngle = aStartAngle - PI2;
aRadius = _CGSizeMake(aRadius, 0);
aRadius = _CGSizeApplyAffineTransform(aRadius, aTransform);
aRadius = SQRT(aRadius.width * aRadius.width + aRadius.height * aRadius.height);
@@ -169,23 +169,38 @@ function CGPathAddLineToPoint(aPath, aTransform, x, y)
function CGPathAddPath(aPath, aTransform, anotherPath)
{
var i = 0,
count = anotherPath.count;
for (; i < count; ++i)
for (var i = 0, count = anotherPath.count; i < count; ++i)
{
var element = anotherPath.elements[i];
aPath.elements[aPath.count] = { type:element.type, x:element.x, y:element.y,
cpx:element.cpx, cpy:element.cpy,
radius:element.radius, startAngle:element.startAngle, endAngle:element.endAngle,
cp1x:element.cp1x, cp1y:element.cp1y, cp2x:element.cp2x, cp2y:element.cp2y,
points: element.points ? element.points.slice() : nil};
aPath.count++
switch (element.type)
{
case kCGPathElementAddLineToPoint: CGPathAddLineToPoint(aPath, aTransform, element.x, element.y);
break;
case kCGPathElementAddCurveToPoint: CGPathAddCurveToPoint(aPath, aTransform,
element.cp1x, element.cp1y,
element.cp2x, element.cp2y,
element.x, element.y);
break;
case kCGPathElementAddArc: CGPathAddArc(aPath, aTransform, element.x, element.y,
element.radius, element.startAngle,
element.endAngle, element.isClockwise);
break;
case kCGPathElementAddQuadCurveToPoint: CGPathAddQuadCurveToPoint(aPath, aTransform,
element.cpx, element.cpy,
element.x, element.y);
break;
case kCGPathElementMoveToPoint: CGPathMoveToPoint(aPath, aTransform, element.x, element.y);
break;
case kCGPathElementCloseSubpath: CGPathCloseSubpath(aPath);
break;
}
}
aPath.current = anotherPath.current;
}
function CGPathAddQuadCurveToPoint(aPath, aTransform, cpx, cpy, x, y)
@@ -250,6 +265,8 @@ function CGPathMoveToPoint(aPath, aTransform, x, y)
aPath.elements[aPath.count++] = { type:kCGPathElementMoveToPoint, x:point.x, y:point.y };
}
var KAPPA = 4.0 * ((SQRT2 - 1.0) / 3.0);
function CGPathWithEllipseInRect(aRect)
{
var path = CGPathCreateMutable();
+11 -17
View File
@@ -351,7 +351,7 @@ var CPDOMWindowGetFrame,
theWindow = candidateWindow;
}
}
return theWindow;
}
@@ -462,7 +462,7 @@ var CTRL_KEY_CODE = 17;
var theType = _overriddenEventType || aDOMEvent.type;
// IE's event order is down, up, up, dblclick, so we have create these events artificially.
if (theType == CPDOMEventDoubleClick)
if (theType === CPDOMEventDoubleClick)
{
_overriddenEventType = CPDOMEventMouseDown;
[self _bridgeMouseEvent:aDOMEvent];
@@ -495,7 +495,7 @@ var CTRL_KEY_CODE = 17;
{
var theWindow = [self hitTest:location];
if (aDOMEvent.type == CPDOMEventMouseDown && theWindow)
if ((aDOMEvent.type === CPDOMEventMouseDown) && theWindow)
_mouseDownWindow = theWindow;
windowNumber = [theWindow windowNumber];
@@ -510,12 +510,10 @@ var CTRL_KEY_CODE = 17;
}
switch (theType)
{
{
case CPDOMEventMouseUp: if(_mouseIsDown)
{
event = [CPEvent mouseEventWithType:CPLeftMouseUp location:location modifierFlags:modifierFlags
timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:-1
clickCount:CPDOMEventGetClickCount(_lastMouseUp, timestamp, location) pressure:0];
event = _CPEventFromNativeMouseEvent(aDOMEvent, CPLeftMouseUp, location, modifierFlags, timestamp, windowNumber, nil, -1, CPDOMEventGetClickCount(_lastMouseUp, timestamp, location), 0);
_mouseIsDown = NO;
_lastMouseUp = event;
@@ -547,9 +545,7 @@ var CTRL_KEY_CODE = 17;
return;
}
event = [CPEvent mouseEventWithType:CPLeftMouseDown location:location modifierFlags:modifierFlags
timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:-1
clickCount:CPDOMEventGetClickCount(_lastMouseDown, timestamp, location) pressure:0];
event = _CPEventFromNativeMouseEvent(aDOMEvent, CPLeftMouseDown, location, modifierFlags, timestamp, windowNumber, nil, -1, CPDOMEventGetClickCount(_lastMouseDown, timestamp, location), 0);
_mouseIsDown = YES;
_lastMouseDown = event;
@@ -558,10 +554,8 @@ var CTRL_KEY_CODE = 17;
case CPDOMEventMouseMoved: if (_DOMEventMode)
return;
event = [CPEvent mouseEventWithType:_mouseIsDown ? CPLeftMouseDragged : CPMouseMoved
location:location modifierFlags:modifierFlags timestamp:timestamp
windowNumber:windowNumber context:nil eventNumber:-1 clickCount:1 pressure:0];
event = _CPEventFromNativeMouseEvent(aDOMEvent, _mouseIsDown ? CPLeftMouseDragged : CPMouseMoved, location, modifierFlags, timestamp, windowNumber, nil, -1, 1, 0);
break;
}
@@ -988,15 +982,15 @@ var CPDOMEventStop = function(aDOMEvent)
// IE Model
aDOMEvent.cancelBubble = true;
aDOMEvent.returnValue = false;
// W3C Model
if (aDOMEvent.preventDefault)
aDOMEvent.preventDefault();
if (aDOMEvent.stopPropagation)
aDOMEvent.stopPropagation();
if (aDOMEvent.type == CPDOMEventMouseDown)
if (aDOMEvent.type === CPDOMEventMouseDown)
{
CPSharedDOMWindowBridge._DOMFocusElement.focus();
CPSharedDOMWindowBridge._DOMFocusElement.blur();
+1 -1
View File
@@ -17,7 +17,7 @@ AppKitFiles = FileList['**/*.j'].exclude('CoreGraphics/CGContextCanvas.j', 'Core
ObjectiveJ::BundleTask.new(:AppKit) do |t|
t.name = 'AppKit'
t.identifier = 'com.280n.AppKit'
t.version = '0.7.0'
t.version = '0.7.1'
t.author = '280 North, Inc.'
t.email = 'feedback @nospam@ 280north.com'
t.summary = 'AppKit classes for Cappuccino'
+5 -1
View File
@@ -5,7 +5,11 @@
<key>CPApplicationDelegateClass</key>
<string>BKShowcaseController</string>
<key>CPBundleName</key>
<string>A</string>
<string>Aristo</string>
<key>BKLearnMoreURL</key>
<string>http://cappuccino.org/aristo</string>
<key>BKLearnMoreButtonTitle</key>
<string>Aristo Home Page</string>
<key>CPPrincipalClass</key>
<string>CPApplication</string>
</dict>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 397 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Before

Width:  |  Height:  |  Size: 1013 B

After

Width:  |  Height:  |  Size: 1013 B

Before

Width:  |  Height:  |  Size: 185 B

After

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

+138 -116
View File
@@ -10,7 +10,7 @@
@import <AppKit/AppKit.j>
@implementation AristoThemeDescriptor : CPObject
@implementation AristoThemeDescriptor : BKThemeDescriptor
{
}
@@ -19,6 +19,137 @@
return @"Aristo";
}
+ (CPButton)button
{
var button = [[CPButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 60.0, 24.0)],
bezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[_CPCibCustomResource imageResourceWithName:"button-bezel-left.png" size:CGSizeMake(4.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"button-bezel-center.png" size:CGSizeMake(1.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"button-bezel-right.png" size:CGSizeMake(4.0, 24.0)]
]
isVertical:NO]],
highlightedBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[_CPCibCustomResource imageResourceWithName:"button-bezel-highlighted-left.png" size:CGSizeMake(4.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"button-bezel-highlighted-center.png" size:CGSizeMake(1.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"button-bezel-highlighted-right.png" size:CGSizeMake(4.0, 24.0)]
]
isVertical:NO]],
defaultBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[_CPCibCustomResource imageResourceWithName:"default-button-bezel-left.png" size:CGSizeMake(4.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"default-button-bezel-center.png" size:CGSizeMake(1.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"default-button-bezel-right.png" size:CGSizeMake(4.0, 24.0)]
]
isVertical:NO]],
defaultHighlightedBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[_CPCibCustomResource imageResourceWithName:"default-button-bezel-highlighted-left.png" size:CGSizeMake(4.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"default-button-bezel-highlighted-center.png" size:CGSizeMake(1.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"default-button-bezel-highlighted-right.png" size:CGSizeMake(4.0, 24.0)]
]
isVertical:NO]];
[button setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font" inState:CPThemeStateBordered];
[button setValue:[CPColor colorWithCalibratedWhite:79.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-color"];
[button setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateBordered];
[button setValue:CGSizeMake(0.0, 1.0) forThemeAttribute:@"text-shadow-offset" inState:CPThemeStateBordered];
[button setValue:CPLineBreakByTruncatingTail forThemeAttribute:@"line-break-mode"];
[button setValue:bezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[button setValue:highlightedBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateHighlighted];
[button setValue:CGInsetMake(0.0, 5.0, 0.0, 5.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered];
[button setValue:defaultBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateDefault];
[button setValue:defaultHighlightedBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateHighlighted|CPThemeStateDefault];
[button setValue:[CPColor colorWithCalibratedRed:13.0/255.0 green:51.0/255.0 blue:70.0/255.0 alpha:1.0] forThemeAttribute:@"text-color" inState:CPThemeStateDefault];
[button setValue:CGSizeMake(0.0, 24.0) forThemeAttribute:@"min-size"];
[button setValue:CGSizeMake(-1.0, 24.0) forThemeAttribute:@"max-size"];
return button;
}
+ (CPButton)themedStandardButton
{
var button = [self button];
[button setTitle:@"Cancel"];
return button;
}
+ (CPButton)themedDefaultButton
{
var button = [self button];
[button setTitle:@"OK"];
[button setDefaultButton:YES];
return button;
}
+ (CPPopUpButton)themedPopUpButton
{
var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 24.0) pullsDown:NO],
color = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[_CPCibCustomResource imageResourceWithName:"button-bezel-left.png" size:CGSizeMake(4.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"button-bezel-center.png" size:CGSizeMake(1.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"popup-bezel-right.png" size:CGSizeMake(27.0, 24.0)]
]
isVertical:NO]];
[button setTitle:@"Pop Up"];
[button setValue:color forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[button setValue:CGInsetMake(0, 27.0 + 5.0, 0, 5.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered];
[button setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font"];
[button setValue:[CPColor colorWithCalibratedWhite:79.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-color"];
[button setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-shadow-color"];
[button setValue:CGSizeMake(0.0, 1.0) forThemeAttribute:@"text-shadow-offset"];
[button setValue:CGSizeMake(32.0, 24.0) forThemeAttribute:@"min-size"];
[button setValue:CGSizeMake(-1.0, 24.0) forThemeAttribute:@"max-size"];
[button addItemWithTitle:@"item"];
return button;
}
+ (CPPopUpButton)themedPullDownMenu
{
var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 24.0) pullsDown:YES],
color = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[_CPCibCustomResource imageResourceWithName:"button-bezel-left.png" size:CGSizeMake(4.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"button-bezel-center.png" size:CGSizeMake(1.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"popup-bezel-right-pullsdown.png" size:CGSizeMake(27.0, 24.0)]
]
isVertical:NO]];
[button setTitle:@"Pull Down"];
[button setValue:color forThemeAttribute:@"bezel-color" inState:CPPopUpButtonStatePullsDown|CPThemeStateBordered];
[button setValue:CGInsetMake(0, 27.0 + 5.0, 0, 5.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered];
[button setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font"];
[button setValue:[CPColor colorWithCalibratedWhite:79.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-color"];
[button setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-shadow-color"];
[button setValue:CGSizeMake(0.0, 1.0) forThemeAttribute:@"text-shadow-offset"];
[button setValue:CGSizeMake(32.0, 24.0) forThemeAttribute:@"min-size"];
[button setValue:CGSizeMake(-1.0, 24.0) forThemeAttribute:@"max-size"];
[button addItemWithTitle:@"item"];
return button;
}
+ (CPScroller)themedVerticalScroller
{
var scroller = [[CPScroller alloc] initWithFrame:CGRectMake(0.0, 0.0, 17.0, 170.0)],
@@ -69,11 +200,11 @@
{
var scroller = [[CPScroller alloc] initWithFrame:CGRectMake(0.0, 0.0, 170.0, 17.0)],
trackColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-horizontal-track.png" size:CGSizeMake(1.0, 17.0)]),
disabledTrackColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-vertical-track-disabled.png" size:CGSizeMake(17.0, 1.0)]);
disabledTrackColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-horizontal-track-disabled.png" size:CGSizeMake(17.0, 1.0)]);
[scroller setValue:19.0 forThemeAttribute:@"minimum-knob-length"];
[scroller setValue:CGInsetMake(2.0, 0.0, 0.0, 0.0) forThemeAttribute:@"knob-inset"];
[scroller setValue:CGInsetMake(0.0, -9.0, 0.0, -11.0) forThemeAttribute:@"track-inset"];
[scroller setValue:CGInsetMake(0.0, -10.0, 0.0, -11.0) forThemeAttribute:@"track-inset"];
[scroller setValue:trackColor forThemeAttribute:@"knob-slot-color"];
[scroller setValue:disabledTrackColor forThemeAttribute:@"knob-slot-color" inState:CPThemeStateDisabled];
@@ -200,65 +331,6 @@
return textfield;
}
+ (CPButton)themedButton
{
var button = [[CPButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 60.0, 24.0)],
bezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[_CPCibCustomResource imageResourceWithName:"button-bezel-left.png" size:CGSizeMake(4.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"button-bezel-center.png" size:CGSizeMake(1.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"button-bezel-right.png" size:CGSizeMake(4.0, 24.0)]
]
isVertical:NO]],
highlightedBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[_CPCibCustomResource imageResourceWithName:"button-bezel-highlighted-left.png" size:CGSizeMake(4.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"button-bezel-highlighted-center.png" size:CGSizeMake(1.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"button-bezel-highlighted-right.png" size:CGSizeMake(4.0, 24.0)]
]
isVertical:NO]],
defaultBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[_CPCibCustomResource imageResourceWithName:"default-button-bezel-left.png" size:CGSizeMake(4.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"default-button-bezel-center.png" size:CGSizeMake(1.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"default-button-bezel-right.png" size:CGSizeMake(4.0, 24.0)]
]
isVertical:NO]],
defaultHighlightedBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[_CPCibCustomResource imageResourceWithName:"default-button-bezel-highlighted-left.png" size:CGSizeMake(4.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"default-button-bezel-highlighted-center.png" size:CGSizeMake(1.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"default-button-bezel-highlighted-right.png" size:CGSizeMake(4.0, 24.0)]
]
isVertical:NO]];
[button setTitle:@"Cancel"];
[button setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font" inState:CPThemeStateBordered];
[button setValue:[CPColor colorWithCalibratedWhite:79.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-color"];
[button setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateBordered];
[button setValue:CGSizeMake(0.0, 1.0) forThemeAttribute:@"text-shadow-offset" inState:CPThemeStateBordered];
[button setValue:CPLineBreakByTruncatingTail forThemeAttribute:@"line-break-mode"];
[button setValue:bezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[button setValue:highlightedBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateHighlighted];
[button setValue:CGInsetMake(0.0, 5.0, 0.0, 5.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered];
[button setValue:defaultBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateDefault];
[button setValue:defaultHighlightedBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateHighlighted|CPThemeStateDefault];
[button setValue:[CPColor colorWithCalibratedRed:13.0/255.0 green:51.0/255.0 blue:70.0/255.0 alpha:1.0] forThemeAttribute:@"text-color" inState:CPThemeStateDefault];
[button setValue:CGSizeMake(0.0, 24.0) forThemeAttribute:@"min-size"];
[button setValue:CGSizeMake(-1.0, 24.0) forThemeAttribute:@"max-size"];
return button;
}
+ (CPRadioButton)themedRadioButton
{
var button = [[CPRadio alloc] initWithFrame:CGRectMake(0.0, 0.0, 120.0, 17.0)];
@@ -315,56 +387,6 @@
return button;
}
+ (CPPopUpButton)themedPopUpButton
{
var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 24.0) pullsDown:NO],
color = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[_CPCibCustomResource imageResourceWithName:"button-bezel-left.png" size:CGSizeMake(4.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"button-bezel-center.png" size:CGSizeMake(1.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"popup-bezel-right.png" size:CGSizeMake(27.0, 24.0)]
]
isVertical:NO]];
[button setTitle:@"Pop Up"];
[button setValue:color forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[button setValue:CGInsetMake(0, 27.0 + 5.0, 0, 5.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered];
[button setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font"];
[button setValue:[CPColor colorWithCalibratedWhite:79.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-color"];
[button setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-shadow-color"];
[button setValue:CGSizeMake(0.0, 1.0) forThemeAttribute:@"text-shadow-offset"];
[button addItemWithTitle:@"item"];
return button;
}
+ (CPPopUpButton)themedPullDownMenu
{
var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 24.0) pullsDown:YES],
color = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[_CPCibCustomResource imageResourceWithName:"button-bezel-left.png" size:CGSizeMake(4.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"button-bezel-center.png" size:CGSizeMake(1.0, 24.0)],
[_CPCibCustomResource imageResourceWithName:"popup-bezel-right-pullsdown.png" size:CGSizeMake(27.0, 24.0)]
]
isVertical:NO]];
[button setTitle:@"Pop Up"];
[button setValue:color forThemeAttribute:@"bezel-color" inState:CPPopUpButtonStatePullsDown|CPThemeStateBordered];
[button setValue:CGInsetMake(0, 27.0 + 5.0, 0, 5.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered];
[button setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font"];
[button setValue:[CPColor colorWithCalibratedWhite:79.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-color"];
[button setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-shadow-color"];
[button setValue:CGSizeMake(0.0, 1.0) forThemeAttribute:@"text-shadow-offset"];
[button addItemWithTitle:@"item"];
return button;
}
+ (CPPopUpButton)themedSegmentedControl
{
var segmentedControl = [[CPSegmentedControl alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 24.0)];
@@ -494,12 +516,12 @@
+ (CPSlider)themedCircularSlider
{
var slider = [[CPSlider alloc] initWithFrame:CGRectMake(0.0, 0.0, 34.0, 34.0)],
trackColor = PatternColor([_CPCibCustomResource imageResourceWithName:"circularSliderBezel.png" size:CGSizeMake(34.0, 34.0)]);
trackColor = PatternColor([_CPCibCustomResource imageResourceWithName:"slider-circular-bezel.png" size:CGSizeMake(34.0, 34.0)]);
[slider setSliderType:CPCircularSlider];
[slider setValue:trackColor forThemeAttribute:@"track-color" inState:CPThemeStateCircular];
var knobColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"circularSliderKnob.png" size:CGSizeMake(5.0, 5.0)]],
var knobColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"slider-circular-knob.png" size:CGSizeMake(5.0, 5.0)]],
knobHighlightedColor = knobColor;
[slider setValue:CGSizeMake(5.0, 5.0) forThemeAttribute:@"knob-size" inState:CPThemeStateCircular];
@@ -527,7 +549,7 @@
@end
@implementation AristoHUDThemeDescriptor : CPObject
@implementation AristoHUDThemeDescriptor : BKThemeDescriptor
{
}
@@ -536,7 +558,7 @@
return @"Aristo-HUD";
}
+ (CPColor)themeShowcaseBackgroundColor
+ (CPColor)defaultShowcaseBackgroundColor
{
return [CPColor blackColor];
}
+47 -13
View File
@@ -4,17 +4,16 @@
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns = "http://www.w3.org/1999/xhtml" xml:lang = "en" lang = "en">
<!--
//
// index-debug.html
// A
//
// Created by __Me__ on __Date__.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
index-debug.html
Aristo
Created by Francisco Tolmasky on May 23, 2009.
Copyright 2009, 280 North, Inc. All rights reserved.
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<title>Hello World</title>
<title>Aristo</title>
<script type = "text/javascript">
OBJJ_MAIN_FILE = "main.j";
@@ -23,14 +22,49 @@
<script src = "Frameworks/Debug/Objective-J/Objective-J.js" type = "text/javascript"></script>
<style type = "text/css">
body{margin:0; padding:0;}
#container {position: absolute; top:50%; left:50%;}
#content {width:800px; text-align:center; margin-left: -400px; height:50px; margin-top:-25px; line-height: 50px;}
#content {font-family: "Helvetica", "Arial", sans-serif; font-size: 18px; color: black; text-shadow: 0px 1px 0px white; }
#loadgraphic {margin-right: 0.2em; margin-bottom:-2px;}
</style>
<!--[if lt IE 7]>
<STYLE type="text/css">
#container { position: relative; top: 50%; }
#content { position: relative;}
</STYLE>
<![endif]-->
</head>
<body>
<div style="position: absolute; left: 50%; top: 50%;">
<center>
<img src = "Frameworks/AppKit/Resources/CPProgressIndicator/CPProgressIndicatorSpinningStyleRegular.gif" style="left: -32px; position: relative; top: -32px;" />
</center>
<body style="">
<div id="loadingcontainer" style=" background-color: #eeeeee; overflow:hidden; width:100%; height:100%; position: absolute; top: 0; left: 0;">
<script type = "text/javascript">
document.write("<div id='container'><p id='content'>" +
"<img id='loadgraphic' width='16' height='16' src='Resources/spinner.gif' /> " +
"Loading Aristo...</p></div>");
</script>
<noscript>
<div id="container">
<div style="width: 440px; padding: 10px 25px 20px 25px; font-family: sans-serif; background-color: #ffffff; position: relative; left: -245px; top: -120px; text-align: center; -moz-border-radius: 20px; -webkit-border-radius: 20px; color: #555555">
<p style="line-height: 1.4em;">JavaScript is required for this site to work correctly but is either disabled or not supported by your browser.</p>
<p style="font-size:120%; padding:10px;"><a href="http://cappuccino.org/noscript">Show me how to enable JavaScript</a></p>
<p style="font-size:80%;">You may want to upgrade to a newer browser while you're at it:</p>
<ul style="margin:0;padding:0; text-align: center; font-size:80%;" >
<li style="display: inline;"><a href="http://www.apple.com/safari/download/">Safari</a></li>
<li style="display: inline;"><a href="http://www.mozilla.com/en-US/firefox/">Firefox</a></li>
<li style="display: inline;"><a href="http://www.google.com/chrome/">Chrome</a></li>
<li style="display: inline;"><a href="http://www.opera.com/download/">Opera</a></li>
<li style="display: inline;"><a href="http://www.microsoft.com/windows/downloads/ie/getitnow.mspx">Internet Explorer</a></li>
</ul>
</div>
</div>
</noscript>
</div>
</body>
</html>
+46 -15
View File
@@ -4,17 +4,16 @@
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns = "http://www.w3.org/1999/xhtml" xml:lang = "en" lang = "en">
<!--
//
// index.html
// A
//
// Created by __Me__ on __Date__.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
index.html
Aristo
Created by Francisco Tolmasky on May 23, 2009.
Copyright 2009, 280 North, Inc. All rights reserved.
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<title>Hello World</title>
<title>Aristo</title>
<script type = "text/javascript">
OBJJ_MAIN_FILE = "main.j";
@@ -22,16 +21,48 @@
<script src = "Frameworks/Objective-J/Objective-J.js" type = "text/javascript"></script>
<style type = "text/css">
body{margin:0; padding:0;}
#container {position: absolute; top:50%; left:50%;}
#content {width:800px; text-align:center; margin-left: -400px; height:50px; margin-top:-25px; line-height: 50px;}
#content {font-family: "Helvetica", "Arial", sans-serif; font-size: 18px; color: black; text-shadow: 0px 1px 0px white; }
#loadgraphic {margin-right: 0.2em; margin-bottom:-2px;}
</style>
<!--[if lt IE 7]>
<STYLE type="text/css">
#container { position: relative; top: 50%; }
#content { position: relative;}
</STYLE>
<![endif]-->
</head>
<body>
<div style="position: absolute; left: 50%; top: 50%;">
<center>
<img src = "Frameworks/AppKit/Resources/CPProgressIndicator/CPProgressIndicatorSpinningStyleRegular.gif" style="left: -32px; position: relative; top: -32px;" />
</center>
<body style="">
<div id="loadingcontainer" style=" background-color: #eeeeee; overflow:hidden; width:100%; height:100%; position: absolute; top: 0; left: 0;">
<script type = "text/javascript">
document.write("<div id='container'><p id='content'>" +
"<img id='loadgraphic' width='16' height='16' src='Resources/spinner.gif' /> " +
"Loading Aristo...</p></div>");
</script>
<noscript>
<div id="container">
<div style="width: 440px; padding: 10px 25px 20px 25px; font-family: sans-serif; background-color: #ffffff; position: relative; left: -245px; top: -120px; text-align: center; -moz-border-radius: 20px; -webkit-border-radius: 20px; color: #555555">
<p style="line-height: 1.4em;">JavaScript is required for this site to work correctly but is either disabled or not supported by your browser.</p>
<p style="font-size:120%; padding:10px;"><a href="http://cappuccino.org/noscript">Show me how to enable JavaScript</a></p>
<p style="font-size:80%;">You may want to upgrade to a newer browser while you're at it:</p>
<ul style="margin:0;padding:0; text-align: center; font-size:80%;" >
<li style="display: inline;"><a href="http://www.apple.com/safari/download/">Safari</a></li>
<li style="display: inline;"><a href="http://www.mozilla.com/en-US/firefox/">Firefox</a></li>
<li style="display: inline;"><a href="http://www.google.com/chrome/">Chrome</a></li>
<li style="display: inline;"><a href="http://www.opera.com/download/">Opera</a></li>
<li style="display: inline;"><a href="http://www.microsoft.com/windows/downloads/ie/getitnow.mspx">Internet Explorer</a></li>
</ul>
</div>
</div>
</noscript>
</div>
</body>
</html>
</html>
+362 -88
View File
@@ -1,112 +1,404 @@
/*
* BKShowcaseController.j
* BlendKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* 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 <AppKit/CPTheme.j>
@import <AppKit/CPView.j>
@import "BKUtilities.j"
var LEFT_PANEL_WIDTH = 176.0;
var BKLearnMoreToolbarItemIdentifier = @"BKLearnMoreToolbarItemIdentifier",
BKStateToolbarItemIdentifier = @"BKStateToolbarItemIdentifier",
BKBackgroundColorToolbarItemIdentifier = @"BKBackgroundColorToolbarItemIdentifier";
@implementation BKShowcaseController : CPObject
{
CPArray _themeDescriptorClasses;
CPCollectionView _themesCollectionView;
CPCollectionView _themedObjectsCollectionView;
}
- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
_themeDescriptorClasses = [BKThemeDescriptor allThemeDescriptorClasses];
var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask],
contentView = [theWindow contentView],
toolbar = [[CPToolbar alloc] initWithIdentifier:@"Toolbar"];
[toolbar setDelegate:self];
[theWindow setToolbar:toolbar];
var contentView = [theWindow contentView],
bounds = [contentView bounds],
themeDescriptorClasses = BKThemeDescriptorClasses();
var tabView = [[CPTabView alloc] initWithFrame:bounds];
[tabView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[contentView addSubview:tabView];
var index = 0,
count = [themeDescriptorClasses count];
for (; index < count; ++index)
splitView = [[CPSplitView alloc] initWithFrame:bounds];
[splitView setIsPaneSplitter:YES];
[splitView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[contentView addSubview:splitView];
// Left Pane
var label = [CPTextField labelWithTitle:@"THEMES"];
[label setFont:[CPFont boldSystemFontOfSize:11.0]];
[label setTextColor:[CPColor colorWithCalibratedRed:92.0 / 255.0 green:110.0 / 255.0 blue:129.0 / 255.0 alpha:1.0]];
[label setTextShadowColor:[CPColor colorWithCalibratedRed:225.0 / 255.0 green:255.0 / 255.0 blue:255.0 / 255.0 alpha:0.7]];
[label setTextShadowOffset:CGSizeMake(0.0, 1.0)];
[label sizeToFit];
[label setFrameOrigin:CGPointMake(5.0, 2.0)];
var themeDescriptorItem = [[CPCollectionViewItem alloc] init];
[themeDescriptorItem setView:[[BKThemeDescriptorCell alloc] init]];
_themesCollectionView = [[CPCollectionView alloc] initWithFrame:CGRectMake(0.0, 0.0, LEFT_PANEL_WIDTH, CGRectGetHeight(bounds))];
[_themesCollectionView setDelegate:self];
[_themesCollectionView setItemPrototype:themeDescriptorItem];
[_themesCollectionView setMinItemSize:CGSizeMake(20.0, 36.0)];
[_themesCollectionView setMaxItemSize:CGSizeMake(10000000.0, 36.0)];
[_themesCollectionView setMaxNumberOfColumns:1];
[_themesCollectionView setContent:_themeDescriptorClasses];
[_themesCollectionView setAutoresizingMask:CPViewWidthSizable];
[_themesCollectionView setVerticalMargin:0.0];
[_themesCollectionView setSelectable:YES];
[_themesCollectionView setFrameOrigin:CGPointMake(0.0, 20.0)];
[_themesCollectionView setAutoresizingMask:CPViewWidthSizable];
var scrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, LEFT_PANEL_WIDTH, CGRectGetHeight(bounds))],
contentView = [scrollView contentView];
[scrollView setAutohidesScrollers:YES];
[scrollView setDocumentView:_themesCollectionView];
[contentView setBackgroundColor:[CPColor colorWithRed:212.0 / 255.0 green:221.0 / 255.0 blue:230.0 / 255.0 alpha:1.0]];
[contentView addSubview:label];
[splitView addSubview:scrollView];
// Right Pane
_themedObjectsCollectionView = [[CPCollectionView alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(bounds) - LEFT_PANEL_WIDTH - 1.0, 10.0)];
var collectionViewItem = [[CPCollectionViewItem alloc] init];
[collectionViewItem setView:[[BKShowcaseCell alloc] init]];
[_themedObjectsCollectionView setItemPrototype:collectionViewItem];
[_themedObjectsCollectionView setVerticalMargin:20.0];
[_themedObjectsCollectionView setAutoresizingMask:CPViewWidthSizable];
var scrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(LEFT_PANEL_WIDTH + 1.0, 0.0, CGRectGetWidth(bounds) - LEFT_PANEL_WIDTH - 1.0, CGRectGetHeight(bounds))];
[scrollView setHasHorizontalScroller:NO];
[scrollView setAutohidesScrollers:YES];
[scrollView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[scrollView setDocumentView:_themedObjectsCollectionView];
[splitView addSubview:scrollView];
[_themesCollectionView setSelectionIndexes:[CPIndexSet indexSetWithIndex:0]];
[theWindow setFullBridge:YES];
[theWindow makeKeyAndOrderFront:self];
}
- (void)collectionViewDidChangeSelection:(CPCollectionView)aCollectionView
{
var themeDescriptorClass = _themeDescriptorClasses[[[aCollectionView selectionIndexes] firstIndex]],
itemSize = [themeDescriptorClass itemSize];
// Make room for label and apply a minimum size.
itemSize.width = MAX(100.0, itemSize.width + 20.0);
itemSize.height = MAX(100.0, itemSize.height + 30.0);
[_themedObjectsCollectionView setMinItemSize:itemSize];
[_themedObjectsCollectionView setMaxItemSize:itemSize];
[_themedObjectsCollectionView setContent:[themeDescriptorClass themedObjectTemplates]];
[BKShowcaseCell setBackgroundColor:[themeDescriptorClass showcaseBackgroundColor]];
}
- (BOOL)hasLearnMoreURL
{
return [[CPBundle mainBundle] objectForInfoDictionaryKey:@"BKLearnMoreURL"];
}
- (CPArray)toolbarAllowedItemIdentifiers:(CPToolbar)aToolbar
{
return [BKLearnMoreToolbarItemIdentifier, CPToolbarSpaceItemIdentifier, CPToolbarFlexibleSpaceItemIdentifier, BKBackgroundColorToolbarItemIdentifier, BKStateToolbarItemIdentifier];
}
- (CPArray)toolbarDefaultItemIdentifiers:(CPToolbar)aToolbar
{
var itemIdentifiers = [CPToolbarFlexibleSpaceItemIdentifier, BKBackgroundColorToolbarItemIdentifier, BKStateToolbarItemIdentifier];
if ([self hasLearnMoreURL])
itemIdentifiers = [BKLearnMoreToolbarItemIdentifier].concat(itemIdentifiers);
return itemIdentifiers;
}
- (CPToolbarItem)toolbar:(CPToolbar)aToolbar itemForItemIdentifier:(CPString)anItemIdentifier willBeInsertedIntoToolbar:(BOOL)aFlag
{
var toolbarItem = [[CPToolbarItem alloc] initWithItemIdentifier:anItemIdentifier];
[toolbarItem setTarget:self];
if (anItemIdentifier === BKStateToolbarItemIdentifier)
{
var theClass = themeDescriptorClasses[index],
item = [[CPTabViewItem alloc] initWithIdentifier:[theClass themeName]],
templates = BKThemeObjectTemplatesForClass(theClass),
templatesCount = [templates count],
viewTemplates = [],
itemSize = CGSizeMake(0.0, 0.0);
while (templatesCount--)
{
var template = templates[templatesCount],
object = [template valueForKey:@"themedObject"];
var popUpButton = [CPPopUpButton buttonWithTitle:@"Enabled"];
if ([object isKindOfClass:[CPView class]])
{
var size = [object frame].size,
labelWidth = [[template valueForKey:@"label"] sizeWithFont:[CPFont boldSystemFontOfSize:12.0]].width + 20.0;
[popUpButton addItemWithTitle:@"Disabled"];
if (size.width > itemSize.width)
itemSize.width = size.width;
if (labelWidth > itemSize.width)
itemSize.width = labelWidth;
if (size.height > itemSize.height)
itemSize.height = size.height;
[viewTemplates addObject:template];
}
}
itemSize.width += 20.0;
itemSize.height += 30.0;
[toolbarItem setView:popUpButton];
[toolbarItem setTarget:nil];
[toolbarItem setAction:@selector(changeState:)];
[toolbarItem setLabel:@"State"];
var collectionView = [[CPCollectionView alloc] initWithFrame:CGRectMakeZero()],
collectionViewItem = [[CPCollectionViewItem alloc] init];
var width = CGRectGetWidth([popUpButton frame]);
var backgroundColor = nil;
[toolbarItem setMinSize:CGSizeMake(width + 20.0, 32.0)];
[toolbarItem setMaxSize:CGSizeMake(width + 20.0, 32.0)];
}
else if (anItemIdentifier === BKBackgroundColorToolbarItemIdentifier)
{
var popUpButton = [CPPopUpButton buttonWithTitle:@"Window Background"];
if ([theClass respondsToSelector:@selector(themeShowcaseBackgroundColor)])
backgroundColor = [theClass themeShowcaseBackgroundColor];
[popUpButton addItemWithTitle:@"Light Checkers"];
[popUpButton addItemWithTitle:@"Dark Checkers"];
[popUpButton addItemWithTitle:@"White"];
[popUpButton addItemWithTitle:@"Black"];
[popUpButton addItemWithTitle:@"More Choices..."];
[collectionViewItem setView:[[BKShowcaseCell alloc] initWithShowcaseBackgroundColor:backgroundColor]];
var itemArray = [popUpButton itemArray];
[collectionView setItemPrototype:collectionViewItem];
[collectionView setMinItemSize:itemSize];
[collectionView setMaxItemSize:itemSize];
[collectionView setVerticalMargin:5.0];
[collectionView setContent:viewTemplates];
[item setLabel:[theClass themeName]];
[item setView:collectionView];
[itemArray[0] setRepresentedObject:[BKThemeDescriptor windowBackgroundColor]];
[itemArray[1] setRepresentedObject:[BKThemeDescriptor lightCheckersColor]];
[itemArray[2] setRepresentedObject:[BKThemeDescriptor darkCheckersColor]];
[itemArray[3] setRepresentedObject:[CPColor whiteColor]];
[itemArray[4] setRepresentedObject:[CPColor blackColor]];
[tabView addTabViewItem:item];
[toolbarItem setView:popUpButton];
[toolbarItem setTarget:nil];
[toolbarItem setAction:@selector(changeColor:)];
[toolbarItem setLabel:@"Background Color"];
var width = CGRectGetWidth([popUpButton frame]);
[toolbarItem setMinSize:CGSizeMake(width, 32.0)];
[toolbarItem setMaxSize:CGSizeMake(width, 32.0)];
}
else if (anItemIdentifier === BKLearnMoreToolbarItemIdentifier)
{
var title = [[CPBundle mainBundle] objectForInfoDictionaryKey:@"BKLearnMoreButtonTitle"];
if (!title)
title = [[CPBundle mainBundle] objectForInfoDictionaryKey:@"CPBundleName"] || @"Home Page";
var button = [CPButton buttonWithTitle:title];
[button setDefaultButton:YES];
[toolbarItem setView:button];
[toolbarItem setLabel:@"Learn More"];
[toolbarItem setTarget:nil];
[toolbarItem setAction:@selector(learnMore:)];
var width = CGRectGetWidth([button frame]);
[toolbarItem setMinSize:CGSizeMake(width, 32.0)];
[toolbarItem setMaxSize:CGSizeMake(width, 32.0)];
}
[theWindow orderFront:self];
return toolbarItem;
}
- (void)learnMore:(id)aSender
{
window.location.href = [[CPBundle mainBundle] objectForInfoDictionaryKey:@"BKLearnMoreURL"];
}
- (BKThemeDescriptor)selectedThemeDescriptor
{
return _themeDescriptorClasses[[[_themesCollectionView selectionIndexes] firstIndex]];
}
- (void)changeState:(id)aSender
{
var themedObjectTemplates = [[self selectedThemeDescriptor] themedObjectTemplates],
count = [themedObjectTemplates count];
while (count--)
{
var themedObject = [themedObjectTemplates[count] valueForKey:@"themedObject"];
if ([themedObject respondsToSelector:@selector(setEnabled:)])
[themedObject setEnabled:[aSender title] === @"Enabled" ? YES : NO];
}
}
- (void)changeColor:(id)aSender
{
var color = nil;
if ([aSender isKindOfClass:[CPColorPanel class]])
color = [aSender color];
else
{
if ([aSender titleOfSelectedItem] === @"More Choices...")
{
[aSender addItemWithTitle:@"Other"];
[aSender selectItemWithTitle:@"Other"];
[CPApp orderFrontColorPanel:self];
}
else
{
color = [[aSender selectedItem] representedObject];
[aSender removeItemWithTitle:@"Other"];
}
}
if (color)
{
[[self selectedThemeDescriptor] setShowcaseBackgroundColor:color];
[BKShowcaseCell setBackgroundColor:color];
}
}
@end
var SelectionColor = nil;
@implementation BKThemeDescriptorCell : CPView
{
CPTextField _label;
}
+ (CPImage)selectionColor
{
if (!SelectionColor)
SelectionColor = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[BKThemeDescriptorCell class]] pathForResource:@"selection.png"] size:CGSizeMake(1.0, 36.0)]];
return SelectionColor;
}
- (void)setRepresentedObject:(id)aThemeDescriptor
{
if (!_label)
{
_label = [CPTextField labelWithTitle:@"hello"];
[_label setFont:[CPFont systemFontOfSize:11.0]];
[_label setFrame:CGRectMake(10.0, 0.0, CGRectGetWidth([self bounds]) - 20.0, CGRectGetHeight([self bounds]))];
[_label setVerticalAlignment:CPCenterVerticalTextAlignment];
[_label setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[self addSubview:_label];
}
[_label setStringValue:[aThemeDescriptor themeName] + " (" + [[aThemeDescriptor themedObjectTemplates] count] + ")"];
}
- (void)setSelected:(BOOL)isSelected
{
[self setBackgroundColor:isSelected ? [[self class] selectionColor] : nil];
[_label setTextShadowOffset:isSelected ? CGSizeMake(0.0, 1.0) : CGSizeMakeZero()];
[_label setTextShadowColor:isSelected ? [CPColor blackColor] : nil];
[_label setFont:isSelected ? [CPFont boldSystemFontOfSize:11.0] : [CPFont systemFontOfSize:11.0]];
[_label setTextColor:isSelected ? [CPColor whiteColor] : [CPColor blackColor]];
}
@end
var ShowcaseCellBackgroundColor = nil;
var BKShowcaseCellBackgroundColorDidChangeNotification = @"BKShowcaseCellBackgroundColorDidChangeNotification";
@implementation BKShowcaseCell : CPView
{
CPColor _showcaseBackgroundColor;
CPView _backgroundView;
CPView _view;
CPTextField _label;
}
- (id)initWithShowcaseBackgroundColor:(CPColor)aColor
+ (void)setBackgroundColor:(CPColor)aColor
{
if (ShowcaseCellBackgroundColor === aColor)
return;
ShowcaseCellBackgroundColor = aColor;
[[CPNotificationCenter defaultCenter]
postNotificationName:BKShowcaseCellBackgroundColorDidChangeNotification
object:nil];
}
+ (CPColor)backgroundColor
{
return ShowcaseCellBackgroundColor;
}
- (id)init
{
self = [super init];
if (self)
_showcaseBackgroundColor = aColor;
[[CPNotificationCenter defaultCenter]
addObserver:self
selector:@selector(showcaseBackgroundDidChange:)
name:BKShowcaseCellBackgroundColorDidChangeNotification
object:nil];
return self;
}
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
if (self)
[[CPNotificationCenter defaultCenter]
addObserver:self
selector:@selector(showcaseBackgroundDidChange:)
name:BKShowcaseCellBackgroundColorDidChangeNotification
object:nil];
return self;
}
- (void)showcaseBackgroundDidChange:(CPNotification)aNotification
{
[_backgroundView setBackgroundColor:[BKShowcaseCell backgroundColor]];
}
- (void)setSelected:(BOOL)isSelected
{
}
@@ -116,26 +408,24 @@
if (!_label)
{
_label = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
[_label setAlignment:CPCenterTextAlignment];
[_label setAutoresizingMask:CPViewMinYMargin | CPViewWidthSizable];
[_label setFont:[CPFont boldSystemFontOfSize:12.0]];
[_label setFont:[CPFont boldSystemFontOfSize:11.0]];
[self addSubview:_label];
}
[_label setStringValue:[anObject valueForKey:@"label"]];
[_label sizeToFit];
[_label setFrame:CGRectMake(0.0, CGRectGetHeight([self bounds]) - CGRectGetHeight([_label frame]),
CGRectGetWidth([self bounds]), CGRectGetHeight([_label frame]))];
if (!_backgroundView)
{
_backgroundView = [[CPView alloc] init];
[_backgroundView setBackgroundColor:_showcaseBackgroundColor];
[self addSubview:_backgroundView];
}
@@ -153,23 +443,7 @@
(CGRectGetHeight([_backgroundView bounds]) - CGRectGetHeight([_view frame])) / 2.0)];
[_backgroundView addSubview:_view];
}
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
if (self)
_showcaseBackgroundColor = [aCoder decodeObjectForKey:@"showcase-background-color"];
return self
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_showcaseBackgroundColor forKey:@"showcase-background-color"];
[_backgroundView setBackgroundColor:[BKShowcaseCell backgroundColor]];
}
@end
+221
View File
@@ -0,0 +1,221 @@
/*
* BKThemeDescriptor.j
* BlendKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* 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 <Foundation/CPObject.j>
var ItemSizes = { },
ThemedObjects = { },
BackgroundColors = { },
LightCheckersColor = nil,
DarkCheckersColor = nil,
WindowBackgroundColor = nil;
@implementation BKThemeDescriptor : CPObject
{
}
+ (CPArray)allThemeDescriptorClasses
{
// Grab Theme Descriptor Classes.
var themeDescriptorClasses = [];
for (candidate in window)
{
var theClass = objj_getClass(candidate),
theClassName = class_getName(theClass);
if (theClassName === "BKThemeDescriptor")
continue;
var index = theClassName.indexOf("ThemeDescriptor");
if ((index >= 0) && (index === theClassName.length - "ThemeDescriptor".length))
themeDescriptorClasses.push(theClass);
}
[themeDescriptorClasses sortUsingSelector:@selector(compare:)];
return themeDescriptorClasses;
}
+ (CPColor)lightCheckersColor
{
if (!LightCheckersColor)
LightCheckersColor = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[BKThemeDescriptor class]] pathForResource:@"light-checkers.png"] size:CGSizeMake(12.0, 12.0)]];
return LightCheckersColor;
}
+ (CPColor)darkCheckersColor
{
if (!DarkCheckersColor)
DarkCheckersColor = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[BKThemeDescriptor class]] pathForResource:@"dark-checkers.png"] size:CGSizeMake(12.0, 12.0)]];
return DarkCheckersColor;
}
+ (CPColor)windowBackgroundColor
{
return [_CPStandardWindowView bodyBackgroundColor];
}
+ (CPColor)defaultShowcaseBackgroundColor
{
return [_CPStandardWindowView bodyBackgroundColor];//[self lightCheckersColor];
}
+ (CPColor)showcaseBackgroundColor
{
var className = [self className];
if (!BackgroundColors[className])
BackgroundColors[className] = [self defaultShowcaseBackgroundColor];
return BackgroundColors[className];
}
+ (void)setShowcaseBackgroundColor:(CPColor)aColor
{
BackgroundColors[[self className]] = aColor;
}
+ (CGSize)itemSize
{
var className = [self className];
if (!ItemSizes[className])
[self calculateThemedObjectTemplates];
return CGSizeMakeCopy(ItemSizes[className]);
}
+ (CPArray)themedObjectTemplates
{
var className = [self className];
if (!ThemedObjects[className])
[self calculateThemedObjectTemplates];
return ThemedObjects[className];
}
+ (void)calculateThemedObjectTemplates
{
var templates = [],
itemSize = CGSizeMake(0.0, 0.0),
methods = class_copyMethodList([self class].isa),
index = 0,
count = [methods count];
for (; index < count; ++index)
{
var method = methods[index],
selector = method_getName(method);
if (selector.indexOf("themed") !== 0)
continue;
var impl = method_getImplementation(method),
object = impl(self, selector);
if (!object)
continue;
var template = [[BKThemedObjectTemplate alloc] init];
[template setValue:object forKey:@"themedObject"];
[template setValue:BKLabelFromIdentifier(selector) forKey:@"label"];
[templates addObject:template];
if ([object isKindOfClass:[CPView class]])
{
var size = [object frame].size,
labelWidth = [[template valueForKey:@"label"] sizeWithFont:[CPFont boldSystemFontOfSize:12.0]].width + 20.0;
if (size.width > itemSize.width)
itemSize.width = size.width;
if (labelWidth > itemSize.width)
itemSize.width = labelWidth;
if (size.height > itemSize.height)
itemSize.height = size.height;
}
}
var className = [self className];
ItemSizes[className] = itemSize;
ThemedObjects[className] = templates;
}
+ (int)compare:(BKThemeDescriptor)aThemeDescriptor
{
return [[self themeName] compare:[aThemeDescriptor themeName]];
}
@end
function BKLabelFromIdentifier(anIdentifier)
{
var string = anIdentifier.substr("themed".length);
index = 0,
count = string.length,
label = "",
lastCapital = null,
isLeadingCapital = YES;
for (; index < count; ++index)
{
var character = string.charAt(index),
isCapital = /^[A-Z]/.test(character);
if (isCapital)
{
if (!isLeadingCapital)
{
if (lastCapital === null)
label += ' ' + character.toLowerCase();
else
label += character;
}
lastCapital = character;
}
else
{
if (isLeadingCapital && lastCapital !== null)
label += lastCapital;
label += character;
lastCapital = null;
isLeadingCapital = NO;
}
}
return label;
}
+51
View File
@@ -0,0 +1,51 @@
/*
* BKThemeTemplate.j
* BlendKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* 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 <Foundation/CPObject.j>
@implementation BKThemeTemplate : CPObject
{
CPString _name;
CPString _description;
}
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
_name = [aCoder decodeObjectForKey:@"BKThemeTemplateName"];
_description = [aCoder decodeObjectForKey:@"BKThemeTemplateDescription"];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_name forKey:@"BKThemeTemplateName"];
[aCoder encodeObject:_description forKey:@"BKThemeTemplateDescription"];
}
@end
@@ -0,0 +1,51 @@
/*
* BKThemedObjectTemplate.j
* BlendKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* 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 <AppKit/CPView.j>
@implementation BKThemedObjectTemplate : CPView
{
CPString _label;
id _themedObject;
}
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
_label = [aCoder decodeObjectForKey:@"BKThemedObjectTemplateLabel"];
_themedObject = [aCoder decodeObjectForKey:@"BKThemedObjectTemplateThemedObject"];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_label forKey:@"BKThemedObjectTemplateLabel"];
[aCoder encodeObject:_themedObject forKey:@"BKThemedObjectTemplateThemedObject"];
}
@end
-145
View File
@@ -1,145 +0,0 @@
@implementation BKThemeTemplate : CPObject
{
CPString _name;
CPString _description;
}
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
_name = [aCoder decodeObjectForKey:@"BKThemeTemplateName"];
_description = [aCoder decodeObjectForKey:@"BKThemeTemplateDescription"];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_name forKey:@"BKThemeTemplateName"];
[aCoder encodeObject:_description forKey:@"BKThemeTemplateDescription"];
}
@end
@implementation BKThemeObjectTemplate : CPView
{
CPString _label;
id _themedObject;
}
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
_label = [aCoder decodeObjectForKey:@"BKThemeObjectTemplateLabel"];
_themedObject = [aCoder decodeObjectForKey:@"BKThemeObjectTemplateThemedObject"];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_label forKey:@"BKThemeObjectTemplateLabel"];
[aCoder encodeObject:_themedObject forKey:@"BKThemeObjectTemplateThemedObject"];
}
@end
function BKThemeDescriptorClasses()
{
// Grab Theme Descriptor Classes.
var themeDescriptorClasses = [];
for (candidate in window)
{
var theClass = objj_getClass(candidate),
theClassName = class_getName(theClass),
index = theClassName.indexOf("ThemeDescriptor");
if ((index >= 0) && (index === theClassName.length - "ThemeDescriptor".length))
themeDescriptorClasses.push(theClass);
}
return themeDescriptorClasses;
}
function BKThemeObjectTemplatesForClass(aClass)
{
var templates = [],
methods = class_copyMethodList(aClass.isa),
count = [methods count];
while (count--)
{
var method = methods[count],
selector = method_getName(method);
if (selector.indexOf("themed") === 0)
{
var impl = method_getImplementation(method),
object = impl(aClass, selector);
if (object)
{
var template = [[BKThemeObjectTemplate alloc] init];
[template setValue:object forKey:@"themedObject"];
[template setValue:BKLabelFromIdentifier(selector) forKey:@"label"];
[templates addObject:template];
}
}
}
return templates;
}
function BKLabelFromIdentifier(anIdentifier)
{
var string = anIdentifier.substr("themed".length);
index = 0,
count = string.length,
label = "",
lastCapital = null,
isLeadingCapital = YES;
for (; index < count; ++index)
{
var character = string.charAt(index),
isCapital = /^[A-Z]/.test(character);
if (isCapital)
{
if (!isLeadingCapital)
{
if (lastCapital === null)
label += ' ' + character.toLowerCase();
else
label += character;
}
lastCapital = character;
}
else
{
if (isLeadingCapital && lastCapital !== null)
label += lastCapital;
label += character;
lastCapital = null;
isLeadingCapital = NO;
}
}
return label;
}
+24 -1
View File
@@ -1,3 +1,26 @@
/*
* BlendKit.j
* BlendKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* 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 "BKShowcaseController.j"
@import "BKUtilities.j"
@import "BKThemeDescriptor.j"
@import "BKThemeTemplate.j"
@import "BKThemedObjectTemplate.j"
+1 -1
View File
@@ -12,7 +12,7 @@ $BUILD_PATH = File.join($BUILD_DIR, $CONFIGURATION, 'BlendKit')
ObjectiveJ::BundleTask.new(:BlendKit) do |t|
t.name = 'BlendKit'
t.identifier = 'com.280n.BlendKit'
t.version = '0.7.0'
t.version = '0.7.1'
t.author = '280 North, Inc.'
t.email = 'feedback @nospam@ 280north.com'
t.summary = 'BlendKit classes for Cappuccino'
Binary file not shown.

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

+1 -1
View File
@@ -15,7 +15,7 @@ $ENVIRONMENT_LIB_PRODUCT = File.join($ENVIRONMENT_LIB_DIR, 'blend')
ObjectiveJ::BundleTask.new(:blend) do |t|
t.name = 'blend'
t.identifier = 'com.280n.blend'
t.version = '0.7.0'
t.version = '0.7.1'
t.author = '280 North, Inc.'
t.email = 'feedback @nospam@ 280north.com'
t.summary = 'blend classes for Cappuccino'
+29 -9
View File
@@ -1,8 +1,28 @@
/*
* main.j
* blend
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* 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 <Foundation/Foundation.j>
@import <AppKit/AppKit.j>
@import <AppKit/CPCib.j>
@import <AppKit/CPTheme.j>
@import <BlendKit/BlendKit.j>
var File = require("file");
@@ -53,7 +73,7 @@ function main()
objj_import(descriptorFiles, YES, function()
{
var themeDescriptorClasses = BKThemeDescriptorClasses(),
var themeDescriptorClasses = [BKThemeDescriptor allThemeDescriptorClasses],
count = [themeDescriptorClasses count];
while (count--)
@@ -63,12 +83,12 @@ function main()
[themeTemplate setValue:[theClass themeName] forKey:@"name"];
var objectTemplates = BKThemeObjectTemplatesForClass(theClass),
var objectTemplates = [theClass themedObjectTemplates],
data = cibDataFromTopLevelObjects(objectTemplates.concat([themeTemplate])),
temporaryCibFile = Packages.java.io.File.createTempFile("temp", ".cib"),
temporaryCibFilePath = String(temporaryCibFile.getAbsolutePath());
File.write(temporaryCibFilePath, [data string], { charset:"UTF8" });
File.write(temporaryCibFilePath, [data string], { charset:"UTF-8" });
cibFiles.push(temporaryCibFilePath);
}
@@ -151,8 +171,8 @@ function buildBlendFromCibFiles(cibFiles, outputFilePath, resourcesPath)
outputFile.mkdirs();
File.write(outputFilePath + "/Info.plist", [CPPropertyListCreate280NorthData(infoDictionary) string], { charset:"UTF8" });
File.write(outputFilePath + '/' + staticContentName, staticContent, { charset:"UTF8" });
File.write(outputFilePath + "/Info.plist", [CPPropertyListCreate280NorthData(infoDictionary) string], { charset:"UTF-8" });
File.write(outputFilePath + '/' + staticContentName, staticContent, { charset:"UTF-8" });
if (resourcesPath)
rsync(new Packages.java.io.File(resourcesPath), new Packages.java.io.File(outputFilePath));
@@ -246,7 +266,7 @@ function exec(/*Array*/ command, /*Boolean*/ showOutput)
{
var theClass = [self class];
if ([theClass isKindOfClass:[BKThemeObjectTemplate class]])
if ([theClass isKindOfClass:[BKThemedObjectTemplate class]])
return [self];
if ([theClass isKindOfClass:[CPView class]])
@@ -266,7 +286,7 @@ function exec(/*Array*/ command, /*Boolean*/ showOutput)
@end
@implementation BKThemeObjectTemplate (BlendAdditions)
@implementation BKThemedObjectTemplate (BlendAdditions)
- (void)blendAddThemedObjectAttributesToTheme:(CPTheme)aTheme
{
+1 -1
+13 -20
View File
@@ -255,18 +255,6 @@
return self;
}
/*!
Returns a hash of the CPArray.
@return an unsigned integer hash
*/
- (unsigned)hash
{
if (self.__address == nil)
self.__address = _objj_generateObjectHash();
return self.__address;
}
// Querying an array
/*!
Returns <code>YES</code> if the array contains <code>anObject</code>. Otherwise, it returns <code>NO</code>.
@@ -799,18 +787,23 @@
*/
- (CPString)description
{
var i = 0,
var index = 0,
count = [self count],
description = '(';
for(; i < count; ++i)
for(; index < count; ++index)
{
if (self[i].isa) description += [self[i] description];
else description += self[i];
if (i != count - 1) description += ", ";
var object = self[index];
if (object && object.isa)
description += [object description];
else
description += object;
if (index !== count - 1)
description += ", ";
}
return description + ')';
}
+2 -2
View File
@@ -247,9 +247,9 @@ CPUnknownUserInfoKey = @"CPUnknownUserInfoKey";
self[ivar] = aValue;
[self didChangeValueForKey:aKey];
return;
}
return;
}
[self setValue:aValue forUndefinedKey:aKey];
+7 -6
View File
@@ -424,15 +424,16 @@ var _CPKeyedUnarchiverDecodeObjectAtIndex = function(self, anIndex)
if (!theClass)
theClass = CPClassFromString(className);
object = [theClass alloc];
// It is important to do this before calling initWithCoder so that decoding can be self referential (something = self).
self._objects[anIndex] = object;
var savedPlistObject = self._plistObject;
self._plistObject = plistObject;
var string = className;
// Should we only call this on _CPCibClassSwapper? (currently the only class that makes use of this).
object = [theClass allocWithCoder:self];
// It is important to do this before calling initWithCoder so that decoding can be self referential (something = self).
self._objects[anIndex] = object;
var processedObject = [object initWithCoder:self];
self._plistObject = savedPlistObject;
+1 -1
View File
@@ -186,7 +186,7 @@ var __placeholder = new Number(),
return anUnsignedShort;
}
- (CPString)hash
- (CPString)UID
{
if (!_CPNumberHashes[self])
_CPNumberHashes[self] = _objj_generateObjectHash();
+13
View File
@@ -92,6 +92,11 @@ CPLog(@"Got some class: %@", inst);</pre>
return class_createInstance(self);
}
+ (id)allocWithCoder:(CPCoder)aCoder
{
return [self alloc];
}
/*!
Initializes the receiver
@return the initialized receiver
@@ -459,6 +464,14 @@ CPLog(@"Got some class: %@", inst);</pre>
*/
- (unsigned)hash
{
return [self UID];
}
- (unsigned)UID
{
if (typeof self.__address === "undefined")
self.__address = _objj_generateObjectHash();
return __address;
}
+3 -3
View File
@@ -502,7 +502,7 @@ var CPStringHashes = new objj_dictionary();
/*!
Returns a hash of the string instance.
*/
- (unsigned)hash
- (unsigned)UID
{
var hash = dictionary_getValue(CPStringHashes, self);
@@ -659,7 +659,7 @@ var CPStringHashes = new objj_dictionary();
*/
+ (CPString)JSONFromObject:(JSObject)anObject
{
return CPJSObjectCreateJSON(anObject);
return JSON.stringify(anObject);
}
/*!
@@ -667,7 +667,7 @@ var CPStringHashes = new objj_dictionary();
*/
- (JSObject)objectFromJSON
{
return CPJSObjectCreateWithJSON(self);
return JSON.parse(self);
}
@end
+6 -118
View File
@@ -83,7 +83,7 @@ var CPValueValueKey = @"CPValueValueKey";
self = [super init];
if (self)
_JSObject = CPJSObjectCreateWithJSON([aCoder decodeObjectForKey:CPValueValueKey]);
_JSObject = JSON.parse([aCoder decodeObjectForKey:CPValueValueKey]);
return self;
}
@@ -94,131 +94,19 @@ var CPValueValueKey = @"CPValueValueKey";
*/
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:CPJSObjectCreateJSON(_JSObject) forKey:CPValueValueKey];
[aCoder encodeObject:JSON.stringify(_JSObject) forKey:CPValueValueKey];
}
@end
var _JSONCharacterEncodings = {};
_JSONCharacterEncodings['\b'] = "\\b";
_JSONCharacterEncodings['\t'] = "\\t";
_JSONCharacterEncodings['\n'] = "\\n";
_JSONCharacterEncodings['\f'] = "\\f";
_JSONCharacterEncodings['\r'] = "\\r";
_JSONCharacterEncodings['"'] = "\\\"";
_JSONCharacterEncodings['\\'] = "\\\\";
// FIXME: Workaround for https://trac.280north.com/ticket/16
var _JSONEncodedCharacters = new RegExp("[\\\"\\\\\\x00-\\x1f\\x7f-\\x9f]", 'g');
function CPJSObjectCreateJSON(aJSObject)
{
// typeof new Number() and new String() gives you "object",
// so valueof in those cases.
var type = typeof aJSObject,
valueOf = aJSObject ? aJSObject.valueOf() : null,
typeValueOf = typeof valueOf;
if (type != typeValueOf)
{
type = typeValueOf;
aJSObject = valueOf;
}
switch (type)
{
case "string": // If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe sequences.
if (!_JSONEncodedCharacters.test(aJSObject))
return '"' + aJSObject + '"';
return '"' + aJSObject.replace(_JSONEncodedCharacters, _CPJSObjectEncodeCharacter) + '"';
case "number": // JSON numbers must be finite. Encode non-finite numbers as null.
return isFinite(aJSObject) ? String(aJSObject) : "null";
case "boolean":
case "null": return String(aJSObject);
case "object": // Due to a specification blunder in ECMAScript,
// typeof null is 'object', so watch out for that case.
if (!aJSObject)
return "null";
// If the object has a toJSON method, call it, and stringify the result.
if (typeof aJSObject.toJSON === "function")
return CPJSObjectCreateJSON(aJSObject.toJSON());
var array = [];
// If the object is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.
if (aJSObject.slice)
{
var index = 0,
count = aJSObject.length;
for (; index < count; ++index)
array.push(CPJSObjectCreateJSON(aJSObject[index]) || "null");
// Join all of the elements together and wrap them in brackets.
return '[' + array.join(',') + ']';
}
// Otherwise, iterate through all of the keys in the object.
var key = NULL;
for (key in aJSObject)
{
if (!(typeof key === "string"))
continue;
var value = CPJSObjectCreateJSON(aJSObject[key]);
if (value)
array.push(CPJSObjectCreateJSON(key) + ':' + value);
}
// Join all of the member texts together and wrap them in braces.
return '{' + array.join(',') + '}';
}
CPLog.warn("CPJSObjectCreateJSON deprecated, use JSON.stringify() or CPString's objectFromJSON");
return JSON.stringify(aJSObject);
}
var _CPJSObjectEncodeCharacter = function(aCharacter)
{
var encoding = _JSONCharacterEncodings[aCharacter];
if (encoding)
return encoding;
encoding = aCharacter.charCodeAt(0);
return '\\u00' + FLOOR(encoding / 16).toString(16) + (encoding % 16).toString(16);
}
var _JSONBackslashCharacters = new RegExp("\\\\.", 'g'),
_JSONSimpleValueTokens = new RegExp("\"[^\"\\\\\\n\\r]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?", 'g'),
_JSONValidOpenBrackets = new RegExp("(?:^|:|,)(?:\\s*\\[)+", 'g'),
_JSONValidExpression = new RegExp("^[\\],:{}\\s]*$");
function CPJSObjectCreateWithJSON(aString)
{
if (_JSONValidExpression.test(aString.replace(_JSONBackslashCharacters, '@').replace(_JSONSimpleValueTokens, ']').replace(_JSONValidOpenBrackets, '')))
return eval('(' + aString + ')');
return nil;
CPLog.warn("CPJSObjectCreateWithJSON deprecated, use JSON.parse() or CPString's JSONFromObject");
return JSON.parse(aString);
}
/*
var _JSONBackslashCharacters = /\\./g,
_JSONSimpleValueTokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
_JSONValidOpenBrackets = /(?:^|:|,)(?:\s*\[)+/g,
_JSONValidExpression = /^[\],:{}\s]*$/;
*/
+1 -1
View File
@@ -14,7 +14,7 @@ task :build => [:Foundation, $ENVIRONMENT_PRODUCT]
ObjectiveJ::BundleTask.new(:Foundation) do |t|
t.name = 'Foundation'
t.identifier = 'com.280n.Foundation'
t.version = '0.7.0'
t.version = '0.7.1'
t.author = '280 North, Inc.'
t.email = 'feedback @nospam@ 280north.com'
t.summary = 'Foundation classes for Cappuccino'
+1
View File
@@ -19,6 +19,7 @@ task :Products => [$BROWSER_FILE, $RHINO_FILE, $LICENSE_PRODUCT]
Files = [ 'constants.js',
'utilities.js',
'json2.js',
'runtime.js',
'dictionary.js',
'plist.js',
+1 -1
View File
@@ -11,7 +11,7 @@ $ENVIRONMENT_OBJJ_PRODUCT = File.join($ENVIRONMENT_NARWHAL_PRODUCT, 'packages',
$OBJJC_JS_COMPILER = File.join($ENVIRONMENT_LIB_DIR, 'shrinksafe.jar')
$OBJJC_JS_COMPILER_RHINO = File.join($ENVIRONMENT_LIB_DIR, 'js.jar')
$EXECUTABLES = ['objj', 'objjc', 'plutil']
$EXECUTABLES = ['objj', 'objjc', 'cplutil']
$EXECUTABLES_PRODUCTS = $EXECUTABLES.map {|e| File.join($ENVIRONMENT_BIN_DIR, e) }
$EXECUTABLES.each do |executable|
@@ -13,6 +13,9 @@ function printUsage()
function main()
{
// FIXME: ARGS
system.args.shift();
if (system.args.length < 1)
return printUsage();
+13 -24
View File
@@ -1,15 +1,14 @@
#!/usr/bin/env narwhal
var objjc = require("objj/objjc");
var objjc = require("objj/objjc"),
File = require("file");
with (objjc)
{
importPackage(java.lang);
importClass(java.io.BufferedReader);
importClass(java.io.FileReader);
importClass(java.io.BufferedWriter);
importClass(java.io.FileWriter);
OBJJ_PREPROCESSOR_PREPROCESS = 1 << 10;
@@ -22,7 +21,7 @@ function exec(/*Array*/ command, /*Boolean*/ showOutput)
output = "",
process = Packages.java.lang.Runtime.getRuntime().exec(command),//jsArrayToJavaArray(command));
reader = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(process.getInputStream()));
reader = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(process.getInputStream(), "UTF-8"));
while (line = reader.readLine())
{
@@ -32,7 +31,7 @@ function exec(/*Array*/ command, /*Boolean*/ showOutput)
output += line + '\n';
}
reader = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(process.getErrorStream()));
reader = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(process.getErrorStream(), "UTF-8"));
while (line = reader.readLine())
System.out.println(line);
@@ -52,13 +51,9 @@ function exec(/*Array*/ command, /*Boolean*/ showOutput)
function compress(/*String*/ aCode, /*Object*/ flags, /*File*/ tmpFile)
{
var writer = new BufferedWriter(new FileWriter(tmpFile));
writer.write(aCode);
writer.close();
File.write(tmpFile, aCode, { charset:"UTF-8" });
return exec(["java", "-classpath", OBJJ_HOME + "/lib/js.jar" + ":" + OBJJ_HOME + "/lib/shrinksafe.jar", "org.dojotoolkit.shrinksafe.Main", tmpFile.getCanonicalPath(), "-escape-unicode"]);
return exec(["java", "-Dfile.encoding=UTF-8", "-classpath", OBJJ_HOME + "/lib/js.jar" + ":" + OBJJ_HOME + "/lib/shrinksafe.jar", "org.dojotoolkit.shrinksafe.Main", tmpFile.getCanonicalPath()]);
}
//#define SET_CONTEXT(aFragment, aContext) aFragment.context = aContext
@@ -112,15 +107,8 @@ function preprocess(aFilePath, outFilePath, gccArgs, flags)
return;
// Read file and preprocess it.
var reader = new BufferedReader(new FileReader(tmpFile)),
fileContents = "";
// Get contents of the file
while (reader.ready())
fileContents += reader.readLine() + '\n';
reader.close();
var fileContents = File.read(tmpFile, { charset: "UTF-8" });
// Preprocess contents into fragments.
var filePath = new String(new java.io.File(aFilePath).getName()),
fragments = objj_preprocess(fileContents, { path:"/x" }, {path:filePath}, flags),
@@ -171,13 +159,14 @@ function preprocess(aFilePath, outFilePath, gccArgs, flags)
}
// Write file.
var writer = new BufferedWriter(new FileWriter(outFilePath));
writer.write(preprocessed);
writer.close();
File.write(outFilePath, preprocessed, { charset: "UTF-8" });
}
function main()
{
// FIXME: ARGS
system.args.shift();
var filePaths = [],
outFilePaths = [],
+4 -1
View File
@@ -12,9 +12,12 @@ if (system.env["OBJJ_INCLUDE_PATHS"])
window.args = system.args;
// FIXME: ARGS
system.args.shift();
with (window)
{
eval(File.read(OBJJ_HOME+"/lib/Frameworks/Objective-J/rhino.platform/Objective-J.js", { charset : "UTF-8" }));
eval(File.read(OBJJ_HOME + "/lib/Frameworks/Objective-J/rhino.platform/Objective-J.js", { charset:"UTF-8" }));
if (system.args.length > 0)
{
+3 -1
View File
@@ -1,6 +1,8 @@
var File = require("file");
var window = require("browser/window");
require("./regexp-rhino-patch");
var exported = ["OBJJ_HOME", "objj_preprocess",
"FRAGMENT_FILE", "FRAGMENT_LOCAL",
"MARKER_CODE", "MARKER_IMPORT_STD", "MARKER_IMPORT_LOCAL",
@@ -10,7 +12,7 @@ var OBJJ_HOME = system.prefix + "/..";
with (window)
{
eval(File.read(OBJJ_HOME+"/lib/Frameworks/Objective-J/rhino.platform/Objective-J.js").toString());
eval(File.read(OBJJ_HOME + "/lib/Frameworks/Objective-J/rhino.platform/Objective-J.js", { charset:"UTF-8" }).toString());
for (var i = 0; i < exported.length; i++)
exports[exported[i]] = eval(exported[i]);
@@ -1,9 +1,3 @@
importClass(java.util.ArrayList);
importClass(java.util.List);
importClass(java.util.regex.Matcher);
importClass(java.util.regex.Pattern);
importClass(java.util.regex.PatternSyntaxException);
var CachedRegexData = [];
function regexDataFromRegex(aRegex)
@@ -37,10 +31,10 @@ function regexDataFromRegex(aRegex)
source = source.replace("(?<!\\\\)\\{(?!\\d)", "\\\\{", "g");
source = source.replace("(?<!(\\d,?|\\\\))\\}", "\\\\}", "g");
return CachedRegexData[string] = { pattern:Pattern.compile(source, 0), flags:flags };
return CachedRegexData[string] = { pattern:java.util.regex.Pattern.compile(source, 0), flags:flags };
}
String.prototype.match = function(regex)
function newMatch(regex)
{
var regexData = regexDataFromRegex(regex);
@@ -68,9 +62,12 @@ String.prototype.match = function(regex)
var group = matcher.group(index);
if (group != null)
groups[i] = group;
groups[index] = group;
}
}
return groups;
}
if (system.platform === "rhino")
String.prototype.match = newMatch;
+2
View File
@@ -301,6 +301,8 @@ objj_search.prototype.request = function(aFilePath, aMethod)
try
{
// unclear whether plusses are reserved in the URI path
//request.open("GET", aFilePath.replace(/\+/g, "%2B"), YES);
request.open("GET", aFilePath, YES);
request.send("");
}
+478
View File
@@ -0,0 +1,478 @@
/*
http://www.JSON.org/json2.js
2009-04-16
Public Domain.
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
See http://www.JSON.org/js.html
This file creates a global JSON object containing two methods: stringify
and parse.
JSON.stringify(value, replacer, space)
value any JavaScript value, usually an object or array.
replacer an optional parameter that determines how object
values are stringified for objects. It can be a
function or an array of strings.
space an optional parameter that specifies the indentation
of nested structures. If it is omitted, the text will
be packed without extra whitespace. If it is a number,
it will specify the number of spaces to indent at each
level. If it is a string (such as '\t' or '&nbsp;'),
it contains the characters used to indent at each level.
This method produces a JSON text from a JavaScript value.
When an object value is found, if the object contains a toJSON
method, its toJSON method will be called and the result will be
stringified. A toJSON method does not serialize: it returns the
value represented by the name/value pair that should be serialized,
or undefined if nothing should be serialized. The toJSON method
will be passed the key associated with the value, and this will be
bound to the object holding the key.
For example, this would serialize Dates as ISO strings.
Date.prototype.toJSON = function (key) {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
return this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z';
};
You can provide an optional replacer method. It will be passed the
key and value of each member, with this bound to the containing
object. The value that is returned from your method will be
serialized. If your method returns undefined, then the member will
be excluded from the serialization.
If the replacer parameter is an array of strings, then it will be
used to select the members to be serialized. It filters the results
such that only members with keys listed in the replacer array are
stringified.
Values that do not have JSON representations, such as undefined or
functions, will not be serialized. Such values in objects will be
dropped; in arrays they will be replaced with null. You can use
a replacer function to replace those with JSON values.
JSON.stringify(undefined) returns undefined.
The optional space parameter produces a stringification of the
value that is filled with line breaks and indentation to make it
easier to read.
If the space parameter is a non-empty string, then that string will
be used for indentation. If the space parameter is a number, then
the indentation will be that many spaces.
Example:
text = JSON.stringify(['e', {pluribus: 'unum'}]);
// text is '["e",{"pluribus":"unum"}]'
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
text = JSON.stringify([new Date()], function (key, value) {
return this[key] instanceof Date ?
'Date(' + this[key] + ')' : value;
});
// text is '["Date(---current time---)"]'
JSON.parse(text, reviver)
This method parses a JSON text to produce an object or array.
It can throw a SyntaxError exception.
The optional reviver parameter is a function that can filter and
transform the results. It receives each of the keys and values,
and its return value is used instead of the original value.
If it returns what it received, then the structure is not modified.
If it returns undefined then the member is deleted.
Example:
// Parse the text. Values that look like ISO date strings will
// be converted to Date objects.
myData = JSON.parse(text, function (key, value) {
var a;
if (typeof value === 'string') {
a =
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
if (a) {
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+a[5], +a[6]));
}
}
return value;
});
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
var d;
if (typeof value === 'string' &&
value.slice(0, 5) === 'Date(' &&
value.slice(-1) === ')') {
d = new Date(value.slice(5, -1));
if (d) {
return d;
}
}
return value;
});
This is a reference implementation. You are free to copy, modify, or
redistribute.
This code should be minified before deployment.
See http://javascript.crockford.com/jsmin.html
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
NOT CONTROL.
*/
/*jslint evil: true */
/*global JSON */
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
lastIndex, length, parse, prototype, push, replace, slice, stringify,
test, toJSON, toString, valueOf
*/
// Create a JSON object only if one does not already exist. We create the
// methods in a closure to avoid creating global variables.
if (!this.JSON) {
JSON = {};
}
(function () {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
if (typeof Date.prototype.toJSON !== 'function') {
Date.prototype.toJSON = function (key) {
return this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z';
};
String.prototype.toJSON =
Number.prototype.toJSON =
Boolean.prototype.toJSON = function (key) {
return this.valueOf();
};
}
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
gap,
indent,
meta = { // table of character substitutions
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
},
rep;
function quote(string) {
// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.
escapable.lastIndex = 0;
return escapable.test(string) ?
'"' + string.replace(escapable, function (a) {
var c = meta[a];
return typeof c === 'string' ? c :
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"' :
'"' + string + '"';
}
function str(key, holder) {
// Produce a string from holder[key].
var i, // The loop counter.
k, // The member key.
v, // The member value.
length,
mind = gap,
partial,
value = holder[key];
// If the value has a toJSON method, call it to obtain a replacement value.
if (value && typeof value === 'object' &&
typeof value.toJSON === 'function') {
value = value.toJSON(key);
}
// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.
if (typeof rep === 'function') {
value = rep.call(holder, key, value);
}
// What happens next depends on the value's type.
switch (typeof value) {
case 'string':
return quote(value);
case 'number':
// JSON numbers must be finite. Encode non-finite numbers as null.
return isFinite(value) ? String(value) : 'null';
case 'boolean':
case 'null':
// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.
return String(value);
// If the type is 'object', we might be dealing with an object or an array or
// null.
case 'object':
// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.
if (!value) {
return 'null';
}
// Make an array to hold the partial results of stringifying this object value.
gap += indent;
partial = [];
// Is the value an array?
if (Object.prototype.toString.apply(value) === '[object Array]') {
// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.
length = value.length;
for (i = 0; i < length; i += 1) {
partial[i] = str(i, value) || 'null';
}
// Join all of the elements together, separated with commas, and wrap them in
// brackets.
v = partial.length === 0 ? '[]' :
gap ? '[\n' + gap +
partial.join(',\n' + gap) + '\n' +
mind + ']' :
'[' + partial.join(',') + ']';
gap = mind;
return v;
}
// If the replacer is an array, use it to select the members to be stringified.
if (rep && typeof rep === 'object') {
length = rep.length;
for (i = 0; i < length; i += 1) {
k = rep[i];
if (typeof k === 'string') {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
} else {
// Otherwise, iterate through all of the keys in the object.
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
}
// Join all of the member texts together, separated with commas,
// and wrap them in braces.
v = partial.length === 0 ? '{}' :
gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
mind + '}' : '{' + partial.join(',') + '}';
gap = mind;
return v;
}
}
// If the JSON object does not yet have a stringify method, give it one.
if (typeof JSON.stringify !== 'function') {
JSON.stringify = function (value, replacer, space) {
// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.
var i;
gap = '';
indent = '';
// If the space parameter is a number, make an indent string containing that
// many spaces.
if (typeof space === 'number') {
for (i = 0; i < space; i += 1) {
indent += ' ';
}
// If the space parameter is a string, it will be used as the indent string.
} else if (typeof space === 'string') {
indent = space;
}
// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.
rep = replacer;
if (replacer && typeof replacer !== 'function' &&
(typeof replacer !== 'object' ||
typeof replacer.length !== 'number')) {
throw new Error('JSON.stringify');
}
// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.
return str('', {'': value});
};
}
// If the JSON object does not yet have a parse method, give it one.
if (typeof JSON.parse !== 'function') {
JSON.parse = function (text, reviver) {
// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.
var j;
function walk(holder, key) {
// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.
var k, v, value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
}
}
return reviver.call(holder, key, value);
}
// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.
cx.lastIndex = 0;
if (cx.test(text)) {
text = text.replace(cx, function (a) {
return '\\u' +
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
});
}
// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.
// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
if (/^[\],:{}\s]*$/.
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.
j = eval('(' + text + ')');
// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.
return typeof reviver === 'function' ?
walk({'': j}, '') : j;
}
// If the text is not JSON parseable, then a SyntaxError is thrown.
throw new SyntaxError('JSON.parse');
};
}
}());
+5 -8
View File
@@ -177,8 +177,8 @@ function class_addMethod(/*Class*/ aClass, /*SEL*/ aName, /*IMP*/ anImplementati
// FIXME: Should this be done here?
// If this is a root class...
if (!ISMETA(aClass) && GETMETA(aClass).isa === GETMETA(aClass))
class_addMethods(GETMETA(aClass), methods);
class_addMethod(GETMETA(aClass), method);
return YES;
}
@@ -472,12 +472,9 @@ function objj_msgSend(/*id*/ aReceiver, /*SEL*/ aSelector)
switch(arguments.length)
{
case 2:
return implementation(aReceiver, aSelector);
case 3:
return implementation(aReceiver, aSelector, arguments[2]);
case 4:
return implementation(aReceiver, aSelector, arguments[2], arguments[3]);
case 2: return implementation(aReceiver, aSelector);
case 3: return implementation(aReceiver, aSelector, arguments[2]);
case 4: return implementation(aReceiver, aSelector, arguments[2], arguments[3]);
}
return implementation.apply(aReceiver, arguments);
+1 -1
View File
@@ -247,7 +247,7 @@ PERLMOD_MAKEVAR_PREFIX =
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
+2 -2
View File
@@ -17,7 +17,7 @@ spec = Gem::Specification.new do |s|
s.homepage = 'http://cappuccino.org/'
s.summary = "Objective-J extensions to Rake."
s.name = 'objective-j'
s.version = "0.7.0"
s.version = "0.7.1"
s.requirements << 'rake'
s.require_path = 'lib'
s.files = PKG_FILES
@@ -34,7 +34,7 @@ Rake::GemPackageTask.new(spec) do |pkg|
end
#task :install do
# Gem::Installer.new(File.join($BUILD_DIR, $CONFIGURATION, 'rake', 'objective-j-0.7.0.gem')).install
# Gem::Installer.new(File.join($BUILD_DIR, $CONFIGURATION, 'rake', 'objective-j-0.7.1.gem')).install
#end
task :objj_gem => [:gem] do
+2
View File
@@ -545,6 +545,8 @@ module ObjectiveJ
list.each do |fileName|
fileName = File.expand_path(fileName)
File.open(fileName) do |file|
if fileName.index(platform_absolute_path) == 0
+1 -1
View File
@@ -15,7 +15,7 @@ $ENVIRONMENT_LIB_PRODUCT = File.join($ENVIRONMENT_LIB_DIR, 'bake')
ObjectiveJ::BundleTask.new(:bake) do |t|
t.name = 'bake'
t.identifier = 'com.280n.bake'
t.version = '0.7.0'
t.version = '0.7.1'
t.author = '280 North, Inc.'
t.email = 'feedback @nospam@ 280north.com'
t.summary = 'Deployment tool for Cappuccino applications'
+1 -1
View File
@@ -28,7 +28,7 @@ function readConfig(configFile)
if (!fileData)
throw new Error("Couldn't read file: " + configFile);
var configs = CPJSObjectCreateWithJSON(fileData);
var configs = JSON.parse(fileData);
return configs;
}
+1 -1
View File
@@ -14,7 +14,7 @@ $ENVIRONMENT_LIB_PRODUCT = File.join($ENVIRONMENT_LIB_DIR, 'capp')
ObjectiveJ::BundleTask.new(:capp) do |t|
t.name = 'capp'
t.identifier = 'com.280n.capp'
t.version = '0.7.0'
t.version = '0.7.1'
t.author = '280 North, Inc.'
t.email = 'feedback @nospam@ 280north.com'
t.summary = 'Setup up Cappuccino projects'
@@ -6,10 +6,10 @@
* Copyright __project.year__, __organization.name__ All rights reserved.
*/
@import <Foundation/CPObject.j>
@import <BlendKit/BKThemeDescriptor.j>
@implementation __project.nameasidentifier__ThemeDescriptor : CPObject
@implementation __project.nameasidentifier__ThemeDescriptor : BKThemeDescriptor
{
}
+1 -1
View File
@@ -24,7 +24,7 @@ function main()
switch (argument)
{
case "version":
case "--version": return print("capp version 0.7.0");
case "--version": return print("capp version 0.7.1");
case "-h":
case "--help": return printUsage();
+1
View File
@@ -22,6 +22,7 @@
@import "NSButton.j"
@import "NSCell.j"
@import "NSClassSwapper.j"
@import "NSClipView.j"
@import "NSColor.j"
@import "NSColorWell.j"
+66
View File
@@ -0,0 +1,66 @@
var NSClassSwapperClassNames = {},
NSClassSwapperOriginalClassNames = {};
var _CPCibClassSwapperClassNameKey = @"_CPCibClassSwapperClassNameKey",
_CPCibClassSwapperOriginalClassNameKey = @"_CPCibClassSwapperOriginalClassNameKey";
@implementation NSClassSwapper : _CPCibClassSwapper
{
}
+ (id)swapperClassForClassName:(CPString)aClassName originalClassName:(CPString)anOriginalClassName
{
var swapperClassName = "$NSClassSwapper_" + aClassName + "_" + anOriginalClassName;
swapperClass = objj_lookUpClass(swapperClassName);
if (!swapperClass)
{
var originalClass = objj_lookUpClass(anOriginalClassName);
swapperClass = objj_allocateClassPair(originalClass, swapperClassName);
objj_registerClassPair(swapperClass);
class_addMethod(swapperClass, @selector(initWithCoder:), function(self, _cmd, aCoder)
{
self = objj_msgSendSuper({super_class:originalClass, receiver:self}, _cmd, aCoder);
if (self)
{
var UID = [self UID];
NSClassSwapperClassNames[UID] = aClassName;
NSClassSwapperOriginalClassNames[UID] = anOriginalClassName;
}
return self;
}, "");
class_addMethod(swapperClass, @selector(classForKeyedArchiver), function(self, _cmd)
{
return [_CPCibClassSwapper class];
}, "");
class_addMethod(swapperClass, @selector(encodeWithCoder:), function(self, _cmd, aCoder)
{
objj_msgSendSuper({super_class:originalClass, receiver:self}, _cmd, aCoder);
// FIXME: map class name as well?
[aCoder encodeObject:aClassName forKey:_CPCibClassSwapperClassNameKey];
[aCoder encodeObject:CP_NSMapClassName(anOriginalClassName) forKey:_CPCibClassSwapperOriginalClassNameKey];
}, "");
}
return swapperClass;
}
+ (id)allocWithCoder:(CPCoder)aCoder
{
var className = [aCoder decodeObjectForKey:@"NSClassName"],
originalClassName = [aCoder decodeObjectForKey:@"NSOriginalClassName"];
return [[self swapperClassForClassName:className originalClassName:originalClassName] alloc];
}
@end
+3 -3
View File
@@ -75,9 +75,9 @@
//_accessibilityOidsKeys = [aCoder decodeObjectForKey:@"NSAccessibilityOidsKeys"];
//_accessibilityOidsValues = [aCoder decodeObjectForKey:@"NSAccessibilityOidsValues"];
_classesKeys = [aCoder decodeObjectForKey:@"NSClassesKeys"];print("d");
_classesValues = [aCoder decodeObjectForKey:@"NSClassesValues"];print("e");
_classesKeys = [aCoder decodeObjectForKey:@"NSClassesKeys"];
_classesValues = [aCoder decodeObjectForKey:@"NSClassesValues"];
_connections = [aCoder decodeObjectForKey:@"NSConnections"];
//_fontManager = [aCoder decodeObjectForKey:@"NSFontManager"] retain];
+1
View File
@@ -34,6 +34,7 @@
var cell = [aCoder decodeObjectForKey:@"NSCell"];
_imageScaling = [cell imageScaling];
_isEditable = [cell isEditable];
}
return self;
+2 -1
View File
@@ -33,6 +33,8 @@
if (self)
{
_isSeparator = [aCoder decodeObjectForKey:@"NSIsSeparator"] || NO;
_title = [aCoder decodeObjectForKey:"NSTitle"];
// _font = [aCoder decodeObjectForKey:"NSTitle"];
@@ -89,7 +91,6 @@
@end
@implementation NSMenuItemCell : NSButtonCell
{
}
+3 -3
View File
@@ -31,14 +31,14 @@
- (id)NS_initWithCoder:(CPCoder)aCoder
{
_frame = CGRectMakeZero();
if ([aCoder containsValueForKey:@"NSFrame"])
_frame = [aCoder decodeRectForKey:@"NSFrame"];
else if ([aCoder containsValueForKey:@"NSFrameSize"])
_frame.size = [aCoder decodeSizeForKey:@"NSFrameSize"];
_frame.size = [aCoder decodeSizeForKey:@"NSFrameSize"];
self = [super NS_initWithCoder:aCoder];
if (self)
{
_tag = -1;
+1 -1
View File
@@ -14,7 +14,7 @@ $ENVIRONMENT_LIB_PRODUCT = File.join($ENVIRONMENT_LIB_DIR, 'nib2cib')
ObjectiveJ::BundleTask.new(:nib2cib) do |t|
t.name = 'nib2cib'
t.identifier = 'com.280n.nib2cib'
t.version = '0.7.0'
t.version = '0.7.1'
t.author = '280 North, Inc.'
t.email = 'feedback @nospam@ 280north.com'
t.summary = 'nib2cib converts Cocoa nib and xibs to Cappuccino cibs'
+3 -3
View File
@@ -125,7 +125,7 @@ function convert(inputFileName, outputFileName, resourcesPath)
return;
}
var data = [CPData dataWithString:File.read(String(temporaryPlistFilePath), { charset:"UTF8" })];
var data = [CPData dataWithString:File.read(String(temporaryPlistFilePath), { charset:"UTF-8" })];
// Minor NSKeyedArchive to CPKeyedArchive conversion.
[data setString:[data string].replace(/\<key\>\s*CF\$UID\s*\<\/key\>/g, "<key>CP$UID</key>")];
@@ -141,7 +141,7 @@ function convert(inputFileName, outputFileName, resourcesPath)
[archiver encodeObject:objectData forKey:@"CPCibObjectDataKey"];
[archiver finishEncoding];
File.write(outputFileName, [data string], { charset:"UTF8" });
File.write(outputFileName, [data string], { charset:"UTF-8" });
}
function loadFrameworks(frameworkPaths, aCallback)
@@ -159,7 +159,7 @@ function loadFrameworks(frameworkPaths, aCallback)
java.lang.System.exit(1);
}
var infoDictionary = CPPropertyListCreateFromData([CPData dataWithString:File.read(frameworkPath + "/Info.plist", { charset:"UTF8" })]);
var infoDictionary = CPPropertyListCreateFromData([CPData dataWithString:File.read(frameworkPath + "/Info.plist", { charset:"UTF-8" })]);
if ([infoDictionary objectForKey:@"CPBundlePackageType"] !== "FMWK")
{
+1 -1
View File
@@ -16,7 +16,7 @@ $ENVIRONMENT_BRIDGE = File.join($ENVIRONMENT_LIB_DIR, 'press', 'bridge.js')
ObjectiveJ::BundleTask.new(:press) do |t|
t.name = 'press'
t.identifier = 'com.280n.press'
t.version = '0.7.0'
t.version = '0.7.1'
t.author = '280 North, Inc.'
t.email = 'feedback @nospam@ 280north.com'
t.summary = 'Deployment tool for Cappuccino applications'
+1 -1
View File
@@ -239,7 +239,7 @@ function main()
// add fake bundle response bookkeeping
applicationJS.push("var __fakeDidReceiveBundleResponse = " + String(fakeDidReceiveBundleResponse));
applicationJS.push("var __fakeBundleArchives = " + CPJSObjectCreateJSON(bundleArchives) + ";");
applicationJS.push("var __fakeBundleArchives = " + JSON.stringify(bundleArchives) + ";");
applicationJS.push("for (var i = 0; i < __fakeBundleArchives.length; i++) __fakeDidReceiveBundleResponse(__fakeBundleArchives[i]);")
// add each fragment, wrapped in a function, along with OBJJ_CURRENT_BUNDLE bookkeeping