Vyacheslav Karpukhin
Vyacheslav Karpukhin

Reputation: 780

NSOutlineView gradient background

I'm trying to implement a NSOutlineView subclass with gradient background:

- (void)drawBackgroundInClipRect:(NSRect)clipRect {
    [gradient drawInRect:clipRect angle:90];
}

It almost works as supposed to:

But when I resize the view, gradient "breaks":

Gradient is being rendered properly everywhere, except under the area that is covered by items. When I change key state of the window (by switching to another app) that area gets rendered correctly too, as will as if I collapse the Queues item. What am I missing? What should I do to update background in that area after resize?

Upvotes: 4

Views: 603

Answers (3)

Frederik Slijkerman
Frederik Slijkerman

Reputation: 6529

I think the outline view doesn't redraw existing items when the size changes, because normally it doesn't need to. In your view, add a notification listener for NSViewFrameDidChangeNotification, and call -setNeedsDisplay on the view when the frame changes.

Upvotes: 0

Vyacheslav Karpukhin
Vyacheslav Karpukhin

Reputation: 780

I had to migrate to view-based NSOutlineView, the following code works perfectly with it:

- (void)drawBackgroundInClipRect:(NSRect)clipRect {
    [gradient drawInRect:self.frame angle:90];
}

Upvotes: 1

Peter Hosey
Peter Hosey

Reputation: 96333

The clip rectangle is the area that has changed, not necessarily the entire area of the gradient. If you want the gradient to start at the top of the (visible area of the) view, and end at the bottom of the (visible area of the) view, then you need to draw the gradient with the same rectangle every time.

Use the NSRectClip function to clip to the given rectangle, which will limit your drawing as you're supposed to, then ask yourself (the outline view) for your enclosing scroll view, ask the scroll view for the visible rect, and tell the scroll view to convert that rect to the outline view's coordinate system.

Upvotes: 2

Related Questions