Problems faced while customizing NSTextFieldCell

Discussion in 'Mac Programming' started by Monaj, Feb 1, 2010.

  1. Monaj macrumors regular

    Joined:
    May 24, 2009
    #1
    Hi all,

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

    For this I created a custom class:

    IconNameCell.h

    Code:
     @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

    Code:
    @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-

    Code:
     - (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,

    Monaj
     
  2. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #2
    What does the crash log show?

    You don't have a dealloc method in your cell. You're just leaking memory.

    Edit: you're also leaking the dictionary and attributed string.
     

Share This Page