Makde some enhancements to make NSOutlineView much faster for large sets of items.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@13253 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Gregory John Casamento 2002-03-28 00:23:37 +00:00
parent e7db1483f6
commit def94af7cf
3 changed files with 64 additions and 82 deletions

View file

@ -1,3 +1,10 @@
2002-03-27 Gregory John Casamento <greg_casamento@yahoo.com>
* Source/NSOutlineView.m make more efficient for large sets of
items
* Headers/gnustep/gui/NSOutlineView.h Added new ivar to cache
item level information.
2002-03-26 Pierre-Yves Rivaille <pyrivail@ens-lyon.fr>
* Source/NSBundleAdditions.m

View file

@ -39,6 +39,7 @@
NSMutableDictionary *_itemDict;
NSMutableArray *_items;
NSMutableArray *_expandedItems;
NSMutableDictionary *_levelOfItems;
BOOL _autoResizesOutlineColumn;
BOOL _indentationMarkerFollowsCell;
BOOL _autosaveExpandedItems;

View file

@ -89,82 +89,8 @@ static NSImage *unexpandable = nil;
- (void) _autoloadTableColumns;
- (void) _openItem: (id)item;
- (void) _closeItem: (id)item;
- (NSDictionary *) _itemDictionary;
@end
// static functions
static void _loadDictionary(NSOutlineView *outline,
id startitem,
NSMutableDictionary *allItems)
{
int num = [[outline dataSource] outlineView: outline
numberOfChildrenOfItem: startitem];
int i = 0;
id sitem = startitem;
if((num > 0) && !([allItems objectForKey: startitem]))
{
if(sitem == nil)
{
sitem = [NSNull null];
}
[allItems setObject: [NSMutableArray array]
forKey: sitem];
}
for(i = 0; i < num; i++)
{
id anitem = [[outline dataSource] outlineView: outline
child: i
ofItem: startitem];
id anarray = [allItems objectForKey: sitem];
[anarray addObject: anitem];
_loadDictionary(outline, anitem, allItems);
}
}
static int _levelForItem(NSDictionary *outlineDict,
id startitem,
id searchitem,
int level,
BOOL *found)
{
id sitem = startitem;
int num = 0;
int i = 0;
int finallevel = 0;
if(sitem == nil)
sitem = [NSNull null];
// get the count for the array...
num = [[outlineDict objectForKey: sitem] count];
if(*found == YES)
{
return level;
}
if(searchitem == startitem)
{
*found = YES;
return level;
}
for(i = 0; i < num; i++)
{
id anitem = [[outlineDict objectForKey: sitem] objectAtIndex: i];
finallevel = _levelForItem(outlineDict, anitem, searchitem, level + 1, found);
if(*found) break;
}
return finallevel;
}
@implementation NSOutlineView
// Initialize the class when it is loaded
@ -194,11 +120,13 @@ static int _levelForItem(NSDictionary *outlineDict,
_itemDict = [NSMutableDictionary dictionary];
_items = [NSMutableArray array];
_expandedItems = [NSMutableArray array];
_levelOfItems = [NSMutableDictionary dictionary];
// Retain items
RETAIN(_items);
RETAIN(_expandedItems);
RETAIN(_itemDict);
RETAIN(_levelOfItems);
return self;
}
@ -240,6 +168,42 @@ static int _levelForItem(NSDictionary *outlineDict,
}
}
- (void) _loadDictionaryStartingWith: (id) startitem
atLevel: (int) level
{
int num = [_dataSource outlineView: self
numberOfChildrenOfItem: startitem];
int i = 0;
id sitem = startitem;
if(num > 0)
{
if(sitem == nil)
{
sitem = [NSNull null];
}
[_itemDict setObject: [NSMutableArray array]
forKey: sitem];
}
[_levelOfItems setObject: [NSNumber numberWithInt: level]
forKey: sitem];
for(i = 0; i < num; i++)
{
id anitem = [_dataSource outlineView: self
child: i
ofItem: startitem];
id anarray = [_itemDict objectForKey: sitem];
[anarray addObject: anitem];
[self _loadDictionaryStartingWith: anitem
atLevel: level + 1];
}
}
- (void)_closeItem: (id)item
{
int numchildren = 0;
@ -257,7 +221,6 @@ static int _levelForItem(NSDictionary *outlineDict,
// For the close method it doesn't matter what order they are
// removed in.
for(i=0; i < numchildren; i++)
{
id child = [removeAll objectAtIndex: i];
@ -503,8 +466,7 @@ static int _levelForItem(NSDictionary *outlineDict,
{
if(item != nil)
{
BOOL found = NO;
return _levelForItem(_itemDict, nil, item, -1, &found);
return [[_levelOfItems objectForKey: item] intValue];
}
return -1;
@ -583,7 +545,8 @@ static int _levelForItem(NSDictionary *outlineDict,
if(reloadChildren && haschildren) // expand all
{
NSMutableDictionary *allChildren = [NSMutableDictionary dictionary];
_loadDictionary(self, item, allChildren);
[self _loadDictionaryStartingWith: item
atLevel: [self levelForItem: item]];
[_itemDict addEntriesFromDictionary: allChildren];
// release the old array
@ -635,7 +598,7 @@ static int _levelForItem(NSDictionary *outlineDict,
- (void) noteNumberOfRowsChanged
{
_numberOfRows = [_items count];
/* If we are selecting rows, we have to check that we have no
selected rows below the new end of the table */
if (!_selectingColumns)
@ -764,13 +727,19 @@ static int _levelForItem(NSDictionary *outlineDict,
RELEASE(_itemDict);
}
if(_levelOfItems != nil)
{
RELEASE(_levelOfItems);
}
// create a new empty one
_items = RETAIN([NSMutableArray array]);
_itemDict = RETAIN([NSMutableDictionary dictionary]);
_itemDict = RETAIN([NSMutableDictionary dictionary]);
_levelOfItems = RETAIN([NSMutableDictionary dictionary]);
// reload all the open items...
_loadDictionary(self, nil, _itemDict);
// NSLog(@"Dictionary = %@",_itemDict);
[self _loadDictionaryStartingWith: nil
atLevel: -1];
[self _openItem: nil];
[super reloadData];
}
@ -897,6 +866,11 @@ static int _levelForItem(NSDictionary *outlineDict,
/* Using columnAtPoint: here would make it called twice per row per drawn
rect - so we avoid it and do it natively */
if(rowIndex >= _numberOfRows)
{
return;
}
/* Determine starting column as fast as possible */
x_pos = NSMinX (aRect);
i = 0;