diff --git a/include/wx/generic/grid.h b/include/wx/generic/grid.h index c51cf031b3..c88b2a6122 100644 --- a/include/wx/generic/grid.h +++ b/include/wx/generic/grid.h @@ -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; diff --git a/include/wx/generic/gridctrl.h b/include/wx/generic/gridctrl.h index 28249fae88..c06937f0b2 100644 --- a/include/wx/generic/gridctrl.h +++ b/include/wx/generic/gridctrl.h @@ -143,9 +143,6 @@ public: virtual wxGridCellRenderer *Clone() const wxOVERRIDE { return new wxGridCellBoolRenderer; } - -private: - static wxSize ms_sizeCheckMark; }; diff --git a/samples/grid/griddemo.cpp b/samples/grid/griddemo.cpp index 62560cc04a..6de852ba6f 100644 --- a/samples/grid/griddemo.cpp +++ b/samples/grid/griddemo.cpp @@ -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); diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index f4196a3969..608feb1634 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -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. diff --git a/src/generic/gridctrl.cpp b/src/generic/gridctrl.cpp index 0d04d89e34..baf5937796 100644 --- a/src/generic/gridctrl.cpp +++ b/src/generic/gridctrl.cpp @@ -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 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,