0

I have a split view window with an outline view on the left and a table view on the right. I want to be able to drag items from the table view and drop them onto items in the outline view. The dragging and dropping work fine, but the user feedback isn't quite visually what I want. Ideally, the behavior will be like the Finder, where folders become visually selected with white text as the dragged item passed over. In my implementation, however, the highlighting works as expected, but the text color remains black.

I'm change the highlighting in my draggingUpdated call, and attempt to change the text color in dataCellForTableColumn. I actually can change the color of the text to white in that method... but not when a drag operation is in place, though the method is fired while dragging.

The code:

- (NSDragOperation) draggingUpdated:(id<NSDraggingInfo>)sender {
    NSPoint     windowLocation = [[self window] convertScreenToBase: [NSEvent mouseLocation]];
    NSPoint     viewLocation   = [self convertPoint: windowLocation fromView: nil];
    NSInteger   mouseRow       = [self rowAtPoint:viewLocation];

    // Get row at specified index
    if (highlightedRow != mouseRow) {
        NSTableCellView     *row;
       // If the highlighted row changed, revert it to a normal background color
        if (highlightedRow > -1) {
            row = [self viewAtColumn:0 row:highlightedRow makeIfNecessary:NO];
            row.wantsLayer = YES;
            row.layer.backgroundColor = [[NSColor controlBackgroundColor] CGColor];
        }
        // Make sure the mouse if pointing to an existing row
        if (mouseRow < self.numberOfRows) {
            if ([[self itemAtRow:mouseRow] isKindOfClass:[ProjectTeamObject class]]) {
                row = [self viewAtColumn:0 row:mouseRow makeIfNecessary:NO];
                row.wantsLayer = YES;
                row.layer.backgroundColor = [[NSColor selectedContentBackgroundColor] CGColor];
                highlightedRow = mouseRow;
            }
        }
        else
            highlightedRow = -1;
    }
    return (NSDragOperationCopy);
}

- (NSCell *)outlineView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn item:(id)item {
    NSCell          *dataCell = [tableColumn dataCell];
    NSTextFieldCell *cell     = [tableColumn dataCell];
    NSInteger       row       = [self rowForItem:item];
    
    cell = [tableColumn dataCell];
    if (dragging) {
        if ([item isKindOfClass:[ProjectTeamObject class]] && row <= self.numberOfRows)
            [cell setTextColor: [NSColor whiteColor]];
        else
            [cell setTextColor: [NSColor blackColor]];
    }
    return (dataCell);

highlightedRow and dragging are both globals and fairly straightforward.

Is there a problem with changing the text color of an outline view item while dragging, or is there perhaps a better way to do this I may be missing?

Thanks!

8
  • Is the outline view view based or cell based?
    – Willeke
    Commented May 1, 2023 at 20:52
  • It is cell based.
    – johnpurlia
    Commented May 2, 2023 at 0:00
  • Does [self viewAtColumn:0 row:highlightedRow makeIfNecessary:NO] return a view? Is converting to a view based table view an option?
    – Willeke
    Commented May 2, 2023 at 1:58
  • It does, yes; it returns an NSWrapperCellView which in turn includes an NSView. Setting the background color in draggingUpdated works as expected, but the setTextColor methods in dataCellForTableColumn don't have any effect while a drag is in progress. The text color remains black. My first choice is to get it working as is, but if I have to I'll move to a view based outline view. My fear, though, is that I may encounter the same behavior while dragging.
    – johnpurlia
    Commented May 2, 2023 at 2:33
  • Are you trying to reimplement the default user feedback because it's not working or does the default user feedback work and are you trying to implement a custom user feedback?
    – Willeke
    Commented May 2, 2023 at 9:07

0