This is just another refactoring in order to avoid duplicating calls to
HideCellEditControl() and SaveEditControlValue() in several different
places.
Also call DoSaveEditControlValue() because if the editor is shown, it is
also necessarily enabled and there is no need to check for this.
No real changes, just simplify the code by using a single function to
retrieve the editor to use for the current cell.
This also allows to get rid of a few temporary variables, further
amplifying the simplification.
Define the common logic for positioning editors not taking the entire
cell area (i.e. basically anything other than wxGridCellTextEditor) in
the new DoPositionEditor() function.
Also use the cell and editor alignment to decide where to position the
control if it's smaller than the cell, as it looks better if e.g.
wxGridCellDateEditor appears near the place where the date is displayed
instead of being centered in the middle of a wide column.
It is necessary to do it since the switch to double buffering wxGrid
painting in ebbadae09a (Double buffer wxGridWindow drawing, 2020-01-28)
as even a "full cell" editor such as wxGridCellTextEditor still doesn't
fill the entire cell, as there are margins around it, and the backing
bitmap could keep whatever junk happened to be there if we didn't erase
it, so do erase it now.
Remove the code doing the same thing from ShowCellEditControl(),
however, as it's redundant and doesn't do anything except creating some
flicker, and also doesn't work on the platforms not supporting the use
of wxClientDC anyhow.
GetPaths/GetFilenames() must be used instead when more than one file
could be selected: document this and assert if the wrong functions are
called.
Closes https://github.com/wxWidgets/wxWidgets/pull/1883
This is another attempt to get rid of the flicker when using the native
header control with wxGrid under MSW and avoid calling UpdateColumn(),
which is currently implemented in a very inefficient way in wxHeaderCtrl
under MSW, during interactive resizing.
See #18794.
Clicking on (or near) the grid column or row edges was handled specially
to allow dragging them in order to resize the column or row, but this
doesn't need to be done if drag-resizing the columns or rows is not
allowed in the first place and resulted in surprising user-visible
behaviour: e.g. when using row selection, clicking mostly anywhere in
the row selected it, except if the click happened to be between the two
columns, in which case it didn't.
Fix this and always select the row in such scenario now.
Unfortunately, doing this required adding yet more CanDragXXX()
functions in addition to the already impressive panoply of them in
wxGrid, but we need CanDragGridColEdges() as none of the existing
functions checked for m_useNativeHeader (there was instead an ad hoc
check for it directly in the mouse handling code) and the row version
had to be added for symmetry.
Optimize wxGrid::AutoSizeColumns() for big grids.
This includes an optimization of wxDC::GetTextExtent() at the price of
slightly reduced precision in wxMSW.
See https://github.com/wxWidgets/wxWidgets/pull/1893
This allows to make computing the best width of numeric columns an O(1)
operation instead of O(number-of-rows), which can make a huge difference
for big grids.
Previously columns using a set of predetermined values used plain
wxGridCellStringRenderer, which didn't allow to determine their best
size efficiently, as wxGrid had to iterate over all the rows of the
table, even if they only took a couple of possible values.
Add wxGridCellChoiceRenderer (refactoring wxGridCellEnumRenderer to
extract the common code from it in the process) which implements
GetMaxBestSize() by just finding the best size of all of these values,
which is much faster for large grids.
This does result in a change in behaviour, as the column now adapts to
its "theoretical" best size and not just the size of the values actually
shown in it, but this seems to be a worthwhile trade-off and could even
be seen as an advantage, as editing a cell won't make its value overflow
the auto-sized column width any more, as it is wide enough to show any
of the column values.
This is another optimization, useful for the renderers that are used
with the values of a fixed form or part of a limited set, as it is much
faster to compute the best size for all values of the set rather than
computing them for all the cells in the column.
Get rid of the unnecessarily complicated functions doing two quite
different things depending on whether their first boolean parameter was
true of false.
Instead, split their body between AutoSize{Columns,Rows}() (which used
to call them) and DoGetBestSize(), keeping just the part needed in each
case.
This is much simpler and even more efficient, as it avoids a completely
unnecessary call to CalcDimensions() and Refresh() from DoGetBestSize(),
which doesn't change the current size at all and so doesn't need to
refresh anything, but previously did it and not only once, but twice,
because both of SetOrCalc{Column,Row}Sizes() did it.
These functions are much simpler to use in the application code using
wxGrid in row- or column-only selection mode than GetSelectedBlocks()
itself because they take care of deduplicating, ordering and squashing
together the adjacent ranges, so that the application can use their
results directly, unlike with GetSelectedBlocks().
For native wxGTK implementation default spin control precision is derived
from the precision of the increment value. Fot the sake of consistency the
same should be done in the generic implementation.
Closes#18764.
Enable warnings for CMake builds and fix some warnings that this
exposed.
Also add wxUSE_NATIVE_DATAVIEWCTRL option and change default GTK version
to 3 for CMake too.
See https://github.com/wxWidgets/wxWidgets/pull/1825
Deleting last grid rows or column in a few event handlers could result
in asserts/crashes in wxGrid code if the event handler also called
event.Skip(), as wxGrid still tried to perform the default action using
the deleted cell, when these events happened in the last row or column.
It's not totally clear whether calling event.Skip() after performing an
action modifying the grid should be allowed at all, but, in doubt, at
least avoid crashing if it does happen, by considering the event as
being handled (and even vetoed) if its handler deleted the cell in which
it was generated.
Closes#18731.
Move the logic determining the return value of SendEvent() into its own
function instead of repeating it twice.
No real changes, this is a pure refactoring.
This is more correct as saving the current width of the last column
would prevent the user from shrinking it under the last automatically
set size, i.e. the UI behaviour would change after restarting the
program, which shouldn't be the case.
Doing this required making WXGetManuallySetWidth(), which previously
existed in the generic version only, available in all ports, so do it
and also rename it to WXGetSpecifiedWidth() in the process, as this
seems a somewhat better name (it doesn't have to be manually specified,
i.e. it could also be done by the program itself or even implicitly by
wxPersistentDataViewCtrl).
Don't make this function public, at least for now, because it's not
clear how could it be useful and it might still need to be changed to
behave differently in the other ports.
This fix for disallowing shrinking the last column to nothing instead of
showing horizontal scrollbar when it became smaller than its minimum
size was wrong and is not necessary any more after the correct fix in
the previous commit.
This effectively reverts 0c90ea40c3 (Don't auto-resize wxDataViewCtrl
columns below their initial size, 2019-10-03).
See #18343.
Columns without any explicitly specified width still shouldn't be shrunk
down to 0 size by UpdateColumnSizes(), so handle them as if they were
created using wxDVC_DEFAULT_WIDTH instead -- which is what their actual
width is/would be.
This is a better fix than the one in 0c90ea40c3 (Don't auto-resize
wxDataViewCtrl columns below their initial size, 2019-10-03) and that
commit can be reverted now, as will be done soon.
See #18343.
These methods do the same thing, so it seems better to use the same name
for them.
This is not really a backwards-incompatible change, as these methods
were just added in the parent commit, so nobody is using them yet.
Completely overhauled selection handling in wxGrid.
Make various ways of extending selection (using Shift-arrow keys,
Ctrl-Shift-arrows, Shift-click etc) work as expected from the user point
of view instead of producing various bizarre results. Also improve
row/column header click selection as well as Ctrl/Shift-Space handling.
Internally, store selection as just a vector of blocks, independently of
the selection mode, and provide a simple API for iterating over it which
remains usable even with selections containing millions of cells (as
long as they're still composed of only a few blocks, which is the case
in practice).
Add more tests and add display of the current selection to the sample.
See https://github.com/wxWidgets/wxWidgets/pull/1772
Unselected current cell should always be considered as the current
selection block to extend, as it doesn't make sense to extend any other
block (perhaps selected on another side of the grid) when pressing
Shift-arrow.
This scenario could be achieved by selecting a block and Ctrl-clicking a
cell (either inside or outside the selection) twice and then extending
it using Shift-arrow keys. Previously, this behaved in a strange way,
combining the corner of the selected block with the target of the
movement, whereas now this just starts selecting a new block from the
current cell as expected.
Also make Page Up/Down themselves work consistently with the other
cursor movement keys and clear current selection if they move the
cursor.
Even though DoMoveCursorByPage() is simpler than DoMoveCursorByBlock(),
still factor out AdvanceByPage() for consistency with AdvanceByBlock()
and because it still makes the code more clear.
Extending the selection with Ctrl-arrows is different from all the other
cases, as we need to combine both the selection anchor and the current
cell coordinates when doing it.
This means that we can't reuse the same PrepareForSelectionExpansion()
helper for this case, so this function is not useful finally and this
commit removes it entirely. It also replaces GetCurrentBlockCornerRow()
and GetCurrentBlockCornerCol() functions with GetExtensionAnchor() which
combines both of them.
Finally, it adds wxGridDirectionOperations::TryToAdvance() helper to
avoid repeating the IsAtBoundary() check which was previously part of
PrepareForSelectionExpansion() in multiple places.
And because the "extending" and normal parts of DoMoveCursorByBlock()
are so different now, it also factors out AdvanceByBlock() helper which
can be used to keep these parts well separate from each other instead of
intermixing them together.
With all these preparatory changes, it's finally possible to implement
the "extending selection by block" logic relatively easily, with the
bulk of this branch actually taken by comments explaining why do we have
to do what we do.
Add unit tests verifying that the functions used by Shift-Ctrl-arrow
work as expected.
This function finally doesn't ever create a new block, except for the
trivial case when there is no current block, so rename it to a simpler
and more clear name.
No real changes.
This seems to be more consistent with the existing functions and doesn't
create ambiguity with a grid range.
Also rename wxGridSelectionRange to just wxGridBlocks as, in principle,
this class could be used for iterating over any blocks, not just the
selected ones.
No changes in functionality, this is just a renaming.
Extend the current block to the entire line when the corresponding
header is Shift-clicked and, importantly, keep the full-line selection
when using Shift-arrows later to make the selection behave in the
expected way.
This made the logic of this function unnecessarily more complicated.
Instead, just fall back to the current cell coordinates in the only
place where this could happen before.
Doing this still preserves the correct behaviour of Shift-arrow
selection when entire rows/columns are selected and the current cell is
not the leftmost/topmost cell (due to scrolling), but the code is
simpler.
Remove the now always true condition check and assert that it's indeed
always true.
Note that the changes to gridsel.cpp in this commit are best viewed
ignoring whitespace changes.
The difference between calling SelectAll() and SelectBlock() with a
block covering the entire grid is that the former discards any
previously selected blocks, which become clearly redundant.
As a consequence, clicking on the grid corner 10 times in a row still
results in a selection with a single block, not 10 (identical) blocks.
Expanding the selection from keyboard with Ctrl pressed should move in
the same way Ctrl-cursor does, but use the same selection anchor as
Shift-cursor does instead of always using the current cell.
This makes the expansion work much more intuitively in the grid, e.g.
pressing Shift-Ctrl-Down in
1 2
3 4
grid when 1 and 2 are selected now selects all the cells instead of
selecting 1 and 3 as it did before.
API of wxAnimationCtrlBase practically forces the derived classes to
have such method, so just add it and make GetAnimation() a simple
non-virtual accessor.
Simplify and streamline animation classes relationship: wxAnimation is
the only public class representing an animation and it can be created by
both the native wxAnimationCtrl and wxGenericAnimationCtrl using the new
public CreateAnimation() method.
Replace wxAnimationImplType enum with more flexible type info based
check.
This is just unnecessary and having wxAnimation::m_refData->m_refData is
confusing, both in wxGTK version where it's not used and in the generic
one where it is, but can be replaced by more type-safe m_decoder.