Permalink
Browse files

- Consolidated the new row spanning table view and the sticky row tab…

…le view into NoodleTableView. Broke out NSTableView category into its own file.

- Added a delegate method to override whether a cell for a specific row/column is to be included in the sticky row header.
- Added iToonz example to demonstrate new row spanning feature. Also makes use of new delegate method.
- Added NSIndexSet category which provides a simple enumerator.
  • Loading branch information...
1 parent c001496 commit 5010dc5353ba38c545a04c24fb8e799cb36468c8 @MrNoodle committed Oct 25, 2009
@@ -27,6 +27,7 @@
//
#import "Controller.h"
+#import "NoodleTableView.h"
@implementation Controller
@@ -65,6 +66,7 @@ - (void)awakeFromNib
}
}
+ [_stickyRowTableView setShowsStickyRowHeader:YES];
[_stickyRowTableView reloadData];
[_iPhoneTableView reloadData];
}
@@ -3,18 +3,18 @@
<data>
<int key="IBDocument.SystemTarget">1050</int>
<string key="IBDocument.SystemVersion">10B504</string>
- <string key="IBDocument.InterfaceBuilderVersion">732</string>
+ <string key="IBDocument.InterfaceBuilderVersion">740</string>
<string key="IBDocument.AppKitVersion">1038.2</string>
<string key="IBDocument.HIToolboxVersion">437.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string key="NS.object.0">732</string>
+ <string key="NS.object.0">740</string>
</object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
- <integer value="57"/>
<integer value="528"/>
<integer value="450"/>
+ <integer value="57"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -3437,7 +3437,7 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>NoodleStickyRowTableView</string>
+ <string>NoodleTableView</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -3607,13 +3607,32 @@
<string key="minorKey">Examples/Window Effects/Controller.h</string>
</object>
</object>
+ <object class="IBPartialClassDescription">
+ <string key="className">Controller</string>
+ <string key="superclassName">NSObject</string>
+ <object class="NSMutableDictionary" key="outlets">
+ <string key="NS.key.0">_tableView</string>
+ <string key="NS.object.0">NoodleTableView</string>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Examples/iToonz/Controller.h</string>
+ </object>
+ </object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">NSObject-NoodlePerformWhenIdle.h</string>
</object>
</object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="732683367">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">NSTableView-NoodleExtensions.h</string>
+ </object>
+ </object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="204379972">
@@ -3641,6 +3660,18 @@
<string key="minorKey">NSResponder-NoodleModalExtensions.h</string>
</object>
</object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSTableColumn</string>
+ <reference key="sourceIdentifier" ref="732683367"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSTableView</string>
+ <object class="NSMutableDictionary" key="actions">
+ <string key="NS.key.0">scrollToStickyRow:</string>
+ <string key="NS.object.0">id</string>
+ </object>
+ <reference key="sourceIdentifier" ref="732683367"/>
+ </object>
<object class="IBPartialClassDescription">
<string key="className">NSTableView</string>
<object class="NSMutableDictionary" key="actions">
@@ -3682,9 +3713,12 @@
</object>
</object>
<object class="IBPartialClassDescription">
- <string key="className">NoodleStickyRowTableView</string>
+ <string key="className">NoodleTableView</string>
<string key="superclassName">NSTableView</string>
- <reference key="sourceIdentifier" ref="204379972"/>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">NoodleTableView.h</string>
+ </object>
</object>
</object>
<object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
@@ -4239,7 +4273,7 @@
<integer value="3100" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
- <string key="IBDocument.LastKnownRelativeProjectPath">../NoodleStickyRowTableViewTest.xcodeproj</string>
+ <string key="IBDocument.LastKnownRelativeProjectPath">../../../NoodleKit.xcodeproj</string>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
</data>
</archive>
@@ -15,23 +15,26 @@
version 0.18369\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
\cf0 \
-This is a sample project and test harness for NoodleStickyRowTableView.\
+This is a sample project and test harness for the sticky row header feature of NoodleTableView.\
\
-NoodleStickyRowTableView is an NSTableView subclass where group rows (this can be overridden) will "stick" to the top of the view when they scroll off. This is like how section headers will stick to the top in UITableViews on the iPhone.\
+NoodleTableView is an NSTableView subclass where group rows (this can be overridden) will "stick" to the top of the view when they scroll off. This is like how section headers will stick to the top in UITableViews on the iPhone.\
\
Almost all of it is accomplished via an NSTableView category. The reason it was done this way was so that (a) you could integrate it into your own NSTableView subclass easily and (b) you could gain the functionality in NSOutlineView and its subclasses as well. To get the basic functionality, all you need to do is subclass
\f1 -drawRect:
\f0 and call
\f1 -drawStickyRowHeader
\f0 after your call to
\f1 super
-\f0 . Look at the very minimal NoodleStickyRowTableView class for details.\
+\f0 . Look at the NoodleTableView class for details.\
\
This project also includes NoodleIPhoneTableView which overrides a bit more to simulate the look and feel of UITableView.\
\
A blog post on this can be found at: {\field{\*\fldinst{HYPERLINK "http://www.noodlesoft.com/blog/2009/09/25/sticky-section-headers-in-nstableview"}}{\fldrslt http://www.noodlesoft.com/blog/2009/09/25/sticky-section-headers-in-nstableview}}\
\
-Notes:\
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
+
+\b \cf0 Notes
+\b0 \
\
\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\ql\qnatural\pardirnatural
\ls1\ilvl0\cf0 {\listtext \'95 }As noted in the article linked above, limitations in being able to get a visual cache of a group row forced me to compromise and use a custom look for the sticky rows in the default implementation. As shown in the NoodleIPhoneTableView class, you can override all the drawing but it requires a bit more work.\
@@ -0,0 +1,42 @@
+//
+// Controller.h
+// NoodleKit
+//
+// Created by Paul Kim on 10/21/09.
+// Copyright 2009 Noodlesoft, LLC. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+
+#import <Cocoa/Cocoa.h>
+
+@class NoodleTableView;
+
+@interface Controller : NSObject
+{
+ IBOutlet NoodleTableView *_tableView;
+ NSArray *_entries;
+ id _number;
+}
+
+@property (readonly) NSArray *entries;
+
+@end
@@ -0,0 +1,162 @@
+//
+// Controller.m
+// NoodleKit
+//
+// Created by Paul Kim on 10/21/09.
+// Copyright 2009 Noodlesoft, LLC. All rights reserved.
+//
+// Created by Paul Kim on 10/20/09.
+// Copyright 2009 Noodlesoft, LLC. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+
+#import "Controller.h"
+#import "NoodleTableView.h"
+
+#define ARTIST_KEY @"artist"
+#define ARTWORK_KEY @"artwork"
+#define ALBUM_KEY @"album"
+#define SONGCOUNT_KEY @"songCount"
+
+@implementation Controller
+
+
+//@synthesize window;
+@synthesize entries = _entries;
+
+- (void)awakeFromNib
+{
+ [_tableView setIntercellSpacing:NSMakeSize(0.0, 0.0)];
+ [_tableView setShowsStickyRowHeader:YES];
+ [_tableView setRowSpanningEnabledForCapableColumns:YES];
+ _number = [NSNumber numberWithInt:5];
+}
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
+{
+ _entries = [[NSArray alloc] initWithObjects:
+ [NSDictionary dictionaryWithObjectsAndKeys:
+ @"Mr Disco", ARTIST_KEY,
+ [NSImage imageNamed:NSImageNameFolderBurnable], ARTWORK_KEY,
+ @"Burn Baby Burn", ALBUM_KEY,
+ [NSNumber numberWithInteger:9], SONGCOUNT_KEY, nil],
+ [NSDictionary dictionaryWithObjectsAndKeys:
+ @"Pierre LeMac", ARTIST_KEY,
+ [NSImage imageNamed:NSImageNameBonjour], ARTWORK_KEY,
+ @"Bonjour Ma Cherie", ALBUM_KEY,
+ [NSNumber numberWithInteger:13], SONGCOUNT_KEY, nil],
+ [NSDictionary dictionaryWithObjectsAndKeys:
+ @"M.C. Mac", ARTIST_KEY,
+ [NSImage imageNamed:NSImageNameDotMac], ARTWORK_KEY,
+ @"Dot Mackin'", ALBUM_KEY,
+ [NSNumber numberWithInteger:7], SONGCOUNT_KEY, nil],
+ [NSDictionary dictionaryWithObjectsAndKeys:
+ @"M.C. Mac", ARTIST_KEY,
+ [NSImage imageNamed:NSImageNameFolderSmart], ARTWORK_KEY,
+ @"You Think You're So Smart", ALBUM_KEY,
+ [NSNumber numberWithInteger:14], SONGCOUNT_KEY, nil],
+ [NSDictionary dictionaryWithObjectsAndKeys:
+ @"ComputerHead", ARTIST_KEY,
+ [NSImage imageNamed:NSImageNameComputer], ARTWORK_KEY,
+ @"Cancel Computer", ALBUM_KEY,
+ [NSNumber numberWithInteger:12], SONGCOUNT_KEY, nil],
+ nil];
+
+ [(NoodleTableColumn *)[_tableView tableColumnWithIdentifier:@"Album"] setRowSpanningEnabled:NO];
+ [_tableView reloadData];
+}
+
+- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView
+{
+ return [[_entries valueForKeyPath:@"@sum.songCount"] integerValue];
+}
+
+- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
+{
+ NSInteger tally, songCount;
+ id identifier;
+
+ tally = 0;
+ identifier = [aTableColumn identifier];
+ for (NSDictionary *dict in _entries)
+ {
+ songCount = [[dict objectForKey:SONGCOUNT_KEY] integerValue];
+
+ if (rowIndex < tally + songCount)
+ {
+ if ([identifier isEqual:@"Artwork"])
+ {
+ return [dict objectForKey:ARTWORK_KEY];
+ }
+ else if ([identifier isEqual:@"Album"])
+ {
+ return [dict objectForKey:ALBUM_KEY];
+ }
+ else if ([identifier isEqual:@"Artist"])
+ {
+ return [dict objectForKey:ARTIST_KEY];
+ }
+ else if ([identifier isEqual:@"Song"])
+ {
+ return [NSString stringWithFormat:@"Song #%d", rowIndex - tally + 1];
+ }
+ }
+ tally += songCount;
+ }
+ return nil;
+}
+
+- (void)tableView:(NSTableView *)tableView didClickTableColumn:(NSTableColumn *)tableColumn
+{
+ if ([[tableColumn identifier] isEqual:@"Album"])
+ {
+ [(NoodleTableColumn *)tableColumn setRowSpanningEnabled:![(NoodleTableColumn *)tableColumn isRowSpanningEnabled]];
+ [_tableView reloadData];
+ }
+}
+
+- (BOOL)tableView:(NSTableView *)tableView isStickyRow:(NSInteger)row
+{
+ id value, newValue;
+ NSTableColumn *column;
+
+ column = [tableView tableColumnWithIdentifier:@"Artist"];
+ value = [self tableView:tableView objectValueForTableColumn:column row:row];
+
+ if (row > 0)
+ {
+ newValue = [self tableView:tableView objectValueForTableColumn:column row:row - 1];
+ if (![value isEqual:newValue])
+ {
+ return YES;
+ }
+ return NO;
+ }
+ return YES;
+}
+
+- (BOOL)tableView:(NSTableView *)tableView shouldDisplayCellInStickyRowHeaderForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex
+{
+ return [[tableColumn identifier] isEqual:@"Artist"];
+}
+
+@end
Oops, something went wrong.

0 comments on commit 5010dc5

Please sign in to comment.