KiCad PCB EDA Suite
Loading...
Searching...
No Matches
eda_reorderable_list_dialog.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 (C) 2022-2023 KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <algorithm>
21#include <bitmaps.h>
22#include <string_utils.h>
25
26
27static int DEFAULT_SINGLE_COL_WIDTH = 260;
28
29
30EDA_REORDERABLE_LIST_DIALOG::EDA_REORDERABLE_LIST_DIALOG( wxWindow* aParent, const wxString& aTitle,
31 const std::vector<wxString>& aAllItems,
32 const std::vector<wxString>& aEnabledItems ) :
33 EDA_REORDERABLE_LIST_DIALOG_BASE( aParent, wxID_ANY, aTitle ),
34 m_availableItems( aAllItems ),
35 m_enabledItems( aEnabledItems ),
36 m_selectedAvailable( 0 ),
37 m_selectedEnabled( 0 )
38{
39 m_btnUp->SetBitmap( KiBitmapBundle( BITMAPS::small_up ) );
40 m_btnDown->SetBitmap( KiBitmapBundle( BITMAPS::small_down ) );
41
42 // DIALOG_SHIM needs a unique hash_key because classname is not sufficient
43 // because so many dialogs share this same class, with different numbers of
44 // columns, different column names, and column widths.
45 m_hash_key = TO_UTF8( aTitle );
46
47 m_availableListBox->InsertColumn( 0, wxEmptyString, wxLIST_FORMAT_LEFT,
49 m_enabledListBox->InsertColumn( 0, wxEmptyString, wxLIST_FORMAT_LEFT,
51
53
55
56 // this line fixes an issue on Linux Ubuntu using Unity (dialog not shown),
57 // and works fine on all systems
58 GetSizer()->Fit( this );
59
60 Centre();
61}
62
63
65{
66 m_availableListBox->DeleteAllItems();
67 m_enabledListBox->DeleteAllItems();
68
69 std::set<wxString> enabledSet;
70
71 for( size_t idx = 0; idx < m_enabledItems.size(); ++idx )
72 {
73 wxListItem info;
74 info.m_itemId = idx;
75 info.m_col = 0;
76 info.m_text = m_enabledItems[idx];
78 info.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_WIDTH;
79
80 m_enabledListBox->InsertItem( info );
81
82 if( m_selectedEnabled == static_cast<long>( idx ) )
83 m_enabledListBox->SetItemState( idx, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
84
85 enabledSet.insert( m_enabledItems[idx] );
86 }
87
88 m_availableItems.erase( std::remove_if( m_availableItems.begin(), m_availableItems.end(),
89 [&]( const wxString& aItem ) -> bool
90 {
91 return enabledSet.count( aItem );
92 } ),
93 m_availableItems.end() );
94
95 for( size_t idx = 0; idx < m_availableItems.size(); ++idx )
96 {
97 wxListItem info;
98 info.m_itemId = idx;
99 info.m_col = 0;
100 info.m_text = m_availableItems[idx];
102 info.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_WIDTH;
103
104 m_availableListBox->InsertItem( info );
105
106 if( m_selectedAvailable == static_cast<long>( idx ) )
107 m_availableListBox->SetItemState( idx, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
108 }
109
110 if( !m_availableItems.empty() )
111 m_availableListBox->EnsureVisible( m_selectedAvailable );
112
113 if( !m_enabledItems.empty() )
114 m_enabledListBox->EnsureVisible( m_selectedEnabled );
115
116 m_btnAdd->Enable( !m_availableItems.empty() );
117 m_btnRemove->Enable( !m_enabledItems.empty() );
118}
119
120
121void EDA_REORDERABLE_LIST_DIALOG::onAddItem( wxCommandEvent& aEvent )
122{
123 wxListItem info;
124
126 {
127 wxBell();
128 return;
129 }
130
131 m_availableItems.erase( m_availableItems.begin() + info.m_itemId );
133
134 long pos = std::min( m_selectedEnabled + 1, static_cast<long>( m_enabledItems.size() ) );
135
136 info.m_itemId = pos;
137 info.m_mask = wxLIST_MASK_TEXT;
138
139 m_enabledItems.insert( m_enabledItems.begin() + pos, info.m_text );
140 m_enabledListBox->InsertItem( info );
141}
142
143
144void EDA_REORDERABLE_LIST_DIALOG::onRemoveItem( wxCommandEvent& aEvent )
145{
146 wxListItem info;
147
148 if( !getSelectedItem( m_enabledListBox, info ) || info.m_itemId == 0 )
149 {
150 wxBell();
151 return;
152 }
153
154 m_enabledItems.erase( m_enabledItems.begin() + info.m_itemId );
155 m_enabledListBox->DeleteItem( m_selectedEnabled );
156
158 static_cast<long>( m_enabledItems.size() - 1 ) );
159
160 m_enabledListBox->SetItemState( m_selectedEnabled, wxLIST_STATE_SELECTED,
161 wxLIST_STATE_SELECTED );
162
163 long pos = std::max( long( 0 ), m_selectedAvailable );
164 info.m_itemId = pos;
165
166 m_availableItems.insert( m_availableItems.begin() + pos, info.m_text );
167 m_availableListBox->InsertItem( info );
168}
169
170
171void EDA_REORDERABLE_LIST_DIALOG::onMoveUp( wxCommandEvent& aEvent )
172{
173 wxListItem info;
174
175 if( !getSelectedItem( m_enabledListBox, info ) || info.m_itemId == 0 )
176 {
177 wxBell();
178 return;
179 }
180
181 auto current = m_enabledItems.begin() + info.m_itemId;
182 auto prev = m_enabledItems.begin() + info.m_itemId - 1;
183
184 std::iter_swap( current, prev );
185
187
188 updateItems();
189}
190
191
192void EDA_REORDERABLE_LIST_DIALOG::onMoveDown( wxCommandEvent& aEvent )
193{
194 wxListItem info;
195
197 || info.m_itemId == static_cast<long>( m_enabledItems.size() ) - 1 )
198 {
199 wxBell();
200 return;
201 }
202
203 auto current = m_enabledItems.begin() + info.m_itemId;
204 auto prev = m_enabledItems.begin() + info.m_itemId + 1;
205
206 std::iter_swap( current, prev );
207
209
210 updateItems();
211}
212
213
214bool EDA_REORDERABLE_LIST_DIALOG::getSelectedItem( wxListCtrl* aList, wxListItem& aInfo )
215{
216 long item = aList->GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
217
218 if( item < 0 )
219 return false;
220
221 aInfo.m_mask = wxLIST_MASK_DATA | wxLIST_MASK_STATE | wxLIST_MASK_TEXT;
222 aInfo.m_itemId = item;
223 aInfo.m_col = 0;
224
225 if( !aList->GetItem( aInfo ) )
226 return false;
227
228 return true;
229}
230
231
233{
234 wxListItem info;
235
237 {
239 return;
240 }
241
242 m_selectedEnabled = info.m_itemId;
243}
244
245
247{
248 wxListItem info;
249
251 {
253 return;
254 }
255
256 m_selectedAvailable = info.m_itemId;
257}
258
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
void SetupStandardButtons(std::map< int, wxString > aLabels={})
std::string m_hash_key
Definition: dialog_shim.h:205
Class EDA_REORDERABLE_LIST_DIALOG_BASE.
std::vector< wxString > m_availableItems
void onAvailableListItemSelected(wxListEvent &event) override
bool getSelectedItem(wxListCtrl *aList, wxListItem &aInfo)
void onMoveUp(wxCommandEvent &aEvent) override
void onMoveDown(wxCommandEvent &aEvent) override
void onEnabledListItemSelected(wxListEvent &event) override
EDA_REORDERABLE_LIST_DIALOG(wxWindow *aParent, const wxString &aTitle, const std::vector< wxString > &aAllItems, const std::vector< wxString > &aEnabledItems)
void onRemoveItem(wxCommandEvent &aEvent) override
void onAddItem(wxCommandEvent &aEvent) override
std::vector< wxString > m_enabledItems
void SetBitmap(const wxBitmapBundle &aBmp)
static int DEFAULT_SINGLE_COL_WIDTH
static int DEFAULT_SINGLE_COL_WIDTH
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: string_utils.h:391