KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_multi_unit_entry.cpp
Go to the documentation of this file.
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, see <https://www.gnu.org/licenses/>.
18 */
19
21
22#include <eda_draw_frame.h>
23#include <widgets/unit_binder.h>
24#include <core/type_helpers.h>
25#include <string_utils.h>
26#include <wx/button.h>
27#include <wx/textctrl.h>
28#include <wx/checkbox.h>
29#include <wx/gbsizer.h>
30#include <wx/stattext.h>
31
32
34 std::vector<ENTRY> aEntries ) :
35 DIALOG_SHIM( aParent, wxID_ANY, aCaption ),
36 m_entries( std::move( aEntries ) )
37{
38 SetSizeHints( wxDefaultSize, wxDefaultSize );
39
40 wxBoxSizer* bSizerMain = new wxBoxSizer( wxVERTICAL );
41
42 wxGridBagSizer* bSizerContent;
43
44 bSizerContent = new wxGridBagSizer( 0, 0 );
45 bSizerContent->SetFlexibleDirection( wxHORIZONTAL );
46 bSizerContent->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_ALL );
47
48 bSizerMain->Add( bSizerContent, 1, wxEXPAND | wxRIGHT | wxLEFT, 5 );
49
50 int gbRow = 0;
51
52 for( const ENTRY& entry : m_entries )
53 {
54 std::visit(
55 [&]( const auto& aValue )
56 {
57 using EntryType = std::decay_t<decltype( aValue )>;
58
59 if constexpr( std::is_same_v<EntryType, UNIT_BOUND> )
60 {
61 // Label / Entry / Unit
62 // and a binder
63 wxStaticText* label = new wxStaticText( this, wxID_ANY, entry.m_label );
64 label->Wrap( -1 );
65 bSizerContent->Add( label, wxGBPosition( gbRow, 0 ), wxGBSpan( 1, 1 ),
66 wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM | wxLEFT, 5 );
67
68 wxTextCtrl* textCtrl = new wxTextCtrl( this, wxID_ANY );
69 bSizerContent->Add( textCtrl, wxGBPosition( gbRow, 1 ), wxGBSpan( 1, 1 ),
70 wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 5 );
71
72 wxStaticText* units = new wxStaticText( this, wxID_ANY, _( "unit" ) );
73 units->Wrap( -1 );
74 bSizerContent->Add( units, wxGBPosition( gbRow, 2 ), wxGBSpan( 1, 1 ),
75 wxTOP | wxBOTTOM | wxRIGHT | wxALIGN_CENTER_VERTICAL, 5 );
76
77 if( !entry.m_tooltip.IsEmpty() )
78 textCtrl->SetToolTip( entry.m_tooltip );
79
80 m_controls.push_back( textCtrl );
81 m_unit_binders.push_back( std::make_unique<UNIT_BINDER>( aParent, label, textCtrl, units ) );
82
83 m_unit_binders.back()->SetValue( aValue.m_default );
84 }
85 else if constexpr( std::is_same_v<EntryType, CHECKBOX> )
86 {
87 // Checkbox across all 3 cols
88 wxCheckBox* checkBox = new wxCheckBox( this, wxID_ANY, entry.m_label );
89 checkBox->SetValue( aValue.m_default );
90 bSizerContent->Add( checkBox, wxGBPosition( gbRow, 0 ), wxGBSpan( 1, 3 ),
91 wxALIGN_CENTER_VERTICAL | wxALL, 5 );
92
93 if( !entry.m_tooltip.IsEmpty() )
94 checkBox->SetToolTip( entry.m_tooltip );
95
96 m_controls.push_back( checkBox );
97 m_unit_binders.push_back( nullptr );
98 }
99 else
100 {
101 static_assert( always_false<EntryType>::value, "non-exhaustive visitor" );
102 }
103 },
104 entry.m_value );
105
106 gbRow++;
107 }
108
109 // Grow the value column (now it knows it has a col 1)
110 bSizerContent->AddGrowableCol( 1 );
111
112 wxStdDialogButtonSizer* sdbSizer1 = new wxStdDialogButtonSizer();
113 wxButton* sdbSizer1OK = new wxButton( this, wxID_OK );
114 sdbSizer1->AddButton( sdbSizer1OK );
115 wxButton* sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
116 sdbSizer1->AddButton( sdbSizer1Cancel );
117 sdbSizer1->Realize();
118
119 bSizerMain->Add( sdbSizer1, 0, wxALL | wxEXPAND, 5 );
120
121 // DIALOG_SHIM needs a title--specific hash_key so we don't save/restore state between
122 // usage cases.
123 m_hash_key = TO_UTF8( GetTitle() );
124
125 SetSizer( bSizerMain );
127 Layout();
128
129 // Now all widgets have the size fixed, call FinishDialogSettings
131}
132
133
134std::vector<WX_MULTI_ENTRY_DIALOG::RESULT> WX_MULTI_ENTRY_DIALOG::GetValues() const
135{
136 std::vector<RESULT> results;
137
138 for( size_t ii = 0; ii < m_entries.size(); ++ii )
139 {
140 wxWindow* const control = m_controls[ii];
141
142 // Visit the value definitons to look up the right control type
143 std::visit(
144 [&]( const auto& aValueDef )
145 {
146 using ArgType = std::decay_t<decltype( aValueDef )>;
147 if constexpr( std::is_same_v<ArgType, UNIT_BOUND> )
148 {
149 UNIT_BINDER* binder = m_unit_binders[ii].get();
150 wxASSERT( binder );
151 results.push_back( binder ? binder->GetValue() : 0 );
152 }
153 else if constexpr( std::is_same_v<ArgType, CHECKBOX> )
154 {
155 wxCheckBox* checkBox = static_cast<wxCheckBox*>( control );
156 results.push_back( checkBox->GetValue() );
157 }
158 else
159 {
160 static_assert( always_false<ArgType>::value, "non-exhaustive visitor" );
161 }
162 },
163 m_entries[ii].m_value );
164 }
165
166 return results;
167}
void SetupStandardButtons(std::map< int, wxString > aLabels={})
std::string m_hash_key
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
DIALOG_SHIM(wxWindow *aParent, wxWindowID id, const wxString &title, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER, const wxString &name=wxDialogNameStr)
The base class for create windows for drawing purpose.
virtual long long int GetValue() const
Return the current value in Internal Units.
std::vector< std::unique_ptr< UNIT_BINDER > > m_unit_binders
WX_MULTI_ENTRY_DIALOG(EDA_DRAW_FRAME *aParent, const wxString &aCaption, std::vector< ENTRY > aEntries)
Create a multi-entry dialog.
std::vector< RESULT > GetValues() const
Returns the values in the order they were added.
std::vector< ENTRY > m_entries
std::vector< wxWindow * > m_controls
#define _(s)
STL namespace.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
A type that is always false.