KiCad PCB EDA Suite
Loading...
Searching...
No Matches
wx_grid.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 3
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#pragma once
21
22#include <bitset>
23#include <memory>
24#include <utility>
25#include <vector>
26
27#include <wx/event.h>
28#include <wx/grid.h>
29#include <wx/version.h>
30
31#include <kicommon.h>
33#include <units_provider.h>
34
35class wxTextEntryBase;
37
38
44{
45 // This does not mean the row contains only one item. For instance,
46 // a row might contain references to U1A and U1B but symbol fields aren't
47 // independently editable for units of one symbol, so the row DATA_MODEL_ROW
48 // will contain multiple references but not be expandable to multiple child items
50 // Synthetic headers display and edit every member of the group.
54 // Real parent headers display and edit only the first member, above its descendants.
58 EXPANDED_CHILD
59};
60
61
62inline bool IsParentRow( ROW_STATE aState )
63{
64 return aState == ROW_STATE::PARENT_COLLAPSED || aState == ROW_STATE::PARENT_COLLAPSED_DURING_SORT
65 || aState == ROW_STATE::PARENT_EXPANDED;
66}
67
68
69inline bool IsRowCollapsed( ROW_STATE aState )
70{
71 return aState == ROW_STATE::GROUP_COLLAPSED || aState == ROW_STATE::PARENT_COLLAPSED;
72}
73
74
75inline bool IsRowExpanded( ROW_STATE aState )
76{
77 return aState == ROW_STATE::GROUP_EXPANDED || aState == ROW_STATE::PARENT_EXPANDED;
78}
79
80
81class KICOMMON_API WX_GRID_TABLE_BASE : public wxGridTableBase
82{
83public:
85 {
86 for( const auto& [col, attr] : m_colAttrs )
87 wxSafeDecRef( attr );
88 }
89
90 void SetColAttr( wxGridCellAttr* aAttr, int aCol ) override
91 {
92 wxSafeDecRef( m_colAttrs[aCol] );
93 m_colAttrs[aCol] = aAttr;
94 }
95
96 wxGridCellAttr* GetAttr( int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind ) override
97 {
98 if( m_colAttrs[aCol] )
99 {
100 m_colAttrs[aCol]->IncRef();
101 return enhanceAttr( m_colAttrs[aCol], aRow, aCol, aKind );
102 }
103
104 return enhanceAttr( nullptr, aRow, aCol, aKind );
105 }
106
108 virtual bool HasRowLabelExpanders() const { return false; }
109 virtual ROW_STATE GetRowState( int aRow ) const { return ROW_STATE::NON_EXPANDABLE; }
110
118 virtual bool HasUndoStateSerialization() const { return false; }
119 virtual wxString SerializeUndoState() const { return wxEmptyString; }
120 virtual void RestoreUndoState( const wxString& aState ) {}
121
122 void Clear() override
123 {
124 if( GetNumberRows() )
125 DeleteRows( 0, GetNumberRows() );
126 }
127
128protected:
129 wxGridCellAttr* enhanceAttr( wxGridCellAttr* aInputAttr, int aRow, int aCol,
130 wxGridCellAttr::wxAttrKind aKind );
131
132protected:
133 std::map<int, wxGridCellAttr*> m_colAttrs;
134};
135
136
137class KICOMMON_API WX_GRID : public wxGrid
138{
139public:
140 // Constructor has to be wxFormBuilder-compatible
141 WX_GRID( wxWindow *parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition,
142 const wxSize& size = wxDefaultSize, long style = wxWANTS_CHARS,
143 const wxString& name = wxGridNameStr );
144
145 ~WX_GRID() override;
146
153 void SetColLabelSize( int aHeight ); // Yes, we're hiding a non-virtual method
154
159 void SetLabelFont( const wxFont& aFont ); // Yes, we're hiding a non-virtual method
160
167 void EnableAlternateRowColors( bool aEnable = true );
168
172 void EnableCursorRowColumnHighlight( bool aEnable = true ) { m_cursorRowColumnHighlight = aEnable; }
173
175
181 wxString GetShownColumnsAsString();
182 std::bitset<64> GetShownColumns();
183
187 void ShowHideColumns( const wxString& shownColumns );
188
193 void SetTable( wxGridTableBase* table, bool aTakeOwnership = false );
194
199 void DestroyTable( wxGridTableBase* aTable );
200
207 bool CommitPendingChanges( bool aQuietMode = false );
208 bool CancelPendingChanges();
209
210 void OnAddRow( const std::function<std::pair<int, int>()>& aAdder );
211
216 void OnDeleteRows( const std::function<void( int row )>& aDeleter );
217
218 void OnDeleteRows( const std::function<bool( int row )>& aFilter,
219 const std::function<void( int row )>& aDeleter );
220
224 void SwapRows( int aRowA, int aRowB );
225 void OnMoveRowUp( const std::function<void( int row )>& aMover );
226 void OnMoveRowDown( const std::function<void( int row )>& aMover );
227 void OnMoveRowUp( const std::function<bool( int row )>& aFilter,
228 const std::function<void( int row )>& aMover );
229 void OnMoveRowDown( const std::function<bool( int row )>& aFilter,
230 const std::function<void( int row )>& aMover );
231
238 void SetUnitsProvider( UNITS_PROVIDER* aProvider, int aCol = 0 );
239
240 void SetAutoEvalCols( const std::vector<int>& aCols ) { m_autoEvalCols = aCols; }
241
245 void SetAutoEvalColUnits( int col, EDA_UNITS aUnit, EDA_DATA_TYPE aUnitType );
246
250 void SetAutoEvalColUnits( int col, EDA_UNITS aUnit );
251
259 int GetUnitValue( int aRow, int aCol );
260
268 std::optional<int> GetOptionalUnitValue( int aRow, int aCol );
269
273 void SetUnitValue( int aRow, int aCol, int aValue );
274
278 void SetOptionalUnitValue( int aRow, int aCol, std::optional<int> aValue );
279
289 int GetVisibleWidth( int aCol, bool aHeader = true, bool aContents = true, bool aKeep = false );
290
295 void EnsureColLabelsVisible();
296
305 void ShowEditorOnMouseUp() { m_waitForSlowClick = true; }
306 void CancelShowEditorOnMouseUp() { m_waitForSlowClick = false; }
307
313 void ClearRows( bool aUpdateLabels = true )
314 {
315 if( GetNumberRows() > 0 )
316 DeleteRows( 0, GetNumberRows(), aUpdateLabels );
317 }
318
322 static void CellEditorSetMargins( wxTextEntryBase* aEntry );
323
327 static void CellEditorTransformSizeRect( wxRect& aRect );
328
336 void OverrideMinSize( double aXPct, double aYPct )
337 {
338 wxSize size = DoGetBestSize();
339 m_minSizeOverride = wxSize( KiROUND( size.x * aXPct ), KiROUND( size.y * aYPct ) );
340 }
341
349 void SetMinVisibleRows( wxWindow* aDialog, int aMinRows );
350
360 static int CapHeightToVisibleRows( int aMinHeight, int aHeaderHeight,
361 const std::vector<int>& aRowHeights, int aMaxRows );
362
363 wxSize DoGetBestSize() const override
364 {
366 return m_minSizeOverride.value();
367 else
368 return wxGrid::DoGetBestSize();
369 }
370
375 void SetupColumnAutosizer( int aFlexibleCol );
376
378
380
381 void RecomputeGridWidths();
382
383protected:
388 void DrawColLabel( wxDC& dc, int col ) override;
389
393 void DrawRowLabel( wxDC& dc, int row ) override;
394
398 void DrawCornerLabel( wxDC& dc ) override;
399
400 void onGridColMove( wxGridEvent& aEvent );
401 void onGridCellSelect( wxGridEvent& aEvent );
402 void onCellEditorShown( wxGridEvent& aEvent );
403 void onCellEditorHidden( wxGridEvent& aEvent );
404
405#ifdef __WXMSW__
407 void onIdleRefreshHighlight( wxIdleEvent& aEvent );
408#endif
409
410 void onDPIChanged(wxDPIChangedEvent& event);
411
413 {
414 if( m_unitsProviders.contains( aCol ) )
415 return m_unitsProviders.at( aCol );
416 else
417 return m_unitsProviders.begin()->second;
418 }
419
423 std::pair<EDA_UNITS, EDA_DATA_TYPE> getColumnUnits( int aCol ) const;
424
425private:
426 void onSizeEvent( wxSizeEvent& aEvent );
427
428protected:
431
432 std::map<int, UNITS_PROVIDER*> m_unitsProviders;
433 std::unique_ptr<NUMERIC_EVALUATOR> m_eval;
434 std::vector<int> m_autoEvalCols;
435 std::unordered_map<int, std::pair<EDA_UNITS, EDA_DATA_TYPE>> m_autoEvalColsUnits;
436 std::map< std::pair<int, int>, std::pair<wxString, wxString> > m_evalBeforeAfter;
437
438 std::optional<wxSize> m_minSizeOverride;
439
440 std::map<int, int> m_autosizedCols; // map of col : min_width
442
443 bool m_gridWidthsDirty = true;
444 int m_gridWidth = 0;
445
447};
const char * name
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:982
Icon provider for the "standard" row indicators, for example in layer selection lists.
~WX_GRID_TABLE_BASE() override
Definition wx_grid.h:84
virtual void RestoreUndoState(const wxString &aState)
Definition wx_grid.h:120
virtual ROW_STATE GetRowState(int aRow) const
Definition wx_grid.h:109
virtual bool HasRowLabelExpanders() const
Show grouping controls in the row headers instead of row numbers.
Definition wx_grid.h:108
wxGridCellAttr * enhanceAttr(wxGridCellAttr *aInputAttr, int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind)
Definition wx_grid.cpp:43
std::map< int, wxGridCellAttr * > m_colAttrs
Definition wx_grid.h:133
void Clear() override
Definition wx_grid.h:122
wxGridCellAttr * GetAttr(int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind) override
Definition wx_grid.h:96
void SetColAttr(wxGridCellAttr *aAttr, int aCol) override
Definition wx_grid.h:90
virtual wxString SerializeUndoState() const
Definition wx_grid.h:119
virtual bool HasUndoStateSerialization() const
Optional identity-based serialization for the host dialog's Ctrl+Z/Ctrl+Y.
Definition wx_grid.h:118
int m_flexibleCol
Definition wx_grid.h:441
std::map< int, int > m_autosizedCols
Definition wx_grid.h:440
bool m_gridWidthsDirty
Definition wx_grid.h:443
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...
Definition wx_grid.cpp:341
bool m_weOwnTable
Definition wx_grid.h:429
std::map< int, UNITS_PROVIDER * > m_unitsProviders
Definition wx_grid.h:432
std::optional< wxSize > m_minSizeOverride
Definition wx_grid.h:438
std::unordered_map< int, std::pair< EDA_UNITS, EDA_DATA_TYPE > > m_autoEvalColsUnits
Definition wx_grid.h:435
void OverrideMinSize(double aXPct, double aYPct)
Grids that have column sizes automatically set to fill the available width don't want to shrink after...
Definition wx_grid.h:336
void SetColLabelSize(int aHeight)
Hide wxGrid's SetColLabelSize() method with one which makes sure the size is tall enough for the syst...
Definition wx_grid.cpp:326
WX_GRID(wxWindow *parent, wxWindowID id, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxWANTS_CHARS, const wxString &name=wxGridNameStr)
Definition wx_grid.cpp:250
void SetGridWidthsDirty()
Definition wx_grid.h:377
void EnableCursorRowColumnHighlight(bool aEnable=true)
Enable repainting for grids whose table uses the cursor row and column when rendering cells.
Definition wx_grid.h:172
std::vector< int > m_autoEvalCols
Definition wx_grid.h:434
UNITS_PROVIDER * getUnitsProvider(int aCol) const
Definition wx_grid.h:412
std::map< std::pair< int, int >, std::pair< wxString, wxString > > m_evalBeforeAfter
Definition wx_grid.h:436
void CancelShowEditorOnMouseUp()
Definition wx_grid.h:306
bool m_cursorRowColumnHighlight
Definition wx_grid.h:430
void ClearRows(bool aUpdateLabels=true)
wxWidgets recently added an ASSERT which fires if the position is greater than or equal to the number...
Definition wx_grid.h:313
ROW_ICON_PROVIDER * m_rowIconProvider
Definition wx_grid.h:446
void ShowEditorOnMouseUp()
WxWidgets has a bunch of bugs in its handling of wxGrid mouse events which close cell editors right a...
Definition wx_grid.h:305
bool IsCursorRowColumnHighlightEnabled() const
Definition wx_grid.h:174
int m_gridWidth
Definition wx_grid.h:444
void SetAutoEvalCols(const std::vector< int > &aCols)
Definition wx_grid.h:240
void EnableAlternateRowColors(bool aEnable=true)
Enable alternate row highlighting, where every odd row has a different background color than the even...
Definition wx_grid.cpp:386
ROW_ICON_PROVIDER * GetRowIconProvider() const
Definition wx_grid.h:379
std::unique_ptr< NUMERIC_EVALUATOR > m_eval
Definition wx_grid.h:433
wxSize DoGetBestSize() const override
Definition wx_grid.h:363
EDA_DATA_TYPE
The type of unit.
Definition eda_units.h:34
EDA_UNITS
Definition eda_units.h:44
#define KICOMMON_API
Definition kicommon.h:27
bool IsRowCollapsed(ROW_STATE aState)
Definition wx_grid.h:69
enum KICOMMON_API ROW_STATE
Used primarily by the fields tables to collapse multiple grouped symbols, etc.
Definition wx_grid.h:44
bool IsParentRow(ROW_STATE aState)
Definition wx_grid.h:62
PARENT_COLLAPSED
Definition wx_grid.h:55
NON_EXPANDABLE
Definition wx_grid.h:49
PARENT_EXPANDED
Definition wx_grid.h:57
GROUP_COLLAPSED_DURING_SORT
Definition wx_grid.h:52
PARENT_COLLAPSED_DURING_SORT
Definition wx_grid.h:56
GROUP_COLLAPSED
Definition wx_grid.h:51
GROUP_EXPANDED
Definition wx_grid.h:53
bool IsRowExpanded(ROW_STATE aState)
Definition wx_grid.h:75