Performance improvements for autocomplete and some syntax help.

This commit is contained in:
Jeff Young 2020-05-25 21:44:49 +01:00
parent 1db799d841
commit 1f93020be4
5 changed files with 242 additions and 60 deletions

View File

@ -27,7 +27,7 @@
#include <tool/tool_manager.h>
#include <drc/drc.h>
#include <panel_setup_rules.h>
#include <html_messagebox.h>
PANEL_SETUP_RULES::PANEL_SETUP_RULES( PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFrame ) :
PANEL_SETUP_RULES_BASE( aParent->GetTreebook() ),
@ -48,6 +48,12 @@ PANEL_SETUP_RULES::PANEL_SETUP_RULES( PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFr
m_textEditor->StyleSetBackground( wxSTC_STYLE_BRACELIGHT, highlight );
m_textEditor->StyleSetForeground( wxSTC_STYLE_BRACEBAD, *wxRED );
int size = wxNORMAL_FONT->GetPointSize();
wxFont fixedFont( size, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTSTYLE_NORMAL );
for( size_t i = 0; i < wxSTC_STYLE_MAX; ++i )
m_textEditor->StyleSetFont( i, fixedFont );
m_textEditor->Bind( wxEVT_STC_CHARADDED, &PANEL_SETUP_RULES::onScintillaCharAdded, this );
m_textEditor->Bind( wxEVT_STC_UPDATEUI, &PANEL_SETUP_RULES::onScintillaUpdateUI, this );
}
@ -102,7 +108,10 @@ void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent )
else if( c == '(' )
{
if( context == SEXPR_OPEN && !partial.IsEmpty() )
{
m_textEditor->AutoCompCancel();
sexprs.push( partial );
}
partial = wxEmptyString;
context = SEXPR_OPEN;
@ -116,6 +125,7 @@ void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent )
{
if( context == SEXPR_OPEN && !partial.IsEmpty() )
{
m_textEditor->AutoCompCancel();
sexprs.push( partial );
wxString top = sexprs.size() ? sexprs.top() : wxEmptyString;
@ -136,6 +146,18 @@ void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent )
}
}
auto autocomplete = [&]( const wxString& partial, const wxString& tokenStr )
{
wxArrayString tokens = wxSplit( tokenStr, ' ' );
bool match = partial.IsEmpty();
for( int i = 0; i < tokens.size() && !match; ++i )
match = tokens[i].StartsWith( partial );
if( match )
m_textEditor->AutoCompShow( partial.size(), tokenStr );
};
// NB: tokens MUST be in alphabetical order because the Scintilla engine is going
// to do a binary search on them
wxString tokens;
@ -150,7 +172,7 @@ void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent )
tokens = "max min opt";
if( !tokens.IsEmpty() )
m_textEditor->AutoCompShow( partial.size(), tokens );
autocomplete( partial, tokens );
}
else if( context == SEXPR_TOKEN )
{
@ -163,7 +185,7 @@ void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent )
wxASSERT( currentPos - wordStartPos == partial.size() );
if( !tokens.IsEmpty() )
m_textEditor->AutoCompShow( partial.size(), tokens );
autocomplete( partial, tokens );
}
}
@ -240,3 +262,52 @@ bool PANEL_SETUP_RULES::TransferDataFromWindow()
}
void PANEL_SETUP_RULES::OnSyntaxHelp( wxHyperlinkEvent& aEvent )
{
wxString msg = _(
"<b>Top-level Expressions</b>"
"<pre>"
"(version &lt;number>)\r"
"(rule &lt;rule_name> &lt;rule_expression> ...)\r"
"\r</pre>"
"<b>Rule Expressions</b>"
"<pre>"
"(disallow &lt;item_type>)\r"
"(constraint &lt;constraint_type> ...)\r"
"(condition \"&lt;expression>\")\r"
"\r</pre>"
"<b>Item Types</b>"
"<pre>"
"track via zone\r"
"pad micro_via text\r"
"hole buried_via graphic\r"
"\r</pre>"
"<b>Constraint Types</b>"
"<pre>"
"clearance annulus_width track_width hole\r"
"\r</pre>"
"<b>Examples</b>"
"<pre>"
"(rule \"copper keepout\"\r"
" (disallow track) (disallow via) (disallow zone)\r"
" (condition \"a.name == no_copper\"))\r"
"\r"
"(rule neckdown\r"
" (constraint track_width (min 0.2mm) (opt 0.25mm) (max 1.0mm)\r"
" (condition \"a.name == BGA\"))\r"
"\r"
"(rule HV\r"
" (constraint clearance (min 1.5mm)\r"
" (condition \"a.netclass == HV\"))\r"
"\r"
"(rule HV-HV\r"
" (constraint clearance (min 2.0mm)\r"
" (condition \"a.netclass == HV && b.netclass == HV\"))\r"
"</pre>" );
HTML_MESSAGE_BOX dlg( m_parent, _( "Syntax Help" ) );
dlg.SetDialogSizeInDU( 320, 320 );
dlg.AddHTML_Text( msg );
dlg.ShowModal();
}

View File

@ -46,6 +46,8 @@ private:
void onScintillaCharAdded( wxStyledTextEvent &aEvent );
void onScintillaUpdateUI( wxStyledTextEvent& aEvent );
void OnSyntaxHelp( wxHyperlinkEvent& aEvent ) override;
bool TransferDataToWindow() override;
bool TransferDataFromWindow() override;
};

View File

@ -18,9 +18,21 @@ PANEL_SETUP_RULES_BASE::PANEL_SETUP_RULES_BASE( wxWindow* parent, wxWindowID id,
m_topMargin = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizer4;
bSizer4 = new wxBoxSizer( wxHORIZONTAL );
m_title = new wxStaticText( this, wxID_ANY, _("DRC rules:"), wxDefaultPosition, wxDefaultSize, 0 );
m_title->Wrap( -1 );
m_topMargin->Add( m_title, 0, wxTOP|wxBOTTOM, 5 );
bSizer4->Add( m_title, 0, wxTOP|wxBOTTOM, 5 );
bSizer4->Add( 0, 0, 1, wxEXPAND, 5 );
m_syntaxHelp = new wxHyperlinkCtrl( this, wxID_ANY, _("Syntax help"), wxT("http://www.wxformbuilder.org"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE );
bSizer4->Add( m_syntaxHelp, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 10 );
m_topMargin->Add( bSizer4, 0, wxEXPAND, 5 );
m_textEditor = new wxStyledTextCtrl( this, ID_RULES_EDITOR, wxDefaultPosition, wxDefaultSize, 0, wxEmptyString );
m_textEditor->SetUseTabs( true );
@ -64,8 +76,14 @@ PANEL_SETUP_RULES_BASE::PANEL_SETUP_RULES_BASE( wxWindow* parent, wxWindowID id,
this->SetSizer( bPanelSizer );
this->Layout();
bPanelSizer->Fit( this );
// Connect Events
m_syntaxHelp->Connect( wxEVT_COMMAND_HYPERLINK, wxHyperlinkEventHandler( PANEL_SETUP_RULES_BASE::OnSyntaxHelp ), NULL, this );
}
PANEL_SETUP_RULES_BASE::~PANEL_SETUP_RULES_BASE()
{
// Disconnect Events
m_syntaxHelp->Disconnect( wxEVT_COMMAND_HYPERLINK, wxHyperlinkEventHandler( PANEL_SETUP_RULES_BASE::OnSyntaxHelp ), NULL, this );
}

View File

@ -74,63 +74,148 @@
<property name="permission">protected</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxTOP|wxBOTTOM</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">DRC rules:</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_title</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
<property name="name">bSizer4</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxTOP|wxBOTTOM</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">DRC rules:</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_title</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="spacer" expanded="1">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">10</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxHyperlinkCtrl" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="hover_color"></property>
<property name="id">wxID_ANY</property>
<property name="label">Syntax help</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_syntaxHelp</property>
<property name="normal_color"></property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxHL_DEFAULT_STYLE</property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="url">http://www.wxformbuilder.org</property>
<property name="visited_color"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnHyperlink">OnSyntaxHelp</event>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="1">

View File

@ -16,8 +16,9 @@
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/stc/stc.h>
#include <wx/hyperlink.h>
#include <wx/sizer.h>
#include <wx/stc/stc.h>
#include <wx/panel.h>
///////////////////////////////////////////////////////////////////////////
@ -35,8 +36,13 @@ class PANEL_SETUP_RULES_BASE : public wxPanel
wxBoxSizer* m_leftMargin;
wxBoxSizer* m_topMargin;
wxStaticText* m_title;
wxHyperlinkCtrl* m_syntaxHelp;
wxStyledTextCtrl* m_textEditor;
// Virtual event handlers, overide them in your derived class
virtual void OnSyntaxHelp( wxHyperlinkEvent& event ) { event.Skip(); }
public:
PANEL_SETUP_RULES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );