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 along
18 * with this program. If not, see <http://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_defaultBg = GetBackgroundColour();
93 m_flashTimer.SetOwner( this );
94 Bind( wxEVT_TIMER, &PANEL_SCH_SELECTION_FILTER::onFlashTimer, this );
95 aParent->Bind( EVT_SCH_SELECTION_FILTER_FLASH, &PANEL_SCH_SELECTION_FILTER::OnFlashEvent, this );
96}
97
98
100{
101 // Stop any active flashing
102 m_flashTimer.Stop();
103 if( !m_flashCounters.empty() )
104 {
105 Unbind( wxEVT_PAINT, &PANEL_SCH_SELECTION_FILTER::onPanelPaint, this );
106 }
107 m_flashCounters.clear();
108
109 m_frame->Unbind( EDA_LANG_CHANGED, &PANEL_SCH_SELECTION_FILTER::OnLanguageChanged, this );
110 m_frame->Unbind( EVT_SCH_SELECTION_FILTER_FLASH, &PANEL_SCH_SELECTION_FILTER::OnFlashEvent, this );
111}
112
113
115{
116 Freeze();
117
118 m_cbLockedItems->SetValue( aOptions.lockedItems );
119 m_cbSymbols->SetValue( aOptions.symbols );
120 m_cbText->SetValue( aOptions.text );
121 m_cbWires->SetValue( aOptions.wires );
122 m_cbLabels->SetValue( aOptions.labels );
123 m_cbPins->SetValue( aOptions.pins );
124 m_cbGraphics->SetValue( aOptions.graphics );
125 m_cbImages->SetValue( aOptions.images );
126 m_cbRuleAreas->SetValue( aOptions.ruleAreas );
127 m_cbOtherItems->SetValue( aOptions.otherItems );
128
129 m_cbAllItems->SetValue( aOptions.All() );
130
131 Thaw();
132}
133
134
136{
137 if( aEvent.GetEventObject() == m_cbAllItems )
138 {
139 bool newState = m_cbAllItems->GetValue();
140
141 m_cbSymbols->SetValue( newState );
142 m_cbText->SetValue( newState );
143 m_cbWires->SetValue( newState );
144 m_cbLabels->SetValue( newState );
145 m_cbPins->SetValue( newState );
146 m_cbGraphics->SetValue( newState );
147 m_cbImages->SetValue( newState );
148 m_cbRuleAreas->SetValue( newState );
149 m_cbOtherItems->SetValue( newState );
150 }
151
152 SCH_SELECTION_FILTER_OPTIONS& opts = m_tool->GetFilter();
153
154 // If any of the other checkboxes turned off, turn off the All Items checkbox
155 bool allChecked = setFilterFromCheckboxes( opts );
156 m_cbAllItems->SetValue( allChecked );
157}
158
159
161{
162 aOptions.lockedItems = m_cbLockedItems->GetValue();
163 aOptions.symbols = m_cbSymbols->GetValue();
164 aOptions.text = m_cbText->GetValue();
165 aOptions.wires = m_cbWires->GetValue();
166 aOptions.labels = m_cbLabels->GetValue();
167 aOptions.pins = m_cbPins->GetValue();
168 aOptions.graphics = m_cbGraphics->GetValue();
169 aOptions.images = m_cbImages->GetValue();
170 aOptions.ruleAreas = m_cbRuleAreas->GetValue();
171 aOptions.otherItems = m_cbOtherItems->GetValue();
172
173 return aOptions.All();
174}
175
176
178{
179 wxMenu menu;
180
181 wxCheckBox* cb = dynamic_cast<wxCheckBox*>( aEvent.GetEventObject() );
182
183 if( !cb )
184 return;
185
186 m_onlyCheckbox = cb;
187
188 wxString label;
189 label.Printf( _( "Only %s" ), cb->GetLabel().Lower() );
190
191 menu.Append( new wxMenuItem( &menu, wxID_ANY, label, wxEmptyString, wxITEM_NORMAL ) );
192
193 menu.Bind( wxEVT_COMMAND_MENU_SELECTED, &PANEL_SCH_SELECTION_FILTER::onPopupSelection, this );
194
195 PopupMenu( &menu );
196}
197
198
200{
201 if( !m_onlyCheckbox )
202 return;
203
204 m_cbAllItems->SetValue( false );
205 m_cbSymbols->SetValue( false );
206 m_cbText->SetValue( false );
207 m_cbWires->SetValue( false );
208 m_cbLabels->SetValue( false );
209 m_cbPins->SetValue( false );
210 m_cbGraphics->SetValue( false );
211 m_cbImages->SetValue( false );
212 m_cbOtherItems->SetValue( false );
213 m_cbRuleAreas->SetValue( false );
214
215 m_onlyCheckbox->SetValue( true );
216 m_onlyCheckbox = nullptr;
217
218 wxCommandEvent dummy;
220}
221
222
224{
225 m_cbAllItems->SetLabel( _( "All items" ) );
226 m_cbLockedItems->SetLabel( _( "Locked items" ) );
227 m_cbLockedItems->SetToolTip( _( "Allow selection of locked items" ) );
228 m_cbSymbols->SetLabel( _( "Symbols" ) );
229 m_cbText->SetLabel( _( "Text" ) );
230 m_cbWires->SetLabel( _( "Wires" ) );
231 m_cbLabels->SetLabel( _( "Labels" ) );
232 m_cbPins->SetLabel( _( "Pins" ) );
233 m_cbGraphics->SetLabel( _( "Graphics" ) );
234 m_cbImages->SetLabel( _( "Images" ) );
235 m_cbRuleAreas->SetLabel( _( "Rule Areas" ) );
236 m_cbOtherItems->SetLabel( _( "Other items" ) );
237
238 m_cbAllItems->GetParent()->Layout();
239
240 aEvent.Skip();
241}
242
243
245{
246 if( !aBox )
247 return;
248
249 // If already flashing, just reset the counter
250 if( m_flashCounters.find( aBox ) != m_flashCounters.end() )
251 {
253 return;
254 }
255
257 m_defaultBg = aBox->GetBackgroundColour();
258
259 // Bind paint event to this panel if not already bound
260 if( m_flashCounters.size() == 1 )
261 {
262 Bind( wxEVT_PAINT, &PANEL_SCH_SELECTION_FILTER::onPanelPaint, this );
263 }
264
265 Refresh();
266}
267
268
270{
271 for( auto it = m_flashCounters.begin(); it != m_flashCounters.end(); )
272 {
273 int step = --( it->second );
274
275 if( step <= 0 )
276 it = m_flashCounters.erase( it );
277 else
278 ++it;
279 }
280
281 if( m_flashCounters.empty() )
282 {
283 m_flashTimer.Stop();
284 // Unbind paint event when no more flashing
285 Unbind( wxEVT_PAINT, &PANEL_SCH_SELECTION_FILTER::onPanelPaint, this );
286 }
287
288 Refresh();
289}
290
291
293{
294 wxPaintDC dc( this );
295
296 // First, let the default painting happen
297 aEvent.Skip();
298
299 // Then draw our highlights on top
300 for( auto& pair : m_flashCounters )
301 {
302 wxCheckBox* checkbox = pair.first;
303 int step = pair.second;
304
305 if( step > 0 )
306 {
307 // Get the checkbox position relative to this panel
308 wxPoint checkboxPos = checkbox->GetPosition();
309 wxSize checkboxSize = checkbox->GetSize();
310 wxRect checkboxRect( checkboxPos, checkboxSize );
311
312 // Calculate blended color based on current flash step
313 wxColour highlight = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT );
314 wxColour blend(
315 ( highlight.Red() * step + m_defaultBg.Red() * ( m_flashSteps - step ) ) / m_flashSteps,
316 ( highlight.Green() * step + m_defaultBg.Green() * ( m_flashSteps - step ) ) / m_flashSteps,
317 ( highlight.Blue() * step + m_defaultBg.Blue() * ( m_flashSteps - step ) ) / m_flashSteps );
318
319 // Draw semi-transparent overlay
320 wxColour overlayColor( blend.Red(), blend.Green(), blend.Blue(), 128 );
321 dc.SetBrush( wxBrush( overlayColor ) );
322 dc.SetPen( wxPen( overlayColor ) );
323 dc.DrawRectangle( checkboxRect );
324 }
325 }
326}
327
328
330{
331 const SCH_SELECTION_FILTER_OPTIONS& aOptions = aEvent.m_options;
332
333 if( aOptions.lockedItems )
335
336 if( aOptions.symbols )
338
339 if( aOptions.text )
341
342 if( aOptions.wires )
344
345 if( aOptions.labels )
347
348 if( aOptions.pins )
350
351 if( aOptions.graphics )
353
354 if( aOptions.images )
356
357 if( aOptions.ruleAreas )
359
360 if( aOptions.otherItems )
362
363 if( !m_flashCounters.empty() )
364 m_flashTimer.Start( 50 );
365}
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:39
#define _(s)
@ FRAME_SCH_SYMBOL_EDITOR
Definition frame_type.h:35
KICOMMON_API wxFont GetInfoFont(wxWindow *aWindow)
wxDEFINE_EVENT(EVT_SCH_SELECTION_FILTER_FLASH, SCH_SELECTION_FILTER_EVENT)
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
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.