mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-13 17:53:11 +02:00
ADDED: Indication of filter blocking
If the selection filter has blocked all selections under the cursor, show a subtle flash on which filter(s) did the blocking. Helpful for people getting frustrated by not being able to select locked items. Fixes https://gitlab.com/kicad/code/kicad/-/issues/20487
This commit is contained in:
parent
8a60893249
commit
e8cec41355
@ -35,6 +35,7 @@
|
||||
#include <project/project_file.h>
|
||||
#include <symbol_editor/symbol_editor_settings.h>
|
||||
#include <sch_draw_panel.h>
|
||||
#include <widgets/panel_sch_selection_filter.h>
|
||||
#include <sch_group.h>
|
||||
#include <sch_view.h>
|
||||
#include <sch_painter.h>
|
||||
@ -942,3 +943,10 @@ SCH_SELECTION_TOOL* SCH_BASE_FRAME::GetSelectionTool()
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void SCH_BASE_FRAME::HighlightSelectionFilter( const SCH_SELECTION_FILTER_OPTIONS& aOptions )
|
||||
{
|
||||
SCH_SELECTION_FILTER_EVENT evt( aOptions );
|
||||
wxPostEvent( this, evt );
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ class LIB_ID;
|
||||
class SYMBOL_LIB_TABLE;
|
||||
class EESCHEMA_SETTINGS;
|
||||
class SYMBOL_EDITOR_SETTINGS;
|
||||
struct SCH_SELECTION_FILTER_OPTIONS;
|
||||
|
||||
#ifndef __linux__
|
||||
class NL_SCHEMATIC_PLUGIN;
|
||||
@ -289,6 +290,8 @@ public:
|
||||
|
||||
void GetLibraryItemsForListDialog( wxArrayString& aHeaders, std::vector<wxArrayString>& aItemsToDisplay );
|
||||
|
||||
void HighlightSelectionFilter( const SCH_SELECTION_FILTER_OPTIONS& aOptions );
|
||||
|
||||
protected:
|
||||
void handleActivateEvent( wxActivateEvent& aEvent ) override;
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <sch_actions.h>
|
||||
#include <sch_collectors.h>
|
||||
#include <sch_selection_tool.h>
|
||||
#include <sch_base_frame.h>
|
||||
#include <eeschema_id.h>
|
||||
#include <symbol_edit_frame.h>
|
||||
#include <symbol_viewer_frame.h>
|
||||
@ -480,9 +481,13 @@ int SCH_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||
schframe->ClearFocus();
|
||||
|
||||
// Collect items at the clicked location (doesn't select them yet)
|
||||
SCH_COLLECTOR collector;
|
||||
SCH_COLLECTOR collector;
|
||||
SCH_SELECTION_FILTER_OPTIONS rejected;
|
||||
|
||||
CollectHits( collector, evt->Position() );
|
||||
narrowSelection( collector, evt->Position(), false );
|
||||
size_t preFilterCount = collector.GetCount();
|
||||
rejected.SetAll( false );
|
||||
narrowSelection( collector, evt->Position(), false, false, &rejected );
|
||||
|
||||
if( m_selection.GetSize() != 0 && dynamic_cast<SCH_TABLECELL*>( m_selection.GetItem( 0 ) ) && m_additive
|
||||
&& collector.GetCount() == 1 && dynamic_cast<SCH_TABLECELL*>( collector[0] ) )
|
||||
@ -564,6 +569,12 @@ int SCH_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||
|
||||
if( !selCancelled )
|
||||
{
|
||||
if( collector.GetCount() == 0 && preFilterCount > 0 )
|
||||
{
|
||||
if( SCH_BASE_FRAME* frame = dynamic_cast<SCH_BASE_FRAME*>( m_frame ) )
|
||||
frame->HighlightSelectionFilter( rejected );
|
||||
}
|
||||
|
||||
selectPoint( collector, evt->Position(), nullptr, nullptr, m_additive,
|
||||
m_subtractive, m_exclusive_or );
|
||||
m_selection.SetIsHover( false );
|
||||
@ -1028,7 +1039,7 @@ int SCH_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||
|
||||
if( CollectHits( collector, evt->Position() ) )
|
||||
{
|
||||
narrowSelection( collector, evt->Position(), false );
|
||||
narrowSelection( collector, evt->Position(), false, false, nullptr );
|
||||
|
||||
if( collector.GetCount() == 1 && !hasModifier() )
|
||||
{
|
||||
@ -1339,7 +1350,8 @@ bool SCH_SELECTION_TOOL::CollectHits( SCH_COLLECTOR& aCollector, const VECTOR2I&
|
||||
|
||||
|
||||
void SCH_SELECTION_TOOL::narrowSelection( SCH_COLLECTOR& collector, const VECTOR2I& aWhere,
|
||||
bool aCheckLocked, bool aSelectedOnly )
|
||||
bool aCheckLocked, bool aSelectedOnly,
|
||||
SCH_SELECTION_FILTER_OPTIONS* aRejected )
|
||||
{
|
||||
SYMBOL_EDIT_FRAME* symbolEditorFrame = dynamic_cast<SYMBOL_EDIT_FRAME*>( m_frame );
|
||||
|
||||
@ -1378,11 +1390,13 @@ void SCH_SELECTION_TOOL::narrowSelection( SCH_COLLECTOR& collector, const VECTOR
|
||||
|
||||
if( aCheckLocked && collector[i]->IsLocked() )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->lockedItems = true;
|
||||
collector.Remove( i );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !itemPassesFilter( collector[i] ) )
|
||||
if( !itemPassesFilter( collector[i], aRejected ) )
|
||||
{
|
||||
collector.Remove( i );
|
||||
continue;
|
||||
@ -1539,7 +1553,18 @@ bool SCH_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere,
|
||||
if( !CollectHits( collector, aWhere, aScanTypes ) )
|
||||
return false;
|
||||
|
||||
narrowSelection( collector, aWhere, aCheckLocked, aSubtract );
|
||||
size_t preFilterCount = collector.GetCount();
|
||||
SCH_SELECTION_FILTER_OPTIONS rejected;
|
||||
rejected.SetAll( false );
|
||||
narrowSelection( collector, aWhere, aCheckLocked, aSubtract, &rejected );
|
||||
|
||||
if( collector.GetCount() == 0 && preFilterCount > 0 )
|
||||
{
|
||||
if( SCH_BASE_FRAME* frame = dynamic_cast<SCH_BASE_FRAME*>( m_frame ) )
|
||||
frame->HighlightSelectionFilter( rejected );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return selectPoint( collector, aWhere, aItem, aSelectionCancelledFlag, aAdd, aSubtract,
|
||||
aExclusiveOr );
|
||||
@ -1589,7 +1614,7 @@ int SCH_SELECTION_TOOL::SelectAll( const TOOL_EVENT& aEvent )
|
||||
|
||||
for( EDA_ITEM* item : collection )
|
||||
{
|
||||
if( Selectable( item ) && itemPassesFilter( item ) )
|
||||
if( Selectable( item ) && itemPassesFilter( item, nullptr ) )
|
||||
{
|
||||
if( item->Type() == SCH_LINE_T )
|
||||
item->SetFlags( STARTPOINT | ENDPOINT );
|
||||
@ -1949,7 +1974,7 @@ void SCH_SELECTION_TOOL::filterCollectedItems( SCH_COLLECTOR& aCollector, bool a
|
||||
|
||||
for( EDA_ITEM* item : aCollector )
|
||||
{
|
||||
if( !itemPassesFilter( item ) )
|
||||
if( !itemPassesFilter( item, nullptr ) )
|
||||
rejected.insert( item );
|
||||
}
|
||||
|
||||
@ -1958,7 +1983,7 @@ void SCH_SELECTION_TOOL::filterCollectedItems( SCH_COLLECTOR& aCollector, bool a
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SELECTION_TOOL::itemPassesFilter( EDA_ITEM* aItem )
|
||||
bool SCH_SELECTION_TOOL::itemPassesFilter( EDA_ITEM* aItem, SCH_SELECTION_FILTER_OPTIONS* aRejected )
|
||||
{
|
||||
if( !aItem )
|
||||
return false;
|
||||
@ -1977,20 +2002,32 @@ bool SCH_SELECTION_TOOL::itemPassesFilter( EDA_ITEM* aItem )
|
||||
case SCH_SYMBOL_T:
|
||||
case SCH_SHEET_T:
|
||||
if( !m_filter.symbols )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->symbols = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SCH_PIN_T:
|
||||
case SCH_SHEET_PIN_T:
|
||||
if( !m_filter.pins )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->pins = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SCH_JUNCTION_T:
|
||||
if( !m_filter.wires )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->wires = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@ -2001,13 +2038,21 @@ bool SCH_SELECTION_TOOL::itemPassesFilter( EDA_ITEM* aItem )
|
||||
case LAYER_WIRE:
|
||||
case LAYER_BUS:
|
||||
if( !m_filter.wires )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->wires = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
if( !m_filter.graphics )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->graphics = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
@ -2015,7 +2060,11 @@ bool SCH_SELECTION_TOOL::itemPassesFilter( EDA_ITEM* aItem )
|
||||
|
||||
case SCH_SHAPE_T:
|
||||
if( !m_filter.graphics )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->graphics = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@ -2025,7 +2074,11 @@ bool SCH_SELECTION_TOOL::itemPassesFilter( EDA_ITEM* aItem )
|
||||
case SCH_TABLECELL_T:
|
||||
case SCH_FIELD_T:
|
||||
if( !m_filter.text )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->text = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@ -2033,25 +2086,41 @@ bool SCH_SELECTION_TOOL::itemPassesFilter( EDA_ITEM* aItem )
|
||||
case SCH_GLOBAL_LABEL_T:
|
||||
case SCH_HIER_LABEL_T:
|
||||
if( !m_filter.labels )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->labels = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SCH_BITMAP_T:
|
||||
if( !m_filter.images )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->images = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SCH_RULE_AREA_T:
|
||||
if( !m_filter.ruleAreas )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->ruleAreas = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
if( !m_filter.otherItems )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->otherItems = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
@ -2335,7 +2404,7 @@ bool SCH_SELECTION_TOOL::selectMultiple()
|
||||
if( m_frame->GetRenderSettings()->m_ShowPinsElectricalType )
|
||||
item->SetFlags( SHOW_ELEC_TYPE );
|
||||
|
||||
if( Selectable( item ) && itemPassesFilter( item ) && !item->GetParent()->HasFlag( SELECTION_CANDIDATE )
|
||||
if( Selectable( item ) && itemPassesFilter( item, nullptr ) && !item->GetParent()->HasFlag( SELECTION_CANDIDATE )
|
||||
&& item->HitTest( selectionRect, !isGreedy ) )
|
||||
{
|
||||
selectItem( item, 0 );
|
||||
|
@ -237,7 +237,8 @@ private:
|
||||
* @param aSelectedOnly If true, remove non-selected items from #collector
|
||||
*/
|
||||
void narrowSelection( SCH_COLLECTOR& collector, const VECTOR2I& aWhere, bool aCheckLocked,
|
||||
bool aSelectedOnly = false );
|
||||
bool aSelectedOnly = false,
|
||||
SCH_SELECTION_FILTER_OPTIONS* aRejected = nullptr );
|
||||
|
||||
/**
|
||||
* Perform a click-type selection at a point (usually the cursor position).
|
||||
@ -341,7 +342,7 @@ private:
|
||||
/**
|
||||
* Return true if the given item passes the stateful selection filter
|
||||
*/
|
||||
bool itemPassesFilter( EDA_ITEM* aItem );
|
||||
bool itemPassesFilter( EDA_ITEM* aItem, SCH_SELECTION_FILTER_OPTIONS* aRejected = nullptr );
|
||||
|
||||
/**
|
||||
* In general we don't want to select both a parent and any of it's children. This includes
|
||||
|
@ -23,8 +23,12 @@
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/sch_selection_tool.h>
|
||||
#include <widgets/panel_sch_selection_filter.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/dcbuffer.h>
|
||||
|
||||
|
||||
wxDEFINE_EVENT( EVT_SCH_SELECTION_FILTER_FLASH, SCH_SELECTION_FILTER_EVENT );
|
||||
|
||||
PANEL_SCH_SELECTION_FILTER::PANEL_SCH_SELECTION_FILTER( wxWindow* aParent ) :
|
||||
PANEL_SCH_SELECTION_FILTER_BASE( aParent ),
|
||||
m_frame( dynamic_cast<SCH_BASE_FRAME*>( aParent ) ),
|
||||
@ -83,12 +87,27 @@ PANEL_SCH_SELECTION_FILTER::PANEL_SCH_SELECTION_FILTER( wxWindow* aParent ) :
|
||||
}
|
||||
|
||||
m_frame->Bind( EDA_LANG_CHANGED, &PANEL_SCH_SELECTION_FILTER::OnLanguageChanged, this );
|
||||
|
||||
m_flashSteps = 10;
|
||||
m_defaultBg = GetBackgroundColour();
|
||||
m_flashTimer.SetOwner( this );
|
||||
Bind( wxEVT_TIMER, &PANEL_SCH_SELECTION_FILTER::onFlashTimer, this );
|
||||
aParent->Bind( EVT_SCH_SELECTION_FILTER_FLASH, &PANEL_SCH_SELECTION_FILTER::OnFlashEvent, this );
|
||||
}
|
||||
|
||||
|
||||
PANEL_SCH_SELECTION_FILTER::~PANEL_SCH_SELECTION_FILTER()
|
||||
{
|
||||
// Stop any active flashing
|
||||
m_flashTimer.Stop();
|
||||
if( !m_flashCounters.empty() )
|
||||
{
|
||||
Unbind( wxEVT_PAINT, &PANEL_SCH_SELECTION_FILTER::onPanelPaint, this );
|
||||
}
|
||||
m_flashCounters.clear();
|
||||
|
||||
m_frame->Unbind( EDA_LANG_CHANGED, &PANEL_SCH_SELECTION_FILTER::OnLanguageChanged, this );
|
||||
m_frame->Unbind( EVT_SCH_SELECTION_FILTER_FLASH, &PANEL_SCH_SELECTION_FILTER::OnFlashEvent, this );
|
||||
}
|
||||
|
||||
|
||||
@ -220,3 +239,127 @@ void PANEL_SCH_SELECTION_FILTER::OnLanguageChanged( wxCommandEvent& aEvent )
|
||||
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
|
||||
void PANEL_SCH_SELECTION_FILTER::flashCheckbox( wxCheckBox* aBox )
|
||||
{
|
||||
if( !aBox )
|
||||
return;
|
||||
|
||||
// If already flashing, just reset the counter
|
||||
if( m_flashCounters.find( aBox ) != m_flashCounters.end() )
|
||||
{
|
||||
m_flashCounters[aBox] = m_flashSteps;
|
||||
return;
|
||||
}
|
||||
|
||||
m_flashCounters[aBox] = m_flashSteps;
|
||||
m_defaultBg = aBox->GetBackgroundColour();
|
||||
|
||||
// Bind paint event to this panel if not already bound
|
||||
if( m_flashCounters.size() == 1 )
|
||||
{
|
||||
Bind( wxEVT_PAINT, &PANEL_SCH_SELECTION_FILTER::onPanelPaint, this );
|
||||
}
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
void PANEL_SCH_SELECTION_FILTER::onFlashTimer( wxTimerEvent& aEvent )
|
||||
{
|
||||
for( auto it = m_flashCounters.begin(); it != m_flashCounters.end(); )
|
||||
{
|
||||
int step = --( it->second );
|
||||
|
||||
if( step <= 0 )
|
||||
it = m_flashCounters.erase( it );
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
if( m_flashCounters.empty() )
|
||||
{
|
||||
m_flashTimer.Stop();
|
||||
// Unbind paint event when no more flashing
|
||||
Unbind( wxEVT_PAINT, &PANEL_SCH_SELECTION_FILTER::onPanelPaint, this );
|
||||
}
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
void PANEL_SCH_SELECTION_FILTER::onPanelPaint( wxPaintEvent& aEvent )
|
||||
{
|
||||
wxPaintDC dc( this );
|
||||
|
||||
// First, let the default painting happen
|
||||
aEvent.Skip();
|
||||
|
||||
// Then draw our highlights on top
|
||||
for( auto& pair : m_flashCounters )
|
||||
{
|
||||
wxCheckBox* checkbox = pair.first;
|
||||
int step = pair.second;
|
||||
|
||||
if( step > 0 )
|
||||
{
|
||||
// Get the checkbox position relative to this panel
|
||||
wxPoint checkboxPos = checkbox->GetPosition();
|
||||
wxSize checkboxSize = checkbox->GetSize();
|
||||
wxRect checkboxRect( checkboxPos, checkboxSize );
|
||||
|
||||
// Calculate blended color based on current flash step
|
||||
wxColour highlight = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT );
|
||||
wxColour blend(
|
||||
( highlight.Red() * step + m_defaultBg.Red() * ( m_flashSteps - step ) ) / m_flashSteps,
|
||||
( highlight.Green() * step + m_defaultBg.Green() * ( m_flashSteps - step ) ) / m_flashSteps,
|
||||
( highlight.Blue() * step + m_defaultBg.Blue() * ( m_flashSteps - step ) ) / m_flashSteps );
|
||||
|
||||
// Draw semi-transparent overlay
|
||||
wxColour overlayColor( blend.Red(), blend.Green(), blend.Blue(), 128 );
|
||||
dc.SetBrush( wxBrush( overlayColor ) );
|
||||
dc.SetPen( wxPen( overlayColor ) );
|
||||
dc.DrawRectangle( checkboxRect );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PANEL_SCH_SELECTION_FILTER::OnFlashEvent( SCH_SELECTION_FILTER_EVENT& aEvent )
|
||||
{
|
||||
const SCH_SELECTION_FILTER_OPTIONS& aOptions = aEvent.m_options;
|
||||
|
||||
if( aOptions.lockedItems )
|
||||
flashCheckbox( m_cbLockedItems );
|
||||
|
||||
if( aOptions.symbols )
|
||||
flashCheckbox( m_cbSymbols );
|
||||
|
||||
if( aOptions.text )
|
||||
flashCheckbox( m_cbText );
|
||||
|
||||
if( aOptions.wires )
|
||||
flashCheckbox( m_cbWires );
|
||||
|
||||
if( aOptions.labels )
|
||||
flashCheckbox( m_cbLabels );
|
||||
|
||||
if( aOptions.pins )
|
||||
flashCheckbox( m_cbPins );
|
||||
|
||||
if( aOptions.graphics )
|
||||
flashCheckbox( m_cbGraphics );
|
||||
|
||||
if( aOptions.images )
|
||||
flashCheckbox( m_cbImages );
|
||||
|
||||
if( aOptions.ruleAreas )
|
||||
flashCheckbox( m_cbRuleAreas );
|
||||
|
||||
if( aOptions.otherItems )
|
||||
flashCheckbox( m_cbOtherItems );
|
||||
|
||||
if( !m_flashCounters.empty() )
|
||||
m_flashTimer.Start( 50 );
|
||||
}
|
||||
|
@ -22,11 +22,31 @@
|
||||
#define KICAD_PANEL_SCH_SELECTION_FILTER_H
|
||||
|
||||
#include <widgets/panel_sch_selection_filter_base.h>
|
||||
#include <wx/timer.h>
|
||||
#include <map>
|
||||
|
||||
class SCH_BASE_FRAME;
|
||||
class SCH_SELECTION_TOOL;
|
||||
struct SCH_SELECTION_FILTER_OPTIONS;
|
||||
|
||||
// Forward declare the event type
|
||||
class SCH_SELECTION_FILTER_EVENT;
|
||||
wxDECLARE_EVENT( EVT_SCH_SELECTION_FILTER_FLASH, SCH_SELECTION_FILTER_EVENT );
|
||||
|
||||
class SCH_SELECTION_FILTER_EVENT : public wxCommandEvent
|
||||
{
|
||||
public:
|
||||
SCH_SELECTION_FILTER_EVENT( const SCH_SELECTION_FILTER_OPTIONS& aOptions = SCH_SELECTION_FILTER_OPTIONS(), int id = 0 ) :
|
||||
wxCommandEvent( EVT_SCH_SELECTION_FILTER_FLASH, id ), m_options( aOptions ) {}
|
||||
|
||||
wxEvent* Clone() const override
|
||||
{
|
||||
return new SCH_SELECTION_FILTER_EVENT( *this );
|
||||
}
|
||||
|
||||
SCH_SELECTION_FILTER_OPTIONS m_options;
|
||||
};
|
||||
|
||||
|
||||
class PANEL_SCH_SELECTION_FILTER : public PANEL_SCH_SELECTION_FILTER_BASE
|
||||
{
|
||||
@ -48,10 +68,19 @@ private:
|
||||
|
||||
void onPopupSelection( wxCommandEvent& aEvent );
|
||||
|
||||
void flashCheckbox( wxCheckBox* aBox );
|
||||
void onFlashTimer( wxTimerEvent& aEvent );
|
||||
void OnFlashEvent( SCH_SELECTION_FILTER_EVENT& aEvent );
|
||||
void onPanelPaint( wxPaintEvent& aEvent );
|
||||
|
||||
private:
|
||||
SCH_BASE_FRAME* m_frame;
|
||||
SCH_SELECTION_TOOL* m_tool;
|
||||
wxCheckBox* m_onlyCheckbox;
|
||||
SCH_BASE_FRAME* m_frame;
|
||||
SCH_SELECTION_TOOL* m_tool;
|
||||
wxCheckBox* m_onlyCheckbox;
|
||||
std::map<wxCheckBox*, int> m_flashCounters;
|
||||
wxTimer m_flashTimer;
|
||||
int m_flashSteps;
|
||||
wxColour m_defaultBg;
|
||||
};
|
||||
|
||||
#endif //KICAD_PANEL_SCH_SELECTION_FILTER_H
|
||||
|
@ -86,6 +86,21 @@ struct KICOMMON_API PCB_SELECTION_FILTER_OPTIONS
|
||||
return ( footprints && text && tracks && vias && pads && graphics && zones
|
||||
&& keepouts && dimensions && otherItems );
|
||||
}
|
||||
|
||||
void SetAll( bool aState )
|
||||
{
|
||||
footprints = aState;
|
||||
text = aState;
|
||||
tracks = aState;
|
||||
vias = aState;
|
||||
pads = aState;
|
||||
graphics = aState;
|
||||
zones = aState;
|
||||
keepouts = aState;
|
||||
dimensions = aState;
|
||||
otherItems = aState;
|
||||
lockedItems = aState;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -77,6 +77,20 @@ struct SCH_SELECTION_FILTER_OPTIONS
|
||||
ruleAreas = true;
|
||||
otherItems = true;
|
||||
}
|
||||
|
||||
void SetAll( bool aState )
|
||||
{
|
||||
lockedItems = aState;
|
||||
symbols = aState;
|
||||
text = aState;
|
||||
wires = aState;
|
||||
labels = aState;
|
||||
pins = aState;
|
||||
graphics = aState;
|
||||
images = aState;
|
||||
ruleAreas = aState;
|
||||
otherItems = aState;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //KICAD_SCH_PROJECT_SETTINGS_H
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/pcb_actions.h>
|
||||
#include <tools/pcb_selection_tool.h>
|
||||
#include <widgets/panel_selection_filter.h>
|
||||
#include <pgm_base.h>
|
||||
#include <board.h>
|
||||
#include <board_design_settings.h>
|
||||
@ -406,3 +407,10 @@ void PCB_BASE_EDIT_FRAME::configureToolbars()
|
||||
|
||||
RegisterCustomToolbarControlFactory( ACTION_TOOLBAR_CONTROLS::layerSelector, layerSelectorFactory );
|
||||
}
|
||||
|
||||
|
||||
void PCB_BASE_EDIT_FRAME::HighlightSelectionFilter( const PCB_SELECTION_FILTER_OPTIONS& aOptions )
|
||||
{
|
||||
PCB_SELECTION_FILTER_EVENT evt( aOptions );
|
||||
wxPostEvent( this, evt );
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ class PCB_TABLE;
|
||||
class PCB_TEXT;
|
||||
class PCB_SHAPE;
|
||||
class FILEDLG_HOOK_NEW_LIBRARY;
|
||||
struct PCB_SELECTION_FILTER_OPTIONS;
|
||||
|
||||
/**
|
||||
* Common, abstract interface for edit frames.
|
||||
@ -245,6 +246,8 @@ public:
|
||||
void GetContextualTextVars( BOARD_ITEM* aSourceItem, const wxString& aCrossRef,
|
||||
wxArrayString* aTokens );
|
||||
|
||||
void HighlightSelectionFilter( const PCB_SELECTION_FILTER_OPTIONS& aOptions );
|
||||
|
||||
protected:
|
||||
void configureToolbars() override;
|
||||
|
||||
|
@ -1806,7 +1806,7 @@ int BOARD_INSPECTION_TOOL::HighlightItem( const TOOL_EVENT& aEvent )
|
||||
bool saved = filter.lockedItems;
|
||||
filter.lockedItems = true;
|
||||
|
||||
selectionTool->FilterCollectedItems( collector, true );
|
||||
selectionTool->FilterCollectedItems( collector, true, nullptr );
|
||||
|
||||
filter.lockedItems = saved;
|
||||
|
||||
|
@ -879,7 +879,7 @@ int PCB_CONTROL::InteractiveDelete( const TOOL_EVENT& aEvent )
|
||||
}
|
||||
|
||||
selectionTool->FilterCollectorForHierarchy( collector, false );
|
||||
selectionTool->FilterCollectedItems( collector, false );
|
||||
selectionTool->FilterCollectedItems( collector, false, nullptr );
|
||||
|
||||
if( collector.GetCount() > 1 )
|
||||
selectionTool->GuessSelectionCandidates( collector, aPos );
|
||||
|
@ -38,6 +38,7 @@ using namespace std::placeholders;
|
||||
#include <pcb_tablecell.h>
|
||||
#include <pcb_marker.h>
|
||||
#include <pcb_generator.h>
|
||||
#include <pcb_base_edit_frame.h>
|
||||
#include <zone.h>
|
||||
#include <collectors.h>
|
||||
#include <dialog_filter_selection.h>
|
||||
@ -769,8 +770,20 @@ bool PCB_SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag, bool
|
||||
|
||||
m_selection.ClearReferencePoint();
|
||||
|
||||
size_t preFilterCount = collector.GetCount();
|
||||
PCB_SELECTION_FILTER_OPTIONS rejected;
|
||||
rejected.SetAll( false );
|
||||
|
||||
// Apply the stateful filter (remove items disabled by the Selection Filter)
|
||||
FilterCollectedItems( collector, false );
|
||||
FilterCollectedItems( collector, false, &rejected );
|
||||
|
||||
if( collector.GetCount() == 0 && preFilterCount > 0 )
|
||||
{
|
||||
if( PCB_BASE_EDIT_FRAME* editFrame = dynamic_cast<PCB_BASE_EDIT_FRAME*>( m_frame ) )
|
||||
editFrame->HighlightSelectionFilter( rejected );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allow the client to do tool- or action-specific filtering to see if we can get down
|
||||
// to a single item
|
||||
@ -1288,7 +1301,7 @@ void PCB_SELECTION_TOOL::SelectMultiple( KIGFX::PREVIEW::SELECTION_AREA& aArea,
|
||||
}
|
||||
|
||||
// Apply the stateful filter
|
||||
FilterCollectedItems( collector, true );
|
||||
FilterCollectedItems( collector, true, nullptr );
|
||||
|
||||
FilterCollectorForHierarchy( collector, true );
|
||||
|
||||
@ -1296,7 +1309,7 @@ void PCB_SELECTION_TOOL::SelectMultiple( KIGFX::PREVIEW::SELECTION_AREA& aArea,
|
||||
if( collector.GetCount() == 0 )
|
||||
{
|
||||
collector = padsCollector;
|
||||
FilterCollectedItems( collector, true );
|
||||
FilterCollectedItems( collector, true, nullptr );
|
||||
FilterCollectorForHierarchy( collector, true );
|
||||
}
|
||||
|
||||
@ -1390,7 +1403,7 @@ int PCB_SELECTION_TOOL::SelectAll( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( viewItem );
|
||||
|
||||
if( item && Selectable( item ) && itemPassesFilter( item, true ) )
|
||||
if( item && Selectable( item ) && itemPassesFilter( item, true, nullptr ) )
|
||||
collection.Append( item );
|
||||
}
|
||||
|
||||
@ -2114,7 +2127,7 @@ void PCB_SELECTION_TOOL::SelectAllItemsOnNet( int aNetCode, bool aSelect )
|
||||
PCB_VIA_T,
|
||||
PCB_SHAPE_T } ) )
|
||||
{
|
||||
if( itemPassesFilter( item, true ) )
|
||||
if( itemPassesFilter( item, true, nullptr ) )
|
||||
aSelect ? select( item ) : unselect( item );
|
||||
}
|
||||
}
|
||||
@ -2719,7 +2732,8 @@ int PCB_SELECTION_TOOL::filterSelection( const TOOL_EVENT& aEvent )
|
||||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::FilterCollectedItems( GENERAL_COLLECTOR& aCollector, bool aMultiSelect )
|
||||
void PCB_SELECTION_TOOL::FilterCollectedItems( GENERAL_COLLECTOR& aCollector, bool aMultiSelect,
|
||||
PCB_SELECTION_FILTER_OPTIONS* aRejected )
|
||||
{
|
||||
if( aCollector.GetCount() == 0 )
|
||||
return;
|
||||
@ -2733,7 +2747,7 @@ void PCB_SELECTION_TOOL::FilterCollectedItems( GENERAL_COLLECTOR& aCollector, bo
|
||||
|
||||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( i );
|
||||
|
||||
if( !itemPassesFilter( item, aMultiSelect ) )
|
||||
if( !itemPassesFilter( item, aMultiSelect, aRejected ) )
|
||||
rejected.insert( item );
|
||||
}
|
||||
|
||||
@ -2742,7 +2756,8 @@ void PCB_SELECTION_TOOL::FilterCollectedItems( GENERAL_COLLECTOR& aCollector, bo
|
||||
}
|
||||
|
||||
|
||||
bool PCB_SELECTION_TOOL::itemPassesFilter( BOARD_ITEM* aItem, bool aMultiSelect )
|
||||
bool PCB_SELECTION_TOOL::itemPassesFilter( BOARD_ITEM* aItem, bool aMultiSelect,
|
||||
PCB_SELECTION_FILTER_OPTIONS* aRejected )
|
||||
{
|
||||
if( !m_filter.lockedItems )
|
||||
{
|
||||
@ -2755,6 +2770,8 @@ bool PCB_SELECTION_TOOL::itemPassesFilter( BOARD_ITEM* aItem, bool aMultiSelect
|
||||
}
|
||||
else
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->lockedItems = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -2770,7 +2787,11 @@ bool PCB_SELECTION_TOOL::itemPassesFilter( BOARD_ITEM* aItem, bool aMultiSelect
|
||||
if( static_cast<PCB_GENERATOR*>( aItem )->GetItems().empty() )
|
||||
{
|
||||
if( !m_filter.otherItems )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->otherItems = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2782,26 +2803,42 @@ bool PCB_SELECTION_TOOL::itemPassesFilter( BOARD_ITEM* aItem, bool aMultiSelect
|
||||
{
|
||||
case PCB_FOOTPRINT_T:
|
||||
if( !m_filter.footprints )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->footprints = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case PCB_PAD_T:
|
||||
if( !m_filter.pads )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->pads = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case PCB_TRACE_T:
|
||||
case PCB_ARC_T:
|
||||
if( !m_filter.tracks )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->tracks = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case PCB_VIA_T:
|
||||
if( !m_filter.vias )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->vias = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@ -2812,6 +2849,13 @@ bool PCB_SELECTION_TOOL::itemPassesFilter( BOARD_ITEM* aItem, bool aMultiSelect
|
||||
if( ( !m_filter.zones && !zone->GetIsRuleArea() )
|
||||
|| ( !m_filter.keepouts && zone->GetIsRuleArea() ) )
|
||||
{
|
||||
if( aRejected )
|
||||
{
|
||||
if( zone->GetIsRuleArea() )
|
||||
aRejected->keepouts = true;
|
||||
else
|
||||
aRejected->zones = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2827,17 +2871,29 @@ bool PCB_SELECTION_TOOL::itemPassesFilter( BOARD_ITEM* aItem, bool aMultiSelect
|
||||
case PCB_SHAPE_T:
|
||||
case PCB_TARGET_T:
|
||||
if( !m_filter.graphics )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->graphics = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case PCB_REFERENCE_IMAGE_T:
|
||||
if( !m_filter.graphics )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->graphics = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// a reference image living in a footprint must not be selected inside the board editor
|
||||
if( !m_isFootprintEditor && aItem->GetParentFootprint() )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->text = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@ -2857,13 +2913,21 @@ bool PCB_SELECTION_TOOL::itemPassesFilter( BOARD_ITEM* aItem, bool aMultiSelect
|
||||
case PCB_DIM_ORTHOGONAL_T:
|
||||
case PCB_DIM_LEADER_T:
|
||||
if( !m_filter.dimensions )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->dimensions = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
if( !m_filter.otherItems )
|
||||
{
|
||||
if( aRejected )
|
||||
aRejected->otherItems = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -250,7 +250,8 @@ public:
|
||||
/**
|
||||
* Apply the SELECTION_FITLER_OPTIONS to the collector.
|
||||
*/
|
||||
void FilterCollectedItems( GENERAL_COLLECTOR& aCollector, bool aMultiSelect );
|
||||
void FilterCollectedItems( GENERAL_COLLECTOR& aCollector, bool aMultiSelect,
|
||||
PCB_SELECTION_FILTER_OPTIONS* aRejected = nullptr );
|
||||
|
||||
/**
|
||||
* Drop footprints that are not directly selected
|
||||
@ -426,7 +427,8 @@ private:
|
||||
int filterSelection( const TOOL_EVENT& aEvent );
|
||||
|
||||
///< Return true if the given item passes the current SELECTION_FILTER_OPTIONS.
|
||||
bool itemPassesFilter( BOARD_ITEM* aItem, bool aMultiSelect );
|
||||
bool itemPassesFilter( BOARD_ITEM* aItem, bool aMultiSelect,
|
||||
PCB_SELECTION_FILTER_OPTIONS* aRejected = nullptr );
|
||||
|
||||
/**
|
||||
* Take necessary action mark an item as unselected.
|
||||
|
@ -22,8 +22,12 @@
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/pcb_selection_tool.h>
|
||||
#include <widgets/panel_selection_filter.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/dcbuffer.h>
|
||||
|
||||
|
||||
wxDEFINE_EVENT( EVT_PCB_SELECTION_FILTER_FLASH, PCB_SELECTION_FILTER_EVENT );
|
||||
|
||||
PANEL_SELECTION_FILTER::PANEL_SELECTION_FILTER( wxWindow* aParent ) :
|
||||
PANEL_SELECTION_FILTER_BASE( aParent ),
|
||||
m_frame( dynamic_cast<PCB_BASE_EDIT_FRAME*>( aParent ) ),
|
||||
@ -66,12 +70,27 @@ PANEL_SELECTION_FILTER::PANEL_SELECTION_FILTER( wxWindow* aParent ) :
|
||||
m_frame->Bind( EDA_LANG_CHANGED, &PANEL_SELECTION_FILTER::OnLanguageChanged, this );
|
||||
|
||||
SetMinSize( GetBestSize() );
|
||||
|
||||
m_flashSteps = 10;
|
||||
m_defaultBg = GetBackgroundColour();
|
||||
m_flashTimer.SetOwner( this );
|
||||
Bind( wxEVT_TIMER, &PANEL_SELECTION_FILTER::onFlashTimer, this );
|
||||
aParent->Bind( EVT_PCB_SELECTION_FILTER_FLASH, &PANEL_SELECTION_FILTER::OnFlashEvent, this );
|
||||
}
|
||||
|
||||
|
||||
PANEL_SELECTION_FILTER::~PANEL_SELECTION_FILTER()
|
||||
{
|
||||
// Stop any active flashing
|
||||
m_flashTimer.Stop();
|
||||
if( !m_flashCounters.empty() )
|
||||
{
|
||||
Unbind( wxEVT_PAINT, &PANEL_SELECTION_FILTER::onPanelPaint, this );
|
||||
}
|
||||
m_flashCounters.clear();
|
||||
|
||||
m_frame->Unbind( EDA_LANG_CHANGED, &PANEL_SELECTION_FILTER::OnLanguageChanged, this );
|
||||
m_frame->Unbind( EVT_PCB_SELECTION_FILTER_FLASH, &PANEL_SELECTION_FILTER::OnFlashEvent, this );
|
||||
}
|
||||
|
||||
|
||||
@ -208,3 +227,130 @@ void PANEL_SELECTION_FILTER::OnLanguageChanged( wxCommandEvent& aEvent )
|
||||
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
|
||||
void PANEL_SELECTION_FILTER::flashCheckbox( wxCheckBox* aBox )
|
||||
{
|
||||
if( !aBox )
|
||||
return;
|
||||
|
||||
// If already flashing, just reset the counter
|
||||
if( m_flashCounters.find( aBox ) != m_flashCounters.end() )
|
||||
{
|
||||
m_flashCounters[aBox] = m_flashSteps;
|
||||
return;
|
||||
}
|
||||
|
||||
m_flashCounters[aBox] = m_flashSteps;
|
||||
m_defaultBg = aBox->GetBackgroundColour();
|
||||
|
||||
// Bind paint event to this panel if not already bound
|
||||
if( m_flashCounters.size() == 1 )
|
||||
{
|
||||
Bind( wxEVT_PAINT, &PANEL_SELECTION_FILTER::onPanelPaint, this );
|
||||
}
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
void PANEL_SELECTION_FILTER::onFlashTimer( wxTimerEvent& aEvent )
|
||||
{
|
||||
for( auto it = m_flashCounters.begin(); it != m_flashCounters.end(); )
|
||||
{
|
||||
int step = --( it->second );
|
||||
|
||||
if( step <= 0 )
|
||||
it = m_flashCounters.erase( it );
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
if( m_flashCounters.empty() )
|
||||
{
|
||||
m_flashTimer.Stop();
|
||||
// Unbind paint event when no more flashing
|
||||
Unbind( wxEVT_PAINT, &PANEL_SELECTION_FILTER::onPanelPaint, this );
|
||||
}
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
void PANEL_SELECTION_FILTER::onPanelPaint( wxPaintEvent& aEvent )
|
||||
{
|
||||
wxPaintDC dc( this );
|
||||
|
||||
// First, let the default painting happen
|
||||
aEvent.Skip();
|
||||
|
||||
// Then draw our highlights on top
|
||||
for( auto& pair : m_flashCounters )
|
||||
{
|
||||
wxCheckBox* checkbox = pair.first;
|
||||
int step = pair.second;
|
||||
|
||||
if( step > 0 )
|
||||
{
|
||||
// Get the checkbox position relative to this panel
|
||||
wxPoint checkboxPos = checkbox->GetPosition();
|
||||
wxSize checkboxSize = checkbox->GetSize();
|
||||
wxRect checkboxRect( checkboxPos, checkboxSize );
|
||||
|
||||
// Calculate blended color based on current flash step
|
||||
wxColour highlight = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT );
|
||||
wxColour blend(
|
||||
( highlight.Red() * step + m_defaultBg.Red() * ( m_flashSteps - step ) ) / m_flashSteps,
|
||||
( highlight.Green() * step + m_defaultBg.Green() * ( m_flashSteps - step ) ) / m_flashSteps,
|
||||
( highlight.Blue() * step + m_defaultBg.Blue() * ( m_flashSteps - step ) ) / m_flashSteps );
|
||||
|
||||
// Draw semi-transparent overlay
|
||||
wxColour overlayColor( blend.Red(), blend.Green(), blend.Blue(), 128 );
|
||||
dc.SetBrush( wxBrush( overlayColor ) );
|
||||
dc.SetPen( wxPen( overlayColor ) );
|
||||
dc.DrawRectangle( checkboxRect );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PANEL_SELECTION_FILTER::OnFlashEvent( PCB_SELECTION_FILTER_EVENT& aEvent )
|
||||
{
|
||||
const PCB_SELECTION_FILTER_OPTIONS& aOptions = aEvent.m_options;
|
||||
|
||||
if( aOptions.lockedItems )
|
||||
flashCheckbox( m_cbLockedItems );
|
||||
|
||||
if( aOptions.footprints )
|
||||
flashCheckbox( m_cbFootprints );
|
||||
|
||||
if( aOptions.text )
|
||||
flashCheckbox( m_cbText );
|
||||
|
||||
if( aOptions.tracks )
|
||||
flashCheckbox( m_cbTracks );
|
||||
|
||||
if( aOptions.vias )
|
||||
flashCheckbox( m_cbVias );
|
||||
|
||||
if( aOptions.pads )
|
||||
flashCheckbox( m_cbPads );
|
||||
|
||||
if( aOptions.graphics )
|
||||
flashCheckbox( m_cbGraphics );
|
||||
|
||||
if( aOptions.zones )
|
||||
flashCheckbox( m_cbZones );
|
||||
|
||||
if( aOptions.keepouts )
|
||||
flashCheckbox( m_cbKeepouts );
|
||||
|
||||
if( aOptions.dimensions )
|
||||
flashCheckbox( m_cbDimensions );
|
||||
|
||||
if( aOptions.otherItems )
|
||||
flashCheckbox( m_cbOtherItems );
|
||||
|
||||
if( !m_flashCounters.empty() )
|
||||
m_flashTimer.Start( 50 );
|
||||
}
|
||||
|
@ -22,11 +22,31 @@
|
||||
#define KICAD_PANEL_SELECTION_FILTER_H
|
||||
|
||||
#include <widgets/panel_selection_filter_base.h>
|
||||
#include <wx/timer.h>
|
||||
#include <map>
|
||||
|
||||
|
||||
class PCB_SELECTION_TOOL;
|
||||
struct PCB_SELECTION_FILTER_OPTIONS;
|
||||
|
||||
// Forward declare the event type
|
||||
class PCB_SELECTION_FILTER_EVENT;
|
||||
wxDECLARE_EVENT( EVT_PCB_SELECTION_FILTER_FLASH, PCB_SELECTION_FILTER_EVENT );
|
||||
|
||||
class PCB_SELECTION_FILTER_EVENT : public wxCommandEvent
|
||||
{
|
||||
public:
|
||||
PCB_SELECTION_FILTER_EVENT( const PCB_SELECTION_FILTER_OPTIONS& aOptions = PCB_SELECTION_FILTER_OPTIONS(), int id = 0 ) :
|
||||
wxCommandEvent( EVT_PCB_SELECTION_FILTER_FLASH, id ), m_options( aOptions ) {}
|
||||
|
||||
wxEvent* Clone() const override
|
||||
{
|
||||
return new PCB_SELECTION_FILTER_EVENT( *this );
|
||||
}
|
||||
|
||||
PCB_SELECTION_FILTER_OPTIONS m_options;
|
||||
};
|
||||
|
||||
|
||||
class PANEL_SELECTION_FILTER : public PANEL_SELECTION_FILTER_BASE
|
||||
{
|
||||
@ -48,10 +68,19 @@ private:
|
||||
|
||||
void onPopupSelection( wxCommandEvent& aEvent );
|
||||
|
||||
void flashCheckbox( wxCheckBox* aBox );
|
||||
void onFlashTimer( wxTimerEvent& aEvent );
|
||||
void OnFlashEvent( PCB_SELECTION_FILTER_EVENT& aEvent );
|
||||
void onPanelPaint( wxPaintEvent& aEvent );
|
||||
|
||||
private:
|
||||
PCB_BASE_EDIT_FRAME* m_frame;
|
||||
PCB_SELECTION_TOOL* m_tool;
|
||||
wxCheckBox* m_onlyCheckbox;
|
||||
PCB_BASE_EDIT_FRAME* m_frame;
|
||||
PCB_SELECTION_TOOL* m_tool;
|
||||
wxCheckBox* m_onlyCheckbox;
|
||||
std::map<wxCheckBox*, int> m_flashCounters;
|
||||
wxTimer m_flashTimer;
|
||||
int m_flashSteps;
|
||||
wxColour m_defaultBg;
|
||||
};
|
||||
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <dialog_find.h>
|
||||
#include <dialog_filter_selection.h>
|
||||
#include <zone_filler.h>
|
||||
struct PCB_SELECTION_FILTER_OPTIONS;
|
||||
#include <preview_items/selection_area.h>
|
||||
|
||||
FP_LIB_TABLE GFootprintTable;
|
||||
@ -360,12 +361,14 @@ int PCB_SELECTION_TOOL::filterSelection( const TOOL_EVENT& aEvent )
|
||||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::FilterCollectedItems( GENERAL_COLLECTOR& aCollector, bool aMultiSelect )
|
||||
void PCB_SELECTION_TOOL::FilterCollectedItems( GENERAL_COLLECTOR& aCollector, bool aMultiSelect,
|
||||
PCB_SELECTION_FILTER_OPTIONS* aRejected )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool PCB_SELECTION_TOOL::itemPassesFilter( BOARD_ITEM* aItem, bool aMultiSelect )
|
||||
bool PCB_SELECTION_TOOL::itemPassesFilter( BOARD_ITEM* aItem, bool aMultiSelect,
|
||||
PCB_SELECTION_FILTER_OPTIONS* aRejected )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user