24#include <wx/tokenzr.h>
26#include <wx/settings.h>
34#define MIN_GRIDCELL_MARGIN 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 )
141 wxGrid::SetColLabelSize( 0 );
147 wxGrid::SetColLabelSize( std::max( aHeight, minHeight ) );
161 int numberCols = GetNumberCols();
162 int* formBuilderColWidths =
new int[numberCols];
164 for(
int i = 0; i < numberCols; ++i )
165 formBuilderColWidths[ i ] = GetColSize( i );
167 wxGrid::SetTable( aTable );
171 numberCols = std::min( numberCols, GetNumberCols() );
173 for(
int i = 0; i < numberCols; ++i )
178 SetColSize( i, std::max( formBuilderColWidths[ i ], headingWidth ) );
181 delete[] formBuilderColWidths;
195 int row = aEvent.GetRow();
196 int col = aEvent.GetCol();
198 if( row >= 0 && col >= 0 )
199 SelectBlock( row, col, row, col,
false );
207 int row = aEvent.GetRow();
208 int col = aEvent.GetCol();
210 const std::pair<wxString, wxString>& beforeAfter =
m_evalBeforeAfter[ { row, col } ];
212 if( GetCellValue( row, col ) == beforeAfter.second )
213 SetCellValue( row, col, beforeAfter.first );
229 int row = aEvent.GetRow();
230 int col = aEvent.GetCol();
233 [
this, row, col, unitsProvider]()
235 wxString stringValue = GetCellValue( row, col );
237 if(
m_eval->Process( stringValue ) )
242 if( stringValue != evalValue )
244 SetCellValue( row, col, evalValue );
264 wxGrid::SetTable(
nullptr );
271 wxString shownColumns;
273 for(
int i = 0; i < GetNumberCols(); ++i )
275 if( IsColShown( i ) )
277 if( shownColumns.Length() )
278 shownColumns << wxT(
" " );
290 std::bitset<64> shownColumns;
292 for(
int ii = 0; ii < GetNumberCols(); ++ii )
293 shownColumns[ii] = IsColShown( ii );
301 for(
int i = 0; i < GetNumberCols(); ++i )
304 wxStringTokenizer shownTokens( shownColumns );
306 while( shownTokens.HasMoreTokens() )
309 shownTokens.GetNextToken().ToLong( &colNumber );
311 if( colNumber >= 0 && colNumber < GetNumberCols() )
312 ShowCol( (
int) colNumber );
319 for(
int ii = 0; ii < GetNumberCols(); ++ ii )
321 if( aShownColumns[ii] )
331 if( m_nativeColumnLabels )
332 wxGrid::DrawCornerLabel( dc );
334 wxRect rect( wxSize( m_rowLabelWidth, m_colLabelHeight ) );
341 wxDCBrushChanger setBrush( dc, m_colLabelWin->GetBackgroundColour() );
342 wxDCPenChanger setPen( dc, m_colLabelWin->GetBackgroundColour() );
343 dc.DrawRectangle( rect.Inflate( 1 ) );
352 if( m_nativeColumnLabels )
353 wxGrid::DrawColLabel( dc, col );
355 if( GetColWidth( col ) <= 0 || m_colLabelHeight <= 0 )
358 wxRect rect( GetColLeft( col ), 0, GetColWidth( col ), m_colLabelHeight );
365 wxDCBrushChanger setBrush( dc, m_colLabelWin->GetBackgroundColour() );
366 wxDCPenChanger setPen( dc, m_colLabelWin->GetBackgroundColour() );
367 dc.DrawRectangle( rect.Inflate( 1 ) );
373 dc.SetFont( GetLabelFont() );
376 GetColLabelAlignment( &hAlign, &vAlign );
377 const int orient = GetColLabelTextOrientation();
380 hAlign = wxALIGN_LEFT;
382 if( hAlign == wxALIGN_LEFT )
385 rend.DrawLabel( *
this, dc, GetColLabelValue( col ), rect, hAlign, vAlign, orient );
391 if ( GetRowHeight( row ) <= 0 || m_rowLabelWidth <= 0 )
394 wxRect rect( 0, GetRowTop( row ), m_rowLabelWidth, GetRowHeight( row ) );
401 wxDCBrushChanger setBrush( dc, m_colLabelWin->GetBackgroundColour() );
402 wxDCPenChanger setPen( dc, m_colLabelWin->GetBackgroundColour() );
403 dc.DrawRectangle( rect.Inflate( 1 ) );
409 dc.SetFont( GetLabelFont() );
412 GetRowLabelAlignment(&hAlign, &vAlign);
414 if( hAlign == wxALIGN_LEFT )
417 rend.DrawLabel( *
this, dc, GetRowLabelValue( row ), rect, hAlign, vAlign, wxHORIZONTAL );
423 if( !IsCellEditControlEnabled() )
426 HideCellEditControl();
429 m_cellEditCtrlEnabled =
false;
431 int row = m_currentCellCoords.GetRow();
432 int col = m_currentCellCoords.GetCol();
434 wxString oldval = GetCellValue( row, col );
437 wxGridCellAttr* attr = GetCellAttr( row, col );
438 wxGridCellEditor*
editor = attr->GetEditor(
this, row, col );
440 editor->EndEdit( row, col,
this, oldval, &newval );
451 if( !IsCellEditControlEnabled() )
454 if( !aQuietMode && SendEvent( wxEVT_GRID_EDITOR_HIDDEN ) == -1 )
457 HideCellEditControl();
460 m_cellEditCtrlEnabled =
false;
462 int row = m_currentCellCoords.GetRow();
463 int col = m_currentCellCoords.GetCol();
465 wxString oldval = GetCellValue( row, col );
468 wxGridCellAttr* attr = GetCellAttr( row, col );
469 wxGridCellEditor*
editor = attr->GetEditor(
this, row, col );
471 bool changed =
editor->EndEdit( row, col,
this, oldval, &newval );
478 if( !aQuietMode && SendEvent( wxEVT_GRID_CELL_CHANGING, newval ) == -1 )
481 editor->ApplyEdit( row, col,
this );
486 if( !aQuietMode && SendEvent( wxEVT_GRID_CELL_CHANGED, oldval ) == -1 )
489 SetCellValue( row, col, oldval );
514 wxString stringValue = GetCellValue( aRow, aCol );
520 if(
m_eval->Process( stringValue ) )
521 stringValue =
m_eval->Result();
535 SetCellValue( aRow, aCol, unitsProvider->
StringFromValue( aValue,
true ) );
553 size = GetRowLabelSize();
555 for(
int row = 0; aContents && row < GetNumberRows(); row++ )
556 size = std::max( size,
int( GetTextExtent( GetRowLabelValue( row ) + wxS(
"M" ) ).x ) );
561 size = GetColSize( aCol );
569 size = std::max( size,
int( GetTextExtent( GetColLabelValue( aCol ) + wxS(
"M" ) ).x ) );
572 for(
int row = 0; aContents && row < GetNumberRows(); row++ )
575 if( GetTable()->CanGetValueAs( row, aCol, wxGRID_VALUE_STRING ) )
576 size = std::max( size, GetTextExtent( GetCellValue( row, aCol ) + wxS(
"M" ) ).x );
578 size = std::max( size, GetTextExtent(
"MM" ).x );
588 int line_height = int( GetTextExtent(
"Mj" ).y ) + 3;
589 int row_height = GetColLabelSize();
590 int initial_row_height = row_height;
595 for(
int col = 0; col < GetNumberCols(); col++ )
597 int nl_count = GetColLabelValue( col ).Freq(
'\n' );
602 if( row_height < line_height * ( nl_count+1 ) )
603 row_height += line_height * nl_count;
609 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.
wxString StringFromValue(double aValue, bool aAddUnitLabel=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Converts aValue in internal units into a united string.
int ValueFromString(const wxString &aTextValue, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Converts aTextValue in aUnits to internal units used by the frame.
EDA_UNITS GetUserUnits() const
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...
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