24#include <wx/tokenzr.h>
26#include <wx/settings.h>
34#define MIN_GRIDCELL_MARGIN FromDIP( 3 )
39 KIGFX::COLOR4D bg = wxSystemSettings::GetColour( wxSYS_COLOUR_FRAMEBK );
40 KIGFX::COLOR4D fg = wxSystemSettings::GetColour( wxSYS_COLOUR_ACTIVEBORDER );
51 wxDCBrushChanger SetBrush( dc, *wxTRANSPARENT_BRUSH );
54 rect.SetTop( rect.GetTop() + 1 );
55 rect.SetLeft( rect.GetLeft() + 1 );
56 rect.SetBottom( rect.GetBottom() - 1 );
57 rect.SetRight( rect.GetRight() - 1 );
58 dc.DrawRectangle( rect );
68 wxDCBrushChanger SetBrush( dc, *wxTRANSPARENT_BRUSH );
71 rect.SetTop( rect.GetTop() + 1 );
72 rect.SetLeft( rect.GetLeft() );
73 rect.SetBottom( rect.GetBottom() - 1 );
74 rect.SetRight( rect.GetRight() - 1 );
75 dc.DrawRectangle( rect );
85 wxDCBrushChanger SetBrush( dc, *wxTRANSPARENT_BRUSH );
88 rect.SetTop( rect.GetTop() + 1 );
89 rect.SetLeft( rect.GetLeft() + 1 );
90 rect.SetBottom( rect.GetBottom() - 1 );
91 rect.SetRight( rect.GetRight() );
92 dc.DrawRectangle( rect );
97WX_GRID::WX_GRID( wxWindow *parent, wxWindowID
id,
const wxPoint& pos,
const wxSize& size,
98 long style,
const wxString&
name ) :
99 wxGrid( parent, id, pos, size, style,
name ),
100 m_weOwnTable( false )
102 SetDefaultCellOverflow(
false );
108 if( GetColLabelSize() > 0 )
140 wxGrid::SetColLabelSize( 0 );
146 wxGrid::SetColLabelSize( std::max( aHeight, minHeight ) );
160 int numberCols = GetNumberCols();
161 int* formBuilderColWidths =
new int[numberCols];
163 for(
int i = 0; i < numberCols; ++i )
164 formBuilderColWidths[ i ] = GetColSize( i );
166 wxGrid::SetTable( aTable );
170 numberCols = std::min( numberCols, GetNumberCols() );
172 for(
int i = 0; i < numberCols; ++i )
177 SetColSize( i, std::max( formBuilderColWidths[ i ], headingWidth ) );
180 delete[] formBuilderColWidths;
194 int row = aEvent.GetRow();
195 int col = aEvent.GetCol();
197 if( row >= 0 && row < GetNumberRows() && col >= 0 && col < GetNumberCols() )
199 if( GetSelectionMode() == wxGrid::wxGridSelectCells )
201 SelectBlock( row, col, row, col,
false );
203 else if( GetSelectionMode() == wxGrid::wxGridSelectRows
204 || GetSelectionMode() == wxGrid::wxGridSelectRowsOrColumns )
206 SelectBlock( row, 0, row, GetNumberCols() - 1,
false );
208 else if( GetSelectionMode() == wxGrid::wxGridSelectColumns )
210 SelectBlock( 0, col, GetNumberRows() - 1, col,
false );
220 int row = aEvent.GetRow();
221 int col = aEvent.GetCol();
223 const std::pair<wxString, wxString>& beforeAfter =
m_evalBeforeAfter[ { row, col } ];
225 if( GetCellValue( row, col ) == beforeAfter.second )
226 SetCellValue( row, col, beforeAfter.first );
242 int row = aEvent.GetRow();
243 int col = aEvent.GetCol();
246 [
this, row, col, unitsProvider]()
248 wxString stringValue = GetCellValue( row, col );
250 if(
m_eval->Process( stringValue ) )
255 if( stringValue != evalValue )
257 SetCellValue( row, col, evalValue );
277 wxGrid::SetTable(
nullptr );
284 wxString shownColumns;
286 for(
int i = 0; i < GetNumberCols(); ++i )
288 if( IsColShown( i ) )
290 if( shownColumns.Length() )
291 shownColumns << wxT(
" " );
303 std::bitset<64> shownColumns;
305 for(
int ii = 0; ii < GetNumberCols(); ++ii )
306 shownColumns[ii] = IsColShown( ii );
314 for(
int i = 0; i < GetNumberCols(); ++i )
317 wxStringTokenizer shownTokens( shownColumns );
319 while( shownTokens.HasMoreTokens() )
322 shownTokens.GetNextToken().ToLong( &colNumber );
324 if( colNumber >= 0 && colNumber < GetNumberCols() )
325 ShowCol( (
int) colNumber );
332 for(
int ii = 0; ii < GetNumberCols(); ++ ii )
334 if( aShownColumns[ii] )
344 if( m_nativeColumnLabels )
345 wxGrid::DrawCornerLabel( dc );
347 wxRect rect( wxSize( m_rowLabelWidth, m_colLabelHeight ) );
354 wxDCBrushChanger setBrush( dc, m_colLabelWin->GetBackgroundColour() );
355 wxDCPenChanger setPen( dc, m_colLabelWin->GetBackgroundColour() );
356 dc.DrawRectangle( rect.Inflate( 1 ) );
365 if( m_nativeColumnLabels )
366 wxGrid::DrawColLabel( dc, col );
368 if( GetColWidth( col ) <= 0 || m_colLabelHeight <= 0 )
371 wxRect rect( GetColLeft( col ), 0, GetColWidth( col ), m_colLabelHeight );
378 wxDCBrushChanger setBrush( dc, m_colLabelWin->GetBackgroundColour() );
379 wxDCPenChanger setPen( dc, m_colLabelWin->GetBackgroundColour() );
380 dc.DrawRectangle( rect.Inflate( 1 ) );
386 dc.SetFont( GetLabelFont() );
389 GetColLabelAlignment( &hAlign, &vAlign );
390 const int orient = GetColLabelTextOrientation();
393 hAlign = wxALIGN_LEFT;
395 if( hAlign == wxALIGN_LEFT )
398 rend.DrawLabel( *
this, dc, GetColLabelValue( col ), rect, hAlign, vAlign, orient );
404 if ( GetRowHeight( row ) <= 0 || m_rowLabelWidth <= 0 )
407 wxRect rect( 0, GetRowTop( row ), m_rowLabelWidth, GetRowHeight( row ) );
414 wxDCBrushChanger setBrush( dc, m_colLabelWin->GetBackgroundColour() );
415 wxDCPenChanger setPen( dc, m_colLabelWin->GetBackgroundColour() );
416 dc.DrawRectangle( rect.Inflate( 1 ) );
422 dc.SetFont( GetLabelFont() );
425 GetRowLabelAlignment(&hAlign, &vAlign);
427 if( hAlign == wxALIGN_LEFT )
430 rend.DrawLabel( *
this, dc, GetRowLabelValue( row ), rect, hAlign, vAlign, wxHORIZONTAL );
436 if( !IsCellEditControlEnabled() )
439 HideCellEditControl();
442 m_cellEditCtrlEnabled =
false;
444 int row = m_currentCellCoords.GetRow();
445 int col = m_currentCellCoords.GetCol();
447 wxString oldval = GetCellValue( row, col );
450 wxGridCellAttr* attr = GetCellAttr( row, col );
451 wxGridCellEditor*
editor = attr->GetEditor(
this, row, col );
453 editor->EndEdit( row, col,
this, oldval, &newval );
464 if( !IsCellEditControlEnabled() )
467 if( !aQuietMode && SendEvent( wxEVT_GRID_EDITOR_HIDDEN ) == -1 )
470 HideCellEditControl();
473 m_cellEditCtrlEnabled =
false;
475 int row = m_currentCellCoords.GetRow();
476 int col = m_currentCellCoords.GetCol();
478 wxString oldval = GetCellValue( row, col );
481 wxGridCellAttr* attr = GetCellAttr( row, col );
482 wxGridCellEditor*
editor = attr->GetEditor(
this, row, col );
484 bool changed =
editor->EndEdit( row, col,
this, oldval, &newval );
491 if( !aQuietMode && SendEvent( wxEVT_GRID_CELL_CHANGING, newval ) == -1 )
494 editor->ApplyEdit( row, col,
this );
499 if( !aQuietMode && SendEvent( wxEVT_GRID_CELL_CHANGED, oldval ) == -1 )
502 SetCellValue( row, col, oldval );
527 wxString stringValue = GetCellValue( aRow, aCol );
533 if(
m_eval->Process( stringValue ) )
534 stringValue =
m_eval->Result();
548 SetCellValue( aRow, aCol, unitsProvider->
StringFromValue( aValue,
true ) );
566 size = GetRowLabelSize();
568 for(
int row = 0; aContents && row < GetNumberRows(); row++ )
569 size = std::max( size,
int( GetTextExtent( GetRowLabelValue( row ) + wxS(
"M" ) ).x ) );
574 size = GetColSize( aCol );
582 size = std::max( size,
int( GetTextExtent( GetColLabelValue( aCol ) + wxS(
"M" ) ).x ) );
585 for(
int row = 0; aContents && row < GetNumberRows(); row++ )
588 if( GetTable()->CanGetValueAs( row, aCol, wxGRID_VALUE_STRING ) )
589 size = std::max( size, GetTextExtent( GetCellValue( row, aCol ) + wxS(
"M" ) ).x );
591 size = std::max( size, GetTextExtent(
"MM" ).x );
601 int line_height = int( GetTextExtent(
"Mj" ).y ) + 3;
602 int row_height = GetColLabelSize();
603 int initial_row_height = row_height;
608 for(
int col = 0; col < GetNumberCols(); col++ )
610 int nl_count = GetColLabelValue( col ).Freq(
'\n' );
615 if( row_height < line_height * ( nl_count+1 ) )
616 row_height += line_height * nl_count;
622 if( initial_row_height != row_height )
A color representation with 4 components: red, green, blue, alpha.
wxColour ToColour() const
COLOR4D Mix(const COLOR4D &aColor, double aFactor) const
Return a color that is mixed with the input by a factor.
EDA_UNITS GetUserUnits() const
wxString StringFromValue(double aValue, bool aAddUnitLabel=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
Converts aValue in internal units into a united string.
int ValueFromString(const wxString &aTextValue, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
Converts aTextValue in aUnits to internal units used by the frame.
void DrawBorder(const wxGrid &grid, wxDC &dc, wxRect &rect) const override
int GetVisibleWidth(int aCol, bool aHeader=true, bool aContents=true, bool aKeep=false)
Calculates the specified column based on the actual size of the text on screen.
void onGridCellSelect(wxGridEvent &aEvent)
void SetLabelFont(const wxFont &aFont)
Hide wxGrid's SetLabelFont() because for some reason on MSW it's a one-shot and subsequent calls to i...
void onDPIChanged(wxDPIChangedEvent &event)
void ShowHideColumns(const wxString &shownColumns)
Show/hide the grid columns based on a tokenized string of shown column indexes.
std::map< int, UNITS_PROVIDER * > m_unitsProviders
void SetTable(wxGridTableBase *table, bool aTakeOwnership=false)
Hide wxGrid's SetTable() method with one which doesn't mess up the grid column widths when setting th...
void DestroyTable(wxGridTableBase *aTable)
Work-around for a bug in wxGrid which crashes when deleting the table if the cell edit control was no...
bool CancelPendingChanges()
void SetColLabelSize(int aHeight)
Hide wxGrid's SetColLabelSize() method with one which makes sure the size is tall enough for the syst...
void SetUnitValue(int aRow, int aCol, int aValue)
Set a unitized cell's value.
WX_GRID(wxWindow *parent, wxWindowID id, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxWANTS_CHARS, const wxString &name=wxGridNameStr)
int GetUnitValue(int aRow, int aCol)
Apply standard KiCad unit and eval services to a numeric cell.
std::vector< int > m_autoEvalCols
std::map< std::pair< int, int >, std::pair< wxString, wxString > > m_evalBeforeAfter
void DrawCornerLabel(wxDC &dc) override
A re-implementation of wxGrid::DrawCornerLabel which draws flat borders.
void onCellEditorHidden(wxGridEvent &aEvent)
void onGridColMove(wxGridEvent &aEvent)
void onCellEditorShown(wxGridEvent &aEvent)
void EnsureColLabelsVisible()
Ensure the height of the row displaying the column labels is enough, even if labels are multiline tex...
wxString GetShownColumnsAsString()
Get a tokenized string containing the shown column indexes.
void DrawRowLabel(wxDC &dc, int row) override
A re-implementation of wxGrid::DrawRowLabel which draws flat borders.
std::bitset< 64 > GetShownColumns()
void SetUnitsProvider(UNITS_PROVIDER *aProvider, int aCol=0)
Set a UNITS_PROVIDER to enable use of unit- and eval-based Getters.
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
std::unique_ptr< NUMERIC_EVALUATOR > m_eval
void DrawColLabel(wxDC &dc, int col) override
A re-implementation of wxGrid::DrawColLabel which left-aligns the first column and draws flat borders...
KICOMMON_API wxFont GetControlFont(wxWindow *aWindow)
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Functions to provide common constants and other functions to assist in making a consistent UI.
wxColour getBorderColour()
#define MIN_GRIDCELL_MARGIN