views:

225

answers:

1

Hi all,

I am trying to make cells in an outline view just like we have for users in Skype's message window.

  1. For this I created a custom class:

IconNameCell.h

    @interface IconNameCell : NSTextFieldCell {
        //@private
        NSImage *userImage;  // size (17,17)
        NSImage *statusIcon; // size (14,14)
        NSString *cellText;

    }
    @property (readwrite, retain) NSImage *userImage;
    @property (readwrite, retain) NSImage *statusIcon;
    @property (readwrite, retain) NSString *cellText;
    - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView;
    @end

IconNameCell.m

@implementation IconNameCell
@synthesize userImage;
@synthesize statusIcon;
@synthesize cellText;


- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView{
    @try{
    // Inset the cell frame to give everything a little horizontal padding
    NSRect anInsetRect = NSInsetRect(cellFrame,2.0,0); 

    //FIXME: flip coordinates and size can be set in accessor methods
    // setting userImage and statusIcon in flipped coordinate 
    [userImage setFlipped:YES];
    [statusIcon setFlipped:YES];

    // setting size of image and icon
    [userImage setSize:NSMakeSize(25.0, 25.0)];
    [statusIcon setSize:NSMakeSize(15.0, 17.0)];

    // setting attributes of cell text
    NSMutableParagraphStyle *dParagraphStyle = [[NSMutableParagraphStyle alloc] init];
    [dParagraphStyle setAlignment:NSLeftTextAlignment];

    NSColor *colorOfText;
    if ([self isHighlighted]) {
        colorOfText = [NSColor whiteColor]; 
    }
    else {
        colorOfText = [NSColor blackColor];
    }

    NSMutableDictionary * dTitleAttributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
                                               colorOfText,NSForegroundColorAttributeName,
                                               [NSFont systemFontOfSize:11.0],NSFontAttributeName,
                                               dParagraphStyle, NSParagraphStyleAttributeName,
                                               nil];

    // getting sizes
    NSSize cellTextSize = [cellText sizeWithAttributes:dTitleAttributes];
    NSSize userImageSize = [userImage size];
    NSSize statusIconSize = [statusIcon size];

    // making layout boxes for all elements

    // vertical padding between the lines of text
    float dVerticalPadding = 2.0;

    // horizontal padding between two images
    float padBtwnImgs = 4.0;

    // horizontal padding between image and text
    float padBtwnImgText = 6.0;


        NSString *userImageName = [userImage name];
        NSLog(@"userImageName - %@ / cellText- %@",userImageName,cellText); // getting null for userImageName

        //if ([userImageName isEqualToString:@"current_D.png"]) {


        //FIXME: this is juggad and should be corrected 
        NSRange rangeOfComma = [cellText rangeOfString:@","];
        if (rangeOfComma.length !=0 ) {
            //<#statements#>

        // userImage box: center the userImage vertically inside of the inset rect
        NSRect cellTitleBox = NSMakeRect(anInsetRect.origin.x,
                                         anInsetRect.origin.y + anInsetRect.size.height*.5 - cellTextSize.height*.5,
                                         cellTextSize.width,
                                         cellTextSize.height);

        // drawing cell text
        [cellText drawInRect:cellTitleBox withAttributes:dTitleAttributes];
    }
    else {
        // userImage box: center the userImage vertically inside of the inset rect
        NSRect userImageBox = NSMakeRect(anInsetRect.origin.x,
                                         anInsetRect.origin.y + anInsetRect.size.height*.5 - userImageSize.height*.5,
                                         userImageSize.width,
                                         userImageSize.height);

        // statusIcon box: center the statusIcon vertically inside of the inset rect
        NSRect statusIconBox = NSMakeRect(userImageBox.origin.x + userImageBox.size.width + padBtwnImgs,
                                          anInsetRect.origin.y + anInsetRect.size.height*.5 - statusIconSize.height*.5,
                                          statusIconSize.width,
                                          statusIconSize.height);

        // cellTitleBox: vertically aligning text
        NSRect cellTitleBox = NSMakeRect(statusIconBox.origin.x + statusIconBox.size.width + padBtwnImgText,
                                         anInsetRect.origin.y + anInsetRect.size.height*.5 - cellTextSize.height*.5,
                                         cellTextSize.width,
                                         cellTextSize.height);

        // drawing user image
        [userImage drawInRect:userImageBox fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];

        // drawing user status
        [statusIcon drawInRect:statusIconBox fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];

        // drawing cell text
        [cellText drawInRect:cellTitleBox withAttributes:dTitleAttributes];
    }
    }
    @catch (NSException *e) {
        NSLog(@"IconNameCell -%@",e);
    }


}
@end

2nd, I assigned text field cell for outline view the class: IconNameCell in IB

3rd, I used this code in delegate to set image, icon and name of user in custom cell-

 - (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item{
        if ([[tableColumn identifier] isEqualToString:@"userInfo"]) {
          // some relevant code

          if( [[item onlineStatus] intValue] == 0 ){
        [cell setStatusIcon:[NSImage imageNamed:@"offline.png"]];
        }
        else{
        [cell setStatusIcon:[NSImage imageNamed:@"online.png"]];
        }

        //similarly, setting attribute for userImage and cellText

        } 

I am facing two problems with it: 1. Application is frequently crashing when I am selecting one or the other row in outline view. Earlier when I had not taken the customized cell but three different columns for - user image, user status and user name it was working fine! 2. For the log: NSLog(@"userImageName - %@ / cellText- %@",userImageName,cellText); I am getting (null) as userImageName, although I should get some string value for it.

Can anyone suggest me some solution for it??

Thanks,

Miraaj

A: 
  1. Application is frequently crashing when I am selecting one or the other row in outline view.

Please edit your question to include the crash log.

2. For the log: NSLog(@"userImageName - %@ / cellText- %@",userImageName,cellText); I am getting (null) as userImageName, although I should get some string value for it.

Have you set the image's name with setName: or obtained it from imageNamed:? Otherwise, it doesn't have one, and this output is correct.

Peter Hosey