diff --git a/AppKit/AppKit.steam b/AppKit/AppKit.steam
index f07d2aaf3..69c4cc952 100644
--- a/AppKit/AppKit.steam
+++ b/AppKit/AppKit.steam
@@ -34,12 +34,12 @@
Name
Debug
+ Flags
+ -DDEBUG
Settings
PREPROCESS
- FLAGS
- -DDEBUG
diff --git a/AppKit/CPAnimation.j b/AppKit/CPAnimation.j
index 11eed88a5..080f19daf 100644
--- a/AppKit/CPAnimation.j
+++ b/AppKit/CPAnimation.j
@@ -211,7 +211,7 @@ ACTUAL_FRAME_RATE = 0;
- (void)startAnimation
{
// If we're already animating, or our delegate stops us, animate.
- if (_timer || _delegate && ![_delegate animationShouldStart:self])
+ if (_timer || _delegate && [_delegate respondsToSelector:@selector(animationShouldStart)] && ![_delegate animationShouldStart:self])
return;
_progress = 0.0;
@@ -258,7 +258,8 @@ ACTUAL_FRAME_RATE = 0;
window.clearTimeout(_timer);
_timer = nil;
- [_delegate animationDidStop:self];
+ if ([_delegate respondsToSelector:@selector(animationDidStop:)])
+ [_delegate animationDidStop:self];
}
/*
diff --git a/AppKit/CPControl.j b/AppKit/CPControl.j
index d76594e3b..a035f5467 100644
--- a/AppKit/CPControl.j
+++ b/AppKit/CPControl.j
@@ -253,8 +253,8 @@ var CPControlBlackColor = [CPColor blackColor];
- (void)mouseUp:(CPEvent)anEvent
{
- if (_sendActionOn & CPLeftMouseUpMask && CPRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil]))
- [self sendAction:_action to:_target];
+ if (_sendActionOn & CPLeftMouseUpMask && CPRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil])){alert([_target description] + " : " + _action);
+ [self sendAction:_action to:_target];}
[super mouseUp:anEvent];
}
@@ -282,7 +282,71 @@ var CPControlBlackColor = [CPColor blackColor];
*/
- (void)setFloatValue:(float)aValue
{
- _value = aValue;
+ [self setObjectValue:aValue];
+}
+
+/*
+ Returns the receiver's object value
+*/
+- (id)objectValue
+{
+ return _value;
+}
+
+/*
+ Set's the receiver's object value
+*/
+- (void)setObjectValue:(id)anObject
+{
+ _value = anObject;
+}
+
+/*
+ Returns the receiver's double value
+*/
+- (id)doubleValue
+{
+ return [self floatValue];
+}
+
+/*
+ Set's the receiver's double value
+*/
+- (void)setDoubleValue:(id)anObject
+{
+ [self setObjectValue:anObject];
+}
+
+/*
+ Returns the receiver's int value
+*/
+- (id)intValue
+{
+ return _value ? parseInt(_value, 10) : 0;
+}
+
+/*
+ Set's the receiver's int value
+*/
+- (void)setIntValue:(id)anObject
+{
+ [self setObjectValue:anObject];
+}
+
+/*
+ Returns the receiver's int value
+*/
+- (id)stringValue
+{
+ return _value ? ""+_value : "";
+}
+
+/*
+ Set's the receiver's int value
+*/
+- (void)setStringValue:(id)anObject
+{
+ [self setObjectValue:anObject];
}
- (void)setBackgroundColor:(CPColor)aColor
diff --git a/AppKit/CPImage.j b/AppKit/CPImage.j
index f51d44805..b5baef554 100644
--- a/AppKit/CPImage.j
+++ b/AppKit/CPImage.j
@@ -20,10 +20,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-import
-import
import
+import
+import
import
+import
import "CPGeometry.j"
@@ -35,6 +36,8 @@ CPImageLoadStatusInvalidData = 4;
CPImageLoadStatusUnexpectedEOF = 5;
CPImageLoadStatusReadError = 6;
+CPImageDidLoadNotification = @"CPImageDidLoadNotification";
+
@implementation CPBundle (CPImageAdditions)
- (CPString)pathForResource:(CPString)aFilename
@@ -219,7 +222,11 @@ CPImageLoadStatusReadError = 6;
// FIXME: IE is wrong on image sizes????
if (!_size || (_size.width == -1 && _size.height == -1))
_size = CGSizeMake(_image.width, _image.height);
-
+
+ [[CPNotificationCenter defaultCenter]
+ postNotificationName:CPImageDidLoadNotification
+ object:self];
+
if ([_delegate respondsToSelector:@selector(imageDidLoad:)])
[_delegate imageDidLoad:self];
diff --git a/AppKit/CPImageView.j b/AppKit/CPImageView.j
index 6aa860c5c..5cba2ae88 100644
--- a/AppKit/CPImageView.j
+++ b/AppKit/CPImageView.j
@@ -20,8 +20,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-import "CPImage.j"
+import
+
import "CPControl.j"
+import "CPImage.j"
import "CPShadowView.j"
#include "Platform/Platform.h"
@@ -110,20 +112,35 @@ var LEFT_SHADOW_INSET = 3.0,
if (_image == anImage)
return;
+ var center = [CPNotificationCenter defaultCenter];
+
+ if (_image)
+ [center removeObserver:self name:CPImageDidLoadNotification object:_image];
+
_image = anImage;
-
_DOMImageElement.src = [anImage filename];
+
+ var size = [_image size];
- if (_imageScaling == CPScaleNone && _image)
+ if (size && size.width == -1 && size.height == -1)
{
- var size = [_image size];
+ [center addObserver:self selector:@selector(imageDidLoad:) name:CPImageDidLoadNotification object:_image];
+
+ _DOMImageElement.width = 0;
+ _DOMImageElement.height = 0;
- _DOMImageElement.width = ROUND(size.width);
- _DOMImageElement.height = ROUND(size.height);
+ [_shadowView setHidden:YES];
}
-
+ else
+ {
+ [self hideOrDisplayContents];
+ [self tile];
+ }
+}
+
+- (void)imageDidLoad:(CPNotification)aNotification
+{
[self hideOrDisplayContents];
-
[self tile];
}
@@ -181,13 +198,6 @@ var LEFT_SHADOW_INSET = 3.0,
{
CPDOMDisplayServerSetStyleLeftTop(_DOMImageElement, NULL, 0.0, 0.0);
}
- else if (_imageScaling == CPScaleNone && _image)
- {
- var size = [_image size];
-
- _DOMImageElement.width = ROUND(size.width);
- _DOMImageElement.height = ROUND(size.height);
- }
[self tile];
}
@@ -240,7 +250,7 @@ var LEFT_SHADOW_INSET = 3.0,
{
if (!_image)
return;
-
+
var bounds = [self bounds],
x = 0.0,
y = 0.0,
@@ -260,6 +270,9 @@ var LEFT_SHADOW_INSET = 3.0,
{
var size = [_image size];
+ if (size.width == -1 && size.height == -1)
+ return;
+
if (_imageScaling == CPScaleProportionally)
{
// The max size it can be is size.width x size.height, so only
@@ -289,6 +302,12 @@ var LEFT_SHADOW_INSET = 3.0,
height = size.height;
}
+ if (_imageScaling == CPScaleNone)
+ {
+ _DOMImageElement.width = ROUND(size.width);
+ _DOMImageElement.height = ROUND(size.height);
+ }
+
var x = (boundsWidth - width) / 2.0,
y = (boundsHeight - height) / 2.0;
diff --git a/AppKit/CPSplitView.j b/AppKit/CPSplitView.j
new file mode 100644
index 000000000..97bff90a7
--- /dev/null
+++ b/AppKit/CPSplitView.j
@@ -0,0 +1,407 @@
+/*
+ * CPSplitView.j
+ * AppKit
+ *
+ * Created by Thomas Robinson.
+ * Copyright 2008, 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 "CPImage.j"
+import "CPView.j"
+
+#include "CoreGraphics/CGGeometry.h"
+#include "Platform/Platform.h"
+#include "Platform/DOM/CPDOMDisplayServer.h"
+
+CPSplitViewDidResizeSubviewsNotification = @"CPSplitViewDidResizeSubviewsNotification";
+CPSplitViewWillResizeSubviewsNotification = @"CPSplitViewWillResizeSubviewsNotification";
+
+var CPSplitViewHorizontalImage = nil,
+ CPSplitViewVerticalImage = nil;
+
+@implementation CPSplitView : CPView
+{
+ id _delegate;
+ BOOL _isVertical;
+ BOOL _isPaneSplitter;
+
+ int _currentDivider;
+ float _initialOffset;
+
+ CPString _originComponent;
+ CPString _sizeComponent;
+
+ CPArray _DOMDividerElements;
+}
+
+/*
+ @ignore
+*/
+//+ (void)initialize
+//{
+// if (self != [CPSplitView class])
+// return;
+//
+// var bundle = [CPBundle bundleForClass:self];
+//
+// CPSplitViewHorizontalImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSplitView/CPSplitViewHorizontal.png"] size:CPSizeMake(5.0, 10.0)];
+// CPSplitViewVerticalImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSplitView/CPSplitViewVertical.png"] size:CPSizeMake(10.0, 5.0)];
+//}
+
+- (id)initWithFrame:(CGRect)aFrame
+{
+ if (self = [super initWithFrame:aFrame])
+ {
+ _currentDivider = CPNotFound;
+
+ _DOMDividerElements = [];
+
+ [self setVertical:YES];
+ [self setIsPaneSplitter:YES];
+ }
+
+ return self;
+}
+
+- (float)dividerThickness
+{
+ return 10.0;
+}
+
+- (BOOL)isVertical
+{
+ return _isVertical;
+}
+- (void)setVertical:(BOOL)flag
+{
+ _isVertical = flag;
+
+ _originComponent = [self isVertical] ? "x" : "y";
+ _sizeComponent = [self isVertical] ? "width" : "height";
+
+ [self adjustSubviews];
+}
+
+- (BOOL)isPaneSplitter
+{
+ return _isPaneSplitter;
+}
+- (void)setIsPaneSplitter:(BOOL)flag
+{
+ _isPaneSplitter = flag;
+}
+
+- (void)didAddSubview:(CPView)subview
+{
+ [self adjustSubviews];
+}
+
+- (void)adjustSubviews
+{
+ var frame = [self frame],
+ dividerThickness = [self dividerThickness];
+
+ [self _postNotificationWillResize];
+
+ var eachSize = (frame.size[_sizeComponent] - dividerThickness * (_subviews.length - 1)) / _subviews.length;
+
+ for (var i = 0; i < [_subviews count]; i++)
+ {
+ if ([self isVertical])
+ [_subviews[i] setFrame:CGRectMake(Math.round((eachSize + dividerThickness) * i), 0, Math.round(eachSize), frame.size.height)];
+ else
+ [_subviews[i] setFrame:CGRectMake(0, Math.round((eachSize + dividerThickness) * i), frame.size.width, Math.round(eachSize))];
+ }
+
+ [self setNeedsDisplay:YES];
+
+ [self _postNotificationDidResize];
+}
+
+- (BOOL)isSubviewCollapsed:(CPView)subview
+{
+ return [subview frame].size[_sizeComponent] < 1 ? YES : NO;
+}
+
+- (CGRect)rectOfDividerAtIndex:(int)aDivider
+{
+ var frame = [_subviews[aDivider] frame];
+
+ var rect = CGRectMakeZero();
+ rect.size = CPSizeCreateCopy([self frame].size);
+
+ rect.size[_sizeComponent] = [self dividerThickness];
+ rect.origin[_originComponent] = frame.origin[_originComponent] + frame.size[_sizeComponent];
+
+ return rect;
+}
+
+- (CGRect)effectiveRectOfDividerAtIndex:(int)aDivider
+{
+ var realRect = [self rectOfDividerAtIndex:aDivider];
+
+ realRect.size[_sizeComponent] += 4;
+ realRect.origin[_originComponent] -= 2;
+
+ return realRect;
+}
+
+- (void)drawRect:(CGRect)rect
+{
+#if PLATFORM(DOM)
+ var dividerPath = [self isVertical] ? [CPSplitViewVerticalImage filename] : [CPSplitViewHorizontalImage filename];
+
+ var count = [_subviews count];
+ for (var i = 0; i < count; i++)
+ {
+ if (!_DOMDividerElements[i])
+ {
+ _DOMDividerElements[i] = document.createElement("div");
+ _DOMDividerElements[i].style.cursor = "move";
+ _DOMDividerElements[i].style.position = "absolute";
+ _DOMDividerElements[i].style.backgroundRepeat = "repeat";
+ CPDOMDisplayServerAppendChild(_DOMElement, _DOMDividerElements[i]);
+ }
+
+ var frame = [self rectOfDividerAtIndex:i];
+ CPDOMDisplayServerSetStyleLeftTop(_DOMDividerElements[i], NULL, _CGRectGetMinX(frame), _CGRectGetMinY(frame));
+ CPDOMDisplayServerSetStyleSize(_DOMDividerElements[i], _CGRectGetWidth(frame), _CGRectGetHeight(frame));
+
+ _DOMDividerElements[i].style.backgroundImage = "url('"+dividerPath+"')";
+ }
+#endif
+}
+
+- (void)drawDividerInRect:(CGRect)aRect
+{
+ // TODO: figure out a way to "draw" dividers using DOM element
+}
+
+- (BOOL)cursorAtPoint:(CPPoint)aPoint hitDividerAtIndex:(int)anIndex
+{
+ var frame = [_subviews[anIndex] frame],
+ startPosition = frame.origin[_originComponent] + frame.size[_sizeComponent],
+ effectiveRect = [self effectiveRectOfDividerAtIndex:anIndex],
+ additionalRect = null;
+
+ if ([_delegate respondsToSelector:@selector(splitView:effectiveRect:forDrawnRect:ofDividerAtIndex:)])
+ effectiveRect = [_delegate splitView:self effectiveRect:effectiveRect forDrawnRect:effectiveRect ofDividerAtIndex:anIndex];
+
+ if ([_delegate respondsToSelector:@selector(splitView:additionalEffectiveRectOfDividerAtIndex:)])
+ additionalRect = [_delegate splitView:self additionalEffectiveRectOfDividerAtIndex:anIndex];
+
+ return CGRectContainsPoint(effectiveRect, aPoint) || (additionalRect && CGRectContainsPoint(additionalRect, aPoint));
+}
+
+- (void)mouseDown:(CPEvent)theEvent
+{
+ var location = [theEvent locationInWindow],
+ point = [self convertPoint:location fromView:nil];
+
+ for (var i = 0; i < [_subviews count] - 1; i++)
+ {
+ var frame = [_subviews[i] frame],
+ startPosition = frame.origin[_originComponent] + frame.size[_sizeComponent];
+
+ if ([self cursorAtPoint:point hitDividerAtIndex:i])
+ {
+ if ([theEvent clickCount] == 2 &&
+ [_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
+ [_delegate respondsToSelector:@selector(splitView:shouldCollapseSubview:forDoubleClickOnDividerAtIndex:)])
+ {
+ var minPosition = [self minPossiblePositionOfDividerAtIndex:i],
+ maxPosition = [self maxPossiblePositionOfDividerAtIndex:i];
+
+ if ([_delegate splitView:self canCollapseSubview:_subviews[i]] && [_delegate splitView:self shouldCollapseSubview:_subviews[i] forDoubleClickOnDividerAtIndex:i])
+ {
+ if ([self isSubviewCollapsed:_subviews[i]])
+ [self setPosition:(minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
+ else
+ [self setPosition:minPosition ofDividerAtIndex:i];
+ }
+ else if ([_delegate splitView:self canCollapseSubview:_subviews[i+1]] && [_delegate splitView:self shouldCollapseSubview:_subviews[i+1] forDoubleClickOnDividerAtIndex:i])
+ {
+ if ([self isSubviewCollapsed:_subviews[i+1]])
+ [self setPosition:(minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
+ else
+ [self setPosition:maxPosition ofDividerAtIndex:i];
+ }
+ }
+ else
+ {
+ _currentDivider = i;
+ _initialOffset = startPosition - point[_originComponent];
+
+ [self _postNotificationWillResize];
+ }
+
+ return;
+ }
+ }
+ _currentDivider = CPNotFound;
+}
+
+- (void)mouseDragged:(CPEvent)theEvent
+{
+ if (_currentDivider != CPNotFound)
+ {
+ var location = [theEvent locationInWindow],
+ point = [self convertPoint:location fromView:nil];
+
+ [self setPosition:(point[_originComponent] + _initialOffset) ofDividerAtIndex:_currentDivider];
+ }
+}
+
+- (void)mouseUp:(CPEvent)theEvent
+{
+ if (_currentDivider != CPNotFound)
+ {
+ _currentDivider = CPNotFound;
+ [self _postNotificationDidResize];
+ }
+}
+
+- (float)maxPossiblePositionOfDividerAtIndex:(int)dividerIndex
+{
+ var frame = [_subviews[dividerIndex + 1] frame];
+
+ if (dividerIndex + 1 < [_subviews count] - 1)
+ return frame.origin[_originComponent] + frame.size[_sizeComponent] - [self dividerThickness];
+ else
+ return [self frame].size[_sizeComponent] - [self dividerThickness];
+}
+
+- (float)minPossiblePositionOfDividerAtIndex:(int)dividerIndex
+{
+ var frame = [_subviews[dividerIndex - 1] frame];
+
+ if (dividerIndex > 0)
+ return frame.origin[_originComponent] + frame.size[_sizeComponent] + [self dividerThickness];
+ else
+ return 0;
+}
+
+- (void)setPosition:(float)position ofDividerAtIndex:(int)dividerIndex
+{
+ // not sure where this should override other positions?
+ if ([_delegate respondsToSelector:@selector(splitView:constrainSplitPosition:ofSubviewAt:)])
+ position = [_delegate splitView:self constrainSplitPosition:position ofSubviewAt:dividerIndex];
+
+ var proposedMax = [self maxPossiblePositionOfDividerAtIndex:dividerIndex],
+ proposedMin = [self minPossiblePositionOfDividerAtIndex:dividerIndex],
+ actualMax = proposedMax,
+ actualMin = proposedMin;
+
+ if([_delegate respondsToSelector:@selector(splitView:constrainMinCoordinate:ofSubviewAt:)])
+ actualMin = [_delegate splitView:self constrainMinCoordinate:proposedMin ofSubviewAt:dividerIndex];
+
+ if([_delegate respondsToSelector:@selector(splitView:constrainMaxCoordinate:ofSubviewAt:)])
+ actualMax = [_delegate splitView:self constrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
+
+ var frame = [self frame],
+ viewA = _subviews[dividerIndex],
+ frameA = CGRectCreateCopy([viewA frame]),
+ viewB = _subviews[dividerIndex+1],
+ frameB = CGRectCreateCopy([viewB frame]);
+
+ var realPosition = MAX(MIN(position, actualMax), actualMin);
+
+ if (position < proposedMin + (actualMin - proposedMin) / 2)
+ if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
+ if ([_delegate splitView:self canCollapseSubview:viewA])
+ realPosition = proposedMin;
+
+ frameA.size[_sizeComponent] = realPosition - frameA.origin[_originComponent];
+ [_subviews[dividerIndex] setFrame:frameA];
+
+ frameB.size[_sizeComponent] = frameB.origin[_originComponent] + frameB.size[_sizeComponent] - realPosition - [self dividerThickness];
+ frameB.origin[_originComponent] = realPosition + [self dividerThickness];
+ [_subviews[dividerIndex+1] setFrame:frameB];
+
+ [self setNeedsDisplay:YES];
+}
+
+- (void)resizeSubviewsWithOldSize:(CPSize)oldSize
+{
+ if ([_delegate respondsToSelector:@selector(splitView:resizeSubviewsWithOldSize:)])
+ {
+ [_delegate splitView:self resizeSubviewsWithOldSize:oldSize];
+ return;
+ }
+
+ [self _postNotificationWillResize];
+
+ var frame = CGRectCreateCopy([self frame]);
+
+ for (var i = 0; i < [_subviews count]; i++)
+ {
+ var view = [_subviews objectAtIndex:i],
+ newFrame = CGRectCreateCopy(frame);
+
+ if(i + 1 == [_subviews count])
+ newFrame.size[_sizeComponent] = frame.size[_sizeComponent] - newFrame.origin[_originComponent];
+ else
+ newFrame.size[_sizeComponent] = frame.size[_sizeComponent] * ([view frame].size[_sizeComponent] / oldSize[_sizeComponent]);
+
+ frame.origin[_originComponent] += newFrame.size[_sizeComponent];
+ frame.origin[_originComponent] += [self dividerThickness];
+
+ [view setFrame:newFrame];
+ }
+
+ [self setNeedsDisplay:YES];
+
+ [self _postNotificationDidResize];
+}
+
+- (void)setDelegate:(id)delegate
+{
+ if ([_delegate respondsToSelector:@selector(splitViewDidResizeSubviews:)])
+ [[CPNotificationCenter defaultCenter] removeObserver:_delegate name:CPSplitViewDidResizeSubviewsNotification object:self];
+ if ([_delegate respondsToSelector:@selector(splitViewWillResizeSubviews:)])
+ [[CPNotificationCenter defaultCenter] removeObserver:_delegate name:CPSplitViewWillResizeSubviewsNotification object:self];
+
+ _delegate = delegate;
+
+ if ([_delegate respondsToSelector:@selector(splitViewDidResizeSubviews:)])
+ [[CPNotificationCenter defaultCenter] addObserver:_delegate
+ selector:@selector(splitViewDidResizeSubviews:)
+ name:CPSplitViewDidResizeSubviewsNotification
+ object:self];
+ if ([_delegate respondsToSelector:@selector(splitViewWillResizeSubviews:)])
+ [[CPNotificationCenter defaultCenter] addObserver:_delegate
+ selector:@selector(splitViewWillResizeSubviews:)
+ name:CPSplitViewWillResizeSubviewsNotification
+ object:self];
+}
+
+- (void)_postNotificationWillResize
+{
+ [[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewWillResizeSubviewsNotification object:self];
+}
+
+- (void)_postNotificationDidResize
+{
+ [[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewDidResizeSubviewsNotification object:self];
+}
+
+@end
+
+// FIXME: once +initialize is fixed for superclasses, remove this and uncomment +initialize
+var bundle = [CPBundle bundleForClass:CPSplitView];
+CPSplitViewHorizontalImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSplitView/CPSplitViewHorizontal.png"] size:CPSizeMake(5.0, 10.0)];
+CPSplitViewVerticalImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSplitView/CPSplitViewVertical.png"] size:CPSizeMake(10.0, 5.0)];
diff --git a/AppKit/CPTextField.j b/AppKit/CPTextField.j
index 2737de94a..900015de8 100644
--- a/AppKit/CPTextField.j
+++ b/AppKit/CPTextField.j
@@ -432,23 +432,28 @@ var _CPTextFieldSquareBezelColor = nil;
return [[self class] _inputElement].value;
#endif
- return [_value string];
+ return [self stringValue];
}
/*
- Sets the string the text field.
+ @ignore
*/
-- (void)setStringValue:(CPString)aStringValue
+- (void)setObjectValue:(id)aValue
{
- _value = aStringValue;
+ [super setObjectValue:aValue];
#if PLATFORM(DOM)
- var cssString = _value ? [_value cssString] : @"";
+ var displayString = "";
+
+ if (aValue && [aValue respondsToSelector:@selector(string)])
+ displayString = [aValue string];
+ else if (aValue)
+ displayString += aValue;
if (CPFeatureIsCompatible(CPJavascriptInnerTextFeature))
- _DOMTextElement.innerText = cssString;
+ _DOMTextElement.innerText = displayString;
else if (CPFeatureIsCompatible(CPJavascriptTextContentFeature))
- _DOMTextElement.textContent = cssString;
+ _DOMTextElement.textContent = displayString;
#endif
}
@@ -468,7 +473,8 @@ var _CPTextFieldSquareBezelColor = nil;
var CPTextFieldIsSelectableKey = @"CPTextFieldIsSelectableKey",
CPTextFieldLineBreakModeKey = @"CPTextFieldLineBreakModeKey",
- CPTextFieldStringValueKey = @"CPTextFieldStringValueKey";
+ CPTextFieldStringValueKey = @"CPTextFieldStringValueKey",
+ CPTextFieldIsEditableKey = @"CPTextFieldIsEditableKey";
@implementation CPTextField (CPCoding)
@@ -503,6 +509,7 @@ var CPTextFieldIsSelectableKey = @"CPTextFieldIsSelectableKey",
_DOMElement.appendChild(_DOMTextElement);
#endif
+ [self setEditable:[aCoder decodeBoolForKey:CPTextFieldIsEditableKey]];
[self setSelectable:[aCoder decodeBoolForKey:CPTextFieldIsSelectableKey]];
[self setLineBreakMode:[aCoder decodeIntForKey:CPTextFieldLineBreakModeKey]];
@@ -526,6 +533,8 @@ var CPTextFieldIsSelectableKey = @"CPTextFieldIsSelectableKey",
[aCoder encodeInt:_lineBreakMode forKey:CPTextFieldLineBreakModeKey];
[aCoder encodeObject:_value forKey:CPTextFieldStringValueKey];
+
+ [aCoder encodeBool:_isEditable forKey:CPTextFieldIsEditableKey];
}
@end
diff --git a/AppKit/CPToolbar.j b/AppKit/CPToolbar.j
index 41fd31005..dc3c112c9 100644
--- a/AppKit/CPToolbar.j
+++ b/AppKit/CPToolbar.j
@@ -373,6 +373,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
[self setBackgroundColor:_CPToolbarViewBackgroundColor];
_additionalItemsButton = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 10.0, 15.0) pullsDown:YES];
+ [_additionalItemsButton setBordered:NO];
[_additionalItemsButton setImagePosition:CPImageOnly];
[[_additionalItemsButton menu] setShowsStateColumn:NO];
diff --git a/AppKit/CPView.j b/AppKit/CPView.j
index 05aedecc4..1fe0de2e2 100644
--- a/AppKit/CPView.j
+++ b/AppKit/CPView.j
@@ -1684,13 +1684,14 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
_DOMElement = DOMElementPrototype.cloneNode(false);
#endif
+ // Also decode these "early".
+ _frame = [aCoder decodeRectForKey:CPViewFrameKey];
+ _bounds = [aCoder decodeRectForKey:CPViewBoundsKey];
+
self = [super initWithCoder:aCoder];
if (self)
{
- _frame = [aCoder decodeRectForKey:CPViewFrameKey];
- _bounds = [aCoder decodeRectForKey:CPViewBoundsKey];
-
_window = [aCoder decodeObjectForKey:CPViewWindowKey];
_subviews = [aCoder decodeObjectForKey:CPViewSubviewsKey];
_superview = [aCoder decodeObjectForKey:CPViewSuperviewKey];
@@ -1716,6 +1717,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
for (; index < count; ++index)
{
CPDOMDisplayServerAppendChild(_DOMElement, _subviews[index]._DOMElement);
+ //_subviews[index]._superview = self;
}
#endif
_displayHash = [self hash];
diff --git a/AppKit/CPWindow.j b/AppKit/CPWindow.j
index 0383b0cd9..fedddb16d 100644
--- a/AppKit/CPWindow.j
+++ b/AppKit/CPWindow.j
@@ -269,7 +269,9 @@ var CPWindowSaveImage = nil,
CPURL _representedURL;
// Bridge Support
+#if PLATFORM(DOM)
DOMElement _DOMElement;
+#endif
CPDOMWindowBridge _bridge;
unsigned _autoresizingMask;
@@ -364,7 +366,8 @@ CPTexturedBackgroundWindowMask
[self setContentView:[[CPView alloc] initWithFrame:CGRectMakeZero()]];
_firstResponder = self;
-
+
+#if PLATFORM(DOM)
_DOMElement = document.createElement("div");
_DOMElement.style.position = "absolute";
@@ -375,7 +378,8 @@ CPTexturedBackgroundWindowMask
CPDOMDisplayServerSetStyleSize(_DOMElement, 1, 1);
CPDOMDisplayServerAppendChild(_DOMElement, _windowView._DOMElement);
-
+#endif
+
[self setBridge:aBridge];
[self setNextResponder:CPApp];
@@ -854,12 +858,15 @@ CPTexturedBackgroundWindowMask
[_shadowView setBackgroundColor:_CPWindowShadowColor];
[_shadowView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
+#if PLATFORM(DOM)
CPDOMDisplayServerInsertBefore(_DOMElement, _shadowView._DOMElement, _windowView._DOMElement);
+#endif
}
else
{
+#if PLATFORM(DOM)
CPDOMDisplayServerRemoveChild(_DOMElement, _shadowView._DOMElement);
-
+#endif
_shadowView = nil;
}
}
diff --git a/AppKit/Cib/CPCib.j b/AppKit/Cib/CPCib.j
index e535eaa78..be630aedb 100644
--- a/AppKit/Cib/CPCib.j
+++ b/AppKit/Cib/CPCib.j
@@ -25,8 +25,9 @@ import
import
import "CPCustomView.j"
+import "_CPCibCustomObject.j"
import "_CPCibObjectData.j"
-
+import "_CPCibWindowTemplate.j"
CPCibOwner = @"CPCibOwner",
CPCibTopLevelObjects = @"CPCibTopLevelObjects";
@@ -56,20 +57,10 @@ var CPCibObjectDataKey = @"CPCibObjectDataKey";
if (!objectData || ![objectData isKindOfClass:[_CPCibObjectData class]])
return NO;
+ [objectData establishConnectionsWithExternalNameTable:anExternalNameTable];
+
var owner = [anExternalNameTable objectForKey:CPCibOwner],
topLevelObjects = [anExternalNameTable objectForKey:CPCibTopLevelObjects];
-
- var objects = unarchiver._objects,
- count = [objects count];
-
- // The order in which objects receive the awakeFromCib message is not guaranteed.
- while (count--)
- {
- var object = objects[count];
-
- if ([object isMemberOfClass:[CPView class]])
- return object;
- }
/*
// [objectData establishConnectionsWithOwner:owner topLevelObjects:topLevelObjects];
// [objectData cibInstantiateWithOwner:owner topLevelObjects:topLevelObjects];
diff --git a/AppKit/Cib/CPCustomView.j b/AppKit/Cib/CPCustomView.j
index c873b2783..e1755d2b5 100644
--- a/AppKit/Cib/CPCustomView.j
+++ b/AppKit/Cib/CPCustomView.j
@@ -1,5 +1,5 @@
/*
- * CPCustomView.j
+ * _CPCibCustomView.j
* AppKit
*
* Created by Francisco Tolmasky.
@@ -36,33 +36,35 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
/* @ignore */
-@implementation CPCustomView : CPView
+@implementation _CPCibCustomView : CPView
{
CPString _className;
}
@end
-var CPCustomViewClassNameKey = @"CPCustomViewClassNameKey";
+var _CPCibCustomViewClassNameKey = @"_CPCibCustomViewClassNameKey";
-@implementation CPCustomView (CPCoding)
+@implementation _CPCibCustomView (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
- _className = [aCoder decodeObjectForKey:CPCustomViewClassNameKey];
+ _className = [aCoder decodeObjectForKey:_CPCibCustomViewClassNameKey];
var theClass = CPClassFromString(_className);
// If we don't have this class, just use CPView.
// FIXME: Should we instead throw an exception?
if (!theClass)
+ {
+ CPLog("Unknown class \"" + _className + "\" in cib file, using CPView instead.");
+
theClass = [CPView class];
+ }
var frame = [aCoder decodeRectForKey:CPViewFrameKey];
- // If this is just a "CPView", don't bother with any funny business, just go ahead and create it with initWithCoder:
- if (theClass == [CPView class])
- self = [[CPView alloc] initWithFrame:frame];
+ self = [[CPView alloc] initWithFrame:frame];
if (self)
{
@@ -75,9 +77,8 @@ var CPCustomViewClassNameKey = @"CPCustomViewClassNameKey";
for (; index < count; ++index)
{
- // This is a bogus superview "CPCustomView".
+ // This is a bogus superview "_CPCibCustomView".
subviews[index]._superview = nil;
-
[self addSubview:subviews[index]];
}
diff --git a/AppKit/Cib/_CPCibConnector.j b/AppKit/Cib/_CPCibConnector.j
new file mode 100644
index 000000000..21225891e
--- /dev/null
+++ b/AppKit/Cib/_CPCibConnector.j
@@ -0,0 +1,112 @@
+
+import
+import
+
+
+var _CPCibConnectorSourceKey = @"_CPCibConnectorSourceKey",
+ _CPCibConnectorDestinationKey = @"_CPCibConnectorDestinationKey",
+ _CPCibConnectorLabelKey = @"_CPCibConnectorLabelKey";
+
+@implementation _CPCibConnector : CPObject
+{
+ id _source;
+ id _destination;
+ CPString _label;
+}
+
+- (void)replaceObject:(id)anObject withObject:(id)anotherObject
+{
+ if (_source == anObject)
+ _source = anotherObject;
+
+ else if (_destination == anObject)
+ _destination = anotherObject;
+}
+
+@end
+
+@implementation _CPCibConnector (CPCoding)
+
+- (id)initWithCoder:(CPCoder)aCoder
+{
+ self = [super init];
+
+ if (self)
+ {
+ _source = [aCoder decodeObjectForKey:_CPCibConnectorSourceKey];
+ _destination = [aCoder decodeObjectForKey:_CPCibConnectorDestinationKey];
+ _label = [aCoder decodeObjectForKey:_CPCibConnectorLabelKey];
+
+#if DEBUG
+ CPLog("Connection from " + [_source description] + " to " + [_destination description] + " and label " + _label + " decoded.");
+#endif
+ }
+
+ return self;
+}
+
+- (void)encodeWithCoder:(CPCoder)aCoder
+{
+ [aCoder encodeObject:_source forKey:_CPCibConnectorSourceKey];
+ [aCoder encodeObject:_destination forKey:_CPCibConnectorDestinationKey];
+ [aCoder encodeObject:_label forKey:_CPCibConnectorLabelKey];
+}
+
+@end
+
+@implementation _CPCibControlConnector : _CPCibConnector
+{
+}
+
+- (void)establishConnection
+{
+#if DEBUG
+ CPLog('[' + [_source description] + " setTarget: " + [_destination description] + ']');
+ CPLog('[' + [_source description] + " setAction: " + _label + ']');
+#endif
+
+ var selectorName = _label;
+
+ if (![selectorName hasSuffix:@":"])
+ selectorName += ':';
+
+ var selector = CPSelectorFromString(selectorName);
+
+ if (!selector)
+ [CPException
+ raise:CPInvalidArgumentException
+ reason:@"-[" + [self className] + ' ' + _cmd + @"] selector " + selectorName + @" does not exist."];
+
+ if ([_source respondsToSelector:@selector(setAction:)])
+ objj_msgSend(_source, @selector(setAction:), selector);
+
+ else
+ [CPException
+ raise:CPInvalidArgumentException
+ reason:@"-[" + [self className] + ' ' + _cmd + @"] " + [_source description] + " does not respond to setAction:"];
+
+ if ([_source respondsToSelector:@selector(setTarget:)])
+ objj_msgSend(_source, @selector(setTarget:), _destination);
+
+ else
+ [CPException
+ raise:CPInvalidArgumentException
+ reason:@"-[" + [self className] + ' ' + _cmd + @"] " + [_source description] + " does not respond to setTarget:"];
+}
+
+@end
+
+@implementation _CPCibOutletConnector : _CPCibConnector
+{
+}
+
+- (void)establishConnection
+{
+#if DEBUG
+ CPLog([_source description] + " setValue: " + [_destination description] + " forKey: " + _label);
+#endif
+
+ [_source setValue:_destination forKey:_label];
+}
+
+@end
diff --git a/AppKit/Cib/_CPCibCustomObject.j b/AppKit/Cib/_CPCibCustomObject.j
new file mode 100644
index 000000000..56b633c9a
--- /dev/null
+++ b/AppKit/Cib/_CPCibCustomObject.j
@@ -0,0 +1,41 @@
+
+import
+
+
+var _CPCibCustomObjectClassName = @"_CPCibCustomObjectClassName";
+
+@implementation _CPCibCustomObject : CPObject
+{
+ CPString _className;
+}
+
+@end
+
+@implementation _CPCibCustomObject (CPCoding)
+
+- (id)initWithCoder:(CPCoder)aCoder
+{
+ self = [super init];
+
+ if (self)
+ _className = [aCoder decodeObjectForKey:_CPCibCustomObjectClassName];
+
+ return self;
+}
+
+- (void)encodeWithCoder:(CPCoder)aCoder
+{
+ [aCoder encodeObject:_className forKey:_CPCibCustomObjectClassName];
+}
+
+- (id)awakeAfterUsingCoder:(CPCoder)aCoder
+{
+ var theClass = CPClassFromString(_className);
+
+ if (!theClass)
+ CPLog("Unknown class \"" + _className + "\" in cib file");
+
+ return [[theClass alloc] init];
+}
+
+@end
diff --git a/AppKit/Cib/_CPCibObjectData.j b/AppKit/Cib/_CPCibObjectData.j
index 53cad72d3..0e43193ab 100644
--- a/AppKit/Cib/_CPCibObjectData.j
+++ b/AppKit/Cib/_CPCibObjectData.j
@@ -24,36 +24,39 @@ import
import
import
+import "CPCib.j"
+import "_CPCibConnector.j"
+
@implementation _CPCibObjectData : CPObject
{
- CPArray _namesKeys;
- CPArray _namesValues;
+ CPArray _namesKeys;
+ CPArray _namesValues;
- CPArray _accessibilityConnectors;
- CPArray _accessibilityOidsKeys;
- CPArray _accessibilityOidsValues;
+ CPArray _accessibilityConnectors;
+ CPArray _accessibilityOidsKeys;
+ CPArray _accessibilityOidsValues;
- CPArray _classesKeys;
- CPArray _classesValues;
+ CPArray _classesKeys;
+ CPArray _classesValues;
- CPArray _connections;
+ CPArray _connections;
- id _fontManager;
+ id _fontManager;
- CPString _framework;
+ CPString _framework;
- int _nextOid;
+ int _nextOid;
- CPArray _objectsKeys;
- CPArray _objectsValues;
+ CPArray _objectsKeys;
+ CPArray _objectsValues;
- CPArray _oidKeys;
- CPArray _oidValues;
+ CPArray _oidKeys;
+ CPArray _oidValues;
- CPCustomObject _rootObject;
+ _CPCibCustomObject _fileOwner;
- CPSet _visibleWindows;
+ CPSet _visibleWindows;
}
/*
- (CPArray)topLevelObjects
@@ -103,7 +106,7 @@ var _CPCibObjectDataNamesKeysKey = @"_CPCibObjectDataNamesKeysKey
_CPCibObjectDataOidKeysKey = @"_CPCibObjectDataOidKeysKey",
_CPCibObjectDataOidValuesKey = @"_CPCibObjectDataOidValuesKey",
- _CPCibObjectDataRootObjectKey = @"_CPCibObjectDataRootObjectKey",
+ _CPCibObjectDataFileOwnerKey = @"_CPCibObjectDataFileOwnerKey",
_CPCibObjectDataVisibleWindowsKey = @"_CPCibObjectDataVisibleWindowsKey";
@implementation _CPCibObjectData (CPCoding)
@@ -125,7 +128,6 @@ var _CPCibObjectDataNamesKeysKey = @"_CPCibObjectDataNamesKeysKey
_classesValues = [aCoder decodeObjectForKey:_CPCibObjectDataClassesValuesKey];
_connections = [aCoder decodeObjectForKey:_CPCibObjectDataConnectionsKey];
-
//id _fontManager;
_framework = [aCoder decodeObjectForKey:_CPCibObjectDataFrameworkKey];
@@ -138,7 +140,7 @@ var _CPCibObjectDataNamesKeysKey = @"_CPCibObjectDataNamesKeysKey
_oidKeys = [aCoder decodeObjectForKey:_CPCibObjectDataOidKeysKey];
_oidValues = [aCoder decodeObjectForKey:_CPCibObjectDataOidValuesKey];
- _rootObject = [aCoder decodeObjectForKey:_CPCibObjectDataRootObjectKey];
+ _fileOwner = [aCoder decodeObjectForKey:_CPCibObjectDataFileOwnerKey];
// CPSet _visibleWindows;
}
@@ -172,10 +174,25 @@ var _CPCibObjectDataNamesKeysKey = @"_CPCibObjectDataNamesKeysKey
[aCoder encodeObject:_oidKeys forKey:_CPCibObjectDataOidKeysKey];
[aCoder encodeObject:_oidValues forKey:_CPCibObjectDataOidValuesKey];
- [aCoder encodeObject:_rootObject forKey:_CPCibObjectDataRootObjectKey];
+ [aCoder encodeObject:_fileOwner forKey:_CPCibObjectDataFileOwnerKey];
// CPCustomObject _fileOwner;
// CPSet _visibleWindows;
}
+- (void)establishConnectionsWithExternalNameTable:(CPDictionary)anExternalNameTable
+{
+ var index = 0,
+ count = _connections.length,
+ cibOwner = [anExternalNameTable objectForKey:CPCibOwner];
+
+ for (; index < count; ++index)
+ {
+ var connection = _connections[index];
+
+ [connection replaceObject:_fileOwner withObject:cibOwner];
+ [connection establishConnection];
+ }
+}
+
@end
diff --git a/AppKit/Cib/_CPCibWindowTemplate.j b/AppKit/Cib/_CPCibWindowTemplate.j
new file mode 100644
index 000000000..7147656aa
--- /dev/null
+++ b/AppKit/Cib/_CPCibWindowTemplate.j
@@ -0,0 +1,97 @@
+
+import
+
+
+var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeKey",
+ _CPCibWindowTemplateMaxSizeKey = @"_CPCibWindowTemplateMaxSizeKey",
+
+ _CPCibWindowTemplateViewClassKey = @"_CPCibWindowTemplateWindowClassKey",
+
+ _CPCibWindowTemplateWindowRectKey = @"_CPCibWindowTemplateWindowRectKey",
+ _CPCibWindowTemplateWindowStyleMaskKey = @"_CPCibWindowTempatStyleMaskKey",
+ _CPCibWindowTemplateWindowTitleKey = @"_CPCibWindowTemplateWindowTitleKey",
+ _CPCibWindowTemplateWindowViewKey = @"_CPCibWindowTemplateWindowViewKey";
+
+@implementation _CPCibWindowTemplate : CPObject
+{
+ CGSize _minSize;
+ CGSize _maxSize;
+ //CGSize _screenRect;
+
+ CPString _viewClass;
+ //unsigned _wtFlags;
+ CPString _windowClass;
+ CGRect _windowRect;
+ unsigned _windowStyleMask;
+
+ CPString _windowTitle;
+ CPView _windowView;
+}
+
+- (id)initWithCoder:(CPCoder)aCoder
+{
+ self = [super init];
+
+ if (self)
+ {
+ _minSize = [aCoder decodeSizeForKey:_CPCibWindowTemplateMinSizeKey];
+ _maxSize = [aCoder decodeSizeForKey:_CPCibWindowTemplateMaxSizeKey];
+
+ _viewClass = [aCoder decodeObjectForKey:_CPCibWindowTemplateViewClassKey];
+
+ _windowClass = [aCoder decodeObjectForKey:_CPCibWindowTemplateViewClassKey];
+ _windowRect = [aCoder decodeRectForKey:_CPCibWindowTemplateWindowRectKey];
+ _windowStyleMask = [aCoder decodeIntForKey:_CPCibWindowTemplateWindowStyleMaskKey];
+
+ _windowTitle = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowTitleKey];
+ _windowView = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowViewKey];
+ }
+
+ return self;
+}
+
+- (void)encodeWithCoder:(CPCoder)aCoder
+{
+ [aCoder encodeSize:_minSize forKey:_CPCibWindowTemplateMinSizeKey];
+ [aCoder encodeSize:_maxSize forKey:_CPCibWindowTemplateMaxSizeKey];
+
+ [aCoder encodeObject:_viewClass forKey:_CPCibWindowTemplateViewClassKey];
+
+ [aCoder encodeObject:_windowClass forKey:_CPCibWindowTemplateViewClassKey];
+ [aCoder encodeRect:_windowRect forKey:_CPCibWindowTemplateWindowRectKey];
+ [aCoder encodeInt:_windowStyleMask forKey:_CPCibWindowTemplateWindowStyleMaskKey];
+
+ [aCoder encodeObject:_windowTitle forKey:_CPCibWindowTemplateWindowTitleKey];
+ [aCoder encodeObject:_windowView forKey:_CPCibWindowTemplateWindowViewKey];
+}
+
+- (id)awakeAfterUsingCoder:(CPCoder)aCoder
+{
+ var windowClass = CPClassFromString(_windowClass);
+
+/* if (!windowClass)
+ [NSException raise:NSInvalidArgumentException format:@"Unable to locate NSWindow class %@, using NSWindow",_windowClass];
+ class=[NSWindow class];*/
+
+ var theWindow = [[windowClass alloc] initWithContentRect:_windowRect styleMask:CPHUDBackgroundWindowMask | CPClosableWindowMask];//styleMask:_windowStyleMask];
+// alert(CPStringFromRect(_windowRect));
+// alert(CPStringFromSize(_minSize));
+// alert(CPStringFromSize(_maxSize));
+ //[theWindow setMinSize:_minSize];
+ //[theWindow setMaxSize:_maxSize];
+ [theWindow setLevel:CPFloatingWindowLevel];
+
+ //[result setHidesOnDeactivate:(_wtFlags&0x80000000)?YES:NO];
+ [theWindow setTitle:_windowTitle];
+
+ // FIXME: we can't autoresize yet...
+ [_windowView setAutoresizesSubviews:NO];
+
+ [theWindow setContentView:_windowView];
+
+ [_windowView setAutoresizesSubviews:YES];
+
+ return theWindow;
+}
+
+@end
diff --git a/AppKit/Resources/CPSplitView/CPSplitViewHorizontal.png b/AppKit/Resources/CPSplitView/CPSplitViewHorizontal.png
new file mode 100644
index 000000000..e144e9b31
Binary files /dev/null and b/AppKit/Resources/CPSplitView/CPSplitViewHorizontal.png differ
diff --git a/AppKit/Resources/CPSplitView/CPSplitViewVertical.png b/AppKit/Resources/CPSplitView/CPSplitViewVertical.png
new file mode 100644
index 000000000..2dd8973d3
Binary files /dev/null and b/AppKit/Resources/CPSplitView/CPSplitViewVertical.png differ
diff --git a/Foundation/CPJSONPConnection.j b/Foundation/CPJSONPConnection.j
index 521b6661b..0f529d39b 100644
--- a/Foundation/CPJSONPConnection.j
+++ b/Foundation/CPJSONPConnection.j
@@ -56,6 +56,8 @@ CPJSONPConnectionCallbacks = {};
{
[_delegate connection:self didReceiveData:data];
[self removeScriptTag];
+
+ [[CPRunLoop currentRunLoop] performSelectors];
};
if(shouldStartImmediately)
diff --git a/Foundation/CPKeyValueCoding.j b/Foundation/CPKeyValueCoding.j
index d0cdbbd13..d825acabd 100644
--- a/Foundation/CPKeyValueCoding.j
+++ b/Foundation/CPKeyValueCoding.j
@@ -22,7 +22,15 @@
import "CPObject.j"
-@implementation CPObject(CPKeyValueCoding)
+
+var CPObjectAccessorsForClass = nil,
+ CPObjectModifiersForClass = nil;
+
+CPUndefinedKeyException = @"CPUndefinedKeyException";
+CPTargetObjectUserInfoKey = @"CPTargetObjectUserInfoKey";
+CPUnknownUserInfoKey = @"CPUnknownUserInfoKey";
+
+@implementation CPObject (CPKeyValueCoding)
+ (BOOL)accessInstanceVariablesDirectly
{
@@ -32,14 +40,42 @@ import "CPObject.j"
/* @ignore */
+ (SEL)_accessorForKey:(CPString)aKey
{
- var capitalizedKey = aKey.charAt(0).toUpperCase() + aKey.substr(1),
- selector = CPSelectorFromString("get" + capitalizedKey);
+ if (!CPObjectAccessorsForClass)
+ CPObjectAccessorsForClass = [CPDictionary dictionary];
- if ([self instancesRespondToSelector:selector] ||
+ var hash = [isa hash],
+ selector = nil,
+ accessors = [CPObjectAccessorsForClass objectForKey:hash];
+
+ if (accessors)
+ {
+ selector = [accessors objectForKey:aKey];
+
+ if (selector)
+ return selector == [CPNull null] ? nil : selector;
+ }
+ else
+ {
+ accessors = [CPDictionary dictionary];
+
+ [CPObjectAccessorsForClass setObject:accessors forKey:hash];
+ }
+
+ var capitalizedKey = aKey.charAt(0).toUpperCase() + aKey.substr(1);
+
+ if ([self instancesRespondToSelector:selector = CPSelectorFromString("get" + capitalizedKey)] ||
[self instancesRespondToSelector:selector = CPSelectorFromString(aKey)] ||
- [self instancesRespondToSelector:selector = CPSelectorFromString("_"+aKey)] ||
- [self instancesRespondToSelector:selector = CPSelectorFromString("is" + capitalizedKey)])
+ [self instancesRespondToSelector:selector = CPSelectorFromString("is" + capitalizedKey)] ||
+ [self instancesRespondToSelector:selector = CPSelectorFromString("_get" + capitalizedKey)] ||
+ [self instancesRespondToSelector:selector = CPSelectorFromString("_" + aKey)] ||
+ [self instancesRespondToSelector:selector = CPSelectorFromString("_is" + capitalizedKey)])
+ {
+ [accessors setObject:selector forKey:aKey];
+
return selector;
+ }
+
+ [accessors setObject:[CPNull null] forKey:aKey];
return nil;
}
@@ -47,22 +83,68 @@ import "CPObject.j"
/* @ignore */
+ (SEL)_modifierForKey:(CPString)aKey
{
- var selector = CPSelectorFromString("set" + aKey.charAt(0).toUpperCase() + aKey.substr(1) + ':');
+ if (!CPObjectModifiersForClass)
+ CPObjectModifiersForClass = [CPDictionary dictionary];
+
+ var hash = [isa hash],
+ selector = nil,
+ modifiers = [CPObjectModifiersForClass objectForKey:hash];
+
+ if (modifiers)
+ {
+ selector = [modifiers objectForKey:aKey];
+
+ if (selector)
+ return selector == [CPNull null] ? nil : selector;
+ }
+ else
+ {
+ modifiers = [CPDictionary dictionary];
+
+ [CPObjectModifiersForClass setObject:modifiers forKey:hash];
+ }
+
+ if (selector)
+ return selector == [CPNull null] ? nil : selector;
- if ([self instancesRespondToSelector:selector])
+ var capitalizedKey = aKey.charAt(0).toUpperCase() + aKey.substr(1) + ':';
+
+ if ([self instancesRespondToSelector:selector = CPSelectorFromString("set" + capitalizedKey)] ||
+ [self instancesRespondToSelector:selector = CPSelectorFromString("_set" + capitalizedKey)])
+ {
+ [modifiers setObject:selector forKey:aKey];
+
return selector;
-
+ }
+
+ [modifiers setObject:[CPNull null] forKey:aKey];
+
return nil;
}
/* @ignore */
- (CPString)_ivarForKey:(CPString)aKey
{
- var ivar,
- isKey = "is" + aKey.charAt(0).toUpperCase() + aKey.substr(1);
+ var ivar = '_' + aKey;
+
+ if (typeof self[ivar] != "undefined")
+ return ivar;
- if (self[ivar = "_" + aKey] != undefined || self[ivar = "_" + isKey] != undefined ||
- self[ivar = aKey] != undefined || self[ivar = isKey] != undefined) ;
+ var isKey = "is" + aKey.charAt(0).toUpperCase() + aKey.substr(1);
+
+ ivar = '_' + isKey;
+
+ if (typeof self[ivar] != "undefined")
+ return ivar;
+
+ ivar = aKey;
+
+ if (typeof self[ivar] != "undefined")
+ return ivar;
+
+ ivar = isKey;
+
+ if (typeof self[ivar] != "undefined")
return ivar;
return nil;
@@ -70,35 +152,62 @@ import "CPObject.j"
- (id)valueForKey:(CPString)aKey
{
- var ivar,
- theClass = [self class],
- selector = [theClass _accessorForKey:aKey]
+ var selector = [isa _accessorForKey:aKey];
if (selector)
- return [self performSelector:selector];
- else if([theClass accessInstanceVariablesDirectly] && (ivar = [self _ivarForKey:aKey]))
- return self[ivar];
- else
- return [self valueForUndefinedKey:aKey];
+ return objj_msgSend(self, selector);
+
+ if([isa accessInstanceVariablesDirectly])
+ {
+ var ivar = [self _ivarForKey:aKey];
+
+ if (ivar)
+ return self[ivar];
+ }
+
+ return [self valueForUndefinedKey:aKey];
}
- (id)valueForKeyPath:(CPString)aKeyPath
{
- var i = 0,
- keys = aKeyPath.split("."),
+ var keys = aKeyPath.split("."),
+
+ index = 0,
count = keys.length,
+
value = self;
- for(; i valueForKey()]: this class is not key value coding-compliant for the key "+aKey+".]");
+ [[CPException exceptionWithName:CPUndefinedKeyException
+ reason:[self description] + " is not key value coding-compliant for the key " + aKey
+ userInfo:[CPDictionary dictionaryWithObjects:[self, aKey] forKeys:[CPTargetObjectUserInfoKey, CPUnknownUserInfoKey]]] raise];
}
- (void)setValue:(id)aValue forKeyPath:(CPString)aKeyPath
@@ -118,22 +227,35 @@ import "CPObject.j"
- (void)setValue:(id)aValue forKey:(CPString)aKey
{
- var ivar,
- theClass = [self class],
- selector = [theClass _modifierForKey:aKey];
+ var selector = [isa _modifierForKey:aKey];
if (selector)
- [self performSelector:selector withObject:aValue];
- else if([theClass accessInstanceVariablesDirectly] && (ivar = [self _ivarForKey:aKey]))
- self[ivar] = aValue;
- else
- [self setValue:aValue forUndefinedKey:aKey];
+ return objj_msgSend(self, selector, aValue);
+
+ if([isa accessInstanceVariablesDirectly])
+ {
+ var ivar = [self _ivarForKey:aKey];
+
+ if (ivar)
+ {
+ [self willChangeValueForKey:aKey];
+
+ self[ivar] = aValue;
+
+ [self didChangeValueForKey:aKey];
+ }
+
+ return;
+ }
+
+ [self setValue:aValue forUndefinedKey:aKey];
}
- (void)setValue:(id)aValue forUndefinedKey:(CPString)aKey
{
- alert("IMPLEMENT EXCEPTIONS, also, setValueForKey died.");
-// CPException.raise(CPUndefinedKeyException, "[<"+this.className()+" "+this+"> setValueForKey()]: this class is not key value coding-compliant for the key "+aKey+".]");
+ [[CPException exceptionWithName:CPUndefinedKeyException
+ reason:[self description] + " is not key value coding-compliant for the key " + aKey
+ userInfo:[CPDictionary dictionaryWithObjects:[self, aKey] forKeys:[CPTargetObjectUserInfoKey, CPUnknownUserInfoKey]]] raise];
}
-@end
\ No newline at end of file
+@end
diff --git a/Foundation/CPKeyValueObserving.j b/Foundation/CPKeyValueObserving.j
new file mode 100644
index 000000000..ea1dc2818
--- /dev/null
+++ b/Foundation/CPKeyValueObserving.j
@@ -0,0 +1,39 @@
+/*
+ * CPKeyValueCoding.j
+ * Foundation
+ *
+ * Created by Francisco Tolmasky.
+ * Copyright 2008, 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 "CPObject.j"
+
+
+@implementation CPObject (KeyValueObserving)
+
+- (void)willChangeValueForKey:(CPString)aKey
+{
+
+}
+
+
+- (void)didChangeValueForKey:(CPString)aKey
+{
+
+}
+
+@end
\ No newline at end of file
diff --git a/Foundation/CPLog.j b/Foundation/CPLog.j
index 82d67a1d1..baea2eed1 100644
--- a/Foundation/CPLog.j
+++ b/Foundation/CPLog.j
@@ -2,7 +2,7 @@
* CPLog.j
* Foundation
*
- * Created by Francisco Tolmasky.
+ * Created by Thomas Robinson.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -34,8 +34,6 @@ for (var i = 0; i < CPLogLevels.length; i++)
var _CPLogRegistrations = {};
// helpers:
-var _randomInteger = function(max) { return Math.round(Math.random() * (typeof(max) != "undefined" ? max : (1 << 30))); }
-var _randomArrayElement = function(element) { return element[_randomInteger(element.length)]; }
var _CPFormatLogMessage = function(aString, aLevel, aTitle)
{
@@ -375,44 +373,11 @@ var _CPLogInitPopup = function(logWindow)
}, false);
}
-// CPLogServer sends log messages to the server
-//var _CPLogServerBatch = true;
-//var _CPLogServerSessionID = _randomInteger();
-//function CPLogServer(aString, aLevel, aTitle)
-//{
-// var entry = { title: aTitle, message: aString, level: aLevel, timestamp: new Date().getTime() }
-//
-// if (_CPLogServerBatch)
-// {
-// }
-// else
-// {
-//
-// }
-//}
-//
-//function _CPLogServerSubmit()
-//{
-//
-//}
-
-// Testing purposes:
-
-var lorem = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas fermentum, elit non lobortis cursus, orci velit suscipit est, id mollis turpis mi eget orci. Ut aliquam sollicitudin metus. Mauris at sapien sed sapien congue iaculis. Nulla lorem urna, bibendum id, laoreet iaculis, nonummy eget, massa. Phasellus ullamcorper commodo velit.";
-
-function CPLogTest(n) {
- for(var i=0;i
@implementation AppController : CPObject
{
+ CPWindow _window;
+ CPWindow _secondWindow;
+ CPView _view;
}
- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
var cib = [[CPCib alloc] initWithContentsOfURL:@"MainMenu.cib"],
- x = [cib instantiateCibWithExternalNameTable:nil];
-
- [x setBackgroundColor:[CPColor blueColor]];
-
- var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask],
+ theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask],
contentView = [theWindow contentView];
-
- [contentView addSubview:x];
-
+
+ [cib instantiateCibWithExternalNameTable:[CPDictionary dictionaryWithObject:self forKey:CPCibOwner]];
+
+ [_view setBackgroundColor:[CPColor blueColor]];
+
+ [contentView addSubview:_view];
[theWindow orderFront:self];
+
+ [_secondWindow orderFront:self];
}
@end
\ No newline at end of file
diff --git a/Tools/NibApp/HelloWorld.nib/classes.nib b/Tools/NibApp/HelloWorld.nib/classes.nib
index c4b887e72..01b9f29b9 100644
--- a/Tools/NibApp/HelloWorld.nib/classes.nib
+++ b/Tools/NibApp/HelloWorld.nib/classes.nib
@@ -2,6 +2,35 @@
+ IBClasses
+
+
+ CLASS
+ NSObject
+ LANGUAGE
+ ObjC
+ OUTLETS
+
+ window
+ id
+
+
+
+ CLASS
+ AppController
+ LANGUAGE
+ ObjC
+ OUTLETS
+
+ secondWindow
+ id
+ view
+ id
+ window
+ id
+
+
+
IBVersion
1
diff --git a/Tools/NibApp/HelloWorld.nib/info.nib b/Tools/NibApp/HelloWorld.nib/info.nib
index 2511941ff..b8f7650f5 100644
--- a/Tools/NibApp/HelloWorld.nib/info.nib
+++ b/Tools/NibApp/HelloWorld.nib/info.nib
@@ -7,11 +7,9 @@
IBOldestOS
5
IBOpenObjects
-
- 1
-
+
IBSystem Version
- 9E17
+ 9F33
targetFramework
IBCocoaFramework
diff --git a/Tools/NibApp/HelloWorld.nib/keyedobjects.nib b/Tools/NibApp/HelloWorld.nib/keyedobjects.nib
index f3853becd..3ad8add67 100644
Binary files a/Tools/NibApp/HelloWorld.nib/keyedobjects.nib and b/Tools/NibApp/HelloWorld.nib/keyedobjects.nib differ
diff --git a/Tools/NibApp/HelloWorld.xib b/Tools/NibApp/HelloWorld.xib
index 18b318598..206d50ba7 100644
--- a/Tools/NibApp/HelloWorld.xib
+++ b/Tools/NibApp/HelloWorld.xib
@@ -2,22 +2,23 @@
1050
- 9E17
+ 9F33
629
- 949.33
+ 949.34
352.00
- 11
+ 26
YES
+
+
+
+
+ YES
+
+ YES
+
+
+ YES
+
+
+
+ YES
+
+ YES
+
+
+
+
+ YES
+ id
+
+
+
+
+ IBUserSource
+
+
+
0
@@ -223,57 +448,90 @@
3
YnBsaXN0MDDUAAEAAgADAAQABQAGAAkAClgkdmVyc2lvblQkdG9wWSRhcmNoaXZlclgkb2JqZWN0cxIA
-AYag0QAHAAhdSUIub2JqZWN0ZGF0YYABXxAPTlNLZXllZEFyY2hpdmVyrxA/AAsADAAxADUANgA7ADwA
-QABEAEcASwBUAGwAbQB1AHYAeQCJAIoAjgCYAAsAmQCfALMAtgC3AL8AwgDHAMgAywALAJ0AzADPANIA
-0wDVAN4A6ADyAPMA9AD1APYA9wD4APkA/AD/AQkBEwEUARUBFgCrARcBGAEZARwBHwEiVSRudWxs3xAS
-AA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAq
-ACsALAAtAC4ALwAwVk5TUm9vdFYkY2xhc3NdTlNPYmplY3RzS2V5c18QD05TQ2xhc3Nlc1ZhbHVlc18Q
-GU5TQWNjZXNzaWJpbGl0eU9pZHNWYWx1ZXNdTlNDb25uZWN0aW9uc1tOU05hbWVzS2V5c1tOU0ZyYW1l
-d29ya11OU0NsYXNzZXNLZXlzWk5TT2lkc0tleXNdTlNOYW1lc1ZhbHVlc18QGU5TQWNjZXNzaWJpbGl0
-eUNvbm5lY3RvcnNdTlNGb250TWFuYWdlcl8QEE5TVmlzaWJsZVdpbmRvd3NfEA9OU09iamVjdHNWYWx1
-ZXNfEBdOU0FjY2Vzc2liaWxpdHlPaWRzS2V5c1lOU05leHRPaWRcTlNPaWRzVmFsdWVzgAKAPoAKgDGA
-PYAIgCeABYAwgDKAKIA7gACABoAmgDwQDYAz0gAOADIAMwA0W05TQ2xhc3NOYW1lgASAA1hOU09iamVj
-dNIANwA4ADkAOlgkY2xhc3Nlc1okY2xhc3NuYW1logA6ADVeTlNDdXN0b21PYmplY3RfEBBJQkNvY29h
-RnJhbWV3b3Jr0gAOAD0APgA/Wk5TLm9iamVjdHOAB6DSADcAOABBAEKjAEIAQwA1XE5TTXV0YWJsZVNl
-dFVOU1NldNIADgA9AEUARoAJoNIANwA4AEgASaMASQBKADVeTlNNdXRhYmxlQXJyYXlXTlNBcnJhedIA
-DgA9AEwATYAlpgBOAE8AUABRAFIAU4ALgBCAF4ATgBqAI9wAVQAOAFYAVwBYAFkAWgBbAFwAXQBeAF8A
-YABhAGIAYwBkAGIAZgBnAE8AaQBqAGtbTlNDZWxsRmxhZ3NfEBNOU0FsdGVybmF0ZUNvbnRlbnRzXxAS
-TlNQZXJpb2RpY0ludGVydmFsXk5TQnV0dG9uRmxhZ3MyXxAPTlNLZXlFcXVpdmFsZW50Wk5TQ29udGVu
-dHNZTlNTdXBwb3J0XU5TQ29udHJvbFZpZXdfEA9OU1BlcmlvZGljRGVsYXlcTlNDZWxsRmxhZ3MyXU5T
-QnV0dG9uRmxhZ3MT/////4QB/gCAEoAREEsQpIARgAyADYAQEQGQEggAAAAT/////4aEQP9fEBFSb3Vu
-ZCBSZWN0IEJ1dHRvbtQADgBuAG8AcABxAHIAcwB0Vk5TU2l6ZVZOU05hbWVYTlNmRmxhZ3OADyNAKAAA
-AAAAAIAOEBBcTHVjaWRhR3JhbmRl0gA3ADgAdwB4ogB4ADVWTlNGb2502AB6AA4AewB8AH0AfgB/AIAA
-UQCCAIMATgCFAIYAhwBRXxAPTlNOZXh0UmVzcG9uZGVyV05TRnJhbWVWTlNDZWxsWE5TdkZsYWdzWU5T
-RW5hYmxlZFhOU1dpbmRvd1tOU1N1cGVydmlld4ATgBaAFIALEQEMCYAVgBNQ0gA3ADgAiwCMpACMAI0A
-fAA1XE5TQnV0dG9uQ2VsbFxOU0FjdGlvbkNlbGzYAHoADgCPAH0AkAB/ADIAgACHAJIAkwCFAJQAhwCW
-AJdaTlNTdWJ2aWV3c1tOU0ZyYW1lU2l6ZYAVgCKAHIAfgBWAIYAgXxAXe3sxNTcsIDExMH0sIHsxNTQs
-IDE5fX3SADcAOACaAJulAJsAnACdAJ4ANVhOU0J1dHRvbllOU0NvbnRyb2xWTlNWaWV3W05TUmVzcG9u
-ZGVy3gCgAFUADgChAKIAWgBbAFwAowCkAF4ApQCmAKcAqABgAKkAqgCrAGIArQBSAK8AsACqALEAsACx
-V05TVmFsdWVfEBNOU051bWJlck9mVGlja01hcmtzXxASTlNUaWNrTWFya1Bvc2l0aW9uWk5TTWF4VmFs
-dWVaTlNNaW5WYWx1ZVpOU1ZlcnRpY2FsXU5TQWx0SW5jVmFsdWVfEBpOU0FsbG93c1RpY2tNYXJrVmFs
-dWVzT25seSNASQAAAAAAAIAbEAAQAYARgBiAGiNAWQAAAAAAACMAAAAAAAAAAAgI1AAOAG4AbwBwAHEA
-cgC1AHSAD4AZWUhlbHZldGljYdgAegAOAHsAfAB9AH4AfwCAAFEAuQC6AFAAhQCGAIcAUYATgB6AHYAX
-CYAVgBPSADcAOADAAMGkAMEAjQB8ADVcTlNTbGlkZXJDZWxs0gAOAD0ARQDEgAmiAE8AUoAQgBpfEBZ7
-ezM1OSwgMTA4fSwgezk2LCAyMX190gA3ADgAyQDKpQDKAJwAnQCeADVYTlNTbGlkZXJaezQ4MCwgMjcy
-fdIANwA4AM0AzqQAzgCdAJ4ANVxOU0N1c3RvbVZpZXfSAA4AMgAzANGABIAkXU5TQXBwbGljYXRpb27S
-ADcAOADUAEqiAEoANdIADgA9AEwA14AlpgBPAFEAUgAfAFEAH4AQgBOAGoACgBOAAtIADgA9AEwA4IAl
-pwBQAB8ATgBPAFEAUgBTgBeAAoALgBCAE4AagCPSAA4APQBMAOqAJacA6wDsAO0A7gDvAPAA8YApgCqA
-K4AsgC2ALoAvW1NsaWRlciBDZWxsXEZpbGUncyBPd25lcl8QH0J1dHRvbiBDZWxsIChSb3VuZCBSZWN0
-IEJ1dHRvbilfECVSb3VuZCBSZWN0IEJ1dHRvbiAoUm91bmQgUmVjdCBCdXR0b24pW0N1c3RvbSBWaWV3
-XxARSG9yaXpvbnRhbCBTbGlkZXJbQXBwbGljYXRpb27SAA4APQBMAPuAJaDSAA4APQBMAP6AJaDSAA4A
-PQBMAQGAJacAUAAfAE4ATwBRAFIAU4AXgAKAC4AQgBOAGoAj0gAOAD0ATAELgCWnAQwBDQEOAQ8BEAER
-ARKANIA1gDaAN4A4gDmAOhALEAwQCRAIEAoT//////////3SAA4APQBFARuACaDSAA4APQBMAR6AJaDS
-AA4APQBMASGAJaDSADcAOAEjASSiASQANV5OU0lCT2JqZWN0RGF0YQAIABkAIgAnADEAOgA/AEQAUgBU
-AGYA5wDtATgBPwFGAVQBZgGCAZABnAGoAbYBwQHPAesB+QIMAh4COAJCAk8CUQJTAlUCVwJZAlsCXQJf
-AmECYwJlAmcCaQJrAm0CbwJxAnMCfAKIAooCjAKVAp4CpwKyArcCxgLZAuIC7QLvAvAC+QMAAw0DEwMc
-Ax4DHwMoAy8DPgNGA08DUQNeA2ADYgNkA2YDaANqA5sDpwO9A9ID4QPzA/4ECAQWBCgENQRDBEwETgRQ
-BFIEVARWBFgEWgRcBF8EZARtBIEEkgSZBKAEqQSrBLQEtgS4BMUEzgTTBNoE+wUNBRUFHAUlBS8FOAVE
-BUYFSAVKBUwFTwVQBVIFVAVVBV4FZwV0BYEFogWtBbkFuwW9Bb8FwQXDBcUFxwXhBeoF9QX+BggGDwYb
-BlQGXAZyBocGkgadBqgGtgbTBtwG3gbgBuIG5AbmBugG8Qb6BvsG/AcNBw8HEQcbBzwHPgdAB0IHRAdF
-B0cHSQdSB1sHaAdxB3MHeAd6B3wHlQeeB6kHsge9B8YHzwfcB+UH5wfpB/cIAAgFCA4IEAgdCB8IIQgj
-CCUIJwgpCDIINAhDCEUIRwhJCEsITQhPCFEIWghcCGsIbQhvCHEIcwh1CHcIeQiFCJIItAjcCOgI/AkI
-CREJEwkUCR0JHwkgCSkJKwk6CTwJPglACUIJRAlGCUgJUQlTCWIJZAlmCWgJaglsCW4JcAlyCXQJdgl4
-CXoJgwmMCY4JjwmYCZoJmwmkCaYJpwmwCbUAAAAAAAACAgAAAAAAAAElAAAAAAAAAAAAAAAAAAAJxA
+AYag0QAHAAhdSUIub2JqZWN0ZGF0YYABXxAPTlNLZXllZEFyY2hpdmVyrxB2AAsADAAxADUANgA7ADwA
+QgBWAFcAWABZAGEAYgBmAGcAagBWAHIACwB7AIAAjACNAKUApgCuAK8AsgCzALcAuwDDAMQAywDMAGEA
+CwBmANAA1ADbAOMA5ADoAO0ACwD1APoBAgEDAMsBCgESARMBJwEqASsBLgExAAsAZAEyATUBNgE7ATwB
+PwFEAUUBVgFZAVoBXAFtAX8BkQGSAZMBlAGVAZYBlwGYAZkBmgGbAZwBnQGeAZ8BoAGjAaYBvAHSAdMB
+1AEfAdUB1gHXAdgB2QHaAdsB3ACtAd0B3gBUAd8B4AHhAeIB5QHoAetVJG51bGzfEBIADQAOAA8AEAAR
+ABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAv
+ADBWTlNSb290ViRjbGFzc11OU09iamVjdHNLZXlzXxAPTlNDbGFzc2VzVmFsdWVzXxAZTlNBY2Nlc3Np
+YmlsaXR5T2lkc1ZhbHVlc11OU0Nvbm5lY3Rpb25zW05TTmFtZXNLZXlzW05TRnJhbWV3b3JrXU5TQ2xh
+c3Nlc0tleXNaTlNPaWRzS2V5c11OU05hbWVzVmFsdWVzXxAZTlNBY2Nlc3NpYmlsaXR5Q29ubmVjdG9y
+c11OU0ZvbnRNYW5hZ2VyXxAQTlNWaXNpYmxlV2luZG93c18QD05TT2JqZWN0c1ZhbHVlc18QF05TQWNj
+ZXNzaWJpbGl0eU9pZHNLZXlzWU5TTmV4dE9pZFxOU09pZHNWYWx1ZXOAAoB1gEWAXIB0gCiASoAFgFuA
+XYBLgHKAAIAGgEmAcxAcgF7SAA4AMgAzADRbTlNDbGFzc05hbWWABIADWE5TT2JqZWN00gA3ADgAOQA6
+WCRjbGFzc2VzWiRjbGFzc25hbWWiADoANV5OU0N1c3RvbU9iamVjdF8QEElCQ29jb2FGcmFtZXdvcmvS
+AA4APQA+AD9aTlMub2JqZWN0c4AnogBAAEGAB4AQ2gBDAA4ARABFAEYARwBIAEkASgBLAEwATQBOAE8A
+UABRAFIAUwBUACtcTlNXaW5kb3dWaWV3XE5TU2NyZWVuUmVjdF1OU1dpbmRvd1RpdGxlWU5TV1RGbGFn
+c11OU1dpbmRvd0NsYXNzXE5TV2luZG93UmVjdF8QD05TV2luZG93QmFja2luZ18QEU5TV2luZG93U3R5
+bGVNYXNrW05TVmlld0NsYXNzgAuAD4AOgAkSJAAAAIAKgAgQAhAPgABfEBh7ezE5NiwgMjQwfSwgezQ4
+MCwgMjcwfX1WV2luZG93WE5TV2luZG931ABaAA4AWwBcACsAXgBfAGBfEA9OU05leHRSZXNwb25kZXJY
+TlN2RmxhZ3NbTlNGcmFtZVNpemWAAIANEQEAgAxaezQ4MCwgMjcwfdIANwA4AGMAZKMAZABlADVWTlNW
+aWV3W05TUmVzcG9uZGVyXxAWe3swLCAwfSwgezE2ODAsIDEwMjh9fdIANwA4AGgAaaIAaQA1XxAQTlNX
+aW5kb3dUZW1wbGF0ZdoAQwAOAEQARQBGAEcASABJAEoASwBrAE0AbQBPAFAAUQBwAFMAVAArgBKAD4Am
+gAmACoARgADXAFoADgBzAFsAXABYAHQAdQBeAHcAXwB4AHUAelpOU1N1YnZpZXdzW05TU3VwZXJ2aWV3
+gBOADYAUgCSAE4Al0gAOAD0AfAB9gCOiAH4Af4AVgB/YAFoADgCBAIIAWwCDAFgAdABrAIUAhgCHAIgA
+iQB1AGtXTlNGcmFtZVZOU0NlbGxZTlNFbmFibGVkgBKAHoAWgBcRAQwJgBOAEl8QF3t7MTQ1LCAxMTN9
+LCB7MTU0LCAxOX193ACOAA4AjwCQAJEAkgCTAJQAlQCWAJcAmACZAJoAmwCcAJ0AmwCfAKAAfgCiAKMA
+pFtOU0NlbGxGbGFnc18QE05TQWx0ZXJuYXRlQ29udGVudHNfEBJOU1BlcmlvZGljSW50ZXJ2YWxeTlNC
+dXR0b25GbGFnczJfEA9OU0tleUVxdWl2YWxlbnRaTlNDb250ZW50c1lOU1N1cHBvcnRdTlNDb250cm9s
+Vmlld18QD05TUGVyaW9kaWNEZWxheVxOU0NlbGxGbGFnczJdTlNCdXR0b25GbGFncxP/////hAH+AIAd
+gBwQSxCkgByAGIAZgBURAZASCAAAABP/////hoRA/1Z5aWtlcyHUAA4ApwCoAKkAqgCrAKwArVZOU1Np
+emVWTlNOYW1lWE5TZkZsYWdzgBsjQCgAAAAAAACAGhAQXEx1Y2lkYUdyYW5kZdIANwA4ALAAsaIAsQA1
+Vk5TRm9udFDSADcAOAC0ALWkALUAtgCCADVcTlNCdXR0b25DZWxsXE5TQWN0aW9uQ2VsbNIANwA4ALgA
+uaUAuQC6AGQAZQA1WE5TQnV0dG9uWU5TQ29udHJvbNgAWgAOAIEAggBbAIMAWAB0AGsAhQC+AL8AiACJ
+AHUAa4ASgB6AIIAhCYATgBJfEBV7ezAsIDI1MX0sIHsxNTQsIDE5fX3cAI4ADgCPAJAAkQCSAJMAlACV
+AJYAlwCYAJkAmgCbAJwAnQCbAMgAoAB/AKIAowCkgB2AHIAcgCKAGYAfXxARUm91bmQgUmVjdCBCdXR0
+b27SADcAOADNAM6jAM4AzwA1Xk5TTXV0YWJsZUFycmF5V05TQXJyYXnSADcAOADRANKjANIA0wA1XE5T
+TXV0YWJsZVNldFVOU1NldNIADgA9AHwA1oAjpADXANgA2QDagCmALIBAgEPUAA4A3ADdAN4A3wBBAB8A
+4l1OU0Rlc3RpbmF0aW9uWE5TU291cmNlV05TTGFiZWyAK4AQgAKAKlZ3aW5kb3fSADcAOADlAOajAOYA
+5wA1XxAUTlNOaWJPdXRsZXRDb25uZWN0b3JeTlNOaWJDb25uZWN0b3LUAA4A3ADdAN4A3wDqAB8A7IAr
+gC2AAoA/2ABaAA4AcwBbAFwAWAAyAHQA7gDvAPAAiADxAO4A8wD0gC6APoAvgDuALoA9gDzSAA4APQB8
+APeAI6IA+AD5gDCANNgAWgAOAIEAggBbAIMAWAB0AOoAhQD9AP4AiACJAO4A6oAtgB6AMYAyCYAugC1f
+EBd7ezE1NywgMTEwfSwgezE1NCwgMTl9fdwAjgAOAI8AkACRAJIAkwCUAJUAlgCXAJgAmQCaAJsAnACd
+AJsBBwCgAPgAogCjAKSAHYAcgByAM4AZgDDYAFoADgCBAIIAWwCDAFgAdADqAQwBDQEOAIgAiQDuAOqA
+LYA6gDWANgmALoAtXxAWe3szNTksIDEwOH0sIHs5NiwgMjF9fd4BFACOAA4BFQEWAJMAlACVARcBGACX
+ARkBGgEbARwAmQEdAR4BHwCbASEA+QEjASQBHgElASQBJVdOU1ZhbHVlXxATTlNOdW1iZXJPZlRpY2tN
+YXJrc18QEk5TVGlja01hcmtQb3NpdGlvblpOU01heFZhbHVlWk5TTWluVmFsdWVaTlNWZXJ0aWNhbF1O
+U0FsdEluY1ZhbHVlXxAaTlNBbGxvd3NUaWNrTWFya1ZhbHVlc09ubHkjQEkAAAAAAACAORAAEAGAHIA3
+gDQjQFkAAAAAAAAjAAAAAAAAAAAICNQADgCnAKgAqQCqAKsBKQCtgBuAOFlIZWx2ZXRpY2HSADcAOAEs
+AS2kAS0AtgCCADVcTlNTbGlkZXJDZWxs0gA3ADgBLwEwpQEwALoAZABlADVYTlNTbGlkZXJaezQ4MCwg
+MjcyfdIANwA4ATMBNKQBNABkAGUANVxOU0N1c3RvbVZpZXdUdmlld9QADgDcAN0A3gE3AEEAfgE6gEKA
+EIAVgEFZb3JkZXJPdXQ60gA3ADgBPQE+owE+AOcANV8QFU5TTmliQ29udHJvbENvbm5lY3RvctQADgDc
+AN0A3gE3AEEA+AFDgEKAEIAwgERbb3JkZXJGcm9udDrSAA4APQFGAUeASK4A+QEOAOoAawCHAL8BTgD+
+AH8AfgBAAEEATAD4gDSANoAtgBKAF4AhgEaAMoAfgBWAB4AQgAuAMNIADgAyADMBWIAEgEddTlNBcHBs
+aWNhdGlvbtIANwA4AVsAz6IAzwA10gAOAD0BRgFegEiuAOoA+QAfAEEAfgB/AB8A+ABrAGsAHwAfAEAA
+6oAtgDSAAoAQgBWAH4ACgDCAEoASgAKAAoAHgC3SAA4APQFGAW+ASK8QDwD5AGsA6gEOAIcAvwFOAP4A
+fwBAAEwAQQB+AB8A+IA0gBKALYA2gBeAIYBGgDKAH4AHgAuAEIAVgAKAMNIADgA9AUYBgYBIrxAPAYIB
+gwGEAYUBhgGHAYgBiQGKAYsBjAGNAY4BjwGQgEyATYBOgE+AUIBRgFKAU4BUgFWAVoBXgFiAWYBaXxAR
+SG9yaXpvbnRhbCBTbGlkZXJcQ29udGVudCBWaWV3W0N1c3RvbSBWaWV3W1NsaWRlciBDZWxsXxAUQnV0
+dG9uIENlbGwgKHlpa2VzISlfECFCdXR0b24gQ2VsbCAoUm91bmQgUmVjdCBCdXR0b24pLTFbQXBwbGlj
+YXRpb25fEB9CdXR0b24gQ2VsbCAoUm91bmQgUmVjdCBCdXR0b24pXxAnUm91bmQgUmVjdCBCdXR0b24g
+KFJvdW5kIFJlY3QgQnV0dG9uKS0xXxARV2luZG93IChXaW5kb3cpLTFeQ29udGVudCBWaWV3LTFfEA9X
+aW5kb3cgKFdpbmRvdylfEBpSb3VuZCBSZWN0IEJ1dHRvbiAoeWlrZXMhKVxGaWxlJ3MgT3duZXJfECVS
+b3VuZCBSZWN0IEJ1dHRvbiAoUm91bmQgUmVjdCBCdXR0b24p0gAOAD0BRgGigEig0gAOAD0BRgGlgEig
+0gAOAD0BRgGogEivEBMA2AD5AQ4A6gBrAIcAvwFOANkA2gD+AH8AfgBAAEEATADXAB8A+IAsgDSANoAt
+gBKAF4AhgEaAQIBDgDKAH4AVgAeAEIALgCmAAoAw0gAOAD0BRgG+gEivEBMBvwHAAcEBwgHDAcQBxQHG
+AccByAHJAcoBywHMAc0BzgHPAdAB0YBfgGCAYYBigGOAZIBlgGaAZ4BogGmAaoBrgGyAbYBugG+AcIBx
+EBQQChALEA0QERAaE//////////9EBgQFhAJEBkQDhAMEBUQGxAI0gAOAD0AfAHkgCOg0gAOAD0BRgHn
+gEig0gAOAD0BRgHqgEig0gA3ADgB7AHtogHtADVeTlNJQk9iamVjdERhdGEACAAZACIAJwAxADoAPwBE
+AFIAVABmAVUBWwGmAa0BtAHCAdQB8AH+AgoCFgIkAi8CPQJZAmcCegKMAqYCsAK9Ar8CwQLDAsUCxwLJ
+AssCzQLPAtEC0wLVAtcC2QLbAt0C3wLhAuoC9gL4AvoDAwMMAxUDIAMlAzQDRwNQA1sDXQNiA2QDZgOP
+A5wDqQO3A8EDzwPcA+4EAgQOBBAEEgQUBBYEGwQdBB8EIQQjBCUEQARHBFAEYQRzBHwEiASKBIwEjwSR
+BJwEpQSsBLMEvwTYBOEE5gT5BSIFJAUmBSgFKgUsBS4FMAVNBVgFZAVmBWgFagVsBW4FcAV5BXsFgAWC
+BYQFpQWtBbQFvgXABcIFxAXGBckFygXMBc4F6AYZBiUGOwZQBl8GcQZ8BoYGlAamBrMGwQbKBswGzgbQ
+BtIG1AbWBtgG2gbdBuIG6wbyBwMHCgcRBxoHHAclBycHKQc2Bz8HRAdLB0wHVQdeB2sHeAeBB4wHlQef
+B8AHwgfEB8YHyAfJB8sHzQflCBYIGAgaCBwIHgggCCIINgg/CEYIVQhdCGYIbQh6CIAIiQiLCJQIlgiY
+CJoInAitCLsIxAjMCM4I0AjSCNQI2wjkCOsJAgkRCSIJJAkmCSgJKglLCU0JTwlRCVMJVQlXCVkJYglk
+CWkJawltCY4JkAmSCZQJlgmXCZkJmwm1CeYJ6AnqCewJ7gnwCfIKEwoVChcKGQobChwKHgogCjkKcgp6
+CpAKpQqwCrsKxgrUCvEK+gr8Cv4LAAsCCwQLBgsPCxgLGQsaCysLLQsvCzkLQgtLC1gLYQtsC3ULgAuJ
+C5ILnwukC7ULtwu5C7sLvQvHC9AL1wvvDAAMAgwEDAYMCAwUDB0MHww8DD4MQAxCDEQMRgxIDEoMTAxO
+DFAMUgxUDFYMWAxhDGMMZQxzDHwMgQyKDIwMqQyrDK0MrwyxDLMMtQy3DLkMuwy9DL8MwQzDDMUMzgzQ
+DPEM8wz1DPcM+Qz7DP0M/w0BDQMNBQ0HDQkNCw0NDQ8NGA0aDTsNPQ0/DUENQw1FDUcNSQ1LDU0NTw1R
+DVMNVQ1XDVkNbQ16DYYNkg2pDc0N2Q37DiUOOQ5IDloOdw6EDqwOtQ63DrgOwQ7DDsQOzQ7PDvgO+g78
+Dv4PAA8CDwQPBg8IDwoPDA8ODxAPEg8UDxYPGA8aDxwPHg8nDykPUg9UD1YPWA9aD1wPXg9gD2IPZA9m
+D2gPag9sD24PcA9yD3QPdg94D3oPfA9+D4APgg+ED40Pjw+RD5MPlQ+XD5kPmw+dD58PqA+qD6sPtA+2
+D7cPwA/CD8MPzA/RAAAAAAAAAgIAAAAAAAAB7gAAAAAAAAAAAAAAAAAAD+A
diff --git a/Tools/NibApp/main.j b/Tools/NibApp/main.j
index 4bbfb1618..9f3ebc983 100755
--- a/Tools/NibApp/main.j
+++ b/Tools/NibApp/main.j
@@ -12,6 +12,8 @@ import
import "AppController.j"
+CPLogRegister(CPLogPopup);
+
function main(args, namedArgs)
{
CPApplicationMain(args, namedArgs);
diff --git a/Tools/nib2cib/NSAppKit.j b/Tools/nib2cib/NSAppKit.j
index f11e4b92d..e307708da 100644
--- a/Tools/nib2cib/NSAppKit.j
+++ b/Tools/nib2cib/NSAppKit.j
@@ -23,9 +23,23 @@
import "NSButton.j"
import "NSCell.j"
import "NSControl.j"
+import "NSCustomObject.j"
import "NSCustomView.j"
import "NSFont.j"
import "NSIBObjectData.j"
+import "NSNibConnector.j"
import "NSResponder.j"
import "NSSlider.j"
import "NSView.j"
+import "NSWindowTemplate.j"
+
+function CP_NSMapClassName(aClassName)
+{
+ if (aClassName == @"NSView")
+ return "CPView";
+
+ if (aClassName == @"NSWindow")
+ return @"CPWindow";
+
+ return aClassName;
+}
diff --git a/Tools/nib2cib/NSButton.j b/Tools/nib2cib/NSButton.j
index 9b0b40d1d..60e408042 100644
--- a/Tools/nib2cib/NSButton.j
+++ b/Tools/nib2cib/NSButton.j
@@ -45,6 +45,9 @@ import "NSControl.j"
[self setBezelStyle:[cell bezelStyle]];
[self setBordered:[cell isBordered]];
+
+ // FIXME
+ _sendActionOn = CPLeftMouseUpMask;
}
return self;
diff --git a/Tools/nib2cib/NSCustomObject.j b/Tools/nib2cib/NSCustomObject.j
new file mode 100644
index 000000000..62891fdb3
--- /dev/null
+++ b/Tools/nib2cib/NSCustomObject.j
@@ -0,0 +1,40 @@
+
+import
+
+
+@implementation _CPCibCustomObject (NSCoding)
+
+- (id)NS_initWithCoder:(CPCoder)aCoder
+{
+ self = [super init];
+
+ if (self){
+ _className = [aCoder decodeObjectForKey:@"NSClassName"];
+ print(":::"+_className);
+ }
+ return self;
+}
+
+@end
+
+@implementation NSCustomObject : _CPCibCustomObject
+{
+}
+
+- (id)initWithCoder:(CPCoder)aCoder
+{print("i-nit form coder");
+ return [self NS_initWithCoder:aCoder];
+}
+
+- (Class)classForKeyedArchiver
+{
+ return [_CPCibCustomObject class];
+}
+
+- (id)awakeAfterUsingCoder:(CPCoder)aCoder
+{
+ print("awaking from coder...");
+ return self;
+}
+
+@end
\ No newline at end of file
diff --git a/Tools/nib2cib/NSCustomView.j b/Tools/nib2cib/NSCustomView.j
index 9b114bf53..6a1362497 100644
--- a/Tools/nib2cib/NSCustomView.j
+++ b/Tools/nib2cib/NSCustomView.j
@@ -25,6 +25,8 @@ import
import "NSView.j"
+var _CPCibCustomViewClassNameKey = @"_CPCibCustomViewClassNameKey";
+
@implementation NSCustomView : CPView
{
CPString _className;
@@ -44,20 +46,13 @@ import "NSView.j"
{
[super encodeWithCoder:aCoder];
- [aCoder encodeObject:_NSCustomViewMapClassName(_className) forKey:@"CPCustomViewClassNameKey"];
+ [aCoder encodeObject:CP_NSMapClassName(_className) forKey:_CPCibCustomViewClassNameKey];
}
- (CPString)classForKeyedArchiver
{
- return [CPCustomView class];
+ return [_CPCibCustomView class];
}
@end
-function _NSCustomViewMapClassName(aClassName)
-{
- if (aClassName == @"NSView")
- return "CPView";
-
- return aClassName;
-}
diff --git a/Tools/nib2cib/NSIBObjectData.j b/Tools/nib2cib/NSIBObjectData.j
index fa7cd2576..594e8ff79 100644
--- a/Tools/nib2cib/NSIBObjectData.j
+++ b/Tools/nib2cib/NSIBObjectData.j
@@ -73,9 +73,9 @@ import
//_accessibilityConnectors = [aCoder decodeObjectForKey:@"NSAccessibilityConnectors"];
//_accessibilityOidsKeys = [aCoder decodeObjectForKey:@"NSAccessibilityOidsKeys"];
//_accessibilityOidsValues = [aCoder decodeObjectForKey:@"NSAccessibilityOidsValues"];
-
- _classesKeys = [aCoder decodeObjectForKey:@"NSClassesKeys"];
- _classesValues = [aCoder decodeObjectForKey:@"NSClassesValues"];
+
+ _classesKeys = [aCoder decodeObjectForKey:@"NSClassesKeys"];print("d");
+ _classesValues = [aCoder decodeObjectForKey:@"NSClassesValues"];print("e");
_connections = [aCoder decodeObjectForKey:@"NSConnections"];
@@ -90,7 +90,7 @@ import
_oidKeys = [aCoder decodeObjectForKey:@"NSOidsKeys"];
_oidValues = [aCoder decodeObjectForKey:@"NSOidsValues"];
- _rootObject = [aCoder decodeObjectForKey:@"NSRoot"];
+ _fileOwner = [aCoder decodeObjectForKey:@"NSRoot"];
_visibleWindows = [aCoder decodeObjectForKey:@"NSVisibleWindows"];
}
diff --git a/Tools/nib2cib/NSNibConnector.j b/Tools/nib2cib/NSNibConnector.j
new file mode 100644
index 000000000..f3dae5301
--- /dev/null
+++ b/Tools/nib2cib/NSNibConnector.j
@@ -0,0 +1,72 @@
+
+import
+
+
+@implementation _CPCibConnector (NSCoding)
+
+- (id)NS_initWithCoder:(CPCoder)aCoder
+{
+ self = [super init];
+
+ if (self)
+ {
+ _source = [aCoder decodeObjectForKey:@"NSSource"];
+ _destination = [aCoder decodeObjectForKey:@"NSDestination"];
+ _label = [aCoder decodeObjectForKey:@"NSLabel"];
+#if DEBUG
+ CPLog(@"Connection: " + [_source description] + " " + [_destination description] + " " + _label);
+#endif
+ }
+
+ return self;
+}
+
+@end
+
+@implementation NSNibConnector : _CPCibConnector
+{
+}
+
+- (id)initWithCoder:(CPCoder)aCoder
+{
+ return [[_CPCibConnector alloc] NS_initWithCoder:aCoder];
+}
+
+- (Class)classForKeyedArchiver
+{
+ return [_CPCibConnector class];
+}
+
+@end
+
+@implementation NSNibControlConnector : _CPCibControlConnector
+{
+}
+
+- (id)initWithCoder:(CPCoder)aCoder
+{
+ return [[_CPCibControlConnector alloc] NS_initWithCoder:aCoder];
+}
+
+- (Class)classForKeyedArchiver
+{
+ return [_CPCibControlConnector class];
+}
+
+@end
+
+@implementation NSNibOutletConnector : _CPCibOutletConnector
+{
+}
+
+- (id)initWithCoder:(CPCoder)aCoder
+{
+ return [[_CPCibOutletConnector alloc] NS_initWithCoder:aCoder];
+}
+
+- (Class)classForKeyedArchiver
+{
+ return [_CPCibOutletConnector class];
+}
+
+@end
diff --git a/Tools/nib2cib/NSWindowTemplate.j b/Tools/nib2cib/NSWindowTemplate.j
new file mode 100644
index 000000000..a87338805
--- /dev/null
+++ b/Tools/nib2cib/NSWindowTemplate.j
@@ -0,0 +1,59 @@
+
+import
+
+
+@implementation _CPCibWindowTemplate (NSCoding)
+
+- (id)NS_initWithCoder:(CPCoder)aCoder
+{
+ self = [super init];
+
+ if (self)
+ {
+ _minSize = [aCoder decodeSizeForKey:@"NSMinSize"];
+ _maxSize = [aCoder decodeSizeForKey:@"NSMaxSize"];
+ _screenRect = [aCoder decodeRectForKey:@"NSScreenRect"]; // screen created on
+ _viewClass = [aCoder decodeObjectForKey:@"NSViewClass"];
+ _wtFlags = [aCoder decodeIntForKey:@"NSWTFlags"];
+ _windowBacking = [aCoder decodeIntForKey:@"NSWindowBacking"];
+
+ // Convert NSWindows to CPWindows.
+ _windowClass = CP_NSMapClassName([aCoder decodeObjectForKey:@"NSWindowClass"]);
+
+ _windowRect = [aCoder decodeRectForKey:@"NSWindowRect"];
+ _windowStyleMask = [aCoder decodeIntForKey:@"NSWindowStyleMask"];
+ _windowTitle = [aCoder decodeObjectForKey:@"NSWindowTitle"];
+ _windowView = [aCoder decodeObjectForKey:@"NSWindowView"];
+
+ /*
+ _windowRect.origin.y -= _screenRect.size.height - [[NSScreen mainScreen] frame].size.height;
+ if (![_windowClass isEqualToString:@"NSPanel"])
+ _windowRect.origin.y -= [NSMainMenuView menuHeight]; // compensation for the additional menu bar
+ */
+ }
+
+ return self;
+}
+
+@end
+
+@implementation NSWindowTemplate : _CPCibWindowTemplate
+{
+}
+
+- (id)initWithCoder:(CPCoder)aCoder
+{
+ return [self NS_initWithCoder:aCoder];
+}
+
+- (id)awakeAfterUsingCoder:(CPCoder)aCoder
+{
+ return self;
+}
+
+- (Class)classForKeyedArchiver
+{
+ return [_CPCibWindowTemplate class];
+}
+
+@end