You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

176 lines
7.1 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, you may find one here:
  18. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  19. * or you may search the http://www.gnu.org website for the version 2 license,
  20. * or you may write to the Free Software Foundation, Inc.,
  21. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  22. */
  23. #include "dialogs/dialog_multi_unit_entry.h"
  24. #include <eda_draw_frame.h>
  25. #include <widgets/unit_binder.h>
  26. #include <core/type_helpers.h>
  27. #include <wx/button.h>
  28. #include <wx/checkbox.h>
  29. #include <wx/gbsizer.h>
  30. #include <wx/stattext.h>
  31. WX_MULTI_ENTRY_DIALOG::WX_MULTI_ENTRY_DIALOG( EDA_DRAW_FRAME* aParent, const wxString& aCaption,
  32. std::vector<ENTRY> aEntries ) :
  33. DIALOG_SHIM( aParent, wxID_ANY, aCaption ), m_entries( std::move( aEntries ) )
  34. {
  35. SetSizeHints( wxDefaultSize, wxDefaultSize );
  36. wxBoxSizer* bSizerMain = new wxBoxSizer( wxVERTICAL );
  37. wxGridBagSizer* bSizerContent;
  38. bSizerContent = new wxGridBagSizer( 0, 0 );
  39. bSizerContent->SetFlexibleDirection( wxHORIZONTAL );
  40. bSizerContent->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_ALL );
  41. bSizerMain->Add( bSizerContent, 1, wxEXPAND | wxRIGHT | wxLEFT, 5 );
  42. int gbRow = 0;
  43. for( const ENTRY& entry : m_entries )
  44. {
  45. std::visit(
  46. [&]( const auto& aValue )
  47. {
  48. using EntryType = std::decay_t<decltype( aValue )>;
  49. if constexpr( std::is_same_v<EntryType, UNIT_BOUND> )
  50. {
  51. // Label / Entry / Unit
  52. // and a binder
  53. wxStaticText* label =
  54. new wxStaticText( this, wxID_ANY, entry.m_label, wxDefaultPosition,
  55. wxDefaultSize, 0 );
  56. label->Wrap( -1 );
  57. bSizerContent->Add( label, wxGBPosition( gbRow, 0 ), wxGBSpan( 1, 1 ),
  58. wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM | wxLEFT,
  59. 5 );
  60. wxTextCtrl* textCtrl =
  61. new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition,
  62. wxDefaultSize, 0 );
  63. bSizerContent->Add( textCtrl, wxGBPosition( gbRow, 1 ), wxGBSpan( 1, 1 ),
  64. wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 5 );
  65. wxStaticText* unit_label = new wxStaticText(
  66. this, wxID_ANY, _( "unit" ), wxDefaultPosition, wxDefaultSize, 0 );
  67. unit_label->Wrap( -1 );
  68. bSizerContent->Add( unit_label, wxGBPosition( gbRow, 2 ), wxGBSpan( 1, 1 ),
  69. wxTOP | wxBOTTOM | wxRIGHT | wxALIGN_CENTER_VERTICAL,
  70. 5 );
  71. if( !entry.m_tooltip.IsEmpty() )
  72. textCtrl->SetToolTip( entry.m_tooltip );
  73. m_controls.push_back( textCtrl );
  74. m_unit_binders.push_back( std::make_unique<UNIT_BINDER>(
  75. aParent, label, textCtrl, unit_label ) );
  76. m_unit_binders.back()->SetValue( aValue.m_default );
  77. }
  78. else if constexpr( std::is_same_v<EntryType, CHECKBOX> )
  79. {
  80. // Checkbox across all 3 cols
  81. wxCheckBox* checkBox =
  82. new wxCheckBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition,
  83. wxDefaultSize, 0 );
  84. bSizerContent->Add( checkBox, wxGBPosition( gbRow, 0 ), wxGBSpan( 1, 3 ),
  85. wxALIGN_CENTER_VERTICAL | wxALL, 5 );
  86. checkBox->SetLabel( entry.m_label );
  87. checkBox->SetValue( aValue.m_default );
  88. if( !entry.m_tooltip.IsEmpty() )
  89. checkBox->SetToolTip( entry.m_tooltip );
  90. m_controls.push_back( checkBox );
  91. m_unit_binders.push_back( nullptr );
  92. }
  93. else
  94. {
  95. static_assert( always_false<EntryType>::value, "non-exhaustive visitor" );
  96. }
  97. },
  98. entry.m_value );
  99. gbRow++;
  100. }
  101. // Grow the value column (now it knows it has a col 1)
  102. bSizerContent->AddGrowableCol( 1 );
  103. wxStdDialogButtonSizer* sdbSizer1 = new wxStdDialogButtonSizer();
  104. wxButton* sdbSizer1OK = new wxButton( this, wxID_OK );
  105. sdbSizer1->AddButton( sdbSizer1OK );
  106. wxButton* sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
  107. sdbSizer1->AddButton( sdbSizer1Cancel );
  108. sdbSizer1->Realize();
  109. bSizerMain->Add( sdbSizer1, 0, wxALL | wxEXPAND, 5 );
  110. SetSizer( bSizerMain );
  111. SetupStandardButtons();
  112. Layout();
  113. // Now all widgets have the size fixed, call FinishDialogSettings
  114. finishDialogSettings();
  115. }
  116. std::vector<WX_MULTI_ENTRY_DIALOG::RESULT> WX_MULTI_ENTRY_DIALOG::GetValues() const
  117. {
  118. std::vector<RESULT> results;
  119. for( size_t ii = 0; ii < m_entries.size(); ++ii )
  120. {
  121. wxWindow* const control = m_controls[ii];
  122. // Visit the value definitons to look up the right control type
  123. std::visit(
  124. [&]( const auto& aValueDef )
  125. {
  126. using ArgType = std::decay_t<decltype( aValueDef )>;
  127. if constexpr( std::is_same_v<ArgType, UNIT_BOUND> )
  128. {
  129. UNIT_BINDER* binder = m_unit_binders[ii].get();
  130. wxASSERT( binder );
  131. results.push_back( binder ? binder->GetValue() : 0 );
  132. }
  133. else if constexpr( std::is_same_v<ArgType, CHECKBOX> )
  134. {
  135. wxCheckBox* checkBox = static_cast<wxCheckBox*>( control );
  136. results.push_back( checkBox->GetValue() );
  137. }
  138. else
  139. {
  140. static_assert( always_false<ArgType>::value, "non-exhaustive visitor" );
  141. }
  142. },
  143. m_entries[ii].m_value );
  144. }
  145. return results;
  146. }