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