Source list group item indentation

  • Howdy list,

    Trying to implement an NSOutlineView as source list.  Everything works
    fine, except that I have group items that I don't want to be
    expandable.  Even if I tell the list view they're not expandable, they
    still appear indented.  What do I have to do to make them flush-left
    with the inside of the outline view, like the Library and Store items
    in the iTunes source list?

    Thanks,
    --Kyle Sluder
  • Le 11 janv. 08 à 15:16, Kyle Sluder a écrit :

    > Howdy list,
    >
    > Trying to implement an NSOutlineView as source list.  Everything works
    > fine, except that I have group items that I don't want to be
    > expandable.  Even if I tell the list view they're not expandable, they
    > still appear indented.  What do I have to do to make them flush-left
    > with the inside of the outline view, like the Library and Store items
    > in the iTunes source list?
    >
    > Thanks,
    > --Kyle Sluder

    There is a bunch of methods to control NSOutlineView indentation. I
    think you will have to subclass the NSOutlineview.

    See NSOutlineView Reference:

    • – levelForItem:
    • – levelForRow:
    • – setIndentationPerLevel:
    • – indentationPerLevel
    • – setIndentationMarkerFollowsCell:
    • – indentationMarkerFollowsCell
  • You need to subclass NSOutlineView and override
    -frameOfOutlineCellAtRow:
    returning NSZeroRect on a condition that makes a group a group in your
    app or returning [super frameOfOutlineCellAtRow:row] if not a group.
    Mine gets the represented object of the item and checks the node's name.

    Jonathan Dann
  • And to further backup what Jonathan said, this is mentioned in the
    AppKit release notes:

    http://developer.apple.com/releasenotes/Cocoa/AppKit.html

    "To not show a disclosure triangle, override -frameOfOutlineCellAtRow:
    and return an empty rect. You will also want to not allow it to be
    collapsed by returning NO from the delegate method -
    outlineView:shouldCollapseItem:. When the disclosure triangle is not
    shown for a section header, the item will automatically be unindented. "

    I realize the release notes are rather long, but they are a good read.
    Especially for controls/components that you use.

    --corbin

    On Jan 11, 2008, at 7:12 AM, Jonathan Dann wrote:

    > You need to subclass NSOutlineView and override
    > -frameOfOutlineCellAtRow:
    > returning NSZeroRect on a condition that makes a group a group in
    > your app or returning [super frameOfOutlineCellAtRow:row] if not a
    > group.  Mine gets the represented object of the item and checks the
    > node's name.
  • (Sorry if you're getting this twice, I'm an idiot and forgot to set
    the From option.)

    On Jan 15, 2008 6:15 PM, Corbin Dunn <corbind...> wrote:
    > I realize the release notes are rather long, but they are a good read.
    > Especially for controls/components that you use.

    I did read them, but obviously not closely enough.  ;)

    To be honest, this seems like The Wrong Way(tm) to do it.  It seems
    far more appropriate for the delegate to provide this information, and
    thus suffer from the tight coupling with the data source.  Filed as r.
    5690092.

    Thanks all,
    --Kyle Sluder
  • On Jan 16, 2008, at 2:23 AM, Kyle Sluder wrote:

    > (Sorry if you're getting this twice, I'm an idiot and forgot to set
    > the From option.)
    >
    > On Jan 15, 2008 6:15 PM, Corbin Dunn <corbind...> wrote:
    >> I realize the release notes are rather long, but they are a good
    >> read.
    >> Especially for controls/components that you use.
    >
    > I did read them, but obviously not closely enough.  ;)
    >
    > To be honest, this seems like The Wrong Way(tm) to do it.  It seems
    > far more appropriate for the delegate to provide this information, and
    > thus suffer from the tight coupling with the data source.  Filed as r.
    > 5690092.

    Thank you for logging the bug! This is the best way to get things like
    this changed.

    For others, Kyle is basically asking that the option to show a
    disclosure triangle be determined by a delegate method. That is an
    excellent it, and it is something we have wanted to do. It was more of
    a timing issue for why it wasn't done.

    thanks,
    corbin
  • On 16 Jan 2008, at 18:08, Corbin Dunn wrote:

    >
    > On Jan 16, 2008, at 2:23 AM, Kyle Sluder wrote:
    >
    >> (Sorry if you're getting this twice, I'm an idiot and forgot to set
    >> the From option.)
    >>
    >> On Jan 15, 2008 6:15 PM, Corbin Dunn <corbind...> wrote:
    >>> I realize the release notes are rather long, but they are a good
    >>> read.
    >>> Especially for controls/components that you use.
    >>
    >> I did read them, but obviously not closely enough.  ;)
    >>
    >> To be honest, this seems like The Wrong Way(tm) to do it.  It seems
    >> far more appropriate for the delegate to provide this information,
    >> and
    >> thus suffer from the tight coupling with the data source.  Filed as
    >> r.
    >> 5690092.
    >
    > Thank you for logging the bug! This is the best way to get things
    > like this changed.
    >
    > For others, Kyle is basically asking that the option to show a
    > disclosure triangle be determined by a delegate method. That is an
    > excellent it, and it is something we have wanted to do. It was more
    > of a timing issue for why it wasn't done.
    >
    > thanks,
    > corbin
    >

    I'm a little unsure of the netiquette here, as I have a nice solution
    BUT *it is someone else's code* and I don't know who/where from!
    Explanation follows, but please don't credit me for it.

    Subclass NSOutlineView, and override the following method:

    - (NSRect)frameOfOutlineCellAtRow:(NSInteger)row
    {
    // Default to show triangle
    BOOL showTriangle = YES;

    // See if delegate responds to new selector
    if ([[self delegate]
    respondsToSelector
    :@selector(outlineView:shouldShowDisclosureTriangleForItem:)])
    {
      // Perform selector using objc_msgSend() to avoid compiler warnings
      SEL selector =
    @selector(outlineView:shouldShowDisclosureTriangleForItem:);
      id item = [self itemAtRow:row];

      showTriangle = (objc_msgSend([self delegate], selector, self, item) !
    = 0x00);
    }

    if (!showTriangle)
    {
      // If not showing triangle, return empty rect
      return NSZeroRect;
    }
    else
    {
      // else return default value
      return [super frameOfOutlineCellAtRow:row];
    }
    }

    Then, replace your outline views in IB with your custom one, and the
    delegate can implement:

    - (void)outlineView:(NSOutlineView *)
    shouldShowDisclosureTriangleForItem:(id)item

    to decide whether or not to show the triangle.

    --Ben
  • >
    >
    > Subclass NSOutlineView, and override the following method:
    >
    > - (NSRect)frameOfOutlineCellAtRow:(NSInteger)row
    > {
    > // Default to show triangle
    > BOOL showTriangle = YES;
    >
    > // See if delegate responds to new selector
    > if ([[self delegate]
    > respondsToSelector
    > :@selector(outlineView:shouldShowDisclosureTriangleForItem:)])
    > {

    Ah! One thing that I highly recommend changing is the selector
    signature. Let's say you call your class "CDOutlineView". I'd suggest
    using the selector name:
    cdOutlineView:shouldShowDisclosureTriangleForItem:.

    If Apple introduces the same method name in a later version of the OS
    then it may conflict with yours, and it may start to be called at
    different times with different parameters. This type of thing does
    happen, and I'll give you an example. On Leopard we introduced:

    - (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:
    (NSTableColumn *)tableColumn row:(NSInteger)row;

    However, other people implemented the same thing in a custom subclass,
    and it caused compatibility problems. The solution was for people to
    be forced to link against Leopard in order to use the new delegate
    method, which is unfortunate (mainly because it doesn't allow people
    to sort of soft-adopt it in their 10.4 apps - if that doesn't make
    sense, don't worry).

    corbin
  • NB to avoid compiler warnings, you can create a category on NSObject:

    @interface NSObject (DisclosureTriangleAdditions)

    - (BOOL)outlineView:(NSOutlineView *) shouldShowDisclosureTriangleForItem:(id);

    @end

    Then your method becomes:

    - (NSRect)frameOfOutlineCellAtRow:(NSInteger)row
    {
        // Default to show triangle
        BOOL showTriangle = YES;

        if ([[self delegate] respondsToSelector:
            @selector(outlineView:shouldShowDisclosureTriangleForItem:)])
        {
            showTriangle = [[self delegate] outlineView:self
                shouldShowDisclosureTriangleForItem:item];
        }

        if (!showTriangle)
        {
            // If not showing triangle, return empty rect
            return NSZeroRect;
        }
        else
        {
            // else return default value
            return [super frameOfOutlineCellAtRow:row];
        }
    }

    > Then, replace your outline views in IB with your custom one, and the
    > delegate can implement:
    >
    > - (void)outlineView:(NSOutlineView *)
    > shouldShowDisclosureTriangleForItem:(id)item

    Don't forget to declare this with a non-void return type :)

    Hamish
  • > Subject: Re: Source list group item indentation
    >
    > On 16 Jan 2008, at 18:08, Corbin Dunn wrote:
    >
    >>
    >> On Jan 16, 2008, at 2:23 AM, Kyle Sluder wrote:
    >>
    >>> (Sorry if you're getting this twice, I'm an idiot and forgot to set
    >>> the From option.)
    >>>
    >>> On Jan 15, 2008 6:15 PM, Corbin Dunn <corbind...> wrote:
    >>>> I realize the release notes are rather long, but they are a good
    >>>> read.
    >>>> Especially for controls/components that you use.
    >>>
    >>> I did read them, but obviously not closely enough.  ;)
    >>>
    >>> To be honest, this seems like The Wrong Way(tm) to do it.  It seems
    >>> far more appropriate for the delegate to provide this information,
    >>> and
    >>> thus suffer from the tight coupling with the data source.  Filed as
    >>> r.
    >>> 5690092.
    >>
    >> Thank you for logging the bug! This is the best way to get things
    >> like this changed.
    >>
    >> For others, Kyle is basically asking that the option to show a
    >> disclosure triangle be determined by a delegate method. That is an
    >> excellent it, and it is something we have wanted to do. It was more
    >> of a timing issue for why it wasn't done.
    >>
    >> thanks,
    >> corbin
    >>
    >
    > I'm a little unsure of the netiquette here, as I have a nice solution
    > BUT *it is someone else's code* and I don't know who/where from!
    > Explanation follows, but please don't credit me for it.
    >
    > Subclass NSOutlineView, and override the following method:
    >
    > - (NSRect)frameOfOutlineCellAtRow:(NSInteger)row
    > {
    > // Default to show triangle
    > BOOL showTriangle = YES;
    >
    > // See if delegate responds to new selector
    > if ([[self delegate]
    > respondsToSelector
    > :@selector(outlineView:shouldShowDisclosureTriangleForItem:)])
    > {
    > // Perform selector using objc_msgSend() to avoid
    > compiler warnings
    > SEL selector =
    > @selector(outlineView:shouldShowDisclosureTriangleForItem:);
    > id item = [self itemAtRow:row];
    >
    > showTriangle = (objc_msgSend([self delegate], selector,
    > self, item) !
    > = 0x00);
    > }
    >
    > if (!showTriangle)
    > {
    > // If not showing triangle, return empty rect
    > return NSZeroRect;
    > }
    > else
    > {
    > // else return default value
    > return [super frameOfOutlineCellAtRow:row];
    > }
    > }
    >
    >
    > Then, replace your outline views in IB with your custom one, and the
    > delegate can implement:
    >
    > - (void)outlineView:(NSOutlineView *)
    > shouldShowDisclosureTriangleForItem:(id)item
    >
    > to decide whether or not to show the triangle.
    >
    > --Ben
    >

    That looks like the code from my blog - I'm just glad it's proven
    useful to people. It's nice to be able to "give something back" to the
    list.

    I'm relatively new to Cocoa development so hadn't considered Corbin's
    point about the selector naming possibly clashing with future API
    updates. Hamish's suggestion of implementing an NSObject category is
    also something that hadn't crossed my mind. I'll update my blog
    incorporating these changes (http://blog.petecallaway.net) soon.

    Cheers,
    Pete
previous month january 2008 next month
MTWTFSS
  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 31      
Go to today