[wx-dev] #9719: wxGrid. Patch for heavily excessive flicker on drag-to-resize-window

wxTrac noreply at wxsite.net
Fri Jul 11 18:40:09 PDT 2008


Ticket URL: <http://trac.wxwidgets.org/ticket/9719>

#9719: wxGrid. Patch for heavily excessive flicker on drag-to-resize-window
-------------------------------+--------------------------------------------
 Reporter:  kjones at cedrus.com  |       Owner:       
     Type:  defect             |      Status:  new  
 Priority:  normal             |   Milestone:       
Component:  wxGrid             |     Version:  2.8.8
 Keywords:                     |   Blockedby:       
    Patch:  1                  |    Blocking:       
-------------------------------+--------------------------------------------
 INTRODUCTION - THE MAIN PROBLEM:

 My "enemy" (enemies) as I crafted this code were the specific cases of
 flicker (mainly on MSW) that happen when you RESIZE the application frame
 (or dialog, or panel, as the case may be) that contains a wxGrid.

 To observe this aggressive flickering, all one needs to do is build the
 "grid" sample provided in the "samples" directory that comes with your
 wxWidgets installation.  Run the grid sample demo on Microsoft Windows,
 and grab the lower right corner of the application frame to drag the
 window bigger and/or smaller.  The entire grid (including row labels,
 column labels, and cell contents) will flicker aggressively no matter
 whether you size the window smaller or larger.

 FOUR LINES OF CODE THAT LIE AT THE HEART OF THIS ISSUE:

 I realized that the lines of code that are the "culprits" of this flicker
 are these four lines:

 {{{
         m_cornerLabelWin->SetSize( 0, 0, m_rowLabelWidth, m_colLabelHeight
 );
         m_colLabelWin->SetSize( m_rowLabelWidth, 0, gw, m_colLabelHeight
 );
         m_rowLabelWin->SetSize( 0, m_colLabelHeight, m_rowLabelWidth, gh
 );
         m_gridWin->SetSize( m_rowLabelWidth, m_colLabelHeight, gw, gh );
 }}}

 These four lines are inside wxGrid::CalcWindowSizes, which gets called for
 every wxSizeEvent received by wxGrid.

 In my patch, I was able to delete three of those four lines completely.
 However, I did have to keep m_gridWin->SetSize, because m_gridWin is the
 "target window" of the wxScrolledWindow, and thus the wxScrolledWindow
 needs up-to-date size information on m_gridWin in order for all the
 scrolling features to work correctly.  (As always, please correct me if
 any of my statements are inaccurate.  It will be great if someone
 contradicts me and has a way to eliminate all the calls to
 m_gridWin->SetSize also.)

 THE SIMPLE, "HUMAN-READABLE" EXPLANATION FOR THE APPROACH I TOOK:

 "INFINITELY-LARGE LABELS"

 What I did in order to eliminate the need for calling SetSize on the
 m_colLabelWin and the m_rowLabelWin was to essentially create (and
 "enforce" over the lifetime of the wxGrid) a m_colLabelWin that is
 "infinitely wide" and a m_rowLabelWin that is "infinitely long/tall."

 Now that SetSize is not called in wxGrid::CalcWindowSizes, there are only
 THREE places where SetSize is used for column labels and row labels.
 Those three spots are generally "once-per-grid-lifetime" spots, and they
 are:  wxGrid::Create, wxGrid::SetColLabelSize, and
 wxGrid::SetRowLabelSize.

 These calls to SetSize are made indirectly via calling
 "AdjustFourGridSubquadrants," which is a private helper function I
 created.  (Feel free to change the name... my function-naming can get
 hideous.... names only a momma could love...  but I'm their momma...)

 Because the column labels and the row labels are now **NOT** refreshed
 during sizing, there was more "manual" work that I had to perform inside
 wxGridWindow::ScrollWindow.  Also, I did find that it becomes necessary to
 still Refresh "everything" during those few special size events in which
 the scrollbars are suddenly removed (you can see these Refresh calls I
 added near the old comment "remove the scrollbars and use the new client
 size").


 MY HESITATIONS / REMAINING QUESTIONS....

 Overall, I am mainly very pleased that with just a few clearcut and easily
 understood changes I was able to (from my perspective) completely remedy
 my flicker problem.

 I have tested this code on MSW and on Mac.  I have tested this using the
 wxWidgets demo sample for the grid, and I have also tested this on my own
 Cedrus application.

 However, there are three main questions that still linger in my mind.

 # 1.  What is the best integer value to use for my "infinite width" and
 "infinite height"?  As you will see in the patch, I am currently (somewhat
 arbitrarily) using ((SHRT_MAX) / 2).  Perhaps there is some wxWidgets flag
 or static function or macro for "maximum possible width of any window"
 ????

 # 2.  As I have said, the "main theme" of my patch is to use "infinite"
 sized labels.  However, in order to completely eliminate flicker in the
 CELL CONTENTS, I had to make two other very small changes.  These two
 changes were literally "one-word" changes apiece.  Not even one whole
 line!  However, I do not know whether these changes are safe for platforms
 other than those platforms on which I have tested.

 NOTE: If these two changes are not cross-platform, then if you use my
 patch EXCLUDING just these two changes, then you still benefit from the
 elimination of flicker on the row labels and the column labels.

 First "one-word" change:  always pass "true" as the last argument to
 SetScrollbars in the function wxGrid::CalcDimensions.

 Second "one-word" change:  REMOVE the flag "wxFULL_REPAINT_ON_RESIZE" from
 the constructor wxGridWindow::ScrollWindow


--
Ticket URL: <http://trac.wxwidgets.org/ticket/9719>


More information about the wx-dev mailing list