|
|
/*
* 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 <eda_draw_frame.h>
#include <widgets/unit_binder.h>
#include <core/type_helpers.h>
#include <wx/button.h>
#include <wx/checkbox.h>
#include <wx/gbsizer.h>
#include <wx/stattext.h>
WX_MULTI_ENTRY_DIALOG::WX_MULTI_ENTRY_DIALOG( EDA_DRAW_FRAME* aParent, const wxString& aCaption, std::vector<ENTRY> 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<decltype( aValue )>; if constexpr( std::is_same_v<EntryType, UNIT_BOUND> ) { // 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<UNIT_BINDER>( aParent, label, textCtrl, unit_label ) );
m_unit_binders.back()->SetValue( aValue.m_default ); } else if constexpr( std::is_same_v<EntryType, CHECKBOX> ) { // 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<EntryType>::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::RESULT> WX_MULTI_ENTRY_DIALOG::GetValues() const{ std::vector<RESULT> 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<decltype( aValueDef )>; if constexpr( std::is_same_v<ArgType, UNIT_BOUND> ) { UNIT_BINDER* binder = m_unit_binders[ii].get(); wxASSERT( binder ); results.push_back( binder ? binder->GetValue() : 0 ); } else if constexpr( std::is_same_v<ArgType, CHECKBOX> ) { wxCheckBox* checkBox = static_cast<wxCheckBox*>( control ); results.push_back( checkBox->GetValue() ); } else { static_assert( always_false<ArgType>::value, "non-exhaustive visitor" ); } }, m_entries[ii].m_value ); }
return results;}
|