[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