mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-06-02 11:00:59 +00:00
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:
parent
5947f65588
commit
16d024bf31
3 changed files with 64 additions and 82 deletions
|
@ -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>
|
2002-03-26 Pierre-Yves Rivaille <pyrivail@ens-lyon.fr>
|
||||||
|
|
||||||
* Source/NSBundleAdditions.m
|
* Source/NSBundleAdditions.m
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
NSMutableDictionary *_itemDict;
|
NSMutableDictionary *_itemDict;
|
||||||
NSMutableArray *_items;
|
NSMutableArray *_items;
|
||||||
NSMutableArray *_expandedItems;
|
NSMutableArray *_expandedItems;
|
||||||
|
NSMutableDictionary *_levelOfItems;
|
||||||
BOOL _autoResizesOutlineColumn;
|
BOOL _autoResizesOutlineColumn;
|
||||||
BOOL _indentationMarkerFollowsCell;
|
BOOL _indentationMarkerFollowsCell;
|
||||||
BOOL _autosaveExpandedItems;
|
BOOL _autosaveExpandedItems;
|
||||||
|
|
|
@ -89,82 +89,8 @@ static NSImage *unexpandable = nil;
|
||||||
- (void) _autoloadTableColumns;
|
- (void) _autoloadTableColumns;
|
||||||
- (void) _openItem: (id)item;
|
- (void) _openItem: (id)item;
|
||||||
- (void) _closeItem: (id)item;
|
- (void) _closeItem: (id)item;
|
||||||
- (NSDictionary *) _itemDictionary;
|
|
||||||
@end
|
@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
|
@implementation NSOutlineView
|
||||||
|
|
||||||
// Initialize the class when it is loaded
|
// Initialize the class when it is loaded
|
||||||
|
@ -194,11 +120,13 @@ static int _levelForItem(NSDictionary *outlineDict,
|
||||||
_itemDict = [NSMutableDictionary dictionary];
|
_itemDict = [NSMutableDictionary dictionary];
|
||||||
_items = [NSMutableArray array];
|
_items = [NSMutableArray array];
|
||||||
_expandedItems = [NSMutableArray array];
|
_expandedItems = [NSMutableArray array];
|
||||||
|
_levelOfItems = [NSMutableDictionary dictionary];
|
||||||
|
|
||||||
// Retain items
|
// Retain items
|
||||||
RETAIN(_items);
|
RETAIN(_items);
|
||||||
RETAIN(_expandedItems);
|
RETAIN(_expandedItems);
|
||||||
RETAIN(_itemDict);
|
RETAIN(_itemDict);
|
||||||
|
RETAIN(_levelOfItems);
|
||||||
|
|
||||||
return self;
|
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
|
- (void)_closeItem: (id)item
|
||||||
{
|
{
|
||||||
int numchildren = 0;
|
int numchildren = 0;
|
||||||
|
@ -257,7 +221,6 @@ static int _levelForItem(NSDictionary *outlineDict,
|
||||||
|
|
||||||
// For the close method it doesn't matter what order they are
|
// For the close method it doesn't matter what order they are
|
||||||
// removed in.
|
// removed in.
|
||||||
|
|
||||||
for(i=0; i < numchildren; i++)
|
for(i=0; i < numchildren; i++)
|
||||||
{
|
{
|
||||||
id child = [removeAll objectAtIndex: i];
|
id child = [removeAll objectAtIndex: i];
|
||||||
|
@ -503,8 +466,7 @@ static int _levelForItem(NSDictionary *outlineDict,
|
||||||
{
|
{
|
||||||
if(item != nil)
|
if(item != nil)
|
||||||
{
|
{
|
||||||
BOOL found = NO;
|
return [[_levelOfItems objectForKey: item] intValue];
|
||||||
return _levelForItem(_itemDict, nil, item, -1, &found);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -583,7 +545,8 @@ static int _levelForItem(NSDictionary *outlineDict,
|
||||||
if(reloadChildren && haschildren) // expand all
|
if(reloadChildren && haschildren) // expand all
|
||||||
{
|
{
|
||||||
NSMutableDictionary *allChildren = [NSMutableDictionary dictionary];
|
NSMutableDictionary *allChildren = [NSMutableDictionary dictionary];
|
||||||
_loadDictionary(self, item, allChildren);
|
[self _loadDictionaryStartingWith: item
|
||||||
|
atLevel: [self levelForItem: item]];
|
||||||
[_itemDict addEntriesFromDictionary: allChildren];
|
[_itemDict addEntriesFromDictionary: allChildren];
|
||||||
|
|
||||||
// release the old array
|
// release the old array
|
||||||
|
@ -635,7 +598,7 @@ static int _levelForItem(NSDictionary *outlineDict,
|
||||||
- (void) noteNumberOfRowsChanged
|
- (void) noteNumberOfRowsChanged
|
||||||
{
|
{
|
||||||
_numberOfRows = [_items count];
|
_numberOfRows = [_items count];
|
||||||
|
|
||||||
/* If we are selecting rows, we have to check that we have no
|
/* If we are selecting rows, we have to check that we have no
|
||||||
selected rows below the new end of the table */
|
selected rows below the new end of the table */
|
||||||
if (!_selectingColumns)
|
if (!_selectingColumns)
|
||||||
|
@ -764,13 +727,19 @@ static int _levelForItem(NSDictionary *outlineDict,
|
||||||
RELEASE(_itemDict);
|
RELEASE(_itemDict);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(_levelOfItems != nil)
|
||||||
|
{
|
||||||
|
RELEASE(_levelOfItems);
|
||||||
|
}
|
||||||
|
|
||||||
// create a new empty one
|
// create a new empty one
|
||||||
_items = RETAIN([NSMutableArray array]);
|
_items = RETAIN([NSMutableArray array]);
|
||||||
_itemDict = RETAIN([NSMutableDictionary dictionary]);
|
_itemDict = RETAIN([NSMutableDictionary dictionary]);
|
||||||
|
_levelOfItems = RETAIN([NSMutableDictionary dictionary]);
|
||||||
|
|
||||||
// reload all the open items...
|
// reload all the open items...
|
||||||
_loadDictionary(self, nil, _itemDict);
|
[self _loadDictionaryStartingWith: nil
|
||||||
// NSLog(@"Dictionary = %@",_itemDict);
|
atLevel: -1];
|
||||||
[self _openItem: nil];
|
[self _openItem: nil];
|
||||||
[super reloadData];
|
[super reloadData];
|
||||||
}
|
}
|
||||||
|
@ -897,6 +866,11 @@ static int _levelForItem(NSDictionary *outlineDict,
|
||||||
/* Using columnAtPoint: here would make it called twice per row per drawn
|
/* Using columnAtPoint: here would make it called twice per row per drawn
|
||||||
rect - so we avoid it and do it natively */
|
rect - so we avoid it and do it natively */
|
||||||
|
|
||||||
|
if(rowIndex >= _numberOfRows)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Determine starting column as fast as possible */
|
/* Determine starting column as fast as possible */
|
||||||
x_pos = NSMinX (aRect);
|
x_pos = NSMinX (aRect);
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue