Commits

Ivan Vučica  committed 9d27464

Added tableview example.

  • Participants
  • Parent commits 5d02230

Comments (0)

Files changed (3)

File HelloGNUstep.preamble.h

 
 #if !GNUSTEP
 #import "OSX_Startup.h"
-#define APPCONTROLLER_PROTOCOLS <NSApplicationDelegate,NSOutlineViewDelegate>
-#define DATASOURCE_PROTOCOLS <NSOutlineViewDataSource>
-#else
-#define APPCONTROLLER_PROTOCOLS
-#define DATASOURCE_PROTOCOLS
 #endif
 

File HelloGNUstepOutlineView.m

 #define APPNAME @"HelloGNUstepOutlineView"
 
+#if !GNUSTEP
+#define APPCONTROLLER_PROTOCOLS <NSApplicationDelegate,NSOutlineViewDelegate>
+#define DATASOURCE_PROTOCOLS <NSOutlineViewDataSource>
+#else
+#define APPCONTROLLER_PROTOCOLS
+#define DATASOURCE_PROTOCOLS
+#endif
+
 #import "HelloGNUstep.preamble.h"
 
 /* This class represents the 'model' for each row in the outline. */

File HelloGNUstepTableView.m

+#define APPNAME @"HelloGNUstepTableView"
+
+#if !GNUSTEP
+#define APPCONTROLLER_PROTOCOLS <NSApplicationDelegate,NSTableViewDelegate>
+#define DATASOURCE_PROTOCOLS <NSTableViewDataSource>
+#else
+#define APPCONTROLLER_PROTOCOLS
+#define DATASOURCE_PROTOCOLS
+#endif
+
+#import "HelloGNUstep.preamble.h"
+
+
+NSString * HelloGNUstepTableViewItemsArrayPboardType = @"HelloGNUstepTableViewItemsArrayPboardType";
+
+/* This class represents the 'model' for each row in the outline. */
+@interface Item : NSObject <NSCoding>
+{
+    NSString * _value;
+}
++ (Item *) itemWithString: (NSString *)string;
+- (id) initWithString: (NSString *)string;
+@end
+@implementation Item
++ (Item *) itemWithString: (NSString *)string
+{
+    return [[[self alloc] initWithString: string] autorelease];
+}
+- (id) initWithString: (NSString *)string
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    
+    _value = [string retain];
+
+    return self;
+}
+- (id) initWithCoder: (NSCoder *)coder
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    
+    _value = [[coder decodeObjectForKey: @"value"] retain];
+
+    return self;
+}
+- (void) encodeWithCoder: (NSCoder *)coder
+{
+    [coder encodeObject: _value forKey: @"value"];
+}
+- (void) dealloc
+{
+    [_value release];
+    [super dealloc];
+}
+- (NSString *) description
+{
+    return _value;
+}
+- (BOOL) isEqualToString: (NSString *)aString
+{
+    return [_value isEqualToString: aString];
+}
+
+- (BOOL) isEqual: (id)object
+{
+    if(![object isKindOfClass:[self class]])
+        return NO;
+    
+    return [self isEqualToString: [object description]];
+}
+- (NSUInteger) hash
+{
+    return [_value hash];
+}
+@end
+
+@interface DataSource : NSObject DATASOURCE_PROTOCOLS
+{
+    NSMutableArray * _items;
+}
+@end
+@implementation DataSource
+- (id) init
+{
+    self = [super init];
+    if (!self)
+        return nil;
+
+    _items = [NSMutableArray new];
+    for(int i = 0; i < 5; i++)
+    {
+        Item * item = [Item itemWithString: [NSString stringWithFormat: @"Top-level item %d", i]];
+	[_items addObject: item];
+    }
+
+    return self;
+}
+-(NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
+{
+    return [_items count];
+}
+- (id)tableView:(NSTableView *)tablewView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex
+{
+    return [[_items objectAtIndex:rowIndex] description];
+}
+
+/* Drag and drop */
+- (BOOL)tableView:(NSTableView *)tableView
+    writeRowsWithIndexes:(NSIndexSet *)indexes
+            toPasteboard:(NSPasteboard*)pboard
+{
+    NSMutableArray * array = [NSMutableArray array];
+    for(NSUInteger currentIndex = [indexes firstIndex];
+        currentIndex != NSNotFound;
+	currentIndex = [indexes indexGreaterThanIndex: currentIndex])
+    {
+        [array addObject: [_items objectAtIndex: currentIndex]];
+    }
+
+    NSData * data = [NSKeyedArchiver archivedDataWithRootObject: array];
+
+    [pboard declareTypes: [NSArray arrayWithObject: HelloGNUstepTableViewItemsArrayPboardType]
+                   owner: self];
+
+    [pboard setData: data
+            forType: HelloGNUstepTableViewItemsArrayPboardType];
+
+    return YES;
+}
+- (NSDragOperation)tableView:(NSTableView*)tv 
+                validateDrop:(id<NSDraggingInfo> )info 
+                 proposedRow:(NSInteger)row 
+       proposedDropOperation:(NSTableViewDropOperation)op 
+{
+    NSPasteboard* pboard = [info draggingPasteboard];
+    if(![pboard.types containsObject: HelloGNUstepTableViewItemsArrayPboardType])
+        return NSDragOperationNone;
+
+    if(op == NSTableViewDropAbove) // This allows choosing between allowing dropping 'between' rows, 'on' rows, or both
+    {
+         if ([info draggingSourceOperationMask] & NSDragOperationCopy ||
+	     [info draggingSource] == tv)
+	 {
+             return NSDragOperationCopy;
+	 }
+         return NSDragOperationMove;
+    }
+    return NSDragOperationNone;
+}
+- (BOOL)tableView:(NSTableView *)tableView
+       acceptDrop:(id<NSDraggingInfo> )info
+              row:(NSInteger)newRow 
+    dropOperation:(NSTableViewDropOperation)operation
+{
+    NSPasteboard* pboard = [info draggingPasteboard];
+    NSData* rowData = [pboard dataForType: HelloGNUstepTableViewItemsArrayPboardType];
+    if (rowData)
+    {
+         NSArray * draggedItems = [NSKeyedUnarchiver unarchiveObjectWithData: rowData];
+	 if ([info draggingSourceOperationMask] & NSDragOperationCopy ||
+	     [info draggingSource] != tableView)
+         {
+             /* COPY OPERATION */
+             for(int i = 0; i < [draggedItems count]; i++)
+             {
+                 Item * draggedItem = [draggedItems objectAtIndex: i];
+                 Item * newItem = [Item itemWithString: [NSString stringWithFormat: @"%@ - copy", [draggedItem description]]];
+                 [_items insertObject:newItem
+                              atIndex:newRow + i];
+             }
+
+	     /* Refresh display */
+	     [tableView reloadData];
+
+             return YES;
+         } 
+	 else
+         {
+             /* MOVE OPERATION */
+             /* The following algorithm presumes every object in the list has unique value. */
+             
+             id objectToInsertAbove = (newRow < [_items count]) ? [_items objectAtIndex: newRow] : nil;
+             while([draggedItems containsObject:objectToInsertAbove] && newRow > 0)
+             {
+                 /* This object will be removed; find another victim */
+                 newRow--;
+        	 objectToInsertAbove = [_items objectAtIndex: newRow];
+             }
+	     if([draggedItems containsObject:objectToInsertAbove])
+                 objectToInsertAbove = nil;
+
+             /* Remove objects being moved */
+             [_items removeObjectsInArray: draggedItems];
+             
+             /* Insert new objects */
+             if(objectToInsertAbove)
+                 newRow = [_items indexOfObject: objectToInsertAbove];
+             else
+                 newRow = [_items count];
+
+	     if(newRow >= [_items count])
+                 newRow = [_items count];
+
+             for(int i = 0; i < [draggedItems count]; i++)
+             {
+	         if(newRow < [_items count])
+                     [_items insertObject:[draggedItems objectAtIndex: i]
+                                  atIndex:newRow + i];
+		 else
+                     [_items addObject:[draggedItems objectAtIndex: i]];
+             }
+             
+	     /* Refresh display */
+	     [tableView reloadData];
+
+             return YES;
+	 }
+    }
+    return NO;
+}
+
+@end
+
+
+@interface AppController : NSObject APPCONTROLLER_PROTOCOLS
+{
+    NSWindow *window;
+    NSTableView *_tableView;
+    id _dataSource;
+}
+-(id)init;
+-(void)applicationDidFinishLaunching:(NSNotification*)notif;
+-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(id)sender;
+@end
+
+@implementation AppController
+-(id)init 
+{ 
+    self = [super init];
+    if(self)
+    {
+        
+    }
+    return self;
+}
+
+-(void)dealloc
+{
+    [_tableView release];
+    [_dataSource release];
+    [window release];
+    [super dealloc];    
+}
+
+-(void)applicationDidFinishLaunching:(NSNotification*)notif 
+{
+    window = [[NSWindow alloc] initWithContentRect:NSMakeRect(50,50,640,480) 
+                                         styleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask
+                                           backing:NSBackingStoreBuffered
+                                             defer:NO];
+    [window setTitle:APPNAME];
+    [window makeKeyAndOrderFront:nil];
+
+    NSButton* button = [[NSButton alloc] initWithFrame:NSMakeRect(15,300,150,24)];
+    [button setTitle:@"Test button"];
+    [button setTarget:self];
+    [button setAction:@selector(buttonWasClicked:)];
+    [button setBezelStyle:NSRoundedBezelStyle];
+    [[window contentView] addSubview:button];
+    [window setDefaultButtonCell:[button cell]];
+    [button release];
+    
+    NSScrollView* scrollView = [[NSScrollView alloc] initWithFrame:NSMakeRect(50,50,300,150)];
+    [[window contentView] addSubview:scrollView];
+    [scrollView release];
+    
+    _dataSource = [DataSource new];
+
+    NSTableView* tableView = [[NSTableView alloc] initWithFrame:NSMakeRect(0,0,150,150)];
+    [tableView setDataSource:_dataSource];
+    [tableView setDelegate:self];
+    [scrollView setDocumentView:tableView];
+    [tableView release];
+    
+    NSTableColumn * column = [[NSTableColumn alloc] initWithIdentifier:@"Column"];
+    [column setWidth: 250];
+    [tableView addTableColumn:column];
+    [column release];
+        
+    /* We support accepting the following types... */
+    [tableView registerForDraggedTypes:[NSArray arrayWithObjects: HelloGNUstepTableViewItemsArrayPboardType, nil]];
+    
+    /* When no modifier is pressed, support only 'move' source operation */
+    [tableView setDraggingSourceOperationMask: NSDragOperationMove forLocal: YES];
+
+    _tableView = tableView;
+}
+
+-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(id)sender 
+{ 
+    return YES; 
+}
+
+-(void)buttonWasClicked:(id)sender
+{
+    [sender setTitle:@"Ouch!"];
+}
+
+@end
+
+#include "HelloGNUstep.postamble.h"
+