Add wxGrid::Render() for drawing the grid to any wxDC.
In particular, this allows to print the grid contents easily. Closes #14294. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@71577 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -526,6 +526,7 @@ All:
|
|||||||
|
|
||||||
All (GUI):
|
All (GUI):
|
||||||
|
|
||||||
|
- Add wxGrid::Render() for printing wxGrid (John Roberts).
|
||||||
- Added strike-through support to wxFont (Igor Korot).
|
- Added strike-through support to wxFont (Igor Korot).
|
||||||
- Add support for horizontal mouse wheel events to MSW and GTK (Lauri Nurmi).
|
- Add support for horizontal mouse wheel events to MSW and GTK (Lauri Nurmi).
|
||||||
- Fix infinite loop in wxHtmlEasyPrinting when trying to page break images
|
- Fix infinite loop in wxHtmlEasyPrinting when trying to page break images
|
||||||
|
@@ -65,6 +65,20 @@ enum wxGridDirection
|
|||||||
wxGRID_ROW
|
wxGRID_ROW
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Flags used with wxGrid::Render() to select parts of the grid to draw.
|
||||||
|
enum wxGridRenderStyle
|
||||||
|
{
|
||||||
|
wxGRID_DRAW_ROWS_HEADER = 0x001,
|
||||||
|
wxGRID_DRAW_COLS_HEADER = 0x002,
|
||||||
|
wxGRID_DRAW_CELL_LINES = 0x004,
|
||||||
|
wxGRID_DRAW_BOX_RECT = 0x008,
|
||||||
|
wxGRID_DRAW_SELECTION = 0x010,
|
||||||
|
wxGRID_DRAW_DEFAULT = wxGRID_DRAW_ROWS_HEADER |
|
||||||
|
wxGRID_DRAW_COLS_HEADER |
|
||||||
|
wxGRID_DRAW_CELL_LINES |
|
||||||
|
wxGRID_DRAW_BOX_RECT
|
||||||
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// forward declarations
|
// forward declarations
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -1030,6 +1044,14 @@ public:
|
|||||||
int verticalAlignment = wxALIGN_TOP,
|
int verticalAlignment = wxALIGN_TOP,
|
||||||
int textOrientation = wxHORIZONTAL ) const;
|
int textOrientation = wxHORIZONTAL ) const;
|
||||||
|
|
||||||
|
// ------ grid render function for printing
|
||||||
|
//
|
||||||
|
void Render( wxDC& dc,
|
||||||
|
const wxPoint& pos = wxDefaultPosition,
|
||||||
|
const wxSize& size = wxDefaultSize,
|
||||||
|
const wxGridCellCoords& topLeft = wxGridCellCoords(-1, -1),
|
||||||
|
const wxGridCellCoords& bottomRight = wxGridCellCoords(-1, -1),
|
||||||
|
int style = wxGRID_DRAW_DEFAULT );
|
||||||
|
|
||||||
// Split a string containing newline characters into an array of
|
// Split a string containing newline characters into an array of
|
||||||
// strings and return the number of lines
|
// strings and return the number of lines
|
||||||
@@ -2253,6 +2275,10 @@ private:
|
|||||||
bool DoCanResizeLine(int line, const wxGridFixedIndicesSet *setFixed) const;
|
bool DoCanResizeLine(int line, const wxGridFixedIndicesSet *setFixed) const;
|
||||||
|
|
||||||
|
|
||||||
|
// Helper of Render(): set the scale to draw the cells at the right size.
|
||||||
|
void SetRenderScale( wxDC& dc, const wxPoint& pos, const wxSize& size,
|
||||||
|
int gridWidth, int gridHeight );
|
||||||
|
|
||||||
|
|
||||||
// these sets contain the indices of fixed, i.e. non-resizable
|
// these sets contain the indices of fixed, i.e. non-resizable
|
||||||
// interactively, grid rows or columns and are NULL if there are no fixed
|
// interactively, grid rows or columns and are NULL if there are no fixed
|
||||||
|
@@ -1850,6 +1850,50 @@ public:
|
|||||||
CellSpan_Main
|
CellSpan_Main
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Rendering styles supported by wxGrid::Render() method.
|
||||||
|
|
||||||
|
@since 2.9.4
|
||||||
|
*/
|
||||||
|
enum wxGridRenderStyle
|
||||||
|
{
|
||||||
|
/// Draw grid row header labels.
|
||||||
|
wxGRID_DRAW_ROWS_HEADER = 0x001,
|
||||||
|
|
||||||
|
/// Draw grid column header labels.
|
||||||
|
wxGRID_DRAW_COLS_HEADER = 0x002,
|
||||||
|
|
||||||
|
/// Draw grid cell border lines.
|
||||||
|
wxGRID_DRAW_CELL_LINES = 0x004,
|
||||||
|
|
||||||
|
/**
|
||||||
|
Draw a bounding rectangle around the rendered cell area.
|
||||||
|
|
||||||
|
Useful where row or column headers are not drawn or where there is
|
||||||
|
multi row or column cell clipping and therefore no cell border at
|
||||||
|
the rendered outer boundary.
|
||||||
|
*/
|
||||||
|
wxGRID_DRAW_BOX_RECT = 0x008,
|
||||||
|
|
||||||
|
/**
|
||||||
|
Draw the grid cell selection highlight if a selection is present.
|
||||||
|
|
||||||
|
At present the highlight colour drawn depends on whether the grid
|
||||||
|
window loses focus before drawing begins.
|
||||||
|
*/
|
||||||
|
wxGRID_DRAW_SELECTION = 0x010,
|
||||||
|
|
||||||
|
/**
|
||||||
|
The default render style.
|
||||||
|
|
||||||
|
Includes all except wxGRID_DRAW_SELECTION.
|
||||||
|
*/
|
||||||
|
wxGRID_DRAW_DEFAULT = wxGRID_DRAW_ROWS_HEADER |
|
||||||
|
wxGRID_DRAW_COLS_HEADER |
|
||||||
|
wxGRID_DRAW_CELL_LINES |
|
||||||
|
wxGRID_DRAW_BOX_RECT
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@name Constructors and Initialization
|
@name Constructors and Initialization
|
||||||
*/
|
*/
|
||||||
@@ -4002,6 +4046,39 @@ public:
|
|||||||
*/
|
*/
|
||||||
void RefreshAttr(int row, int col);
|
void RefreshAttr(int row, int col);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Draws part or all of a wxGrid on a wxDC for printing or display.
|
||||||
|
|
||||||
|
Pagination can be accomplished by using sequential Render() calls
|
||||||
|
with appropriate values in wxGridCellCoords topLeft and bottomRight.
|
||||||
|
|
||||||
|
@param dc
|
||||||
|
The wxDC to be drawn on.
|
||||||
|
@param pos
|
||||||
|
The position on the wxDC where rendering should begin. If not
|
||||||
|
specified drawing will begin at the wxDC MaxX() and MaxY().
|
||||||
|
@param size
|
||||||
|
The size of the area on the wxDC that the rendered wxGrid should
|
||||||
|
occupy. If not specified the drawing will be scaled to fit the
|
||||||
|
available dc width or height. The wxGrid's aspect ratio is
|
||||||
|
maintained whether or not size is specified.
|
||||||
|
@param topLeft
|
||||||
|
The top left cell of the block to be drawn. Defaults to ( 0, 0 ).
|
||||||
|
@param bottomRight
|
||||||
|
The bottom right cell of the block to be drawn. Defaults to row and
|
||||||
|
column counts.
|
||||||
|
@param style
|
||||||
|
A combination of values from wxGridRenderStyle.
|
||||||
|
|
||||||
|
@since 2.9.4
|
||||||
|
*/
|
||||||
|
void Render( wxDC& dc,
|
||||||
|
const wxPoint& pos = wxDefaultPosition,
|
||||||
|
const wxSize& size = wxDefaultSize,
|
||||||
|
const wxGridCellCoords& topLeft = wxGridCellCoords( -1, -1 ),
|
||||||
|
const wxGridCellCoords& bottomRight = wxGridCellCoords( -1, -1 ),
|
||||||
|
int style = wxGRID_DRAW_DEFAULT );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sets the cell attributes for all cells in the specified column.
|
Sets the cell attributes for all cells in the specified column.
|
||||||
|
|
||||||
|
@@ -212,6 +212,9 @@ BEGIN_EVENT_TABLE( GridFrame, wxFrame )
|
|||||||
EVT_MENU( ID_SET_HIGHLIGHT_WIDTH, GridFrame::OnSetHighlightWidth)
|
EVT_MENU( ID_SET_HIGHLIGHT_WIDTH, GridFrame::OnSetHighlightWidth)
|
||||||
EVT_MENU( ID_SET_RO_HIGHLIGHT_WIDTH, GridFrame::OnSetROHighlightWidth)
|
EVT_MENU( ID_SET_RO_HIGHLIGHT_WIDTH, GridFrame::OnSetROHighlightWidth)
|
||||||
|
|
||||||
|
EVT_MENU( wxID_PRINT, GridFrame::OnGridRender )
|
||||||
|
EVT_MENU( ID_RENDER_COORDS, GridFrame::OnGridRender )
|
||||||
|
|
||||||
EVT_GRID_LABEL_LEFT_CLICK( GridFrame::OnLabelLeftClick )
|
EVT_GRID_LABEL_LEFT_CLICK( GridFrame::OnLabelLeftClick )
|
||||||
EVT_GRID_CELL_LEFT_CLICK( GridFrame::OnCellLeftClick )
|
EVT_GRID_CELL_LEFT_CLICK( GridFrame::OnCellLeftClick )
|
||||||
EVT_GRID_ROW_SIZE( GridFrame::OnRowSize )
|
EVT_GRID_ROW_SIZE( GridFrame::OnRowSize )
|
||||||
@@ -238,6 +241,38 @@ GridFrame::GridFrame()
|
|||||||
fileMenu->Append( ID_VTABLE, wxT("&Virtual table test\tCtrl-V"));
|
fileMenu->Append( ID_VTABLE, wxT("&Virtual table test\tCtrl-V"));
|
||||||
fileMenu->Append( ID_BUGS_TABLE, wxT("&Bugs table test\tCtrl-B"));
|
fileMenu->Append( ID_BUGS_TABLE, wxT("&Bugs table test\tCtrl-B"));
|
||||||
fileMenu->Append( ID_TABULAR_TABLE, wxT("&Tabular table test\tCtrl-T"));
|
fileMenu->Append( ID_TABULAR_TABLE, wxT("&Tabular table test\tCtrl-T"));
|
||||||
|
fileMenu->AppendSeparator();
|
||||||
|
|
||||||
|
wxMenu* setupMenu = new wxMenu;
|
||||||
|
wxMenuItem* item;
|
||||||
|
item = setupMenu->AppendCheckItem( ID_RENDER_ROW_LABEL,
|
||||||
|
"Render row labels" );
|
||||||
|
item->Check();
|
||||||
|
item = setupMenu->AppendCheckItem( ID_RENDER_COL_LABEL,
|
||||||
|
"Render column labels" );
|
||||||
|
item->Check();
|
||||||
|
item = setupMenu->AppendCheckItem( ID_RENDER_GRID_LINES,
|
||||||
|
"Render grid cell lines" );
|
||||||
|
item->Check();
|
||||||
|
item = setupMenu->AppendCheckItem( ID_RENDER_GRID_BORDER,
|
||||||
|
"Render border" );
|
||||||
|
item->Check();
|
||||||
|
item = setupMenu->AppendCheckItem( ID_RENDER_SELECT_HLIGHT,
|
||||||
|
"Render selection highlight" );
|
||||||
|
setupMenu->AppendSeparator();
|
||||||
|
setupMenu->AppendCheckItem( ID_RENDER_LOMETRIC,
|
||||||
|
"Use LOMETRIC mapping mode" );
|
||||||
|
setupMenu->AppendCheckItem( ID_RENDER_DEFAULT_SIZE,
|
||||||
|
"Use wxDefaultSize" );
|
||||||
|
setupMenu->AppendCheckItem( ID_RENDER_MARGIN,
|
||||||
|
"Logical 50 unit margin" );
|
||||||
|
setupMenu->AppendCheckItem( ID_RENDER_ZOOM,
|
||||||
|
"Zoom 125%" );
|
||||||
|
|
||||||
|
fileMenu->AppendSubMenu( setupMenu, "Render setup" );
|
||||||
|
fileMenu->Append( wxID_PRINT, "Render" );
|
||||||
|
fileMenu->Append( ID_RENDER_COORDS, "Render G5:P30" );
|
||||||
|
|
||||||
fileMenu->AppendSeparator();
|
fileMenu->AppendSeparator();
|
||||||
fileMenu->Append( wxID_EXIT, wxT("E&xit\tAlt-X") );
|
fileMenu->Append( wxID_EXIT, wxT("E&xit\tAlt-X") );
|
||||||
|
|
||||||
@@ -2068,3 +2103,158 @@ void GridFrame::OnTabularTable(wxCommandEvent&)
|
|||||||
{
|
{
|
||||||
new TabularGridFrame;
|
new TabularGridFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Example using wxGrid::Render
|
||||||
|
// Displays a preset selection or, if it exists, a selection block
|
||||||
|
// Draws the selection to a wxBitmap and displays the bitmap
|
||||||
|
void GridFrame::OnGridRender( wxCommandEvent& event )
|
||||||
|
{
|
||||||
|
int styleRender = 0, i;
|
||||||
|
bool useLometric = false, defSize = false;
|
||||||
|
double zoom = 1;
|
||||||
|
wxSize sizeMargin( 0, 0 );
|
||||||
|
wxPoint pointOrigin( 0, 0 );
|
||||||
|
|
||||||
|
wxMenu* menu = GetMenuBar()->GetMenu( 0 );
|
||||||
|
wxMenuItem* menuItem = menu->FindItem( ID_RENDER_ROW_LABEL );
|
||||||
|
menu = menuItem->GetMenu();
|
||||||
|
|
||||||
|
if ( menu->FindItem( ID_RENDER_ROW_LABEL )->IsChecked() )
|
||||||
|
styleRender |= wxGRID_DRAW_ROWS_HEADER;
|
||||||
|
if ( menu->FindItem( ID_RENDER_COL_LABEL )->IsChecked() )
|
||||||
|
styleRender |= wxGRID_DRAW_COLS_HEADER;
|
||||||
|
if ( menu->FindItem( ID_RENDER_GRID_LINES )->IsChecked() )
|
||||||
|
styleRender |= wxGRID_DRAW_CELL_LINES;
|
||||||
|
if ( menu->FindItem( ID_RENDER_GRID_BORDER )->IsChecked() )
|
||||||
|
styleRender |= wxGRID_DRAW_BOX_RECT;
|
||||||
|
if ( menu->FindItem( ID_RENDER_SELECT_HLIGHT )->IsChecked() )
|
||||||
|
styleRender |= wxGRID_DRAW_SELECTION;
|
||||||
|
if ( menu->FindItem( ID_RENDER_LOMETRIC )->IsChecked() )
|
||||||
|
useLometric = true;
|
||||||
|
if ( menu->FindItem( ID_RENDER_MARGIN )->IsChecked() )
|
||||||
|
{
|
||||||
|
pointOrigin.x += 50;
|
||||||
|
pointOrigin.y += 50;
|
||||||
|
sizeMargin.IncBy( 50 );
|
||||||
|
}
|
||||||
|
if ( menu->FindItem( ID_RENDER_ZOOM )->IsChecked() )
|
||||||
|
zoom = 1.25;
|
||||||
|
if ( menu->FindItem( ID_RENDER_DEFAULT_SIZE )->IsChecked() )
|
||||||
|
defSize = true;
|
||||||
|
|
||||||
|
// init render area coords with a default row and col selection
|
||||||
|
wxGridCellCoords topLeft( 0, 0 ), bottomRight( 8, 6 );
|
||||||
|
// check whether we are printing a block selection
|
||||||
|
// other selection types not catered for here
|
||||||
|
if ( event.GetId() == ID_RENDER_COORDS )
|
||||||
|
{
|
||||||
|
topLeft.SetCol( 6 );
|
||||||
|
topLeft.SetRow( 4 );
|
||||||
|
bottomRight.SetCol( 15 );
|
||||||
|
bottomRight.SetRow( 29 );
|
||||||
|
}
|
||||||
|
else if ( grid->IsSelection() && grid->GetSelectionBlockTopLeft().Count() )
|
||||||
|
{
|
||||||
|
wxGridCellCoordsArray cells = grid->GetSelectionBlockTopLeft();
|
||||||
|
if ( grid->GetSelectionBlockBottomRight().Count() )
|
||||||
|
{
|
||||||
|
cells.Add( grid->GetSelectionBlockBottomRight()[ 0 ] );
|
||||||
|
topLeft.Set( cells[ 0 ].GetRow(),
|
||||||
|
cells[ 0 ].GetCol() );
|
||||||
|
bottomRight.Set( cells[ 1 ].GetRow(),
|
||||||
|
cells[ 1 ].GetCol() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum col widths
|
||||||
|
wxSize sizeRender( 0, 0 );
|
||||||
|
wxGridSizesInfo sizeinfo = grid->GetColSizes();
|
||||||
|
for ( i = topLeft.GetCol(); i <= bottomRight.GetCol(); i++ )
|
||||||
|
{
|
||||||
|
sizeRender.x += sizeinfo.GetSize( i );
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum row heights
|
||||||
|
sizeinfo = grid->GetRowSizes();
|
||||||
|
for ( i = topLeft.GetRow(); i <= bottomRight.GetRow(); i++ )
|
||||||
|
{
|
||||||
|
sizeRender.y += sizeinfo.GetSize( i );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( styleRender & wxGRID_DRAW_ROWS_HEADER )
|
||||||
|
sizeRender.x += grid->GetRowLabelSize();
|
||||||
|
if ( styleRender & wxGRID_DRAW_COLS_HEADER )
|
||||||
|
sizeRender.y += grid->GetColLabelSize();
|
||||||
|
|
||||||
|
sizeRender.x *= zoom;
|
||||||
|
sizeRender.y *= zoom;
|
||||||
|
|
||||||
|
// delete any existing render frame and create new one
|
||||||
|
wxWindow* win = FindWindow( "frameRender" );
|
||||||
|
if ( win )
|
||||||
|
win->Destroy();
|
||||||
|
|
||||||
|
wxFrame* frame = new wxFrame( this, wxID_ANY, "Grid Render" );
|
||||||
|
frame->SetClientSize( 780, 400 );
|
||||||
|
frame->SetName( "frameRender" );
|
||||||
|
|
||||||
|
wxPanel* canvas = new wxPanel( frame, wxID_ANY );
|
||||||
|
|
||||||
|
// make bitmap large enough for margins if any
|
||||||
|
if ( !defSize )
|
||||||
|
sizeRender.IncBy( sizeMargin * 2 );
|
||||||
|
else
|
||||||
|
sizeRender.IncBy( sizeMargin );
|
||||||
|
|
||||||
|
wxBitmap bmp( sizeRender );
|
||||||
|
// don't leave it larger or drawing will be scaled
|
||||||
|
sizeRender.DecBy( sizeMargin * 2 );
|
||||||
|
|
||||||
|
wxMemoryDC memDc(bmp);
|
||||||
|
|
||||||
|
// default row labels have no background colour so set background
|
||||||
|
memDc.SetBackground( wxBrush( canvas->GetBackgroundColour() ) );
|
||||||
|
memDc.Clear();
|
||||||
|
|
||||||
|
// convert sizeRender to mapping mode units if necessary
|
||||||
|
if ( useLometric )
|
||||||
|
{
|
||||||
|
memDc.SetMapMode( wxMM_LOMETRIC );
|
||||||
|
wxSize sizePPI = memDc.GetPPI();
|
||||||
|
sizeRender.x = memDc.DeviceToLogicalXRel( sizeRender.x );
|
||||||
|
sizeRender.y = memDc.DeviceToLogicalYRel( sizeRender.y );
|
||||||
|
}
|
||||||
|
|
||||||
|
// pass wxDefaultSize if menu item is checked
|
||||||
|
if ( defSize )
|
||||||
|
sizeRender = wxDefaultSize;
|
||||||
|
|
||||||
|
grid->Render( memDc,
|
||||||
|
pointOrigin,
|
||||||
|
sizeRender,
|
||||||
|
topLeft, bottomRight,
|
||||||
|
wxGridRenderStyle( styleRender ) );
|
||||||
|
|
||||||
|
m_gridBitmap = bmp;
|
||||||
|
|
||||||
|
canvas->Bind( wxEVT_PAINT, &GridFrame::OnRenderPaint, this );
|
||||||
|
|
||||||
|
frame->Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridFrame::OnRenderPaint( wxPaintEvent& event )
|
||||||
|
{
|
||||||
|
wxPanel* canvas = ( wxPanel* )event.GetEventObject();
|
||||||
|
wxPaintDC dc( canvas );
|
||||||
|
canvas->PrepareDC( dc );
|
||||||
|
|
||||||
|
if ( !m_gridBitmap.IsOk() )
|
||||||
|
return;;
|
||||||
|
|
||||||
|
wxMemoryDC memDc( m_gridBitmap );
|
||||||
|
|
||||||
|
dc.Blit( 0, 0,
|
||||||
|
m_gridBitmap.GetWidth(),
|
||||||
|
m_gridBitmap.GetHeight(),
|
||||||
|
&memDc, 0, 0 );
|
||||||
|
}
|
||||||
|
@@ -111,6 +111,8 @@ public:
|
|||||||
void OnVTable( wxCommandEvent& );
|
void OnVTable( wxCommandEvent& );
|
||||||
void OnBugsTable( wxCommandEvent& );
|
void OnBugsTable( wxCommandEvent& );
|
||||||
void OnTabularTable( wxCommandEvent& );
|
void OnTabularTable( wxCommandEvent& );
|
||||||
|
void OnGridRender( wxCommandEvent& event );
|
||||||
|
void OnRenderPaint( wxPaintEvent& event );
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@@ -174,7 +176,18 @@ public:
|
|||||||
ID_SET_HIGHLIGHT_WIDTH,
|
ID_SET_HIGHLIGHT_WIDTH,
|
||||||
ID_SET_RO_HIGHLIGHT_WIDTH,
|
ID_SET_RO_HIGHLIGHT_WIDTH,
|
||||||
|
|
||||||
ID_TESTFUNC
|
ID_TESTFUNC,
|
||||||
|
|
||||||
|
ID_RENDER_ROW_LABEL,
|
||||||
|
ID_RENDER_COL_LABEL,
|
||||||
|
ID_RENDER_GRID_LINES,
|
||||||
|
ID_RENDER_GRID_BORDER,
|
||||||
|
ID_RENDER_SELECT_HLIGHT,
|
||||||
|
ID_RENDER_LOMETRIC,
|
||||||
|
ID_RENDER_COORDS,
|
||||||
|
ID_RENDER_ZOOM,
|
||||||
|
ID_RENDER_MARGIN,
|
||||||
|
ID_RENDER_DEFAULT_SIZE,
|
||||||
};
|
};
|
||||||
|
|
||||||
#if wxUSE_LOG
|
#if wxUSE_LOG
|
||||||
@@ -184,6 +197,8 @@ public:
|
|||||||
// add the cells to selection when using commands from select menu?
|
// add the cells to selection when using commands from select menu?
|
||||||
bool m_addToSel;
|
bool m_addToSel;
|
||||||
|
|
||||||
|
wxBitmap m_gridBitmap;
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1776,6 +1776,267 @@ void wxGridWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
|
|||||||
m_owner->DrawHighlight( dc, dirtyCells );
|
m_owner->DrawHighlight( dc, dirtyCells );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxGrid::Render( wxDC& dc,
|
||||||
|
const wxPoint& position,
|
||||||
|
const wxSize& size,
|
||||||
|
const wxGridCellCoords& topLeft,
|
||||||
|
const wxGridCellCoords& bottomRight,
|
||||||
|
int style )
|
||||||
|
{
|
||||||
|
wxCHECK_RET( bottomRight.GetCol() < GetNumberCols(),
|
||||||
|
"Invalid right column" );
|
||||||
|
wxCHECK_RET( bottomRight.GetRow() < GetNumberRows(),
|
||||||
|
"Invalid bottom row" );
|
||||||
|
|
||||||
|
// store user settings and reset later
|
||||||
|
|
||||||
|
// remove grid selection, don't paint selection colour
|
||||||
|
// unless we have wxGRID_DRAW_SELECTION
|
||||||
|
// block selections are the only ones catered for here
|
||||||
|
wxGridCellCoordsArray selectedCells;
|
||||||
|
bool hasSelection = IsSelection();
|
||||||
|
if ( hasSelection && !( style & wxGRID_DRAW_SELECTION ) )
|
||||||
|
{
|
||||||
|
selectedCells = GetSelectionBlockTopLeft();
|
||||||
|
// non block selections may not have a bottom right
|
||||||
|
if ( GetSelectionBlockBottomRight().size() )
|
||||||
|
selectedCells.Add( GetSelectionBlockBottomRight()[ 0 ] );
|
||||||
|
|
||||||
|
ClearSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
// store user device origin
|
||||||
|
wxCoord userOriginX, userOriginY;
|
||||||
|
dc.GetDeviceOrigin( &userOriginX, &userOriginY );
|
||||||
|
|
||||||
|
// store user scale
|
||||||
|
double scaleUserX, scaleUserY;
|
||||||
|
dc.GetUserScale( &scaleUserX, &scaleUserY );
|
||||||
|
|
||||||
|
// set defaults if necessary
|
||||||
|
long colLeft = topLeft.GetCol() > -1 ? topLeft.GetCol() : 0;
|
||||||
|
long rowTop = topLeft.GetRow() > -1 ? topLeft.GetRow() : 0;
|
||||||
|
long colRight = bottomRight.GetCol() > -1 ? bottomRight.GetCol()
|
||||||
|
: GetNumberCols() - 1;
|
||||||
|
long rowBottom = bottomRight.GetRow() > -1 ? bottomRight.GetRow()
|
||||||
|
: GetNumberRows() - 1;
|
||||||
|
|
||||||
|
// get grid area size to be rendered
|
||||||
|
long offsetCols = 0, offsetRows = 0;
|
||||||
|
wxGridCellCoordsArray renderCells;
|
||||||
|
wxArrayInt arrayCols;
|
||||||
|
wxArrayInt arrayRows;
|
||||||
|
int col, row, gridWidth, gridHeight;
|
||||||
|
|
||||||
|
// fill array with cells to be rendered
|
||||||
|
// calculate width of cell drawn area
|
||||||
|
// and get grid column offset used where startcol > 0
|
||||||
|
gridWidth = 0;
|
||||||
|
wxGridSizesInfo sizeinfo = GetColSizes();
|
||||||
|
for ( col = 0; col <= colRight; col++ )
|
||||||
|
{
|
||||||
|
if ( col < colLeft )
|
||||||
|
{
|
||||||
|
offsetCols += sizeinfo.GetSize( col );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for ( row = rowTop; row <= rowBottom; row++ )
|
||||||
|
{
|
||||||
|
renderCells.Add( wxGridCellCoords( row, col ));
|
||||||
|
arrayRows.Add( row ); // column labels rendered in DrawColLabels
|
||||||
|
}
|
||||||
|
arrayCols.Add( col ); // row labels rendered in DrawRowLabels
|
||||||
|
gridWidth += sizeinfo.GetSize( col );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate height of rendered cells
|
||||||
|
// and row Y offset where startrow > 0
|
||||||
|
gridHeight = 0;
|
||||||
|
sizeinfo = GetRowSizes();
|
||||||
|
for ( row = 0; row <= rowBottom; row++ )
|
||||||
|
{
|
||||||
|
if ( row < rowTop )
|
||||||
|
offsetRows += sizeinfo.GetSize( row );
|
||||||
|
else
|
||||||
|
gridHeight += sizeinfo.GetSize( row );
|
||||||
|
}
|
||||||
|
|
||||||
|
// add headers/labels to dimensions
|
||||||
|
if ( style & wxGRID_DRAW_ROWS_HEADER )
|
||||||
|
gridWidth += GetRowLabelSize();
|
||||||
|
if ( style & wxGRID_DRAW_COLS_HEADER )
|
||||||
|
gridHeight += GetColLabelSize();
|
||||||
|
|
||||||
|
// set drawing start position DeviceOrigin
|
||||||
|
// if not specified use previous dc draw extents MaxX and MaxY
|
||||||
|
wxPoint positionRender = position;
|
||||||
|
if ( !positionRender.IsFullySpecified() )
|
||||||
|
{
|
||||||
|
if ( positionRender.x == wxDefaultPosition.x )
|
||||||
|
positionRender.x = dc.MaxX();
|
||||||
|
|
||||||
|
if ( positionRender.y == wxDefaultPosition.y )
|
||||||
|
positionRender.y = dc.MaxY();
|
||||||
|
}
|
||||||
|
|
||||||
|
// positionRender should be in logical units
|
||||||
|
wxCoord originX = dc.LogicalToDeviceX( positionRender.x );
|
||||||
|
wxCoord originY = dc.LogicalToDeviceY( positionRender.y );
|
||||||
|
|
||||||
|
dc.SetDeviceOrigin( originX, originY );
|
||||||
|
|
||||||
|
SetRenderScale( dc, positionRender, size, gridWidth, gridHeight );
|
||||||
|
|
||||||
|
// draw row headers at specified origin
|
||||||
|
if ( GetRowLabelSize() > 0 && ( style & wxGRID_DRAW_ROWS_HEADER ) )
|
||||||
|
{
|
||||||
|
if ( style & wxGRID_DRAW_COLS_HEADER )
|
||||||
|
{
|
||||||
|
DrawCornerLabel( dc ); // do only if both col and row labels drawn
|
||||||
|
originY += dc.LogicalToDeviceYRel( GetColLabelSize() );
|
||||||
|
}
|
||||||
|
|
||||||
|
originY -= dc.LogicalToDeviceYRel( offsetRows );
|
||||||
|
dc.SetDeviceOrigin( originX, originY );
|
||||||
|
|
||||||
|
DrawRowLabels( dc, arrayRows );
|
||||||
|
|
||||||
|
// reset for columns
|
||||||
|
if ( style & wxGRID_DRAW_COLS_HEADER )
|
||||||
|
originY -= dc.LogicalToDeviceYRel( GetColLabelSize() );
|
||||||
|
|
||||||
|
originY += dc.LogicalToDeviceYRel( offsetRows );
|
||||||
|
// X offset so we don't overwrite row labels
|
||||||
|
originX += dc.LogicalToDeviceXRel( GetRowLabelSize() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// subtract col offset where startcol > 0
|
||||||
|
originX -= dc.LogicalToDeviceXRel( offsetCols );
|
||||||
|
// no y offset for col labels, they are at the Y origin
|
||||||
|
|
||||||
|
// draw column labels
|
||||||
|
if ( style & wxGRID_DRAW_COLS_HEADER )
|
||||||
|
{
|
||||||
|
dc.SetDeviceOrigin( originX, originY );
|
||||||
|
DrawColLabels( dc, arrayCols );
|
||||||
|
// don't overwrite the labels, increment originY
|
||||||
|
originY += dc.LogicalToDeviceYRel( GetColLabelSize() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// set device origin to draw grid cells and lines
|
||||||
|
originY -= dc.LogicalToDeviceYRel( offsetRows );
|
||||||
|
dc.SetDeviceOrigin( originX, originY );
|
||||||
|
|
||||||
|
// draw cell area background
|
||||||
|
dc.SetBrush( GetDefaultCellBackgroundColour() );
|
||||||
|
dc.SetPen( *wxTRANSPARENT_PEN );
|
||||||
|
// subtract headers from grid area dimensions
|
||||||
|
unsigned cellsWidth = gridWidth, cellsHeight = gridHeight;
|
||||||
|
if ( style & wxGRID_DRAW_ROWS_HEADER )
|
||||||
|
cellsWidth -= GetRowLabelSize();
|
||||||
|
if ( style & wxGRID_DRAW_COLS_HEADER )
|
||||||
|
cellsHeight -= GetColLabelSize();
|
||||||
|
|
||||||
|
dc.DrawRectangle( wxPoint( offsetCols, offsetRows ),
|
||||||
|
wxSize( cellsWidth, cellsHeight ) );
|
||||||
|
|
||||||
|
// draw cells
|
||||||
|
DrawGridCellArea( dc, renderCells );
|
||||||
|
|
||||||
|
// calculate region for drawing grid lines
|
||||||
|
if ( style & wxGRID_DRAW_CELL_LINES )
|
||||||
|
{
|
||||||
|
wxRegion regionClip( offsetCols,
|
||||||
|
offsetRows,
|
||||||
|
cellsWidth,
|
||||||
|
cellsHeight );
|
||||||
|
|
||||||
|
DrawRangeGridLines(dc, regionClip, renderCells[0], renderCells.Last());
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw render rectangle bounding lines
|
||||||
|
// useful where there is multi cell row or col clipping and no cell border
|
||||||
|
if ( style & wxGRID_DRAW_BOX_RECT )
|
||||||
|
{
|
||||||
|
int bottom = offsetRows + cellsHeight,
|
||||||
|
right = offsetCols + cellsWidth - 1;
|
||||||
|
|
||||||
|
// horiz top line if we are not drawing column header/labels
|
||||||
|
if ( !( style & wxGRID_DRAW_COLS_HEADER ) )
|
||||||
|
{
|
||||||
|
int left = offsetCols;
|
||||||
|
left += ( style & wxGRID_DRAW_COLS_HEADER )
|
||||||
|
? - GetRowLabelSize() : 0;
|
||||||
|
dc.SetPen( GetRowGridLinePen( rowTop ) );
|
||||||
|
dc.DrawLine( left,
|
||||||
|
offsetRows,
|
||||||
|
right,
|
||||||
|
offsetRows );
|
||||||
|
}
|
||||||
|
|
||||||
|
// horiz bottom line
|
||||||
|
dc.SetPen( GetRowGridLinePen( rowBottom ) );
|
||||||
|
dc.DrawLine( offsetCols, bottom - 1, right, bottom - 1 );
|
||||||
|
|
||||||
|
// left vertical line if we are not drawing row header/labels
|
||||||
|
if ( !( style & wxGRID_DRAW_ROWS_HEADER ) )
|
||||||
|
{
|
||||||
|
int top = offsetRows;
|
||||||
|
top += ( style & wxGRID_DRAW_COLS_HEADER )
|
||||||
|
? - GetColLabelSize() : 0;
|
||||||
|
dc.SetPen( GetColGridLinePen( colLeft ) );
|
||||||
|
dc.DrawLine( offsetCols -1,
|
||||||
|
top,
|
||||||
|
offsetCols - 1,
|
||||||
|
bottom - 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// right vertical line
|
||||||
|
dc.SetPen( GetColGridLinePen( colRight ) );
|
||||||
|
dc.DrawLine( right, offsetRows, right, bottom - 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// restore user setings
|
||||||
|
dc.SetDeviceOrigin( userOriginX, userOriginY );
|
||||||
|
dc.SetUserScale( scaleUserX, scaleUserY );
|
||||||
|
|
||||||
|
if ( selectedCells.size() && !( style & wxGRID_DRAW_SELECTION ) )
|
||||||
|
{
|
||||||
|
SelectBlock( selectedCells[ 0 ].GetRow(),
|
||||||
|
selectedCells[ 0 ].GetCol(),
|
||||||
|
selectedCells[ selectedCells.size() -1 ].GetRow(),
|
||||||
|
selectedCells[ selectedCells.size() -1 ].GetCol() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wxGrid::SetRenderScale(wxDC& dc,
|
||||||
|
const wxPoint& pos, const wxSize& size,
|
||||||
|
int gridWidth, int gridHeight)
|
||||||
|
{
|
||||||
|
double scaleX, scaleY;
|
||||||
|
wxSize sizeTemp;
|
||||||
|
|
||||||
|
if ( size.GetX() != wxDefaultSize.GetX() ) // size.x was specified
|
||||||
|
sizeTemp.SetWidth( size.GetX() );
|
||||||
|
else
|
||||||
|
sizeTemp.SetWidth( dc.DeviceToLogicalXRel( dc.GetSize().GetX() )
|
||||||
|
- pos.x );
|
||||||
|
|
||||||
|
if ( size.GetY() != wxDefaultSize.GetY() ) // size.y was specified
|
||||||
|
sizeTemp.SetHeight( size.GetY() );
|
||||||
|
else
|
||||||
|
sizeTemp.SetHeight( dc.DeviceToLogicalYRel( dc.GetSize().GetY() )
|
||||||
|
- pos.y );
|
||||||
|
|
||||||
|
scaleX = (double)( (double) sizeTemp.GetX() / (double) gridWidth );
|
||||||
|
scaleY = (double)( (double) sizeTemp.GetY() / (double) gridHeight );
|
||||||
|
|
||||||
|
dc.SetUserScale( wxMin( scaleX, scaleY), wxMin( scaleX, scaleY ) );
|
||||||
|
}
|
||||||
|
|
||||||
void wxGridWindow::ScrollWindow( int dx, int dy, const wxRect *rect )
|
void wxGridWindow::ScrollWindow( int dx, int dy, const wxRect *rect )
|
||||||
{
|
{
|
||||||
wxWindow::ScrollWindow( dx, dy, rect );
|
wxWindow::ScrollWindow( dx, dy, rect );
|
||||||
|
Reference in New Issue
Block a user