Add Scintilla support to WX_GRID.
This commit is contained in:
parent
f6fcae479c
commit
87eb4401e3
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2022 KiCad Developers, see change_log.txt for contributors.
|
* Copyright (C) 2020-2023 KiCad Developers, see change_log.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -33,7 +33,8 @@
|
||||||
#include <confirm.h>
|
#include <confirm.h>
|
||||||
|
|
||||||
SCINTILLA_TRICKS::SCINTILLA_TRICKS( wxStyledTextCtrl* aScintilla, const wxString& aBraces,
|
SCINTILLA_TRICKS::SCINTILLA_TRICKS( wxStyledTextCtrl* aScintilla, const wxString& aBraces,
|
||||||
bool aSingleLine, std::function<void()> aReturnCallback ) :
|
bool aSingleLine, std::function<void()> aReturnCallback,
|
||||||
|
std::function<void( wxStyledTextEvent& )> aCharCallback ) :
|
||||||
m_te( aScintilla ),
|
m_te( aScintilla ),
|
||||||
m_braces( aBraces ),
|
m_braces( aBraces ),
|
||||||
m_lastCaretPos( -1 ),
|
m_lastCaretPos( -1 ),
|
||||||
|
@ -41,7 +42,8 @@ SCINTILLA_TRICKS::SCINTILLA_TRICKS( wxStyledTextCtrl* aScintilla, const wxString
|
||||||
m_lastSelEnd( -1 ),
|
m_lastSelEnd( -1 ),
|
||||||
m_suppressAutocomplete( false ),
|
m_suppressAutocomplete( false ),
|
||||||
m_singleLine( aSingleLine ),
|
m_singleLine( aSingleLine ),
|
||||||
m_returnCallback( aReturnCallback )
|
m_returnCallback( aReturnCallback ),
|
||||||
|
m_charCallback( aCharCallback )
|
||||||
{
|
{
|
||||||
// Always use LF as eol char, regardless the platform
|
// Always use LF as eol char, regardless the platform
|
||||||
m_te->SetEOLMode( wxSTC_EOL_LF );
|
m_te->SetEOLMode( wxSTC_EOL_LF );
|
||||||
|
@ -55,12 +57,18 @@ SCINTILLA_TRICKS::SCINTILLA_TRICKS( wxStyledTextCtrl* aScintilla, const wxString
|
||||||
|
|
||||||
// Set up autocomplete
|
// Set up autocomplete
|
||||||
m_te->AutoCompSetIgnoreCase( true );
|
m_te->AutoCompSetIgnoreCase( true );
|
||||||
m_te->AutoCompSetFillUps( m_braces[1] );
|
|
||||||
m_te->AutoCompSetMaxHeight( 20 );
|
m_te->AutoCompSetMaxHeight( 20 );
|
||||||
|
|
||||||
|
if( aBraces.Length() >= 2 )
|
||||||
|
m_te->AutoCompSetFillUps( m_braces[1] );
|
||||||
|
|
||||||
// Hook up events
|
// Hook up events
|
||||||
m_te->Bind( wxEVT_STC_UPDATEUI, &SCINTILLA_TRICKS::onScintillaUpdateUI, this );
|
m_te->Bind( wxEVT_STC_UPDATEUI, &SCINTILLA_TRICKS::onScintillaUpdateUI, this );
|
||||||
|
|
||||||
|
// Handle autocomplete
|
||||||
|
m_te->Bind( wxEVT_STC_CHARADDED, &SCINTILLA_TRICKS::onChar, this );
|
||||||
|
m_te->Bind( wxEVT_STC_AUTOCOMP_CHAR_DELETED, &SCINTILLA_TRICKS::onChar, this );
|
||||||
|
|
||||||
// Dispatch command-keys in Scintilla control.
|
// Dispatch command-keys in Scintilla control.
|
||||||
m_te->Bind( wxEVT_CHAR_HOOK, &SCINTILLA_TRICKS::onCharHook, this );
|
m_te->Bind( wxEVT_CHAR_HOOK, &SCINTILLA_TRICKS::onCharHook, this );
|
||||||
|
|
||||||
|
@ -155,6 +163,12 @@ bool isCtrlSlash( wxKeyEvent& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCINTILLA_TRICKS::onChar( wxStyledTextEvent& aEvent )
|
||||||
|
{
|
||||||
|
m_charCallback( aEvent );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCINTILLA_TRICKS::onCharHook( wxKeyEvent& aEvent )
|
void SCINTILLA_TRICKS::onCharHook( wxKeyEvent& aEvent )
|
||||||
{
|
{
|
||||||
wxString c = aEvent.GetUnicodeKey();
|
wxString c = aEvent.GetUnicodeKey();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
* @author Jon Evans <jon@craftyjon.com>
|
* @author Jon Evans <jon@craftyjon.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
@ -19,9 +19,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string_utils.h>
|
#include <string_utils.h>
|
||||||
|
#include <wx/stc/stc.h>
|
||||||
#include <widgets/grid_text_helpers.h>
|
#include <widgets/grid_text_helpers.h>
|
||||||
|
#include <scintilla_tricks.h>
|
||||||
|
|
||||||
|
|
||||||
|
//-------- GRID_CELL_ESCAPED_TEXT_RENDERER ------------------------------------------------------
|
||||||
|
//
|
||||||
|
|
||||||
GRID_CELL_ESCAPED_TEXT_RENDERER::GRID_CELL_ESCAPED_TEXT_RENDERER() :
|
GRID_CELL_ESCAPED_TEXT_RENDERER::GRID_CELL_ESCAPED_TEXT_RENDERER() :
|
||||||
wxGridCellStringRenderer()
|
wxGridCellStringRenderer()
|
||||||
{
|
{
|
||||||
|
@ -50,3 +55,117 @@ wxSize GRID_CELL_ESCAPED_TEXT_RENDERER::GetBestSize( wxGrid & aGrid, wxGridCellA
|
||||||
wxString unescaped = UnescapeString( aGrid.GetCellValue( aRow, aCol ) );
|
wxString unescaped = UnescapeString( aGrid.GetCellValue( aRow, aCol ) );
|
||||||
return wxGridCellStringRenderer::DoGetBestSize( aAttr, aDC, unescaped );
|
return wxGridCellStringRenderer::DoGetBestSize( aAttr, aDC, unescaped );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------- GRID_CELL_STC_EDITOR -----------------------------------------------------------------
|
||||||
|
//
|
||||||
|
|
||||||
|
GRID_CELL_STC_EDITOR::GRID_CELL_STC_EDITOR( std::function<void( wxStyledTextEvent&,
|
||||||
|
SCINTILLA_TRICKS* )> aOnChar ) :
|
||||||
|
m_onChar( aOnChar )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
void GRID_CELL_STC_EDITOR::Create( wxWindow* aParent, wxWindowID aId, wxEvtHandler* aEventHandler )
|
||||||
|
{
|
||||||
|
m_control = new wxStyledTextCtrl( aParent );
|
||||||
|
|
||||||
|
stc_ctrl()->SetTabIndents( false );
|
||||||
|
stc_ctrl()->SetBackSpaceUnIndents( false );
|
||||||
|
stc_ctrl()->SetViewEOL( false );
|
||||||
|
stc_ctrl()->SetViewWhiteSpace( false );
|
||||||
|
stc_ctrl()->SetIndentationGuides( false );
|
||||||
|
stc_ctrl()->SetMarginWidth( 0, 0 ); // Symbol margin
|
||||||
|
stc_ctrl()->SetMarginWidth( 1, 0 ); // Line-number margin
|
||||||
|
stc_ctrl()->SetEOLMode( wxSTC_EOL_LF );
|
||||||
|
stc_ctrl()->AutoCompSetMaxWidth( 25 );
|
||||||
|
stc_ctrl()->UsePopUp( 0 );
|
||||||
|
|
||||||
|
// A hack which causes Scintilla to auto-size the text editor canvas
|
||||||
|
// See: https://github.com/jacobslusser/ScintillaNET/issues/216
|
||||||
|
stc_ctrl()->SetScrollWidth( 1 );
|
||||||
|
stc_ctrl()->SetScrollWidthTracking( true );
|
||||||
|
|
||||||
|
m_scintillaTricks = new SCINTILLA_TRICKS(
|
||||||
|
stc_ctrl(), wxEmptyString, true,
|
||||||
|
[this]()
|
||||||
|
{
|
||||||
|
stc_ctrl()->AutoCompComplete();
|
||||||
|
},
|
||||||
|
[this]( wxStyledTextEvent& aEvent )
|
||||||
|
{
|
||||||
|
m_onChar( aEvent, m_scintillaTricks );
|
||||||
|
} );
|
||||||
|
|
||||||
|
stc_ctrl()->Bind( wxEVT_KILL_FOCUS, &GRID_CELL_STC_EDITOR::onFocusLoss, this );
|
||||||
|
|
||||||
|
wxGridCellEditor::Create( aParent, aId, aEventHandler );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxStyledTextCtrl* GRID_CELL_STC_EDITOR::stc_ctrl() const
|
||||||
|
{
|
||||||
|
return static_cast<wxStyledTextCtrl*>( m_control );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxString GRID_CELL_STC_EDITOR::GetValue() const
|
||||||
|
{
|
||||||
|
return stc_ctrl()->GetText();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GRID_CELL_STC_EDITOR::Show( bool aShow, wxGridCellAttr* aAttr )
|
||||||
|
{
|
||||||
|
if( !aShow )
|
||||||
|
stc_ctrl()->AutoCompCancel();
|
||||||
|
|
||||||
|
wxGridCellEditor::Show( aShow, aAttr );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GRID_CELL_STC_EDITOR::BeginEdit( int aRow, int aCol, wxGrid* aGrid )
|
||||||
|
{
|
||||||
|
auto evtHandler = static_cast<wxGridCellEditorEvtHandler*>( m_control->GetEventHandler()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Don't immediately end if we get a kill focus event within BeginEdit
|
||||||
|
evtHandler->SetInSetFocus( true );
|
||||||
|
|
||||||
|
m_value = aGrid->GetTable()->GetValue( aRow, aCol );
|
||||||
|
|
||||||
|
stc_ctrl()->SetFocus();
|
||||||
|
stc_ctrl()->SetText( m_value );
|
||||||
|
stc_ctrl()->SelectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool GRID_CELL_STC_EDITOR::EndEdit( int, int, const wxGrid*, const wxString&, wxString *aNewVal )
|
||||||
|
{
|
||||||
|
const wxString value = stc_ctrl()->GetText();
|
||||||
|
|
||||||
|
if( value == m_value )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_value = value;
|
||||||
|
|
||||||
|
if( aNewVal )
|
||||||
|
*aNewVal = value;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GRID_CELL_STC_EDITOR::ApplyEdit( int aRow, int aCol, wxGrid* aGrid )
|
||||||
|
{
|
||||||
|
aGrid->GetTable()->SetValue( aRow, aCol, m_value );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GRID_CELL_STC_EDITOR::onFocusLoss( wxFocusEvent& aEvent )
|
||||||
|
{
|
||||||
|
if( stc_ctrl() )
|
||||||
|
stc_ctrl()->AutoCompCancel();
|
||||||
|
|
||||||
|
aEvent.Skip();
|
||||||
|
}
|
||||||
|
|
|
@ -37,7 +37,14 @@ class SCINTILLA_TRICKS : public wxEvtHandler
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SCINTILLA_TRICKS( wxStyledTextCtrl* aScintilla, const wxString& aBraces, bool aSingleLine,
|
SCINTILLA_TRICKS( wxStyledTextCtrl* aScintilla, const wxString& aBraces, bool aSingleLine,
|
||||||
std::function<void()> m_enterCallback = [](){ } );
|
std::function<void()> aReturnCallback =
|
||||||
|
[]()
|
||||||
|
{ },
|
||||||
|
std::function<void( wxStyledTextEvent& )> aCharCallback =
|
||||||
|
[]( wxStyledTextEvent& )
|
||||||
|
{ } );
|
||||||
|
|
||||||
|
wxStyledTextCtrl* Scintilla() const { return m_te; }
|
||||||
|
|
||||||
void DoAutocomplete( const wxString& aPartial, const wxArrayString& aTokens );
|
void DoAutocomplete( const wxString& aPartial, const wxArrayString& aTokens );
|
||||||
|
|
||||||
|
@ -49,6 +56,7 @@ protected:
|
||||||
int firstNonWhitespace( int aLine, int* aWhitespaceCount = nullptr );
|
int firstNonWhitespace( int aLine, int* aWhitespaceCount = nullptr );
|
||||||
|
|
||||||
void onCharHook( wxKeyEvent& aEvent );
|
void onCharHook( wxKeyEvent& aEvent );
|
||||||
|
void onChar( wxStyledTextEvent& aEvent );
|
||||||
void onScintillaUpdateUI( wxStyledTextEvent& aEvent );
|
void onScintillaUpdateUI( wxStyledTextEvent& aEvent );
|
||||||
void onThemeChanged( wxSysColourChangedEvent &aEvent );
|
void onThemeChanged( wxSysColourChangedEvent &aEvent );
|
||||||
|
|
||||||
|
@ -61,8 +69,11 @@ protected:
|
||||||
bool m_suppressAutocomplete;
|
bool m_suppressAutocomplete;
|
||||||
bool m_singleLine; // Treat <return> as OK, and skip special tab
|
bool m_singleLine; // Treat <return> as OK, and skip special tab
|
||||||
// stop handling (including monospaced font).
|
// stop handling (including monospaced font).
|
||||||
|
|
||||||
std::function<void()> m_returnCallback; // Process <return> in singleLine, and
|
std::function<void()> m_returnCallback; // Process <return> in singleLine, and
|
||||||
// <shift> + <return> irrespective.
|
// <shift> + <return> irrespective.
|
||||||
|
|
||||||
|
std::function<void( wxStyledTextEvent& aEvent )> m_charCallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SCINTILLA_TRICKS_H
|
#endif // SCINTILLA_TRICKS_H
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
* @author Jon Evans <jon@craftyjon.com>
|
* @author Jon Evans <jon@craftyjon.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
@ -24,6 +24,9 @@
|
||||||
#include <wx/generic/gridctrl.h>
|
#include <wx/generic/gridctrl.h>
|
||||||
|
|
||||||
class wxGrid;
|
class wxGrid;
|
||||||
|
class wxStyledTextCtrl;
|
||||||
|
class wxStyledTextEvent;
|
||||||
|
class SCINTILLA_TRICKS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A text renderer that can unescape text for display
|
* A text renderer that can unescape text for display
|
||||||
|
@ -34,11 +37,44 @@ class GRID_CELL_ESCAPED_TEXT_RENDERER : public wxGridCellStringRenderer
|
||||||
public:
|
public:
|
||||||
GRID_CELL_ESCAPED_TEXT_RENDERER();
|
GRID_CELL_ESCAPED_TEXT_RENDERER();
|
||||||
|
|
||||||
void Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& aDC,
|
void Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& aDC, const wxRect& aRect, int aRow,
|
||||||
const wxRect& aRect, int aRow, int aCol, bool isSelected ) override;
|
int aCol, bool isSelected ) override;
|
||||||
|
|
||||||
wxSize GetBestSize( wxGrid & grid, wxGridCellAttr & attr, wxDC & dc,
|
wxSize GetBestSize( wxGrid& grid, wxGridCellAttr& attr, wxDC& dc, int row, int col ) override;
|
||||||
int row, int col ) override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class GRID_CELL_STC_EDITOR : public wxGridCellEditor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_CELL_STC_EDITOR( std::function<void( wxStyledTextEvent&, SCINTILLA_TRICKS* )> aOnChar );
|
||||||
|
|
||||||
|
void Create( wxWindow* aParent, wxWindowID aId, wxEvtHandler* aEventHandler ) override;
|
||||||
|
|
||||||
|
wxGridCellEditor* Clone() const override
|
||||||
|
{
|
||||||
|
return new GRID_CELL_STC_EDITOR( m_onChar );
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString GetValue() const override;
|
||||||
|
|
||||||
|
void Show( bool aShow, wxGridCellAttr *aAttr = nullptr ) override;
|
||||||
|
void BeginEdit( int aRow, int aCol, wxGrid* aGrid ) override;
|
||||||
|
bool EndEdit( int aRow, int aCol, const wxGrid*, const wxString&, wxString* aNewVal ) override;
|
||||||
|
void ApplyEdit( int aRow, int aCol, wxGrid* aGrid ) override;
|
||||||
|
void Reset() override {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void onFocusLoss( wxFocusEvent& aEvent );
|
||||||
|
|
||||||
|
wxStyledTextCtrl* stc_ctrl() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SCINTILLA_TRICKS* m_scintillaTricks;
|
||||||
|
wxString m_value;
|
||||||
|
|
||||||
|
std::function<void( wxStyledTextEvent&, SCINTILLA_TRICKS* )> m_onChar;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // KICAD_GRID_TEXT_HELPERS_H
|
#endif // KICAD_GRID_TEXT_HELPERS_H
|
||||||
|
|
Loading…
Reference in New Issue