diff --git a/AppKit/AppKit.j b/AppKit/AppKit.j
index 7a4263b61..b0a9f66d1 100644
--- a/AppKit/AppKit.j
+++ b/AppKit/AppKit.j
@@ -53,9 +53,11 @@ import "CPSecureTextField.j"
import "CPSegmentedControl.j"
import "CPShadow.j"
import "CPSlider.j"
+import "CPSplitView.j"
import "CPTextField.j"
import "CPToolbar.j"
import "CPToolbarItem.j"
import "CPView.j"
+import "CPWebView.j"
import "CPWindow.j"
import "CPWindowController.j"
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/CPDocument.j b/AppKit/CPDocument.j
index 2e53ce40a..cff5335eb 100644
--- a/AppKit/CPDocument.j
+++ b/AppKit/CPDocument.j
@@ -200,7 +200,7 @@ var CPDocumentUntitledCount = 0;
- (CPData)dataOfType:(CPString)aType error:({CPError})anError
{
[CPException raise:CPUnsupportedMethodException
- reason:"This method must be overridden by the document"];
+ reason:"dataOfType:error: must be overridden by the document subclass."];
}
/*
@@ -215,7 +215,7 @@ var CPDocumentUntitledCount = 0;
- (void)readFromData:(CPData)aData ofType:(CPString)aType error:(CPError)anError
{
[CPException raise:CPUnsupportedMethodException
- reason:"This method must be overridden by the document"];
+ reason:"readFromData:ofType: must be overridden by the document subclass."];
}
// Creating and managing window controllers
diff --git a/AppKit/CPDocumentController.j b/AppKit/CPDocumentController.j
index 84fbd9d7a..dc2c04e33 100644
--- a/AppKit/CPDocumentController.j
+++ b/AppKit/CPDocumentController.j
@@ -100,18 +100,18 @@ var CPSharedDocumentController = nil;
*/
- (void)openUntitledDocumentOfType:(CPString)aType display:(BOOL)shouldDisplay
{
- var document = [self makeUntitledDocumentOfType:aType error:nil];
+ var theDocument = [self makeUntitledDocumentOfType:aType error:nil];
- if (document)
- [self addDocument:document];
+ if (theDocument)
+ [self addDocument:theDocument];
if (shouldDisplay)
{
- [document makeWindowControllers];
- [document showWindows];
+ [theDocument makeWindowControllers];
+ [theDocument showWindows];
}
- return document;
+ return theDocument;
}
/*
@@ -137,9 +137,11 @@ var CPSharedDocumentController = nil;
var result = [self documentForURL:anAbsoluteURL];
if (!result)
- // FIXME: type(!)
- result = [self makeDocumentWithContentsOfURL:anAbsoluteURL ofType:[[_documentTypes objectAtIndex:0] objectForKey:@"CPBundleTypeName"] delegate:self didReadSelector:@selector(document:didRead:contextInfo:) contextInfo:nil];
-
+ {
+ var type = [self typeForContentsOfURL:anAbsoluteURL error:anError];
+
+ result = [self makeDocumentWithContentsOfURL:anAbsoluteURL ofType:type delegate:self didReadSelector:@selector(document:didRead:contextInfo:) contextInfo:[CPDictionary dictionaryWithObject:shouldDisplay forKey:@"shouldDisplay"]];
+ }
else if (shouldDisplay)
[result showWindows];
@@ -200,6 +202,9 @@ var CPSharedDocumentController = nil;
[self addDocument:aDocument];
[aDocument makeWindowControllers];
+
+ if ([aContextInfo objectForKey:@"shouldDisplay"])
+ [aDocument showWindows];
}
/*
@@ -240,6 +245,34 @@ var CPSharedDocumentController = nil;
[_documents removeObjectIdenticalTo:aDocument];
}
+- (CPString)defaultType
+{
+ return [_documentTypes[0] objectForKey:@"CPBundleTypeName"];
+}
+
+- (CPString)typeForContentsOfURL:(CPURL)anAbsoluteURL error:(CPError)outError
+{
+ var index = 0,
+ count = _documentTypes.length,
+
+ extension = [[anAbsoluteURL pathExtension] lowercaseString];
+
+ for (; index < count; ++index)
+ {
+ var documentType = _documentTypes[index],
+ extensions = [documentType objectForKey:@"CFBundleTypeExtensions"],
+ extensionIndex = 0,
+ extensionCount = extensions.length;
+
+ for (; extensionIndex < extensionCount; ++extensionIndex)
+ if ([extensions[extensionIndex] lowercaseString] == extension)
+ return [documentType objectForKey:@"CPBundleTypeName"];
+ }
+
+ // FIXME?
+ return [self defaultType];//nil;
+}
+
// Managing Document Types
/* @ignore */
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/CPResponder.j b/AppKit/CPResponder.j
index 34e177677..406dbb43e 100644
--- a/AppKit/CPResponder.j
+++ b/AppKit/CPResponder.j
@@ -301,7 +301,7 @@ var CPResponderNextResponderKey = @"CPResponderNextResponderKey";
*/
- (id)initWithCoder:(CPCoder)aCoder
{
- self = [self init];
+ self = [super init];
if (self)
_nextResponder = [aCoder decodeObjectForKey:CPResponderNextResponderKey];
diff --git a/AppKit/CPSlider.j b/AppKit/CPSlider.j
index 8f0240a9d..ab8d2e6b6 100644
--- a/AppKit/CPSlider.j
+++ b/AppKit/CPSlider.j
@@ -22,7 +22,7 @@
import "CPControl.j"
-var CPSliderHorizontalKnobImage = nil
+var CPSliderHorizontalKnobImage = nil,
CPSliderHorizontalBarLeftImage = nil,
CPSliderHorizontalBarRightImage = nil,
CPSliderHorizontalBarCenterImage = nil;
diff --git a/AppKit/CPSplitView.j b/AppKit/CPSplitView.j
new file mode 100644
index 000000000..fc9ac630a
--- /dev/null
+++ b/AppKit/CPSplitView.j
@@ -0,0 +1,512 @@
+/*
+ * 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;
+ CPString _dividerImagePath;
+ int _drawingDivider;
+}
+
+/*
+ @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];
+ }
+
+ return self;
+}
+
+- (float)dividerThickness
+{
+ return _isPaneSplitter ? 1.0 : 10.0;
+}
+
+- (BOOL)isVertical
+{
+ return _isVertical;
+}
+
+- (void)setVertical:(BOOL)flag
+{
+ [self _setVertical:flag];
+
+ [self adjustSubviews];
+}
+
+- (void)_setVertical:(BOOL)flag
+{
+ _isVertical = flag;
+
+ _originComponent = [self isVertical] ? "x" : "y";
+ _sizeComponent = [self isVertical] ? "width" : "height";
+ _dividerImagePath = [self isVertical] ? [CPSplitViewVerticalImage filename] : [CPSplitViewHorizontalImage filename];
+}
+
+- (BOOL)isPaneSplitter
+{
+ return _isPaneSplitter;
+}
+
+- (void)setIsPaneSplitter:(BOOL)shouldBePaneSplitter
+{
+ if (_isPaneSplitter == shouldBePaneSplitter)
+ return;
+
+ _isPaneSplitter = shouldBePaneSplitter;
+
+#if PLATFORM(DOM)
+ _DOMDividerElements = [];
+#endif
+
+ [self setNeedsDisplay:YES];
+}
+
+- (void)didAddSubview:(CPView)subview
+{
+ [self adjustSubviews];
+}
+
+- (void)adjustSubviews
+{
+ var frame = [self frame],
+ dividerThickness = [self dividerThickness];
+
+ [self _postNotificationWillResize];
+
+ var eachSize = ROUND((frame.size[_sizeComponent] - dividerThickness * (_subviews.length - 1)) / _subviews.length),
+ index = 0,
+ count = _subviews.length;
+
+ if ([self isVertical])
+ for (; index < count; ++index)
+ [_subviews[index] setFrame:CGRectMake(ROUND((eachSize + dividerThickness) * index), 0, eachSize, frame.size.height)];
+ else
+ for (; index < count; ++index)
+ [_subviews[index] setFrame:CGRectMake(0, ROUND((eachSize + dividerThickness) * index), frame.size.width, 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],
+ rect = CGRectMakeZero();
+
+ rect.size = [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];
+
+ var padding = 2;
+
+ realRect.size[_sizeComponent] += padding * 2;
+ realRect.origin[_originComponent] -= padding;
+
+ return realRect;
+}
+
+- (void)drawRect:(CGRect)rect
+{
+ var count = [_subviews count] - 1;
+
+ while (count--)
+ [self drawDividerInRect:[self rectOfDividerAtIndex:count]];
+}
+
+- (void)drawDividerInRect:(CGRect)aRect
+{
+#if PLATFORM(DOM)
+ if (!_DOMDividerElements[_drawingDivider])
+ {
+ _DOMDividerElements[_drawingDivider] = document.createElement("div");
+ _DOMDividerElements[_drawingDivider].style.cursor = "move";
+ _DOMDividerElements[_drawingDivider].style.position = "absolute";
+ _DOMDividerElements[_drawingDivider].style.backgroundRepeat = "repeat";
+
+ CPDOMDisplayServerAppendChild(_DOMElement, _DOMDividerElements[_drawingDivider]);
+
+ if (_isPaneSplitter)
+ {
+ _DOMDividerElements[_drawingDivider].style.backgroundColor = "#A5A5A5";
+ _DOMDividerElements[_drawingDivider].style.backgroundImage = "";
+ }
+ else
+ {
+ _DOMDividerElements[_drawingDivider].style.backgroundColor = "";
+ _DOMDividerElements[_drawingDivider].style.backgroundImage = "url('"+_dividerImagePath+"')";
+ }
+ }
+
+ CPDOMDisplayServerSetStyleLeftTop(_DOMDividerElements[_drawingDivider], NULL, _CGRectGetMinX(aRect), _CGRectGetMinY(aRect));
+ CPDOMDisplayServerSetStyleSize(_DOMDividerElements[_drawingDivider], _CGRectGetWidth(aRect), _CGRectGetHeight(aRect));
+#endif
+}
+
+- (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));
+}
+
+- (CPView)hitTest:(CGPoint)aPoint
+{
+ if ([self isHidden] || ![self hitTests] || !CGRectContainsPoint([self frame], aPoint))
+ return nil;
+
+ var point = [self convertPoint:aPoint fromView:[self superview]];
+
+ var count = [_subviews count] - 1;
+ for (var i = 0; i < count; i++)
+ {
+ if ([self cursorAtPoint:point hitDividerAtIndex:i])
+ return self;
+ }
+
+ return [super hitTest:aPoint];
+}
+
+/*
+ Tracks the divider.
+ @param anEvent the input event
+*/
+- (void)trackDivider:(CPEvent)anEvent
+{
+ var type = [anEvent type];
+
+ if (type == CPLeftMouseUp)
+ {
+ if (_currentDivider != CPNotFound)
+ {
+ _currentDivider = CPNotFound;
+ [self _postNotificationDidResize];
+ }
+
+ return;
+ }
+
+ if (type == CPLeftMouseDown)
+ {
+ var point = [self convertPoint:[anEvent locationInWindow] fromView:nil];
+
+ _currentDivider = CPNotFound;
+ var count = [_subviews count] - 1;
+ for (var i = 0; i < count; i++)
+ {
+ var frame = [_subviews[i] frame],
+ startPosition = frame.origin[_originComponent] + frame.size[_sizeComponent];
+
+ if ([self cursorAtPoint:point hitDividerAtIndex:i])
+ {
+ if ([anEvent 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];
+ }
+ }
+ }
+ }
+
+ else if (type == CPLeftMouseDragged && _currentDivider != CPNotFound)
+ {
+ var point = [self convertPoint:[anEvent locationInWindow] fromView:nil];
+
+ [self setPosition:(point[_originComponent] + _initialOffset) ofDividerAtIndex:_currentDivider];
+ }
+
+ [CPApp setTarget:self selector:@selector(trackDivider:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
+}
+
+- (void)mouseDown:(CPEvent)anEvent
+{
+ [self trackDivider:anEvent];
+}
+
+- (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 = [viewA frame],
+ viewB = _subviews[dividerIndex+1],
+ frameB = [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 = [self frame];
+
+ var index = 0,
+ count = [_subviews count],
+ dividerThickness = [self dividerThickness];
+
+ for (; index < count; ++index)
+ {
+ var view = _subviews[index],
+ newFrame = CGRectCreateCopy(frame);
+
+ if (index + 1 == 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] + 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
+
+var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
+ CPSplitViewIsVerticalKey = "CPSplitViewIsVerticalKey",
+ CPSplitViewIsPaneSplitterKey = "CPSplitViewIsPaneSplitterKey";
+
+@implementation CPSplitView (CPCoding)
+
+/*
+ Initializes the split view by unarchiving data from aCoder.
+ @param aCoder the coder containing the archived CPSplitView.
+*/
+- (id)initWithCoder:(CPCoder)aCoder
+{
+ self = [super initWithCoder:aCoder];
+
+ if (self)
+ {
+ _currentDivider = CPNotFound;
+
+ _DOMDividerElements = [];
+
+ _delegate = [aCoder decodeObjectForKey:CPSplitViewDelegateKey];;
+
+ _isPaneSplitter = [aCoder decodeBoolForKey:CPSplitViewIsPaneSplitterKey];
+ [self _setVertical:[aCoder decodeBoolForKey:CPSplitViewIsVerticalKey]];
+ }
+
+ return self;
+}
+
+/*
+ Archives this split view into the provided coder.
+ @param aCoder the coder to which the button's instance data will be written.
+*/
+- (void)encodeWithCoder:(CPCoder)aCoder
+{
+ [super encodeWithCoder:aCoder];
+
+ [aCoder encodeConditionalObject:_delegate forKey:CPSplitViewDelegateKey];
+
+ [aCoder encodeBool:_isVertical forKey:CPSplitViewIsVerticalKey];
+ [aCoder encodeBool:_isPaneSplitter forKey:CPSplitViewIsPaneSplitterKey];
+}
+
+@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 900015de8..fbb63ca66 100644
--- a/AppKit/CPTextField.j
+++ b/AppKit/CPTextField.j
@@ -105,6 +105,7 @@ var _CPTextFieldSquareBezelColor = nil;
BOOL _isSelectable;
id _value;
+ id _placeholderString;
CPLineBreakMode _lineBreakMode;
#if PLATFORM(DOM)
@@ -140,11 +141,12 @@ var _CPTextFieldSquareBezelColor = nil;
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
-
+
if (self)
{
_value = @"";
-
+ _placeholderString = @"";
+
#if PLATFORM(DOM)
_DOMTextElement = document.createElement("div");
_DOMTextElement.style.position = "absolute";
@@ -167,8 +169,7 @@ var _CPTextFieldSquareBezelColor = nil;
// Setting the Bezel Style
/*
Sets whether the textfield will have a bezeled border.
- @param shouldBeBezeled YES means the textfield
- will draw a bezeled border
+ @param shouldBeBezeled YES means the textfield will draw a bezeled border
*/
- (void)setBezeled:(BOOL)shouldBeBezeled
{
@@ -181,8 +182,7 @@ var _CPTextFieldSquareBezelColor = nil;
}
/*
- Returns YES if the textfield draws a
- bezeled border.
+ Returns YES if the textfield draws a bezeled border.
*/
- (BOOL)isBezeled
{
@@ -213,8 +213,7 @@ var _CPTextFieldSquareBezelColor = nil;
/*
Sets whether the textfield will have a border drawn.
- @param shouldBeBordered YES makes the
- textfield draw a border
+ @param shouldBeBordered YES makes the textfield draw a border
*/
- (void)setBordered:(BOOL)shouldBeBordered
{
@@ -227,8 +226,7 @@ var _CPTextFieldSquareBezelColor = nil;
}
/*
- Returns YES if the textfield has
- a border.
+ Returns YES if the textfield has a border.
*/
- (BOOL)isBordered
{
@@ -264,11 +262,13 @@ var _CPTextFieldSquareBezelColor = nil;
[self setBackgroundColor:nil];
}
+/* @ignore */
- (BOOL)acceptsFirstResponder
{
return _isEditable;
}
+/* @ignore */
- (BOOL)becomeFirstResponder
{
var string = [self stringValue];
@@ -283,12 +283,12 @@ var _CPTextFieldSquareBezelColor = nil;
element.style.font = _DOMElement.style.font;
element.style.zIndex = 1000;
element.style.width = CGRectGetWidth([self bounds]) - 3.0 + "px";
-// element.style.left = _DOMTextElement.style.left;
-// element.style.top = _DOMTextElement.style.top;
+ //element.style.left = _DOMTextElement.style.left;
+ //element.style.top = _DOMTextElement.style.top;
_DOMElement.appendChild(element);
window.setTimeout(function() { element.focus(); }, 0.0);
-// element.onblur = function() { objj_debug_print_backtrace(); }
+ //element.onblur = function() { objj_debug_print_backtrace(); }
//element.select();
element.onkeypress = function(aDOMEvent)
@@ -309,12 +309,17 @@ var _CPTextFieldSquareBezelColor = nil;
}
};
+ // If current value is the placeholder value, remove it to allow user to update.
+ if ([_value lowercaseString] == [[self placeholderString] lowercaseString])
+ [self setStringValue:@""];
+
[[CPDOMWindowBridge sharedDOMWindowBridge] _propagateCurrentDOMEvent:YES];
#endif
return YES;
}
+/* @ignore */
- (BOOL)resignFirstResponder
{
#if PLATFORM(DOM)
@@ -322,19 +327,25 @@ var _CPTextFieldSquareBezelColor = nil;
_DOMElement.removeChild(element);
[self setStringValue:element.value];
-#endif
+ // If textfield has no value, then display the placeholderValue
+ if (!_value)
+ [self setStringValue:[self placeholderString]];
+
+#endif
return YES;
}
+/*
+ Sets whether or not the receiver text field can be edited
+*/
- (void)setEditable:(BOOL)shouldBeEditable
{
_isEditable = shouldBeEditable;
}
/*
- Returns YES if the textfield is currently
- editable by the user.
+ Returns YES if the textfield is currently editable by the user.
*/
- (BOOL)isEditable
{
@@ -351,8 +362,7 @@ var _CPTextFieldSquareBezelColor = nil;
}
/*
- Returns YES if the field's text is
- selectable by the user.
+ Returns YES if the field's text is selectable by the user.
*/
- (BOOL)isSelectable
{
@@ -360,8 +370,7 @@ var _CPTextFieldSquareBezelColor = nil;
}
/*
- Sets whether the field's text is selectable
- by the user.
+ Sets whether the field's text is selectable by the user.
@param aFlag YES makes the text selectable
*/
- (void)setSelectable:(BOOL)aFlag
@@ -432,7 +441,7 @@ var _CPTextFieldSquareBezelColor = nil;
return [[self class] _inputElement].value;
#endif
- return [self stringValue];
+ return [super stringValue];
}
/*
@@ -457,6 +466,23 @@ var _CPTextFieldSquareBezelColor = nil;
#endif
}
+/*
+ Returns the receiver's placeholder string
+*/
+- (CPString)placeholderString
+{
+ return _placeholderString;
+}
+
+/*
+ Sets a placeholder string for the receiver. The placeholder is displayed until editing begins,
+ and after editing ends, if the text field has an empty string value
+*/
+-(void)setPlaceholderString:(CPString)aStringValue
+{
+ _placeholderString = aStringValue;
+}
+
/*
Adjusts the text field's size in the application.
*/
@@ -469,6 +495,19 @@ var _CPTextFieldSquareBezelColor = nil;
#endif
}
+/*
+ Select all the text in the CPTextField.
+*/
+- (void)selectText:(id)sender
+{
+#if PLATFORM(DOM)
+ var element = [[self class] _inputElement];
+
+ if (element.parentNode == _DOMElement && ([self isEditable] || [self isSelectable]))
+ element.select();
+#endif
+}
+
@end
var CPTextFieldIsSelectableKey = @"CPTextFieldIsSelectableKey",
@@ -520,10 +559,8 @@ var CPTextFieldIsSelectableKey = @"CPTextFieldIsSelectableKey",
}
/*
- Encodes the data of this textfield into the
- provided coder.
- @param aCoder the coder into which the data
- will be written
+ Encodes the data of this textfield into the provided coder.
+ @param aCoder the coder into which the data will be written
*/
- (void)encodeWithCoder:(CPCoder)aCoder
{
diff --git a/AppKit/CPView.j b/AppKit/CPView.j
index e09f3f557..db843c9d9 100644
--- a/AppKit/CPView.j
+++ b/AppKit/CPView.j
@@ -122,6 +122,8 @@ var DOMElementPrototype = nil,
CPGraphicsContext _graphicsContext;
+ int _tag;
+
CGRect _frame;
CGRect _bounds;
CGAffineTransform _boundsTransform;
@@ -193,6 +195,11 @@ var DOMElementPrototype = nil,
_CPViewNotificationCenter = [CPNotificationCenter defaultCenter];
}
+- (id)init
+{
+ return [self initWithFrame:CGRectMakeZero()];
+}
+
/*
Initializes the receiver for usage with the specified bounding rectangle
@return the initialized view
@@ -208,6 +215,8 @@ var DOMElementPrototype = nil,
_subviews = [];
+ _tag = -1;
+
_frame = _CGRectMakeCopy(aFrame);
_bounds = _CGRectMake(0.0, 0.0, width, height);
@@ -398,7 +407,7 @@ var DOMElementPrototype = nil,
[aSubview removeFromSuperview];
- [aView _insertSubview:aView atIndex:index];
+ [self _insertSubview:aView atIndex:index];
}
/* @ignore */
@@ -498,6 +507,11 @@ var DOMElementPrototype = nil,
return enclosingMenuItem;*/
}
+- (int)tag
+{
+ return _tag;
+}
+
/*
Returns whether the view is flipped.
@return YES if the view is flipped. NO, otherwise.
@@ -1699,6 +1713,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
CPViewOpacityKey = @"CPViewOpacityKey",
CPViewSubviewsKey = @"CPViewSubviewsKey",
CPViewSuperviewKey = @"CPViewSuperviewKey",
+ CPViewTagKey = @"CPViewTagKey",
CPViewWindowKey = @"CPViewWindowKey";
@implementation CPView (CPCoding)
@@ -1718,13 +1733,19 @@ 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];
-
+ _tag = -1;
+
+ if ([aCoder containsValueForKey:CPViewTagKey])
+ _tag = [aCoder decodeIntForKey:CPViewTagKey];
+
_window = [aCoder decodeObjectForKey:CPViewWindowKey];
_subviews = [aCoder decodeObjectForKey:CPViewSubviewsKey];
_superview = [aCoder decodeObjectForKey:CPViewSuperviewKey];
@@ -1750,6 +1771,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
for (; index < count; ++index)
{
CPDOMDisplayServerAppendChild(_DOMElement, _subviews[index]._DOMElement);
+ //_subviews[index]._superview = self;
}
#endif
_displayHash = [self hash];
@@ -1768,6 +1790,9 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
{
[super encodeWithCoder:aCoder];
+ if (_tag != -1)
+ [aCoder encodeInt:_tag forKey:CPViewTagKey];
+
[aCoder encodeRect:_frame forKey:CPViewFrameKey];
[aCoder encodeRect:_bounds forKey:CPViewBoundsKey];
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..ee27f538d 100644
--- a/AppKit/Cib/CPCib.j
+++ b/AppKit/Cib/CPCib.j
@@ -25,8 +25,10 @@ import
import
import "CPCustomView.j"
+import "_CPCibCustomObject.j"
+import "_CPCibKeyedUnarchiver.j"
import "_CPCibObjectData.j"
-
+import "_CPCibWindowTemplate.j"
CPCibOwner = @"CPCibOwner",
CPCibTopLevelObjects = @"CPCibTopLevelObjects";
@@ -50,26 +52,16 @@ var CPCibObjectDataKey = @"CPCibObjectDataKey";
- (BOOL)instantiateCibWithExternalNameTable:(CPDictionary)anExternalNameTable
{
- var unarchiver = [[CPKeyedUnarchiver alloc] initForReadingWithData:_data],
+ var unarchiver = [[_CPCibKeyedUnarchiver alloc] initForReadingWithData:_data],
objectData = [unarchiver decodeObjectForKey: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..c0c70fce2 100644
--- a/AppKit/Cib/CPCustomView.j
+++ b/AppKit/Cib/CPCustomView.j
@@ -1,5 +1,5 @@
/*
- * CPCustomView.j
+ * _CPCibCustomView.j
* AppKit
*
* Created by Francisco Tolmasky.
@@ -22,76 +22,75 @@
import "CPView.j"
-var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
- CPViewAutoresizesSubviewsKey = @"CPViewAutoresizesSubviews",
- CPViewBackgroundColorKey = @"CPViewBackgroundColor",
- CPViewBoundsKey = @"CPViewBoundsKey",
- CPViewFrameKey = @"CPViewFrameKey",
- CPViewHitTestsKey = @"CPViewHitTestsKey",
- CPViewIsHiddenKey = @"CPViewIsHiddenKey",
- CPViewOpacityKey = @"CPViewOpacityKey",
- CPViewSubviewsKey = @"CPViewSubviewsKey",
- CPViewSuperviewKey = @"CPViewSuperviewKey",
- CPViewWindowKey = @"CPViewWindowKey";
/* @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];
+ self = [super initWithCoder:aCoder];
+
+ if (self)
+ _className = [aCoder decodeObjectForKey:_CPCibCustomViewClassNameKey];
+
+ return self;
+}
+
+- (void)encodeWithCoder:(CPCoder)aCoder
+{
+ [super encodeWithCoder:aCoder];
+ [aCoder encodeObject:_className forKey:_CPCibCustomViewClassNameKey];
+}
+
+- (id)_cibInstantiate
+{
var theClass = CPClassFromString(_className);
// If we don't have this class, just use CPView.
// FIXME: Should we instead throw an exception?
if (!theClass)
- 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];
+ {
+ CPLog("Unknown class \"" + _className + "\" in cib file, using CPView instead.");
- if (self)
- {
- [self _setWindow:[aCoder decodeObjectForKey:CPViewWindowKey]];
+ theClass = [CPView class];
+ }
+
+ var view = [[theClass alloc] initWithFrame:[self frame]];
+
+ if (view)
+ {
+ [view setBounds:[self bounds]];
// Since the object replacement logic hasn't had a chance to kick in yet, we need to do it manually:
- var subviews = [aCoder decodeObjectForKey:CPViewSubviewsKey],
+ var subviews = [self subviews],
index = 0,
count = subviews.length;
for (; index < count; ++index)
- {
- // This is a bogus superview "CPCustomView".
- subviews[index]._superview = nil;
-
- [self addSubview:subviews[index]];
- }
-
- _autoresizingMask = [aCoder decodeIntForKey:CPViewAutoresizingMaskKey];
- _autoresizesSubviews = [aCoder decodeBoolForKey:CPViewAutoresizesSubviewsKey];
-
- _hitTests = [aCoder decodeObjectForKey:CPViewHitTestsKey];
- _isHidden = [aCoder decodeObjectForKey:CPViewIsHiddenKey];
- _opacity = [aCoder decodeIntForKey:CPViewOpacityKey];
+ [view addSubview:subviews[index]];
+
+ [view setAutoresizingMask:[self autoresizingMask]];
+ [view setAutoresizesSubviews:[self autoresizesSubviews]];
- [self setBackgroundColor:[aCoder decodeObjectForKey:CPViewBackgroundColorKey]];
+ [view setHitTests:[self hitTests]];
+ [view setHidden:[self isHidden]];
+ [view setAlphaValue:[self alphaValue]];
+
+ [view setBackgroundColor:[self backgroundColor]];
}
- return self;
+ return view;
}
@end
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..5064784d8
--- /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)_cibInstantiate
+{
+ var theClass = CPClassFromString(_className);
+
+ if (!theClass)
+ CPLog("Unknown class \"" + _className + "\" in cib file");
+
+ return [[theClass alloc] init];
+}
+
+@end
diff --git a/AppKit/Cib/_CPCibKeyedUnarchiver.j b/AppKit/Cib/_CPCibKeyedUnarchiver.j
new file mode 100644
index 000000000..3776cc5a8
--- /dev/null
+++ b/AppKit/Cib/_CPCibKeyedUnarchiver.j
@@ -0,0 +1,37 @@
+
+import
+
+
+@implementation _CPCibKeyedUnarchiver : CPKeyedUnarchiver
+{
+}
+
+- (id)initForReadingWithData:(CPData)data
+{
+ self = [super initForReadingWithData:data];
+
+ if (self)
+ [self setDelegate:self];
+
+ return self;
+}
+
+- (id)unarchiver:(CPKeyedUnarchiver)aKeyedUnarchiver didDecodeObject:(id)anObject
+{
+ if ([anObject respondsToSelector:@selector(_cibInstantiate)])
+ return [anObject _cibInstantiate];
+
+ return anObject;
+}
+
+- (void)replaceObjectAtUID:(int)aUID withObject:(id)anObject
+{
+ _objects[aUID] = anObject;
+}
+
+- (id)objectAtUID:(int)aUID
+{
+ return _objects[aUID];
+}
+
+@end
\ No newline at end of file
diff --git a/AppKit/Cib/_CPCibObjectData.j b/AppKit/Cib/_CPCibObjectData.j
index 53cad72d3..f336e6942 100644
--- a/AppKit/Cib/_CPCibObjectData.j
+++ b/AppKit/Cib/_CPCibObjectData.j
@@ -24,47 +24,51 @@ 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
{
- var count = [_objectsValues count];
+ var count = [_objectsValues count],
+ topLevelObjects = [];
while (count--)
{
var eachObject = _objectsValues[count];
- if(eachObject == _fileOwner)
+ if (eachObject == _fileOwner)
{
var anObject = _objectsKeys[count];
@@ -75,7 +79,6 @@ import
return topLevelObjects;
}
-*/
@end
@@ -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..dec6bd3c4
--- /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)_cibInstantiate
+{
+ 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/Platform/DOM/CPDOMDisplayServer.j b/AppKit/Platform/DOM/CPDOMDisplayServer.j
index 0e34fef89..b2338c339 100644
--- a/AppKit/Platform/DOM/CPDOMDisplayServer.j
+++ b/AppKit/Platform/DOM/CPDOMDisplayServer.j
@@ -133,7 +133,7 @@ CPDOMDisplayServerViewsContext = {};
CPDOMDisplayServerInstructions[index++] = nil;
break;
- }}catch(e) { alert("here?" + instruction) }
+ }}catch(e) { CPLog("here?" + instruction) }
}
CPDOMDisplayServerInstructionCount = 0;
@@ -155,7 +155,7 @@ CPDOMDisplayServerViewsContext = {};
[view displayIfNeeded];
}
}
-
+
[CPDOMDisplayRunLoop performSelector:@selector(run) target:CPDOMDisplayServer argument:nil order:0 modes:[CPDefaultRunLoopMode]];
}
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/AppKit/_CPWindowView.j b/AppKit/_CPWindowView.j
index f427f98a5..7bbadec51 100644
--- a/AppKit/_CPWindowView.j
+++ b/AppKit/_CPWindowView.j
@@ -62,7 +62,7 @@ var _CPWindowViewResizeIndicatorImage = nil;
{
_resizeIndicatorOffset = CGSizeMake(0.0, 0.0);
- [self setShowsResizeIndicator:((_styleMask & CPBorderlessWindowMask) || (_styleMask & CPBorderlessBridgeWindowMask)) && (_styleMask & CPResizableWindowMask)];
+ [self setShowsResizeIndicator:!(_styleMask & CPBorderlessBridgeWindowMask) && (_styleMask & CPResizableWindowMask)];
}
return self;
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..e6ff1f2ef 100644
--- a/Tools/NibApp/HelloWorld.nib/info.nib
+++ b/Tools/NibApp/HelloWorld.nib/info.nib
@@ -11,7 +11,7 @@
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..44157a897 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..b94e7b7a8 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
YES
+
+
+
+
+ YES
+
+ YES
+
+
+ YES
+
+
+
+ YES
+
+ YES
+
+
+
+
+ YES
+ id
+
+
+
+
+ IBUserSource
+
+
+
0
@@ -223,57 +449,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
+AYag0QAHAAhdSUIub2JqZWN0ZGF0YYABXxAPTlNLZXllZEFyY2hpdmVyrxB1AAsADAAxADUANgA7ADwA
+QgBWAFcAWABZAGEAYgBmAGcAagBWAHIACwB7AIAAjACNAKUApgCuAK8AsgCzALcAuwDDAMQAywDMAGEA
+CwBmANAA1ADbAOMA5ADoAO0A9QD9AAsA/gEFAQYBCQEOAQ8BFAEZASEBIgE2ATkBOgE9AUAACwBkAUEB
+RAFFAVYBWQFaAVwBbQF/AZEBkgGTAZQBlQGWAZcBmAGZAZoBmwGcAZ0BngGfAaABowGmAbwB0gHTAdQB
+1QHWAdcB2AEuAdkAVAHaAdsB3AHdAd4B3wHgAK0B4QHiAeUB6AHrVSRudWxs3xASAA0ADgAPABAAEQAS
+ABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAqACsALAAtAC4ALwAw
+Vk5TUm9vdFYkY2xhc3NdTlNPYmplY3RzS2V5c18QD05TQ2xhc3Nlc1ZhbHVlc18QGU5TQWNjZXNzaWJp
+bGl0eU9pZHNWYWx1ZXNdTlNDb25uZWN0aW9uc1tOU05hbWVzS2V5c1tOU0ZyYW1ld29ya11OU0NsYXNz
+ZXNLZXlzWk5TT2lkc0tleXNdTlNOYW1lc1ZhbHVlc18QGU5TQWNjZXNzaWJpbGl0eUNvbm5lY3RvcnNd
+TlNGb250TWFuYWdlcl8QEE5TVmlzaWJsZVdpbmRvd3NfEA9OU09iamVjdHNWYWx1ZXNfEBdOU0FjY2Vz
+c2liaWxpdHlPaWRzS2V5c1lOU05leHRPaWRcTlNPaWRzVmFsdWVzgAKAdIBEgFuAc4AogEmABYBagFyA
+SoBxgACABoBIgHIQHIBd0gAOADIAMwA0W05TQ2xhc3NOYW1lgASAA1hOU09iamVjdNIANwA4ADkAOlgk
+Y2xhc3Nlc1okY2xhc3NuYW1logA6ADVeTlNDdXN0b21PYmplY3RfEBBJQkNvY29hRnJhbWV3b3Jr0gAO
+AD0APgA/Wk5TLm9iamVjdHOAJ6IAQABBgAeAENoAQwAOAEQARQBGAEcASABJAEoASwBMAE0ATgBPAFAA
+UQBSAFMAVAArXE5TV2luZG93Vmlld1xOU1NjcmVlblJlY3RdTlNXaW5kb3dUaXRsZVlOU1dURmxhZ3Nd
+TlNXaW5kb3dDbGFzc1xOU1dpbmRvd1JlY3RfEA9OU1dpbmRvd0JhY2tpbmdfEBFOU1dpbmRvd1N0eWxl
+TWFza1tOU1ZpZXdDbGFzc4ALgA+ADoAJEiQAAACACoAIEAIQD4AAXxAYe3sxOTYsIDI0MH0sIHs0ODAs
+IDI3MH19VldpbmRvd1hOU1dpbmRvd9QAWgAOAFsAXAArAF4AXwBgXxAPTlNOZXh0UmVzcG9uZGVyWE5T
+dkZsYWdzW05TRnJhbWVTaXplgACADREBAIAMWns0ODAsIDI3MH3SADcAOABjAGSjAGQAZQA1Vk5TVmll
+d1tOU1Jlc3BvbmRlcl8QFnt7MCwgMH0sIHsxNjgwLCAxMDI4fX3SADcAOABoAGmiAGkANV8QEE5TV2lu
+ZG93VGVtcGxhdGXaAEMADgBEAEUARgBHAEgASQBKAEsAawBNAG0ATwBQAFEAcABTAFQAK4ASgA+AJoAJ
+gAqAEYAA1wBaAA4AcwBbAFwAWAB0AHUAXgB3AF8AeAB1AHpaTlNTdWJ2aWV3c1tOU1N1cGVydmlld4AT
+gA2AFIAkgBOAJdIADgA9AHwAfYAjogB+AH+AFYAf2ABaAA4AgQCCAFsAgwBYAHQAawCFAIYAhwCIAIkA
+dQBrV05TRnJhbWVWTlNDZWxsWU5TRW5hYmxlZIASgB6AFoAXEQEMCYATgBJfEBd7ezE0NSwgMTEzfSwg
+ezE1NCwgMTl9fdwAjgAOAI8AkACRAJIAkwCUAJUAlgCXAJgAmQCaAJsAnACdAJsAnwCgAH4AogCjAKRb
+TlNDZWxsRmxhZ3NfEBNOU0FsdGVybmF0ZUNvbnRlbnRzXxASTlNQZXJpb2RpY0ludGVydmFsXk5TQnV0
+dG9uRmxhZ3MyXxAPTlNLZXlFcXVpdmFsZW50Wk5TQ29udGVudHNZTlNTdXBwb3J0XU5TQ29udHJvbFZp
+ZXdfEA9OU1BlcmlvZGljRGVsYXlcTlNDZWxsRmxhZ3MyXU5TQnV0dG9uRmxhZ3MT/////4QB/gCAHYAc
+EEsQpIAcgBiAGYAVEQGQEggAAAAT/////4aEQP9WeWlrZXMh1AAOAKcAqACpAKoAqwCsAK1WTlNTaXpl
+Vk5TTmFtZVhOU2ZGbGFnc4AbI0AoAAAAAAAAgBoQEFxMdWNpZGFHcmFuZGXSADcAOACwALGiALEANVZO
+U0ZvbnRQ0gA3ADgAtAC1pAC1ALYAggA1XE5TQnV0dG9uQ2VsbFxOU0FjdGlvbkNlbGzSADcAOAC4ALml
+ALkAugBkAGUANVhOU0J1dHRvbllOU0NvbnRyb2zYAFoADgCBAIIAWwCDAFgAdABrAIUAvgC/AIgAiQB1
+AGuAEoAegCCAIQmAE4ASXxAVe3swLCAyNTF9LCB7MTU0LCAxOX193ACOAA4AjwCQAJEAkgCTAJQAlQCW
+AJcAmACZAJoAmwCcAJ0AmwDIAKAAfwCiAKMApIAdgByAHIAigBmAH18QEVJvdW5kIFJlY3QgQnV0dG9u
+0gA3ADgAzQDOowDOAM8ANV5OU011dGFibGVBcnJheVdOU0FycmF50gA3ADgA0QDSowDSANMANVxOU011
+dGFibGVTZXRVTlNTZXTSAA4APQB8ANaAI6QA1wDYANkA2oApgCyANIA21AAOANwA3QDeAN8AQQAfAOJd
+TlNEZXN0aW5hdGlvblhOU1NvdXJjZVdOU0xhYmVsgCuAEIACgCpWd2luZG930gA3ADgA5QDmowDmAOcA
+NV8QFE5TTmliT3V0bGV0Q29ubmVjdG9yXk5TTmliQ29ubmVjdG9y1AAOANwA3QDeAOkAQQDrAOyAM4AQ
+gC2AMtgAWgAOAIEAggBbAIMAWAB0AO4AhQDwAPEAiACJAPMA7oAugB6AL4AxCYAwgC7YAFoADgBzAFsA
+XABYADIAdADzAPcA+ACIAPkA8wD7APyAMIBCgDeAP4AwgEGAQF8QF3t7MTU3LCAxMTB9LCB7MTU0LCAx
+OX193ACOAA4AjwCQAJEAkgCTAJQAlQCWAJcAmACZAJoAmwCcAJ0AmwDIAKAA6wCiAKMApIAdgByAHIAi
+gBmALVtvcmRlckZyb250OtIANwA4AQcBCKMBCADnADVfEBVOU05pYkNvbnRyb2xDb25uZWN0b3LUAA4A
+3ADdAN4A6QBBAH4BDYAzgBCAFYA1WW9yZGVyT3V0OtQADgDcAN0A3gDfAO4AHwETgCuALoACgEPSAA4A
+PQB8ARaAI6IA6wEYgC2AONgAWgAOAIEAggBbAIMAWAB0AO4BGwEcAR0AiACJAPMA7oAugD6AOYA6CYAw
+gC5fEBZ7ezM1OSwgMTA4fSwgezk2LCAyMX193gEjAI4ADgEkASUAkwCUAJUBJgEnAJcBKAEpASoBKwCZ
+ASwBLQEuAJsBMAEYATIBMwEtATQBMwE0V05TVmFsdWVfEBNOU051bWJlck9mVGlja01hcmtzXxASTlNU
+aWNrTWFya1Bvc2l0aW9uWk5TTWF4VmFsdWVaTlNNaW5WYWx1ZVpOU1ZlcnRpY2FsXU5TQWx0SW5jVmFs
+dWVfEBpOU0FsbG93c1RpY2tNYXJrVmFsdWVzT25seSNASQAAAAAAAIA9EAAQAYAcgDuAOCNAWQAAAAAA
+ACMAAAAAAAAAAAgI1AAOAKcAqACpAKoAqwE4AK2AG4A8WUhlbHZldGljYdIANwA4ATsBPKQBPAC2AIIA
+NVxOU1NsaWRlckNlbGzSADcAOAE+AT+lAT8AugBkAGUANVhOU1NsaWRlclp7NDgwLCAyNzJ90gA3ADgB
+QgFDpAFDAGQAZQA1XE5TQ3VzdG9tVmlld1R2aWV30gAOAD0BRgFHgEeuAGsAfwEYAEAA7gFNAEwA8QEd
+AEEA6wCHAL8AfoASgB+AOIAHgC6ARYALgDGAOoAQgC2AF4AhgBXSAA4AMgAzAViABIBGXU5TQXBwbGlj
+YXRpb27SADcAOAFbAM+iAM8ANdIADgA9AUYBXoBHrgBBAGsA7gAfAB8AHwBAAOsBGAAfAO4AfgB/AGuA
+EIASgC6AAoACgAKAB4AtgDiAAoAugBWAH4AS0gAOAD0BRgFvgEevEA8AawB/ARgAQADuAU0ATADxAR0A
+QQAfAOsAvwB+AIeAEoAfgDiAB4AugEWAC4AxgDqAEIACgC2AIYAVgBfSAA4APQFGAYGAR68QDwGCAYMB
+hAGFAYYBhwGIAYkBigGLAYwBjQGOAY8BkIBLgEyATYBOgE+AUIBRgFKAU4BUgFWAVoBXgFiAWVxDb250
+ZW50IFZpZXdfECdSb3VuZCBSZWN0IEJ1dHRvbiAoUm91bmQgUmVjdCBCdXR0b24pLTFfEBFIb3Jpem9u
+dGFsIFNsaWRlcllGcmFuY2lzY29bQ3VzdG9tIFZpZXdbQXBwbGljYXRpb25eQ29udGVudCBWaWV3LTFf
+EB9CdXR0b24gQ2VsbCAoUm91bmQgUmVjdCBCdXR0b24pW1NsaWRlciBDZWxsXxAPV2luZG93IChXaW5k
+b3cpXEZpbGUncyBPd25lcl8QJVJvdW5kIFJlY3QgQnV0dG9uIChSb3VuZCBSZWN0IEJ1dHRvbilfECFC
+dXR0b24gQ2VsbCAoUm91bmQgUmVjdCBCdXR0b24pLTFfEBpSb3VuZCBSZWN0IEJ1dHRvbiAoeWlrZXMh
+KV8QFEJ1dHRvbiBDZWxsICh5aWtlcyEp0gAOAD0BRgGigEeg0gAOAD0BRgGlgEeg0gAOAD0BRgGogEev
+EBMAawB/ARgA2gDYAEAA2QDuAU0ATADXAPEBHQBBAB8A6wCHAH4Av4ASgB+AOIA2gCyAB4A0gC6ARYAL
+gCmAMYA6gBCAAoAtgBeAFYAh0gAOAD0BRgG+gEevEBMBvwHAAcEBwgHDAcQBxQHGAccByAHJAcoBywHM
+Ac0BzgHPAdAB0YBegF+AYIBhgGKAY4BkgGWAZoBngGiAaYBqgGuAbIBtgG6Ab4BwEA0QGRAKEBQQFhAO
+EBgT//////////0QFRAJEAsQDBAbEAgQERAa0gAOAD0AfAHkgCOg0gAOAD0BRgHngEeg0gAOAD0BRgHq
+gEeg0gA3ADgB7AHtogHtADVeTlNJQk9iamVjdERhdGEACAAZACIAJwAxADoAPwBEAFIAVABmAVMBWQGk
+AasBsgHAAdIB7gH8AggCFAIiAi0COwJXAmUCeAKKAqQCrgK7Ar0CvwLBAsMCxQLHAskCywLNAs8C0QLT
+AtUC1wLZAtsC3QLfAugC9AL2AvgDAQMKAxMDHgMjAzIDRQNOA1kDWwNgA2IDZAONA5oDpwO1A78DzQPa
+A+wEAAQMBA4EEAQSBBQEGQQbBB0EHwQhBCMEPgRFBE4EXwRxBHoEhgSIBIoEjQSPBJoEowSqBLEEvQTW
+BN8E5AT3BSAFIgUkBSYFKAUqBSwFLgVLBVYFYgVkBWYFaAVqBWwFbgV3BXkFfgWABYIFowWrBbIFvAW+
+BcAFwgXEBccFyAXKBcwF5gYXBiMGOQZOBl0GbwZ6BoQGkgakBrEGvwbIBsoGzAbOBtAG0gbUBtYG2Abb
+BuAG6QbwBwEHCAcPBxgHGgcjByUHJwc0Bz0HQgdJB0oHUwdcB2kHdgd/B4oHkwedB74HwAfCB8QHxgfH
+B8kHywfjCBQIFggYCBoIHAgeCCAINAg9CEQIUwhbCGQIawh4CH4IhwiJCJIIlAiWCJgImgirCLkIwgjK
+CMwIzgjQCNII2QjiCOkJAAkPCSAJIgkkCSYJKAlJCUsJTQlPCVEJUglUCVYJdwl5CXsJfQl/CYEJgwmF
+CZ8J0AnSCdQJ1gnYCdoJ3AnoCfEJ+AoQCiEKIwolCicKKQozCkQKRgpICkoKTApVClcKXApeCmAKgQqD
+CoUKhwqJCooKjAqOCqcK4AroCv4LEwseCykLNAtCC18LaAtqC2wLbgtwC3ILdAt9C4YLhwuIC5kLmwud
+C6cLsAu5C8YLzwvaC+ML7gv3DAAMDQwSDBsMHQw6DDwMPgxADEIMRAxGDEgMSgxMDE4MUAxSDFQMVgxf
+DGEMYwxxDHoMfwyIDIoMpwypDKsMrQyvDLEMswy1DLcMuQy7DL0MvwzBDMMMzAzODO8M8QzzDPUM9wz5
+DPsM/Qz/DQENAw0FDQcNCQ0LDQ0NFg0YDTkNOw09DT8NQQ1DDUUNRw1JDUsNTQ1PDVENUw1VDVcNZA2O
+DaINrA24DcQN0w31DgEOEw4gDkgObA6JDqAOqQ6rDqwOtQ63DrgOwQ7DDuwO7g7wDvIO9A72DvgO+g78
+Dv4PAA8CDwQPBg8IDwoPDA8ODxAPEg8bDx0PRg9ID0oPTA9OD1APUg9UD1YPWA9aD1wPXg9gD2IPZA9m
+D2gPag9sD24PcA9yD3QPdg94D3oPgw+FD4cPiQ+LD40Pjw+RD5MPnA+eD58PqA+qD6sPtA+2D7cPwA/F
+AAAAAAAAAgIAAAAAAAAB7gAAAAAAAAAAAAAAAAAAD9Q
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/TextMate/JavaScript Objective-J.tmbundle.zip b/Tools/TextMate/JavaScript Objective-J.tmbundle.zip
index 10319c643..e26fd961c 100644
Binary files a/Tools/TextMate/JavaScript Objective-J.tmbundle.zip and b/Tools/TextMate/JavaScript Objective-J.tmbundle.zip differ
diff --git a/Tools/nib2cib/NSAppKit.j b/Tools/nib2cib/NSAppKit.j
index f11e4b92d..efb30c17b 100644
--- a/Tools/nib2cib/NSAppKit.j
+++ b/Tools/nib2cib/NSAppKit.j
@@ -23,9 +23,24 @@
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"
+import "NSSplitView.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..58b5f600c
--- /dev/null
+++ b/Tools/nib2cib/NSCustomObject.j
@@ -0,0 +1,34 @@
+
+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];
+}
+
+@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/NSSplitView.j b/Tools/nib2cib/NSSplitView.j
new file mode 100644
index 000000000..8dc7d83ab
--- /dev/null
+++ b/Tools/nib2cib/NSSplitView.j
@@ -0,0 +1,55 @@
+/*
+ * NSSplitView.j
+ * nib2cib
+ *
+ * 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
+
+
+@implementation CPSplitView (CPCoding)
+
+- (id)NS_initWithCoder:(CPCoder)aCoder
+{
+ if (self = [super NS_initWithCoder:aCoder])
+ {
+ _isVertical = [aCoder decodeBoolForKey:@"NSIsVertical"];
+ _isPaneSplitter = [aCoder decodeIntForKey:@"NSDividerStyle"] == 2 ? YES : NO;
+ }
+
+ return self;
+}
+
+@end
+
+@implementation NSSplitView : CPSplitView
+{
+}
+
+- (id)initWithCoder:(CPCoder)aCoder
+{
+ return [self NS_initWithCoder:aCoder];
+}
+
+- (Class)classForKeyedArchiver
+{
+ return [CPSplitView class];
+}
+
+@end
diff --git a/Tools/nib2cib/NSView.j b/Tools/nib2cib/NSView.j
index 4d92d3010..dc8eb9058 100644
--- a/Tools/nib2cib/NSView.j
+++ b/Tools/nib2cib/NSView.j
@@ -41,6 +41,11 @@ import
if (self)
{
+ _tag = -1;
+
+ if([aCoder containsValueForKey:@"NSTag"])
+ _tag = [aCoder decodeIntForKey:@"NSTag"];
+
_bounds = CGRectMake(0.0, 0.0, CGRectGetWidth(_frame), CGRectGetHeight(_frame));
_window = [aCoder decodeObjectForKey:@"NSWindow"];
diff --git a/Tools/nib2cib/NSWindowTemplate.j b/Tools/nib2cib/NSWindowTemplate.j
new file mode 100644
index 000000000..9a8b7b2e7
--- /dev/null
+++ b/Tools/nib2cib/NSWindowTemplate.j
@@ -0,0 +1,54 @@
+
+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];
+}
+
+- (Class)classForKeyedArchiver
+{
+ return [_CPCibWindowTemplate class];
+}
+
+@end
diff --git a/Tools/nib2cib/main.j b/Tools/nib2cib/main.j
index 8a822799d..43866e029 100644
--- a/Tools/nib2cib/main.j
+++ b/Tools/nib2cib/main.j
@@ -30,6 +30,7 @@ import "NSAppKit.j"
importClass(java.io.FileWriter);
importClass(java.io.BufferedWriter);
+CPLogRegister(CPLogPrint);
function exec(command)
{