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, 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
25
26#include <eda_draw_frame.h>
27#include <widgets/unit_binder.h>
28#include <core/type_helpers.h>
29#include <string_utils.h>
30#include <wx/button.h>
31#include <wx/checkbox.h>
32#include <wx/gbsizer.h>
33#include <wx/stattext.h>
34
35
37 std::vector<ENTRY> aEntries ) :
38 DIALOG_SHIM( aParent, wxID_ANY, aCaption ),
39 m_entries( std::move( aEntries ) )
40{
41 SetSizeHints( wxDefaultSize, wxDefaultSize );
42
43 wxBoxSizer* bSizerMain = new wxBoxSizer( wxVERTICAL );
44
45 wxGridBagSizer* bSizerContent;
46
47 bSizerContent = new wxGridBagSizer( 0, 0 );
48 bSizerContent->SetFlexibleDirection( wxHORIZONTAL );
49 bSizerContent->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_ALL );
50
51 bSizerMain->Add( bSizerContent, 1, wxEXPAND | wxRIGHT | wxLEFT, 5 );
52
53 int gbRow = 0;
54
55 for( const ENTRY& entry : m_entries )
56 {
57 std::visit(
58 [&]( const auto& aValue )
59 {
60 using EntryType = std::decay_t<decltype( aValue )>;
61
62 if constexpr( std::is_same_v<EntryType, UNIT_BOUND> )
63 {
64 // Label / Entry / Unit
65 // and a binder
66 wxStaticText* label = new wxStaticText( this, wxID_ANY, entry.m_label );
67 label->Wrap( -1 );
68 bSizerContent->Add( label, wxGBPosition( gbRow, 0 ), wxGBSpan( 1, 1 ),
69 wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM | wxLEFT, 5 );
70
71 wxTextCtrl* textCtrl = new wxTextCtrl( this, wxID_ANY );
72 bSizerContent->Add( textCtrl, wxGBPosition( gbRow, 1 ), wxGBSpan( 1, 1 ),
73 wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 5 );
74
75 wxStaticText* units = new wxStaticText( this, wxID_ANY, _( "unit" ) );
76 units->Wrap( -1 );
77 bSizerContent->Add( units, wxGBPosition( gbRow, 2 ), wxGBSpan( 1, 1 ),
78 wxTOP | wxBOTTOM | wxRIGHT | wxALIGN_CENTER_VERTICAL, 5 );
79
80 if( !entry.m_tooltip.IsEmpty() )
81 textCtrl->SetToolTip( entry.m_tooltip );
82
83 m_controls.push_back( textCtrl );
84 m_unit_binders.push_back( std::make_unique<UNIT_BINDER>( aParent, label, textCtrl, units ) );
85
86 m_unit_binders.back()->SetValue( aValue.m_default );
87 }
88 else if constexpr( std::is_same_v<EntryType, CHECKBOX> )
89 {
90 // Checkbox across all 3 cols
91 wxCheckBox* checkBox = new wxCheckBox( this, wxID_ANY, entry.m_label );
92 checkBox->SetValue( aValue.m_default );
93 bSizerContent->Add( checkBox, wxGBPosition( gbRow, 0 ), wxGBSpan( 1, 3 ),
94 wxALIGN_CENTER_VERTICAL | wxALL, 5 );
95
96 if( !entry.m_tooltip.IsEmpty() )
97 checkBox->SetToolTip( entry.m_tooltip );
98
99 m_controls.push_back( checkBox );
100 m_unit_binders.push_back( nullptr );
101 }
102 else
103 {
104 static_assert( always_false<EntryType>::value, "non-exhaustive visitor" );
105 }
106 },
107 entry.m_value );
108
109 gbRow++;
110 }
111
112 // Grow the value column (now it knows it has a col 1)
113 bSizerContent->AddGrowableCol( 1 );
114
115 wxStdDialogButtonSizer* sdbSizer1 = new wxStdDialogButtonSizer();
116 wxButton* sdbSizer1OK = new wxButton( this, wxID_OK );
117 sdbSizer1->AddButton( sdbSizer1OK );
118 wxButton* sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
119 sdbSizer1->AddButton( sdbSizer1Cancel );
120 sdbSizer1->Realize();
121
122 bSizerMain->Add( sdbSizer1, 0, wxALL | wxEXPAND, 5 );
123
124 // DIALOG_SHIM needs a title--specific hash_key so we don't save/restore state between
125 // usage cases.
126 m_hash_key = TO_UTF8( GetTitle() );
127
128 SetSizer( bSizerMain );
130 Layout();
131
132 // Now all widgets have the size fixed, call FinishDialogSettings
134}
135
136
137std::vector<WX_MULTI_ENTRY_DIALOG::RESULT> WX_MULTI_ENTRY_DIALOG::GetValues() const
138{
139 std::vector<RESULT> results;
140
141 for( size_t ii = 0; ii < m_entries.size(); ++ii )
142 {
143 wxWindow* const control = m_controls[ii];
144
145 // Visit the value definitons to look up the right control type
146 std::visit(
147 [&]( const auto& aValueDef )
148 {
149 using ArgType = std::decay_t<decltype( aValueDef )>;
150 if constexpr( std::is_same_v<ArgType, UNIT_BOUND> )
151 {
152 UNIT_BINDER* binder = m_unit_binders[ii].get();
153 wxASSERT( binder );
154 results.push_back( binder ? binder->GetValue() : 0 );
155 }
156 else if constexpr( std::is_same_v<ArgType, CHECKBOX> )
157 {
158 wxCheckBox* checkBox = static_cast<wxCheckBox*>( control );
159 results.push_back( checkBox->GetValue() );
160 }
161 else
162 {
163 static_assert( always_false<ArgType>::value, "non-exhaustive visitor" );
164 }
165 },
166 m_entries[ii].m_value );
167 }
168
169 return results;
170}
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.