KiCad PCB EDA Suite
Loading...
Searching...
No Matches
scintilla_tricks.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, 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
25#include <string_utils.h>
26#include <scintilla_tricks.h>
27#include <widgets/wx_grid.h>
28#include <widgets/ui_common.h>
29#include <wx/stc/stc.h>
30#include <gal/color4d.h>
31#include <dialog_shim.h>
32#include <wx/clipbrd.h>
33#include <wx/log.h>
34#include <wx/settings.h>
35#include <confirm.h>
36#include <grid_tricks.h>
37
38SCINTILLA_TRICKS::SCINTILLA_TRICKS( wxStyledTextCtrl* aScintilla, const wxString& aBraces,
39 bool aSingleLine,
40 std::function<void( wxKeyEvent& )> onAcceptFn,
41 std::function<void( wxStyledTextEvent& )> onCharAddedFn ) :
42 m_te( aScintilla ),
43 m_braces( aBraces ),
44 m_lastCaretPos( -1 ),
45 m_lastSelStart( -1 ),
46 m_lastSelEnd( -1 ),
47 m_suppressAutocomplete( false ),
48 m_singleLine( aSingleLine ),
49 m_onAcceptFn( std::move( onAcceptFn ) ),
50 m_onCharAddedFn( std::move( onCharAddedFn ) )
51{
52 // Always use LF as eol char, regardless the platform
53 m_te->SetEOLMode( wxSTC_EOL_LF );
54
55 // A hack which causes Scintilla to auto-size the text editor canvas
56 // See: https://github.com/jacobslusser/ScintillaNET/issues/216
57 m_te->SetScrollWidth( 1 );
58 m_te->SetScrollWidthTracking( true );
59
60 if( m_singleLine )
61 {
62 m_te->SetUseVerticalScrollBar( false );
63 m_te->SetUseHorizontalScrollBar( false );
64 }
65
67
68 // Set up autocomplete
69 m_te->AutoCompSetIgnoreCase( true );
70 m_te->AutoCompSetMaxHeight( 20 );
71
72 if( aBraces.Length() >= 2 )
73 m_te->AutoCompSetFillUps( m_braces[1] );
74
75 // Hook up events
76 m_te->Bind( wxEVT_STC_UPDATEUI, &SCINTILLA_TRICKS::onScintillaUpdateUI, this );
77 m_te->Bind( wxEVT_STC_MODIFIED, &SCINTILLA_TRICKS::onModified, this );
78
79 // Handle autocomplete
80 m_te->Bind( wxEVT_STC_CHARADDED, &SCINTILLA_TRICKS::onChar, this );
81 m_te->Bind( wxEVT_STC_AUTOCOMP_CHAR_DELETED, &SCINTILLA_TRICKS::onChar, this );
82
83 // Dispatch command-keys in Scintilla control.
84 m_te->Bind( wxEVT_CHAR_HOOK, &SCINTILLA_TRICKS::onCharHook, this );
85
86 m_te->Bind( wxEVT_SYS_COLOUR_CHANGED,
87 wxSysColourChangedEventHandler( SCINTILLA_TRICKS::onThemeChanged ), this );
88}
89
90
91void SCINTILLA_TRICKS::onThemeChanged( wxSysColourChangedEvent &aEvent )
92{
94
95 aEvent.Skip();
96}
97
98
100{
101 wxTextCtrl dummy( m_te->GetParent(), wxID_ANY );
102 KIGFX::COLOR4D foreground = dummy.GetForegroundColour();
103 KIGFX::COLOR4D background = dummy.GetBackgroundColour();
104 KIGFX::COLOR4D highlight = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT );
105 KIGFX::COLOR4D highlightText = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHTTEXT );
106
107 m_te->StyleSetForeground( wxSTC_STYLE_DEFAULT, foreground.ToColour() );
108 m_te->StyleSetBackground( wxSTC_STYLE_DEFAULT, background.ToColour() );
109 m_te->StyleClearAll();
110
111 // Scintilla doesn't handle alpha channel, which at least OSX uses in some highlight colours,
112 // such as "graphite".
113 highlight = highlight.Mix( background, highlight.a ).WithAlpha( 1.0 );
114 highlightText = highlightText.Mix( background, highlightText.a ).WithAlpha( 1.0 );
115
116 m_te->SetSelForeground( true, highlightText.ToColour() );
117 m_te->SetSelBackground( true, highlight.ToColour() );
118 m_te->SetCaretForeground( foreground.ToColour() );
119
120 if( !m_singleLine )
121 {
122 // Set a monospace font with a tab width of 4. This is the closest we can get to having
123 // Scintilla mimic the stroke font's tab positioning.
124 wxFont fixedFont = KIUI::GetMonospacedUIFont();
125
126 for( size_t i = 0; i < wxSTC_STYLE_MAX; ++i )
127 m_te->StyleSetFont( i, fixedFont );
128
129 m_te->SetTabWidth( 4 );
130 }
131
132 // Set up the brace highlighting. Scintilla doesn't handle alpha, so we construct our own
133 // 20% wash by blending with the background.
134 KIGFX::COLOR4D braceText = foreground;
135 KIGFX::COLOR4D braceHighlight = braceText.Mix( background, 0.2 );
136
137 m_te->StyleSetForeground( wxSTC_STYLE_BRACELIGHT, highlightText.ToColour() );
138 m_te->StyleSetBackground( wxSTC_STYLE_BRACELIGHT, braceHighlight.ToColour() );
139 m_te->StyleSetForeground( wxSTC_STYLE_BRACEBAD, *wxRED );
140}
141
142
143bool isCtrlSlash( wxKeyEvent& aEvent )
144{
145 if( !aEvent.ControlDown() || aEvent.MetaDown() )
146 return false;
147
148 if( aEvent.GetUnicodeKey() == '/' )
149 return true;
150
151 // OK, now the wxWidgets hacks start.
152 // (We should abandon these if https://trac.wxwidgets.org/ticket/18911 gets resolved.)
153
154 // Many Latin America and European keyboards have have the / over the 7. We know that
155 // wxWidgets messes this up and returns Shift+7 through GetUnicodeKey(). However, other
156 // keyboards (such as France and Belgium) have 7 in the shifted position, so a Shift+7
157 // *could* be legitimate.
158
159 // However, we *are* checking Ctrl, so to assume any Shift+7 is a Ctrl-/ really only
160 // disallows Ctrl+Shift+7 from doing something else, which is probably OK. (This routine
161 // is only used in the Scintilla editor, not in the rest of KiCad.)
162
163 // The other main shifted location of / is over : (France and Belgium), so we'll sacrifice
164 // Ctrl+Shift+: too.
165
166 if( aEvent.ShiftDown() && ( aEvent.GetUnicodeKey() == '7' || aEvent.GetUnicodeKey() == ':' ) )
167 return true;
168
169 // A few keyboards have / in an Alt position. Since we're expressly not checking Alt for
170 // up or down, those should work. However, if they don't, there's room below for yet
171 // another hack....
172
173 return false;
174}
175
176
177void SCINTILLA_TRICKS::onChar( wxStyledTextEvent& aEvent )
178{
179 m_onCharAddedFn( aEvent );
180}
181
182
183void SCINTILLA_TRICKS::onModified( wxStyledTextEvent& aEvent )
184{
185 if( m_singleLine )
186 {
187 wxString curr_text = m_te->GetText();
188
189 if( curr_text.Contains( wxS( "\n" ) ) || curr_text.Contains( wxS( "\r" ) ) )
190 {
191 // Scintilla won't allow us to call SetText() from within this event processor,
192 // so we have to delay the processing.
193 CallAfter( [this]()
194 {
195 wxString text = m_te->GetText();
196 int currpos = m_te->GetCurrentPos();
197
198 text.Replace( wxS( "\n" ), wxS( "" ) );
199 text.Replace( wxS( "\r" ), wxS( "" ) );
200 m_te->SetText( text );
201 m_te->GotoPos( currpos-1 );
202 } );
203 }
204 }
205
206 if( m_singleLine || m_te->GetCurrentLine() == 0 )
207 {
208 // If the font is larger than the height of a single-line text box we can get issues
209 // with the text disappearing every other character due to dodgy scrolling behaviour.
210 CallAfter( [this]()
211 {
212 m_te->ScrollToStart();
213 } );
214 }
215}
216
217
218void SCINTILLA_TRICKS::onCharHook( wxKeyEvent& aEvent )
219{
220 auto findGridTricks =
221 [&]() -> GRID_TRICKS*
222 {
223 wxWindow* parent = m_te->GetParent();
224
225 while( parent && !dynamic_cast<WX_GRID*>( parent ) )
226 parent = parent->GetParent();
227
228 if( WX_GRID* grid = dynamic_cast<WX_GRID*>( parent ) )
229 {
230 wxEvtHandler* handler = grid->GetEventHandler();
231
232 while( handler && !dynamic_cast<GRID_TRICKS*>( handler ) )
233 handler = handler->GetNextHandler();
234
235 if( GRID_TRICKS* gridTricks = dynamic_cast<GRID_TRICKS*>( handler ) )
236 return gridTricks;
237 }
238
239 return nullptr;
240 };
241
242 wxString c = aEvent.GetUnicodeKey();
243
244 if( m_te->AutoCompActive() )
245 {
246 if( aEvent.GetKeyCode() == WXK_ESCAPE )
247 {
248 m_te->AutoCompCancel();
249 m_suppressAutocomplete = true; // Don't run autocomplete again on the next char...
250 }
251 else if( aEvent.GetKeyCode() == WXK_RETURN || aEvent.GetKeyCode() == WXK_NUMPAD_ENTER )
252 {
253 int start = m_te->AutoCompPosStart();
254
255 m_te->AutoCompComplete();
256
257 int finish = m_te->GetCurrentPos();
258
259 if( finish > start )
260 {
261 // Select the last substitution token (if any) in the autocompleted text
262
263 int selStart = m_te->FindText( finish, start, "<" );
264 int selEnd = m_te->FindText( finish, start, ">" );
265
266 if( selStart > start && selEnd <= finish && selEnd > selStart )
267 m_te->SetSelection( selStart, selEnd + 1 );
268 }
269 }
270 else
271 {
272 aEvent.Skip();
273 }
274
275 return;
276 }
277
278#ifdef __WXMAC__
279 if( aEvent.GetModifiers() == wxMOD_RAW_CONTROL && aEvent.GetKeyCode() == WXK_SPACE )
280#else
281 if( aEvent.GetModifiers() == wxMOD_CONTROL && aEvent.GetKeyCode() == WXK_SPACE )
282#endif
283 {
285
286 wxStyledTextEvent event;
287 event.SetKey( ' ' );
288 event.SetModifiers( wxMOD_CONTROL );
289 m_onCharAddedFn( event );
290
291 return;
292 }
293
294 if( !isalpha( aEvent.GetKeyCode() ) )
296
297 if( ( aEvent.GetKeyCode() == WXK_RETURN || aEvent.GetKeyCode() == WXK_NUMPAD_ENTER )
298 && ( m_singleLine || aEvent.ShiftDown() ) )
299 {
300 m_onAcceptFn( aEvent );
301 }
302 else if( ConvertSmartQuotesAndDashes( &c ) )
303 {
304 m_te->AddText( c );
305 }
306 else if( aEvent.GetKeyCode() == WXK_TAB )
307 {
308 wxWindow* ancestor = m_te->GetParent();
309
310 while( ancestor && !dynamic_cast<WX_GRID*>( ancestor ) )
311 ancestor = ancestor->GetParent();
312
313 if( aEvent.ControlDown() )
314 {
315 int flags = 0;
316
317 if( !aEvent.ShiftDown() )
318 flags |= wxNavigationKeyEvent::IsForward;
319
320 if( DIALOG_SHIM* dlg = dynamic_cast<DIALOG_SHIM*>( wxGetTopLevelParent( m_te ) ) )
321 dlg->NavigateIn( flags );
322 }
323 else if( dynamic_cast<WX_GRID*>( ancestor ) )
324 {
325 WX_GRID* grid = static_cast<WX_GRID*>( ancestor );
326 int row = grid->GetGridCursorRow();
327 int col = grid->GetGridCursorCol();
328
329 if( aEvent.ShiftDown() )
330 {
331 if( col > 0 )
332 {
333 col--;
334 }
335 else if( row > 0 )
336 {
337 col = (int) grid->GetNumberCols() - 1;
338 row--;
339 }
340 }
341 else
342 {
343 if( col < (int) grid->GetNumberCols() - 1 )
344 {
345 col++;
346 }
347 else if( row < grid->GetNumberRows() - 1 )
348 {
349 col = 0;
350 row++;
351 }
352 }
353
354 grid->SetGridCursor( row, col );
355 }
356 else
357 {
358 m_te->Tab();
359 }
360 }
361 else if( aEvent.GetModifiers() == wxMOD_CONTROL && aEvent.GetKeyCode() == 'Z' )
362 {
363 m_te->Undo();
364 }
365 else if( ( aEvent.GetModifiers() == wxMOD_SHIFT+wxMOD_CONTROL && aEvent.GetKeyCode() == 'Z' )
366 || ( aEvent.GetModifiers() == wxMOD_CONTROL && aEvent.GetKeyCode() == 'Y' ) )
367 {
368 m_te->Redo();
369 }
370 else if( aEvent.GetModifiers() == wxMOD_CONTROL && aEvent.GetKeyCode() == 'A' )
371 {
372 m_te->SelectAll();
373 }
374 else if( aEvent.GetModifiers() == wxMOD_CONTROL && aEvent.GetKeyCode() == 'X' )
375 {
376 m_te->Cut();
377
378 if( wxTheClipboard->Open() )
379 {
380 wxTheClipboard->Flush(); // Allow data to be available after closing KiCad
381 wxTheClipboard->Close();
382 }
383 }
384 else if( aEvent.GetModifiers() == wxMOD_CONTROL && aEvent.GetKeyCode() == 'C' )
385 {
386 m_te->Copy();
387
388 if( wxTheClipboard->Open() )
389 {
390 wxTheClipboard->Flush(); // Allow data to be available after closing KiCad
391 wxTheClipboard->Close();
392 }
393 }
394 else if( aEvent.GetModifiers() == wxMOD_CONTROL && aEvent.GetKeyCode() == 'V' )
395 {
396 if( m_te->GetSelectionEnd() > m_te->GetSelectionStart() )
397 m_te->DeleteBack();
398
399 GRID_TRICKS* gridTricks = nullptr;
400 wxLogNull doNotLog; // disable logging of failed clipboard actions
401
402 if( wxTheClipboard->Open() )
403 {
404 if( wxTheClipboard->IsSupported( wxDF_TEXT ) ||
405 wxTheClipboard->IsSupported( wxDF_UNICODETEXT ) )
406 {
407 wxTextDataObject data;
408 wxString str;
409
410 wxTheClipboard->GetData( data );
411 str = data.GetText();
412
413 if( str.Contains( '\t' ) )
414 gridTricks = findGridTricks();
415
416 if( !gridTricks )
417 {
419
420 if( m_singleLine )
421 {
422 str.Replace( wxS( "\n" ), wxEmptyString );
423 str.Replace( wxS( "\r" ), wxEmptyString );
424 }
425
426 m_te->BeginUndoAction();
427 m_te->AddText( str );
428 m_te->EndUndoAction();
429 }
430 }
431
432 wxTheClipboard->Close();
433 }
434
435 if( gridTricks )
436 gridTricks->onKeyDown( aEvent );
437 }
438 else if( aEvent.GetKeyCode() == WXK_BACK )
439 {
440 if( aEvent.GetModifiers() == wxMOD_CONTROL )
441#ifdef __WXMAC__
442 m_te->HomeExtend();
443 else if( aEvent.GetModifiers() == wxMOD_ALT )
444#endif
445 m_te->WordLeftExtend();
446
447 m_te->DeleteBack();
448 }
449 else if( aEvent.GetKeyCode() == WXK_DELETE )
450 {
451 if( m_te->GetSelectionEnd() == m_te->GetSelectionStart() )
452 {
453#ifndef __WXMAC__
454 if( aEvent.GetModifiers() == wxMOD_CONTROL )
455 m_te->WordRightExtend();
456 else
457#endif
458 m_te->CharRightExtend();
459 }
460
461 if( m_te->GetSelectionEnd() > m_te->GetSelectionStart() )
462 m_te->DeleteBack();
463 }
464 else if( isCtrlSlash( aEvent ) )
465 {
466 int startLine = m_te->LineFromPosition( m_te->GetSelectionStart() );
467 int endLine = m_te->LineFromPosition( m_te->GetSelectionEnd() );
468 bool comment = firstNonWhitespace( startLine ) != '#';
469 int whitespaceCount;
470
471 m_te->BeginUndoAction();
472
473 for( int ii = startLine; ii <= endLine; ++ii )
474 {
475 if( comment )
476 m_te->InsertText( m_te->PositionFromLine( ii ), wxT( "#" ) );
477 else if( firstNonWhitespace( ii, &whitespaceCount ) == '#' )
478 m_te->DeleteRange( m_te->PositionFromLine( ii ) + whitespaceCount, 1 );
479 }
480
481 m_te->SetSelection( m_te->PositionFromLine( startLine ),
482 m_te->PositionFromLine( endLine ) + m_te->GetLineLength( endLine ) );
483
484 m_te->EndUndoAction();
485 }
486#ifdef __WXMAC__
487 else if( aEvent.GetModifiers() == wxMOD_RAW_CONTROL && aEvent.GetKeyCode() == 'A' )
488 {
489 m_te->HomeWrap();
490 }
491 else if( aEvent.GetModifiers() == wxMOD_RAW_CONTROL && aEvent.GetKeyCode() == 'E' )
492 {
493 m_te->LineEndWrap();
494 }
495 else if( ( aEvent.GetModifiers() & wxMOD_RAW_CONTROL ) && aEvent.GetKeyCode() == 'B' )
496 {
497 if( aEvent.GetModifiers() & wxMOD_ALT )
498 m_te->WordLeft();
499 else
500 m_te->CharLeft();
501 }
502 else if( ( aEvent.GetModifiers() & wxMOD_RAW_CONTROL ) && aEvent.GetKeyCode() == 'F' )
503 {
504 if( aEvent.GetModifiers() & wxMOD_ALT )
505 m_te->WordRight();
506 else
507 m_te->CharRight();
508 }
509 else if( aEvent.GetModifiers() == wxMOD_RAW_CONTROL && aEvent.GetKeyCode() == 'D' )
510 {
511 if( m_te->GetSelectionEnd() == m_te->GetSelectionStart() )
512 m_te->CharRightExtend();
513
514 if( m_te->GetSelectionEnd() > m_te->GetSelectionStart() )
515 m_te->DeleteBack();
516 }
517#endif
518 else if( aEvent.GetKeyCode() == WXK_SPECIAL20 )
519 {
520 // Proxy for a wxSysColourChangedEvent
521 setupStyles();
522 }
523 else
524 {
525 aEvent.Skip();
526 }
527}
528
529
530int SCINTILLA_TRICKS::firstNonWhitespace( int aLine, int* aWhitespaceCharCount )
531{
532 int lineStart = m_te->PositionFromLine( aLine );
533
534 if( aWhitespaceCharCount )
535 *aWhitespaceCharCount = 0;
536
537 for( int ii = 0; ii < m_te->GetLineLength( aLine ); ++ii )
538 {
539 int c = m_te->GetCharAt( lineStart + ii );
540
541 if( c == ' ' || c == '\t' )
542 {
543 if( aWhitespaceCharCount )
544 *aWhitespaceCharCount += 1;
545
546 continue;
547 }
548 else
549 {
550 return c;
551 }
552 }
553
554 return '\r';
555}
556
557
558void SCINTILLA_TRICKS::onScintillaUpdateUI( wxStyledTextEvent& aEvent )
559{
560 auto isBrace = [this]( int c ) -> bool
561 {
562 return m_braces.Find( (wxChar) c ) >= 0;
563 };
564
565 // Has the caret changed position?
566 int caretPos = m_te->GetCurrentPos();
567 int selStart = m_te->GetSelectionStart();
568 int selEnd = m_te->GetSelectionEnd();
569
570 if( m_lastCaretPos != caretPos || m_lastSelStart != selStart || m_lastSelEnd != selEnd )
571 {
572 m_lastCaretPos = caretPos;
573 m_lastSelStart = selStart;
574 m_lastSelEnd = selEnd;
575 int bracePos1 = -1;
576 int bracePos2 = -1;
577
578 // Is there a brace to the left or right?
579 if( caretPos > 0 && isBrace( m_te->GetCharAt( caretPos-1 ) ) )
580 bracePos1 = ( caretPos - 1 );
581 else if( isBrace( m_te->GetCharAt( caretPos ) ) )
582 bracePos1 = caretPos;
583
584 if( bracePos1 >= 0 )
585 {
586 // Find the matching brace
587 bracePos2 = m_te->BraceMatch( bracePos1 );
588
589 if( bracePos2 == -1 )
590 {
591 m_te->BraceBadLight( bracePos1 );
592 m_te->SetHighlightGuide( 0 );
593 }
594 else
595 {
596 m_te->BraceHighlight( bracePos1, bracePos2 );
597 m_te->SetHighlightGuide( m_te->GetColumn( bracePos1 ) );
598 }
599 }
600 else
601 {
602 // Turn off brace matching
603 m_te->BraceHighlight( -1, -1 );
604 m_te->SetHighlightGuide( 0 );
605 }
606 }
607}
608
609
610void SCINTILLA_TRICKS::DoTextVarAutocomplete( const std::function<void( const wxString& xRef,
611 wxArrayString* tokens )>& getTokensFn )
612{
613 wxArrayString autocompleteTokens;
614 int text_pos = m_te->GetCurrentPos();
615 int start = m_te->WordStartPosition( text_pos, true );
616 wxString partial;
617
618 auto textVarRef =
619 [&]( int pos )
620 {
621 return pos >= 2 && m_te->GetCharAt( pos-2 ) == '$'
622 && m_te->GetCharAt( pos-1 ) == '{';
623 };
624
625 // Check for cross-reference
626 if( start > 1 && m_te->GetCharAt( start-1 ) == ':' )
627 {
628 int refStart = m_te->WordStartPosition( start-1, true );
629
630 if( textVarRef( refStart ) )
631 {
632 partial = m_te->GetRange( start, text_pos );
633 getTokensFn( m_te->GetRange( refStart, start-1 ), &autocompleteTokens );
634 }
635 }
636 else if( textVarRef( start ) )
637 {
638 partial = m_te->GetTextRange( start, text_pos );
639 getTokensFn( wxEmptyString, &autocompleteTokens );
640 }
641
642 DoAutocomplete( partial, autocompleteTokens );
643 m_te->SetFocus();
644}
645
646
647void SCINTILLA_TRICKS::DoAutocomplete( const wxString& aPartial, const wxArrayString& aTokens )
648{
650 return;
651
652 wxArrayString matchedTokens;
653
654 wxString filter = wxT( "*" ) + aPartial.Lower() + wxT( "*" );
655
656 for( const wxString& token : aTokens )
657 {
658 if( token.Lower().Matches( filter ) )
659 matchedTokens.push_back( token );
660 }
661
662 if( matchedTokens.size() > 0 )
663 {
664 // NB: tokens MUST be in alphabetical order because the Scintilla engine is going
665 // to do a binary search on them
666 matchedTokens.Sort( []( const wxString& first, const wxString& second ) -> int
667 {
668 return first.CmpNoCase( second );
669 });
670
671 m_te->AutoCompSetSeparator( '\t' );
672 m_te->AutoCompShow( aPartial.size(), wxJoin( matchedTokens, '\t' ) );
673 }
674}
675
676
678{
679 m_te->AutoCompCancel();
680}
681
Dialog helper object to sit in the inheritance tree between wxDialog and any class written by wxFormB...
Definition: dialog_shim.h:61
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition: grid_tricks.h:61
void onKeyDown(wxKeyEvent &event)
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
COLOR4D WithAlpha(double aAlpha) const
Return a color with the same color, but the given alpha.
Definition: color4d.h:311
double a
Alpha component.
Definition: color4d.h:395
wxColour ToColour() const
Definition: color4d.cpp:220
COLOR4D Mix(const COLOR4D &aColor, double aFactor) const
Return a color that is mixed with the input by a factor.
Definition: color4d.h:295
void onChar(wxStyledTextEvent &aEvent)
int firstNonWhitespace(int aLine, int *aWhitespaceCount=nullptr)
virtual void onCharHook(wxKeyEvent &aEvent)
std::function< void(wxKeyEvent &aEvent)> m_onAcceptFn
void onThemeChanged(wxSysColourChangedEvent &aEvent)
void DoAutocomplete(const wxString &aPartial, const wxArrayString &aTokens)
void onScintillaUpdateUI(wxStyledTextEvent &aEvent)
void DoTextVarAutocomplete(const std::function< void(const wxString &xRef, wxArrayString *tokens)> &getTokensFn)
std::function< void(wxStyledTextEvent &aEvent)> m_onCharAddedFn
void onModified(wxStyledTextEvent &aEvent)
SCINTILLA_TRICKS(wxStyledTextCtrl *aScintilla, const wxString &aBraces, bool aSingleLine, std::function< void(wxKeyEvent &)> onAcceptHandler=[](wxKeyEvent &aEvent) { }, std::function< void(wxStyledTextEvent &)> onCharAddedHandler=[](wxStyledTextEvent &) { })
wxStyledTextCtrl * m_te
This file is part of the common library.
KICOMMON_API wxFont GetMonospacedUIFont()
Definition: ui_common.cpp:93
STL namespace.
bool isCtrlSlash(wxKeyEvent &aEvent)
std::vector< FAB_LAYER_COLOR > dummy
bool ConvertSmartQuotesAndDashes(wxString *aString)
Convert curly quotes and em/en dashes to straight quotes and dashes.
Functions to provide common constants and other functions to assist in making a consistent UI.