diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index d063d63dec..dab37c4be9 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -114,6 +114,8 @@ set( COMMON_DLG_SRCS dialogs/dialog_edit_library_tables.cpp dialogs/dialog_global_lib_table_config.cpp dialogs/dialog_global_lib_table_config_base.cpp + dialogs/dialog_grid_settings.cpp + dialogs/dialog_grid_settings_base.cpp dialogs/dialog_hotkey_list.cpp dialogs/dialog_HTML_reporter_base.cpp dialogs/dialog_locked_items_query.cpp @@ -468,6 +470,7 @@ set( COMMON_SRCS settings/color_settings.cpp settings/cvpcb_settings.cpp settings/common_settings.cpp + settings/grid_settings.cpp settings/json_settings.cpp settings/nested_settings.cpp settings/parameters.cpp diff --git a/common/dialogs/dialog_grid_settings.cpp b/common/dialogs/dialog_grid_settings.cpp new file mode 100644 index 0000000000..42f7ccce01 --- /dev/null +++ b/common/dialogs/dialog_grid_settings.cpp @@ -0,0 +1,81 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DIALOG_GRID_SETTINGS::DIALOG_GRID_SETTINGS( wxWindow* aParent, wxWindow* aEventSource, + UNITS_PROVIDER* aProvider, GRID& aGrid ) : + DIALOG_GRID_SETTINGS_BASE( aParent ), + m_unitsProvider( aProvider ), m_grid( aGrid ), + m_gridSizeX( aProvider, aEventSource, m_staticTextX, m_textX, m_staticTextXUnits, true ), + m_gridSizeY( aProvider, aEventSource, m_staticTextY, m_textY, m_staticTextYUnits, true ) +{ + SetupStandardButtons(); + SetInitialFocus( m_textName ); + + Layout(); + + // Now all widgets have the size fixed, call FinishDialogSettings + finishDialogSettings(); +} + +bool DIALOG_GRID_SETTINGS::TransferDataFromWindow() +{ + double gridX = m_gridSizeX.GetDoubleValue(); + double gridY = m_checkLinked->IsChecked() ? gridX : m_gridSizeY.GetDoubleValue(); + + if( gridX <= 0.0f || gridY <= 0.0f ) + { + wxMessageBox( _( "Grid size must be greater than zero." ), _( "Error" ), + wxOK | wxICON_ERROR ); + return false; + } + + m_grid.name = m_textName->GetValue(); + // Grid X/Y are always stored in millimeters so we can compare them easily + m_grid.x = EDA_UNIT_UTILS::UI::StringFromValue( m_unitsProvider->GetIuScale(), + EDA_UNITS::MILLIMETRES, gridX ); + m_grid.y = EDA_UNIT_UTILS::UI::StringFromValue( m_unitsProvider->GetIuScale(), + EDA_UNITS::MILLIMETRES, gridY ); + + return true; +} + + +void DIALOG_GRID_SETTINGS::OnLinkedChecked( wxCommandEvent& event ) +{ + m_textY->Enable( !m_checkLinked->IsChecked() ); +} diff --git a/common/dialogs/dialog_grid_settings.fbp b/common/dialogs/dialog_grid_settings.fbp new file mode 100644 index 0000000000..aa1a60bb54 --- /dev/null +++ b/common/dialogs/dialog_grid_settings.fbp @@ -0,0 +1,746 @@ + + + + + ; + C++ + 1 + source_name + 0 + 0 + res + UTF-8 + connect + dialog_grid_settings_base + 1000 + none + + + 0 + DIALOG_GRID_SETTINGS + + . + + 1 + 1 + 1 + 1 + UI + 0 + 0 + 0 + + 0 + wxAUI_MGR_DEFAULT + + wxBOTH + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + DIALOG_GRID_SETTINGS_BASE + + 288,233 + wxDEFAULT_DIALOG_STYLE + DIALOG_SHIM; dialog_shim.h; forward_declare + Grid Settings + + 0 + + + + + + bMainSizer + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 3 + wxBOTH + 1 + + 0 + + m_fgGrid + wxFLEX_GROWMODE_SPECIFIED + none + 0 + 0 + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Name: + 0 + + 0 + + + 0 + + 1 + m_staticTextName + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_textName + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + (optional) + 0 + + 0 + + + 0 + + 1 + m_staticTextOptional + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + X: + 0 + + 0 + + + 0 + + 1 + m_staticTextX + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_textX + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + unit + 0 + + 0 + + + 0 + + 1 + m_staticTextXUnits + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxEXPAND + 0 + + 0 + protected + 0 + + + + 5 + wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Linked + + 0 + + + 0 + + 1 + m_checkLinked + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnLinkedChecked + + + + 5 + wxEXPAND + 0 + + 0 + protected + 0 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Y: + 0 + + 0 + + + 0 + + 1 + m_staticTextY + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_textY + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + unit + 0 + + 0 + + + 0 + + 1 + m_staticTextYUnits + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + + + 5 + wxALL|wxEXPAND + 1 + + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + + m_stdButtons + protected + + + + + + diff --git a/common/dialogs/dialog_grid_settings_base.cpp b/common/dialogs/dialog_grid_settings_base.cpp new file mode 100644 index 0000000000..3fc5ba0914 --- /dev/null +++ b/common/dialogs/dialog_grid_settings_base.cpp @@ -0,0 +1,97 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3) +// http://www.wxformbuilder.org/ +// +// PLEASE DO *NOT* EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "dialog_grid_settings_base.h" + +/////////////////////////////////////////////////////////////////////////// + +DIALOG_GRID_SETTINGS_BASE::DIALOG_GRID_SETTINGS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bMainSizer; + bMainSizer = new wxBoxSizer( wxVERTICAL ); + + wxFlexGridSizer* m_fgGrid; + m_fgGrid = new wxFlexGridSizer( 0, 3, 0, 0 ); + m_fgGrid->AddGrowableCol( 1 ); + m_fgGrid->SetFlexibleDirection( wxBOTH ); + m_fgGrid->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + m_staticTextName = new wxStaticText( this, wxID_ANY, wxT("Name:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextName->Wrap( -1 ); + m_fgGrid->Add( m_staticTextName, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 ); + + m_textName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_fgGrid->Add( m_textName, 1, wxALL|wxEXPAND, 5 ); + + m_staticTextOptional = new wxStaticText( this, wxID_ANY, wxT("(optional)"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextOptional->Wrap( -1 ); + m_fgGrid->Add( m_staticTextOptional, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxLEFT, 5 ); + + m_staticTextX = new wxStaticText( this, wxID_ANY, wxT("X:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextX->Wrap( -1 ); + m_fgGrid->Add( m_staticTextX, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 ); + + m_textX = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_fgGrid->Add( m_textX, 1, wxALL|wxEXPAND, 5 ); + + m_staticTextXUnits = new wxStaticText( this, wxID_ANY, wxT("unit"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextXUnits->Wrap( -1 ); + m_fgGrid->Add( m_staticTextXUnits, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL, 5 ); + + + m_fgGrid->Add( 0, 0, 0, wxEXPAND, 5 ); + + m_checkLinked = new wxCheckBox( this, wxID_ANY, wxT("Linked"), wxDefaultPosition, wxDefaultSize, 0 ); + m_checkLinked->SetValue(true); + m_fgGrid->Add( m_checkLinked, 1, wxALL|wxEXPAND, 5 ); + + + m_fgGrid->Add( 0, 0, 0, wxEXPAND, 5 ); + + m_staticTextY = new wxStaticText( this, wxID_ANY, wxT("Y:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextY->Wrap( -1 ); + m_fgGrid->Add( m_staticTextY, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 ); + + m_textY = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textY->Enable( false ); + + m_fgGrid->Add( m_textY, 1, wxALL|wxEXPAND, 5 ); + + m_staticTextYUnits = new wxStaticText( this, wxID_ANY, wxT("unit"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextYUnits->Wrap( -1 ); + m_fgGrid->Add( m_staticTextYUnits, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL, 5 ); + + + bMainSizer->Add( m_fgGrid, 0, wxEXPAND, 5 ); + + m_stdButtons = new wxStdDialogButtonSizer(); + m_stdButtonsOK = new wxButton( this, wxID_OK ); + m_stdButtons->AddButton( m_stdButtonsOK ); + m_stdButtonsCancel = new wxButton( this, wxID_CANCEL ); + m_stdButtons->AddButton( m_stdButtonsCancel ); + m_stdButtons->Realize(); + + bMainSizer->Add( m_stdButtons, 1, wxALL|wxEXPAND, 5 ); + + + this->SetSizer( bMainSizer ); + this->Layout(); + + this->Centre( wxBOTH ); + + // Connect Events + m_checkLinked->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_GRID_SETTINGS_BASE::OnLinkedChecked ), NULL, this ); +} + +DIALOG_GRID_SETTINGS_BASE::~DIALOG_GRID_SETTINGS_BASE() +{ + // Disconnect Events + m_checkLinked->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_GRID_SETTINGS_BASE::OnLinkedChecked ), NULL, this ); + +} diff --git a/common/dialogs/dialog_grid_settings_base.h b/common/dialogs/dialog_grid_settings_base.h new file mode 100644 index 0000000000..d2d11da3fc --- /dev/null +++ b/common/dialogs/dialog_grid_settings_base.h @@ -0,0 +1,61 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3) +// http://www.wxformbuilder.org/ +// +// PLEASE DO *NOT* EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include +#include "dialog_shim.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +/// Class DIALOG_GRID_SETTINGS_BASE +/////////////////////////////////////////////////////////////////////////////// +class DIALOG_GRID_SETTINGS_BASE : public DIALOG_SHIM +{ + private: + + protected: + wxStaticText* m_staticTextName; + wxTextCtrl* m_textName; + wxStaticText* m_staticTextOptional; + wxStaticText* m_staticTextX; + wxTextCtrl* m_textX; + wxStaticText* m_staticTextXUnits; + wxCheckBox* m_checkLinked; + wxStaticText* m_staticTextY; + wxTextCtrl* m_textY; + wxStaticText* m_staticTextYUnits; + wxStdDialogButtonSizer* m_stdButtons; + wxButton* m_stdButtonsOK; + wxButton* m_stdButtonsCancel; + + // Virtual event handlers, override them in your derived class + virtual void OnLinkedChecked( wxCommandEvent& event ) { event.Skip(); } + + + public: + + DIALOG_GRID_SETTINGS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Grid Settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 288,233 ), long style = wxDEFAULT_DIALOG_STYLE ); + + ~DIALOG_GRID_SETTINGS_BASE(); + +}; + diff --git a/common/dialogs/panel_grid_settings.cpp b/common/dialogs/panel_grid_settings.cpp index a9b640d816..241bb47f8f 100644 --- a/common/dialogs/panel_grid_settings.cpp +++ b/common/dialogs/panel_grid_settings.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -40,17 +41,16 @@ PANEL_GRID_SETTINGS::PANEL_GRID_SETTINGS( wxWindow* aParent, UNITS_PROVIDER* aUn wxWindow* aEventSource, APP_SETTINGS_BASE* aCfg, FRAME_T aFrameType ) : PANEL_GRID_SETTINGS_BASE( aParent ), - m_unitsProvider( aUnitsProvider ), - m_cfg( aCfg ), - m_frameType( aFrameType ), + m_unitsProvider( aUnitsProvider ), m_cfg( aCfg ), m_frameType( aFrameType ), + m_eventSource( aEventSource ), m_gridOverrideConnected( aUnitsProvider, aEventSource, m_staticTextConnected, m_GridOverrideConnectedSize, m_staticTextConnectedUnits ), m_gridOverrideWires( aUnitsProvider, aEventSource, m_staticTextWires, m_GridOverrideWiresSize, m_staticTextWiresUnits ), - m_gridOverrideVias( aUnitsProvider, aEventSource, m_staticTextVias, - m_GridOverrideViasSize, m_staticTextViasUnits ), - m_gridOverrideText( aUnitsProvider, aEventSource, m_staticTextText, - m_GridOverrideTextSize, m_staticTextTextUnits ), + m_gridOverrideVias( aUnitsProvider, aEventSource, m_staticTextVias, m_GridOverrideViasSize, + m_staticTextViasUnits ), + m_gridOverrideText( aUnitsProvider, aEventSource, m_staticTextText, m_GridOverrideTextSize, + m_staticTextTextUnits ), m_gridOverrideGraphics( aUnitsProvider, aEventSource, m_staticTextGraphics, m_GridOverrideGraphicsSize, m_staticTextGraphicsUnits ) { @@ -97,7 +97,7 @@ PANEL_GRID_SETTINGS::PANEL_GRID_SETTINGS( wxWindow* aParent, UNITS_PROVIDER* aUn void PANEL_GRID_SETTINGS::ResetPanel() { - m_cfg->m_Window.grid.sizes = m_cfg->DefaultGridSizeList(); + m_cfg->m_Window.grid.grids = m_cfg->DefaultGridSizeList(); RebuildGridSizes(); m_cfg->m_Window.grid.last_size_idx = m_currentGridCtrl->GetSelection(); } @@ -117,14 +117,15 @@ void PANEL_GRID_SETTINGS::RebuildGridSizes() m_unitsProvider->GetUnitPair( primaryUnit, secondaryUnit ); - for( const wxString& gridSize : m_cfg->m_Window.grid.sizes ) + for( const struct GRID& grid : m_cfg->m_Window.grid.grids ) { - double val = EDA_UNIT_UTILS::UI::DoubleValueFromString( scale, EDA_UNITS::MILLIMETRES, - gridSize ); + wxString name = grid.name; - msg.Printf( _( "%s (%s)" ), - EDA_UNIT_UTILS::UI::MessageTextFromValue( scale, primaryUnit, val ), - EDA_UNIT_UTILS::UI::MessageTextFromValue( scale, secondaryUnit, val ) ); + if( !name.IsEmpty() ) + name += wxT( ": " ); + + msg.Printf( _( "%s%s (%s)" ), name, grid.MessageText( scale, primaryUnit, true ), + grid.MessageText( scale, secondaryUnit, true ) ); grids.Add( msg ); } @@ -205,38 +206,26 @@ bool PANEL_GRID_SETTINGS::TransferDataToWindow() void PANEL_GRID_SETTINGS::OnAddGrid( wxCommandEvent& event ) { - wxTextEntryDialog dlg( this, _( "New grid:" ), _( "Add Grid" ) ); + GRID newGrid = GRID{ wxEmptyString, "", "" }; + DIALOG_GRID_SETTINGS dlg( this->GetParent(), m_eventSource, m_unitsProvider, newGrid ); if( dlg.ShowModal() != wxID_OK ) return; int row = m_currentGridCtrl->GetSelection(); GRID_SETTINGS& gridCfg = m_cfg->m_Window.grid; - EDA_IU_SCALE scale = m_unitsProvider->GetIuScale(); - EDA_UNITS units = m_unitsProvider->GetUserUnits(); - double gridSize = EDA_UNIT_UTILS::UI::DoubleValueFromString( scale, units, dlg.GetValue() ); - - if( gridSize == 0.0f ) + for( GRID& g : gridCfg.grids ) { - DisplayError( this, _( "Grid must have a valid size." ) ); - return; - } - - wxString gridSizeStr = - EDA_UNIT_UTILS::UI::StringFromValue( scale, EDA_UNITS::MILLIMETRES, gridSize ); - - for( const wxString& size : gridCfg.sizes ) - { - if( gridSizeStr == size ) + if( newGrid == g ) { - DisplayError( this, - wxString::Format( _( "Grid size '%s' already exists." ), gridSizeStr ) ); + DisplayError( this, wxString::Format( _( "Grid size '%s' already exists." ), + g.UserUnitsMessageText( m_unitsProvider ) ) ); return; } } - gridCfg.sizes.insert( gridCfg.sizes.begin() + row, gridSizeStr ); + gridCfg.grids.insert( gridCfg.grids.begin() + row, newGrid ); RebuildGridSizes(); m_currentGridCtrl->SetSelection( row ); } @@ -247,13 +236,13 @@ void PANEL_GRID_SETTINGS::OnRemoveGrid( wxCommandEvent& event ) GRID_SETTINGS& gridCfg = m_cfg->m_Window.grid; int row = m_currentGridCtrl->GetSelection(); - if( gridCfg.sizes.size() <= 1 ) + if( gridCfg.grids.size() <= 1 ) { DisplayError( this, wxString::Format( _( "At least one grid size is required." ) ) ); return; } - gridCfg.sizes.erase( gridCfg.sizes.begin() + row ); + gridCfg.grids.erase( gridCfg.grids.begin() + row ); RebuildGridSizes(); if( row != 0 ) @@ -266,10 +255,10 @@ void PANEL_GRID_SETTINGS::OnMoveGridUp( wxCommandEvent& event ) GRID_SETTINGS& gridCfg = m_cfg->m_Window.grid; int row = m_currentGridCtrl->GetSelection(); - if( gridCfg.sizes.size() <= 1 || row == 0 ) + if( gridCfg.grids.size() <= 1 || row == 0 ) return; - std::swap( gridCfg.sizes[row], gridCfg.sizes[row - 1] ); + std::swap( gridCfg.grids[row], gridCfg.grids[row - 1] ); RebuildGridSizes(); if( row != 0 ) @@ -282,10 +271,10 @@ void PANEL_GRID_SETTINGS::OnMoveGridDown( wxCommandEvent& event ) GRID_SETTINGS& gridCfg = m_cfg->m_Window.grid; int row = m_currentGridCtrl->GetSelection(); - if( gridCfg.sizes.size() <= 1 || row == ( (int) gridCfg.sizes.size() - 1 ) ) + if( gridCfg.grids.size() <= 1 || row == ( (int) gridCfg.grids.size() - 1 ) ) return; - std::swap( gridCfg.sizes[row], gridCfg.sizes[row + 1] ); + std::swap( gridCfg.grids[row], gridCfg.grids[row + 1] ); RebuildGridSizes(); if( row != 0 ) diff --git a/common/eda_draw_frame.cpp b/common/eda_draw_frame.cpp index f25857379a..f1380801ce 100644 --- a/common/eda_draw_frame.cpp +++ b/common/eda_draw_frame.cpp @@ -631,8 +631,11 @@ void EDA_DRAW_FRAME::DisplayGridMsg() { wxString msg; - msg.Printf( _( "grid %s" ), MessageTextFromValue( GetCanvas()->GetGAL()->GetGridSize().x, - false ) ); + GRID_SETTINGS& gridSettings = m_toolManager->GetSettings()->m_Window.grid; + int currentIdx = m_toolManager->GetSettings()->m_Window.grid.last_size_idx; + + msg.Printf( _( "grid %s" ), + gridSettings.grids[currentIdx].UserUnitsMessageText( this, false ) ); SetStatusText( msg, 4 ); } diff --git a/common/settings/app_settings.cpp b/common/settings/app_settings.cpp index 7c6003e8ae..05b392d32c 100644 --- a/common/settings/app_settings.cpp +++ b/common/settings/app_settings.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -337,8 +338,8 @@ void APP_SETTINGS_BASE::addParamsForWindow( WINDOW_SETTINGS* aWindow, const std: defaultGridIdx = 4; } - m_params.emplace_back( new PARAM_LIST( aJsonPath + ".grid.sizes", - &aWindow->grid.sizes, DefaultGridSizeList() ) ); + m_params.emplace_back( new PARAM_LIST( aJsonPath + ".grid.sizes", &aWindow->grid.grids, + DefaultGridSizeList() ) ); m_params.emplace_back( new PARAM( aJsonPath + ".grid.last_size", &aWindow->grid.last_size_idx, defaultGridIdx ) ); @@ -349,7 +350,7 @@ void APP_SETTINGS_BASE::addParamsForWindow( WINDOW_SETTINGS* aWindow, const std: m_params.emplace_back( new PARAM( aJsonPath + ".grid.fast_grid_2", &aWindow->grid.fast_grid_2, defaultGridIdx + 1 ) ); - // for grid user, use a default value compatible with eeschema and pcbnew (10 mils) + // legacy values, leave blank by default so we don't convert them m_params.emplace_back( new PARAM( aJsonPath + ".grid.user_grid_x", &aWindow->grid.user_grid_x, wxEmptyString ) ); m_params.emplace_back( new PARAM( aJsonPath + ".grid.user_grid_y", @@ -441,39 +442,39 @@ void APP_SETTINGS_BASE::addParamsForWindow( WINDOW_SETTINGS* aWindow, const std: } -const std::vector APP_SETTINGS_BASE::DefaultGridSizeList() const +const std::vector APP_SETTINGS_BASE::DefaultGridSizeList() const { if( m_filename == wxS( "eeschema" ) || m_filename == wxS( "symbol_editor" ) ) { - return { wxS( "100 mil" ), - wxS( "50 mil" ), - wxS( "25 mil" ), - wxS( "10 mil" ) }; + return { GRID{ wxEmptyString, wxS( "100 mil" ), wxS( "100 mil" ) }, + GRID{ wxEmptyString, wxS( "50 mil" ), wxS( "50 mil" ) }, + GRID{ wxEmptyString, wxS( "25 mil" ), wxS( "25 mil" ) }, + GRID{ wxEmptyString, wxS( "10 mil" ), wxS( "10 mil" ) } }; } else { - return { wxS( "1000 mil" ), - wxS( "500 mil" ), - wxS( "250 mil" ), - wxS( "200 mil" ), - wxS( "100 mil" ), - wxS( "50 mil" ), - wxS( "25 mil" ), - wxS( "20 mil" ), - wxS( "10 mil" ), - wxS( "5 mil" ), - wxS( "2 mil" ), - wxS( "1 mil" ), - wxS( "5.0 mm" ), - wxS( "2.5 mm" ), - wxS( "1.0 mm" ), - wxS( "0.5 mm" ), - wxS( "0.25 mm" ), - wxS( "0.2 mm" ), - wxS( "0.1 mm" ), - wxS( "0.05 mm" ), - wxS( "0.025 mm" ), - wxS( "0.01 mm" ) }; + return { GRID{ wxEmptyString, wxS( "1000 mil" ), wxS( "1000 mil" ) }, + GRID{ wxEmptyString, wxS( "500 mil" ), wxS( "500 mil" ) }, + GRID{ wxEmptyString, wxS( "250 mil" ), wxS( "250 mil" ) }, + GRID{ wxEmptyString, wxS( "200 mil" ), wxS( "200 mil" ) }, + GRID{ wxEmptyString, wxS( "100 mil" ), wxS( "100 mil" ) }, + GRID{ wxEmptyString, wxS( "50 mil" ), wxS( "50 mil" ) }, + GRID{ wxEmptyString, wxS( "25 mil" ), wxS( "25 mil" ) }, + GRID{ wxEmptyString, wxS( "20 mil" ), wxS( "20 mil" ) }, + GRID{ wxEmptyString, wxS( "10 mil" ), wxS( "10 mil" ) }, + GRID{ wxEmptyString, wxS( "5 mil" ), wxS( "5 mil" ) }, + GRID{ wxEmptyString, wxS( "2 mil" ), wxS( "2 mil" ) }, + GRID{ wxEmptyString, wxS( "1 mil" ), wxS( "1 mil" ) }, + GRID{ wxEmptyString, wxS( "5.0 mm" ), wxS( "5.0 mm" ) }, + GRID{ wxEmptyString, wxS( "2.5 mm" ), wxS( "2.5 mm" ) }, + GRID{ wxEmptyString, wxS( "1.0 mm" ), wxS( "1.0 mm" ) }, + GRID{ wxEmptyString, wxS( "0.5 mm" ), wxS( "0.5 mm" ) }, + GRID{ wxEmptyString, wxS( "0.25 mm" ), wxS( "0.25 mm" ) }, + GRID{ wxEmptyString, wxS( "0.2 mm" ), wxS( "0.2 mm" ) }, + GRID{ wxEmptyString, wxS( "0.1 mm" ), wxS( "0.1 mm" ) }, + GRID{ wxEmptyString, wxS( "0.05 mm" ), wxS( "0.05 mm" ) }, + GRID{ wxEmptyString, wxS( "0.025 mm" ), wxS( "0.025 mm" ) }, + GRID{ wxEmptyString, wxS( "0.01 mm" ), wxS( "0.01 mm" ) } }; } } diff --git a/common/settings/grid_settings.cpp b/common/settings/grid_settings.cpp new file mode 100644 index 0000000000..b4bf89220f --- /dev/null +++ b/common/settings/grid_settings.cpp @@ -0,0 +1,99 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Mike Williams + * Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include +#include +#include + +#include + +namespace nlohmann +{ +template <> +struct adl_serializer +{ + static void to_json( json& j, const wxString& s ) { j = s.ToUTF8(); } + + static void from_json( const json& j, wxString& s ) + { + s = wxString::FromUTF8( j.get().c_str() ); + } +}; +} // namespace nlohmann + +wxString GRID::MessageText( EDA_IU_SCALE aScale, EDA_UNITS aUnits, bool aDisplayUnits ) const +{ + EDA_DATA_TYPE type = EDA_DATA_TYPE::DISTANCE; + + wxString xStr = EDA_UNIT_UTILS::UI::MessageTextFromValue( + aScale, aUnits, + EDA_UNIT_UTILS::UI::DoubleValueFromString( aScale, EDA_UNITS::MILLIMETRES, x, type ), + aDisplayUnits ); + wxString yStr = EDA_UNIT_UTILS::UI::MessageTextFromValue( + aScale, aUnits, + EDA_UNIT_UTILS::UI::DoubleValueFromString( aScale, EDA_UNITS::MILLIMETRES, y, type ), + aDisplayUnits ); + + if( xStr == yStr ) + return xStr; + + return wxString::Format( wxS( "%s x %s" ), xStr, yStr ); +} + +wxString GRID::UserUnitsMessageText( UNITS_PROVIDER* aProvider, bool aDisplayUnits ) const +{ + return MessageText( aProvider->GetIuScale(), aProvider->GetUserUnits(), aDisplayUnits ); +} + + +bool GRID::operator==( const GRID& aOther ) const +{ + return x == aOther.x && y == aOther.y; +} + + +bool operator!=( const GRID& lhs, const GRID& rhs ) +{ + return !( lhs == rhs ); +} + + +bool operator<( const GRID& lhs, const GRID& rhs ) +{ + return lhs.name < rhs.name; +} + + +void to_json( nlohmann::json& j, const GRID& g ) +{ + j = nlohmann::json{ + { "name", g.name }, + { "x", g.x }, + { "y", g.y }, + }; +} + + +void from_json( const nlohmann::json& j, GRID& g ) +{ + j.at( "name" ).get_to( g.name ); + j.at( "x" ).get_to( g.x ); + j.at( "y" ).get_to( g.y ); +} diff --git a/common/settings/json_settings.cpp b/common/settings/json_settings.cpp index 353e6bc928..ae6c9c2d34 100644 --- a/common/settings/json_settings.cpp +++ b/common/settings/json_settings.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -574,6 +575,7 @@ template std::optional JSON_SETTINGS::Get( const template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; @@ -600,6 +602,7 @@ template void JSON_SETTINGS::Set( const std::string& aPath, KIGF template void JSON_SETTINGS::Set( const std::string& aPath, BOM_FIELD aValue ); template void JSON_SETTINGS::Set( const std::string& aPath, BOM_PRESET aValue ); template void JSON_SETTINGS::Set( const std::string& aPath, BOM_FMT_PRESET aValue ); +template void JSON_SETTINGS::Set( const std::string& aPath, GRID aValue ); template void JSON_SETTINGS::Set( const std::string& aPath, wxPoint aValue ); template void JSON_SETTINGS::Set( const std::string& aPath, wxSize aValue ); template void JSON_SETTINGS::Set( const std::string& aPath, wxRect aValue ); diff --git a/common/settings/parameters.cpp b/common/settings/parameters.cpp index 86c559f43c..4a58c1edcf 100644 --- a/common/settings/parameters.cpp +++ b/common/settings/parameters.cpp @@ -26,6 +26,7 @@ #include #include #include +#include template void PARAM_LAMBDA::Load( JSON_SETTINGS* aSettings, bool aResetIfMissing ) const @@ -137,6 +138,7 @@ template class PARAM_LIST; template class PARAM_LIST; template class PARAM_LIST; template class PARAM_LIST; +template class PARAM_LIST; template diff --git a/common/tool/common_tools.cpp b/common/tool/common_tools.cpp index fd984b739e..f3035e3342 100644 --- a/common/tool/common_tools.cpp +++ b/common/tool/common_tools.cpp @@ -61,12 +61,15 @@ void COMMON_TOOLS::Reset( RESET_REASON aReason ) m_grids.clear(); - for( const wxString& gridDef : settings.sizes ) + for( GRID& gridDef : settings.grids ) { - double gridSize = EDA_UNIT_UTILS::UI::DoubleValueFromString( scale, EDA_UNITS::MILLIMETRES, - gridDef ); + double gridSizeX = EDA_UNIT_UTILS::UI::DoubleValueFromString( scale, EDA_UNITS::MILLIMETRES, + gridDef.x ); + double gridSizeY = EDA_UNIT_UTILS::UI::DoubleValueFromString( scale, EDA_UNITS::MILLIMETRES, + gridDef.y ); - m_grids.emplace_back( KiROUND( gridSize ), KiROUND( gridSize ) ); + m_grids.emplace_back( KiROUND( gridSizeX ), + KiROUND( gridSizeY ) ); } OnGridChanged( false ); diff --git a/common/tool/grid_menu.cpp b/common/tool/grid_menu.cpp index 5579f0b8ea..620ac4c3db 100644 --- a/common/tool/grid_menu.cpp +++ b/common/tool/grid_menu.cpp @@ -84,6 +84,7 @@ void GRID_MENU::update() } } + void GRID_MENU::BuildChoiceList( wxArrayString* aGridsList, APP_SETTINGS_BASE* aCfg, EDA_DRAW_FRAME* aParent ) { @@ -94,14 +95,15 @@ void GRID_MENU::BuildChoiceList( wxArrayString* aGridsList, APP_SETTINGS_BASE* a aParent->GetUnitPair( primaryUnit, secondaryUnit ); - for( const wxString& gridSize : aCfg->m_Window.grid.sizes ) + for( GRID& gridSize : aCfg->m_Window.grid.grids ) { - double val = EDA_UNIT_UTILS::UI::DoubleValueFromString( scale, EDA_UNITS::MILLIMETRES, - gridSize ); + wxString name; - msg.Printf( _( "%s (%s)" ), - EDA_UNIT_UTILS::UI::MessageTextFromValue( scale, primaryUnit, val ), - EDA_UNIT_UTILS::UI::MessageTextFromValue( scale, secondaryUnit, val ) ); + if( !gridSize.name.IsEmpty() ) + name = gridSize.name + ": "; + + msg.Printf( _( "%s%s (%s)" ), name, gridSize.MessageText( scale, primaryUnit, true ), + gridSize.MessageText( scale, secondaryUnit, true ) ); aGridsList->Add( msg ); } diff --git a/eeschema/eeschema_config.cpp b/eeschema/eeschema_config.cpp index 908d2e37ff..16dca7cca9 100644 --- a/eeschema/eeschema_config.cpp +++ b/eeschema/eeschema_config.cpp @@ -244,24 +244,25 @@ void SCH_BASE_FRAME::LoadSettings( APP_SETTINGS_BASE* aCfg ) EDA_DRAW_FRAME::LoadSettings( aCfg ); - if( aCfg->m_Window.grid.sizes.empty() ) - aCfg->m_Window.grid.sizes = aCfg->DefaultGridSizeList(); + if( aCfg->m_Window.grid.grids.empty() ) + aCfg->m_Window.grid.grids = aCfg->DefaultGridSizeList(); // Move legacy user grids to grid list if( !aCfg->m_Window.grid.user_grid_x.empty() ) { - aCfg->m_Window.grid.sizes.emplace_back( aCfg->m_Window.grid.user_grid_x ); + aCfg->m_Window.grid.grids.emplace_back( GRID{ "User Grid", aCfg->m_Window.grid.user_grid_x, + aCfg->m_Window.grid.user_grid_y } ); aCfg->m_Window.grid.user_grid_x = wxEmptyString; aCfg->m_Window.grid.user_grid_y = wxEmptyString; } - if( aCfg->m_Window.grid.last_size_idx > (int) aCfg->m_Window.grid.sizes.size() ) + if( aCfg->m_Window.grid.last_size_idx > (int) aCfg->m_Window.grid.grids.size() ) aCfg->m_Window.grid.last_size_idx = 1; - if( aCfg->m_Window.grid.fast_grid_1 > (int) aCfg->m_Window.grid.sizes.size() ) + if( aCfg->m_Window.grid.fast_grid_1 > (int) aCfg->m_Window.grid.grids.size() ) aCfg->m_Window.grid.fast_grid_1 = 1; - if( aCfg->m_Window.grid.fast_grid_2 > (int) aCfg->m_Window.grid.sizes.size() ) + if( aCfg->m_Window.grid.fast_grid_2 > (int) aCfg->m_Window.grid.grids.size() ) aCfg->m_Window.grid.fast_grid_2 = 2; if( aCfg->m_Window.zoom_factors.empty() ) diff --git a/eeschema/tools/sch_editor_control.cpp b/eeschema/tools/sch_editor_control.cpp index a115361a7d..fba972c9fe 100644 --- a/eeschema/tools/sch_editor_control.cpp +++ b/eeschema/tools/sch_editor_control.cpp @@ -2387,13 +2387,13 @@ int SCH_EDITOR_CONTROL::GridFeedback( const TOOL_EVENT& aEvent ) if( !Pgm().GetCommonSettings()->m_Input.hotkey_feedback ) return 0; - const std::vector& grids = m_toolMgr->GetTool()->Grids(); + GRID_SETTINGS& gridSettings = m_toolMgr->GetSettings()->m_Window.grid; int currentIdx = m_toolMgr->GetSettings()->m_Window.grid.last_size_idx; wxArrayString gridsLabels; - for( const VECTOR2I& grid : grids ) - gridsLabels.Add( m_frame->StringFromValue( grid.x, true ) ); + for( const GRID& grid : gridSettings.grids ) + gridsLabels.Add( grid.UserUnitsMessageText( m_frame ) ); if( !m_frame->GetHotkeyPopup() ) m_frame->CreateHotkeyPopup(); diff --git a/gerbview/gerbview_frame.cpp b/gerbview/gerbview_frame.cpp index ac2225cb40..6953057420 100644 --- a/gerbview/gerbview_frame.cpp +++ b/gerbview/gerbview_frame.cpp @@ -310,30 +310,30 @@ void GERBVIEW_FRAME::LoadSettings( APP_SETTINGS_BASE* aCfg ) { EDA_DRAW_FRAME::LoadSettings( aCfg ); - if( aCfg->m_Window.grid.sizes.empty() ) + if( aCfg->m_Window.grid.grids.empty() ) { - aCfg->m_Window.grid.sizes = { wxT( "100 mil" ), - wxT( "50 mil" ), - wxT( "25 mil" ), - wxT( "20 mil" ), - wxT( "10 mil" ), - wxT( "5 mil" ), - wxT( "2.5 mil" ), - wxT( "2 mil" ), - wxT( "1 mil" ), - wxT( "0.5 mil" ), - wxT( "0.2 mil" ), - wxT( "0.1 mil" ), - wxT( "5.0 mm" ), - wxT( "2.5 mm" ), - wxT( "1.0 mm" ), - wxT( "0.5 mm" ), - wxT( "0.25 mm" ), - wxT( "0.2 mm" ), - wxT( "0.1 mm" ), - wxT( "0.05 mm" ), - wxT( "0.025 mm" ), - wxT( "0.01 mm" ) }; + aCfg->m_Window.grid.grids = { GRID{ wxEmptyString, wxS( "100 mil" ), wxS( "100 mil" ) }, + GRID{ wxEmptyString, wxS( "50 mil" ), wxS( "50 mil" ) }, + GRID{ wxEmptyString, wxS( "25 mil" ), wxS( "25 mil" ) }, + GRID{ wxEmptyString, wxS( "20 mil" ), wxS( "20 mil" ) }, + GRID{ wxEmptyString, wxS( "10 mil" ), wxS( "10 mil" ) }, + GRID{ wxEmptyString, wxS( "5 mil" ), wxS( "5 mil" ) }, + GRID{ wxEmptyString, wxS( "2.5 mil" ), wxS( "2.5 mil" ) }, + GRID{ wxEmptyString, wxS( "2 mil" ), wxS( "2 mil" ) }, + GRID{ wxEmptyString, wxS( "1 mil" ), wxS( "1 mil" ) }, + GRID{ wxEmptyString, wxS( "0.5 mil" ), wxS( "0.5 mil" ) }, + GRID{ wxEmptyString, wxS( "0.2 mil" ), wxS( "0.2 mil" ) }, + GRID{ wxEmptyString, wxS( "0.1 mil" ), wxS( "0.1 mil" ) }, + GRID{ wxEmptyString, wxS( "5.0 mm" ), wxS( "5.0 mm" ) }, + GRID{ wxEmptyString, wxS( "1.5 mm" ), wxS( "2.5 mm" ) }, + GRID{ wxEmptyString, wxS( "1.0 mm" ), wxS( "1.0 mm" ) }, + GRID{ wxEmptyString, wxS( "0.5 mm" ), wxS( "0.5 mm" ) }, + GRID{ wxEmptyString, wxS( "0.25 mm" ), wxS( "0.25 mm" ) }, + GRID{ wxEmptyString, wxS( "0.2 mm" ), wxS( "0.2 mm" ) }, + GRID{ wxEmptyString, wxS( "0.1 mm" ), wxS( "0.1 mm" ) }, + GRID{ wxEmptyString, wxS( "0.05 mm" ), wxS( "0.0 mm" ) }, + GRID{ wxEmptyString, wxS( "0.025 mm" ), wxS( "0.0 mm" ) }, + GRID{ wxEmptyString, wxS( "0.01 mm" ), wxS( "0.0 mm" ) } }; } if( aCfg->m_Window.zoom_factors.empty() ) diff --git a/include/dialogs/dialog_grid_settings.h b/include/dialogs/dialog_grid_settings.h new file mode 100644 index 0000000000..c4fb64f8d2 --- /dev/null +++ b/include/dialogs/dialog_grid_settings.h @@ -0,0 +1,54 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Mike Williams + * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef DIALOG_GRID_SETTINGS_H +#define DIALOG_GRID_SETTINGS_H + +#include +#include + +struct GRID; + +class DIALOG_GRID_SETTINGS : public DIALOG_GRID_SETTINGS_BASE +{ + EDA_DRAW_FRAME* m_parent; + +public: + DIALOG_GRID_SETTINGS( wxWindow* aParent, wxWindow* aEventSource, UNITS_PROVIDER* aProvider, + GRID& aGrid ); + ~DIALOG_GRID_SETTINGS() override = default; + + bool TransferDataFromWindow() override; + +protected: + void OnLinkedChecked( wxCommandEvent& event ) override; + +private: + UNITS_PROVIDER* m_unitsProvider; + GRID& m_grid; + UNIT_BINDER m_gridSizeX; + UNIT_BINDER m_gridSizeY; +}; + +#endif // DIALOG_GRID_SETTINGS_H diff --git a/include/dialogs/panel_grid_settings.h b/include/dialogs/panel_grid_settings.h index b6f8021f9a..761ef8f2b7 100644 --- a/include/dialogs/panel_grid_settings.h +++ b/include/dialogs/panel_grid_settings.h @@ -55,6 +55,7 @@ private: UNITS_PROVIDER* m_unitsProvider; APP_SETTINGS_BASE* m_cfg; FRAME_T m_frameType; + wxWindow* m_eventSource; UNIT_BINDER m_gridOverrideConnected; UNIT_BINDER m_gridOverrideWires; diff --git a/include/pcb_base_frame.h b/include/pcb_base_frame.h index d350802996..4c6eb8f07e 100644 --- a/include/pcb_base_frame.h +++ b/include/pcb_base_frame.h @@ -379,11 +379,6 @@ public: void CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged ) override; - /** - * Display the current grid pane on the status bar. - */ - void DisplayGridMsg() override; - PCB_DRAW_PANEL_GAL* GetCanvas() const override; virtual void ActivateGalCanvas() override; diff --git a/include/settings/app_settings.h b/include/settings/app_settings.h index b96700eb69..48bb12322f 100644 --- a/include/settings/app_settings.h +++ b/include/settings/app_settings.h @@ -23,6 +23,7 @@ #include #include +#include /** * Cross-probing behavior @@ -44,37 +45,6 @@ struct CURSOR_SETTINGS bool fullscreen_cursor; }; -/** - * Common grid settings, available to every frame - */ -struct GRID_SETTINGS -{ - bool axes_enabled; - std::vector sizes; - wxString user_grid_x; - wxString user_grid_y; - int last_size_idx; - int fast_grid_1; - int fast_grid_2; - double line_width; - double min_spacing; - bool show; - int style; - int snap; - bool force_component_snap; - bool overrides_enabled; - bool override_connected; - wxString override_connected_size; - bool override_wires; - wxString override_wires_size; - bool override_vias; - wxString override_vias_size; - bool override_text; - wxString override_text_size; - bool override_graphics; - wxString override_graphics_size; -}; - /** * Settings for arc editing. Used by pcbnew and footprint editor */ @@ -179,7 +149,7 @@ public: virtual bool MigrateFromLegacy( wxConfigBase* aCfg ) override; - const std::vector DefaultGridSizeList() const; + const std::vector DefaultGridSizeList() const; public: CROSS_PROBING_SETTINGS m_CrossProbing; diff --git a/include/settings/grid_settings.h b/include/settings/grid_settings.h new file mode 100644 index 0000000000..50d1db33a0 --- /dev/null +++ b/include/settings/grid_settings.h @@ -0,0 +1,89 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Mike Williams + * Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef _GRID_SETTINGS_H +#define _GRID_SETTINGS_H + +#include +#include +#include + +class UNITS_PROVIDER; + +/** + * Common grid settings, available to every frame + */ +struct GRID +{ + bool operator==( const GRID& aOther ) const; + + /** + * Returns a string representation of the grid in specified units. + * Will reduce to a single dimension if the grid is square. + */ + wxString MessageText( EDA_IU_SCALE aScale, EDA_UNITS aUnits, bool aDisplayUnits = true ) const; + + /** + * Returns a string representation of the grid in the user's units. + * Will reduce to a single dimension if the grid is square. + */ + wxString UserUnitsMessageText( UNITS_PROVIDER* aProvider, bool aDisplayUnits = true ) const; + + wxString name; + wxString x; + wxString y; +}; + +bool operator!=( const GRID& lhs, const GRID& rhs ); +bool operator<( const GRID& lhs, const GRID& rhs ); + +void to_json( nlohmann::json& j, const GRID& g ); +void from_json( const nlohmann::json& j, GRID& g ); + + +struct GRID_SETTINGS +{ + bool axes_enabled; + std::vector grids; + wxString user_grid_x; + wxString user_grid_y; + int last_size_idx; + int fast_grid_1; + int fast_grid_2; + double line_width; + double min_spacing; + bool show; + int style; + int snap; + bool force_component_snap; + bool overrides_enabled; + bool override_connected; + wxString override_connected_size; + bool override_wires; + wxString override_wires_size; + bool override_vias; + wxString override_vias_size; + bool override_text; + wxString override_text_size; + bool override_graphics; + wxString override_graphics_size; +}; + +#endif diff --git a/pagelayout_editor/pl_editor_frame.cpp b/pagelayout_editor/pl_editor_frame.cpp index 36cf50a226..7fda7802b2 100644 --- a/pagelayout_editor/pl_editor_frame.cpp +++ b/pagelayout_editor/pl_editor_frame.cpp @@ -495,16 +495,16 @@ void PL_EDITOR_FRAME::LoadSettings( APP_SETTINGS_BASE* aCfg ) { EDA_DRAW_FRAME::LoadSettings( aCfg ); - if( aCfg->m_Window.grid.sizes.empty() ) + if( aCfg->m_Window.grid.grids.empty() ) { - aCfg->m_Window.grid.sizes = { "5.00 mm", - "2.50 mm", - "2.00 mm", - "1.00 mm", - "0.50 mm", - "0.25 mm", - "0.20 mm", - "0.10 mm" }; + aCfg->m_Window.grid.grids = { GRID{ wxEmptyString, wxS( "5.00 mm" ), wxS( "5.00 mm" ) }, + GRID{ wxEmptyString, wxS( "2.50 mm" ), wxS( "2.50 mm" ) }, + GRID{ wxEmptyString, wxS( "2.00 mm" ), wxS( "2.00 mm" ) }, + GRID{ wxEmptyString, wxS( "1.00 mm" ), wxS( "1.00 mm" ) }, + GRID{ wxEmptyString, wxS( "0.50 mm" ), wxS( "0.50 mm" ) }, + GRID{ wxEmptyString, wxS( "0.25 mm" ), wxS( "0.25 mm" ) }, + GRID{ wxEmptyString, wxS( "0.20 mm" ), wxS( "0.20 mm" ) }, + GRID{ wxEmptyString, wxS( "0.10 mm" ), wxS( "0.10 mm" ) } }; } // Currently values read from config file are not used because the user cannot diff --git a/pcbnew/dialogs/dialog_board_reannotate.cpp b/pcbnew/dialogs/dialog_board_reannotate.cpp index be6a5c7cb7..a9b145a261 100644 --- a/pcbnew/dialogs/dialog_board_reannotate.cpp +++ b/pcbnew/dialogs/dialog_board_reannotate.cpp @@ -404,8 +404,9 @@ void DIALOG_BOARD_REANNOTATE::GetParameters() m_gridIndex = m_GridChoice->GetSelection(); m_sortGridx = EDA_UNIT_UTILS::UI::DoubleValueFromString( - pcbIUScale, EDA_UNITS::MILS, m_settings->m_Window.grid.sizes[m_gridIndex] ); - m_sortGridy = m_sortGridx; + pcbIUScale, EDA_UNITS::MILS, m_settings->m_Window.grid.grids[m_gridIndex].x ); + m_sortGridy = EDA_UNIT_UTILS::UI::DoubleValueFromString( + pcbIUScale, EDA_UNITS::MILS, m_settings->m_Window.grid.grids[m_gridIndex].y ); m_annotationScope = ANNOTATE_ALL; diff --git a/pcbnew/footprint_preview_panel.cpp b/pcbnew/footprint_preview_panel.cpp index 7cb94f8ad8..fa7b531cee 100644 --- a/pcbnew/footprint_preview_panel.cpp +++ b/pcbnew/footprint_preview_panel.cpp @@ -249,8 +249,8 @@ FOOTPRINT_PREVIEW_PANEL* FOOTPRINT_PREVIEW_PANEL::New( KIWAY* aKiway, wxWindow* { PCBNEW_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings(); - if( cfg->m_Window.grid.sizes.empty() ) - cfg->m_Window.grid.sizes = cfg->DefaultGridSizeList(); + if( cfg->m_Window.grid.grids.empty() ) + cfg->m_Window.grid.grids = cfg->DefaultGridSizeList(); // Currently values read from config file are not used because the user cannot // change this config @@ -277,10 +277,12 @@ FOOTPRINT_PREVIEW_PANEL* FOOTPRINT_PREVIEW_PANEL::New( KIWAY* aKiway, wxWindow* panel->GetGAL()->SetGridVisibility( gridCfg.show ); //Bounds checking cannot include number of elements as an index! - int gridIdx = alg::clamp( 0, gridCfg.last_size_idx, (int) gridCfg.sizes.size() - 1 ); - double gridSize = EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, EDA_UNITS::MILS, - gridCfg.sizes[ gridIdx ] ); - panel->GetGAL()->SetGridSize( VECTOR2D( gridSize, gridSize ) ); + int gridIdx = alg::clamp( 0, gridCfg.last_size_idx, (int) gridCfg.grids.size() - 1 ); + double gridSizeX = EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, EDA_UNITS::MILS, + gridCfg.grids[gridIdx].x ); + double gridSizeY = EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, EDA_UNITS::MILS, + gridCfg.grids[gridIdx].y ); + panel->GetGAL()->SetGridSize( VECTOR2D( gridSizeX, gridSizeY ) ); auto painter = static_cast( panel->GetView()->GetPainter() ); auto settings = static_cast( painter->GetSettings() ); diff --git a/pcbnew/pcb_base_frame.cpp b/pcbnew/pcb_base_frame.cpp index 2d1f10aae0..7124eb26bf 100644 --- a/pcbnew/pcb_base_frame.cpp +++ b/pcbnew/pcb_base_frame.cpp @@ -810,19 +810,6 @@ GENERAL_COLLECTORS_GUIDE PCB_BASE_FRAME::GetCollectorsGuide() } -void PCB_BASE_FRAME::DisplayGridMsg() -{ - VECTOR2D gridSize = GetCanvas()->GetGAL()->GetGridSize(); - wxString line; - - line.Printf( wxT( "grid X %s Y %s" ), - MessageTextFromValue( gridSize.x, false ), - MessageTextFromValue( gridSize.y, false ) ); - - SetStatusText( line, 4 ); -} - - void PCB_BASE_FRAME::UpdateStatusBar() { EDA_DRAW_FRAME::UpdateStatusBar(); @@ -895,13 +882,14 @@ void PCB_BASE_FRAME::LoadSettings( APP_SETTINGS_BASE* aCfg ) { EDA_DRAW_FRAME::LoadSettings( aCfg ); - if( aCfg->m_Window.grid.sizes.empty() ) - aCfg->m_Window.grid.sizes = aCfg->DefaultGridSizeList(); + if( aCfg->m_Window.grid.grids.empty() ) + aCfg->m_Window.grid.grids = aCfg->DefaultGridSizeList(); // Move legacy user grids to grid list if( !aCfg->m_Window.grid.user_grid_x.empty() ) { - aCfg->m_Window.grid.sizes.emplace_back( aCfg->m_Window.grid.user_grid_x ); + aCfg->m_Window.grid.grids.emplace_back( GRID{ "User Grid", aCfg->m_Window.grid.user_grid_x, + aCfg->m_Window.grid.user_grid_y } ); aCfg->m_Window.grid.user_grid_x = wxEmptyString; aCfg->m_Window.grid.user_grid_y = wxEmptyString; }