Go back to using space-width for tabs (instead of max-char-width).

The max-char-width impl was buggy and never applied to PCBNew anyway.
Plus the stroke font has a max-char-width of 2.8 time the space width,
so it made for really wide tab spacing.

Also fixes a bug where the Scintilla editors weren't getting a
monospace font on Mac.  (This bug may also exist on the other
platforms, but each would need its own fix.)

Also moves more of the Scintalla customizations to SCINTILLA_TRICKS
where they can be shared.

Fixes https://gitlab.com/kicad/code/kicad/issues/8666
This commit is contained in:
Jeff Young 2021-06-24 23:50:57 +01:00
parent 232ffe97be
commit 27804e40e2
7 changed files with 39 additions and 95 deletions

View File

@ -4,7 +4,7 @@
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de * Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
* Copyright (C) 2013 CERN * Copyright (C) 2013 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* Copyright (C) 2016 Kicad Developers, see change_log.txt for contributors. * Copyright (C) 2016-2021 Kicad Developers, see change_log.txt for contributors.
* *
* Stroke font class * Stroke font class
* *
@ -48,7 +48,9 @@ std::vector<BOX2D>* g_newStrokeFontGlyphBoundingBoxes; ///< Bounding boxes of
STROKE_FONT::STROKE_FONT( GAL* aGal ) : STROKE_FONT::STROKE_FONT( GAL* aGal ) :
m_gal( aGal ), m_glyphs( nullptr ), m_glyphBoundingBoxes( nullptr ), m_maxGlyphWidth( 1.0 ) m_gal( aGal ),
m_glyphs( nullptr ),
m_glyphBoundingBoxes( nullptr )
{ {
} }
@ -151,8 +153,6 @@ bool STROKE_FONT::LoadNewStrokeFont( const char* const aNewStrokeFont[], int aNe
// Compute the bounding box of the glyph // Compute the bounding box of the glyph
g_newStrokeFontGlyphBoundingBoxes->emplace_back( computeBoundingBox( glyph, glyphWidth ) ); g_newStrokeFontGlyphBoundingBoxes->emplace_back( computeBoundingBox( glyph, glyphWidth ) );
g_newStrokeFontGlyphs->push_back( glyph ); g_newStrokeFontGlyphs->push_back( glyph );
m_maxGlyphWidth = std::max( m_maxGlyphWidth,
g_newStrokeFontGlyphBoundingBoxes->back().GetWidth() );
} }
m_glyphs = g_newStrokeFontGlyphs; m_glyphs = g_newStrokeFontGlyphs;
@ -343,15 +343,15 @@ void STROKE_FONT::drawSingleLineText( const UTF8& aText )
for( UTF8::uni_iter chIt = aText.ubegin(), end = aText.uend(); chIt < end; ++chIt ) for( UTF8::uni_iter chIt = aText.ubegin(), end = aText.uend(); chIt < end; ++chIt )
{ {
// Handle tabs as locked to the nearest 4th column (counting in spaces) // Handle tabs as locked to the nearest 4th column (counting in space-widths).
// The choice of spaces is somewhat arbitrary but sufficient for aligning text // The choice of spaces is somewhat arbitrary but sufficient for aligning text; while
// it can produce tabs that go backwards when following wide characters, spacing in
// widest-char-widths produces tab spacing that is much too wide (and would change the
// layout of existing boards).
if( *chIt == '\t' ) if( *chIt == '\t' )
{ {
// We align to the 4th column. This is based on the monospace font used in the text input
// boxes. Here, we take the widest character as our baseline spacing and make tab stops
// at each fourth of this widest character
char_count = ( char_count / 4 + 1 ) * 4 - 1; char_count = ( char_count / 4 + 1 ) * 4 - 1;
xOffset = m_maxGlyphWidth * baseGlyphSize.x * char_count; xOffset = baseGlyphSize.x * char_count;
glyphSize = baseGlyphSize; glyphSize = baseGlyphSize;
yOffset = 0; yOffset = 0;

View File

@ -43,6 +43,23 @@ SCINTILLA_TRICKS::SCINTILLA_TRICKS( wxStyledTextCtrl* aScintilla, const wxString
m_te->SetScrollWidth( 1 ); m_te->SetScrollWidth( 1 );
m_te->SetScrollWidthTracking( true ); m_te->SetScrollWidthTracking( true );
// Set a monospace font with a tab width of 4. This is the closest we can get to having
// Scintilla mimic the stroke font's tab positioning.
int size = wxNORMAL_FONT->GetPointSize();
wxFont fixedFont( size, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL );
#ifdef __WXMAC__
// I think wxFONTFAMILY_TELETYPE worked on wxWidgets 3.0, but it doesn't on 3.1. Set a
// monospaced font by hand.
fixedFont.SetFaceName( "Menlo" );
#endif
for( size_t i = 0; i < wxSTC_STYLE_MAX; ++i )
m_te->StyleSetFont( i, fixedFont );
m_te->StyleClearAll(); // Addresses a bug in wx3.0 where styles are not correctly set
m_te->SetTabWidth( 4 );
// Set up the brace highlighting // Set up the brace highlighting
wxColour highlight = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ); wxColour highlight = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT );
wxColour highlightText = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ); wxColour highlightText = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );

View File

@ -55,7 +55,7 @@ DIALOG_LABEL_EDITOR::DIALOG_LABEL_EDITOR( SCH_EDIT_FRAME* aParent, SCH_TEXT* aTe
m_valueMultiLine->SetEOLMode( wxSTC_EOL_LF ); m_valueMultiLine->SetEOLMode( wxSTC_EOL_LF );
m_scintillaTricks = new SCINTILLA_TRICKS( m_valueMultiLine, wxT( "()" ) ); m_scintillaTricks = new SCINTILLA_TRICKS( m_valueMultiLine, wxT( "{}" ) );
if( m_CurrentText->IsMultilineAllowed() ) if( m_CurrentText->IsMultilineAllowed() )
{ {
@ -127,15 +127,6 @@ DIALOG_LABEL_EDITOR::DIALOG_LABEL_EDITOR( SCH_EDIT_FRAME* aParent, SCH_TEXT* aTe
m_valueMultiLine->Bind( wxEVT_STC_CHARADDED, &DIALOG_LABEL_EDITOR::onScintillaCharAdded, this ); m_valueMultiLine->Bind( wxEVT_STC_CHARADDED, &DIALOG_LABEL_EDITOR::onScintillaCharAdded, this );
int size = wxNORMAL_FONT->GetPointSize();
wxFont fixedFont( size, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL );
for( size_t i = 0; i < wxSTC_STYLE_MAX; ++i )
m_valueMultiLine->StyleSetFont( i, fixedFont );
// Addresses a bug in wx3.0 where styles are not correctly set
m_valueMultiLine->StyleClearAll();
// DIALOG_SHIM needs a unique hash_key because classname is not sufficient because the // DIALOG_SHIM needs a unique hash_key because classname is not sufficient because the
// various versions have different controls so we want to store sizes for each version. // various versions have different controls so we want to store sizes for each version.
m_hash_key = TO_UTF8( GetTitle() ); m_hash_key = TO_UTF8( GetTitle() );

View File

@ -168,7 +168,6 @@ private:
GAL* m_gal; ///< Pointer to the GAL GAL* m_gal; ///< Pointer to the GAL
const GLYPH_LIST* m_glyphs; ///< Glyph list const GLYPH_LIST* m_glyphs; ///< Glyph list
const std::vector<BOX2D>* m_glyphBoundingBoxes; ///< Bounding boxes of the glyphs const std::vector<BOX2D>* m_glyphBoundingBoxes; ///< Bounding boxes of the glyphs
double m_maxGlyphWidth; ///< The widest glyph in our set
///< Factor that determines relative vertical position of the overbar. ///< Factor that determines relative vertical position of the overbar.
static const double OVERBAR_POSITION_FACTOR; static const double OVERBAR_POSITION_FACTOR;

View File

@ -36,7 +36,7 @@
#include <pcb_layer_box_selector.h> #include <pcb_layer_box_selector.h>
#include <wx/valnum.h> #include <wx/valnum.h>
#include <math/util.h> // for KiROUND #include <math/util.h> // for KiROUND
#include <scintilla_tricks.h>
DIALOG_TEXT_PROPERTIES::DIALOG_TEXT_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent, BOARD_ITEM* aItem ) : DIALOG_TEXT_PROPERTIES::DIALOG_TEXT_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent, BOARD_ITEM* aItem ) :
DIALOG_TEXT_PROPERTIES_BASE( aParent ), DIALOG_TEXT_PROPERTIES_BASE( aParent ),
@ -60,6 +60,8 @@ DIALOG_TEXT_PROPERTIES::DIALOG_TEXT_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent, BO
m_MultiLineText->SetEOLMode( wxSTC_EOL_LF ); m_MultiLineText->SetEOLMode( wxSTC_EOL_LF );
m_scintillaTricks = new SCINTILLA_TRICKS( m_MultiLineText, wxT( "{}" ) );
// A hack which causes Scintilla to auto-size the text editor canvas // A hack which causes Scintilla to auto-size the text editor canvas
// See: https://github.com/jacobslusser/ScintillaNET/issues/216 // See: https://github.com/jacobslusser/ScintillaNET/issues/216
m_MultiLineText->SetScrollWidth( 1 ); m_MultiLineText->SetScrollWidth( 1 );
@ -92,15 +94,6 @@ DIALOG_TEXT_PROPERTIES::DIALOG_TEXT_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent, BO
SetInitialFocus( m_MultiLineText ); SetInitialFocus( m_MultiLineText );
m_SingleLineSizer->Show( false ); m_SingleLineSizer->Show( false );
int size = wxNORMAL_FONT->GetPointSize();
wxFont fixedFont( size, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL );
for( size_t i = 0; i < wxSTC_STYLE_MAX; ++i )
m_MultiLineText->StyleSetFont( i, fixedFont );
// Addresses a bug in wx3.0 where styles are not correctly set
m_MultiLineText->StyleClearAll();
// This option makes sense only for footprint texts; texts on board are always visible. // This option makes sense only for footprint texts; texts on board are always visible.
m_Visible->SetValue( true ); m_Visible->SetValue( true );
m_Visible->Enable( false ); m_Visible->Enable( false );
@ -170,6 +163,8 @@ DIALOG_TEXT_PROPERTIES::DIALOG_TEXT_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent, BO
DIALOG_TEXT_PROPERTIES::~DIALOG_TEXT_PROPERTIES() DIALOG_TEXT_PROPERTIES::~DIALOG_TEXT_PROPERTIES()
{ {
Disconnect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_TEXT_PROPERTIES::OnCharHook ), NULL, this ); Disconnect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_TEXT_PROPERTIES::OnCharHook ), NULL, this );
delete m_scintillaTricks;
} }
@ -181,60 +176,6 @@ void PCB_BASE_EDIT_FRAME::ShowTextPropertiesDialog( BOARD_ITEM* aText )
} }
void DIALOG_TEXT_PROPERTIES::OnCharHook( wxKeyEvent& aEvent )
{
if( aEvent.GetKeyCode() == WXK_RETURN && aEvent.ShiftDown() )
{
if( TransferDataFromWindow() )
{
// Do not use EndModal to close the dialog that can be opened
// in quasi modal mode
SetReturnCode( wxID_OK );
Close();
}
}
else if( m_MultiLineText->IsShown() && m_MultiLineText->HasFocus() )
{
if( aEvent.GetKeyCode() == WXK_TAB && !aEvent.ControlDown() )
{
m_MultiLineText->Tab();
}
else if( IsCtrl( 'Z', aEvent ) )
{
m_MultiLineText->Undo();
}
else if( IsShiftCtrl( 'Z', aEvent ) || IsCtrl( 'Y', aEvent ) )
{
m_MultiLineText->Redo();
}
else if( IsCtrl( 'X', aEvent ) )
{
m_MultiLineText->Cut();
}
else if( IsCtrl( 'C', aEvent ) )
{
m_MultiLineText->Copy();
}
else if( IsCtrl( 'V', aEvent ) )
{
m_MultiLineText->Paste();
}
else if( IsCtrl( 'A', aEvent ) )
{
m_MultiLineText->SelectAll();
}
else
{
aEvent.Skip();
}
}
else
{
aEvent.Skip();
}
}
void DIALOG_TEXT_PROPERTIES::OnSetFocusText( wxFocusEvent& event ) void DIALOG_TEXT_PROPERTIES::OnSetFocusText( wxFocusEvent& event )
{ {
#ifdef __WXGTK__ #ifdef __WXGTK__

View File

@ -35,6 +35,7 @@ class BOARD_ITEM;
class EDA_TEXT; class EDA_TEXT;
class FP_TEXT; class FP_TEXT;
class PCB_TEXT; class PCB_TEXT;
class SCINTILLA_TRICKS;
class DIALOG_TEXT_PROPERTIES : public DIALOG_TEXT_PROPERTIES_BASE class DIALOG_TEXT_PROPERTIES : public DIALOG_TEXT_PROPERTIES_BASE
@ -50,6 +51,10 @@ public:
*/ */
virtual void OnSetFocusText( wxFocusEvent& event ) override; virtual void OnSetFocusText( wxFocusEvent& event ) override;
private:
bool TransferDataToWindow() override;
bool TransferDataFromWindow() override;
private: private:
PCB_BASE_EDIT_FRAME* m_Parent; PCB_BASE_EDIT_FRAME* m_Parent;
BOARD_ITEM* m_item; // FP_TEXT or PCB_TEXT BOARD_ITEM* m_item; // FP_TEXT or PCB_TEXT
@ -65,10 +70,7 @@ private:
UNIT_BINDER m_orientation; // rotation in degrees UNIT_BINDER m_orientation; // rotation in degrees
double m_OrientValue; double m_OrientValue;
bool TransferDataToWindow() override; SCINTILLA_TRICKS* m_scintillaTricks;
bool TransferDataFromWindow() override;
void OnCharHook( wxKeyEvent& aEvent ) override;
}; };

View File

@ -49,12 +49,6 @@ PANEL_SETUP_RULES::PANEL_SETUP_RULES( PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFr
{ {
m_scintillaTricks = new SCINTILLA_TRICKS( m_textEditor, wxT( "()" ) ); m_scintillaTricks = new SCINTILLA_TRICKS( m_textEditor, wxT( "()" ) );
int size = wxNORMAL_FONT->GetPointSize();
wxFont fixedFont( size, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL );
for( size_t i = 0; i < wxSTC_STYLE_MAX; ++i )
m_textEditor->StyleSetFont( i, fixedFont );
m_netClassRegex.Compile( "NetClass\\s*[!=]=\\s*$", wxRE_ADVANCED ); m_netClassRegex.Compile( "NetClass\\s*[!=]=\\s*$", wxRE_ADVANCED );
m_netNameRegex.Compile( "NetName\\s*[!=]=\\s*$", wxRE_ADVANCED ); m_netNameRegex.Compile( "NetName\\s*[!=]=\\s*$", wxRE_ADVANCED );