Compare commits

..
89 Commits
Author SHA1 Message Date
release be0b97cb56 Changed version number to 1.0.0.019 2011-09-20 04:55:07 -05:00
Aparajita Fishman 6f7cbe21ef Main Jakefile improvements...
- 'jake clean' now cleans only the .build directories instead of doing the same as clobber.
- Added task 'clean-sprites', cleans sprited images.
- Added task 'clobber-theme', clobbers all Aristo.blend and Aristo.build directories.
2011-09-19 21:38:35 -07:00
Aparajita Fishman eff3dfc74a Merge branch 'master' of github.com:intalio/cappuccino 2011-09-19 11:12:57 -07:00
Aparajita Fishman 2ad1f4e4e5 Merge branch 'master' of github.com:cappuccino/cappuccino
Conflicts:
	Tests/Manual/CPTokenFieldTest/AppController.j
2011-09-18 16:04:42 -07:00
Alexander Ljungberg 4aec3f7466 Refs #1355. Manual window title test.
In the PlatformWindows test, change the window title both when theWindow is a non platform window and when it is a platform window to verify that the browser window title changes only when it should.
2011-09-17 11:07:38 +01:00
Alexander Ljungberg c8991e07b9 Merge pull request #1355 from primalmotion/cappuccino
---

if setTitle: is called on a CPWindow with the primaryPlatformWindow as platformWindow,
the main pages title is changed. This patch prevent changing the primaryPlatformWindows title.
This is not optimal, but this is better than changing the title at each window setTitle: call
2011-09-17 10:55:43 +01:00
Alexander Ljungberg 48157db973 Refs #1360. Fixed: index was always 0 in CPTokenField tokenField:shouldAddObjects:atIndex: delegate method. 2011-09-16 21:52:09 +01:00
Alexander Ljungberg d070e5fce5 Merge branch 'master' of github.com:cappuccino/cappuccino 2011-09-16 21:47:20 +01:00
Alexander Ljungberg a8fae51ea8 Refs #1360. Cursor movement fixes, optimisations.
Don't move the cursor forward if no token was inserted. Only count new tokens once.
2011-09-16 21:46:20 +01:00
Alexander Ljungberg 2815d462be Refs #1360. Test for CPTokenField tokenField:shouldAddObjects:atIndex:. 2011-09-16 20:51:45 +01:00
release ed002d7d3e Changed version number to 1.0.0.019-SNAPSHOT 2011-09-16 13:44:57 -05:00
release a7994c1480 Changed version number to 1.0.0.018 2011-09-16 13:44:51 -05:00
Alexander Ljungberg 85f8ca9241 Refs #1360. Format code. 2011-09-16 19:29:53 +01:00
Alexander Ljungberg b5fb9e8c23 Merge pull request #1360 from jigzat/cappuccino
---

Enabled tokenField:shouldAddObjects:atIndex delegate method and used on _autocompleteWithDOMEvent method to have some control over tokens. Not sure why wasnt enabled, it needed very few code. Maybe no one needed it til now.

This is my first collaboration ever, so Im not sure if is of any use.
2011-09-16 19:10:23 +01:00
release c605ca4531 Changed version number to 1.0.0.018-SNAPSHOT 2011-09-16 12:37:07 -05:00
release c288930a3c Changed version number to 1.0.0.017 2011-09-16 12:36:59 -05:00
release 596676a562 Changed version number to 1.0.0.017-SNAPSHOT 2011-09-16 06:01:02 -05:00
release cc3d9f337c Changed version number to 1.0.0.016 2011-09-16 06:00:55 -05:00
Klaas Pieter Annema 1addc002d3 Merge branch 'master' of github.com:cappuccino/cappuccino 2011-09-16 12:00:05 +02:00
Klaas Pieter Annema e99e2660e9 more fixes and tests for _CPKVCArray 2011-09-16 11:43:42 +02:00
Aparajita Fishman 03d1bb8bce Added missing statement separator, concatenated var block, fixed symlink deletion/creation sometimes failing. 2011-09-15 17:09:15 -07:00
Aparajita Fishman 8d210100a5 Fix for symlink creation sometimes failing. 2011-09-15 16:41:52 -07:00
Aparajita Fishman d25e96902f Added missing statement separator, concatenated var block 2011-09-15 14:56:24 -07:00
Aparajita Fishman ad792d9772 Fixed problem with FILE.remove sometimes failing to delete the symbolic link. 2011-09-15 14:28:57 -07:00
Klaas Pieter Annema 5b00f7f2e8 improve _CPKVCArray
_CPKVCArray now consistently calls both single and multiple indexes accessors consistently
Tests that verify the behavior are included
2011-09-15 22:32:23 +02:00
Klaas Pieter Annema 97b7f0901e add tests for key view loop behavior 2011-09-15 17:50:37 +02:00
Klaas Pieter Annema 67b2671dad improve key view loops
- include the window's content view at the start of the key view loop
- set the initial first responder to the window's content view (and keep it that way unless it is explicitly changed)
- CPWindow should return NO from acceptsFirstResponder (Cocoa compliance).
- change the type of setInitialFirstResponder, this is compliant with Cocoa. The new key view loop code will break if initial first responder is anything but a view
- change the implementation of selectNextKeyView:, selectPreviousKeyView:, selectKeyViewFollowingView: and selectKeyViewPrecedingView: to follow to Cocoa's documentation
2011-09-15 16:39:24 +02:00
Aparajita Fishman 9e7b737960 Merge branch 'master' of github.com:intalio/cappuccino 2011-09-13 12:36:53 -07:00
release 9bc6a69b76 Changed version number to 1.0.0.016-SNAPSHOT 2011-09-10 05:58:01 -05:00
release 1cb28e4206 Changed version number to 1.0.0.015 2011-09-10 05:57:56 -05:00
release 5311689265 Changed version number to 1.0.0.015-SNAPSHOT 2011-09-10 04:58:47 -05:00
release 4228a2a146 Changed version number to 1.0.0.014 2011-09-10 04:58:42 -05:00
aparajita 7886d49e65 Merge pull request #1359 from primalmotion/fix-and-improve-doxygen-theme
Fix and improve doxygen theme
2011-09-09 21:48:17 -07:00
Samir Gartner e5284e9b43 Fixed some possible error of my part where selectedRange is moved beyond bounds 2011-09-09 22:31:17 -05:00
Samir Gartner c6403baa04 Fixed cursor position issue in a little escapade...guess that's all for now folks 2011-09-09 13:28:37 -05:00
Samir Gartner 662b1ec696 Submitted the right CPTokenField file, was missing the part to use the delegate approved tokens. Still lacks a way to put the cursor after the last token (if the delegate returns more than one token) 2011-09-09 12:48:18 -05:00
Samir Gartner 043df71185 Enabled tokenField:shouldAddObjects:atIndex delegate method and used on _autocompleteWithDOMEvent method to have some control over tokens. Not sure why wasn't enabled, it was very few code. Maybe no one needed it 'til now 2011-09-08 22:56:52 -05:00
Antoine Mercadal 8dab47f4da mozilla compat 2011-09-08 18:12:32 +02:00
Alexander Ljungberg 90d069df2b Refs #1343. Remove now obsolete README.md.
Everything in the README has been fixed except 3 and 4. 4 is outside of the issue scope and 3 works as intended (nearly). The array controller does not have `setAvoidsEmptySelection:NO` so an empty selection should not be possible unless there are no items.
2011-09-08 17:02:15 +01:00
Antoine Mercadal dcbe3ee650 fix paremeters touching their description in bubbles 2011-09-08 17:15:12 +02:00
Antoine Mercadal e32489aba1 tiny padding improvment in generated html docs 2011-09-08 17:08:50 +02:00
Antoine Mercadal b619c0b793 some small graphical improvments 2011-09-08 16:55:12 +02:00
Antoine Mercadal fab61d14fa forget to restore the bg color of the tree view 2011-09-08 14:44:05 +02:00
Antoine Mercadal b4edc084f8 add Cappuccino logo 2011-09-08 14:00:20 +02:00
Antoine Mercadal c7518d0c49 merge Aparajita's previous improvments on the CSS 2011-09-08 12:44:10 +02:00
Antoine Mercadal a40345c14d fix the slider 2011-09-08 11:46:20 +02:00
Aparajita Fishman bacc50c271 Merge remote branch 'refs/remotes/cappuccino/master'
Conflicts:
	AppKit/CPArrayController.j
	Foundation/CPKeyValueObserving.j
	Tests/Manual/Bindings/AppController.j
2011-09-07 22:04:42 -04:00
Antoine Mercadal 909471a5d7 fix the documentation generation process 2011-09-08 01:30:58 +02:00
Antoine Mercadal 38f7ea00c2 update doxygen.css 2011-09-08 00:43:32 +02:00
Alexander Ljungberg 9f459f053e Fixed: several CPArrayController methods returned undefined instead of booleans. 2011-09-07 18:17:35 +01:00
Alexander Ljungberg 4195f3b8c6 Test that CPArrayController setSelectionIndexes: does not modify its input. 2011-09-07 18:02:53 +01:00
Alexander Ljungberg 4926824482 Fixed: CPArrayController setSelectionIndexes: sometimes modified its input.
Also very slightly improved performance as sometimes the input index set would be instantiated internally and then needlessly copied.
2011-09-07 17:53:48 +01:00
Alexander Ljungberg cb2f539cf7 Send didChange in reverse order of willChange in CPObjectController setContent:. 2011-09-07 17:32:19 +01:00
Alexander Ljungberg 7f31be7cb1 Fixed: array replaceObjectsInRange:withObjectsFromArray: always failed with a "'null' is not an object' error.
This was caused by the new range checks in f8404c7a97.
2011-09-07 16:18:08 +01:00
Alexander Ljungberg 78b9c5b576 Fixes #1343. Support nested willChange… didChange… calls.
When multiple calls are nested, only the first willChange… and the last didChange… will notify observers, avoiding duplicate notifications for the same change.
2011-09-07 16:14:01 +01:00
Alexander Ljungberg 01e35efdbb Refs #1343. Recreate manual bindings test as an automatic test. 2011-09-07 16:04:35 +01:00
Aparajita FishmanandAlexander Ljungberg bef1687b1f Test app for bindings fixes. 2011-09-07 12:51:36 +01:00
release da18a9eb24 Changed version number to 1.0.0.014-SNAPSHOT 2011-09-07 06:16:58 -05:00
release d975e90407 Changed version number to 1.0.0.013 2011-09-07 06:16:52 -05:00
Shao Fang abc8e14275 Change version back to 13-SNAPSHOT to prepare for next build. 2011-09-06 18:57:58 -07:00
Shao Fang b032cd5b7d Manually bump up the version to 1.0.0.012 and see if this helps. 2011-09-05 22:25:27 -07:00
release bb589285e3 Changed version number to 1.0.0.011-SNAPSHOT 2011-09-05 22:00:00 -05:00
release 1d52c3e957 Changed version number to 1.0.0.010 2011-09-05 21:59:49 -05:00
Aparajita Fishman df5ce9e0f3 Merge branch 'master' of github.com:intalio/cappuccino 2011-09-05 10:15:27 -04:00
Aparajita Fishman 16b446ae08 Finished CPComboBox, reworked _CPPopUpList to be more generic, factored some code from CPComboBox to _CPPopUpList 2011-09-05 02:02:05 -04:00
Antoine Mercadal afa691376e fix unable to change mainWindow's title 2011-09-02 14:00:49 +02:00
Antoine Mercadal be10bcf27a Fix CPPlatformWindow's title bug
if setTitle: is called on a CPWindow with the primaryPlatformWindow as platformWindow,
the main page's title is changed. This patch prevent changing the primaryPlatformWindow's title.
This is not optimal, but this is better than changing the title at each window setTitle: call
2011-09-02 12:42:09 +02:00
Aparajita Fishman d0a5b6e1c7 Added test app. 2011-09-02 03:41:17 -04:00
Aparajita Fishman 271a1ef3b4 Cocoa always sends NSControlTextDidEndEditingNotification and the action when resigning, whether or not editing had begun. 2011-09-02 02:48:34 -04:00
Aparajita Fishman b91042eb08 Merge remote branch 'refs/remotes/cappuccino/master' 2011-09-02 02:48:20 -04:00
Alexander Ljungberg 608cb86a4a Whitespace cleanup. 2011-08-31 18:51:15 +01:00
Alexander Ljungberg 88780ff0a9 Merge pull request #1352 from primalmotion/cappuccino
---

In latest versions of webkit window.open(url) return undefined if url == ""
2011-08-31 18:47:43 +01:00
Antoine Mercadal a5e241afd7 update PlatformWindows test (use the slider to play with the titles) 2011-08-31 19:17:41 +02:00
Antoine Mercadal 28772d3254 use CPWindow's title for platform window 2011-08-31 19:17:10 +02:00
Antoine Mercadal d1f5c1eebc patch for enventual webkit bug with window.open() 2011-08-31 18:28:47 +02:00
release d40ebaf369 Changed version number to 1.0.0.010-SNAPSHOT 2011-08-29 16:34:09 -05:00
release 06f74e5ef0 Changed version number to 1.0.0.009 2011-08-29 16:34:00 -05:00
release 5eaeb5f05e Changed version number to 1.0.0.009-SNAPSHOT 2011-08-29 15:42:45 -05:00
release 961cb2f6ed Changed version number to 1.0.0.008 2011-08-29 15:42:34 -05:00
alenovo 4dca2bbb85 Edited Buildfile via GitHub 2011-08-29 22:25:30 -03:00
alenovo 892d3d7120 Edited Buildfile via GitHub 2011-08-29 21:46:34 -03:00
alenovo c0fe499937 Edited Buildfile via GitHub 2011-08-29 21:26:34 -03:00
alenovo 01e8e9e597 Edited Buildfile via GitHub 2011-08-29 21:25:32 -03:00
alenovo 08b740c36f Edited Buildfile via GitHub 2011-08-29 21:24:23 -03:00
alenovo 31918bc0cd Edited Buildfile via GitHub 2011-08-29 21:22:21 -03:00
aparajita d45aeed224 Merge pull request #1 from correa-intalio/master
Changing version number
2011-08-29 07:47:40 -07:00
Diego Martin Correa 7d2835c522 Changing version numbre to complete build process 2011-08-29 11:45:47 -03:00
Alexander Ljungberg c77a282aaf Raise CPRangeException if CPString substringToIndex: is out of bounds. 2011-08-27 23:50:18 +01:00
Alexander Ljungberg 7a1cd5c545 Fix CPString substringToIndex documentation. The index parameter is not inclusive. 2011-08-27 23:49:40 +01:00
46 changed files with 3566 additions and 1016 deletions
+70 -108
View File
@@ -27,7 +27,6 @@
@import "CPObjectController.j"
@import "CPKeyValueBinding.j"
/*!
@class CPArrayController
@@ -285,7 +284,8 @@
if (value === nil)
value = [];
else if (![value isKindOfClass:[CPArray class]])
if (![value isKindOfClass:[CPArray class]])
value = [value];
var oldSelectedObjects = nil,
@@ -339,6 +339,14 @@
[self setContent:anArray];
}
/*!
@ignore
*/
- (void)_setContentSet:(id)aSet
{
[self setContent:[aSet allObjects]];
}
/*!
Returns the content array of the controller.
@return id the content array of the receiver
@@ -348,14 +356,6 @@
return [self content];
}
/*!
@ignore
*/
- (void)_setContentSet:(id)aSet
{
[self setContent:[aSet allObjects]];
}
/*!
Returns the content of the receiver as a CPSet.
@@ -564,13 +564,9 @@
- (BOOL)setSelectionIndexes:(CPIndexSet)indexes
{
[self _selectionWillChange]
// When explicitly setting the selection, ignore avoidsEmptySelection
var changed = [self __setSelectionIndexes:indexes obeyAvoidsEmptySelection:NO];
[self _selectionDidChangeNotify:NO];
return changed;
var r = [self __setSelectionIndexes:indexes];
[self _selectionDidChange];
return r;
}
/*
@@ -579,7 +575,7 @@
*/
- (BOOL)__setSelectionIndex:(int)theIndex
{
return [self __setSelectionIndexes:[CPIndexSet indexSetWithIndex:theIndex] obeyAvoidsEmptySelection:YES];
return [self __setSelectionIndexes:[CPIndexSet indexSetWithIndex:theIndex]];
}
/*
@@ -588,37 +584,38 @@
*/
- (BOOL)__setSelectionIndexes:(CPIndexSet)indexes
{
[self __setSelectionIndexes:indexes obeyAvoidsEmptySelection:YES];
}
var newIndexes = indexes;
/*
Like setSelectionIndexes but don't fire any change notifications.
@ignore
*/
- (BOOL)__setSelectionIndexes:(CPIndexSet)indexes obeyAvoidsEmptySelection:(BOOL)obeyAvoidsEmptySelection
{
if (!indexes)
indexes = [CPIndexSet indexSet];
if (!newIndexes)
newIndexes = [CPIndexSet indexSet];
if (![indexes count])
if (![newIndexes count])
{
if (obeyAvoidsEmptySelection && _avoidsEmptySelection && [[self arrangedObjects] count])
indexes = [CPIndexSet indexSetWithIndex:0];
if (_avoidsEmptySelection && [[self arrangedObjects] count])
newIndexes = [CPIndexSet indexSetWithIndex:0];
}
else
{
var objectsCount = [[self arrangedObjects] count];
// Don't trash the input - the caller might depend on it or we might have been
// given _selectionIndexes as the input in which case the equality test below
// would always succeed despite our change below.
newIndexes = [newIndexes copy];
// Remove out of bounds indexes.
[indexes removeIndexesInRange:CPMakeRange(objectsCount, [indexes lastIndex] + 1)];
[newIndexes removeIndexesInRange:CPMakeRange(objectsCount, [newIndexes lastIndex] + 1)];
// When avoiding empty selection and the deleted selection was at the bottom, select the last item.
if (![indexes count] && _avoidsEmptySelection && objectsCount)
indexes = [CPIndexSet indexSetWithIndex:objectsCount - 1];
if (![newIndexes count] && _avoidsEmptySelection && objectsCount)
newIndexes = [CPIndexSet indexSetWithIndex:objectsCount - 1];
}
if ([_selectionIndexes isEqualToIndexSet:indexes])
if ([_selectionIndexes isEqualToIndexSet:newIndexes])
return NO;
_selectionIndexes = [indexes copy];
// If we haven't already created our own index instance, make sure to copy it here so that
// the copy the user sent in is decoupled from our internal copy.
_selectionIndexes = indexes === newIndexes ? [indexes copy] : newIndexes;
// Push back the new selection to the model for selectionIndexes if we have one.
// There won't be an infinite loop because of the equality check above.
@@ -650,10 +647,11 @@
[self willChangeValueForKey:@"selectionIndexes"];
[self _selectionWillChange];
[self __setSelectedObjects:objects obeyAvoidsEmptySelection:NO];
var r = [self __setSelectedObjects:objects];
[self didChangeValueForKey:@"selectionIndexes"];
[self _selectionDidChangeNotify:NO];
[self _selectionDidChange];
return r;
}
/*
@@ -661,15 +659,6 @@
@ignore
*/
- (BOOL)__setSelectedObjects:(CPArray)objects
{
[self __setSelectedObjects:objects obeyAvoidsEmptySelection:YES];
}
/*
Like setSelectedObjects but don't fire any change notifications.
@ignore
*/
- (BOOL)__setSelectedObjects:(CPArray)objects obeyAvoidsEmptySelection:(BOOL)obeyAvoidsEmptySelection
{
var set = [CPIndexSet indexSet],
count = [objects count],
@@ -683,7 +672,7 @@
[set addIndex:index];
}
[self __setSelectionIndexes:set obeyAvoidsEmptySelection:obeyAvoidsEmptySelection];
[self __setSelectionIndexes:set];
return YES;
}
@@ -752,13 +741,21 @@
}
[self willChangeValueForKey:@"content"];
[self _willModifyContent];
/*
If the content array is bound then our addObject: message below will cause the observed
array to change. The binding will call setContent:_contentObject on this array
controller to let it know about the change. We want to ignore that message since we
A) already have the right _contentObject and B) properly update _arrangedObjects
by hand below.
*/
_disableSetContent = YES;
[_contentObject addObject:object];
// Allow handlesContentAsCompoundValue reverse sets to trigger.
[[CPBinder getBinding:@"contentArray" forObject:self] _contentArrayDidChange];
[self _didModifyContent];
_disableSetContent = NO;
if (willClearPredicate)
{
@@ -779,15 +776,14 @@
[_selectionIndexes shiftIndexesStartingAtIndex:pos by:1];
}
/*
else if (_filterPredicate !== nil)
...
Implies _filterPredicate && ![_filterPredicate evaluateWithObject:object], so the new object does
not appear in arrangedObjects and we do not have to update at all.
else if (_filterPredicate !== nil)
...
// Implies _filterPredicate && ![_filterPredicate evaluateWithObject:object], so the new object does
// not appear in arrangedObjects and we do not have to update at all.
*/
// This will also send notificaitons for arrangedObjects.
[self didChangeValueForKey:@"content"];
if (willClearPredicate)
[self didChangeValueForKey:@"filterPredicate"];
}
@@ -813,7 +809,10 @@
[self willChangeValueForKey:@"content"];
[self _willModifyContent];
/*
See _disableSetContent explanation in addObject:.
*/
_disableSetContent = YES;
// The atArrangedObjectIndex: part of this method's name only refers to where the
// object goes in arrangedObjects, not in the content array. So use addObject:,
@@ -822,7 +821,7 @@
// Allow handlesContentAsCompoundValue reverse sets to trigger.
[[CPBinder getBinding:@"contentArray" forObject:self] _contentArrayDidChange];
[self _didModifyContent];
_disableSetContent = NO;
if (willClearPredicate)
[self __setFilterPredicate:nil];
@@ -840,7 +839,6 @@
[self __setSelectionIndexes:[CPIndexSet indexSetWithIndex:0]];
[self didChangeValueForKey:@"content"];
if (willClearPredicate)
[self didChangeValueForKey:@"filterPredicate"];
}
@@ -853,13 +851,15 @@
- (void)removeObject:(id)object
{
[self willChangeValueForKey:@"content"];
[self _willModifyContent];
// See _disableSetContent explanation in addObject:.
_disableSetContent = YES;
[_contentObject removeObject:object];
// Allow handlesContentAsCompoundValue reverse sets to trigger.
[[CPBinder getBinding:@"contentArray" forObject:self] _contentArrayDidChange];
[self _didModifyContent];
_disableSetContent = NO;
if (_filterPredicate === nil || [_filterPredicate evaluateWithObject:object])
{
@@ -910,15 +910,6 @@
[self removeObjectsAtArrangedObjectIndexes:_selectionIndexes];
}
/*!
Removes the object at the specified index in the controller's arranged objects from the content array.
@param int index - index of the object to remove.
*/
- (void)removeObjectAtArrangedObjectIndex:(int)index
{
[self removeObjectsAtArrangedObjectIndexes:[CPIndexSet indexSetWithIndex:index]];
}
/*!
Removes the objects at the specified indexes in the controller's arranged objects from the content array.
@param CPIndexSet indexes - indexes of the objects to remove.
@@ -927,21 +918,20 @@
{
[self willChangeValueForKey:@"content"];
/*
See _disableSetContent explanation in addObject:.
*/
_disableSetContent = YES;
var arrangedObjects = [self arrangedObjects],
index = [anIndexSet lastIndex],
position = CPNotFound,
newSelectionIndexes = [_selectionIndexes copy],
proxy = [_CPKVOProxy proxyForObject:self];
newSelectionIndexes = [_selectionIndexes copy];
while (index !== CPNotFound)
{
var object = [arrangedObjects objectAtIndex:index];
// Make sure arrangedObjects does not notify because of content change
[proxy suppressNotificationsForKeyPath:@"arrangedObjects"];
// First try the simple case which should work if there are no sort descriptors.
if ([_contentObject objectAtIndex:index] === object)
[_contentObject removeObjectAtIndex:index];
@@ -955,9 +945,6 @@
contentIndex = [_contentObject indexOfObjectIdenticalTo:object];
[_contentObject removeObjectAtIndex:contentIndex];
}
// Now arrangedObjects can notify
[proxy unsuppressNotificationsForKeyPath:@"arrangedObjects"];
[arrangedObjects removeObjectAtIndex:index];
// Deselect this row if it was selected, and either way shift all selection indexes
@@ -967,7 +954,6 @@
index = [anIndexSet indexLessThanIndex:index];
}
// Allow handlesContentAsCompoundValue reverse sets to trigger.
[[CPBinder getBinding:@"contentArray" forObject:self] _contentArrayDidChange];
_disableSetContent = NO;
@@ -1014,13 +1000,15 @@
- (void)_removeObjects:(CPArray)objects
{
[self willChangeValueForKey:@"content"];
[self _willModifyContent];
// See _disableSetContent explanation in addObject:.
_disableSetContent = YES;
[_contentObject removeObjectsInArray:objects];
// Allow handlesContentAsCompoundValue reverse sets to trigger.
[[CPBinder getBinding:@"contentArray" forObject:self] _contentArrayDidChange];
[self _didModifyContent];
_disableSetContent = NO;
var arrangedObjects = [self arrangedObjects],
position = [arrangedObjects indexOfObject:[objects objectAtIndex:0]];
@@ -1057,39 +1045,13 @@
return [self isEditable];
}
// Internal
- (void)_willModifyContent
{
/*
If the content array is bound then our addObject: message below will cause the observed
array to change. The binding will call setContent:_contentObject on this array
controller to let it know about the change. We want to ignore that message since we
A) already have the right _contentObject and B) properly update _arrangedObjects
by hand below.
*/
_disableSetContent = YES;
/*
When mutating arrangedObjects, we mutate the content first. But mutating the content
will trigger a notification that the arrangedObjects have changed, which we want to
suppress, since the arrangedObjects mutation will do the correct notification.
*/
[[_CPKVOProxy proxyForObject:self] suppressNotificationsForKeyPath:@"arrangedObjects"];
}
- (void)_didModifyContent
{
_disableSetContent = NO;
[[_CPKVOProxy proxyForObject:self] unsuppressNotificationsForKeyPath:@"arrangedObjects"];
}
@end
@implementation CPArrayController (CPBinder)
+ (Class)_binderClassForBinding:(CPString)theBinding
{
if (theBinding === @"content" || theBinding === @"contentArray")
if (theBinding == @"contentArray")
return [_CPArrayControllerContentBinder class];
return [super _binderClassForBinding:theBinding];
@@ -1104,7 +1066,7 @@
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
options = [_info objectForKey:CPOptionsKey],
isCompound = [self handlesContentAsCompoundValue] || keyPath.indexOf("@") !== -1;
isCompound = [self handlesContentAsCompoundValue];
if (!isCompound)
{
+53 -88
View File
@@ -389,12 +389,12 @@ var CPComboBoxTextSubview = @"text",
_listDelegate = aDelegate;
[defaultCenter addObserver:self
selector:@selector(listWillPopUp:)
selector:@selector(comboBoxWillPopUp:)
name:_CPPopUpListWillPopUpNotification
object:_listDelegate];
[defaultCenter addObserver:self
selector:@selector(listWillDismiss:)
selector:@selector(comboBoxWillDismiss:)
name:_CPPopUpListWillDismissNotification
object:_listDelegate];
@@ -467,7 +467,7 @@ var CPComboBoxTextSubview = @"text",
- (void)popUpList
{
if (!_listDelegate)
[self setListDelegate:[[_CPPopUpList alloc] initWithDelegate:self]];
[self setListDelegate:[[_CPPopUpList alloc] initWithDataSource:self]];
[self selectMatchingItem];
@@ -521,24 +521,6 @@ var CPComboBoxTextSubview = @"text",
return YES;
}
/*!
The receiver receives this notification when the list is about to be pop up.
@ignore
*/
- (void)listWillPopUp:(CPNotification)aNotification
{
[self comboBoxWillPopUp];
}
/*!
The receiver receives this notification when the list is about to be dismissed.
@ignore
*/
- (void)listWillDismiss:(CPNotification)aNotification
{
[self comboBoxWillDismiss];
}
/*!
The receiver receives this notification when the list is closed.
@ignore
@@ -731,7 +713,10 @@ var CPComboBoxTextSubview = @"text",
[super textDidChange:aNotification];
}
/*! @ignore */
/*!
Override of CPView -performKeyEquivalent
@ignore
*/
- (BOOL)performKeyEquivalent:(CPEvent)anEvent
{
if ([[self window] firstResponder] === self)
@@ -741,17 +726,9 @@ var CPComboBoxTextSubview = @"text",
switch (key)
{
case CPDownArrowFunctionKey:
if ([self listIsVisible])
[_listDelegate selectNextItem];
else
[self popUpList];
return YES;
case CPUpArrowFunctionKey:
if ([self listIsVisible])
if (![self listIsVisible])
{
[_listDelegate selectPreviousItem];
[self popUpList];
return YES;
}
break;
@@ -763,44 +740,12 @@ var CPComboBoxTextSubview = @"text",
// in the list, revert to the most recent valid value.
if (_forceSelection && ([self _inputElement].value !== _selectedStringValue))
[self setStringValue:_selectedStringValue];
[_listDelegate close];
return YES;
}
break;
case CPPageUpFunctionKey:
if ([self listIsVisible])
{
[_listDelegate scrollPageUp];
return YES;
}
break;
case CPPageDownFunctionKey:
if ([self listIsVisible])
{
[_listDelegate scrollPageDown];
return YES;
}
break;
case CPHomeFunctionKey:
if ([self listIsVisible])
{
[_listDelegate scrollToTop];
return YES;
}
break;
case CPEndFunctionKey:
if ([self listIsVisible])
{
[_listDelegate scrollToBottom];
return YES;
}
break;
}
if ([_listDelegate performKeyEquivalent:anEvent])
return YES;
}
return [super performKeyEquivalent:anEvent];
@@ -817,18 +762,15 @@ var CPComboBoxTextSubview = @"text",
If the list or popup button is clicked, we lose focus. The list will refuse first responder,
and we refuse to resign. But we still have to manually restore the focus to the input element.
*/
if ([_listDelegate listWasClicked] || buttonCausedResign)
{
/*
If an item was not clicked (probably the scrollbar), clear the click flag so that future
clicks outside the list will allow it to close. It isn't so great doing that here, but
the sequence of events is such that it has to be done here.
*/
if ([_listDelegate listWasClicked] && ![_listDelegate itemWasClicked])
[_listDelegate setListWasClicked:NO];
var shouldResign = !buttonCausedResign && [_listDelegate controllingViewShouldResign];
if (!shouldResign)
{
#if PLATFORM(DOM)
[self _inputElement].focus();
// In FireFox this needs to be done in setTimeout, otherwise there is no caret
// We have to save the input element now, when we lose focus it will change.
var element = [self _inputElement];
window.setTimeout(function() { element.focus(); }, 0);
#endif
return NO;
@@ -917,14 +859,6 @@ var CPComboBoxTextSubview = @"text",
CPLog.warn("-[%s %s] should not be called when usesDataSource is set to %s", [self className], cmd, flag ? "YES" : "NO");
}
- (id)objectValueForItemAtIndex:(int)index
{
if (_usesDataSource)
return [_dataSource comboBox:self objectValueForItemAtIndex:index];
else
return _items[index];
}
/*!
Select the item that matches the current value of the combobox.
@ignore
@@ -971,7 +905,6 @@ var CPComboBoxTextSubview = @"text",
- (CGRect)borderFrame
{
var inset = [self borderInset],
buttonSize = [self currentValueForThemeAttribute:@"popup-button-size"],
frame = [self bounds];
frame.origin.x += inset.left;
@@ -1022,13 +955,13 @@ var CPComboBoxTextSubview = @"text",
}
/*! @ignore */
- (void)comboBoxWillPopUp
- (void)comboBoxWillPopUp:(CPNotification)aNotification
{
[[CPNotificationCenter defaultCenter] postNotificationName:CPComboBoxWillPopUpNotification object:self];
}
/*! @ignore */
- (void)comboBoxWillDismiss
- (void)comboBoxWillDismiss:(CPNotification)aNotification
{
[[CPNotificationCenter defaultCenter] postNotificationName:CPComboBoxWillDismissNotification object:self];
}
@@ -1048,6 +981,38 @@ var CPComboBoxTextSubview = @"text",
@end
@implementation CPComboBox (_CPPopUpListDataSource)
- (int)numberOfItemsInList:(_CPPopUpList)aList
{
return [self numberOfItems];
}
- (int)numberOfVisibleItemsInList:(_CPPopUpList)aList
{
return [self numberOfVisibleItems];
}
- (id)list:(_CPPopUpList)aList objectValueForItemAtIndex:(int)index
{
if (_usesDataSource)
return [_dataSource comboBox:self objectValueForItemAtIndex:index];
else
return _items[index];
}
- (id)list:(_CPPopUpList)aList displayValueForObjectValue:(id)aValue
{
return aValue || @"";
}
- (CPString)list:(_CPPopUpList)aList stringValueForObjectValue:(id)aValue
{
return String(aValue);
}
@end
@implementation CPComboBox (Bindings)
/*! @ignore */
+3 -3
View File
@@ -526,7 +526,7 @@ var CPControlBlackColor = [CPColor blackColor];
// Cocoa raises an invalid parameter assertion and returns if you pass nil.
if (aString === nil || aString === undefined)
{
CPLog.warn("nil sent to CPControl -setStringValue");
CPLog.warn("nil or undefined sent to CPControl -setStringValue");
return;
}
@@ -536,10 +536,10 @@ var CPControlBlackColor = [CPColor blackColor];
{
value = nil;
if ([_formatter getObjectValue:AT_REF(value) forString:aString errorDescription:nil] === NO)
if (![_formatter getObjectValue:AT_REF(value) forString:aString errorDescription:nil])
{
// If the given string is non-empty and doesn't work, Cocoa tries an empty string.
if (!aString || [_formatter getObjectValue:AT_REF(value) forString:@"" errorDescription:nil] === NO)
if (!aString || ![_formatter getObjectValue:AT_REF(value) forString:@"" errorDescription:nil])
value = undefined; // Means the value is invalid
}
}
+1 -1
View File
@@ -131,8 +131,8 @@
_contentObject = aContent;
[self didChangeValueForKey:@"contentObject"];
[self _selectionDidChange];
[self didChangeValueForKey:@"contentObject"];
}
/*!
+4 -8
View File
@@ -626,15 +626,11 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
#endif
// post CPControlTextDidEndEditingNotification
if (_isEditing)
{
_isEditing = NO;
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
_isEditing = NO;
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
if ([self sendsActionOnEndEditing])
[self sendAction:[self action] to:[self target]];
}
if ([self sendsActionOnEndEditing])
[self sendAction:[self action] to:[self target]];
[self textDidBlur:[CPNotification notificationWithName:CPTextFieldDidBlurNotification object:self userInfo:nil]];
+30 -3
View File
@@ -210,10 +210,25 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
if (shouldRemoveLastObject)
[objectValue removeObjectAtIndex:_selectedRange.location];
[objectValue insertObject:token atIndex:_selectedRange.location];
// Give the delegate a chance to confirm, replace or add to the list of tokens being added.
var delegateApprovedObjects = [self tokenField:self shouldAddObjects:[CPArray arrayWithObject:token] atIndex:_selectedRange.location],
delegateApprovedObjectsCount = [delegateApprovedObjects count];
if (delegateApprovedObjects)
{
for (var i = 0; i < delegateApprovedObjectsCount; i++)
{
[objectValue insertObject:[delegateApprovedObjects objectAtIndex:i] atIndex:_selectedRange.location + i];
}
}
// Put the cursor after the last inserted token.
var location = _selectedRange.location;
[self setObjectValue:objectValue];
_selectedRange = CPMakeRange(location + 1, 0);
if (delegateApprovedObjectsCount)
location += delegateApprovedObjectsCount;
_selectedRange = CPMakeRange(location, 0);
[self _inputElement].value = @"";
[self setNeedsLayout];
@@ -1175,7 +1190,19 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
// // return an array of represented objects you want to add.
// // If you want to reject the add, return an empty array.
// // returning nil will cause an error.
// - (NSArray *)tokenField:(NSTokenField *)tokenField shouldAddObjects:(NSArray *)tokens atIndex:(NSUInteger)index;
- (CPArray)tokenField:(CPTokenField)tokenField shouldAddObjects:(CPArray)tokens atIndex:(int)index
{
var delegate = [self delegate];
if ([delegate respondsToSelector:@selector(tokenField:shouldAddObjects:atIndex:)])
{
var approvedObjects = [delegate tokenField:tokenField shouldAddObjects:tokens atIndex:index];
if (approvedObjects !== nil)
return approvedObjects;
}
return tokens;
}
//
// // If you return nil or don't implement these delegate methods, we will assume
// // editing string = display string = represented object
+63 -12
View File
@@ -426,6 +426,7 @@ CPTexturedBackgroundWindowMask
// Create a generic content view.
[self setContentView:[[CPView alloc] initWithFrame:CGRectMakeZero()]];
[self setInitialFirstResponder:[self contentView]];
_firstResponder = self;
@@ -480,6 +481,7 @@ CPTexturedBackgroundWindowMask
[self close];
_platformWindow = aPlatformWindow;
[_platformWindow _setTitle:_title window:self];
if (wasVisible)
[self orderFront:self];
@@ -949,6 +951,12 @@ CPTexturedBackgroundWindowMask
var bounds = CGRectMake(0.0, 0.0, CGRectGetWidth(_frame), CGRectGetHeight(_frame));
// During init the initial first responder is set to the contentView
// if it hasn't changed in the mean time we need to update that reference
// to the new contentView
if ([self initialFirstResponder] === _contentView)
[self setInitialFirstResponder:aView];
_contentView = aView;
[_contentView setFrame:[self contentRectForFrameRect:bounds]];
@@ -1273,17 +1281,17 @@ CPTexturedBackgroundWindowMask
- (BOOL)acceptsFirstResponder
{
return YES;
return NO;
}
- (id)initialFirstResponder
- (CPView)initialFirstResponder
{
return _initialFirstResponder;
}
- (void)setInitialFirstResponder:(id)aResponder
- (void)setInitialFirstResponder:(CPView)aView
{
_initialFirstResponder = aResponder;
_initialFirstResponder = aView;
}
/*!
@@ -1359,6 +1367,7 @@ CPTexturedBackgroundWindowMask
_title = aTitle;
[_windowView setTitle:aTitle];
[_platformWindow _setTitle:_title window:self];
[self _synchronizeMenuBarTitleWithWindowTitle];
}
@@ -2485,30 +2494,70 @@ CPTexturedBackgroundWindowMask
- (void)selectNextKeyView:(id)sender
{
if (_keyViewLoopIsDirty && [self autorecalculatesKeyViewLoop])
[self recalculateKeyViewLoop];
var nextValidKeyView = nil;
if ([_firstResponder isKindOfClass:[CPView class]])
[self selectKeyViewFollowingView:_firstResponder];
nextValidKeyView = [_firstResponder nextValidKeyView];
if (!nextValidKeyView)
{
var initialFirstResponder = [self initialFirstResponder];
if ([initialFirstResponder acceptsFirstResponder])
nextValidKeyView = initialFirstResponder;
else
nextValidKeyView = [initialFirstResponder nextValidKeyView];
}
[self makeFirstResponder:nextValidKeyView];
}
- (void)selectPreviousKeyView:(id)sender
{
if (_keyViewLoopIsDirty && [self autorecalculatesKeyViewLoop])
[self recalculateKeyViewLoop];
var previousValidKeyView = nil;
if ([_firstResponder isKindOfClass:[CPView class]])
[self selectKeyViewPrecedingView:_firstResponder];
previousValidKeyView = [_firstResponder previousValidKeyView];
if (!previousValidKeyView)
{
var initialFirstResponder = [self initialFirstResponder];
if ([initialFirstResponder acceptsFirstResponder])
previousValidKeyView = initialFirstResponder;
else
previousValidKeyView = [initialFirstResponder previousValidKeyView];
}
[self makeFirstResponder:previousValidKeyView];
}
- (void)selectKeyViewFollowingView:(CPView)aView
{
if (_keyViewLoopIsDirty)
if (_keyViewLoopIsDirty && [self autorecalculatesKeyViewLoop])
[self recalculateKeyViewLoop];
[self makeFirstResponder:[aView nextValidKeyView]];
var nextValidKeyView = [aView nextValidKeyView];
if ([nextValidKeyView isKindOfClass:[CPView class]])
[self makeFirstResponder:nextValidKeyView];
}
- (void)selectKeyViewPrecedingView:(CPView)aView
{
if (_keyViewLoopIsDirty)
if (_keyViewLoopIsDirty && [self autorecalculatesKeyViewLoop])
[self recalculateKeyViewLoop];
[self makeFirstResponder:[aView previousValidKeyView]];
var previousValidKeyView = [aView previousValidKeyView];
if ([previousValidKeyView isKindOfClass:[CPView class]])
[self makeFirstResponder:previousValidKeyView];
}
/*!
@@ -2596,9 +2645,11 @@ CPTexturedBackgroundWindowMask
var allViews = function(aWindow)
{
var views = [[aWindow contentView] subviews],
index = 0;
var views = [CPArray arrayWithObject:[aWindow contentView]];
[views addObjectsFromArray:[[aWindow contentView] subviews]];
var index = 0;
for (; index < views.length; ++index)
views = views.concat([views[index] subviews]);
+16
View File
@@ -32,6 +32,7 @@ var PrimaryPlatformWindow = NULL;
CPInteger _level;
BOOL _hasShadow;
unsigned _shadowStyle;
CPString _title;
#if PLATFORM(DOM)
DOMWindow _DOMWindow;
@@ -258,6 +259,21 @@ var PrimaryPlatformWindow = NULL;
return [CPPlatform isBrowser];
}
- (void)_setTitle:(CPString)aTitle window:(CPWindow)aWindow
{
_title = aTitle;
#if PLATFORM(DOM)
if (_DOMWindow && _DOMWindow.document && (aWindow === [CPApp mainWindow]))
_DOMWindow.document.title = _title;
#endif
}
- (CPString)title
{
return _title;
}
@end
#if PLATFORM(BROWSER)
+3 -1
View File
@@ -534,13 +534,15 @@ var ModifierKeyCodes = [
if (_DOMWindow)
return _DOMWindow.focus();
_DOMWindow = window.open("", "_blank", "menubar=no,location=no,resizable=yes,scrollbars=no,status=no,left=" + _CGRectGetMinX(_contentRect) + ",top=" + _CGRectGetMinY(_contentRect) + ",width=" + _CGRectGetWidth(_contentRect) + ",height=" + _CGRectGetHeight(_contentRect));
_DOMWindow = window.open("about:blank", "_blank", "menubar=no,location=no,resizable=yes,scrollbars=no,status=no,left=" + _CGRectGetMinX(_contentRect) + ",top=" + _CGRectGetMinY(_contentRect) + ",width=" + _CGRectGetWidth(_contentRect) + ",height=" + _CGRectGetHeight(_contentRect));
[PlatformWindows addObject:self];
// FIXME: cpSetFrame?
_DOMWindow.document.write("<!DOCTYPE html><html lang='en'><head></head><body style='background-color:transparent;'></body></html>");
_DOMWindow.document.close();
if (self != [CPPlatformWindow primaryPlatformWindow])
_DOMWindow.document.title = _title;
if (![CPPlatform isBrowser])
{
+431 -308
View File
@@ -21,6 +21,7 @@
*/
@import "CPTableView.j"
@import "_CPPopUpListDataSource.j"
/*!
@@ -69,13 +70,9 @@ var ListColumnIdentifier = @"1";
/*!
This class is a controller for a panel that can pop up and display a scrollable list of items in a CPTableView.
For tables that display single-line rows of scalar data, no subclassing should be necessary.
It is used by CPComboBox to display the list of choices.
The delegate of this class MUST implement the following methods:
numberOfItems The number of items the list should display
numberOfVisibleItems The maximum number of items to display at once
objectValueForItemAtIndex: Retrieves an object value for an item in the range 0..(numberOfItems - 1)
This class requires a data source which must conform to the interface of _CPPopUpListDataSource.
Objects of this class send the following notifications:
@@ -86,28 +83,30 @@ var ListColumnIdentifier = @"1";
*/
@implementation _CPPopUpList : CPObject
{
_CPPopUpListDelegate _delegate;
_CPPopUpListDataSource _dataSource;
BOOL _itemWasClicked;
BOOL _listWasClicked;
int _listWidth;
_CPPopUpPanel _panel @accessors(readonly, property=panel);
CPScrollView _scrollView @accessors(readonly, property=scrollView);
_CPPopUpTableView _tableView @accessors(readonly, property=tableView);
_CPPopUpPanel _panel;
CPScrollView _scrollView;
_CPPopUpTableView _tableView;
CPTableColumn _tableColumn;
}
/*!
Creates a pop up list of choices which will display relative to the given rect in base coordinates.
#pragma mark Creating and Displaying a List
@param aDelegate The object that usually is controlling this list.
/*!
Creates a pop up list of choices that will display in a scrollable CPTableView.
@param aDataSource A subclass of _CPPopUpListDataSource
*/
- (id)initWithDelegate:(_CPPopUpListDelegate)aDelegate
- (id)initWithDataSource:(_CPPopUpListDataSource)aDataSource
{
self = [super init];
if (self)
{
_delegate = aDelegate;
[self setDataSource:aDataSource];
_itemWasClicked = NO;
_listWasClicked = NO;
_listWidth = 0;
@@ -132,24 +131,18 @@ var ListColumnIdentifier = @"1";
[[_panel contentView] addSubview:_scrollView];
[_panel setInitialFirstResponder:_tableView];
if ([_delegate numberOfItems] > 0)
if ([_dataSource numberOfItemsInList:self] > 0)
[_tableView selectRowIndexes:[CPIndexSet indexSetWithIndex:0] byExtendingSelection:NO];
else
[_tableView setEnabled:NO];
[_scrollView scrollToBeginningOfDocument:nil];
[self finalizeTableView:_tableView];
}
return self;
}
/*!
Create and configure the panel containing the table view.
Subclasses should override this (and usually call super first)
if they want to customize the list panel.
*/
/*! @ignore */
- (CPPanel)makeListPanelWithFrame:(CGRect)aFrame
{
var panel = [[_CPPopUpPanel alloc] initWithContentRect:aFrame styleMask:CPBorderlessWindowMask];
@@ -164,9 +157,7 @@ var ListColumnIdentifier = @"1";
return panel;
}
/*!
Create and configure the table view. Subclasses should use \ref finalizeTableView:.
*/
/*! @ignore */
- (_CPPopUpTableView)makeTableView
{
[self removeTableViewObservers];
@@ -187,6 +178,7 @@ var ListColumnIdentifier = @"1";
return table;
}
/*! @ignore */
- (void)removeTableViewObservers
{
if (_tableView)
@@ -198,21 +190,7 @@ var ListColumnIdentifier = @"1";
}
}
/*!
If subclasses want to configure the table view after it has been
completely configured, for example to set a custom data view,
this is the place. Such customization can also be done by an
observer of _CPPopUpListListWillDisplayNotification.
*/
- (void)finalizeTableView:(CPTableView)aTableView
{
}
/*!
Creates and configures the scroll view containing the table view.
Subclasses should override this (and usually call super first)
if they want to customize the scroll view.
*/
/*! @ignore */
- (CPScrollView)makeScrollViewWithFrame:(CGRect)aFrame
{
var scroll = [[CPScrollView alloc] initWithFrame:aFrame];
@@ -227,6 +205,37 @@ var ListColumnIdentifier = @"1";
return scroll;
}
/*!
Pop up the list if it is not already visible.
If it is not visible, a _CPPopUpListWillPopUpNotification will be sent.
@param aRect A rect (in \c aView coordinates) to display relative to
@param aView The view whose coordinate system \c aRect is in
@param offset How far to offset the list from \c aRect
*/
- (void)popUpRelativeToRect:(CGRect)aRect view:(CPView)aView offset:(int)offset
{
if ([_panel isVisible])
return;
var rowRect = [_tableView rectOfRow:[self numberOfRowsInTableView:_tableView] - 1],
frame = CGRectMake(0, 0, MAX(_listWidth, CGRectGetWidth(aRect)), CGRectGetMaxY(rowRect));
// Place the frame relative to aRect and constrain it to the screen bounds
frame = [self constrain:frame relativeToRect:aRect view:aView offset:offset];
[_panel setFrame:frame];
[_scrollView setFrameSize:CGSizeMakeCopy(frame.size)];
[_tableView setEnabled:[_dataSource numberOfItemsInList:self] > 0];
[self scrollItemAtIndexToTop:[_tableView selectedRow]];
[self listWillPopUp];
[_panel orderFront:nil];
}
#pragma mark Setting Display Attributes
/*!
Returns the desired width of the list.
*/
@@ -272,31 +281,388 @@ var ListColumnIdentifier = @"1";
}
/*!
Pop up the list if it is not already visible.
If it is not visible, a _CPPopUpListWillPopUpNotification will be sent.
@param aRect A rect (in \c aView coordinates) to display relative to
@param aView The view whose coordinate system \c aRect is in
@param offset How far to offset the list from \c aRect
Returns whether the list is currently visible.
*/
- (void)popUpRelativeToRect:(CGRect)aRect view:(CPView)aView offset:(int)offset
- (BOOL)isVisible
{
if ([_panel isVisible])
return [_panel isVisible];
}
/*!
Returns the desired row height for the table view.
Subclasses should override this if they want something other than the default.
*/
- (int)rowHeightForTableView:(CPTableView)aTableView
{
return [aTableView rowHeight];
}
/*!
Returns the table view used by the list.
*/
- (CPTableView)tableView
{
return _tableView;
}
/*!
Returns the single table column used by the list.
*/
- (CPTableColumn)tableColumn
{
return _tableColumn;
}
/*!
Returns the scroll view used by the list.
*/
- (CPScrollView)scrollView
{
return _scrollView;
}
/*!
Returns the panel in which the list appears.
*/
- (CPPanel)panel
{
return _panel;
}
#pragma mark Setting a Data Source
- (void)setDataSource:(_CPPopUpListDataSource)aDataSource
{
if (_dataSource === aDataSource)
return;
var rowRect = [_tableView rectOfRow:[self numberOfRowsInTableView:_tableView] - 1],
frame = CGRectMake(0, 0, MAX(_listWidth, CGRectGetWidth(aRect)), CGRectGetMaxY(rowRect));
if (![_CPPopUpListDataSource protocolIsImplementedByObject:aDataSource])
{
CPLog.warn("Illegal %s data source (%s). Must implement the methods in _CPPopUpListDataSource.", [self className], [aDataSource description]);
}
else
_dataSource = aDataSource;
}
// Place the frame relative to aRect and constrain it to the screen bounds
frame = [self constrain:frame relativeToRect:aRect view:aView offset:offset];
- (_CPPopUpListDataSource)dataSource
{
return _dataSource;
}
[_panel setFrame:frame];
[_scrollView setFrameSize:CGSizeMakeCopy(frame.size)];
[self scrollItemAtIndexToTop:[_tableView selectedRow]];
#pragma mark Manipulating the Selection
[self listWillPopUp];
/*!
Select the next item in the list if there one. If there is currently no selected item,
the first item is selected. Returns YES if the selection changed.
*/
- (BOOL)selectNextItem
{
if (![_tableView isEnabled])
return NO;
[_panel orderFront:nil];
var row = [_tableView selectedRow];
if (row < ([_dataSource numberOfItemsInList:self] - 1))
return [self selectRow:++row];
else
return NO;
}
/*!
Select the previous item in the list. If there is currently no selected item,
nothing happens. Returns YES if the selection changed.
*/
- (BOOL)selectPreviousItem
{
if (![_tableView isEnabled])
return NO;
var row = [_tableView selectedRow];
if (row > 0)
return [self selectRow:--row];
else
return NO;
}
/*!
Returns the selected object value. If no value is selected,
returns nil.
*/
- (id)selectedObjectValue
{
var row = [_tableView selectedRow];
return (row >= 0) ? [_dataSource list:self objectValueForItemAtIndex:row] : nil;
}
/*!
Returns the selected value as a single-line string. If no value is selected,
returns nil.
*/
- (CPString)selectedStringValue
{
var value = [self selectedObjectValue];
return value !== nil ? [_dataSource list:self stringValueForObjectValue:value] : nil;
}
/*!
Returns the last selected row in the list. If no row has been selected, returns -1.
*/
- (int)selectedRow
{
return [_tableView selectedRow];
}
/*!
Selects a row and scrolls it to be visible. Returns YES if the selection actually changed.
*/
- (BOOL)selectRow:(int)row
{
if (row === [_tableView selectedRow])
return NO;
var validRow = (row >= 0 && row < [self numberOfRowsInTableView:_tableView]),
indexes = validRow ? [CPIndexSet indexSetWithIndex:row] : [CPIndexSet indexSet];
[_tableView selectRowIndexes:indexes byExtendingSelection:NO];
if (validRow)
{
[_tableView scrollRowToVisible:row];
return YES;
}
else
return NO;
}
#pragma mark Manipulating the Displayed List
/*!
Scroll the list down one page.
*/
- (void)scrollPageDown
{
[_scrollView scrollPageDown:nil];
}
/*!
Scroll the list up one page.
*/
- (void)scrollPageUp
{
[_scrollView scrollPageUp:nil];
}
/*!
Scroll to the top of the list.
*/
- (void)scrollToTop
{
[_scrollView scrollToBeginningOfDocument:nil];
}
/*!
Scroll to the bottom of the list.
*/
- (void)scrollToBottom
{
[_scrollView scrollToEndOfDocument:nil];
}
- (void)scrollItemAtIndexToTop:(int)row
{
var rect = [_tableView rectOfRow:row];
[[_tableView superview] scrollToPoint:rect.origin];
}
/*!
Close the list if it is currently visible. If it is visible,
a CPComboBoxWillDismissNotification will be sent. If the
list is being closed after an item was clicked, the close
is delayed slightly so the user can briefly see the clicked row
get highlighted.
*/
- (void)close
{
if (![_panel isVisible])
return;
if ([self listWasClicked])
{
[self setListWasClicked:NO];
// Wait until we get through the run loop and delay a little
// so the user can briefly see the clicked row get highlighted.
if ([self itemWasClicked])
{
[self setItemWasClicked:NO];
[CPTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(closeListAfterItemClick) userInfo:nil repeats:NO];
return;
}
}
[[CPNotificationCenter defaultCenter] postNotificationName:_CPPopUpListWillDismissNotification object:self];
[_panel close];
[[CPNotificationCenter defaultCenter] postNotificationName:_CPPopUpListDidDismissNotification object:self];
}
/*!
Close the list after an item was clicked.
*/
- (void)closeListAfterItemClick
{
[self close];
[[CPNotificationCenter defaultCenter] postNotificationName:_CPPopUpListItemWasClickedNotification object:self];
}
#pragma mark Handling Events
/*!
Handles standard key equivalents for moving the selection
and selecting an item. This method should be called by
the -performKeyEquivalent method of the field that is
controlling the list.
*/
- (BOOL)performKeyEquivalent:(CPEvent)anEvent
{
var key = [anEvent charactersIgnoringModifiers];
switch (key)
{
case CPDownArrowFunctionKey:
if ([self isVisible])
{
[self selectNextItem];
return YES;
}
break;
case CPUpArrowFunctionKey:
if ([self isVisible])
{
[self selectPreviousItem];
return YES;
}
break;
case CPEscapeFunctionKey:
if ([self isVisible])
{
[self close];
return YES;
}
break;
case CPPageUpFunctionKey:
if ([self isVisible])
{
[self scrollPageUp];
return YES;
}
break;
case CPPageDownFunctionKey:
if ([self isVisible])
{
[self scrollPageDown];
return YES;
}
break;
case CPHomeFunctionKey:
if ([self isVisible])
{
[self scrollToTop];
return YES;
}
break;
case CPEndFunctionKey:
if ([self isVisible])
{
[self scrollToBottom];
return YES;
}
break;
}
return NO;
}
/*!
Returns whether an item in the list was clicked since it was opened.
If there are no items, \ref itemWasClicked will always return NO.
*/
- (BOOL)itemWasClicked
{
return _itemWasClicked && ([_dataSource numberOfItemsInList:self] > 0);
}
/*!
Sets whether an item in the list was clicked since it was opened.
If there are no items, \ref itemWasClicked will always return NO.
Subclasses will usually want to set this in the mouseDown:
of the control.
*/
- (void)setItemWasClicked:(BOOL)flag
{
_itemWasClicked = ([_dataSource numberOfItemsInList:self] > 0) && flag;
}
/*!
Returns whether any view in the list was clicked since it was opened.
If there are no items, \ref listWasClicked will always return NO.
*/
- (BOOL)listWasClicked
{
return _listWasClicked && ([_dataSource numberOfItemsInList:self] > 0);
}
/*!
Sets whether any view in the list was clicked since it was opened.
If there are no items, \ref listWasClicked will always return NO.
Subclasses will usually want to use a subclass of CPPanel and override
sendEvent: to set this flag when the event type is CPLeftMouseDown
or CPRightMouseDown. This is distinct from \ref itemWasClicked because,
for example, a scroller in the list may be clicked without clicking an
item in the list.
*/
- (void)setListWasClicked:(BOOL)flag
{
_listWasClicked = ([_dataSource numberOfItemsInList:self] > 0) && flag;
}
/*!
Returns whether a controlling view should resign. This should be called
from the controlling view's resignFirstResponder method.
*/
- (BOOL)controllingViewShouldResign
{
if ([self listWasClicked])
{
/*
If an item was not clicked (probably the scrollbar), clear the click flag so that future
clicks outside the list will allow it to close.
*/
if ([self listWasClicked] && ![self itemWasClicked])
[self setListWasClicked:NO];
return NO;
}
else
return YES;
}
#pragma mark Internal Helpers
/*! @ignore */
- (void)listWillPopUp
{
[[CPNotificationCenter defaultCenter] postNotificationName:_CPPopUpListWillPopUpNotification object:self];
}
/*!
@@ -305,6 +671,7 @@ var ListColumnIdentifier = @"1";
for at least ListMinimumItems items, an attempt should be made to display that many
items above \c aRect. If the minimum cannot be displayed on top, whichever direction can display more items
is chosen.
@ignore
*/
- (CGRect)constrain:(CGRect)aFrame relativeToRect:(CGRect)aRect view:(CPView)aView offset:(int)offset
{
@@ -314,7 +681,7 @@ var ListColumnIdentifier = @"1";
rowHeight = [self rowHeightForTableView:_tableView] + [_tableView intercellSpacing].height,
// Be sure to clip the number of displayed rows to what the field wants
numberOfRows = MIN([self numberOfRowsInTableView:_tableView], [_delegate numberOfVisibleItems]),
numberOfRows = MIN([self numberOfRowsInTableView:_tableView], [_dataSource numberOfVisibleItemsInList:self]),
// Add 2 to height for border
frame = CGRectMake(windowOrigin.x, windowOrigin.y + CGRectGetHeight(aRect) + offset, MAX(_listWidth, CGRectGetWidth(aFrame)), (rowHeight * numberOfRows) + 2),
@@ -363,250 +730,6 @@ var ListColumnIdentifier = @"1";
return frame;
}
/*!
Returns whether the list is currently visible.
*/
- (BOOL)isVisible
{
return [_panel isVisible];
}
/*!
Subclasses MUST call this method just before the list is about to display.
*/
- (void)listWillPopUp
{
[[CPNotificationCenter defaultCenter] postNotificationName:_CPPopUpListWillPopUpNotification object:self];
}
/*!
Select the next item in the list if there one. If there is currently no selected item,
the first item is selected. Returns YES if the selection changed.
*/
- (BOOL)selectNextItem
{
if (![_tableView isEnabled])
return NO;
var row = [_tableView selectedRow];
if (row < ([_delegate numberOfItems] - 1))
return [self selectRow:++row];
else
return NO;
}
/*!
Select the previous item in the list. If there is currently no selected item,
nothing happens. Returns YES if the selection changed.
*/
- (BOOL)selectPreviousItem
{
if (![_tableView isEnabled])
return NO;
var row = [_tableView selectedRow];
if (row > 0)
return [self selectRow:--row];
else
return NO;
}
/*!
Scroll the list down one page.
*/
- (void)scrollPageDown
{
[_scrollView scrollPageDown:nil];
}
/*!
Scroll the list up one page.
*/
- (void)scrollPageUp
{
[_scrollView scrollPageUp:nil];
}
/*!
Scroll to the top of the list.
*/
- (void)scrollToTop
{
[_scrollView scrollToBeginningOfDocument:nil];
}
/*!
Scroll to the bottom of the list.
*/
- (void)scrollToBottom
{
[_scrollView scrollToEndOfDocument:nil];
}
- (BOOL)selectRow:(int)row
{
if (row === [_tableView selectedRow])
return NO;
var indexes = row >= 0 ? [CPIndexSet indexSetWithIndex:row] : [CPIndexSet indexSet];
[_tableView selectRowIndexes:indexes byExtendingSelection:NO];
if (row >= 0)
{
[_tableView scrollRowToVisible:row];
return YES;
}
else
return NO;
}
- (void)scrollItemAtIndexToTop:(int)row
{
var rect = [_tableView rectOfRow:row];
[[_tableView superview] scrollToPoint:rect.origin];
}
/*!
Returns the selected value as a single-line string. If no value is selected,
returns nil.
*/
- (CPString)selectedStringValue
{
var row = [_tableView selectedRow];
return (row >= 0) ? [self stringValueForObjectValue:[_delegate objectValueForItemAtIndex:row] row:row] : nil;
}
/*!
Returns whether an item in the list was clicked since it was opened.
If there are no items, \ref itemWasClicked will always return NO.
*/
- (BOOL)itemWasClicked
{
return _itemWasClicked && ([_delegate numberOfItems] > 0);
}
/*!
Sets whether an item in the list was clicked since it was opened.
If there are no items, \ref itemWasClicked will always return NO.
Subclasses will usually want to set this in the mouseDown:
of the control.
*/
- (void)setItemWasClicked:(BOOL)flag
{
_itemWasClicked = ([_delegate numberOfItems] > 0) && flag;
}
/*!
Returns whether any view in the list was clicked since it was opened.
If there are no items, \ref listWasClicked will always return NO.
*/
- (BOOL)listWasClicked
{
return _listWasClicked && ([_delegate numberOfItems] > 0);
}
/*!
Sets whether any view in the list was clicked since it was opened.
If there are no items, \ref listWasClicked will always return NO.
Subclasses will usually want to use a subclass of CPPanel and override
sendEvent: to set this flag when the event type is CPLeftMouseDown
or CPRightMouseDown. This is distinct from \ref itemWasClicked because,
for example, a scroller in the list may be clicked without clicking an
item in the list.
*/
- (void)setListWasClicked:(BOOL)flag
{
_listWasClicked = ([_delegate numberOfItems] > 0) && flag;
}
/*!
Close the list if it is currently visible. If it is visible,
a CPComboBoxWillDismissNotification will be sent. If the
list is being closed after an item was clicked, the close
is delayed slightly so the user can briefly see the clicked row
get highlighted.
*/
- (void)close
{
if (![_panel isVisible])
return;
if ([self listWasClicked])
{
[self setListWasClicked:NO];
// Wait until we get through the run loop and delay a little
// so the user can briefly see the clicked row get highlighted.
if ([self itemWasClicked])
{
[self setItemWasClicked:NO];
[CPTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(closeListAfterItemClick) userInfo:nil repeats:NO];
return;
}
}
[[CPNotificationCenter defaultCenter] postNotificationName:_CPPopUpListWillDismissNotification object:self];
[_panel close];
[[CPNotificationCenter defaultCenter] postNotificationName:_CPPopUpListDidDismissNotification object:self];
}
/*!
Close the list after an item was clicked.
*/
- (void)closeListAfterItemClick
{
[self close];
[[CPNotificationCenter defaultCenter] postNotificationName:_CPPopUpListItemWasClickedNotification object:self];
}
/*!
Returns the desired row height for the table view.
Subclasses should override this if they want something other than the default.
*/
- (int)rowHeightForTableView:(CPTableView)aTableView
{
return [aTableView rowHeight];
}
/*!
Returns a value to display for a single row in the list. Subclasses should override
this if the table data needs to be converted or formatted in some way to be displayed.
If there are no search results, an empty string is returned.
If subclasses use a data representation other than CPStrings, they must override
this method and return the appropriate data when there are no search results.
If the table uses a custom data view, this method should return a value suitable
for sending to the setObjectValue: method of the data view.
@param aValue Table data for the given row
@param aRow The row being displayed
@return A value to be displayed in the list
*/
- (id)displayValueForObjectValue:(id)aValue row:(int)aRow
{
return aValue || @"";
}
/*!
Returns a single-line string for use in an autocomplete field. Subclasses should override
this if the row data is not convertable to a simple string, and return the data as a single-line string.
@param aValue Table data to be converted to a string
@param aRow The row whose data is being converted
@return A value to be displayed in the autocomplete field
*/
- (CPString)stringValueForObjectValue:(id)aValue row:(int)aRow
{
return String(aValue);
}
- (void)tableViewClickAction:(id)sender
{
[self close];
@@ -615,7 +738,7 @@ var ListColumnIdentifier = @"1";
@end
var _CPPopUpListFieldKey = @"_CPPopUpListDelegateKey",
var _CPPopUpListDataSourceKey = @"_CPPopUpListDataSourceKey",
_CPPopUpListListWidthKey = @"_CPPopUpListListWidthKey",
_CPPopUpListListPanelKey = @"_CPPopUpListListPanelKey",
_CPPopUpListScrollViewKey = @"_CPPopUpListScrollViewKey",
@@ -632,7 +755,7 @@ var _CPPopUpListFieldKey = @"_CPPopUpListDelegateKey",
_listWasClicked = NO;
_itemWasClicked = NO;
_delegate = [aCoder decodeObjectForKey:_CPPopUpListDelegateKey];
_dataSource = [aCoder decodeObjectForKey:_CPPopUpListDataSourceKey];
_listWidth = [aCoder decodeIntForKey:_CPPopUpListListWidthKey];
_panel = [aCoder decodeObjectForKey:_CPPopUpListListPanelKey];
_scrollView = [aCoder decodeObjectForKey:_CPPopUpListScrollViewKey];
@@ -648,7 +771,7 @@ var _CPPopUpListFieldKey = @"_CPPopUpListDelegateKey",
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_delegate forKey:_CPPopUpListDelegateKey];
[aCoder encodeObject:_dataSource forKey:_CPPopUpListDataSourceKey];
[aCoder encodeObject:_listWidth forKey:_CPPopUpListListWidthKey];
[aCoder encodeObject:_panel forKey:_CPPopUpListListPanelKey];
[aCoder encodeObject:_scrollView forKey:_CPPopUpListScrollViewKey];
@@ -661,12 +784,12 @@ var _CPPopUpListFieldKey = @"_CPPopUpListDelegateKey",
- (int)numberOfRowsInTableView:(id)aTableView
{
return MAX([_delegate numberOfItems], 1);
return MAX([_dataSource numberOfItemsInList:self], 1);
}
- (id)tableView:(id)aTableView objectValueForTableColumn:(CPTableColumn)aColumn row:(int)aRow
{
return [self displayValueForObjectValue:[_delegate objectValueForItemAtIndex:aRow] row:aRow];
return [_dataSource list:self displayValueForObjectValue:[_dataSource list:self objectValueForItemAtIndex:aRow]];
}
@end
+98
View File
@@ -0,0 +1,98 @@
/*
* _CPPopUpListDataSource.j
* AppKit
*
* Created by Aparajita Fishman.
* Copyright (c) 2011, Intalio, 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
*/
/*!
This abstract base class defines the methods that delegates of _CPPopUpList must implement.
You may either subclass this class to use the default implementation of
list:objectValueForItemAtIndex: and list:displayValueForObjectValue: or use your
own class and define these methods yourself.
*/
@implementation _CPPopUpListDataSource : CPObject
/*!
Returns whether the given object conforms to the minimum protocol defined by this class.
*/
+ (BOOL)protocolIsImplementedByObject:(id)anObject
{
return (anObject &&
[anObject respondsToSelector:@selector(numberOfItemsInList:)] &&
[anObject respondsToSelector:@selector(numberOfVisibleItemsInList:)] &&
[anObject respondsToSelector:@selector(list:objectValueForItemAtIndex:)] &&
[anObject respondsToSelector:@selector(list:displayValueForObjectValue:)] &&
[anObject respondsToSelector:@selector(list:stringValueForObjectValue:)]);
}
/*!
Returns the number of items managed by the list.
*/
- (int)numberOfItemsInList:(_CPPopUpList)aList
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
/*!
Returns the number of items to display at one time.
*/
- (int)numberOfVisibleItemsInList:(_CPPopUpList)aList
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
/*!
Returns the data for a given row index.
*/
- (id)list:(_CPPopUpList)aList objectValueForItemAtIndex:(int)index
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
/*!
Returns a value to display for a single row in the list. Subclasses should override
this if the table data needs to be converted or formatted in some way to be displayed.
If your data source use a data representation other than CPStrings, you must override
this method and return the appropriate data when there are no search results.
If the _CPPopUpList's table uses a custom data view, this method should return a value suitable
for sending to the setObjectValue: method of the data view.
@param aValue Data for the given row
@return A value to be displayed in the list
*/
- (id)list:(_CPPopUpList)aList displayValueForObjectValue:(id)aValue
{
return aValue || @"";
}
/*!
Returns a single-line string representation for an object value. Subclasses should override
this if the object data is not convertible to a simple single-line string.
@param aValue Table data to be converted to a string
@return A value to be displayed in the autocomplete field
*/
- (CPString)list:(_CPPopUpList)aList stringValueForObjectValue:(id)aValue
{
return String(aValue);
}
@end
+1 -1
View File
@@ -2,7 +2,7 @@ require File.join(File.dirname(__FILE__), "repositories.rb")
require File.join(File.dirname(__FILE__), "dependencies.rb")
# Keep this structure to allow the build system to update version numbers.
VERSION_NUMBER = "1.0.0.007"
VERSION_NUMBER = "1.0.0.019"
# Shorten expressions
+108 -19
View File
@@ -131,7 +131,7 @@
_replaceManySEL = sel_getName(@"replace" + capitalizedKey + "AtIndexes:with" + capitalizedKey + ":");
if ([_proxyObject respondsToSelector:_replaceManySEL])
_replace = [_proxyObject methodForSelector:_replaceManySEL];
_replaceMany = [_proxyObject methodForSelector:_replaceManySEL];
_objectAtIndexSEL = sel_getName(@"objectIn" + capitalizedKey + "AtIndex:");
if ([_proxyObject respondsToSelector:_objectAtIndexSEL])
@@ -233,10 +233,25 @@
- (id)objectAtIndex:(unsigned)anIndex
{
if (_objectAtIndex)
return _objectAtIndex(_proxyObject, _objectAtIndexSEL, anIndex);
return [[self objectsAtIndexes:[CPIndexSet indexSetWithIndex:anIndex]] firstObject];
}
return [[self _representedObject] objectAtIndex:anIndex];
- (CPArray)objectsAtIndexes:(CPIndexSet)theIndexes
{
if (_objectsAtIndexes)
return _objectsAtIndexes(_proxyObject, _objectsAtIndexesSEL, theIndexes);
if (_objectAtIndex)
{
var index = CPNotFound,
objects = [];
while ((index = [theIndexes indexGreaterThanIndex:index]) !== CPNotFound)
objects.push(_objectAtIndex(_proxyObject, _objectAtIndexSEL, index));
return objects;
}
return [[self _representedObject] objectsAtIndexes:theIndexes];
}
- (void)addObject:(id)anObject
@@ -288,37 +303,111 @@
[self removeObject:anObject inRange:CPMakeRange(0, [self count])];
}
- (void)removeLastObject
- (void)removeObjectsInArray:(CPArray)theObjects
{
if (_removeMany)
{
var indexes = [CPIndexSet indexSet],
index = [theObjects count];
while (index--)
[indexes addIndex:[self indexOfObject:[theObjects objectAtIndex:index]]];
_removeMany(_proxyObject, _removeManySEL, indexes);
}
else if (_remove)
{
var index = [theObjects count];
while (index--)
_remove(_proxyObject, _removeSEL, [self indexOfObject:[theObjects objectAtIndex:index]]);
}
else
{
var target = [[self _representedObject] copy];
[target removeObjectsInArray:theObjects];
[self _setRepresentedObject:target];
}
}
- (void)removeObject:(id)theObject inRange:(CPRange)theRange
{
if (_remove)
return _remove(_proxyObject, _removeSEL, [self count] - 1);
_remove(_proxyObject, _removeSEL, [self indexOfObject:theObject inRange:theRange]);
else if (_removeMany)
{
var index = [self indexOfObject:theObject inRange:theRange];
_removeMany(_proxyObject, _removeManySEL, [CPIndexSet indexSetWithIndex:index]);
}
else
{
var index;
var target = [[self _representedObject] copy];
while ((index = [self indexOfObject:theObject inRange:theRange]) !== CPNotFound)
{
[self removeObjectAtIndex:index];
theRange = CPIntersectionRange(CPMakeRange(index, length - index), theRange);
}
}
}
[target removeLastObject];
[self _setRepresentedObject:target];
- (void)removeLastObject
{
[self removeObjectsAtIndexes:[CPIndexSet indexSetWithIndex:[self count] - 1]];
}
- (void)removeObjectAtIndex:(unsigned)anIndex
{
if (_remove)
return _remove(_proxyObject, _removeSEL, anIndex);
[self removeObjectsAtIndexes:[CPIndexSet indexSetWithIndex:anIndex]];
}
var target = [[self _representedObject] copy];
- (void)removeObjectsAtIndexes:(CPIndexSet)theIndexes
{
if (_removeMany)
_removeMany(_proxyObject, _removeManySEL, theIndexes);
else if (_remove)
{
var index = [theIndexes lastIndex];
[target removeObjectAtIndex:anIndex];
[self _setRepresentedObject:target];
while (index !== CPNotFound)
{
_remove(_proxyObject, _removeSEL, index)
index = [theIndexes indexLessThanIndex:index];
}
}
else
{
var target = [[self _representedObject] copy];
[target removeObjectsAtIndexes:theIndexes];
[self _setRepresentedObject:target];
}
}
- (void)replaceObjectAtIndex:(unsigned)anIndex withObject:(id)anObject
{
if (_replace)
return _replace(_proxyObject, _replaceSEL, anIndex, anObject);
[self replaceObjectsAtIndexes:[CPIndexSet indexSetWithIndex:anIndex] withObjects:[anObject]]
}
var target = [[self _representedObject] copy];
- (void)replaceObjectsAtIndexes:(CPIndexSet)theIndexes withObjects:(CPArray)theObjects
{
if (_replaceMany)
return _replaceMany(_proxyObject, _replaceManySEL, theIndexes, theObjects);
else if (_replace)
{
var i = 0,
index = [theIndexes firstIndex];
[target replaceObjectAtIndex:anIndex withObject:anObject];
[self _setRepresentedObject:target];
while (index !== CPNotFound)
{
_replace(_proxyObject, _replaceSEL, index, [theObjects objectAtIndex:i++]);
index = [theIndexes indexGreaterThanIndex:index];
}
}
else
{
var target = [[self _representedObject] copy];
[target replaceObjectsAtIndexes:theIndexes withObjects:theObjects];
[self _setRepresentedObject:target];
}
}
@end
+1 -1
View File
@@ -259,7 +259,7 @@ var concat = Array.prototype.concat,
if (aRange.location < 0 || CPMaxRange(aRange) > self.length)
[CPException raise:CPRangeException reason:_cmd + " aRange out of bounds"];
if (otherRange.location < 0 || CPMaxRange(otherRange) > anArray.length)
if (otherRange && (otherRange.location < 0 || CPMaxRange(otherRange) > anArray.length))
[CPException raise:CPRangeException reason:_cmd + " otherRange out of bounds"];
if (otherRange && (otherRange.location !== 0 || otherRange.length !== [anArray count]))
+39 -26
View File
@@ -228,10 +228,10 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
id _targetObject;
Class _nativeClass;
CPDictionary _changesForKey;
CPDictionary _nestingForKey;
Object _observersForKey;
int _observersForKeyLength;
CPSet _replacedKeys;
CPSet _suppressedNotifications;
}
+ (id)proxyForObject:(CPObject)anObject
@@ -248,12 +248,12 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
{
if (self = [super init])
{
_targetObject = aTarget;
_nativeClass = [aTarget class];
_observersForKey = {};
_changesForKey = {};
_observersForKeyLength = 0;
_suppressedNotifications = [CPSet set];
_targetObject = aTarget;
_nativeClass = [aTarget class];
_observersForKey = {};
_changesForKey = {};
_nestingForKey = {};
_observersForKeyLength = 0;
[self _replaceClass];
aTarget[KVOProxyKey] = self;
@@ -631,12 +631,12 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
{
// Fire change events for the dependent keys
var dependentKeysForClass = _nativeClass[DependentKeysKey],
dependentKeys = [dependentKeysForClass[theKeyPath] allObjects],
isBeforeFlag = !![theChanges objectForKey:CPKeyValueChangeNotificationIsPriorKey];
dependantKeys = [dependentKeysForClass[theKeyPath] allObjects];
for (var i = 0; i < [dependentKeys count]; i++)
var isBeforeFlag = !![theChanges objectForKey:CPKeyValueChangeNotificationIsPriorKey];
for (var i = 0; i < [dependantKeys count]; i++)
{
var dependantKey = [dependentKeys objectAtIndex:i];
var dependantKey = [dependantKeys objectAtIndex:i];
[self _sendNotificationsForKey:dependantKey changeOptions:theChanges isBefore:isBeforeFlag];
}
}
@@ -717,6 +717,18 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
if (isBefore)
{
if (changes)
{
// "willChange:X" nesting.
var level = _nestingForKey[aKey];
if (!level)
[CPException raise:CPInternalInconsistencyException reason:@"_changesForKey without _nestingForKey"];
_nestingForKey[aKey] = level + 1;
// Only notify on the first willChange..., silently note any following nested calls.
return;
}
_nestingForKey[aKey] = 1;
changes = changeOptions;
var indexes = [changes objectForKey:CPKeyValueChangeIndexesKey],
@@ -774,9 +786,19 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
}
else
{
if (!changes)
var level = _nestingForKey[aKey];
if (!changes || !level)
[CPException raise:@"CPKeyValueObservingException" reason:@"'didChange...' message called without prior call of 'willChange...'"];
_nestingForKey[aKey] = level - 1;
if (level - 1 > 0)
{
// willChange... was called multiple times. Only fire observation notifications when
// didChange... has been called an equal number of times.
return;
}
delete _nestingForKey[aKey];
[changes removeObjectForKey:CPKeyValueChangeNotificationIsPriorKey];
var indexes = [changes objectForKey:CPKeyValueChangeIndexesKey],
@@ -814,6 +836,8 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
[changes setObject:newValue forKey:CPKeyValueChangeNewKey];
}
delete _changesForKey[aKey];
}
var observers = [_observersForKey[aKey] allValues],
@@ -844,23 +868,12 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
{
var keyPath = dependentKeyPaths[index];
if (![_suppressedNotifications containsObject:keyPath])
[self _sendNotificationsForKey:keyPath
changeOptions:isBefore ? [changeOptions copy] : _changesForKey[keyPath]
isBefore:isBefore];
[self _sendNotificationsForKey:keyPath
changeOptions:isBefore ? [changeOptions copy] : _changesForKey[keyPath]
isBefore:isBefore];
}
}
- (void)suppressNotificationsForKeyPath:(CPString)keyPath
{
[_suppressedNotifications addObject:keyPath];
}
- (void)unsuppressNotificationsForKeyPath:(CPString)keyPath
{
[_suppressedNotifications removeObject:keyPath];
}
@end
@implementation _CPKVOModelSubclass
+7 -2
View File
@@ -306,12 +306,17 @@ var CPStringRegexSpecialCharacters = [
}
/*!
Creates a substring from the beginning of the receiver to the specified index.
@param anIndex the last index of the receiver to use for the substring (inclusive)
Creates a substring of characters from the receiver, starting at the beginning and up to
the given index.
@param anIndex the index of the receiver where the substring should end (non inclusive)
@return the substring
*/
- (CPString)substringToIndex:(unsigned)anIndex
{
if (anIndex > length)
[CPException raise:CPRangeException reason:"index out of bounds"];
return substring(0, anIndex);
}
+43 -11
View File
@@ -59,7 +59,7 @@ task ("sudo-install", ["CommonJS"], function()
if (OS.system(["sudo", "tusk", "install", "--force", $BUILD_CJS_OBJECTIVE_J, $BUILD_CJS_CAPPUCCINO]))
{
// Attempt a hackish work-around for sudo compiled with the --with-secure-path option
sudo("tusk install --force " + $BUILD_CJS_OBJECTIVE_J + " " + $BUILD_CJS_CAPPUCCINO)
sudo("tusk install --force " + $BUILD_CJS_OBJECTIVE_J + " " + $BUILD_CJS_CAPPUCCINO);
}
});
@@ -71,10 +71,38 @@ task ("install-symlinks", function()
task ("install-debug-symlinks", function()
{
SYSTEM.env["CONFIG"] = "Debug";
SYSTEM.env.CONFIG = "Debug";
spawnJake("install-symlinks");
});
task ("clean-sprites", function()
{
var f = new FileList(FILE.join(SYSTEM.env.CAPP_BUILD, "**/dataURLs.txt")),
paths = f.items();
f = new FileList(FILE.join(SYSTEM.env.CAPP_BUILD, "**/MHTML*.txt"));
paths = paths.concat(f.items());
paths.forEach(function(path)
{
FILE.remove(path);
});
});
task ("clobber-theme", function()
{
var f = new FileList(FILE.join(SYSTEM.env.CAPP_BUILD, "**/Aristo.blend")),
paths = f.items();
f = new FileList(FILE.join(SYSTEM.env.CAPP_BUILD, "Aristo.build"));
paths = paths.concat(f.items());
paths.forEach(function(path)
{
rm_rf(path);
});
});
// Documentation
$DOCUMENTATION_BUILD = FILE.join($BUILD_DIR, "Documentation");
@@ -160,6 +188,10 @@ function generateDocs(/* boolean */ noFrame)
rm_rf($DOCUMENTATION_BUILD);
mv("debug.txt", FILE.join("Documentation", "debug.txt"));
mv("Documentation", $DOCUMENTATION_BUILD);
// There is a bug in doxygen 1.7.x preventing loading correctly the custom CSS
// So let's do it manually
cp(FILE.join(documentationDir, "doxygen.css"), FILE.join($DOCUMENTATION_BUILD, "html", "doxygen.css"));
}
}
@@ -247,30 +279,30 @@ task ("demos", function()
if (key)
return this._plist.valueForKey(key);
return this._plist;
}
};
Demo.prototype.name = function()
{
return this.plist("CPBundleName");
}
};
Demo.prototype.path = function()
{
return this._path;
}
};
Demo.prototype.excluded = function()
{
return !!this.plist("CPDemoExcluded");
}
};
Demo.prototype.toString = function()
{
return this.name();
}
};
FILE.glob(FILE.join(demosDir, "demos", "**/Info.plist")).map(function(demoPath){
return new Demo(FILE.dirname(demoPath))
return new Demo(FILE.dirname(demoPath));
}).filter(function(demo){
return !demo.excluded();
}).forEach(function(demo)
@@ -315,7 +347,7 @@ task("push-cappuccino", function() {
pushPackage(
$BUILD_CJS_CAPPUCCINO,
"git@github.com:280north/cappuccino-package.git",
SYSTEM.env["PACKAGE_BRANCH"]
SYSTEM.env.PACKAGE_BRANCH
);
});
@@ -323,7 +355,7 @@ task("push-objective-j", function() {
pushPackage(
$BUILD_CJS_OBJECTIVE_J,
"git@github.com:280north/objective-j-package.git",
SYSTEM.env["PACKAGE_BRANCH"]
SYSTEM.env.PACKAGE_BRANCH
);
});
@@ -361,7 +393,7 @@ function pushPackage(path, remote, branch)
var pkg = JSON.parse(packagePath.join("package.json").read({ charset : "UTF-8" }));
stream.print(" Version: " + colorize(pkg["version"], "purple"));
stream.print(" Version: " + colorize(pkg.version, "purple"));
stream.print(" Revision: " + colorize(pkg["cappuccino-revision"], "purple"));
stream.print(" Timestamp: " + colorize(pkg["cappuccino-timestamp"], "purple"));
+74 -1
View File
@@ -464,6 +464,45 @@
[self assert:1 equals:[observations count] message:@"exactly 1 notification for insertObject x 2 (clearsFilterPredicate YES)"];
}
/**
Replicate the situation found in the Bindings manual test where one array controller's
contents depend on the selection of another.
*/
- (void)testObservationBetweenBoundControllers
{
var companies = [Companies new],
companiesController = [CPArrayController new],
employeesController = [CPArrayController new];
[companiesController bind:@"contentArray" toObject:companies withKeyPath:@"items" options:nil];
[employeesController bind:@"contentArray" toObject:companiesController withKeyPath:@"selection.employees" options:nil];
[companiesController addObserver:self forKeyPath:@"selection" options:0 context:@"companies.selection"];
[companiesController addObserver:self forKeyPath:@"selectionIndexes" options:0 context:@"companies.selectionIndexes"];
[companiesController addObserver:self forKeyPath:@"arrangedObjects" options:0 context:@"companies.arrangedObjects"];
[employeesController addObserver:self forKeyPath:@"selectionIndexes" options:0 context:@"employees.selectionIndexes"];
[employeesController addObserver:self forKeyPath:@"selection" options:0 context:@"employees.selection"];
[employeesController addObserver:self forKeyPath:@"arrangedObjects" options:0 context:@"employees.arrangedObjects"];
observations = [];
[companiesController setSelectionIndexes:[CPIndexSet indexSetWithIndex:1]];
//for (var i = 0; i < [observations count]; i++)
// CPLog.error(observations[i].context);
// There should be exactly one observation of each kind, and they should be in the right
// order.
[self assert:5 equals:[observations count]];
[self assert:@"companies.selectionIndexes" equals:observations[0].context];
[self assert:@"employees.arrangedObjects" equals:observations[1].context];
[self assert:@"employees.selectionIndexes" equals:observations[2].context];
[self assert:@"employees.selection" equals:observations[3].context];
// This observation registers after the employees update because we are later in the
// observation queue than the binding.
[self assert:@"companies.selection" equals:observations[4].context];
}
- (void)testCompoundKeyPaths
{
var departmentNameField = [[CPTextField alloc] init];
@@ -524,6 +563,18 @@
[self assert:[1, 2, 1] equals:[ac arrangedObjects] message:"only one copy of 1 removed + the right copy should be removed"];
}
- (void)testSetOutOfBoundsSelectedIndexes
{
var ac = [CPArrayController new],
contentArray = [1, 2, 3],
indexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, 4)];
[ac setContent:contentArray];
[ac setSelectionIndexes:indexes];
[self assert:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, 3)] equals:[ac selectionIndexes]];
[self assert:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, 4)] equals:indexes];
}
- (void)observeValueForKeyPath:keyPath
ofObject:anActivity
change:change
@@ -534,6 +585,7 @@
[observations addObject:{
keyPath: keyPath,
context: context,
oldValue: [change valueForKey:CPKeyValueChangeOldKey],
newValue: [change valueForKey:CPKeyValueChangeNewKey]
}];
@@ -620,4 +672,25 @@
return self;
}
@end
@end
@implementation Companies : CPObject
{
CPMutableArray items @accessors;
}
- (id)init
{
self = [super init];
if (self)
{
items = [CPMutableArray array];
[items addObject:[CPDictionary dictionaryWithObjectsAndKeys:@"Spacely Sprockets", @"name", [CPArray arrayWithObjects:@"Tom", @"Dick", @"Harry"], @"employees"]];
[items addObject:[CPDictionary dictionaryWithObjectsAndKeys:@"Cogswell Cogs", @"name", [CPArray arrayWithObjects:@"Jane", @"Mary", @"Vic"], @"employees"]];
}
return self;
}
@end
+98 -5
View File
@@ -5,15 +5,108 @@
@implementation CPWindowTest : OJTestCase
{
CPWindow theWindow;
CPWindow _window @accessors(property=window);
}
-(void)testCanAllocWindow
- (void)setUp
{
theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(0,0,200,150)
styleMask:CPWindowNotSizable];
_window = [[CPWindow alloc] initWithContentRect:CGRectMake(0.0, 0.0, 1024.0, 768.0)
styleMask:CPWindowNotSizable];
}
[self assertTrue:!!theWindow];
- (void)testCanAllocWindow
{
[self assertTrue:!![self window]];
}
- (void)testThatContentViewIsInitialFirstResponder
{
var contentView = [[self window] contentView];
[self assert:contentView
equals:[[self window] initialFirstResponder]
message:@"The window's content view must be the initial first responder"];
}
- (void)testKeyViewLoop
{
var contentView = [[self window] contentView],
textField = [CPTextField textFieldWithStringValue:@"" placeholder:@"" width:100.0];
[textField setFrame:CGRectMake(100.0, 100.0, 100.0, 26.0)];
[contentView addSubview:textField];
[[self window] recalculateKeyViewLoop];
var nextTextField = [CPTextField textFieldWithStringValue:@"" placeholder:@"" width:100];
[nextTextField setFrame:CGRectMake(100.0, 200.0, 100.0, 26.0)];
[contentView addSubview:nextTextField];
[[self window] recalculateKeyViewLoop];
// Test nextKeyView
[self assert:textField
equals:[contentView nextKeyView]
message:@"textField should be the next key view of contentView"];
[self assert:nextTextField
equals:[textField nextKeyView]
message:@"nextTextField should be the next key view of textField"];
[self assert:contentView
equals:[nextTextField nextKeyView]
message:@"contentView should be the next key view of nextTextField"];
// Test previousKeyView
[self assert:contentView
equals:[textField previousKeyView]
message:@"contentView should be the previous key view of textField"];
[self assert:textField
equals:[nextTextField previousKeyView]
message:@"textField should be the previous key view of nextTextField"];
[self assert:nextTextField
equals:[contentView previousKeyView]
message:@"nextTextField should be the previous key view of contentView"];
}
- (void)testValiKeyViewLoop
{
var contentView = [[self window] contentView],
textField = [CPTextField textFieldWithStringValue:@"" placeholder:@"" width:100.0];
[textField setFrame:CGRectMake(100.0, 100.0, 100.0, 26.0)];
[contentView addSubview:textField];
[[self window] recalculateKeyViewLoop];
var nextTextField = [CPTextField textFieldWithStringValue:@"" placeholder:@"" width:100];
[nextTextField setFrame:CGRectMake(100.0, 200.0, 100.0, 26.0)];
[contentView addSubview:nextTextField];
[[self window] recalculateKeyViewLoop];
// Test nextValidKeyView
[self assert:textField
equals:[contentView nextValidKeyView]
message:@"textField should be the next valid key view of contentView"];
[self assert:nextTextField
equals:[textField nextValidKeyView]
message:@"nextTextField should be the next valid key view of textField"];
[self assert:textField
equals:[nextTextField nextValidKeyView]
message:@"textField should be the next key valid view of nextTextField"];
// Test previousValidKeyView
[self assert:nextTextField
equals:[textField previousValidKeyView]
message:@"nextTextField should be the previous valid key view of textField"];
[self assert:textField
equals:[nextTextField previousValidKeyView]
message:@"textField should be the previous key valid view of nextTextField"];
[self assert:nextTextField
equals:[contentView previousValidKeyView]
message:@"nextTextField should be the previous valid key view of contentView"];
}
@end
+396
View File
@@ -0,0 +1,396 @@
var COUNTER;
@implementation CPKVCArrayTest : OJTestCase
{
TestObject _object @accessors(property=object);
ImplementedTestObject _implementedObject @accessors(property=implementedObject);
}
- (void)setUp
{
_object = [[TestObject alloc] init];
_implementedObject = [[ImplementedTestObject alloc] init];
COUNTER = 0;
}
- (void)_patchSelector:(SEL)theSelector
{
var method_dtable = [[self object] class].method_dtable,
method_list = [[self object] class].method_list,
selectorsToRemove = [@selector(countOfValues), @selector(objectInValuesAtIndex),
@selector(objectInValuesAtIndex:), @selector(valuesAtIndexes:),
@selector(insertObject:inValuesAtIndex:), @selector(insertValues:atIndexes:),
@selector(removeObjectFromValuesAtIndex:), @selector(removeValuesAtIndexes:),
@selector(removeObjectFromValuesAtIndex:),
@selector(replaceObjectInValuesAtIndex:withObject:),
@selector(replaceValuesAtIndexes:withValues:)],
selectorIndex = [selectorsToRemove count];
while (selectorIndex--)
{
var selector = [selectorsToRemove objectAtIndex:selectorIndex],
implementation = method_dtable[selector];
if (!implementation)
continue;
delete method_dtable[selector]
[method_list removeObject:implementation];
}
var method = class_getInstanceMethod([[self implementedObject] class], theSelector),
implementation = method_getImplementation(method);
class_addMethod([[self object] class], theSelector, implementation);
}
- (void)testUsesCountOfKey
{
[self _patchSelector:@selector(countOfValues)];
var count = [[[self object] mutableArrayValueForKey:@"values"] count];
[self assert:10 equals:count message:@"countOfValues should return 10"];
[self assert:1 equals:COUNTER message:@"countOfValues should have been called once"]
}
- (void)testObjectAtIndexUsesObjectInKeyAtIndex
{
[self _patchSelector:@selector(objectInValuesAtIndex:)];
var values = [[self object] mutableArrayValueForKey:@"values"],
object = [values objectAtIndex:0];
[self assert:0 equals:object]
[self assert:1 equals:COUNTER message:@"objectInValuesAtIndex: should have been called once"];
}
- (void)testObjectsAtIndexesUsesObjectInKeyAtIndex
{
[self _patchSelector:@selector(objectInValuesAtIndex:)];
var values = [[self object] mutableArrayValueForKey:@"values"],
objects = [values objectsAtIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, 2)]];
[self assert:[0, 1] equals:objects]
[self assert:2 equals:COUNTER message:@"objectInValuesAtIndex: should have been called once"];
}
- (void)testObjectAtIndexUsesKeyAtIndexes
{
[self _patchSelector:@selector(valuesAtIndexes:)];
var values = [[self object] mutableArrayValueForKey:@"values"],
object = [values objectAtIndex:0];
[self assert:0 equals:object]
[self assert:1 equals:COUNTER message:@"valuesAtIndexes: should have been called once"];
}
- (void)testObjectsAtIndexesUsesKeyAtIndexes
{
[self _patchSelector:@selector(valuesAtIndexes:)];
var values = [[self object] mutableArrayValueForKey:@"values"],
objects = [values objectsAtIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, 2)]];
[self assert:[0, 1] equals:objects]
[self assert:1 equals:COUNTER message:@"valuesAtIndexes: should have been called once"];
}
- (void)testInsertObjectAtIndexUsesInsertKeyAtIndex
{
[self _patchSelector:@selector(insertObject:inValuesAtIndex:)];
[[[self object] mutableArrayValueForKey:@"values"] insertObject:11 atIndex:10];
[self assert:11 equals:[[[self object] values] objectAtIndex:10]];
[self assert:1 equals:COUNTER message:@"insertObject:inValuesAtIndex: should have been called once"];
}
- (void)testInsertObjectsAtIndexesUsesInsertKeyAtIndex
{
[self _patchSelector:@selector(insertObject:inValuesAtIndex:)];
var indexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(10, 2)];
[[[self object] mutableArrayValueForKey:@"values"] insertObjects:[11, 12] atIndexes:indexes];
[self assert:[11, 12] equals:[[[self object] values] objectsAtIndexes:indexes]];
[self assert:2
equals:COUNTER
message:@"insertValues:atIndexes: should have been called once for each object"];
}
- (void)testInsertObjectAtIndexUsesInsertKeyAtIndexes
{
[self _patchSelector:@selector(insertValues:atIndexes:)];
[[[self object] mutableArrayValueForKey:@"values"] insertObject:11 atIndex:10];
[self assert:11 equals:[[[self object] values] objectAtIndex:10]];
[self assert:1 equals:COUNTER message:@"insertValues:atIndexes: should have been called once"];
}
- (void)testInsertObjectsAtIndexesUsesInsertKeyAtIndexes
{
[self _patchSelector:@selector(insertValues:atIndexes:)];
var indexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(10, 2)];
[[[self object] mutableArrayValueForKey:@"values"] insertObjects:[11, 12] atIndexes:indexes];
[self assert:[11, 12] equals:[[[self object] values] objectsAtIndexes:indexes]];
[self assert:1
equals:COUNTER
message:@"insertValues:atIndexes: should have been called once for each object"];
}
- (void)testRemoveObjectAtIndexUsesRemoveObjectFromKeyAtIndex
{
[self _patchSelector:@selector(removeObjectFromValuesAtIndex:)];
[[[self object] mutableArrayValueForKey:@"values"] removeObjectAtIndex:0];
[self assert:[1, 2, 3, 4, 5, 6, 7, 8, 9] equals:[[self object] values]];
[self assert:1 equals:COUNTER message:@"removeObjectFromValuesAtIndex: should have been called once"];
}
- (void)testRemoveObjectAtIndexesUsesRemoveObjectFromKeyAtIndex
{
[self _patchSelector:@selector(removeObjectFromValuesAtIndex:)];
var indexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, 2)];
[[[self object] mutableArrayValueForKey:@"values"] removeObjectsAtIndexes:indexes];
[self assert:[2, 3, 4, 5, 6, 7, 8, 9] equals:[[self object] values]];
[self assert:2 equals:COUNTER message:@"removeValuesAtIndex: should have been called once for each object"];
}
- (void)testRemoveObjectsAtIndexesUsesRemoveKeyAtIndex
{
[self _patchSelector:@selector(removeValuesAtIndexes:)];
[[[self object] mutableArrayValueForKey:@"values"] removeObjectAtIndex:0];
[self assert:[1, 2, 3, 4, 5, 6, 7, 8, 9] equals:[[self object] values]];
[self assert:1
equals:COUNTER
message:@"removeValuesAtIndexes: should have been once for each object"];
}
- (void)testRemoveObjectsAtIndexesUsesRemoveKeyAtIndexes
{
[self _patchSelector:@selector(removeValuesAtIndexes:)];
var indexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(3, 2)];
[[[self object] mutableArrayValueForKey:@"values"] removeObjectsAtIndexes:indexes];
[self assert:[0, 1, 2, 5, 6, 7, 8, 9] equals:[[self object] values]];
[self assert:1 equals:COUNTER message:@"removeValuesAtIndexes: should have been called once"];
}
- (void)testRemoveObjectUsesRemoveKeyAtIndex
{
[self _patchSelector:@selector(removeObjectFromValuesAtIndex:)];
[[[self object] mutableArrayValueForKey:@"values"] removeObject:1];
[self assert:[0, 2, 3, 4, 5, 6, 7, 8, 9] equals:[[self object] values]];
[self assert:1 equals:COUNTER message:"removeObjectFromValuesAtIndex: should have been called once"]
}
- (void)testeRemoveObjectUsesRemoveKeyAtIndexes
{
[self _patchSelector:@selector(removeValuesAtIndexes:)];
[[[self object] mutableArrayValueForKey:@"values"] removeObject:5];
[self assert:[0, 1, 2, 3, 4, 6, 7, 8, 9] equals:[[self object] values]];
[self assert:1 equals:COUNTER message:@"removeValuesAtIndexes: should have been called once"];
}
- (void)testRemoveObjectsInArrayUsesRemoveKeyAtIndex
{
[self _patchSelector:@selector(removeObjectFromValuesAtIndex:)];
[[[self object] mutableArrayValueForKey:@"values"] removeObjectsInArray:[3, 6]];
[self assert:[0, 1, 2, 4, 5, 7, 8, 9] equals:[[self object] values]];
[self assert:2 equals:COUNTER message:"removeObjectFromValuesAtIndex: should have been called once"]
}
- (void)testRemoveObjectsInArrayUsesRemoveKeyAtIndexes
{
[self _patchSelector:@selector(removeValuesAtIndexes:)];
[[[self object] mutableArrayValueForKey:@"values"] removeObjectsInArray:[0, 9]];
[self assert:[1, 2, 3, 4, 5, 6, 7, 8] equals:[[self object] values]];
[self assert:1 equals:COUNTER message:@"removeValuesAtIndexes: should have been called once"];
}
- (void)testRemoveLastObjectUsesRemoveKeyAtIndex
{
[self _patchSelector:@selector(removeObjectFromValuesAtIndex:)];
[[[self object] mutableArrayValueForKey:@"values"] removeLastObject];
[self assert:[0, 1, 2, 3, 4, 5, 6, 7, 8] equals:[[self object] values]];
[self assert:1 equals:COUNTER message:"removeObjectFromValuesAtIndex: should have been called once"]
}
- (void)testRemoveLastObjectUsesRemoveKeyAtIndexes
{
[self _patchSelector:@selector(removeValuesAtIndexes:)];
[[[self object] mutableArrayValueForKey:@"values"] removeLastObject];
[self assert:[0, 1, 2, 3, 4, 5, 6, 7, 8] equals:[[self object] values]];
[self assert:1 equals:COUNTER message:@"removeValuesAtIndexes: should have been called once"];
}
- (void)testReplaceObjectAtIndexWithObjectUsesReplaceObjectInKeyAtIndexWithObject
{
[self _patchSelector:@selector(replaceObjectInValuesAtIndex:withObject:)];
[[[self object] mutableArrayValueForKey:@"values"] replaceObjectAtIndex:0 withObject:1];
[self assert:[1, 1, 2, 3, 4, 5, 6, 7, 8, 9] equals:[[self object] values]];
[self assert:1
equals:COUNTER
message:@"replaceObjectInValuesAtIndex:withObject: should have been called once"];
}
- (void)testReplaceObjectsAtIndexesWithObjectsUsesReplaceObjectInKeyAtIndexWithObject
{
[self _patchSelector:@selector(replaceObjectInValuesAtIndex:withObject:)];
var indexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(5, 3)];
[[[self object] mutableArrayValueForKey:@"values"] replaceObjectsAtIndexes:indexes withObjects:[1, 2, 3]];
[self assert:[0, 1, 2, 3, 4, 1, 2, 3, 8, 9] equals:[[self object] values]];
[self assert:3
equals:COUNTER
message:@"replaceObjectInValuesAtIndex:withObject: should have been called once"];
}
- (void)testReplaceObjectAtIndexWithObjectUsesReplaceKeyAtIndexesWithKeys
{
[self _patchSelector:@selector(replaceValuesAtIndexes:withValues:)];
[[[self object] mutableArrayValueForKey:@"values"] replaceObjectAtIndex:5 withObject:6];
[self assert:[0, 1, 2, 3, 4, 6, 6, 7, 8, 9] equals:[[self object] values]];
[self assert:1
equals:COUNTER
message:@"replaceObjectInValuesAtIndex:withObject: should have been called once"];
}
- (void)testReplaceObjectsAtIndexesWithObjectsUsesReplaceKeyAtIndexesWithKeys
{
[self _patchSelector:@selector(replaceValuesAtIndexes:withValues:)];
var indexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(6, 2)];
[[[self object] mutableArrayValueForKey:@"values"] replaceObjectsAtIndexes:indexes withObjects:[7, 8]];
[self assert:[0, 1, 2, 3, 4, 5, 7, 8, 8, 9] equals:[[self object] values]];
[self assert:1
equals:COUNTER
message:@"replaceObjectInValuesAtIndexes:withValues: should have been called once"];
}
@end
@implementation TestObject : CPObject
{
CPArray _values @accessors(property=values);
}
- (id)init
{
if (self = [super init])
{
_values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
}
return self;
}
@end
@implementation ImplementedTestObject : TestObject
{
}
- (int)countOfValues
{
// CPLog.warn(@"countOfValues");
COUNTER += 1;
return [[self values] count];
}
- (id)objectInValuesAtIndex:(int)theIndex
{
// CPLog.warn(@"objectInValuesAtIndex: %@", theIndex);
COUNTER += 1;
return [[self values] objectAtIndex:theIndex];
}
- (CPArray)valuesAtIndexes:(CPIndexSet)theIndexes
{
// CPLog.warn(@"valuesAtIndexes: %@", theIndexes);
COUNTER += 1;
return [[self values] objectsAtIndexes:theIndexes];
}
- (void)insertObject:(id)theObject inValuesAtIndex:(int)theIndex
{
// CPLog.warn(@"insertObject: %@ inValuesAtIndex: %@", theObject, theIndex);
COUNTER += 1;
[[self values] insertObject:theObject atIndex:theIndex];
}
- (void)insertValues:(CPArray)theObjects atIndexes:(CPIndexSet)theIndexes
{
// CPLog.warn(@"insertValues: %@ atIndexes: %@", theObjects, theIndexes);
COUNTER += 1;
[[self values] insertObjects:theObjects atIndexes:theIndexes];
}
- (void)removeObjectFromValuesAtIndex:(int)theIndex
{
// CPLog.warn(@"removeObjectFromValuesAtIndex: %@", theIndex);
COUNTER += 1;
[[self values] removeObjectAtIndex:theIndex];
}
- (void)removeValuesAtIndexes:(CPIndexSet)theIndexes
{
// CPLog.warn(@"removeValuesAtIndexes: %@", theIndexes);
COUNTER += 1;
[[self values] removeObjectsAtIndexes:theIndexes];
}
- (void)replaceObjectInValuesAtIndex:(int)theIndex withObject:(id)theObject
{
// CPLog.warn(@"replaceObjectInValuesAtIndex: %@ withObject: %@", theIndex, theObject);
COUNTER += 1;
[[self values] replaceObjectAtIndex:theIndex withObject:theObject];
}
- (void)replaceValuesAtIndexes:(CPIndexSet)theIndexes withValues:(id)theObjects
{
// CPLog.warn(@"replaceValuesAtIndexes: %@ withValues: %@", theIndexes, theObjects);
COUNTER += 1;
[[self values] replaceObjectsAtIndexes:theIndexes withObjects:theObjects];
}
@end
+12
View File
@@ -128,6 +128,18 @@
[self assert:"abcd" equals:["abcd" substringToIndex:4]];
[self assert:"abc" equals:["abcd" substringToIndex:3]];
[self assert:"" equals:["abcd" substringToIndex:0]];
var sawException = false;
try
{
[@"abcd" substringToIndex:5];
}
catch (anException)
{
sawException = true;
[self assert:CPRangeException equals:[anException name]];
}
[self assertTrue:sawException message:"expected CPRangeException"];
}
- (void)testBoolValue
-41
View File
@@ -78,27 +78,6 @@
[contentView addSubview:employeesScrollView];
[contentView addSubview:text];
var button = [CPButton buttonWithTitle:@"Add Item"];
[button setFrameOrigin:CGPointMake(500, 30)];
[button setTarget:self];
[button setAction:@selector(addItem:)];
[contentView addSubview:button];
button = [CPButton buttonWithTitle:@"Insert Item"];
[button setFrameOrigin:CGPointMake(500, 70)];
[button setTarget:self];
[button setAction:@selector(insertItem:)];
[contentView addSubview:button];
button = [CPButton buttonWithTitle:@"Remove Item"];
[button setFrameOrigin:CGPointMake(500, 110)];
[button setTarget:self];
[button setAction:@selector(removeItem:)];
[contentView addSubview:button];
companiesController = [CPArrayController new];
[companiesController bind:@"contentArray" toObject:companies withKeyPath:@"items" options:nil];
@@ -129,24 +108,4 @@
console.log("\nkeyPath: %s\ncontext: %s\nnew: %s\nold: %s", keyPath, context, [[change valueForKey:CPKeyValueChangeNewKey] description], [[change valueForKey:CPKeyValueChangeOldKey] description]);
}
- (void)addItem:(id)sender
{
var item = [CPDictionary dictionaryWithObjectsAndKeys:@"Seven Dwarves", @"name", [CPArray arrayWithObjects:@"Sneezy", @"Dopey", @"Sleepy", @"Doc", @"Bashful", @"Happy", @"Grumpy"], @"employees"];
[companiesController addObject:item];
}
- (void)insertItem:(id)sender
{
var item = [CPDictionary dictionaryWithObjectsAndKeys:@"Acme Corp", @"name", [CPArray arrayWithObjects:@"Road Runner", @"Wile E. Coyote"], @"employees"];
[companiesController insertObject:item atArrangedObjectIndex:1];
}
- (void)removeItem:(id)sender
{
if ([[companiesController arrangedObjects] count])
[companiesController removeObjectAtArrangedObjectIndex:0];
}
@end
-14
View File
@@ -1,14 +0,0 @@
Run this application with the current master, and note the following bugs:
- When you click on any item, there are two selection change notifications instead of one.
- If you compare the order of the notifications with Cocoa, they are slightly different.
- The right hand table is configured to allow an empty selection. If you click in the
empty area below the names, there is an empty selection notification, but then the
the current selection changes to the first item and generates another notification.
- If you select multiple items on the left, there is an error. This is a bug that will
have to be fixed in a later commit.
If you apply the changes in these commits, the first three bugs are fixed.
+8 -10
View File
@@ -54,6 +54,7 @@
@implementation AppController : CPObject
{
@outlet CPWindow theWindow;
CPWindow testWindow;
CPString employee @accessors;
Companies companies @accessors;
CPArrayController companiesController;
@@ -81,18 +82,17 @@
- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(30, 50, 500, 400) styleMask:CPTitledWindowMask | CPResizableWindowMask];
testWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(30, 50, 500, 400) styleMask:CPTitledWindowMask | CPResizableWindowMask];
var contentView = [theWindow contentView],
var contentView = [testWindow contentView],
companiesScrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(30, 30, 200, 100)],
companiesTable = [[CPTableView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)],
employeesScrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(250, 30, 200, 200)],
employeesTable = [[CPTableView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
[theWindow setTitle:@"CPComboBox (from code)"];
[testWindow setTitle:@"CPComboBox (from code)"];
var column = [[CPTableColumn alloc] initWithIdentifier:@"name"];
[column setResizingMask:CPTableColumnAutoresizingMask];
[companiesTable addTableColumn:column];
[companiesTable setAllowsMultipleSelection:YES];
@@ -107,7 +107,6 @@
[contentView addSubview:companiesScrollView];
column = [[CPTableColumn alloc] initWithIdentifier:@"name"];
[column setResizingMask:CPTableColumnAutoresizingMask];
[employeesTable addTableColumn:column];
[employeesTable setAllowsMultipleSelection:YES];
@@ -130,11 +129,11 @@
[contentView addSubview:textfield];
var center = [CPNotificationCenter defaultCenter];
[center addObserver:self selector:@selector(comboNote:) name:CPComboBoxSelectionDidChangeNotification object:combo];
[center addObserver:self selector:@selector(comboNote:) name:CPComboBoxSelectionIsChangingNotification object:combo];
[center addObserver:self selector:@selector(comboNote:) name:CPComboBoxWillDismissNotification object:combo];
[center addObserver:self selector:@selector(comboNote:) name:CPComboBoxWillPopUpNotification object:combo];
[center addObserver:self selector:@selector(comboNote:) name:CPControlTextDidEndEditingNotification object:combo];
nextCheckboxY = 166;
[self makeCheckBoxWithTitle:@"Enabled" defaultState:CPOnState];
@@ -153,7 +152,6 @@
[employeesController bind:@"contentArray" toObject:companiesController withKeyPath:@"selection.employees" options:nil];
var employeeController = [CPObjectController new];
[employeeController bind:@"content" toObject:employeesController withKeyPath:@"selection.self" options:nil];
[[companiesTable tableColumnWithIdentifier:@"name"] bind:@"value" toObject:companiesController withKeyPath:@"arrangedObjects.name" options:nil];
@@ -169,8 +167,8 @@
[employeesController addObserver:self forKeyPath:@"arrangedObjects" options:0 context:@"employees.arrangedObjects"];
[combo addObserver:self forKeyPath:@"value" options:0 context:@"combo.value"];
[theWindow setInitialFirstResponder:companiesTable];
[theWindow orderFront:self];
[testWindow setInitialFirstResponder:combo];
[testWindow makeKeyAndOrderFront:self];
}
- (void)makeCheckBoxWithTitle:(CPString)aTitle defaultState:(BOOL)aState
@@ -180,7 +178,7 @@
[checkbox setState:aState];
[checkbox setTarget:self];
[checkbox setAction:@selector(setComboState:)];
[[theWindow contentView] addSubview:checkbox];
[[testWindow contentView] addSubview:checkbox];
nextCheckboxY += 25;
}
File diff suppressed because one or more lines are too long
@@ -735,7 +735,7 @@
<reference key="dict.values" ref="0"/>
</object>
<nil key="sourceID"/>
<int key="maxID">574</int>
<int key="maxID">576</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
+36 -12
View File
@@ -15,6 +15,7 @@ var STATES = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorad
CPTokenField tokenFieldD;
CPArray allPersons;
CPButton manipulateTokenInsertionButton;
}
- (void)applicationDidFinishLaunching:(CPNotification)aNotification
@@ -22,28 +23,28 @@ var STATES = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorad
var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask],
contentView = [theWindow contentView],
tokenFieldA = [[CPTokenField alloc] initWithFrame:CGRectMake(15, 40, 500, 29)],
tokenFieldA = [[CPTokenField alloc] initWithFrame:CGRectMake(15, 40, 500, 30)],
label = [[CPTextField alloc] initWithFrame:CGRectMake(15, 15, 500, 24)];
[label setStringValue:@"This token field has no auto suggestions and uses space to separate tokens."];
[label setStringValue:"This token field has no auto suggestions and uses space to separate tokens."];
[contentView addSubview:label];
[tokenFieldA setEditable:YES];
[tokenFieldA setPlaceholderString:@"Type in a token!"];
[tokenFieldA setPlaceholderString:"Type in a token!"];
[tokenFieldA setTokenizingCharacterSet:[CPCharacterSet characterSetWithCharactersInString:@" "]];
[contentView addSubview:tokenFieldA];
var tokenFieldB = [[CPTokenField alloc] initWithFrame:CGRectMake(15, 110, 500, 29)],
var tokenFieldB = [[CPTokenField alloc] initWithFrame:CGRectMake(15, 110, 500, 30)],
labelB = [[CPTextField alloc] initWithFrame:CGRectMake(15, 80, 500, 24)];
[labelB setStringValue:@"This token field has no bezel, uses comma to separate tokens and has auto suggest."];
[labelB setStringValue:"This token field has no bezel, uses comma to separate tokens and has auto suggest."];
[contentView addSubview:labelB];
[tokenFieldB setEditable:YES];
[tokenFieldB setBezeled:NO];
[tokenFieldB setPlaceholderString:@"Edit me!"];
[tokenFieldB setPlaceholderString:"Edit me!"];
[tokenFieldB setObjectValue:["Missouri", "California"]];
[tokenFieldB setDelegate:self];
@@ -53,14 +54,18 @@ var STATES = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorad
[contentView addSubview:tokenFieldB];
var tokenFieldC = [[CPTokenField alloc] initWithFrame:CGRectMake(15, 170, 500, 29)],
manipulateTokenInsertionButton = [CPCheckBox checkBoxWithTitle:"Token transformations"];
[manipulateTokenInsertionButton setFrame:CGRectMake(525, 110, 200, 50)];
[contentView addSubview:manipulateTokenInsertionButton];
var tokenFieldC = [[CPTokenField alloc] initWithFrame:CGRectMake(15, 170, 500, 30)],
labelC = [[CPTextField alloc] initWithFrame:CGRectMake(15, 150, 500, 24)];
[labelC setStringValue:@"This token field can't fit all its tokens."];
[labelC setStringValue:"This token field can't fit all its tokens."];
[contentView addSubview:labelC];
[tokenFieldC setEditable:YES];
[tokenFieldC setPlaceholderString:@"Edit me!"];
[tokenFieldC setPlaceholderString:"Edit me!"];
[tokenFieldC setObjectValue:['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado']];
[tokenFieldC setDelegate:self];
@@ -71,10 +76,10 @@ var STATES = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorad
[tokenFieldC setAction:@selector(tokenFieldAction:)];
[tokenFieldC setTarget:self];
tokenFieldD = [[CPTokenField alloc] initWithFrame:CGRectMake(15, 230, 500, 29)],
tokenFieldD = [[CPTokenField alloc] initWithFrame:CGRectMake(15, 230, 500, 30)],
labelD = [[CPTextField alloc] initWithFrame:CGRectMake(15, 210, 500, 24)];
[labelD setStringValue:@"This token field contains represented objects."];
[labelD setStringValue:"This token field contains represented objects."];
[contentView addSubview:labelD];
[tokenFieldD setEditable:YES];
@@ -93,7 +98,7 @@ var STATES = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorad
[contentView addSubview:tokenFieldD];
var button = [[CPButton alloc] initWithFrame:CGRectMake(15, 270, 0, 0)];
[button setTitle:@"Get Object Values"];
[button setTitle:"Get Object Values"];
[button sizeToFit];
[button setTarget:self];
[button setAction:@selector(getObjectValues:)];
@@ -148,6 +153,25 @@ var STATES = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorad
CPLog.info("tokenFieldAction: " + sender);
}
- (CPArray)tokenField:tokenField shouldAddObjects:tokens atIndex:index
{
CPLog.info("tokenField: " + tokenField + " shouldAddObjects: " + tokens + " atIndex: " + index);
// Texas -> Utah, Michigan -> Michigan & Arkansas, Washington -> nil
if ([manipulateTokenInsertionButton intValue])
{
if (tokens[0] == "Texas")
return ["Utah"];
else if (tokens[0] == "Michigan")
return ["Michigan", "Arkansas"];
else if (tokens[0] == "Washington")
return [];
}
return tokens;
}
@end
// A sample of a custom Object
+36 -22
View File
@@ -30,44 +30,53 @@
{
// This is called when the cib is done loading.
// You can implement this method on any object instantiated from a Cib.
// It's a useful hook for setting up current UI values, and other things.
// It's a useful hook for setting up current UI values, and other things.
// In this case, we want the window from Cib to become our full browser window
//[theWindow setFullBridge:YES];
platformWindow = [[CPPlatformWindow alloc] init];
// [platformWindow orderFront:self];//console.log(CPStringFromRect([theWindow contentRectForFrameRect:[theWindow frame]]));
// [platformWindow orderFront:self];//console.log(CPStringFromRect([theWindow contentRectForFrameRect:[theWindow frame]]));
[platformWindow setContentRect:[theWindow contentRectForFrameRect:[theWindow frame]]];
//[platformWindow orderFront:self];
// seriously, this test file is dirty :)
var slider = [[theWindow contentView] subviews][0];
[slider setTarget:self];
[slider setAction:@selector(randomTitle:)];
[slider setContinuous:NO];
window.setTimeout(function(){
[theWindow orderOut:self];
[theWindow setPlatformWindow:platformWindow];
[theWindow orderFront:self];
[theWindow setFullBridge:YES];
var button = [[theWindow contentView] subviews][2];
[theWindow setTitle:"Initial title (pop out pending)"];
window.setTimeout(function()
{
[theWindow orderOut:self];
[theWindow setPlatformWindow:platformWindow];
[theWindow orderFront:self];
[theWindow setFullBridge:YES];
var button = [[theWindow contentView] subviews][2];
[button setTarget:self];
[button setAction:@selector(close)];
[button setTarget:self];
[button setAction:@selector(close)];
[theWindow setTitle:"Title after pop out (red box pending)"];
window.setTimeout(function(){
var view = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 100.0)];
[view setBackgroundColor:[CPColor redColor]];
[[theWindow contentView] addSubview:view];},1000);
}, 1000);
//window.setTimeout(function() { [platformWindow orderOut:self]; [platformWindow orderFront:self]; }, 2000);
window.setTimeout(function()
{
var view = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 100.0)];
[view setBackgroundColor:[CPColor redColor]];
[[theWindow contentView] addSubview:view];
[theWindow setTitle:"Title in final stage"];
}, 1000);
}, 2000);
}
- (void)close
{
[[theWindow platformWindow] orderOut:self];
window.setTimeout(function(){
[[theWindow platformWindow] orderFront:self];}, 1000);
window.setTimeout(function()
{
[[theWindow platformWindow] orderFront:self];
}, 1000);
}
- (void)another:(id)aSender
@@ -75,4 +84,9 @@ window.setTimeout(function(){
[platformWindow orderFront:self];
}
- (IBAction)randomTitle:(id)aSender
{
[theWindow setTitle:@"Window random number " + Math.random(1000)];
}
@end
@@ -0,0 +1,10 @@
@interface AppController : NSObject
{
IBOutlet NSWindow* theWindow;
IBOutlet NSTextField* field1;
IBOutlet NSTextField* field2;
IBOutlet NSTextField* status;
}
@end
@@ -0,0 +1,357 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
9EEC4498135749D200615446 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EEC4497135749D200615446 /* Cocoa.framework */; };
9EEC44B5135749D300615446 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EEC4497135749D200615446 /* Cocoa.framework */; };
9EEC44CC13574A0B00615446 /* resignFirstResponder-CPControlTextDidEndEditing in Resources */ = {isa = PBXBuildFile; fileRef = 9EEC44CB13574A0B00615446 /* resignFirstResponder-CPControlTextDidEndEditing */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
9EEC44B6135749D300615446 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 9EEC448A135749D200615446 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 9EEC4492135749D200615446;
remoteInfo = Another;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
9EEC4493135749D200615446 /* Another.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Another.app; sourceTree = BUILT_PRODUCTS_DIR; };
9EEC4497135749D200615446 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
9EEC449A135749D300615446 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
9EEC449B135749D300615446 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
9EEC449C135749D300615446 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
9EEC44B4135749D300615446 /* AnotherTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AnotherTests.octest; sourceTree = BUILT_PRODUCTS_DIR; };
9EEC44CB13574A0B00615446 /* resignFirstResponder-CPControlTextDidEndEditing */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "resignFirstResponder-CPControlTextDidEndEditing"; path = ..; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
9EEC4490135749D200615446 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9EEC4498135749D200615446 /* Cocoa.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
9EEC44B0135749D300615446 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9EEC44B5135749D300615446 /* Cocoa.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
9EEC4488135749D200615446 = {
isa = PBXGroup;
children = (
9EEC44CB13574A0B00615446 /* resignFirstResponder-CPControlTextDidEndEditing */,
9EEC4496135749D200615446 /* Frameworks */,
9EEC4494135749D200615446 /* Products */,
);
sourceTree = "<group>";
};
9EEC4494135749D200615446 /* Products */ = {
isa = PBXGroup;
children = (
9EEC4493135749D200615446 /* Another.app */,
9EEC44B4135749D300615446 /* AnotherTests.octest */,
);
name = Products;
sourceTree = "<group>";
};
9EEC4496135749D200615446 /* Frameworks */ = {
isa = PBXGroup;
children = (
9EEC4497135749D200615446 /* Cocoa.framework */,
9EEC4499135749D300615446 /* Other Frameworks */,
);
name = Frameworks;
sourceTree = "<group>";
};
9EEC4499135749D300615446 /* Other Frameworks */ = {
isa = PBXGroup;
children = (
9EEC449A135749D300615446 /* AppKit.framework */,
9EEC449B135749D300615446 /* CoreData.framework */,
9EEC449C135749D300615446 /* Foundation.framework */,
);
name = "Other Frameworks";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
9EEC4492135749D200615446 /* Another */ = {
isa = PBXNativeTarget;
buildConfigurationList = 9EEC44C5135749D300615446 /* Build configuration list for PBXNativeTarget "Another" */;
buildPhases = (
9EEC448F135749D200615446 /* Sources */,
9EEC4490135749D200615446 /* Frameworks */,
9EEC4491135749D200615446 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = Another;
productName = Another;
productReference = 9EEC4493135749D200615446 /* Another.app */;
productType = "com.apple.product-type.application";
};
9EEC44B3135749D300615446 /* AnotherTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 9EEC44C8135749D300615446 /* Build configuration list for PBXNativeTarget "AnotherTests" */;
buildPhases = (
9EEC44AF135749D300615446 /* Sources */,
9EEC44B0135749D300615446 /* Frameworks */,
9EEC44B1135749D300615446 /* Resources */,
9EEC44B2135749D300615446 /* ShellScript */,
);
buildRules = (
);
dependencies = (
9EEC44B7135749D300615446 /* PBXTargetDependency */,
);
name = AnotherTests;
productName = AnotherTests;
productReference = 9EEC44B4135749D300615446 /* AnotherTests.octest */;
productType = "com.apple.product-type.bundle";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
9EEC448A135749D200615446 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0420;
ORGANIZATIONNAME = "280 North, Inc.";
};
buildConfigurationList = 9EEC448D135749D200615446 /* Build configuration list for PBXProject "resignFirstResponder-CPControlTextDidEndEditing" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 9EEC4488135749D200615446;
productRefGroup = 9EEC4494135749D200615446 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
9EEC4492135749D200615446 /* Another */,
9EEC44B3135749D300615446 /* AnotherTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
9EEC4491135749D200615446 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9EEC44CC13574A0B00615446 /* resignFirstResponder-CPControlTextDidEndEditing in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
9EEC44B1135749D300615446 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
9EEC44B2135749D300615446 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
9EEC448F135749D200615446 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
9EEC44AF135749D300615446 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
9EEC44B7135749D300615446 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 9EEC4492135749D200615446 /* Another */;
targetProxy = 9EEC44B6135749D300615446 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
9EEC44C3135749D300615446 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = DEBUG;
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.6;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
9EEC44C4135749D300615446 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.6;
SDKROOT = macosx;
};
name = Release;
};
9EEC44C6135749D300615446 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Another/Another-Prefix.pch";
INFOPLIST_FILE = "Another/Another-Info.plist";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
name = Debug;
};
9EEC44C7135749D300615446 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Another/Another-Prefix.pch";
INFOPLIST_FILE = "Another/Another-Info.plist";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
name = Release;
};
9EEC44C9135749D300615446 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Another.app/Contents/MacOS/Another";
COPY_PHASE_STRIP = NO;
FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks";
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "AnotherTests/AnotherTests-Prefix.pch";
INFOPLIST_FILE = "AnotherTests/AnotherTests-Info.plist";
OTHER_LDFLAGS = (
"-framework",
SenTestingKit,
);
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUNDLE_LOADER)";
WRAPPER_EXTENSION = octest;
};
name = Debug;
};
9EEC44CA135749D300615446 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Another.app/Contents/MacOS/Another";
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks";
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "AnotherTests/AnotherTests-Prefix.pch";
INFOPLIST_FILE = "AnotherTests/AnotherTests-Info.plist";
OTHER_LDFLAGS = (
"-framework",
SenTestingKit,
);
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUNDLE_LOADER)";
WRAPPER_EXTENSION = octest;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
9EEC448D135749D200615446 /* Build configuration list for PBXProject "resignFirstResponder-CPControlTextDidEndEditing" */ = {
isa = XCConfigurationList;
buildConfigurations = (
9EEC44C3135749D300615446 /* Debug */,
9EEC44C4135749D300615446 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
9EEC44C5135749D300615446 /* Build configuration list for PBXNativeTarget "Another" */ = {
isa = XCConfigurationList;
buildConfigurations = (
9EEC44C6135749D300615446 /* Debug */,
9EEC44C7135749D300615446 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
9EEC44C8135749D300615446 /* Build configuration list for PBXNativeTarget "AnotherTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
9EEC44C9135749D300615446 /* Debug */,
9EEC44CA135749D300615446 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 9EEC448A135749D200615446 /* Project object */;
}
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:resignFirstResponder-CPControlTextDidEndEditing.xcodeproj">
</FileRef>
</Workspace>
@@ -0,0 +1,38 @@
/*
* AppController.j
* resignFirstResponder-CPControlTextDidEndEditing
*
* Created by aparajita on September 2, 2011.
* Copyright 2011, Victory-Heart Productions All rights reserved.
*/
@import <Foundation/CPObject.j>
@implementation AppController : CPObject
{
@outlet CPWindow theWindow;
@outlet CPTextField field1;
@outlet CPTextField field2;
@outlet CPTextField status;
}
- (void)awakeFromCib
{
var center = [CPNotificationCenter defaultCenter];
[center addObserver:self selector:@selector(showNote:) name:CPControlTextDidBeginEditingNotification object:field1];
[center addObserver:self selector:@selector(showNote:) name:CPControlTextDidEndEditingNotification object:field1];
[center addObserver:self selector:@selector(showNote:) name:CPControlTextDidBeginEditingNotification object:field2];
[center addObserver:self selector:@selector(showNote:) name:CPControlTextDidEndEditingNotification object:field2];
[status setStringValue:@""];
}
- (void)showNote:(CPNotification)note
{
var fieldName = [note object] === field1 ? "field1" : "field2";
[status setStringValue:[CPString stringWithFormat:@"%@\n%@", fieldName, [note name]]];
}
@end
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Main cib file base name</key>
<string>MainMenu.cib</string>
<key>CPBundleName</key>
<string>resignFirstResponder-CPControlTextDidEndEditing</string>
</dict>
</plist>
@@ -0,0 +1,94 @@
/*
* Jakefile
* resignFirstResponder-CPControlTextDidEndEditing
*
* Created by aparajita on September 2, 2011.
* Copyright 2011, Victory-Heart Productions All rights reserved.
*/
var ENV = require("system").env,
FILE = require("file"),
JAKE = require("jake"),
task = JAKE.task,
FileList = JAKE.FileList,
app = require("cappuccino/jake").app,
configuration = ENV["CONFIG"] || ENV["CONFIGURATION"] || ENV["c"] || "Debug",
OS = require("os");
app ("resignFirstResponderCPControlTextDidEndEditing", function(task)
{
task.setBuildIntermediatesPath(FILE.join("Build", "resignFirstResponderCPControlTextDidEndEditing.build", configuration));
task.setBuildPath(FILE.join("Build", configuration));
task.setProductName("resignFirstResponder-CPControlTextDidEndEditing");
task.setIdentifier("com.aparajita.resignFirstResponderCPControlTextDidEndEditing");
task.setVersion("1.0");
task.setAuthor("Victory-Heart Productions");
task.setEmail("feedback @nospam@ yourcompany.com");
task.setSummary("resignFirstResponder-CPControlTextDidEndEditing");
task.setSources((new FileList("**/*.j")).exclude(FILE.join("Build", "**")));
task.setResources(new FileList("Resources/**"));
task.setIndexFilePath("index.html");
task.setInfoPlistPath("Info.plist");
task.setNib2CibFlags("-R Resources/");
if (configuration === "Debug")
task.setCompilerFlags("-DDEBUG -g");
else
task.setCompilerFlags("-O");
});
task ("default", ["resignFirstResponderCPControlTextDidEndEditing"], function()
{
printResults(configuration);
});
task ("build", ["default"]);
task ("debug", function()
{
ENV["CONFIGURATION"] = "Debug";
JAKE.subjake(["."], "build", ENV);
});
task ("release", function()
{
ENV["CONFIGURATION"] = "Release";
JAKE.subjake(["."], "build", ENV);
});
task ("run", ["debug"], function()
{
OS.system(["open", FILE.join("Build", "Debug", "resignFirstResponderCPControlTextDidEndEditing", "index.html")]);
});
task ("run-release", ["release"], function()
{
OS.system(["open", FILE.join("Build", "Release", "resignFirstResponderCPControlTextDidEndEditing", "index.html")]);
});
task ("deploy", ["release"], function()
{
FILE.mkdirs(FILE.join("Build", "Deployment", "resignFirstResponderCPControlTextDidEndEditing"));
OS.system(["press", "-f", FILE.join("Build", "Release", "resignFirstResponderCPControlTextDidEndEditing"), FILE.join("Build", "Deployment", "resignFirstResponderCPControlTextDidEndEditing")]);
printResults("Deployment")
});
task ("desktop", ["release"], function()
{
FILE.mkdirs(FILE.join("Build", "Desktop", "resignFirstResponderCPControlTextDidEndEditing"));
require("cappuccino/nativehost").buildNativeHost(FILE.join("Build", "Release", "resignFirstResponderCPControlTextDidEndEditing"), FILE.join("Build", "Desktop", "resignFirstResponderCPControlTextDidEndEditing", "resignFirstResponderCPControlTextDidEndEditing.app"));
printResults("Desktop")
});
task ("run-desktop", ["desktop"], function()
{
OS.system([FILE.join("Build", "Desktop", "resignFirstResponderCPControlTextDidEndEditing", "resignFirstResponderCPControlTextDidEndEditing.app", "Contents", "MacOS", "NativeHost"), "-i"]);
});
function printResults(configuration)
{
print("----------------------------");
print(configuration+" app built at path: "+FILE.join("Build", configuration, "resignFirstResponderCPControlTextDidEndEditing"));
print("----------------------------");
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,431 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
<data>
<int key="IBDocument.SystemTarget">1050</int>
<string key="IBDocument.SystemVersion">10K549</string>
<string key="IBDocument.InterfaceBuilderVersion">1923</string>
<string key="IBDocument.AppKitVersion">1038.36</string>
<string key="IBDocument.HIToolboxVersion">461.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">1923</string>
</object>
<object class="NSArray" key="IBDocument.IntegratedClassDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>NSTextField</string>
<string>NSTextFieldCell</string>
<string>NSWindowTemplate</string>
<string>NSView</string>
<string>NSCustomObject</string>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</object>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1048">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSCustomObject" id="1021">
<string key="NSClassName">NSApplication</string>
</object>
<object class="NSCustomObject" id="1014">
<string key="NSClassName">FirstResponder</string>
</object>
<object class="NSCustomObject" id="1050">
<string key="NSClassName">NSApplication</string>
</object>
<object class="NSWindowTemplate" id="972006081">
<int key="NSWindowStyleMask">7</int>
<int key="NSWindowBacking">2</int>
<string key="NSWindowRect">{{131, 728}, {480, 360}}</string>
<int key="NSWTFlags">1946157056</int>
<string key="NSWindowTitle">Window</string>
<string key="NSWindowClass">NSWindow</string>
<nil key="NSViewClass"/>
<object class="NSView" key="NSWindowView" id="439893737">
<reference key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSTextField" id="160623561">
<reference key="NSNextResponder" ref="439893737"/>
<int key="NSvFlags">301</int>
<string key="NSFrame">{{192, 275}, {96, 22}}</string>
<reference key="NSSuperview" ref="439893737"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="818861456"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="46991665">
<int key="NSCellFlags">-1804468671</int>
<int key="NSCellFlags2">272630784</int>
<string key="NSContents"/>
<object class="NSFont" key="NSSupport" id="105728881">
<string key="NSName">LucidaGrande</string>
<double key="NSSize">13</double>
<int key="NSfFlags">1044</int>
</object>
<reference key="NSControlView" ref="160623561"/>
<bool key="NSDrawsBackground">YES</bool>
<object class="NSColor" key="NSBackgroundColor" id="878641937">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">textBackgroundColor</string>
<object class="NSColor" key="NSColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
</object>
<object class="NSColor" key="NSTextColor" id="286271178">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">textColor</string>
<object class="NSColor" key="NSColor" id="658927846">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MAA</bytes>
</object>
</object>
</object>
</object>
<object class="NSTextField" id="818861456">
<reference key="NSNextResponder" ref="439893737"/>
<int key="NSvFlags">301</int>
<string key="NSFrame">{{192, 220}, {96, 22}}</string>
<reference key="NSSuperview" ref="439893737"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="279373907">
<int key="NSCellFlags">-1804468671</int>
<int key="NSCellFlags2">272630784</int>
<string key="NSContents"/>
<reference key="NSSupport" ref="105728881"/>
<reference key="NSControlView" ref="818861456"/>
<bool key="NSDrawsBackground">YES</bool>
<reference key="NSBackgroundColor" ref="878641937"/>
<reference key="NSTextColor" ref="286271178"/>
</object>
</object>
<object class="NSTextField" id="883996342">
<reference key="NSNextResponder" ref="439893737"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{17, 76}, {446, 94}}</string>
<reference key="NSSuperview" ref="439893737"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="483058531">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">138412032</int>
<string key="NSContents">Multiline Label</string>
<object class="NSFont" key="NSSupport">
<string key="NSName">LucidaGrande</string>
<double key="NSSize">13</double>
<int key="NSfFlags">16</int>
</object>
<reference key="NSControlView" ref="883996342"/>
<object class="NSColor" key="NSBackgroundColor">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">controlColor</string>
<object class="NSColor" key="NSColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
</object>
</object>
<object class="NSColor" key="NSTextColor">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">controlTextColor</string>
<reference key="NSColor" ref="658927846"/>
</object>
</object>
</object>
</object>
<string key="NSFrameSize">{480, 360}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="160623561"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1920, 1178}}</string>
<string key="NSMaxSize">{1e+13, 1e+13}</string>
</object>
<object class="NSCustomObject" id="635946545">
<string key="NSClassName">AppController</string>
</object>
</object>
<object class="IBObjectContainer" key="IBDocument.Objects">
<object class="NSMutableArray" key="connectionRecords">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="1021"/>
<reference key="destination" ref="635946545"/>
</object>
<int key="connectionID">451</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">initialFirstResponder</string>
<reference key="source" ref="972006081"/>
<reference key="destination" ref="160623561"/>
</object>
<int key="connectionID">469</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">theWindow</string>
<reference key="source" ref="635946545"/>
<reference key="destination" ref="972006081"/>
</object>
<int key="connectionID">459</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">field1</string>
<reference key="source" ref="635946545"/>
<reference key="destination" ref="160623561"/>
</object>
<int key="connectionID">466</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">field2</string>
<reference key="source" ref="635946545"/>
<reference key="destination" ref="818861456"/>
</object>
<int key="connectionID">467</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">status</string>
<reference key="source" ref="635946545"/>
<reference key="destination" ref="883996342"/>
</object>
<int key="connectionID">468</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBObjectRecord">
<int key="objectID">0</int>
<object class="NSArray" key="object" id="0">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<reference key="children" ref="1048"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="1021"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="1014"/>
<reference key="parent" ref="0"/>
<string key="objectName">First Responder</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-3</int>
<reference key="object" ref="1050"/>
<reference key="parent" ref="0"/>
<string key="objectName">Application</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">371</int>
<reference key="object" ref="972006081"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="439893737"/>
</object>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">372</int>
<reference key="object" ref="439893737"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="160623561"/>
<reference ref="818861456"/>
<reference ref="883996342"/>
</object>
<reference key="parent" ref="972006081"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">450</int>
<reference key="object" ref="635946545"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">456</int>
<reference key="object" ref="160623561"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="46991665"/>
</object>
<reference key="parent" ref="439893737"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">457</int>
<reference key="object" ref="46991665"/>
<reference key="parent" ref="160623561"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">460</int>
<reference key="object" ref="818861456"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="279373907"/>
</object>
<reference key="parent" ref="439893737"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">461</int>
<reference key="object" ref="279373907"/>
<reference key="parent" ref="818861456"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">464</int>
<reference key="object" ref="883996342"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="483058531"/>
</object>
<reference key="parent" ref="439893737"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">465</int>
<reference key="object" ref="483058531"/>
<reference key="parent" ref="883996342"/>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>-1.IBPluginDependency</string>
<string>-2.IBPluginDependency</string>
<string>-3.IBPluginDependency</string>
<string>371.IBPluginDependency</string>
<string>371.IBWindowTemplateEditedContentRect</string>
<string>371.NSWindowTemplate.visibleAtLaunch</string>
<string>372.IBPluginDependency</string>
<string>450.IBPluginDependency</string>
<string>456.IBPluginDependency</string>
<string>457.IBPluginDependency</string>
<string>460.IBPluginDependency</string>
<string>461.IBPluginDependency</string>
<string>464.IBPluginDependency</string>
<string>465.IBPluginDependency</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{303, 221}, {480, 360}}</string>
<integer value="1"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
<reference key="dict.values" ref="0"/>
</object>
<nil key="activeLocalization"/>
<object class="NSMutableDictionary" key="localizations">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
<reference key="dict.values" ref="0"/>
</object>
<nil key="sourceID"/>
<int key="maxID">469</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
<string key="className">AppController</string>
<string key="superclassName">NSObject</string>
<object class="NSMutableDictionary" key="outlets">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>field1</string>
<string>field2</string>
<string>status</string>
<string>theWindow</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>NSTextField</string>
<string>NSTextField</string>
<string>NSTextField</string>
<string>NSWindow</string>
</object>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>field1</string>
<string>field2</string>
<string>status</string>
<string>theWindow</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBToOneOutletInfo">
<string key="name">field1</string>
<string key="candidateClassName">NSTextField</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">field2</string>
<string key="candidateClassName">NSTextField</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">status</string>
<string key="candidateClassName">NSTextField</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">theWindow</string>
<string key="candidateClassName">NSWindow</string>
</object>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/AppController.h</string>
</object>
</object>
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
<integer value="1050" key="NS.object.0"/>
</object>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3</string>
<integer value="3000" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
</data>
</archive>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

@@ -0,0 +1,103 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!--
index-debug.html
resignFirstResponder-CPControlTextDidEndEditing
Created by aparajita on September 2, 2011.
Copyright 2011, Victory-Heart Productions All rights reserved.
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7, chrome=1" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<link rel="apple-touch-icon" href="Resources/icon.png" />
<link rel="apple-touch-startup-image" href="Resources/default.png" />
<title>resignFirstResponder-CPControlTextDidEndEditing</title>
<script type="text/javascript">
OBJJ_MAIN_FILE = "main.j";
OBJJ_INCLUDE_PATHS = ["Frameworks/Debug", "Frameworks", "SomethingElse"];
</script>
<script type="text/javascript" src="Frameworks/Debug/Objective-J/Objective-J.js" charset="UTF-8"></script>
<script type="text/javascript">
objj_msgSend_reset();
// DEBUG OPTIONS:
// Uncomment to enable printing of backtraces on exceptions:
//objj_msgSend_decorate(objj_backtrace_decorator);
// Uncomment to supress exceptions that take place inside a message
//objj_msgSend_decorate(objj_supress_exceptions_decorator)
// Uncomment to enable runtime type checking:
//objj_msgSend_decorate(objj_typecheck_decorator);
// Uncomment (along with both above) to print backtraces on type check errors:
//objj_typecheck_prints_backtrace = true;
// Uncomment to disable the default logger (CPLogConsole if window.console exists, CPLogPopup otherwise):
//CPLogUnregister(CPLogDefault);
// Uncomment to enable a specific logger:
//CPLogRegister(CPLogConsole);
//CPLogRegister(CPLogPopup);
</script>
<style type="text/css">
body{margin:0; padding:0;}
#container {position: absolute; top:50%; left:50%;}
#content {width:800px; text-align:center; margin-left: -400px; height:50px; margin-top:-25px; line-height: 50px;}
#content {font-family: "Helvetica", "Arial", sans-serif; font-size: 18px; color: black; text-shadow: 0px 1px 0px white; }
#loadgraphic {margin-right: 0.2em; margin-bottom:-2px;}
</style>
<!--[if lt IE 7]>
<STYLE type="text/css">
#container { position: relative; top: 50%; }
#content { position: relative;}
</STYLE>
<![endif]-->
</head>
<body style="">
<div id="cappuccino-body">
<div id="loadingcontainer" style="background-color: #eeeeee; overflow:hidden; width:100%; height:100%; position: absolute; top: 0; left: 0;">
<script type="text/javascript">
document.write("<div id='container'><p id='content'>" +
"<img id='loadgraphic' width='16' height='16' src='Resources/spinner.gif' /> " +
"Loading resignFirstResponder-CPControlTextDidEndEditing...</p></div>");
</script>
<noscript>
<div id="container">
<div style="width: 440px; padding: 10px 25px 20px 25px; font-family: sans-serif; background-color: #ffffff; position: relative; left: -245px; top: -120px; text-align: center; -moz-border-radius: 20px; -webkit-border-radius: 20px; color: #555555">
<p style="line-height: 1.4em;">JavaScript is required for this site to work correctly but is either disabled or not supported by your browser.</p>
<p style="font-size:120%; padding:10px;"><a href="http://cappuccino.org/noscript">Show me how to enable JavaScript</a></p>
<p style="font-size:80%;">You may want to upgrade to a newer browser while you're at it:</p>
<ul style="margin:0;padding:0; text-align: center; font-size:80%;" >
<li style="display: inline;"><a href="http://www.apple.com/safari/download/">Safari</a></li>
<li style="display: inline;"><a href="http://www.mozilla.com/en-US/firefox/">Firefox</a></li>
<li style="display: inline;"><a href="http://www.google.com/chrome/">Chrome</a></li>
<li style="display: inline;"><a href="http://www.opera.com/download/">Opera</a></li>
<li style="display: inline;"><a href="http://www.microsoft.com/windows/downloads/ie/getitnow.mspx">Internet Explorer</a></li>
</ul>
</div>
</div>
</noscript>
</div>
</div>
</body>
</html>
@@ -0,0 +1,77 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!--
index.html
resignFirstResponder-CPControlTextDidEndEditing
Created by aparajita on September 2, 2011.
Copyright 2011, Victory-Heart Productions All rights reserved.
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7, chrome=1" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<link rel="apple-touch-icon" href="Resources/icon.png" />
<link rel="apple-touch-startup-image" href="Resources/default.png" />
<title>resignFirstResponder-CPControlTextDidEndEditing</title>
<script type="text/javascript">
OBJJ_MAIN_FILE = "main.j";
</script>
<script type="text/javascript" src="Frameworks/Objective-J/Objective-J.js" charset="UTF-8"></script>
<style type="text/css">
body{margin:0; padding:0;}
#container {position: absolute; top:50%; left:50%;}
#content {width:800px; text-align:center; margin-left: -400px; height:50px; margin-top:-25px; line-height: 50px;}
#content {font-family: "Helvetica", "Arial", sans-serif; font-size: 18px; color: black; text-shadow: 0px 1px 0px white; }
#loadgraphic {margin-right: 0.2em; margin-bottom:-2px;}
</style>
<!--[if lt IE 7]>
<STYLE type="text/css">
#container { position: relative; top: 50%; }
#content { position: relative;}
</STYLE>
<![endif]-->
</head>
<body style="">
<div id="cappuccino-body">
<div id="loadingcontainer" style="background-color: #eeeeee; overflow:hidden; width:100%; height:100%; position: absolute; top: 0; left: 0;">
<script type="text/javascript">
document.write("<div id='container'><p id='content'>" +
"<img id='loadgraphic' width='16' height='16' src='Resources/spinner.gif' /> " +
"Loading resignFirstResponder-CPControlTextDidEndEditing...</p></div>");
</script>
<noscript>
<div id="container">
<div style="width: 440px; padding: 10px 25px 20px 25px; font-family: sans-serif; background-color: #ffffff; position: relative; left: -245px; top: -120px; text-align: center; -moz-border-radius: 20px; -webkit-border-radius: 20px; color: #555555">
<p style="line-height: 1.4em;">JavaScript is required for this site to work correctly but is either disabled or not supported by your browser.</p>
<p style="font-size:120%; padding:10px;"><a href="http://cappuccino.org/noscript">Show me how to enable JavaScript</a></p>
<p style="font-size:80%;">You may want to upgrade to a newer browser while you're at it:</p>
<ul style="margin:0;padding:0; text-align: center; font-size:80%;" >
<li style="display: inline;"><a href="http://www.apple.com/safari/download/">Safari</a></li>
<li style="display: inline;"><a href="http://www.mozilla.com/en-US/firefox/">Firefox</a></li>
<li style="display: inline;"><a href="http://www.google.com/chrome/">Chrome</a></li>
<li style="display: inline;"><a href="http://www.opera.com/download/">Opera</a></li>
<li style="display: inline;"><a href="http://www.microsoft.com/windows/downloads/ie/getitnow.mspx">Internet Explorer</a></li>
</ul>
</div>
</div>
</noscript>
</div>
</div>
</body>
</html>
@@ -0,0 +1,18 @@
/*
* AppController.j
* resignFirstResponder-CPControlTextDidEndEditing
*
* Created by aparajita on September 2, 2011.
* Copyright 2011, Victory-Heart Productions All rights reserved.
*/
@import <Foundation/Foundation.j>
@import <AppKit/AppKit.j>
@import "AppController.j"
function main(args, namedArgs)
{
CPApplicationMain(args, namedArgs);
}
+4 -2
View File
@@ -25,7 +25,7 @@ DOXYFILE_ENCODING = UTF-8
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project.
PROJECT_NAME = "Cappuccino API"
PROJECT_NAME = " API"
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
@@ -33,6 +33,8 @@ PROJECT_NAME = "Cappuccino API"
PROJECT_NUMBER = 0.9.1
PROJECT_LOGO = ./Tools/Documentation/logo.png
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
# If a relative path is entered, it will be relative to the location
@@ -845,7 +847,7 @@ HTML_FOOTER =
# the style sheet file to the HTML output directory, so don't put your own
# stylesheet in the HTML output directory as well, or it will be erased!
HTML_STYLESHEET = ./Tools/Documentation/doxygen.css
#HTML_STYLESHEET = doxygen.css
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
# Doxygen will adjust the colors in the stylesheet and background images
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

+5 -7
View File
@@ -1,10 +1,10 @@
require("../../common.jake");
var OS = require("os");
var task = require("jake").task
var stream = require("narwhal/term").stream;
var applicationName = "xcodecapp-cocoa.app";
var OS = require("os"),
task = require("jake").task,
stream = require("narwhal/term").stream,
applicationName = "xcodecapp-cocoa.app";
task ("build", function()
{
@@ -22,9 +22,7 @@ task ("build", function()
cp_r(FILE.join("build", "Release", "xcodecapp-cocoa.app"), supportPath);
FILE.chmod(FILE.join(supportPath, "Contents", "MacOS", "xcodecapp-cocoa"), 0755);
if (FILE.exists(installPath))
FILE.remove(installPath);
FILE.symlink(supportPath, installPath);
OS.system(["ln", "-sf", supportPath, installPath]);
}
else
{
+1 -1
View File
@@ -133,7 +133,7 @@ global.$BUILD_CJS_CAPPUCCINO_FRAMEWORKS = FILE.join($BUILD_CJS_CAPPUCCINO, "Fram
global.CLEAN = require("jake/clean").CLEAN;
global.CLOBBER = require("jake/clean").CLOBBER;
global.CLEAN.include(global.$BUILD_DIR);
global.CLEAN.include(FILE.join(global.$BUILD_DIR, "*.build"));
global.CLOBBER.include(global.$BUILD_DIR);
global.$HOME_DIR = FILE.absolute(FILE.dirname(module.path));