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 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 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, see <https://www.gnu.org/licenses/>.
18 */
19
20#include <scintilla_tricks.h>
23#include <grid_tricks.h>
27#include <string_utils.h>
28
29
31 std::map<int, wxString>* aSignals ) :
33 m_frame( aParent ),
34 m_signals( aSignals ),
35 m_helpWindow( nullptr )
36{
37 m_grid->PushEventHandler( new GRID_TRICKS( m_grid ) );
38
39 wxGridCellAttr* attr = new wxGridCellAttr;
40 attr->SetReadOnly();
41 m_grid->SetColAttr( 1, attr );
42
43 for( const auto& [ id, signal ] : *m_signals )
44 addGridRow( signal, id );
45
48
50 Layout();
51
52 // Now all widgets have the size fixed, call FinishDialogSettings
54}
55
56
58{
59 // Delete the GRID_TRICKS.
60 m_grid->PopEventHandler( true );
61
62 if( m_helpWindow )
63 m_helpWindow->Destroy();
64}
65
66
67void DIALOG_USER_DEFINED_SIGNALS::addGridRow( const wxString& aText, int aId )
68{
69 int row = m_grid->GetNumberRows();
70
71 m_grid->AppendRows();
72 m_grid->SetCellValue( row, 0, aText );
73 m_grid->SetCellValue( row, 1, wxString::Format( wxS( "%d" ), aId ) );
74
75 wxGridCellAttr* attr = new wxGridCellAttr;
76 attr->SetEditor( new GRID_CELL_STC_EDITOR( true, true,
77 [this]( wxStyledTextEvent& aEvent, SCINTILLA_TRICKS* aScintillaTricks )
78 {
79 onScintillaCharAdded( aEvent, aScintillaTricks );
80 } ) );
81 m_grid->SetAttr( row, 0, attr );
82}
83
84
85void DIALOG_USER_DEFINED_SIGNALS::onAddSignal( wxCommandEvent& event )
86{
87 m_grid->OnAddRow(
88 [&]() -> std::pair<int, int>
89 {
90 long newId = 0;
91
92 for( int ii = 0; ii < m_grid->GetNumberRows(); ++ii )
93 {
94 long usedId;
95 m_grid->GetCellValue( ii, 1 ).ToLong( &usedId );
96
97 if( usedId >= newId )
98 newId = usedId + 1;
99 }
100
101 addGridRow( wxEmptyString, (int) newId );
102 return { m_grid->GetNumberRows() - 1, 0 };
103 } );
104}
105
106
108{
109 m_grid->OnDeleteRows(
110 [&]( int row )
111 {
112 m_grid->DeleteRows( row, 1 );
113 } );
114}
115
116
118{
119 wxStyledTextCtrl* textCtrl = aTricks->Scintilla();
120 wxArrayString tokens;
121
122 for( const wxString& signal : m_frame->SimPlotVectors() )
123 tokens.push_back( signal );
124
125 tokens.push_back( wxS( "sqrt(x)" ) );
126 tokens.push_back( wxS( "sin(x)" ) );
127 tokens.push_back( wxS( "cos(x)" ) );
128 tokens.push_back( wxS( "tan(x)" ) );
129 tokens.push_back( wxS( "sinh(x)" ) );
130 tokens.push_back( wxS( "cosh(x)" ) );
131 tokens.push_back( wxS( "tanh(x)" ) );
132 tokens.push_back( wxS( "asin(x)" ) );
133 tokens.push_back( wxS( "acos(x)" ) );
134 tokens.push_back( wxS( "atan(x)" ) );
135 tokens.push_back( wxS( "asinh(x)" ) );
136 tokens.push_back( wxS( "acosh(x)" ) );
137 tokens.push_back( wxS( "atanh(x)" ) );
138 tokens.push_back( wxS( "arctan(x)" ) );
139 tokens.push_back( wxS( "exp(x)" ) );
140 tokens.push_back( wxS( "ln(x)" ) );
141 tokens.push_back( wxS( "log(x)" ) );
142 tokens.push_back( wxS( "abs(x)" ) );
143 tokens.push_back( wxS( "nint(x)" ) );
144 tokens.push_back( wxS( "int(x)" ) );
145 tokens.push_back( wxS( "floor(x)" ) );
146 tokens.push_back( wxS( "ceil(x)" ) );
147 tokens.push_back( wxS( "pow(x,y)" ) );
148 tokens.push_back( wxS( "pwr(x,y)" ) );
149 tokens.push_back( wxS( "min(x,y)" ) );
150 tokens.push_back( wxS( "max(x,y)" ) );
151 tokens.push_back( wxS( "sgn(x)" ) );
152 tokens.push_back( wxS( "ternary_fcn(x,y,z)" ) );
153 tokens.push_back( wxS( "gauss(nom,rvar,sigma)" ) );
154 tokens.push_back( wxS( "agauss(nom,avar,sigma)" ) );
155 tokens.push_back( wxS( "unif(nom,rvar)" ) );
156 tokens.push_back( wxS( "aunif(nom,avar)" ) );
157 tokens.push_back( wxS( "limit(nom,avar)" ) );
158
159 int text_pos = textCtrl->GetCurrentPos();
160 int start = textCtrl->WordStartPosition( text_pos, true );
161 int parenCount = 0;
162
163 for( start = text_pos - 1; start > 0; start-- )
164 {
165 wxUniChar c = textCtrl->GetCharAt( start );
166
167 if( c == '(' )
168 {
169 if( parenCount )
170 {
171 start += 1;
172 break;
173 }
174 else
175 {
176 parenCount++;
177 }
178 }
179 else if( wxIsalpha( c ) && parenCount )
180 {
181 break;
182 }
183 else if( !wxIsalnum( c ) && c != '/' )
184 {
185 start += 1;
186 break;
187 }
188 }
189
190 if( start >= 0 ) // i.e. at least one char entered
191 {
192 wxString partial = textCtrl->GetRange( start, text_pos );
193 aTricks->DoAutocomplete( partial, tokens );
194 }
195
196 textCtrl->SetFocus();
197}
198
199
201{
202 if( !wxDialog::TransferDataFromWindow() )
203 return false;
204
205 if( !m_grid->CommitPendingChanges() )
206 return false;
207
208 m_signals->clear();
209
210 for( int ii = 0; ii < m_grid->GetNumberRows(); ++ii )
211 {
212 wxString signal = m_grid->GetCellValue( ii, 0 );
213
214 if( !signal.IsEmpty() )
215 {
216 long id;
217 m_grid->GetCellValue( ii, 1 ).ToLong( &id );
218 (*m_signals)[ (int) id ] = signal;
219 }
220 }
221
222 return true;
223}
224
225
226void DIALOG_USER_DEFINED_SIGNALS::OnFormattingHelp( wxHyperlinkEvent& aEvent )
227{
228 wxString msg =
230 ;
231
232 m_helpWindow = new HTML_MESSAGE_BOX( nullptr, _( "Syntax Help" ) );
233
234 wxSize sz( 320, 320 );
235 m_helpWindow->SetMinSize( m_helpWindow->ConvertDialogToPixels( sz ) );
236 m_helpWindow->SetDialogSizeInDU( sz.x, sz.y );
237
238 wxString html_txt;
239 ConvertMarkdown2Html( wxGetTranslation( msg ), html_txt );
240 m_helpWindow->AddHTML_Text( html_txt );
241 m_helpWindow->ShowModeless();
242}
243
244
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
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...
DIALOG_USER_DEFINED_SIGNALS_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("User-defined Signals"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
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:57
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.
#define _(s)
void ConvertMarkdown2Html(const wxString &aMarkdownInput, wxString &aHtmlOutput)