KiCad PCB EDA Suite
Loading...
Searching...
No Matches
panel_selection_filter.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) 2020 Jon Evans <[email protected]>
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21#include <pcb_base_edit_frame.h>
22#include <tool/tool_manager.h>
25#include <wx/settings.h>
26#include <wx/dcbuffer.h>
27
28
29wxDEFINE_EVENT( EVT_PCB_SELECTION_FILTER_FLASH, PCB_SELECTION_FILTER_EVENT );
30
33 m_frame( dynamic_cast<PCB_BASE_EDIT_FRAME*>( aParent ) ),
34 m_onlyCheckbox( nullptr )
35{
36 wxFont font = KIUI::GetInfoFont( this );
37 m_cbLockedItems->SetFont( font );
38 m_cbFootprints->SetFont( font );
39 m_cbText->SetFont( font );
40 m_cbTracks->SetFont( font );
41 m_cbVias->SetFont( font );
42 m_cbPads->SetFont( font );
43 m_cbGraphics->SetFont( font );
44 m_cbZones->SetFont( font );
45 m_cbKeepouts->SetFont( font );
46 m_cbDimensions->SetFont( font );
47 m_cbPoints->SetFont( font );
48 m_cbGridItems->SetFont( font );
49 m_cbOtherItems->SetFont( font );
50 m_cbAllItems->SetFont( font );
51
52 SetBorders( true, false, false, false );
53
54 wxASSERT( m_frame );
55 m_tool = m_frame->GetToolManager()->GetTool<PCB_SELECTION_TOOL>();
56 wxASSERT( m_tool );
57
58 PCB_SELECTION_FILTER_OPTIONS& opts = m_tool->GetFilter();
60
61 m_cbFootprints->Bind( wxEVT_RIGHT_DOWN, &PANEL_SELECTION_FILTER::onRightClick, this );
62 m_cbText->Bind( wxEVT_RIGHT_DOWN, &PANEL_SELECTION_FILTER::onRightClick, this );
63 m_cbTracks->Bind( wxEVT_RIGHT_DOWN, &PANEL_SELECTION_FILTER::onRightClick, this );
64 m_cbVias->Bind( wxEVT_RIGHT_DOWN, &PANEL_SELECTION_FILTER::onRightClick, this );
65 m_cbPads->Bind( wxEVT_RIGHT_DOWN, &PANEL_SELECTION_FILTER::onRightClick, this );
66 m_cbGraphics->Bind( wxEVT_RIGHT_DOWN, &PANEL_SELECTION_FILTER::onRightClick, this );
67 m_cbZones->Bind( wxEVT_RIGHT_DOWN, &PANEL_SELECTION_FILTER::onRightClick, this );
68 m_cbKeepouts->Bind( wxEVT_RIGHT_DOWN, &PANEL_SELECTION_FILTER::onRightClick, this );
69 m_cbDimensions->Bind( wxEVT_RIGHT_DOWN, &PANEL_SELECTION_FILTER::onRightClick, this );
70 m_cbPoints->Bind( wxEVT_RIGHT_DOWN, &PANEL_SELECTION_FILTER::onRightClick, this );
71 m_cbGridItems->Bind( wxEVT_RIGHT_DOWN, &PANEL_SELECTION_FILTER::onRightClick, this );
72 m_cbOtherItems->Bind( wxEVT_RIGHT_DOWN, &PANEL_SELECTION_FILTER::onRightClick, this );
73
74 m_frame->Bind( EDA_LANG_CHANGED, &PANEL_SELECTION_FILTER::OnLanguageChanged, this );
75
76 SetMinSize( GetBestSize() );
77
78 m_flashSteps = 10;
79 m_defaultBg = GetBackgroundColour();
80 m_flashTimer.SetOwner( this );
81 Bind( wxEVT_TIMER, &PANEL_SELECTION_FILTER::onFlashTimer, this );
82 aParent->Bind( EVT_PCB_SELECTION_FILTER_FLASH, &PANEL_SELECTION_FILTER::OnFlashEvent, this );
83}
84
85
87{
88 // Stop any active flashing
89 m_flashTimer.Stop();
90 if( !m_flashCounters.empty() )
91 {
92 Unbind( wxEVT_PAINT, &PANEL_SELECTION_FILTER::onPanelPaint, this );
93 }
94 m_flashCounters.clear();
95
96 m_frame->Unbind( EDA_LANG_CHANGED, &PANEL_SELECTION_FILTER::OnLanguageChanged, this );
97 m_frame->Unbind( EVT_PCB_SELECTION_FILTER_FLASH, &PANEL_SELECTION_FILTER::OnFlashEvent, this );
98}
99
100
102{
103 Freeze();
104
105 m_cbLockedItems->SetValue( aOptions.lockedItems );
106 m_cbFootprints->SetValue( aOptions.footprints );
107 m_cbText->SetValue( aOptions.text );
108 m_cbTracks->SetValue( aOptions.tracks );
109 m_cbVias->SetValue( aOptions.vias );
110 m_cbPads->SetValue( aOptions.pads );
111 m_cbGraphics->SetValue( aOptions.graphics );
112 m_cbZones->SetValue( aOptions.zones );
113 m_cbKeepouts->SetValue( aOptions.keepouts );
114 m_cbDimensions->SetValue( aOptions.dimensions );
115 m_cbPoints->SetValue( aOptions.points );
116 m_cbGridItems->SetValue( aOptions.gridItems );
117 m_cbOtherItems->SetValue( aOptions.otherItems );
118
119 m_cbAllItems->SetValue( aOptions.All() );
120
121 Thaw();
122}
123
124
125void PANEL_SELECTION_FILTER::OnFilterChanged( wxCommandEvent& aEvent )
126{
127 if( aEvent.GetEventObject() == m_cbAllItems )
128 {
129 bool newState = m_cbAllItems->GetValue();
130
131 m_cbFootprints->SetValue( newState );
132 m_cbText->SetValue( newState );
133 m_cbTracks->SetValue( newState );
134 m_cbVias->SetValue( newState );
135 m_cbPads->SetValue( newState );
136 m_cbGraphics->SetValue( newState );
137 m_cbZones->SetValue( newState );
138 m_cbKeepouts->SetValue( newState );
139 m_cbDimensions->SetValue( newState );
140 m_cbPoints->SetValue( newState );
141 m_cbGridItems->SetValue( newState );
142 m_cbOtherItems->SetValue( newState );
143 }
144
145 PCB_SELECTION_FILTER_OPTIONS& opts = m_tool->GetFilter();
146
147 // If any of the other checkboxes turned off, turn off the All Items checkbox
148 bool allChecked = setFilterFromCheckboxes( opts );
149 m_cbAllItems->SetValue( allChecked );
150}
151
152
154{
155 aOptions.lockedItems = m_cbLockedItems->GetValue();
156 aOptions.footprints = m_cbFootprints->GetValue();
157 aOptions.text = m_cbText->GetValue();
158 aOptions.tracks = m_cbTracks->GetValue();
159 aOptions.vias = m_cbVias->GetValue();
160 aOptions.pads = m_cbPads->GetValue();
161 aOptions.graphics = m_cbGraphics->GetValue();
162 aOptions.zones = m_cbZones->GetValue();
163 aOptions.keepouts = m_cbKeepouts->GetValue();
164 aOptions.dimensions = m_cbDimensions->GetValue();
165 aOptions.points = m_cbPoints->GetValue();
166 aOptions.gridItems = m_cbGridItems->GetValue();
167 aOptions.otherItems = m_cbOtherItems->GetValue();
168
169 return aOptions.All();
170}
171
172
173void PANEL_SELECTION_FILTER::onRightClick( wxMouseEvent& aEvent )
174{
175 wxMenu menu;
176
177 wxCheckBox* cb = dynamic_cast<wxCheckBox*>( aEvent.GetEventObject() );
178
179 if( !cb )
180 return;
181
182 m_onlyCheckbox = cb;
183
184 wxString label;
185 label.Printf( _( "Only %s" ), cb->GetLabel().Lower() );
186
187 menu.Append( new wxMenuItem( &menu, wxID_ANY, label, wxEmptyString, wxITEM_NORMAL ) );
188
189 menu.Bind( wxEVT_COMMAND_MENU_SELECTED, &PANEL_SELECTION_FILTER::onPopupSelection, this );
190
191 PopupMenu( &menu );
192}
193
194
195void PANEL_SELECTION_FILTER::onPopupSelection( wxCommandEvent& aEvent )
196{
197 if( !m_onlyCheckbox )
198 return;
199
200 m_cbAllItems->SetValue( false );
201 m_cbFootprints->SetValue( false );
202 m_cbText->SetValue( false );
203 m_cbTracks->SetValue( false );
204 m_cbVias->SetValue( false );
205 m_cbPads->SetValue( false );
206 m_cbGraphics->SetValue( false );
207 m_cbZones->SetValue( false );
208 m_cbKeepouts->SetValue( false );
209 m_cbDimensions->SetValue( false );
210 m_cbPoints->SetValue( false );
211 m_cbGridItems->SetValue( false );
212 m_cbOtherItems->SetValue( false );
213
214 m_onlyCheckbox->SetValue( true );
215 m_onlyCheckbox = nullptr;
216
217 wxCommandEvent dummy;
219}
220
221
222void PANEL_SELECTION_FILTER::OnLanguageChanged( wxCommandEvent& aEvent )
223{
224 m_cbAllItems->SetLabel( _( "All items" ) );
225 m_cbLockedItems->SetLabel( _( "Locked items" ) );
226 m_cbLockedItems->SetToolTip( _( "Allow selection of locked items" ) );
227 m_cbFootprints->SetLabel( _( "Footprints" ) );
228 m_cbText->SetLabel( _( "Text" ) );
229 m_cbTracks->SetLabel( _( "Tracks" ) );
230 m_cbVias->SetLabel( _( "Vias" ) );
231 m_cbPads->SetLabel( _( "Pads" ) );
232 m_cbGraphics->SetLabel( _( "Graphics" ) );
233 m_cbZones->SetLabel( _( "Zones" ) );
234 m_cbKeepouts->SetLabel( _( "Rule Areas" ) );
235 m_cbDimensions->SetLabel( _( "Dimensions" ) );
236 m_cbPoints->SetLabel( _( "Points" ) );
237 m_cbGridItems->SetLabel( _( "Grid Items" ) );
238 m_cbOtherItems->SetLabel( _( "Other items" ) );
239
240 m_cbAllItems->GetParent()->Layout();
241
242 aEvent.Skip();
243}
244
245
247{
248 if( !aBox )
249 return;
250
251 // If already flashing, just reset the counter
252 if( m_flashCounters.find( aBox ) != m_flashCounters.end() )
253 {
255 return;
256 }
257
259 m_defaultBg = aBox->GetBackgroundColour();
260
261 // Bind paint event to this panel if not already bound
262 if( m_flashCounters.size() == 1 )
263 {
264 Bind( wxEVT_PAINT, &PANEL_SELECTION_FILTER::onPanelPaint, this );
265 }
266
267 Refresh();
268}
269
270
271void PANEL_SELECTION_FILTER::onFlashTimer( wxTimerEvent& aEvent )
272{
273 for( auto it = m_flashCounters.begin(); it != m_flashCounters.end(); )
274 {
275 int step = --( it->second );
276
277 if( step <= 0 )
278 it = m_flashCounters.erase( it );
279 else
280 ++it;
281 }
282
283 if( m_flashCounters.empty() )
284 {
285 m_flashTimer.Stop();
286 // Unbind paint event when no more flashing
287 Unbind( wxEVT_PAINT, &PANEL_SELECTION_FILTER::onPanelPaint, this );
288 }
289
290 Refresh();
291}
292
293
294void PANEL_SELECTION_FILTER::onPanelPaint( wxPaintEvent& aEvent )
295{
296 wxPaintDC dc( this );
297
298 // First, let the default painting happen
299 aEvent.Skip();
300
301 // Then draw our highlights on top
302 for( auto& pair : m_flashCounters )
303 {
304 wxCheckBox* checkbox = pair.first;
305 int step = pair.second;
306
307 if( step > 0 )
308 {
309 // Get the checkbox position relative to this panel
310 wxPoint checkboxPos = checkbox->GetPosition();
311 wxSize checkboxSize = checkbox->GetSize();
312 wxRect checkboxRect( checkboxPos, checkboxSize );
313
314 // Calculate blended color based on current flash step
315 wxColour highlight = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT );
316 wxColour blend(
317 ( highlight.Red() * step + m_defaultBg.Red() * ( m_flashSteps - step ) ) / m_flashSteps,
318 ( highlight.Green() * step + m_defaultBg.Green() * ( m_flashSteps - step ) ) / m_flashSteps,
319 ( highlight.Blue() * step + m_defaultBg.Blue() * ( m_flashSteps - step ) ) / m_flashSteps );
320
321 // Draw semi-transparent overlay
322 wxColour overlayColor( blend.Red(), blend.Green(), blend.Blue(), 128 );
323 dc.SetBrush( wxBrush( overlayColor ) );
324 dc.SetPen( wxPen( overlayColor ) );
325 dc.DrawRectangle( checkboxRect );
326 }
327 }
328}
329
330
332{
333 const PCB_SELECTION_FILTER_OPTIONS& aOptions = aEvent.m_options;
334
335 if( aOptions.lockedItems )
337
338 if( aOptions.footprints )
340
341 if( aOptions.text )
343
344 if( aOptions.tracks )
346
347 if( aOptions.vias )
349
350 if( aOptions.pads )
352
353 if( aOptions.graphics )
355
356 if( aOptions.zones )
358
359 if( aOptions.keepouts )
361
362 if( aOptions.dimensions )
364
365 if( aOptions.points )
367
368 if( aOptions.gridItems )
370
371 if( aOptions.otherItems )
373
374 if( !m_flashCounters.empty() )
375 m_flashTimer.Start( 50 );
376}
PANEL_SELECTION_FILTER_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
PCB_BASE_EDIT_FRAME * m_frame
void onPopupSelection(wxCommandEvent &aEvent)
std::map< wxCheckBox *, int > m_flashCounters
void flashCheckbox(wxCheckBox *aBox)
PCB_SELECTION_TOOL * m_tool
bool setFilterFromCheckboxes(PCB_SELECTION_FILTER_OPTIONS &aOptions)
PANEL_SELECTION_FILTER(wxWindow *aParent)
void OnFlashEvent(PCB_SELECTION_FILTER_EVENT &aEvent)
void SetCheckboxesFromFilter(PCB_SELECTION_FILTER_OPTIONS &aOptions)
void onFlashTimer(wxTimerEvent &aEvent)
void OnLanguageChanged(wxCommandEvent &aEvent)
void OnFilterChanged(wxCommandEvent &aEvent) override
void onRightClick(wxMouseEvent &aEvent)
void onPanelPaint(wxPaintEvent &aEvent)
Common, abstract interface for edit frames.
PCB_SELECTION_FILTER_OPTIONS m_options
The selection tool: currently supports:
void SetBorders(bool aLeft, bool aRight, bool aTop, bool aBottom)
Definition wx_panel.h:35
#define _(s)
KICOMMON_API wxFont GetInfoFont(wxWindow *aWindow)
wxDEFINE_EVENT(EVT_PCB_SELECTION_FILTER_FLASH, PCB_SELECTION_FILTER_EVENT)
std::vector< FAB_LAYER_COLOR > dummy
This file contains data structures that are saved in the project file or project local settings file ...
bool otherItems
Anything not fitting one of the above categories.
bool graphics
Graphic lines, shapes, polygons.
bool footprints
Allow selecting entire footprints.
bool text
Text (free or attached to a footprint)
bool lockedItems
Allow selecting locked items.