From 0bf3a19967d133477594b2ef8409d467cba39616 Mon Sep 17 00:00:00 2001 From: John Beard Date: Mon, 13 Feb 2017 11:47:50 +0800 Subject: [PATCH] Add user control for grid minimum spacing in GAL This allows the user to set a thicker grid line without causing the grid lines to become over dense, or just make the grid denser according to preference. The term "density" is modified to "minimum grid spacing", which is the pixel spacing between adjacent grid lines. The spacing settings now comes in along, with other GAL display settings, as part of GAL_DISPLAY_OPTIONS observer functionality. To this end, the setter in GAL interface is removed, as an external user should be setting this parameter via the GAL_DISPLAY_OPTIONS interface. --- common/gal/gal_display_options.cpp | 7 + common/gal/graphics_abstraction_layer.cpp | 38 +- common/gal/opengl/opengl_gal.cpp | 16 +- include/gal/gal_display_options.h | 3 + include/gal/graphics_abstraction_layer.h | 19 +- pcbnew/dialogs/dialog_display_options.cpp | 14 + pcbnew/dialogs/dialog_display_options.h | 1 + .../dialogs/dialog_display_options_base.cpp | 22 +- .../dialogs/dialog_display_options_base.fbp | 428 +++++++++++++++++- pcbnew/dialogs/dialog_display_options_base.h | 5 + 10 files changed, 520 insertions(+), 33 deletions(-) diff --git a/common/gal/gal_display_options.cpp b/common/gal/gal_display_options.cpp index ce85aade5b..6544abd8ef 100644 --- a/common/gal/gal_display_options.cpp +++ b/common/gal/gal_display_options.cpp @@ -32,6 +32,7 @@ using namespace KIGFX; static const wxString GalGLAntialiasingKeyword( "OpenGLAntialiasingMode" ); static const wxString GalGridStyleConfig( "GridStyle" ); static const wxString GalGridLineWidthConfig( "GridLineWidth" ); +static const wxString GalGridMaxDensityConfig( "GridMaxDensity" ); GAL_DISPLAY_OPTIONS::GAL_DISPLAY_OPTIONS() @@ -53,6 +54,9 @@ void GAL_DISPLAY_OPTIONS::ReadConfig( wxConfigBase* aCfg, wxString aBaseName ) aCfg->Read( aBaseName + GalGridLineWidthConfig, &m_gridLineWidth, 0.5 ); + aCfg->Read( aBaseName + GalGridMaxDensityConfig, + &m_gridMinSpacing, 10 ); + NotifyChanged(); } @@ -67,6 +71,9 @@ void GAL_DISPLAY_OPTIONS::WriteConfig( wxConfigBase* aCfg, wxString aBaseName ) aCfg->Write( aBaseName + GalGridLineWidthConfig, m_gridLineWidth ); + + aCfg->Write( aBaseName + GalGridMaxDensityConfig, + m_gridMinSpacing ); } diff --git a/common/gal/graphics_abstraction_layer.cpp b/common/gal/graphics_abstraction_layer.cpp index 7e4ac5dbf2..9bd8a98d8b 100644 --- a/common/gal/graphics_abstraction_layer.cpp +++ b/common/gal/graphics_abstraction_layer.cpp @@ -58,10 +58,10 @@ GAL::GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions ) : // Set grid defaults SetGridVisibility( true ); - SetGridDrawThreshold( 10 ); SetCoarseGrid( 10 ); gridLineWidth = 0.5; gridStyle = GRID_STYLE::LINES; + gridMinSpacing = 10; // Initialize the cursor shape SetCursorColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) ); @@ -104,6 +104,12 @@ bool GAL::updatedGalDisplayOptions( const GAL_DISPLAY_OPTIONS& aOptions ) refresh = true; } + if( options.m_gridMinSpacing != gridMinSpacing ) + { + gridMinSpacing = options.m_gridMinSpacing; + refresh = true; + } + // tell the derived class if the base class needs an update or not return refresh; } @@ -157,6 +163,14 @@ void GAL::ComputeWorldScreenMatrix() } +double GAL::computeMinGridSpacing() const +{ + // just return the current value. This could be cleverer and take + // into account other settings in future + return gridMinSpacing; +} + + void GAL::DrawGrid() { if( !gridVisibility ) @@ -170,6 +184,8 @@ void GAL::DrawGrid() VECTOR2D worldStartPoint = screenWorldMatrix * VECTOR2D( 0.0, 0.0 ); VECTOR2D worldEndPoint = screenWorldMatrix * VECTOR2D( screenSize ); + const double gridThreshold = computeMinGridSpacing(); + int gridScreenSizeDense = KiROUND( gridSize.x * worldScale ); int gridScreenSizeCoarse = KiROUND( gridSize.x * static_cast( gridTick ) * worldScale ); @@ -181,7 +197,7 @@ void GAL::DrawGrid() double doubleMarker = 2.0 * marker; // Check if the grid would not be too dense - if( std::max( gridScreenSizeDense, gridScreenSizeCoarse ) > gridDrawThreshold ) + if( std::max( gridScreenSizeDense, gridScreenSizeCoarse ) > gridThreshold ) { // Compute grid variables int gridStartX = KiROUND( worldStartPoint.x / gridSize.x ); @@ -222,13 +238,13 @@ void GAL::DrawGrid() // Vertical lines for( int j = gridStartY; j != gridEndY; j += dirY ) { - if( j % gridTick == 0 && gridScreenSizeDense > gridDrawThreshold ) + if( j % gridTick == 0 && gridScreenSizeDense > gridThreshold ) SetLineWidth( doubleMarker ); else SetLineWidth( marker ); - if( ( j % gridTick == 0 && gridScreenSizeCoarse > gridDrawThreshold ) - || gridScreenSizeDense > gridDrawThreshold ) + if( ( j % gridTick == 0 && gridScreenSizeCoarse > gridThreshold ) + || gridScreenSizeDense > gridThreshold ) { drawGridLine( VECTOR2D( gridStartX * gridSize.x, j * gridSize.y + gridOrigin.y ), VECTOR2D( gridEndX * gridSize.x, j * gridSize.y + gridOrigin.y ) ); @@ -238,13 +254,13 @@ void GAL::DrawGrid() // Horizontal lines for( int i = gridStartX; i != gridEndX; i += dirX ) { - if( i % gridTick == 0 && gridScreenSizeDense > gridDrawThreshold ) + if( i % gridTick == 0 && gridScreenSizeDense > gridThreshold ) SetLineWidth( doubleMarker ); else SetLineWidth( marker ); - if( ( i % gridTick == 0 && gridScreenSizeCoarse > gridDrawThreshold ) - || gridScreenSizeDense > gridDrawThreshold ) + if( ( i % gridTick == 0 && gridScreenSizeCoarse > gridThreshold ) + || gridScreenSizeDense > gridThreshold ) { drawGridLine( VECTOR2D( i * gridSize.x + gridOrigin.x, gridStartY * gridSize.y ), VECTOR2D( i * gridSize.x + gridOrigin.x, gridEndY * gridSize.y ) ); @@ -260,19 +276,19 @@ void GAL::DrawGrid() for( int j = gridStartY; j != gridEndY; j += dirY ) { - if( j % gridTick == 0 && gridScreenSizeDense > gridDrawThreshold ) + if( j % gridTick == 0 && gridScreenSizeDense > gridThreshold ) tickY = true; else tickY = false; for( int i = gridStartX; i != gridEndX; i += dirX ) { - if( i % gridTick == 0 && gridScreenSizeDense > gridDrawThreshold ) + if( i % gridTick == 0 && gridScreenSizeDense > gridThreshold ) tickX = true; else tickX = false; - if( tickX || tickY || gridScreenSizeDense > gridDrawThreshold ) + if( tickX || tickY || gridScreenSizeDense > gridThreshold ) { double radius = ( ( tickX && tickY ) ? doubleMarker : marker ) / 2.0; DrawRectangle( VECTOR2D( i * gridSize.x - radius + gridOrigin.x, diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index bd50e673af..0153360176 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -852,8 +852,10 @@ void OPENGL_GAL::DrawGrid() double minorLineWidth = std::max( 1.0, gridLineWidth ); double majorLineWidth = minorLineWidth * 2.0; + const double gridThreshold = computeMinGridSpacing(); + // Check if the grid would not be too dense - if( std::max( gridScreenSizeDense, gridScreenSizeCoarse ) < gridDrawThreshold ) + if( std::max( gridScreenSizeDense, gridScreenSizeCoarse ) < gridThreshold ) return; SetTarget( TARGET_NONCACHED ); @@ -907,13 +909,13 @@ void OPENGL_GAL::DrawGrid() // Vertical lines for( int j = gridStartY; j != gridEndY; j += dirY ) { - if( j % gridTick == 0 && gridScreenSizeDense > gridDrawThreshold ) + if( j % gridTick == 0 && gridScreenSizeDense > gridThreshold ) glLineWidth( majorLineWidth ); else glLineWidth( minorLineWidth ); - if( ( j % gridTick == 0 && gridScreenSizeCoarse > gridDrawThreshold ) - || gridScreenSizeDense > gridDrawThreshold ) + if( ( j % gridTick == 0 && gridScreenSizeCoarse > gridThreshold ) + || gridScreenSizeDense > gridThreshold ) { glBegin( GL_LINES ); glVertex2d( gridStartX * gridSize.x, j * gridSize.y + gridOrigin.y ); @@ -931,13 +933,13 @@ void OPENGL_GAL::DrawGrid() // Horizontal lines for( int i = gridStartX; i != gridEndX; i += dirX ) { - if( i % gridTick == 0 && gridScreenSizeDense > gridDrawThreshold ) + if( i % gridTick == 0 && gridScreenSizeDense > gridThreshold ) glLineWidth( majorLineWidth ); else glLineWidth( minorLineWidth ); - if( ( i % gridTick == 0 && gridScreenSizeCoarse > gridDrawThreshold ) - || gridScreenSizeDense > gridDrawThreshold ) + if( ( i % gridTick == 0 && gridScreenSizeCoarse > gridThreshold ) + || gridScreenSizeDense > gridThreshold ) { glBegin( GL_LINES ); glVertex2d( i * gridSize.x + gridOrigin.x, gridStartY * gridSize.y ); diff --git a/include/gal/gal_display_options.h b/include/gal/gal_display_options.h index b7524d2cf3..1c505a06fd 100644 --- a/include/gal/gal_display_options.h +++ b/include/gal/gal_display_options.h @@ -74,6 +74,9 @@ namespace KIGFX ///> Thickness to render grid lines/dots double m_gridLineWidth; + + ///> Minimum pixel distance between displayed grid lines + double m_gridMinSpacing; }; } diff --git a/include/gal/graphics_abstraction_layer.h b/include/gal/graphics_abstraction_layer.h index b3f78a2543..8c00d511c9 100644 --- a/include/gal/graphics_abstraction_layer.h +++ b/include/gal/graphics_abstraction_layer.h @@ -766,16 +766,6 @@ public: (long) gridOrigin.y % (long) gridSize.y ); } - /** - * @brief Set the threshold for grid drawing. - * - * @param aThreshold is the minimum grid cell size (in pixels) for which the grid is drawn. - */ - inline void SetGridDrawThreshold( int aThreshold ) - { - gridDrawThreshold = aThreshold; - } - /** * @brief Set the grid size. * @@ -978,7 +968,7 @@ protected: COLOR4D gridColor; ///< Color of the grid int gridTick; ///< Every tick line gets the double width double gridLineWidth; ///< Line width of the grid - int gridDrawThreshold; ///< Minimum screen size of the grid (pixels) + int gridMinSpacing; ///< Minimum screen size of the grid (pixels) ///< below which the grid is not drawn // Cursor settings @@ -996,6 +986,13 @@ protected: worldScale = screenDPI * worldUnitLength * zoomFactor; } + /** + * @brief compute minimum grid spacing from the grid settings + * + * @return the minimum spacing to use for drawing the grid + */ + double computeMinGridSpacing() const; + /** * @brief Draw a grid line (usually a simplified line function). * diff --git a/pcbnew/dialogs/dialog_display_options.cpp b/pcbnew/dialogs/dialog_display_options.cpp index 8c2ddd1ccc..ee0697aff0 100644 --- a/pcbnew/dialogs/dialog_display_options.cpp +++ b/pcbnew/dialogs/dialog_display_options.cpp @@ -51,6 +51,9 @@ static const double gridThicknessMin = 0.5; static const double gridThicknessMax = 10.0; static const double gridThicknessStep = 0.5; +static const double gridMinSpacingMin = 5; +static const double gridMinSpacingMax = 200; +static const double gridMinSpacingStep = 5; static void setRadioFromGridStyle( wxRadioBox& aRBox, KIGFX::GRID_STYLE aStyle ) @@ -214,6 +217,13 @@ DIALOG_DISPLAY_OPTIONS::DIALOG_DISPLAY_OPTIONS( PCB_EDIT_FRAME* parent ) : gridThicknessStep ); m_gridSizeIncrementer->SetPrecision( 1 ); + m_gridMinSpacingIncrementer = std::make_unique( + *m_gridMinSpacingSpinBtn, *m_gridMinSpacing); + + m_gridMinSpacingIncrementer->SetStep( gridMinSpacingMin, gridMinSpacingMax, + gridMinSpacingStep ); + m_gridMinSpacingIncrementer->SetPrecision( 0 ); // restrict to ints + // load settings into controls init(); @@ -254,6 +264,8 @@ void DIALOG_DISPLAY_OPTIONS::init() setRadioFromGridStyle( *m_gridStyle, gal_opts.m_gridStyle ); m_gridSizeIncrementer->SetValue( gal_opts.m_gridLineWidth ); + + m_gridMinSpacingIncrementer->SetValue( gal_opts.m_gridMinSpacing ); } @@ -300,6 +312,8 @@ void DIALOG_DISPLAY_OPTIONS::OnOkClick(wxCommandEvent& event) gal_opts.m_gridLineWidth = m_gridSizeIncrementer->GetValue(); + gal_opts.m_gridMinSpacing = m_gridMinSpacingIncrementer->GetValue(); + gal_opts.NotifyChanged(); // Apply changes to the GAL diff --git a/pcbnew/dialogs/dialog_display_options.h b/pcbnew/dialogs/dialog_display_options.h index 63a34b612b..dc8b58692c 100644 --- a/pcbnew/dialogs/dialog_display_options.h +++ b/pcbnew/dialogs/dialog_display_options.h @@ -35,6 +35,7 @@ private: PCB_EDIT_FRAME* m_Parent; std::unique_ptr m_gridSizeIncrementer; + std::unique_ptr m_gridMinSpacingIncrementer; void init(); diff --git a/pcbnew/dialogs/dialog_display_options_base.cpp b/pcbnew/dialogs/dialog_display_options_base.cpp index a508791b67..db2a7b4e86 100644 --- a/pcbnew/dialogs/dialog_display_options_base.cpp +++ b/pcbnew/dialogs/dialog_display_options_base.cpp @@ -56,7 +56,7 @@ DIALOG_DISPLAY_OPTIONS_BASE::DIALOG_DISPLAY_OPTIONS_BASE( wxWindow* parent, wxWi sGridSettings->Add( m_gridStyle, 0, wxALL|wxEXPAND, 5 ); wxFlexGridSizer* sGridSettingsGrid; - sGridSettingsGrid = new wxFlexGridSizer( 0, 3, 0, 0 ); + sGridSettingsGrid = new wxFlexGridSizer( 0, 4, 0, 0 ); sGridSettingsGrid->AddGrowableCol( 1 ); sGridSettingsGrid->SetFlexibleDirection( wxBOTH ); sGridSettingsGrid->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); @@ -66,11 +66,29 @@ DIALOG_DISPLAY_OPTIONS_BASE::DIALOG_DISPLAY_OPTIONS_BASE( wxWindow* parent, wxWi sGridSettingsGrid->Add( l_gridLineWidth, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); m_gridLineWidth = new wxTextCtrl( sGridSettings->GetStaticBox(), wxID_ANY, _("0.5"), wxDefaultPosition, wxDefaultSize, 0 ); - sGridSettingsGrid->Add( m_gridLineWidth, 0, wxEXPAND, 0 ); + sGridSettingsGrid->Add( m_gridLineWidth, 0, wxEXPAND, 5 ); m_gridLineWidthSpinBtn = new wxSpinButton( sGridSettings->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS ); sGridSettingsGrid->Add( m_gridLineWidthSpinBtn, 0, wxALL, 0 ); + l_gridLineWidthUnits = new wxStaticText( sGridSettings->GetStaticBox(), wxID_ANY, _("px"), wxDefaultPosition, wxDefaultSize, 0 ); + l_gridLineWidthUnits->Wrap( -1 ); + sGridSettingsGrid->Add( l_gridLineWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + l_gridMinSpacing = new wxStaticText( sGridSettings->GetStaticBox(), wxID_ANY, _("Min grid spacing:"), wxDefaultPosition, wxDefaultSize, 0 ); + l_gridMinSpacing->Wrap( -1 ); + sGridSettingsGrid->Add( l_gridMinSpacing, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + m_gridMinSpacing = new wxTextCtrl( sGridSettings->GetStaticBox(), wxID_ANY, _("10"), wxDefaultPosition, wxDefaultSize, 0 ); + sGridSettingsGrid->Add( m_gridMinSpacing, 0, wxEXPAND, 5 ); + + m_gridMinSpacingSpinBtn = new wxSpinButton( sGridSettings->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS ); + sGridSettingsGrid->Add( m_gridMinSpacingSpinBtn, 0, wxALL, 0 ); + + l_gridMinSpacingUnits = new wxStaticText( sGridSettings->GetStaticBox(), wxID_ANY, _("px"), wxDefaultPosition, wxDefaultSize, 0 ); + l_gridMinSpacingUnits->Wrap( -1 ); + sGridSettingsGrid->Add( l_gridMinSpacingUnits, 0, wxALL, 5 ); + sGridSettings->Add( sGridSettingsGrid, 1, wxALL|wxEXPAND, 5 ); diff --git a/pcbnew/dialogs/dialog_display_options_base.fbp b/pcbnew/dialogs/dialog_display_options_base.fbp index 724e2692a1..0ec8d3c9ae 100644 --- a/pcbnew/dialogs/dialog_display_options_base.fbp +++ b/pcbnew/dialogs/dialog_display_options_base.fbp @@ -513,7 +513,7 @@ wxALL|wxEXPAND 1 - 3 + 4 wxBOTH 1 @@ -608,7 +608,7 @@ - 0 + 5 wxEXPAND 0 @@ -782,6 +782,430 @@ + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + px + + 0 + + + 0 + + 1 + l_gridLineWidthUnits + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Min grid spacing: + + 0 + + + 0 + + 1 + l_gridMinSpacing + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_gridMinSpacing + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_gridMinSpacingSpinBtn + 1 + + + protected + 1 + + Resizable + 1 + + wxSP_ARROW_KEYS + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + px + + 0 + + + 0 + + 1 + l_gridMinSpacingUnits + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pcbnew/dialogs/dialog_display_options_base.h b/pcbnew/dialogs/dialog_display_options_base.h index d48ad7ccfd..7dc31703c0 100644 --- a/pcbnew/dialogs/dialog_display_options_base.h +++ b/pcbnew/dialogs/dialog_display_options_base.h @@ -53,6 +53,11 @@ class DIALOG_DISPLAY_OPTIONS_BASE : public DIALOG_SHIM wxStaticText* l_gridLineWidth; wxTextCtrl* m_gridLineWidth; wxSpinButton* m_gridLineWidthSpinBtn; + wxStaticText* l_gridLineWidthUnits; + wxStaticText* l_gridMinSpacing; + wxTextCtrl* m_gridMinSpacing; + wxSpinButton* m_gridMinSpacingSpinBtn; + wxStaticText* l_gridMinSpacingUnits; wxRadioBox* m_ShowNetNamesOption; wxRadioBox* m_OptDisplayTracksClearance; wxCheckBox* m_OptDisplayModOutlines;