Merge branch 'grid-hidpi'

wxGrid improvements for high DPI and DPI changes

See https://github.com/wxWidgets/wxWidgets/pull/1776
This commit is contained in:
Vadim Zeitlin
2020-04-04 18:46:54 +02:00
5 changed files with 133 additions and 51 deletions

View File

@@ -25,8 +25,8 @@
extern WXDLLIMPEXP_DATA_CORE(const char) wxGridNameStr[];
// Default parameters for wxGrid
//
// Obsolete constants not used by wxWidgets itself any longer, preserved only
// for compatibility.
#define WXGRID_DEFAULT_NUMBER_ROWS 10
#define WXGRID_DEFAULT_NUMBER_COLS 10
#if defined(__WXMSW__) || defined(__WXGTK20__)
@@ -34,13 +34,18 @@ extern WXDLLIMPEXP_DATA_CORE(const char) wxGridNameStr[];
#else
#define WXGRID_DEFAULT_ROW_HEIGHT 30
#endif // __WXMSW__
#define WXGRID_DEFAULT_SCROLLBAR_WIDTH 16
// Various constants used in wxGrid code.
//
// Note that all the values are in DIPs, not pixels, i.e. you must use
// FromDIP() when using them in your code.
#define WXGRID_DEFAULT_COL_WIDTH 80
#define WXGRID_DEFAULT_COL_LABEL_HEIGHT 32
#define WXGRID_DEFAULT_ROW_LABEL_WIDTH 82
#define WXGRID_LABEL_EDGE_ZONE 2
#define WXGRID_MIN_ROW_HEIGHT 15
#define WXGRID_MIN_COL_WIDTH 15
#define WXGRID_DEFAULT_SCROLLBAR_WIDTH 16
// type names for grid table values
#define wxGRID_VALUE_STRING wxT("string")
@@ -1372,9 +1377,9 @@ public:
// ------ label and gridline formatting
//
int GetDefaultRowLabelSize() const { return WXGRID_DEFAULT_ROW_LABEL_WIDTH; }
int GetDefaultRowLabelSize() const { return FromDIP(WXGRID_DEFAULT_ROW_LABEL_WIDTH); }
int GetRowLabelSize() const { return m_rowLabelWidth; }
int GetDefaultColLabelSize() const { return WXGRID_DEFAULT_COL_LABEL_HEIGHT; }
int GetDefaultColLabelSize() const { return FromDIP(WXGRID_DEFAULT_COL_LABEL_HEIGHT); }
int GetColLabelSize() const { return m_colLabelHeight; }
wxColour GetLabelBackgroundColour() const { return m_labelBackgroundColour; }
wxColour GetLabelTextColour() const { return m_labelTextColour; }
@@ -2410,6 +2415,13 @@ protected:
friend class wxGridHeaderCtrl;
private:
// This is called from both Create() and OnDPIChanged() to (re)initialize
// the values in pixels, which depend on the current DPI.
void InitPixelFields();
// Event handler for DPI change event recomputes pixel values and relays
// out the grid.
void OnDPIChanged(wxDPIChangedEvent& event);
// implement wxScrolledCanvas method to return m_gridWin size
virtual wxSize GetSizeAvailableForScrollTarget(const wxSize& size) wxOVERRIDE;

View File

@@ -143,9 +143,6 @@ public:
virtual wxGridCellRenderer *Clone() const wxOVERRIDE
{ return new wxGridCellBoolRenderer; }
private:
static wxSize ms_sizeCheckMark;
};

View File

@@ -432,18 +432,15 @@ GridFrame::GridFrame()
grid = new wxGrid( this,
wxID_ANY,
wxPoint( 0, 0 ),
wxSize( 400, 300 ) );
FromDIP(wxSize( 400, 300 )) );
#if wxUSE_LOG
int gridW = 600, gridH = 300;
int logW = gridW, logH = 100;
logWin = new wxTextCtrl( this,
wxID_ANY,
wxEmptyString,
wxPoint( 0, gridH + 20 ),
wxSize( logW, logH ),
wxDefaultPosition,
wxDefaultSize,
wxTE_MULTILINE );
logger = new wxLogTextCtrl( logWin );
@@ -464,7 +461,7 @@ GridFrame::GridFrame()
grid->DeleteRows(0, ir);
grid->AppendRows(ir);
grid->SetRowSize( 0, 60 );
grid->SetRowSize( 0, 4*grid->GetDefaultRowSize() );
grid->SetCellValue( 0, 0, "Ctrl+Home\nwill go to\nthis cell" );
grid->SetCellValue( 0, 1, "A long piece of text to demonstrate wrapping." );
@@ -477,7 +474,7 @@ GridFrame::GridFrame()
grid->SetCellValue( 0, 4, "Can veto edit this cell" );
grid->SetColSize(10, 150);
grid->SetColSize(10, FromDIP(150));
wxString longtext = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\n\n";
longtext += "With tabs :\n";
longtext += "Home,\t\thome\t\t\tagain\n";
@@ -494,7 +491,7 @@ GridFrame::GridFrame()
grid->SetCellValue( 0, 5, "Press\nCtrl+arrow\nto skip over\ncells" );
grid->SetRowSize( 99, 60 );
grid->SetRowSize( 99, 4*grid->GetDefaultRowSize() );
grid->SetCellValue(98, 98, "Test background colour setting");
grid->SetCellBackgroundColour(98, 99, wxColour(255, 127, 127));
grid->SetCellBackgroundColour(99, 98, wxColour(255, 127, 127));
@@ -537,8 +534,8 @@ GridFrame::GridFrame()
grid->SetRowAttr(5, attr);
grid->SetCellValue(2, 4, "a wider column");
grid->SetColSize(4, 120);
grid->SetColMinimalWidth(4, 120);
grid->SetColSize(4, 3*grid->GetDefaultColLabelSize()/2);
grid->SetColMinimalWidth(4, grid->GetColSize(4));
grid->SetCellTextColour(5, 8, *wxGREEN);
grid->SetCellValue(5, 8, "Bg from row attr\nText col from cell attr");
@@ -611,7 +608,7 @@ GridFrame::GridFrame()
// create a separator-like row: it's grey and it's non-resizable
grid->DisableRowResize(10);
grid->SetRowSize(10, 30);
grid->SetRowSize(10, 3*grid->GetDefaultRowSize()/2);
attr = new wxGridCellAttr;
attr->SetBackgroundColour(*wxLIGHT_GREY);
attr->SetAlignment(wxALIGN_INVALID, wxALIGN_CENTRE);
@@ -1669,8 +1666,7 @@ void MyGridCellRenderer::Draw(wxGrid& grid,
// ============================================================================
BigGridFrame::BigGridFrame(long sizeGrid)
: wxFrame(NULL, wxID_ANY, "Plugin Virtual Table",
wxDefaultPosition, wxSize(500, 450))
: wxFrame(NULL, wxID_ANY, "Plugin Virtual Table")
{
m_grid = new wxGrid(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
m_table = new BigGridTable(sizeGrid);
@@ -1681,12 +1677,7 @@ BigGridFrame::BigGridFrame(long sizeGrid)
m_grid->AssignTable(m_table);
#if defined __WXMOTIF__
// MB: the grid isn't getting a sensible default size under wxMotif
int cw, ch;
GetClientSize( &cw, &ch );
m_grid->SetSize( cw, ch );
#endif
SetClientSize(FromDIP(wxSize(500, 450)));
}
// ============================================================================
@@ -2363,7 +2354,7 @@ TabularGridFrame::TabularGridFrame()
sizerStyles->Add(m_chkEnableColMove, wxSizerFlags().Border());
sizerControls->Add(sizerStyles);
sizerControls->AddSpacer(10);
sizerControls->AddSpacer(FromDIP(10));
wxSizer * const sizerColumns = new wxBoxSizer(wxVERTICAL);
wxSizer * const sizerMoveCols = new wxBoxSizer(wxHORIZONTAL);

View File

@@ -2325,6 +2325,7 @@ void wxGridWindow::OnFocus(wxFocusEvent& event)
wxBEGIN_EVENT_TABLE( wxGrid, wxScrolledCanvas )
EVT_SIZE( wxGrid::OnSize )
EVT_DPI_CHANGED( wxGrid::OnDPIChanged )
EVT_KEY_DOWN( wxGrid::OnKeyDown )
EVT_KEY_UP( wxGrid::OnKeyUp )
EVT_CHAR ( wxGrid::OnChar )
@@ -2465,8 +2466,11 @@ void wxGrid::Create()
m_labelBackgroundColour = m_rowLabelWin->GetBackgroundColour();
m_labelTextColour = m_rowLabelWin->GetForegroundColour();
// now that we have the grid window, use its font to compute the default
// row height
InitPixelFields();
}
void wxGrid::InitPixelFields()
{
m_defaultRowHeight = m_gridWin->GetCharHeight();
#if defined(__WXMOTIF__) || defined(__WXGTK__) || defined(__WXQT__) // see also text ctrl sizing in ShowCellEditControl()
m_defaultRowHeight += 8;
@@ -2474,6 +2478,13 @@ void wxGrid::Create()
m_defaultRowHeight += 4;
#endif
m_rowLabelWidth = FromDIP(WXGRID_DEFAULT_ROW_LABEL_WIDTH);
m_colLabelHeight = FromDIP(WXGRID_DEFAULT_COL_LABEL_HEIGHT);
m_defaultColWidth = FromDIP(WXGRID_DEFAULT_COL_WIDTH);
m_minAcceptableColWidth = FromDIP(WXGRID_MIN_COL_WIDTH);
m_minAcceptableRowHeight = FromDIP(WXGRID_MIN_ROW_HEIGHT);
}
void wxGrid::CreateColumnWindow()
@@ -2486,7 +2497,7 @@ void wxGrid::CreateColumnWindow()
else // draw labels ourselves
{
m_colLabelWin = new wxGridColLabelWindow(this);
m_colLabelHeight = WXGRID_DEFAULT_COL_LABEL_HEIGHT;
m_colLabelHeight = FromDIP(WXGRID_DEFAULT_COL_LABEL_HEIGHT);
}
}
@@ -2638,9 +2649,6 @@ void wxGrid::Init()
m_defaultCellAttr = NULL;
m_typeRegistry = NULL;
m_rowLabelWidth = WXGRID_DEFAULT_ROW_LABEL_WIDTH;
m_colLabelHeight = WXGRID_DEFAULT_COL_LABEL_HEIGHT;
m_setFixedRows =
m_setFixedCols = NULL;
@@ -2663,11 +2671,15 @@ void wxGrid::Init()
m_cornerLabelVertAlign = wxALIGN_CENTRE;
m_cornerLabelTextOrientation = wxHORIZONTAL;
m_defaultColWidth = WXGRID_DEFAULT_COL_WIDTH;
m_defaultRowHeight = 0; // this will be initialized after creation
// All these fields require a valid window, so are initialized in Create().
m_rowLabelWidth =
m_colLabelHeight = 0;
m_minAcceptableColWidth = WXGRID_MIN_COL_WIDTH;
m_minAcceptableRowHeight = WXGRID_MIN_ROW_HEIGHT;
m_defaultColWidth =
m_defaultRowHeight = 0;
m_minAcceptableColWidth =
m_minAcceptableRowHeight = 0;
m_gridLineColour = wxColour( 192,192,192 );
m_gridLinesEnabled = true;
@@ -5346,6 +5358,72 @@ void wxGrid::OnSize(wxSizeEvent& WXUNUSED(event))
}
}
void wxGrid::OnDPIChanged(wxDPIChangedEvent& event)
{
InitPixelFields();
// If we have any non-default row sizes, we need to scale them (default
// ones will be scaled due to the reinitialization of m_defaultRowHeight
// inside InitPixelFields() above).
if ( !m_rowHeights.empty() )
{
int total = 0;
for ( unsigned i = 0; i < m_rowHeights.size(); ++i )
{
int height = m_rowHeights[i];
// Skip hidden rows.
if ( height <= 0 )
continue;
height = height * event.GetNewDPI().x / event.GetOldDPI().x;
total += height;
m_rowHeights[i] = height;
m_rowBottoms[i] = total;
}
}
// Similarly for columns, except that here we need to update the native
// control even if none of the widths had been changed, as it's not going
// to do it on its own when redisplayed.
wxHeaderCtrl* const
colHeader = m_useNativeHeader ? GetGridColHeader() : NULL;
if ( !m_colWidths.empty() )
{
int total = 0;
for ( unsigned i = 0; i < m_colWidths.size(); ++i )
{
int width = m_colWidths[i];
if ( width <= 0 )
continue;
width = width * event.GetNewDPI().x / event.GetOldDPI().x;
total += width;
m_colWidths[i] = width;
m_colRights[i] = total;
if ( colHeader )
colHeader->UpdateColumn(i);
}
}
else if ( colHeader )
{
for ( int i = 0; i < m_numCols; ++i )
{
colHeader->UpdateColumn(i);
}
}
InvalidateBestSize();
CalcDimensions();
event.Skip();
}
void wxGrid::OnKeyDown( wxKeyEvent& event )
{
if ( m_inOnKeyDown )
@@ -7330,15 +7408,15 @@ int wxGrid::PosToEdgeOfLine(int pos, const wxGridOperations& oper) const
if ( line == wxNOT_FOUND )
return -1;
if ( oper.GetLineSize(this, line) > WXGRID_LABEL_EDGE_ZONE )
const int edge = FromDIP(WXGRID_LABEL_EDGE_ZONE);
if ( oper.GetLineSize(this, line) > edge )
{
// We know that we are in this line, test whether we are close enough
// to start or end border, respectively.
if ( abs(oper.GetLineEndPos(this, line) - pos) < WXGRID_LABEL_EDGE_ZONE )
if ( abs(oper.GetLineEndPos(this, line) - pos) < edge )
return line;
else if ( line > 0 &&
pos - oper.GetLineStartPos(this,
line) < WXGRID_LABEL_EDGE_ZONE )
else if ( line > 0 && pos - oper.GetLineStartPos(this, line) < edge )
{
// We need to find the previous visible line, so skip all the
// hidden (of size 0) ones.

View File

@@ -32,6 +32,7 @@
#include "wx/renderer.h"
#include "wx/generic/private/grid.h"
#include "wx/private/window.h"
// ----------------------------------------------------------------------------
// wxGridCellRenderer
@@ -920,22 +921,25 @@ void wxGridCellFloatRenderer::SetParameters(const wxString& params)
// wxGridCellBoolRenderer
// ----------------------------------------------------------------------------
wxSize wxGridCellBoolRenderer::ms_sizeCheckMark;
wxSize wxGridCellBoolRenderer::GetBestSize(wxGrid& grid,
wxGridCellAttr& WXUNUSED(attr),
wxDC& WXUNUSED(dc),
int WXUNUSED(row),
int WXUNUSED(col))
{
// compute it only once (no locks for MT safeness in GUI thread...)
if ( !ms_sizeCheckMark.x )
static wxPrivate::DpiDependentValue<wxSize> s_sizeCheckMark;
// Get the check mark size in pixels if it hadn't been done yet or if the
// DPI has changed.
if ( s_sizeCheckMark.HasChanged(&grid) )
{
ms_sizeCheckMark =
wxRendererNative::Get().GetCheckBoxSize(&grid, wxCONTROL_CELL);
s_sizeCheckMark.SetAtNewDPI
(
wxRendererNative::Get().GetCheckBoxSize(&grid, wxCONTROL_CELL)
);
}
return ms_sizeCheckMark;
return s_sizeCheckMark.Get();
}
void wxGridCellBoolRenderer::Draw(wxGrid& grid,