Reducing Flicker

team bbl


Flicker is a perennial annoyance in GUI programming. Often an application will need some tweaking to reduce it; here are some tips that might help.

On Windows, if your window is using the wxFULL_REPAINT_ON_RESIZE style, try removing it. This will cause the repaint area to be restricted to only the parts of the window "damaged" by resizing, so less erasing and redrawing is done. Otherwise, even if the window was resized a tiny amount, the whole window will be refreshed, causing flicker. However, this will not work if the appearance of your window contents depends on the size because the whole window will require updating.

You may sometimes need to use the wxCLIP_CHILDREN style on Windows to prevent a window refresh from affecting its children. The style has no effect on other platforms.

When you are drawing in a scrolled window, you can do quite a lot to improve refresh speed and reduce flicker. First, optimize the way you find the appropriate data to draw: you need a way to gather just the information that is in the current view (see wxWindow::GetViewStart and wxWindow:: GetClientSize), and in your paint handler, you should also be able to eliminate the graphics that are not in the update region (wxWindow::GetUpdateRegion). You need data structures that can get you to the start of the view quickly before you start drawing. You may be able to calculate that position from your graphics (rather than search), for example if you have columns with constant width. A linked list or array should be fairly fast to search. If it's time-consuming to calculate the current position, then perhaps you can use a caching mechanism to store the current list position for the last set of data displayed, and then you can simply scan back or forward to find the data at the start of the current scroll position. You can keep a tally of the window position for each piece of data so that you don't have to recalculate the whole thing from the start to find where the data should be drawn.

When implementing scrolling graphics, you can use wxWindow::ScrollWindow to physically move the pixels on the window, and this will mean that only the remaining "dirty" area of the window will need refreshing, which will further reduce flickering. (wxScrolledWindow already does this for you, by default.) GetUpdateRegion will reflect the smaller amount of screen that you need to update.

As mentioned in Chapter 5, "Drawing And, Printing," you may want to define your own erase background handler and leave it empty to stop the framework from clearing the background itself. Then you can draw the whole graphic (including as much of the background as necessary) on top of the old one without the flashing caused by clearing the entire background before drawing the content. Use wxWindow::SetBackgroundStyle with wxBG_STYLE_CUSTOM to tell wxWidgets not to automatically erase the background. Chapter 5 also discusses use of wxBufferedDC and wxBufferedPaintDC, which you can use in combination with the other techniques mentioned here.

Another problem is inefficiency and flicker caused by doing many updates to a window in quick succession. wxWidgets provides wxWindow:: Freeze and wxWindow::Thaw to switch off updates while code is executed between these function calls. For example, you might want to use this when adding a lot of lines to a text control one by one or appending many items to a list box. When Thaw is called, the window will normally be completely refreshed. Freeze and Thaw are implemented on Windows and Mac OS X for wxWindow and on GTK+ for wxTextCtrl. You can also implement it for your own window classes to avoid doing unnecessary processing and updating (our wxThumbnailCtrl example from Chapter 12, "Advanced Window Classes," does this; see examples/chap12/thumbnail).

    team bbl



    Cross-Platform GUI Programming with wxWidgets
    Cross-Platform GUI Programming with wxWidgets
    ISBN: 0131473816
    EAN: 2147483647
    Year: 2005
    Pages: 262

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net