KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_user_defined_signals.cpp
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 (C) 2023 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 2
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, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include <scintilla_tricks.h>
27#include <grid_tricks.h>
29#include <../sim/simulator_frame.h>
31
32
34 std::map<int, wxString>* aSignals ) :
36 m_frame( aParent ),
37 m_signals( aSignals ),
38 m_helpWindow( nullptr )
39{
40 m_grid->PushEventHandler( new GRID_TRICKS( m_grid ) );
41
42 wxGridCellAttr* attr = new wxGridCellAttr;
43 attr->SetReadOnly();
44 m_grid->SetColAttr( 1, attr );
45
46 for( const auto& [ id, signal ] : *m_signals )
47 addGridRow( signal, id );
48
49 m_addButton->SetBitmap( KiBitmap( BITMAPS::small_plus ) );
50 m_deleteButton->SetBitmap( KiBitmap( BITMAPS::small_trash ) );
51
53 Layout();
54
55 // Now all widgets have the size fixed, call FinishDialogSettings
57}
58
59
61{
62 // Delete the GRID_TRICKS.
63 m_grid->PopEventHandler( true );
64
65 if( m_helpWindow )
66 m_helpWindow->Destroy();
67}
68
69
71{
72 if( !wxDialog::TransferDataToWindow() )
73 return false;
74
75 return true;
76}
77
78
79void DIALOG_USER_DEFINED_SIGNALS::addGridRow( const wxString& aText, int aId )
80{
81 int row = m_grid->GetNumberRows();
82
83 m_grid->AppendRows();
84 m_grid->SetCellValue( row, 0, aText );
85 m_grid->SetCellValue( row, 1, wxString::Format( wxS( "%d" ), aId ) );
86
87 wxGridCellAttr* attr = new wxGridCellAttr;
88 attr->SetEditor( new GRID_CELL_STC_EDITOR( true,
89 [this]( wxStyledTextEvent& aEvent, SCINTILLA_TRICKS* aScintillaTricks )
90 {
91 onScintillaCharAdded( aEvent, aScintillaTricks );
92 } ) );
93
94 m_grid->SetAttr( row, 0, attr );
95}
96
97
98void DIALOG_USER_DEFINED_SIGNALS::onAddSignal( wxCommandEvent& event )
99{
101 return;
102
103 long newId = 0;
104
105 for( int ii = 0; ii < m_grid->GetNumberRows(); ++ii )
106 {
107 long usedId;
108 m_grid->GetCellValue( ii, 1 ).ToLong( &usedId );
109
110 if( usedId > newId )
111 newId = usedId + 1;
112 }
113
114 addGridRow( wxEmptyString, (int) newId );
115
116 m_grid->MakeCellVisible( m_grid->GetNumberRows() - 1, 0 );
117 m_grid->SetGridCursor( m_grid->GetNumberRows() - 1, 0 );
118
119 m_grid->EnableCellEditControl( true );
120 m_grid->ShowCellEditControl();
121}
122
123
125{
126 int curRow = m_grid->GetGridCursorRow();
127
128 if( curRow < 0 || m_grid->GetNumberRows() <= curRow )
129 return;
130
131 m_grid->CommitPendingChanges( true /* silent mode; we don't care if it's valid */ );
132 m_grid->DeleteRows( curRow, 1 );
133
134 m_grid->MakeCellVisible( std::max( 0, curRow-1 ), m_grid->GetGridCursorCol() );
135 m_grid->SetGridCursor( std::max( 0, curRow-1 ), m_grid->GetGridCursorCol() );
136}
137
138
140 SCINTILLA_TRICKS* aTricks )
141{
142 wxStyledTextCtrl* textCtrl = aTricks->Scintilla();
143 wxArrayString tokens;
144
145 for( const wxString& signal : m_frame->Signals() )
146 tokens.push_back( signal );
147
148 tokens.push_back( wxS( "sqrt(x)" ) );
149 tokens.push_back( wxS( "sin(x)" ) );
150 tokens.push_back( wxS( "cos(x)" ) );
151 tokens.push_back( wxS( "tan(x)" ) );
152 tokens.push_back( wxS( "sinh(x)" ) );
153 tokens.push_back( wxS( "cosh(x)" ) );
154 tokens.push_back( wxS( "tanh(x)" ) );
155 tokens.push_back( wxS( "asin(x)" ) );
156 tokens.push_back( wxS( "acos(x)" ) );
157 tokens.push_back( wxS( "atan(x)" ) );
158 tokens.push_back( wxS( "asinh(x)" ) );
159 tokens.push_back( wxS( "acosh(x)" ) );
160 tokens.push_back( wxS( "atanh(x)" ) );
161 tokens.push_back( wxS( "arctan(x)" ) );
162 tokens.push_back( wxS( "exp(x)" ) );
163 tokens.push_back( wxS( "ln(x)" ) );
164 tokens.push_back( wxS( "log(x)" ) );
165 tokens.push_back( wxS( "abs(x)" ) );
166 tokens.push_back( wxS( "nint(x)" ) );
167 tokens.push_back( wxS( "int(x)" ) );
168 tokens.push_back( wxS( "floor(x)" ) );
169 tokens.push_back( wxS( "ceil(x)" ) );
170 tokens.push_back( wxS( "pow(x,y)" ) );
171 tokens.push_back( wxS( "pwr(x,y)" ) );
172 tokens.push_back( wxS( "min(x,y)" ) );
173 tokens.push_back( wxS( "max(x,y)" ) );
174 tokens.push_back( wxS( "sgn(x)" ) );
175 tokens.push_back( wxS( "ternary_fcn(x,y,z)" ) );
176 tokens.push_back( wxS( "gauss(nom,rvar,sigma)" ) );
177 tokens.push_back( wxS( "agauss(nom,avar,sigma)" ) );
178 tokens.push_back( wxS( "unif(nom,rvar)" ) );
179 tokens.push_back( wxS( "aunif(nom,avar)" ) );
180 tokens.push_back( wxS( "limit(nom,avar)" ) );
181
182 int text_pos = textCtrl->GetCurrentPos();
183 int start = textCtrl->WordStartPosition( text_pos, true );
184 int parenCount = 0;
185
186 for( start = text_pos - 1; start > 0; start-- )
187 {
188 wxUniChar c = textCtrl->GetCharAt( start );
189
190 if( c == '(' )
191 {
192 if( parenCount )
193 {
194 start += 1;
195 break;
196 }
197 else
198 {
199 parenCount++;
200 }
201 }
202 else if( wxIsalpha( c ) && parenCount )
203 {
204 break;
205 }
206 else if( !wxIsalnum( c ) && c != '/' )
207 {
208 start += 1;
209 break;
210 }
211 }
212
213 wxString partial = textCtrl->GetRange( start, text_pos );
214
215 aTricks->DoAutocomplete( partial, tokens );
216 textCtrl->SetFocus();
217}
218
219
221{
222 if( !wxDialog::TransferDataFromWindow() )
223 return false;
224
226 return false;
227
228 m_signals->clear();
229
230 for( int ii = 0; ii < m_grid->GetNumberRows(); ++ii )
231 {
232 wxString signal = m_grid->GetCellValue( ii, 0 );
233
234 if( !signal.IsEmpty() )
235 {
236 long id;
237 m_grid->GetCellValue( ii, 1 ).ToLong( &id );
238 (*m_signals)[ (int) id ] = signal;
239 }
240 }
241
242 return true;
243}
244
245
246void DIALOG_USER_DEFINED_SIGNALS::OnFormattingHelp( wxHyperlinkEvent& aEvent )
247{
249}
250
251
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:106
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
Class DIALOG_USER_DEFINED_SIGNALS_BASE.
void onAddSignal(wxCommandEvent &event) override
DIALOG_USER_DEFINED_SIGNALS(SIMULATOR_FRAME *parent, std::map< int, wxString > *aSignals)
void onDeleteSignal(wxCommandEvent &event) override
void addGridRow(const wxString &aValue, int aId)
void onScintillaCharAdded(wxStyledTextEvent &aEvent, SCINTILLA_TRICKS *aTricks)
std::map< int, wxString > * m_signals
void OnFormattingHelp(wxHyperlinkEvent &aEvent) override
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition: grid_tricks.h:61
static HTML_MESSAGE_BOX * ShowSyntaxHelp(wxWindow *aParentWindow)
Definition: sch_label.cpp:1804
Add cut/copy/paste, dark theme, autocomplete and brace highlighting to a wxStyleTextCtrl instance.
wxStyledTextCtrl * Scintilla() const
void DoAutocomplete(const wxString &aPartial, const wxArrayString &aTokens)
The SIMULATOR_FRAME holds the main user-interface for running simulations.
const std::vector< wxString > & Signals()
void SetBitmap(const wxBitmapBundle &aBmp)
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:474