Merge branch 'grid-enhance'
Many enhancement to wxGrid UI: fix redraw and (some) flicker bugs; fix bugs with mouse handling; improve editors positioning etc. See https://github.com/wxWidgets/wxWidgets/pull/1902
This commit is contained in:
@@ -339,6 +339,16 @@ protected:
|
||||
// the dtor is private because only DecRef() can delete us
|
||||
virtual ~wxGridCellEditor();
|
||||
|
||||
// Helper for the derived classes positioning the control according to the
|
||||
// attribute alignment if the desired control size is smaller than the cell
|
||||
// size, or centering it vertically if its size is bigger: this looks like
|
||||
// the best compromise when the editor control doesn't fit into the cell.
|
||||
void DoPositionEditor(const wxSize& size,
|
||||
const wxRect& rectCell,
|
||||
int hAlign = wxALIGN_LEFT,
|
||||
int vAlign = wxALIGN_CENTRE_VERTICAL);
|
||||
|
||||
|
||||
// the actual window we show on screen (this variable should actually be
|
||||
// named m_window, but m_control is kept for backward compatibility)
|
||||
wxWindow* m_control;
|
||||
@@ -1675,7 +1685,27 @@ public:
|
||||
void DisableRowResize(int row) { DoDisableLineResize(row, m_setFixedRows); }
|
||||
void DisableColResize(int col) { DoDisableLineResize(col, m_setFixedCols); }
|
||||
|
||||
// these functions return whether the given row/column can be
|
||||
// These function return true if resizing rows/columns by dragging
|
||||
// their edges inside the grid is enabled. Note that this doesn't cover
|
||||
// dragging their separators in the label windows (which can be enabled
|
||||
// for the columns even if dragging inside the grid is not), nor checks
|
||||
// whether a particular row/column is resizeable or not, so you should
|
||||
// always check CanDrag{Row,Col}Size() below too.
|
||||
bool CanDragGridRowEdges() const
|
||||
{
|
||||
return m_canDragGridSize && m_canDragRowSize;
|
||||
}
|
||||
|
||||
bool CanDragGridColEdges() const
|
||||
{
|
||||
// When using the native header window we can only resize the columns by
|
||||
// dragging the dividers in the header itself, but not by dragging them
|
||||
// in the grid because we can't make the native control enter into the
|
||||
// column resizing mode programmatically.
|
||||
return m_canDragGridSize && m_canDragColSize && !m_useNativeHeader;
|
||||
}
|
||||
|
||||
// These functions return whether the given row/column can be
|
||||
// effectively resized: for this interactive resizing must be enabled
|
||||
// and this index must not have been passed to DisableRow/ColResize()
|
||||
bool CanDragRowSize(int row) const
|
||||
|
@@ -60,10 +60,6 @@ public:
|
||||
wxEvtHandler* evtHandler) wxOVERRIDE;
|
||||
virtual void SetSize(const wxRect& rect) wxOVERRIDE;
|
||||
|
||||
virtual void PaintBackground(wxDC& dc,
|
||||
const wxRect& rectCell,
|
||||
const wxGridCellAttr& attr) wxOVERRIDE;
|
||||
|
||||
virtual bool IsAcceptedKey(wxKeyEvent& event) wxOVERRIDE;
|
||||
virtual void BeginEdit(int row, int col, wxGrid* grid) wxOVERRIDE;
|
||||
virtual bool EndEdit(int row, int col, const wxGrid* grid,
|
||||
@@ -307,10 +303,6 @@ public:
|
||||
|
||||
virtual void SetSize(const wxRect& rect) wxOVERRIDE;
|
||||
|
||||
virtual void PaintBackground(wxDC& dc,
|
||||
const wxRect& rectCell,
|
||||
const wxGridCellAttr& attr) wxOVERRIDE;
|
||||
|
||||
virtual void BeginEdit(int row, int col, wxGrid* grid) wxOVERRIDE;
|
||||
virtual bool EndEdit(int row, int col, const wxGrid* grid,
|
||||
const wxString& oldval, wxString *newval) wxOVERRIDE;
|
||||
|
@@ -152,6 +152,14 @@ public:
|
||||
(owner->CanHideColumns() ? wxHD_ALLOW_HIDE : 0) |
|
||||
(owner->CanDragColMove() ? wxHD_ALLOW_REORDER : 0))
|
||||
{
|
||||
m_inResizing = 0;
|
||||
}
|
||||
|
||||
// Special method to call from wxGrid::DoSetColSize(), see comments there.
|
||||
void UpdateIfNotResizing(unsigned int idx)
|
||||
{
|
||||
if ( !m_inResizing )
|
||||
UpdateColumn(idx);
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -259,7 +267,20 @@ private:
|
||||
|
||||
void OnResizing(wxHeaderCtrlEvent& event)
|
||||
{
|
||||
// Calling wxGrid method results in a call to our own UpdateColumn()
|
||||
// because it ends up in wxGrid::SetColSize() which must indeed update
|
||||
// the column when it's called by the program -- but in the case where
|
||||
// the size change comes from the column itself, it is useless and, in
|
||||
// fact, harmful, as it results in extra flicker due to the inefficient
|
||||
// implementation of UpdateColumn() in wxMSW wxHeaderCtrl, so skip
|
||||
// calling it from our overridden version by setting this flag for the
|
||||
// duration of this function execution and checking it in our
|
||||
// UpdateIfNotResizing().
|
||||
m_inResizing++;
|
||||
|
||||
GetOwner()->DoHeaderDragResizeCol(event.GetWidth());
|
||||
|
||||
m_inResizing--;
|
||||
}
|
||||
|
||||
void OnEndResize(wxHeaderCtrlEvent& event)
|
||||
@@ -281,6 +302,9 @@ private:
|
||||
|
||||
wxVector<wxGridHeaderColumn> m_columns;
|
||||
|
||||
// The count of OnResizing() call nesting, 0 if not inside it.
|
||||
int m_inResizing;
|
||||
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
wxDECLARE_NO_COPY_CLASS(wxGridHeaderCtrl);
|
||||
};
|
||||
|
@@ -4322,6 +4322,26 @@ public:
|
||||
*/
|
||||
bool CanDragColSize(int col) const;
|
||||
|
||||
/**
|
||||
Return @true if column edges inside the grid can be dragged to resize
|
||||
the rows.
|
||||
|
||||
@see CanDragGridSize(), CanDragColSize()
|
||||
|
||||
@since 3.1.4
|
||||
*/
|
||||
bool CanDragGridColEdges() const;
|
||||
|
||||
/**
|
||||
Return @true if row edges inside the grid can be dragged to resize the
|
||||
rows.
|
||||
|
||||
@see CanDragGridSize(), CanDragRowSize()
|
||||
|
||||
@since 3.1.4
|
||||
*/
|
||||
bool CanDragGridRowEdges() const;
|
||||
|
||||
/**
|
||||
Return @true if the dragging of grid lines to resize rows and columns
|
||||
is enabled or @false otherwise.
|
||||
|
@@ -543,12 +543,14 @@ GridFrame::GridFrame()
|
||||
|
||||
// Some numeric columns with different formatting.
|
||||
grid->SetColFormatFloat(6);
|
||||
grid->SetReadOnly(0, 6);
|
||||
grid->SetCellValue(0, 6, "Default\nfloat format");
|
||||
grid->SetCellValue(1, 6, wxString::Format("%g", 3.1415));
|
||||
grid->SetCellValue(2, 6, wxString::Format("%g", 1415.0));
|
||||
grid->SetCellValue(3, 6, wxString::Format("%g", 12345.67890));
|
||||
|
||||
grid->SetColFormatFloat(7, 6, 2);
|
||||
grid->SetReadOnly(0, 7);
|
||||
grid->SetCellValue(0, 7, "Width 6\nprecision 2");
|
||||
grid->SetCellValue(1, 7, wxString::Format("%g", 3.1415));
|
||||
grid->SetCellValue(2, 7, wxString::Format("%g", 1415.0));
|
||||
@@ -556,22 +558,28 @@ GridFrame::GridFrame()
|
||||
|
||||
grid->SetColFormatCustom(8,
|
||||
wxString::Format("%s:%i,%i,%s", wxGRID_VALUE_FLOAT, -1, 4, "g"));
|
||||
grid->SetReadOnly(0, 8);
|
||||
grid->SetCellValue(0, 8, "Compact\nformat");
|
||||
grid->SetCellValue(1, 8, "31415e-4");
|
||||
grid->SetCellValue(2, 8, "1415");
|
||||
grid->SetCellValue(3, 8, "123456789e-4");
|
||||
|
||||
grid->SetColFormatNumber(9);
|
||||
grid->SetReadOnly(0, 9);
|
||||
grid->SetCellValue(0, 9, "Integer\ncolumn");
|
||||
grid->SetCellValue(1, 9, "17");
|
||||
grid->SetCellValue(2, 9, "0");
|
||||
grid->SetCellEditor(2, 9, new wxGridCellNumberEditor(0, 100));
|
||||
grid->SetCellValue(2, 10, "<- This cell uses [0, 100] range");
|
||||
grid->SetCellValue(3, 9, "-666");
|
||||
grid->SetCellAlignment(3, 9, wxALIGN_CENTRE, wxALIGN_TOP);
|
||||
grid->SetCellValue(3, 10, "<- This numeric cell should be centred");
|
||||
|
||||
grid->SetReadOnly(0, 13);
|
||||
grid->SetCellValue(0, 13, "Localized date\ncolumn");
|
||||
grid->SetColFormatDate(13); // Localized by default.
|
||||
grid->SetCellValue(1, 13, "Today");
|
||||
grid->SetReadOnly(0, 14);
|
||||
grid->SetCellValue(0, 14, "ISO 8601 date\ncolumn");
|
||||
grid->SetColFormatDate(14, "%Y-%m-%d"); // ISO 8601 date format.
|
||||
grid->SetCellValue(1, 14, "Tomorrow");
|
||||
|
@@ -3015,22 +3015,17 @@ void wxGrid::CalcDimensions()
|
||||
// take into account editor if shown
|
||||
if ( IsCellEditControlShown() )
|
||||
{
|
||||
int w2, h2;
|
||||
int r = m_currentCellCoords.GetRow();
|
||||
int c = m_currentCellCoords.GetCol();
|
||||
int x = GetColLeft(c);
|
||||
int y = GetRowTop(r);
|
||||
|
||||
// how big is the editor
|
||||
wxGridCellAttrPtr attr = GetCellAttrPtr(r, c);
|
||||
wxGridCellEditorPtr editor = attr->GetEditorPtr(this, r, c);
|
||||
editor->GetWindow()->GetSize(&w2, &h2);
|
||||
w2 += x;
|
||||
h2 += y;
|
||||
if ( w2 > w )
|
||||
w = w2;
|
||||
if ( h2 > h )
|
||||
h = h2;
|
||||
const wxRect rect = editor->GetWindow()->GetRect();
|
||||
if ( rect.GetRight() > w )
|
||||
w = rect.GetRight();
|
||||
if ( rect.GetBottom() > h )
|
||||
h = rect.GetBottom();
|
||||
}
|
||||
|
||||
wxPoint offset = GetGridWindowOffset(m_gridWin);
|
||||
@@ -4577,8 +4572,20 @@ wxGrid::DoGridCellLeftDown(wxMouseEvent& event,
|
||||
MakeCellVisible(coords);
|
||||
}
|
||||
}
|
||||
else if ( XToEdgeOfCol(pos.x) < 0 && YToEdgeOfRow(pos.y) < 0 )
|
||||
else
|
||||
{
|
||||
// Clicking on (or very near) the separating lines shouldn't change the
|
||||
// selection when it's used for resizing -- but should still do it if
|
||||
// resizing is disabled (notice that we intentionally don't check for
|
||||
// it being disabled for a particular row/column as it would be
|
||||
// surprising to have different mouse behaviour in different parts of
|
||||
// the same grid, so we only check for it being globally disabled).
|
||||
if ( CanDragGridColEdges() && XToEdgeOfCol(pos.x) != wxNOT_FOUND )
|
||||
return;
|
||||
|
||||
if ( CanDragGridRowEdges() && YToEdgeOfRow(pos.y) != wxNOT_FOUND )
|
||||
return;
|
||||
|
||||
DisableCellEditControl();
|
||||
MakeCellVisible( coords );
|
||||
|
||||
@@ -4709,28 +4716,10 @@ wxGrid::DoGridMouseMoveEvent(wxMouseEvent& WXUNUSED(event),
|
||||
int dragRow = YToEdgeOfRow( pos.y );
|
||||
int dragCol = XToEdgeOfCol( pos.x );
|
||||
|
||||
// Dragging on the corner of a cell to resize in both
|
||||
// directions is not implemented yet...
|
||||
//
|
||||
if ( dragRow >= 0 && dragCol >= 0 )
|
||||
{
|
||||
ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, gridWindow, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( dragRow >= 0 && CanDragGridSize() && CanDragRowSize(dragRow) )
|
||||
{
|
||||
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
|
||||
{
|
||||
DoStartResizeRowOrCol(dragRow);
|
||||
ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, gridWindow, false);
|
||||
}
|
||||
}
|
||||
// When using the native header window we can only resize the columns by
|
||||
// dragging the dividers in it because we can't make it enter into the
|
||||
// column resizing mode programmatically
|
||||
else if ( dragCol >= 0 && !m_useNativeHeader &&
|
||||
CanDragGridSize() && CanDragColSize(dragCol) )
|
||||
// Dragging on the corner of a cell to resize in both directions is not
|
||||
// implemented, so choose to resize the column when the cursor is over the
|
||||
// cell corner, as this is a more common operation.
|
||||
if ( dragCol >= 0 && CanDragGridColEdges() && CanDragColSize(dragCol) )
|
||||
{
|
||||
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
|
||||
{
|
||||
@@ -4738,6 +4727,14 @@ wxGrid::DoGridMouseMoveEvent(wxMouseEvent& WXUNUSED(event),
|
||||
ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, gridWindow, false);
|
||||
}
|
||||
}
|
||||
else if ( dragRow >= 0 && CanDragGridRowEdges() && CanDragRowSize(dragRow) )
|
||||
{
|
||||
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
|
||||
{
|
||||
DoStartResizeRowOrCol(dragRow);
|
||||
ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, gridWindow, false);
|
||||
}
|
||||
}
|
||||
else // Neither on a row or col edge
|
||||
{
|
||||
if ( m_cursorMode != WXGRID_CURSOR_SELECT_CELL )
|
||||
@@ -7262,24 +7259,11 @@ void wxGrid::ShowCellEditControl()
|
||||
m_currentCellCoords.SetCol( col );
|
||||
}
|
||||
|
||||
// erase the highlight and the cell contents because the editor
|
||||
// might not cover the entire cell
|
||||
wxClientDC dc( gridWindow );
|
||||
PrepareDCFor(dc, gridWindow);
|
||||
wxGridCellAttrPtr attr = GetCellAttrPtr(row, col);
|
||||
dc.SetBrush(wxBrush(attr->GetBackgroundColour()));
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
dc.DrawRectangle(rect);
|
||||
|
||||
rect.Offset(-GetGridWindowOffset(gridWindow));
|
||||
|
||||
// convert to scrolled coords
|
||||
CalcGridWindowScrolledPosition( rect.x, rect.y, &rect.x, &rect.y, gridWindow );
|
||||
|
||||
int nXMove = 0;
|
||||
if (rect.x < 0)
|
||||
nXMove = rect.x;
|
||||
|
||||
#ifdef __WXQT__
|
||||
// Substract 1 pixel in every dimension to fit in the cell area.
|
||||
// If not, Qt will draw the control outside the cell.
|
||||
@@ -7287,6 +7271,7 @@ void wxGrid::ShowCellEditControl()
|
||||
rect.Deflate(1, 1);
|
||||
#endif
|
||||
|
||||
wxGridCellAttrPtr attr = GetCellAttrPtr(row, col);
|
||||
wxGridCellEditorPtr editor = attr->GetEditorPtr(this, row, col);
|
||||
if ( !editor->IsCreated() )
|
||||
{
|
||||
@@ -7328,10 +7313,6 @@ void wxGrid::ShowCellEditControl()
|
||||
maxWidth = rect.width;
|
||||
}
|
||||
|
||||
int client_right = gridWindow->GetClientSize().GetWidth();
|
||||
if (rect.x + maxWidth > client_right)
|
||||
maxWidth = client_right - rect.x;
|
||||
|
||||
if ((maxWidth > rect.width) && (col < m_numCols) && m_table)
|
||||
{
|
||||
GetCellSize( row, col, &cell_rows, &cell_cols );
|
||||
@@ -7350,17 +7331,35 @@ void wxGrid::ShowCellEditControl()
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (rect.GetRight() > client_right)
|
||||
rect.SetRight( client_right - 1 );
|
||||
}
|
||||
|
||||
editor->SetCellAttr( attr.get() );
|
||||
editor->SetSize( rect );
|
||||
if (nXMove != 0)
|
||||
editor->GetWindow()->Move(
|
||||
editor->GetWindow()->GetPosition().x + nXMove,
|
||||
editor->GetWindow()->GetPosition().y );
|
||||
|
||||
// Note that the actual rectangle used by the editor could be
|
||||
// different from the one we proposed.
|
||||
rect = editor->GetWindow()->GetRect();
|
||||
|
||||
// Ensure that the edit control fits into the visible part of the
|
||||
// window by shifting it if necessary: we don't want to truncate
|
||||
// any part of it by trying to position it too far to the left or
|
||||
// top and we definitely don't want to start showing scrollbars by
|
||||
// positioning it too far to the right or bottom.
|
||||
const wxSize sizeMax = gridWindow->GetClientSize();
|
||||
if ( !wxRect(sizeMax).Contains(rect) )
|
||||
{
|
||||
if ( rect.x < 0 )
|
||||
rect.x = 0;
|
||||
if ( rect.y < 0 )
|
||||
rect.y = 0;
|
||||
if ( rect.x > sizeMax.x - rect.width )
|
||||
rect.x = sizeMax.x - rect.width;
|
||||
if ( rect.y > sizeMax.y - rect.height )
|
||||
rect.y = sizeMax.y - rect.height;
|
||||
|
||||
editor->GetWindow()->Move(rect.x, rect.y);
|
||||
}
|
||||
|
||||
editor->Show( true, attr.get() );
|
||||
|
||||
// recalc dimensions in case we need to
|
||||
@@ -9757,7 +9756,16 @@ void wxGrid::DoSetColSize( int col, int width )
|
||||
return;
|
||||
|
||||
if ( m_useNativeHeader )
|
||||
GetGridColHeader()->UpdateColumn(col);
|
||||
{
|
||||
// We have to update the native control if we're called from the
|
||||
// program (directly or indirectly, e.g. via AutoSizeColumn()), but we
|
||||
// want to avoid doing it when the column is being resized
|
||||
// interactively, as this is unnecessary and results in very visible
|
||||
// flicker, so take care to call the special method of our header
|
||||
// control checking for whether it's being resized interactively
|
||||
// instead of the usual UpdateColumn().
|
||||
static_cast<wxGridHeaderCtrl*>(m_colLabelWin)->UpdateIfNotResizing(col);
|
||||
}
|
||||
//else: will be refreshed when the header is redrawn
|
||||
|
||||
for ( int colPos = GetColPos(col); colPos < m_numCols; colPos++ )
|
||||
@@ -9836,7 +9844,10 @@ void wxGrid::DoSetColSize( int col, int width )
|
||||
|
||||
FurtherWindowPartRefresher refreshFurtherPart(x);
|
||||
|
||||
refreshFurtherPart(m_colLabelWin);
|
||||
// Refreshing the native header is unnecessary, as it updates
|
||||
// itself correctly anyhow, and just results in extra flicker.
|
||||
if ( !IsUsingNativeHeader() )
|
||||
refreshFurtherPart(m_colLabelWin);
|
||||
refreshFurtherPart(m_gridWin);
|
||||
|
||||
if ( m_frozenRowGridWin )
|
||||
|
@@ -331,6 +331,62 @@ void wxGridCellEditor::SetSize(const wxRect& rect)
|
||||
m_control->SetSize(rect, wxSIZE_ALLOW_MINUS_ONE);
|
||||
}
|
||||
|
||||
void wxGridCellEditor::DoPositionEditor(const wxSize& size,
|
||||
const wxRect& rectCell,
|
||||
int hAlign,
|
||||
int vAlign)
|
||||
{
|
||||
wxRect rect(rectCell.GetPosition(), size);
|
||||
|
||||
// We center the control around the cell if it doesn't fit into it in one
|
||||
// or both of directions, as this seems to look the best (difference is
|
||||
// typically relatively small and by centering it, we divide it by two on
|
||||
// each side, making it even smaller).
|
||||
//
|
||||
// For now just remember in which direction to do it in this variable and
|
||||
// then do it at the end.
|
||||
int centerDir = 0;
|
||||
|
||||
// We're only going to need the alignment if the control is smaller than
|
||||
// the cell in at least one direction.
|
||||
if ( size.x < rectCell.width || size.y < rectCell.height )
|
||||
{
|
||||
if ( GetCellAttr() )
|
||||
GetCellAttr()->GetNonDefaultAlignment(&hAlign, &vAlign);
|
||||
}
|
||||
|
||||
if ( size.x < rectCell.width )
|
||||
{
|
||||
if ( hAlign == wxALIGN_CENTER_HORIZONTAL )
|
||||
centerDir |= wxHORIZONTAL;
|
||||
else if ( hAlign == wxALIGN_RIGHT )
|
||||
rect.x = rectCell.x + rectCell.width - rect.width;
|
||||
//else: nothing to do for the left alignment
|
||||
}
|
||||
else
|
||||
{
|
||||
centerDir |= wxHORIZONTAL;
|
||||
}
|
||||
|
||||
if ( size.y < rectCell.height )
|
||||
{
|
||||
if ( vAlign == wxALIGN_CENTRE_VERTICAL )
|
||||
centerDir |= wxVERTICAL;
|
||||
else if ( vAlign == wxALIGN_BOTTOM )
|
||||
rect.y = rectCell.y + rectCell.height - rect.height;
|
||||
//else: nothing to do for the top alignment
|
||||
}
|
||||
else
|
||||
{
|
||||
centerDir |= wxVERTICAL;
|
||||
}
|
||||
|
||||
if ( centerDir )
|
||||
rect = rect.CenterIn(rectCell, centerDir);
|
||||
|
||||
wxGridCellEditor::SetSize(rect);
|
||||
}
|
||||
|
||||
void wxGridCellEditor::HandleReturn(wxKeyEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
@@ -426,14 +482,6 @@ void wxGridCellTextEditor::DoCreate(wxWindow* parent,
|
||||
wxGridCellEditor::Create(parent, id, evtHandler);
|
||||
}
|
||||
|
||||
void wxGridCellTextEditor::PaintBackground(wxDC& WXUNUSED(dc),
|
||||
const wxRect& WXUNUSED(rectCell),
|
||||
const wxGridCellAttr& WXUNUSED(attr))
|
||||
{
|
||||
// as we fill the entire client area,
|
||||
// don't do anything here to minimize flicker
|
||||
}
|
||||
|
||||
void wxGridCellTextEditor::SetSize(const wxRect& rectOrig)
|
||||
{
|
||||
wxRect rect(rectOrig);
|
||||
@@ -703,22 +751,7 @@ void wxGridCellNumberEditor::SetSize(const wxRect& rectCell)
|
||||
if ( size.y <= 0 )
|
||||
size.y = rectCell.GetHeight();
|
||||
|
||||
wxRect rectSpin(rectCell.GetPosition(), size);
|
||||
|
||||
// If possible, i.e. if we're not editing the topmost or leftmost cell,
|
||||
// center the control rectangle in the cell.
|
||||
if ( rectCell.GetTop() > 0 )
|
||||
{
|
||||
rectSpin.SetTop(rectCell.GetTop() -
|
||||
(rectSpin.GetHeight() - rectCell.GetHeight()) / 2);
|
||||
}
|
||||
if ( rectCell.GetLeft() > 0 )
|
||||
{
|
||||
rectSpin.SetLeft(rectCell.GetLeft() -
|
||||
(rectSpin.GetWidth() - rectCell.GetWidth()) / 2);
|
||||
}
|
||||
|
||||
wxGridCellEditor::SetSize(rectSpin);
|
||||
DoPositionEditor(size, rectCell);
|
||||
}
|
||||
else
|
||||
#endif // wxUSE_SPINCTRL
|
||||
@@ -836,10 +869,19 @@ bool wxGridCellNumberEditor::IsAcceptedKey(wxKeyEvent& event)
|
||||
if ( wxGridCellEditor::IsAcceptedKey(event) )
|
||||
{
|
||||
int keycode = event.GetKeyCode();
|
||||
if ( (keycode < 128) &&
|
||||
(wxIsdigit(keycode) || keycode == '+' || keycode == '-'))
|
||||
switch ( keycode )
|
||||
{
|
||||
return true;
|
||||
// Accept +/- because they can be part of the number and space just
|
||||
// because it's a convenient key to start editing with and is also
|
||||
// consistent with many (all?) other editors, which allow starting
|
||||
// editing using it.
|
||||
case '+':
|
||||
case '-':
|
||||
case ' ':
|
||||
return true;
|
||||
|
||||
default:
|
||||
return (keycode < 128) && wxIsdigit(keycode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1451,25 +1493,14 @@ void wxGridCellChoiceEditor::SetSize(const wxRect& rect)
|
||||
wxASSERT_MSG(m_control,
|
||||
wxT("The wxGridCellChoiceEditor must be created first!"));
|
||||
|
||||
// Check that the rectangle is big enough to fit the combobox, we can't
|
||||
// afford truncating it.
|
||||
wxSize size = rect.GetSize();
|
||||
size.IncTo(m_control->GetBestSize());
|
||||
// Use normal wxChoice size, except for extending it to fill the cell
|
||||
// width: we can't be smaller because this could make the control unusable
|
||||
// and we don't want to be taller because this looks unusual and weird.
|
||||
wxSize size = m_control->GetBestSize();
|
||||
if ( size.x < rect.width )
|
||||
size.x = rect.width;
|
||||
|
||||
wxGridCellEditor::SetSize(wxRect(size).CentreIn(rect));
|
||||
}
|
||||
|
||||
void wxGridCellChoiceEditor::PaintBackground(wxDC& dc,
|
||||
const wxRect& rectCell,
|
||||
const wxGridCellAttr& attr)
|
||||
{
|
||||
// as we fill the entire client area, don't do anything here to minimize
|
||||
// flicker
|
||||
|
||||
// TODO: It doesn't actually fill the client area since the height of a
|
||||
// combo always defaults to the standard. Until someone has time to
|
||||
// figure out the right rectangle to paint, just do it the normal way.
|
||||
wxGridCellEditor::PaintBackground(dc, rectCell, attr);
|
||||
DoPositionEditor(size, rect);
|
||||
}
|
||||
|
||||
void wxGridCellChoiceEditor::BeginEdit(int row, int col, wxGrid* grid)
|
||||
@@ -1780,18 +1811,18 @@ void wxGridCellDateEditor::SetSize(const wxRect& r)
|
||||
{
|
||||
wxASSERT_MSG(m_control, "The wxGridCellDateEditor must be created first!");
|
||||
|
||||
const wxSize bestSize = DatePicker()->GetBestSize();
|
||||
wxSize size = DatePicker()->GetBestSize();
|
||||
|
||||
wxRect rect(r.GetPosition(), bestSize);
|
||||
|
||||
// Allow edit picker to become a bit wider, if necessary, but no more than
|
||||
// twice as wide as the best width, otherwise they just look ugly.
|
||||
if ( r.GetWidth() > bestSize.GetWidth() )
|
||||
// Allow date picker to become a bit wider, if necessary, but not too wide,
|
||||
// otherwise it just looks ugly.
|
||||
if ( r.GetWidth() > size.GetWidth()
|
||||
&& r.GetWidth() < 3*size.GetWidth()/2 )
|
||||
{
|
||||
rect.SetWidth(wxMin(r.GetWidth(), 2*bestSize.GetWidth()));
|
||||
size.x = r.GetWidth();
|
||||
}
|
||||
|
||||
wxGridCellEditor::SetSize(rect);
|
||||
// Use right alignment by default for consistency with the date renderer.
|
||||
DoPositionEditor(size, r, wxALIGN_RIGHT);
|
||||
}
|
||||
|
||||
void wxGridCellDateEditor::BeginEdit(int row, int col, wxGrid* grid)
|
||||
|
@@ -290,6 +290,22 @@ WXLRESULT wxTopLevelWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WX
|
||||
|
||||
DoRestoreLastFocus();
|
||||
}
|
||||
else if ( id == SC_KEYMENU )
|
||||
{
|
||||
// Alt-Backspace is understood as an accelerator for "Undo"
|
||||
// by the native EDIT control, but pressing it results in a
|
||||
// beep by default when the resulting SC_KEYMENU is handled
|
||||
// by DefWindowProc(), so pretend to handle it ourselves if
|
||||
// we're editing a text control to avoid the annoying beep.
|
||||
if ( lParam == VK_BACK )
|
||||
{
|
||||
if ( wxWindow* const focus = FindFocus() )
|
||||
{
|
||||
if ( focus->WXGetTextEntry() )
|
||||
processed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __WXUNIVERSAL__
|
||||
// We need to generate events for the custom items added to the
|
||||
|
Reference in New Issue
Block a user