Re: Adaptable NSTableViewHeader

  • Before I reply - sorry for the late delivery of this e-mail; it was
    never sent when it was intended to, and I haven't thought about it
    since. Hope your memory is as good as your coding skills ;)

    > On Oct 30, 2007, at 10:24 AM, Mattias Arrelid wrote:
    >> [...]
    >> Now, if I set my tableview's headerview to my custom subclass, and
    >> place the tableview inside a NSScrollView, my custom tableview
    >> header is displayed just fine. So far, so nice. Now let us assume
    >> that the statistics are not that important for the user, so as she
    >> begins to scroll everything that is visible in the clip view (table
    >> header view + table view) is scrolled
    > The table view and the header view are each in different clip views.
    > You scroll through the height of the NSScrollView's documentView.
    > That's why the rows in your table view start scrolling before you
    > want them to.

    Yes, I figured that too. I only intended to show what I wanted to
    achieve, and that was the easiest way of doing it (from what I knew
    then)... :)

    > I'd subclass NSScrollView to handle an additional view, for you're
    > statistics, which you want to appear above the header.  Implement -
    > tile to put it in the right place.  You may need to override -
    > reflectScrolledClipView:.  You need to get the scroll view to use the
    > combined height of the document view and statistics view as the
    > height it scrolls through.  When you scroll down, you need to first
    > shrink the visible height of the stats view, and use any left-over
    > for normal scrolling of the document view.  Scrolling up is just the
    > opposite.

    I've subclassed NSScrollView to have two clip views instead of just
    one (or at least two clip views that I am in charge of, in opposite to
    the two clip views that's already included in NSScrollView). The
    following snippet in reflectScrolledClipView: makes the views realign
    just fine when using the scrollview arrows or the scroll wheel of my

    - (void)reflectScrolledClipView:(NSClipView *)aClipView {

      [super reflectScrolledClipView:aClipView];

      // Scroll accordingly
      if (upperClipView && lowerClipView && [aClipView isEqualTo:[self
    contentView]]) {

        NSRect clipBounds = [aClipView bounds];
        NSRect clipDocumentRect = [aClipView documentRect];

        float upperHeight = MAX(250 - clipBounds.origin.y, 20);

        NSRect upperRect, lowerRect;
        NSDivideRect(clipBounds, &upperRect, &lowerRect, upperHeight,

        lowerRect.origin.y -= upperRect.origin.y;
        upperRect.origin.y = 0;

        [upperClipView setFrame:upperRect];
        [lowerClipView setFrame:lowerRect];

        if (upperHeight <= 20)
          [lowerClipView scrollToPoint:NSMakePoint(0, clipBounds.origin.y
    - 230)];
          [lowerClipView scrollToPoint:NSMakePoint(0, 0)];

        [self setNeedsDisplay:TRUE];

    Now, there's only one thing left; keyboard navigation in the lower
    view (the table view itself). I'd like to handle each keypress just as
    they're handled by default, but they should additionally make the clip
    views realign if needed. Imagine the start case; both the statistics
    view and the table view are showing. I select a row in the table view
    and press the down arrow. Now the selection changes. Pressing the down
    key repeatedly makes the selection go downwards until I reach the last
    visible row. Yet another press will select the next row, which isn't
    visible. What I want here is for the clip views in my custom
    scrollview to realign; the statistics view should start to compress
    and the table view's clip view height should get increased. What's the
    "best" approach here? I tried listening to
    "NSViewBoundsDidChangeNotification" of the clip view that belongs to
    the table view, but once I recieved the message, I wasn't able to
    realign the clip views properly. Any ideas?

    > [...]
    > By the way, after looking at your code, NSDivideRect() is a handy
    > function:
    > NSDivideRect([self bounds], &lowerRect, &upperRect, [self
    > minimumHeight], NSMaxYEdge);

    Didn't know about it, thank you very much! A handy function that will
    save me many lines of unnecessary code...

    And by the way; is this the proper way of answering a message that was
    delivered to me through a digest? I just selected your portion of the
    digest and hit Reply in my mail client... plus switched the subject
    field. I searched the FAQ without any success...

    Thanks again.

previous month december 2007 next month
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Go to today