Skip to content
This repository has been archived by the owner on Jan 18, 2023. It is now read-only.

Fixes a bug affecting resizing of cells with varying and dynamic cell heights. #10

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Classes/PXListView+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,6 @@ typedef NSInteger PXIsDragStartResult;
- (void)enqueueCell:(PXListViewCell*)cell;

- (void)contentViewBoundsDidChange:(NSNotification*)notification;
-(void)layoutCellsForResizeEvent;

@end
43 changes: 7 additions & 36 deletions Classes/PXListView+UserInteraction.m
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,8 @@ - (void)handleMouseDown:(NSEvent*)theEvent inCell:(PXListViewCell*)theCell // Ce
- (void)handleMouseDownOutsideCells: (NSEvent*)theEvent
{
#pragma unused(theEvent)
[[self window] makeFirstResponder: self];

//[[self window] makeFirstResponder: self];
//
if( _allowsEmptySelection )
[self deselectRows];
else if( _numberOfRows > 1 )
Expand Down Expand Up @@ -329,7 +329,6 @@ -(void) setShowsDropHighlight: (BOOL)inState

-(NSUInteger) indexOfRowAtPoint: (NSPoint)pos returningProposedDropHighlight: (PXListViewDropHighlight*)outDropHighlight
{
PXLog( @"====================" );
*outDropHighlight = PXListViewDropOn;

if( _numberOfRows > 0 )
Expand All @@ -339,14 +338,12 @@ -(NSUInteger) indexOfRowAtPoint: (NSPoint)pos returningProposedDropHighlight: (P
{
if( _cellYOffsets[x] > pos.y )
{
PXLog( @"cellYOffset[%ld] = %f > %f", x, _cellYOffsets[x], pos.y );
break;
}

idx = x;
}

PXLog( @"idx = %ld", idx );

CGFloat cellHeight = 0,
cellOffset = 0,
Expand All @@ -356,42 +353,31 @@ -(NSUInteger) indexOfRowAtPoint: (NSPoint)pos returningProposedDropHighlight: (P
cellOffset = _cellYOffsets[idx];
nextCellOffset = _cellYOffsets[idx+1];
cellHeight = nextCellOffset -cellOffset;
if( cellHeight < 0 )
PXLog( @"Urk. (1)" );
}
else if( idx < _numberOfRows && _numberOfRows > 0 ) // drag is somewhere close to or beyond end of list.
{
PXListViewCell* theCell = [self visibleCellForRow: idx];
cellHeight = [theCell frame].size.height;
cellOffset = [theCell frame].origin.y;
nextCellOffset = cellOffset +cellHeight;
if( cellHeight < 0 )
PXLog( @"Urk. (2)" );
}
else if( idx >= _numberOfRows && _numberOfRows > 0 ) // drag is somewhere close to or beyond end of list.
{
cellHeight = 0;
cellOffset = [[self documentView] frame].size.height;
nextCellOffset = cellOffset;
idx = NSUIntegerMax;
if( cellHeight < 0 )
PXLog( @"Urk. (3)" );
}

PXLog( @"cellHeight = %f", cellHeight );
if( pos.y < (cellOffset +(cellHeight / 6.0)) )
{
*outDropHighlight = PXListViewDropAbove;
PXLog( @"*** ABOVE %ld", idx );
}
else if( pos.y > (nextCellOffset -(cellHeight / 6.0)) )
{
idx++;
*outDropHighlight = PXListViewDropAbove;
PXLog( @"*** ABOVE %ld (below %d)", idx, idx -1 );
}
else
PXLog( @"*** ON %ld", idx );

if( idx > _numberOfRows )
idx = NSUIntegerMax;
Expand All @@ -400,7 +386,6 @@ -(NSUInteger) indexOfRowAtPoint: (NSPoint)pos returningProposedDropHighlight: (P
}
else
{
PXLog( @"*** ON %d", NSUIntegerMax );
return NSUIntegerMax;
}
}
Expand All @@ -426,8 +411,6 @@ -(PXListViewCell*) cellForDropHighlight: (PXListViewDropHighlight*)dhl row: (NSU

- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
{
PXLog( @"draggingEntered" );

NSDragOperation theOperation = NSDragOperationNone;

NSUInteger oldDropRow = _dropRow;
Expand All @@ -436,14 +419,11 @@ - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
if( [_delegate respondsToSelector: @selector(listView:validateDrop:proposedRow:proposedDropHighlight:)] )
{
NSPoint dragMouse = [[self documentView] convertPoint: [sender draggingLocation] fromView: nil];
PXLog( @"dragMouse = %@", NSStringFromPoint(dragMouse) );
_dropRow = [self indexOfRowAtPoint: dragMouse returningProposedDropHighlight: &_dropHighlight];

theOperation = [_delegate listView: self validateDrop: sender proposedRow: _dropRow
proposedDropHighlight: _dropHighlight];
}

PXLog( @"op = %lu, row = %ld, hl = %lu", theOperation, _dropRow, _dropHighlight );

if( theOperation != NSDragOperationNone )
{
Expand All @@ -456,23 +436,16 @@ - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
[oldCell setDropHighlight: PXListViewDropNowhere];
[newCell setDropHighlight: _dropHighlight];
PXListViewDropHighlight dropHL = ((_dropRow == _numberOfRows) ? PXListViewDropAbove : PXListViewDropOn);
PXLog( @"TOTAL DROP %s", dropHL == PXListViewDropOn ? "on" : "above" );
[[self documentView] setDropHighlight: dropHL];
}
else
PXLog(@"TOTAL DROP unchanged");
}
else
PXLog( @"TOTAL DROP NOWHERE" );

return theOperation;
}


- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender /* if the destination responded to draggingEntered: but not to draggingUpdated: the return value from draggingEntered: is used */
{
PXLog( @"draggingUpdated" );

NSDragOperation theOperation = NSDragOperationNone;

NSUInteger oldDropRow = _dropRow;
Expand All @@ -481,15 +454,12 @@ - (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender /* if the destina
if( [_delegate respondsToSelector: @selector(listView:validateDrop:proposedRow:proposedDropHighlight:)] )
{
NSPoint dragMouse = [[self documentView] convertPoint: [sender draggingLocation] fromView: nil];
PXLog( @"dragMouse = %@", NSStringFromPoint(dragMouse) );
_dropRow = [self indexOfRowAtPoint: dragMouse returningProposedDropHighlight: &_dropHighlight];

theOperation = [_delegate listView: self validateDrop: sender proposedRow: _dropRow
proposedDropHighlight: _dropHighlight];
}

NSLog( @"op = %lu, row = %ld, hl = %lu", theOperation, _dropRow, _dropHighlight );

if( theOperation != NSDragOperationNone )
{
if( oldDropRow != _dropRow
Expand All @@ -501,15 +471,11 @@ - (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender /* if the destina
[oldCell setDropHighlight: PXListViewDropNowhere];
[newCell setDropHighlight: _dropHighlight];
PXListViewDropHighlight dropHL = ((_dropRow == _numberOfRows) ? PXListViewDropAbove : PXListViewDropOn);
NSLog( @"TOTAL DROP %s", dropHL == PXListViewDropOn ? "on" : "above" );
[[self documentView] setDropHighlight: dropHL];
}
else
PXLog(@"TOTAL DROP unchanged");
}
else
{
PXLog( @"TOTAL DROP NOWHERE" );
[self setShowsDropHighlight: NO];
}

Expand Down Expand Up @@ -556,6 +522,11 @@ - (void)draggingEnded:(id <NSDraggingInfo>)sender
[oldCell setDropHighlight: PXListViewDropNowhere];

[self setShowsDropHighlight: NO];

for(PXListViewCell *cell in [self visibleCells])
{
[cell setDropHighlight:PXListViewDropNowhere];
}
}


Expand Down
3 changes: 3 additions & 0 deletions Classes/PXListView.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,13 @@
@property (nonatomic, assign) BOOL usesLiveResize;

- (void)reloadData;
-(void)reloadRowAtIndex:(NSInteger)inIndex;

- (PXListViewCell*)dequeueCellWithReusableIdentifier:(NSString*)identifier;

- (NSArray*)visibleCells;
-(PXListViewCell *)cellForRowAtIndex:(NSUInteger)inIndex;

- (NSRange)visibleRange;
- (NSRect)rectOfRow:(NSUInteger)row;
- (void)deselectRows;
Expand Down
72 changes: 58 additions & 14 deletions Classes/PXListView.m
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,7 @@ - (void)dealloc

- (void)setDelegate:(id<PXListViewDelegate>)delegate
{
[_delegate removeObserver:_delegate
name:PXListViewSelectionDidChange
object:self];
[[NSNotificationCenter defaultCenter] removeObserver:_delegate name:PXListViewSelectionDidChange object:self];

_delegate = delegate;

Expand All @@ -105,6 +103,13 @@ - (void)setDelegate:(id<PXListViewDelegate>)delegate
}
}

-(void)reloadRowAtIndex:(NSInteger)inIndex;
{
[self cacheCellLayout];
[self layoutCells];
//[self layoutCellsForResizeEvent];
}

- (void)reloadData
{
id <PXListViewDelegate> delegate = [self delegate];
Expand Down Expand Up @@ -312,6 +317,11 @@ - (PXListViewCell*)visibleCellForRow:(NSUInteger)row
return outCell;
}

-(PXListViewCell *)cellForRowAtIndex:(NSUInteger)inIndex
{
return [self visibleCellForRow:inIndex];
}

- (NSArray*)visibleCellsForRowIndexes:(NSIndexSet*)rows
{
NSMutableArray *theCells = [NSMutableArray array];
Expand Down Expand Up @@ -495,6 +505,7 @@ - (void)layoutCells
{
NSInteger row = [cell row];
[cell setFrame:[self rectOfRow:row]];
[cell layoutSubviews];
}

NSRect bounds = [self bounds];
Expand Down Expand Up @@ -596,23 +607,56 @@ - (void)scrollRowToVisible:(NSUInteger)row
- (void)viewWillStartLiveResize
{
_widthPriorToResize = NSWidth([self contentViewRect]);
if([self usesLiveResize])
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowSizing:) name:NSSplitViewDidResizeSubviewsNotification object:self.superview];
}

- (void)viewDidEndLiveResize
-(void)layoutCellsForResizeEvent
{
[super viewDidEndLiveResize];

//If we use live resize the view will already be up to date
if(![self usesLiveResize]) {
//Change the layout of the cells
[_visibleCells removeAllObjects];
[[self documentView] setSubviews:[NSArray array]];
//Change the layout of the cells
[_visibleCells removeAllObjects];
[[self documentView] setSubviews:[NSArray array]];

[self cacheCellLayout];
[self addCellsFromVisibleRange];

if ([_delegate conformsToProtocol:@protocol(PXListViewDelegate)])
{
CGFloat totalHeight = 0;

for (NSUInteger i = 0; i < _numberOfRows; i++)
{
CGFloat cellHeight = [_delegate listView:self heightOfRow:i];
totalHeight += cellHeight +[self cellSpacing];
}

[self cacheCellLayout];
[self addCellsFromVisibleRange];
_totalHeight = totalHeight;

_currentRange = [self visibleRange];
NSRect bounds = [self bounds];
CGFloat documentHeight = _totalHeight > NSHeight(bounds) ? _totalHeight:(NSHeight(bounds) - 2);

[[self documentView] setFrame:NSMakeRect(0.0f, 0.0f, NSWidth([self contentViewRect]), documentHeight)];
}

_currentRange = [self visibleRange];
}

-(void)viewDidEndLiveResize
{
[super viewDidEndLiveResize];

//If we use live resize the view will already be up to date
if (![self usesLiveResize])
{
[self layoutCellsForResizeEvent];
}
if ([self usesLiveResize])
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSSplitViewDidResizeSubviewsNotification object:self.superview];
}

-(void)windowSizing:(NSNotification *)inNot
{
[self layoutCellsForResizeEvent];
}

#pragma mark -
Expand Down
2 changes: 2 additions & 0 deletions Classes/PXListViewCell.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,6 @@
- (id)initWithReusableIdentifier:(NSString*)identifier;
- (void)prepareForReuse;

-(void)layoutSubviews;

@end
8 changes: 8 additions & 0 deletions Classes/PXListViewCell.m
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,14 @@ - (void)prepareForReuse
_dropHighlight = PXListViewDropNowhere;
}


#pragma mark layout

-(void)layoutSubviews;
{

}

#pragma mark -
#pragma mark Accessibility

Expand Down