Strange NSView redraw problem

  • Hello,
    I have a nsview class which is used more than once at a time. the view
    can be 'selected' in that its background color can change based on a
    boolean value.

    when i change the 'selection' from view to view, the nsbezierpath used
    to draw the curved border around the view does not clear properly.

    here are two example images:
    before: http://img88.imageshack.us/img88/7259/beforemultipleredrawsvc7.png
    after: http://img136.imageshack.us/img136/3713/aftermultipleredrawsrz9.png

    i think this has something to do with anti-aliasing, but i am not sure.

    i am using the following three lines to try and clear the view before a redraw:

    NSEraseRect([self frame]);
    [[NSColor clearColor] set];
    NSRectFill([self frame]);

    here is the whole code:

    <<START CODE>>

    NSEraseRect([self frame]);
        [[NSColor clearColor] set];
        NSRectFill([self frame]);

           NSColor *bgColor = [NSColor colorWithCalibratedWhite:0.25 alpha:0.85];
        NSRect bgRect = rect;
        int minX = NSMinX(bgRect);
        int midX = NSMidX(bgRect);
        int maxX = NSMaxX(bgRect);
        int minY = NSMinY(bgRect);
        int midY = NSMidY(bgRect);
        int maxY = NSMaxY(bgRect);
        float radius = 10.0; // correct value to duplicate Panther's App Switcher
        NSBezierPath *bgPath = [NSBezierPath bezierPath];

        // Bottom edge and bottom-right curve
        [bgPath moveToPoint:NSMakePoint(midX, minY)];
        [bgPath appendBezierPathWithArcFromPoint:NSMakePoint(maxX, minY)
                                        toPoint:NSMakePoint(maxX, midY)
                                          radius:radius];

        // Right edge and top-right curve
        [bgPath appendBezierPathWithArcFromPoint:NSMakePoint(maxX, maxY)
                                        toPoint:NSMakePoint(midX, maxY)
                                          radius:radius];

        // Top edge and top-left curve
        [bgPath appendBezierPathWithArcFromPoint:NSMakePoint(minX, maxY)
                                        toPoint:NSMakePoint(minX, midY)
                                          radius:radius];

        // Left edge and bottom-left curve
        [bgPath appendBezierPathWithArcFromPoint:bgRect.origin
                                        toPoint:NSMakePoint(midX, minY)
                                          radius:radius];
        [bgPath closePath];

        [bgColor set];
    if (isSelected) {
      [[NSColor colorWithCalibratedWhite:1.0 alpha:0.3] set];
    }
        [bgPath fill];

    [[NSColor colorWithCalibratedWhite:1.0 alpha:0.2] set];
    [bgPath setLineWidth:2.0];

    [bgPath setLineJoinStyle:NSRoundLineJoinStyle];
    [bgPath stroke];

    int i = 0;
    for (i=0;i<[imagesArray count];i++) {
      NSImage *thisIcon = [imagesArray objectAtIndex:i];
      [thisIcon drawAtPoint:NSMakePoint((64*i)+10,3)
    fromRect:NSMakeRect(0,0,[thisIcon size].width,[thisIcon size].height)
    operation:NSCompositeSourceOver fraction:1.0];
    }

    <<END CODE>>

    If anyone has any idea as to how i can make the corners of my view
    draw properly,
    it would be much appreciated.

    Thanks,
    John Cassington
  • On Sep 30, 2006, at 12:39 AM, John Cassington wrote:

    > Hello,
    > I have a nsview class which is used more than once at a time. the view
    > can be 'selected' in that its background color can change based on a
    > boolean value.
    >
    > when i change the 'selection' from view to view, the nsbezierpath used
    > to draw the curved border around the view does not clear properly.
    >
    > here are two example images:
    > before: http://img88.imageshack.us/img88/7259/
    > beforemultipleredrawsvc7.png
    > after: http://img136.imageshack.us/img136/3713/
    > aftermultipleredrawsrz9.png
    >
    > i think this has something to do with anti-aliasing, but i am not
    > sure.
    >
    > i am using the following three lines to try and clear the view
    > before a redraw:
    >
    > NSEraseRect([self frame]);
    > [[NSColor clearColor] set];
    > NSRectFill([self frame]);

    Try removing the above three lines and then make sure if you
    implement isOpaque, that you return NO:

    - (BOOL)isOpaque
    {
        return NO;
    }

    Or, simply leave out isOpaque as by default, NSView returns NO.

    ___________________________________________________________
    Ricky A. Sharp        mailto:<rsharp...>
    Instant Interactive(tm)  http://www.instantinteractive.com
  • -clearColor hasn't been so clear for me in Cocoa.  I have had to use Quartz:

    NSGraphicsContext *nsctx = [NSGraphicsContext currentContext];
    CGContextRef context = (CGContextRef)[nsctx graphicsPort];

          CGRect rect = CGRectMake(x, y, width, height);

          CGContextClearRect(context, rect);

    CGContextFlush(context);
previous month september 2006 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  
Go to today