/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright The 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 "dialogs/dialog_multi_unit_entry.h" #include #include #include #include #include #include #include WX_MULTI_ENTRY_DIALOG::WX_MULTI_ENTRY_DIALOG( EDA_DRAW_FRAME* aParent, const wxString& aCaption, std::vector aEntries ) : DIALOG_SHIM( aParent, wxID_ANY, aCaption ), m_entries( std::move( aEntries ) ) { SetSizeHints( wxDefaultSize, wxDefaultSize ); wxBoxSizer* bSizerMain = new wxBoxSizer( wxVERTICAL ); wxGridBagSizer* bSizerContent; bSizerContent = new wxGridBagSizer( 0, 0 ); bSizerContent->SetFlexibleDirection( wxHORIZONTAL ); bSizerContent->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_ALL ); bSizerMain->Add( bSizerContent, 1, wxEXPAND | wxRIGHT | wxLEFT, 5 ); int gbRow = 0; for( const ENTRY& entry : m_entries ) { std::visit( [&]( const auto& aValue ) { using EntryType = std::decay_t; if constexpr( std::is_same_v ) { // Label / Entry / Unit // and a binder wxStaticText* label = new wxStaticText( this, wxID_ANY, entry.m_label, wxDefaultPosition, wxDefaultSize, 0 ); label->Wrap( -1 ); bSizerContent->Add( label, wxGBPosition( gbRow, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM | wxLEFT, 5 ); wxTextCtrl* textCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); bSizerContent->Add( textCtrl, wxGBPosition( gbRow, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 5 ); wxStaticText* unit_label = new wxStaticText( this, wxID_ANY, _( "unit" ), wxDefaultPosition, wxDefaultSize, 0 ); unit_label->Wrap( -1 ); bSizerContent->Add( unit_label, wxGBPosition( gbRow, 2 ), wxGBSpan( 1, 1 ), wxTOP | wxBOTTOM | wxRIGHT | wxALIGN_CENTER_VERTICAL, 5 ); if( !entry.m_tooltip.IsEmpty() ) textCtrl->SetToolTip( entry.m_tooltip ); m_controls.push_back( textCtrl ); m_unit_binders.push_back( std::make_unique( aParent, label, textCtrl, unit_label ) ); m_unit_binders.back()->SetValue( aValue.m_default ); } else if constexpr( std::is_same_v ) { // Checkbox across all 3 cols wxCheckBox* checkBox = new wxCheckBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); bSizerContent->Add( checkBox, wxGBPosition( gbRow, 0 ), wxGBSpan( 1, 3 ), wxALIGN_CENTER_VERTICAL | wxALL, 5 ); checkBox->SetLabel( entry.m_label ); checkBox->SetValue( aValue.m_default ); if( !entry.m_tooltip.IsEmpty() ) checkBox->SetToolTip( entry.m_tooltip ); m_controls.push_back( checkBox ); m_unit_binders.push_back( nullptr ); } else { static_assert( always_false::value, "non-exhaustive visitor" ); } }, entry.m_value ); gbRow++; } // Grow the value column (now it knows it has a col 1) bSizerContent->AddGrowableCol( 1 ); wxStdDialogButtonSizer* sdbSizer1 = new wxStdDialogButtonSizer(); wxButton* sdbSizer1OK = new wxButton( this, wxID_OK ); sdbSizer1->AddButton( sdbSizer1OK ); wxButton* sdbSizer1Cancel = new wxButton( this, wxID_CANCEL ); sdbSizer1->AddButton( sdbSizer1Cancel ); sdbSizer1->Realize(); bSizerMain->Add( sdbSizer1, 0, wxALL | wxEXPAND, 5 ); SetSizer( bSizerMain ); SetupStandardButtons(); Layout(); // Now all widgets have the size fixed, call FinishDialogSettings finishDialogSettings(); } std::vector WX_MULTI_ENTRY_DIALOG::GetValues() const { std::vector results; for( size_t ii = 0; ii < m_entries.size(); ++ii ) { wxWindow* const control = m_controls[ii]; // Visit the value definitons to look up the right control type std::visit( [&]( const auto& aValueDef ) { using ArgType = std::decay_t; if constexpr( std::is_same_v ) { UNIT_BINDER* binder = m_unit_binders[ii].get(); wxASSERT( binder ); results.push_back( binder ? binder->GetValue() : 0 ); } else if constexpr( std::is_same_v ) { wxCheckBox* checkBox = static_cast( control ); results.push_back( checkBox->GetValue() ); } else { static_assert( always_false::value, "non-exhaustive visitor" ); } }, m_entries[ii].m_value ); } return results; }