KiCad PCB EDA Suite
Loading...
Searching...
No Matches
panel_sch_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) 2024 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
22#include <sch_base_frame.h>
23#include <tool/tool_manager.h>
26#include <wx/settings.h>
27#include <wx/dcbuffer.h>
28
29
30wxDEFINE_EVENT( EVT_SCH_SELECTION_FILTER_FLASH, SCH_SELECTION_FILTER_EVENT );
31
34 m_frame( dynamic_cast<SCH_BASE_FRAME*>( aParent ) ),
35 m_onlyCheckbox( nullptr )
36{
37 wxFont font = KIUI::GetInfoFont( this );
38 m_cbLockedItems->SetFont( font );
39 m_cbSymbols->SetFont( font );
40 m_cbText->SetFont( font );
41 m_cbWires->SetFont( font );
42 m_cbLabels->SetFont( font );
43 m_cbPins->SetFont( font );
44 m_cbGraphics->SetFont( font );
45 m_cbImages->SetFont( font );
46 m_cbOtherItems->SetFont( font );
47 m_cbAllItems->SetFont( font );
48 m_cbRuleAreas->SetFont( font );
49
50 SetBorders( true, false, false, false );
51
52 wxASSERT( m_frame );
53 m_tool = m_frame->GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
54 wxASSERT( m_tool );
55
56 SCH_SELECTION_FILTER_OPTIONS& opts = m_tool->GetFilter();
58
59 m_cbSymbols->Bind( wxEVT_RIGHT_DOWN, &PANEL_SCH_SELECTION_FILTER::onRightClick, this );
60 m_cbText->Bind( wxEVT_RIGHT_DOWN, &PANEL_SCH_SELECTION_FILTER::onRightClick, this );
61 m_cbWires->Bind( wxEVT_RIGHT_DOWN, &PANEL_SCH_SELECTION_FILTER::onRightClick, this );
62 m_cbLabels->Bind( wxEVT_RIGHT_DOWN, &PANEL_SCH_SELECTION_FILTER::onRightClick, this );
63 m_cbPins->Bind( wxEVT_RIGHT_DOWN, &PANEL_SCH_SELECTION_FILTER::onRightClick, this );
64 m_cbGraphics->Bind( wxEVT_RIGHT_DOWN, &PANEL_SCH_SELECTION_FILTER::onRightClick, this );
65 m_cbImages->Bind( wxEVT_RIGHT_DOWN, &PANEL_SCH_SELECTION_FILTER::onRightClick, this );
66 m_cbOtherItems->Bind( wxEVT_RIGHT_DOWN, &PANEL_SCH_SELECTION_FILTER::onRightClick, this );
67 m_cbRuleAreas->Bind( wxEVT_RIGHT_DOWN, &PANEL_SCH_SELECTION_FILTER::onRightClick, this );
68
69 if( m_frame->GetFrameType() == FRAME_SCH_SYMBOL_EDITOR )
70 {
71 Freeze();
72 m_gridSizer->SetItemPosition( m_cbSymbols, wxGBPosition( 6, 0 ) );
73 m_gridSizer->SetItemPosition( m_cbWires, wxGBPosition( 6, 1 ) );
74 m_gridSizer->SetItemPosition( m_cbLabels, wxGBPosition( 7, 0 ) );
75 m_gridSizer->SetItemPosition( m_cbImages, wxGBPosition( 7, 1 ) );
76 m_cbSymbols->Hide();
77 m_cbWires->Hide();
78 m_cbLabels->Hide();
79 m_cbImages->Hide();
80 m_cbRuleAreas->Hide();
81
82 m_gridSizer->SetItemPosition( m_cbPins, wxGBPosition( 1, 0 ) );
83 m_gridSizer->SetItemPosition( m_cbText, wxGBPosition( 1, 1 ) );
84 m_gridSizer->SetItemPosition( m_cbGraphics, wxGBPosition( 2, 0 ) );
85 m_gridSizer->SetItemPosition( m_cbOtherItems, wxGBPosition( 2, 1 ) );
86 Thaw();
87 }
88
89 m_frame->Bind( EDA_LANG_CHANGED, &PANEL_SCH_SELECTION_FILTER::OnLanguageChanged, this );
90
91 m_flashSteps = 10;
92 m_flashTimer.SetOwner( this );
93 Bind( wxEVT_TIMER, &PANEL_SCH_SELECTION_FILTER::onFlashTimer, this );
94 aParent->Bind( EVT_SCH_SELECTION_FILTER_FLASH, &PANEL_SCH_SELECTION_FILTER::OnFlashEvent, this );
95}
96
97
99{
100 // Stop any active flashing
101 m_flashTimer.Stop();
102
103#ifndef __WXMSW__
104 if( !m_flashCounters.empty() )
105 {
106 Unbind( wxEVT_PAINT, &PANEL_SCH_SELECTION_FILTER::onPanelPaint, this );
107 }
108#endif
109
110 m_flashCounters.clear();
111
112 m_frame->Unbind( EDA_LANG_CHANGED, &PANEL_SCH_SELECTION_FILTER::OnLanguageChanged, this );
113 m_frame->Unbind( EVT_SCH_SELECTION_FILTER_FLASH, &PANEL_SCH_SELECTION_FILTER::OnFlashEvent, this );
114}
115
116
118{
119 Freeze();
120
121 m_cbLockedItems->SetValue( aOptions.lockedItems );
122 m_cbSymbols->SetValue( aOptions.symbols );
123 m_cbText->SetValue( aOptions.text );
124 m_cbWires->SetValue( aOptions.wires );
125 m_cbLabels->SetValue( aOptions.labels );
126 m_cbPins->SetValue( aOptions.pins );
127 m_cbGraphics->SetValue( aOptions.graphics );
128 m_cbImages->SetValue( aOptions.images );
129 m_cbRuleAreas->SetValue( aOptions.ruleAreas );
130 m_cbOtherItems->SetValue( aOptions.otherItems );
131
132 m_cbAllItems->SetValue( aOptions.All() );
133
134 Thaw();
135}
136
137
139{
140 if( aEvent.GetEventObject() == m_cbAllItems )
141 {
142 bool newState = m_cbAllItems->GetValue();
143
144 m_cbSymbols->SetValue( newState );
145 m_cbText->SetValue( newState );
146 m_cbWires->SetValue( newState );
147 m_cbLabels->SetValue( newState );
148 m_cbPins->SetValue( newState );
149 m_cbGraphics->SetValue( newState );
150 m_cbImages->SetValue( newState );
151 m_cbRuleAreas->SetValue( newState );
152 m_cbOtherItems->SetValue( newState );
153 }
154
155 SCH_SELECTION_FILTER_OPTIONS& opts = m_tool->GetFilter();
156
157 // If any of the other checkboxes turned off, turn off the All Items checkbox
158 bool allChecked = setFilterFromCheckboxes( opts );
159 m_cbAllItems->SetValue( allChecked );
160}
161
162
164{
165 aOptions.lockedItems = m_cbLockedItems->GetValue();
166 aOptions.symbols = m_cbSymbols->GetValue();
167 aOptions.text = m_cbText->GetValue();
168 aOptions.wires = m_cbWires->GetValue();
169 aOptions.labels = m_cbLabels->GetValue();
170 aOptions.pins = m_cbPins->GetValue();
171 aOptions.graphics = m_cbGraphics->GetValue();
172 aOptions.images = m_cbImages->GetValue();
173 aOptions.ruleAreas = m_cbRuleAreas->GetValue();
174 aOptions.otherItems = m_cbOtherItems->GetValue();
175
176 return aOptions.All();
177}
178
179
181{
182 wxMenu menu;
183
184 wxCheckBox* cb = dynamic_cast<wxCheckBox*>( aEvent.GetEventObject() );
185
186 if( !cb )
187 return;
188
189 m_onlyCheckbox = cb;
190
191 wxString label;
192 label.Printf( _( "Only %s" ), cb->GetLabel().Lower() );
193
194 menu.Append( new wxMenuItem( &menu, wxID_ANY, label, wxEmptyString, wxITEM_NORMAL ) );
195
196 menu.Bind( wxEVT_COMMAND_MENU_SELECTED, &PANEL_SCH_SELECTION_FILTER::onPopupSelection, this );
197
198 PopupMenu( &menu );
199}
200
201
203{
204 if( !m_onlyCheckbox )
205 return;
206
207 m_cbAllItems->SetValue( false );
208 m_cbSymbols->SetValue( false );
209 m_cbText->SetValue( false );
210 m_cbWires->SetValue( false );
211 m_cbLabels->SetValue( false );
212 m_cbPins->SetValue( false );
213 m_cbGraphics->SetValue( false );
214 m_cbImages->SetValue( false );
215 m_cbOtherItems->SetValue( false );
216 m_cbRuleAreas->SetValue( false );
217
218 m_onlyCheckbox->SetValue( true );
219 m_onlyCheckbox = nullptr;
220
221 wxCommandEvent dummy;
223}
224
225
227{
228 m_cbAllItems->SetLabel( _( "All items" ) );
229 m_cbLockedItems->SetLabel( _( "Locked items" ) );
230 m_cbLockedItems->SetToolTip( _( "Allow selection of locked items" ) );
231 m_cbSymbols->SetLabel( _( "Symbols" ) );
232 m_cbText->SetLabel( _( "Text" ) );
233 m_cbWires->SetLabel( _( "Wires" ) );
234 m_cbLabels->SetLabel( _( "Labels" ) );
235 m_cbPins->SetLabel( _( "Pins" ) );
236 m_cbGraphics->SetLabel( _( "Graphics" ) );
237 m_cbImages->SetLabel( _( "Images" ) );
238 m_cbRuleAreas->SetLabel( _( "Rule Areas" ) );
239 m_cbOtherItems->SetLabel( _( "Other items" ) );
240
241 m_cbAllItems->GetParent()->Layout();
242
243 aEvent.Skip();
244}
245
246
248{
249 if( !aBox )
250 return;
251
252#ifdef __WXMSW__
253 // Native MSW checkboxes paint over the panel, so tint the box itself
255 aBox->SetBackgroundColour( flashColour( m_flashSteps ) );
256 aBox->Refresh();
257#else
258 // Bind paint event to this panel if not already bound
259 if( m_flashCounters.empty() )
260 {
261 Bind( wxEVT_PAINT, &PANEL_SCH_SELECTION_FILTER::onPanelPaint, this );
262 }
263
265 Refresh();
266#endif
267}
268
269
271{
272 // Blend from the panel, never from a box that may still carry a flash colour
273 wxColour highlight = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT );
274 wxColour bg = GetBackgroundColour();
275
276 return wxColour( ( highlight.Red() * aStep + bg.Red() * ( m_flashSteps - aStep ) ) / m_flashSteps,
277 ( highlight.Green() * aStep + bg.Green() * ( m_flashSteps - aStep ) ) / m_flashSteps,
278 ( highlight.Blue() * aStep + bg.Blue() * ( m_flashSteps - aStep ) ) / m_flashSteps );
279}
280
281
283{
284 for( auto it = m_flashCounters.begin(); it != m_flashCounters.end(); )
285 {
286 int step = --( it->second );
287
288#ifdef __WXMSW__
289 // wxNullColour drops the override so the box inherits the panel colour again
290 it->first->SetBackgroundColour( step > 0 ? flashColour( step ) : wxNullColour );
291 it->first->Refresh();
292#endif
293
294 if( step <= 0 )
295 it = m_flashCounters.erase( it );
296 else
297 ++it;
298 }
299
300 if( m_flashCounters.empty() )
301 {
302 m_flashTimer.Stop();
303
304#ifndef __WXMSW__
305 // Unbind paint event when no more flashing
306 Unbind( wxEVT_PAINT, &PANEL_SCH_SELECTION_FILTER::onPanelPaint, this );
307#endif
308 }
309
310#ifndef __WXMSW__
311 Refresh();
312#endif
313}
314
315
317{
318 wxPaintDC dc( this );
319
320 // First, let the default painting happen
321 aEvent.Skip();
322
323 // Then draw our highlights on top
324 for( auto& pair : m_flashCounters )
325 {
326 wxCheckBox* checkbox = pair.first;
327 int step = pair.second;
328
329 if( step > 0 )
330 {
331 // Get the checkbox position relative to this panel
332 wxPoint checkboxPos = checkbox->GetPosition();
333 wxSize checkboxSize = checkbox->GetSize();
334 wxRect checkboxRect( checkboxPos, checkboxSize );
335
336 // Calculate blended color based on current flash step
337 wxColour blend = flashColour( step );
338
339 // Draw semi-transparent overlay
340 wxColour overlayColor( blend.Red(), blend.Green(), blend.Blue(), 128 );
341 dc.SetBrush( wxBrush( overlayColor ) );
342 dc.SetPen( wxPen( overlayColor ) );
343 dc.DrawRectangle( checkboxRect );
344 }
345 }
346}
347
348
350{
351 const SCH_SELECTION_FILTER_OPTIONS& aOptions = aEvent.m_options;
352
353 if( aOptions.lockedItems )
355
356 if( aOptions.symbols )
358
359 if( aOptions.text )
361
362 if( aOptions.wires )
364
365 if( aOptions.labels )
367
368 if( aOptions.pins )
370
371 if( aOptions.graphics )
373
374 if( aOptions.images )
376
377 if( aOptions.ruleAreas )
379
380 if( aOptions.otherItems )
382
383 // Restarting a running timer on every event would stall the fade
384 if( !m_flashCounters.empty() && !m_flashTimer.IsRunning() )
385 m_flashTimer.Start( 50 );
386}
PANEL_SCH_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)
bool setFilterFromCheckboxes(SCH_SELECTION_FILTER_OPTIONS &aOptions)
void OnFlashEvent(SCH_SELECTION_FILTER_EVENT &aEvent)
void OnLanguageChanged(wxCommandEvent &aEvent)
void SetCheckboxesFromFilter(SCH_SELECTION_FILTER_OPTIONS &aOptions)
void onRightClick(wxMouseEvent &aEvent)
void onPanelPaint(wxPaintEvent &aEvent)
void onFlashTimer(wxTimerEvent &aEvent)
void OnFilterChanged(wxCommandEvent &aEvent) override
std::map< wxCheckBox *, int > m_flashCounters
void onPopupSelection(wxCommandEvent &aEvent)
A shim class between EDA_DRAW_FRAME and several derived classes: SYMBOL_EDIT_FRAME,...
SCH_SELECTION_FILTER_OPTIONS m_options
void SetBorders(bool aLeft, bool aRight, bool aTop, bool aBottom)
Definition wx_panel.h:35
#define _(s)
@ FRAME_SCH_SYMBOL_EDITOR
Definition frame_type.h:31
KICOMMON_API wxFont GetInfoFont(wxWindow *aWindow)
wxDEFINE_EVENT(EVT_SCH_SELECTION_FILTER_FLASH, SCH_SELECTION_FILTER_EVENT)
std::vector< FAB_LAYER_COLOR > dummy
bool symbols
Allow selecting symbols and sheet symbols.
bool labels
Net and bus labels.
bool pins
Symbol and sheet pins.
bool graphics
Graphic lines, shapes, polygons.
bool lockedItems
Allow selecting locked items.
bool images
Bitmap/vector images.
bool otherItems
Anything not fitting one of the above categories.
bool wires
Net and bus wires and junctions.