Suppressing drawing

  • Hello,

    I'm fairly new to Cocoa programming, and I'm having a little drawing
    problem that I'm sure is simple to solve if somebody would be kind
    enough to point me in the right direction.

    Here's my problem.  I have an NSTextView with some text in it.  When a
    particular event happens, I need to change the text in the view, and
    also resize the view (I'm moving the left edge of the view over a bit
    to make room for a "caution" icon that only appears when the app
    encounters a problem.

    So, the first thing that I do is to set the frame and bounds of the
    view (setView and setBounds), and then I call
    replaceCharactersInRange:withAttributedString: to replace the text.  I
    do these two things one right after the other in one function.
    Sometimes, I get a brief flicker as the view re-draws in its new size,
    before the new text renders.

    What I'd like to do is to suppress the re-draw of the view until both
    the resize and the text set have completed.

    I'd appreciate any pointers to the proper way to do this.  I've tried
    searching both the docs and the list, but I must be looking for the
    wrong terminology.

    Thanks!
    --Mike
  • All windows in OS X are double-buffered; as such, the redraw is
    suppressed until the event loop next runs.
    In other words, your flicker is caused by something else...

    On Dec 15, 2007, at 5:47 PM, Mike Kobb wrote:

    > Hello,
    >
    > I'm fairly new to Cocoa programming, and I'm having a little
    > drawing problem that I'm sure is simple to solve if somebody would
    > be kind enough to point me in the right direction.
    >
    > Here's my problem.  I have an NSTextView with some text in it.
    > When a particular event happens, I need to change the text in the
    > view, and also resize the view (I'm moving the left edge of the
    > view over a bit to make room for a "caution" icon that only appears
    > when the app encounters a problem.
    >
    > So, the first thing that I do is to set the frame and bounds of the
    > view (setView and setBounds), and then I call
    > replaceCharactersInRange:withAttributedString: to replace the
    > text.  I do these two things one right after the other in one
    > function.  Sometimes, I get a brief flicker as the view re-draws in
    > its new size, before the new text renders.
    >
    > What I'd like to do is to suppress the re-draw of the view until
    > both the resize and the text set have completed.
    >
    > I'd appreciate any pointers to the proper way to do this.  I've
    > tried searching both the docs and the list, but I must be looking
    > for the wrong terminology.
    >
    > Thanks!
    > --Mike
  • I have a similar problem, but at the window level.  The following two
    lines of code cause the window to first redraw in the wrong position, then
    immediately in the correct position, resulting in a visible flash jump.  I
    would also like to suppress the window drawing until both statements
    execute.

        //    Set the window size and readjust location so title bar stays put
        [window setContentSize:NSMakeSize([contentView frame].size.width,
    totalHeight)];
        [window setFrameTopLeftPoint:frameTopLeftPoint];

        This is in a controller that handles disclosure panes within an
    inspector panel window.

    > All windows in OS X are double-buffered; as such, the redraw is
    > suppressed until the event loop next runs.
    > In other words, your flicker is caused by something else...
    >
    >
    > On Dec 15, 2007, at 5:47 PM, Mike Kobb wrote:
    >
    >> Hello,
    >>
    >> I'm fairly new to Cocoa programming, and I'm having a little
    >> drawing problem that I'm sure is simple to solve if somebody would
    >> be kind enough to point me in the right direction.
    >>
    >> Here's my problem.  I have an NSTextView with some text in it.
    >> When a particular event happens, I need to change the text in the
    >> view, and also resize the view (I'm moving the left edge of the
    >> view over a bit to make room for a "caution" icon that only appears
    >> when the app encounters a problem.
    >>
    >> So, the first thing that I do is to set the frame and bounds of the
    >> view (setView and setBounds), and then I call
    >> replaceCharactersInRange:withAttributedString: to replace the
    >> text.  I do these two things one right after the other in one
    >> function.  Sometimes, I get a brief flicker as the view re-draws in
    >> its new size, before the new text renders.
    >>
    >> What I'd like to do is to suppress the re-draw of the view until
    >> both the resize and the text set have completed.
    >>
    >> I'd appreciate any pointers to the proper way to do this.  I've
    >> tried searching both the docs and the list, but I must be looking
    >> for the wrong terminology.
    >>
    >> Thanks!
    >> --Mike
    >
  • On Dec 16, 2007, at 1:34 PM, Gordon Apple wrote:

    > //    Set the window size and readjust location so title bar
    > stays put
    > [window setContentSize:NSMakeSize([contentView frame].size.width,
    > totalHeight)];
    > [window setFrameTopLeftPoint:frameTopLeftPoint];

    Replace those two calls with one to "-[NSWindow setFrame:display:]"

    j o a r
  • It wasn't quite that easy, but that did eventually solve the jump
    problem.  Now, if I could just get the enclosed panes to position before
    they redraw, maybe I could get rid of the redraw flash.

        [window setFrame:NSMakeRect(frame.origin.x,
                                    frameTop - newFrame.size.height,
                                    newFrame.size.width, newFrame.size.height)
                display:NO];

        //    Stack the panes in their proper locations
        float currentY = totalHeight;    //    Start at the top and work down
        for(NSView* view in array)
        {
            float height = [view frame].size.height;
            currentY -= height;
            [view setFrameOrigin:NSMakePoint(0.0, currentY)];
            [view setNeedsDisplay:NO];
            currentY -= ViewSpacing;
        }

    > On Dec 16, 2007, at 1:34 PM, Gordon Apple wrote:
    >
    >> //    Set the window size and readjust location so title bar
    >> stays put
    >> [window setContentSize:NSMakeSize([contentView frame].size.width,
    >> totalHeight)];
    >> [window setFrameTopLeftPoint:frameTopLeftPoint];
    >
    >
    > Replace those two calls with one to "-[NSWindow setFrame:display:]"
    >
    > j o a r
  • Gordon,

    That should be possible if you update the frames on your views before
    you update the frame on your window, or completely automatically if
    your view hierarchy is capable of updating the size + position of
    subviews in response to a change in the size of the window.

    Have you thought abut adding code to the superview of your "panes" for
    repositioning them as its size changes?
    If you just stack subviews vertically, and if you're on Leopard, have
    you considered using NSCollectionView?

    Note that updating the frame of a view doesn't marks it as needing
    display, so your call to setNeedsDisplay:NO below shouldn't be
    necessary.

    Btw. I take it you're using Quartz Debug to track your drawing updates?

    j o a r

    On Dec 17, 2007, at 9:31 AM, Gordon Apple wrote:

    > It wasn't quite that easy, but that did eventually solve the jump
    > problem.  Now, if I could just get the enclosed panes to position
    > before
    > they redraw, maybe I could get rid of the redraw flash.
    >
    > [window setFrame:NSMakeRect(frame.origin.x,
    > frameTop - newFrame.size.height,
    > newFrame.size.width,
    > newFrame.size.height)
    > display:NO];
    >
    > //    Stack the panes in their proper locations
    > float currentY = totalHeight;    //    Start at the top and work
    > down
    > for(NSView* view in array)
    > {
    > float height = [view frame].size.height;
    > currentY -= height;
    > [view setFrameOrigin:NSMakePoint(0.0, currentY)];
    > [view setNeedsDisplay:NO];
    > currentY -= ViewSpacing;
    > }
previous month december 2007 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