KiCad PCB EDA Suite
FOOTPRINT_CHOICE Class Reference

Customized combo box for footprint selection. More...

#include <footprint_choice.h>

Inheritance diagram for FOOTPRINT_CHOICE:

Public Member Functions

 FOOTPRINT_CHOICE (wxWindow *aParent, int aId)
 
virtual ~FOOTPRINT_CHOICE ()
 

Protected Member Functions

virtual void DoSetPopupControl (wxComboPopup *aPopup) override
 
virtual void OnDrawItem (wxDC &aDC, wxRect const &aRect, int aItem, int aFlags) const override
 
virtual wxCoord OnMeasureItem (size_t aItem) const override
 
virtual wxCoord OnMeasureItemWidth (size_t aItem) const override
 
void TryVetoMouse (wxMouseEvent &aEvent)
 Veto a mouseover event if in the separator. More...
 
void TryVetoSelect (wxCommandEvent &aEvent, bool aInner)
 Veto a select event for the separator. More...
 
void OnMouseUp (wxMouseEvent &aEvent)
 Mouse up on an item in the list. More...
 
void OnKeyUp (wxKeyEvent &aEvent)
 Key up on an item in the list. More...
 
void TrySkipSeparator (wxKeyEvent &aEvent, bool aInner)
 For arrow key events, skip over separators. More...
 
wxString SafeGetString (int aItem) const
 Safely get a string for an item, returning wxEmptyString if the item doesn't exist. More...
 
int GetSelectionEither (bool aInner) const
 Get selection from either the outer (combo box) or inner (popup) list. More...
 
void SetSelectionEither (bool aInner, int aSel)
 Safely set selection for either the outer (combo box) or inner (popup) list, doing nothing for invalid selections. More...
 

Static Protected Member Functions

static wxCoord DrawTextFragment (wxDC &aDC, wxCoord x, wxCoord y, wxString const &aText)
 Draw a fragment of text, then return the next x coordinate to continue drawing. More...
 

Static Protected Attributes

static wxColour m_grey
 

Private Attributes

int m_last_selection
 

Detailed Description

Customized combo box for footprint selection.

This provides the following features:

  • library name is greyed out for readability when lib:footprint format is found in the item text
  • empty items are displayed as nonselectable separators

Multiple separators in a row is undefined behavior; it is likely to result in errors such as the ability to select separators. Separators ARE valid at the top and bottom.

For any items containing footprints, the "lib:footprint" name should be attached to the item as a wxStringClientData.

Definition at line 46 of file footprint_choice.h.

Constructor & Destructor Documentation

FOOTPRINT_CHOICE::FOOTPRINT_CHOICE ( wxWindow *  aParent,
int  aId 
)

Definition at line 31 of file footprint_choice.cpp.

32  : wxOwnerDrawnComboBox( aParent, aId, wxEmptyString, wxDefaultPosition, wxDefaultSize,
33  /* n */ 0, /* choices */ nullptr, wxCB_READONLY ),
34  m_last_selection( 0 )
35 {
36 }
FOOTPRINT_CHOICE::~FOOTPRINT_CHOICE ( )
virtual

Definition at line 39 of file footprint_choice.cpp.

40 {
41 }

Member Function Documentation

void FOOTPRINT_CHOICE::DoSetPopupControl ( wxComboPopup *  aPopup)
overrideprotectedvirtual

Definition at line 44 of file footprint_choice.cpp.

References OnKeyUp(), OnMouseUp(), TrySkipSeparator(), TryVetoMouse(), and TryVetoSelect().

45 {
46  using namespace std::placeholders;
47  wxOwnerDrawnComboBox::DoSetPopupControl( aPopup );
48 
49  // Bind events to intercept selections, so the separator can be made nonselectable.
50 
51  GetVListBoxComboPopup()->Bind( wxEVT_MOTION, &FOOTPRINT_CHOICE::TryVetoMouse, this );
52  GetVListBoxComboPopup()->Bind( wxEVT_LEFT_DOWN, &FOOTPRINT_CHOICE::TryVetoMouse, this );
53  GetVListBoxComboPopup()->Bind( wxEVT_LEFT_UP, &FOOTPRINT_CHOICE::TryVetoMouse, this );
54  GetVListBoxComboPopup()->Bind( wxEVT_LEFT_UP, &FOOTPRINT_CHOICE::OnMouseUp, this );
55  GetVListBoxComboPopup()->Bind( wxEVT_LEFT_DCLICK, &FOOTPRINT_CHOICE::TryVetoMouse, this );
56  GetVListBoxComboPopup()->Bind(
57  wxEVT_LISTBOX, std::bind( &FOOTPRINT_CHOICE::TryVetoSelect, this, _1, true ) );
58  Bind( wxEVT_COMBOBOX, std::bind( &FOOTPRINT_CHOICE::TryVetoSelect, this, _1, false ) );
59  GetVListBoxComboPopup()->Bind(
60  wxEVT_CHAR_HOOK, std::bind( &FOOTPRINT_CHOICE::TrySkipSeparator, this, _1, true ) );
61  GetVListBoxComboPopup()->Bind( wxEVT_CHAR_HOOK, &FOOTPRINT_CHOICE::OnKeyUp, this );
62  Bind( wxEVT_KEY_DOWN, std::bind( &FOOTPRINT_CHOICE::TrySkipSeparator, this, _1, false ) );
63 }
void TrySkipSeparator(wxKeyEvent &aEvent, bool aInner)
For arrow key events, skip over separators.
void TryVetoMouse(wxMouseEvent &aEvent)
Veto a mouseover event if in the separator.
void TryVetoSelect(wxCommandEvent &aEvent, bool aInner)
Veto a select event for the separator.
void OnMouseUp(wxMouseEvent &aEvent)
Mouse up on an item in the list.
void OnKeyUp(wxKeyEvent &aEvent)
Key up on an item in the list.
wxCoord FOOTPRINT_CHOICE::DrawTextFragment ( wxDC &  aDC,
wxCoord  x,
wxCoord  y,
wxString const &  aText 
)
staticprotected

Draw a fragment of text, then return the next x coordinate to continue drawing.

Definition at line 151 of file footprint_choice.cpp.

Referenced by OnDrawItem().

152 {
153  aDC.DrawText( aText, x, y );
154  return x + aDC.GetTextExtent( aText ).GetWidth();
155 }
int FOOTPRINT_CHOICE::GetSelectionEither ( bool  aInner) const
protected

Get selection from either the outer (combo box) or inner (popup) list.

Definition at line 244 of file footprint_choice.cpp.

Referenced by OnKeyUp(), TrySkipSeparator(), and TryVetoSelect().

245 {
246  if( aInner )
247  return GetVListBoxComboPopup()->wxVListBox::GetSelection();
248  else
249  return GetSelection();
250 }
void FOOTPRINT_CHOICE::OnDrawItem ( wxDC &  aDC,
wxRect const &  aRect,
int  aItem,
int  aFlags 
) const
overrideprotectedvirtual

Definition at line 66 of file footprint_choice.cpp.

References DrawTextFragment(), m_grey, and SafeGetString().

67 {
68  wxString text = SafeGetString( aItem );
69 
70  if( text == wxEmptyString )
71  {
72  wxPen pen( m_grey, 1, wxPENSTYLE_SOLID );
73 
74  aDC.SetPen( pen );
75  aDC.DrawLine( aRect.x, aRect.y + aRect.height / 2, aRect.x + aRect.width,
76  aRect.y + aRect.height / 2 );
77  }
78  else
79  {
80  wxCoord x, y;
81 
82  if( aFlags & wxODCB_PAINTING_CONTROL )
83  {
84  x = aRect.x + GetMargins().x;
85  y = ( aRect.height - aDC.GetCharHeight() ) / 2 + aRect.y;
86  }
87  else
88  {
89  x = aRect.x + 2;
90  y = aRect.y;
91  }
92 
93  // If this item has a footprint and that footprint has a ":" delimiter, find the
94  // library component, then find that in the display string and grey it out.
95 
96  size_t start_grey = 0;
97  size_t end_grey = 0;
98 
99  wxString lib = static_cast<wxStringClientData*>( GetClientObject( aItem ) )->GetData();
100  size_t colon_index = lib.rfind( ':' );
101 
102  if( colon_index != wxString::npos )
103  {
104  wxString library_part = lib.SubString( 0, colon_index );
105  size_t library_index = text.rfind( library_part );
106 
107  if( library_index != wxString::npos )
108  {
109  start_grey = library_index;
110  end_grey = start_grey + library_part.Length();
111  }
112  }
113 
114  if( start_grey != end_grey && !( aFlags & wxODCB_PAINTING_SELECTED ) )
115  {
116  x = DrawTextFragment( aDC, x, y, text.SubString( 0, start_grey - 1 ) );
117 
118  wxColour standard_color = aDC.GetTextForeground();
119 
120  aDC.SetTextForeground( m_grey );
121  x = DrawTextFragment( aDC, x, y, text.SubString( start_grey, end_grey - 1 ) );
122 
123  aDC.SetTextForeground( standard_color );
124  x = DrawTextFragment( aDC, x, y, text.SubString( end_grey, text.Length() - 1 ) );
125  }
126  else
127  {
128  aDC.DrawText( text, x, y );
129  }
130  }
131 }
static wxCoord DrawTextFragment(wxDC &aDC, wxCoord x, wxCoord y, wxString const &aText)
Draw a fragment of text, then return the next x coordinate to continue drawing.
wxString SafeGetString(int aItem) const
Safely get a string for an item, returning wxEmptyString if the item doesn't exist.
static wxColour m_grey
void FOOTPRINT_CHOICE::OnKeyUp ( wxKeyEvent &  aEvent)
protected

Key up on an item in the list.

Definition at line 179 of file footprint_choice.cpp.

References GetSelectionEither().

Referenced by DoSetPopupControl().

180 {
181  int item = GetSelectionEither( true );
182 
183  if( aEvent.GetKeyCode() == WXK_RETURN )
184  {
185  wxCommandEvent evt( EVT_INTERACTIVE_CHOICE );
186  evt.SetInt( item );
187  wxPostEvent( this, evt );
188  }
189 
190  aEvent.Skip();
191 }
int GetSelectionEither(bool aInner) const
Get selection from either the outer (combo box) or inner (popup) list.
wxCoord FOOTPRINT_CHOICE::OnMeasureItem ( size_t  aItem) const
overrideprotectedvirtual

Definition at line 133 of file footprint_choice.cpp.

References SafeGetString().

134 {
135  if( SafeGetString( aItem ) == "" )
136  return 11;
137  else
138  return wxOwnerDrawnComboBox::OnMeasureItem( aItem );
139 }
wxString SafeGetString(int aItem) const
Safely get a string for an item, returning wxEmptyString if the item doesn't exist.
wxCoord FOOTPRINT_CHOICE::OnMeasureItemWidth ( size_t  aItem) const
overrideprotectedvirtual

Definition at line 142 of file footprint_choice.cpp.

References SafeGetString().

143 {
144  if( SafeGetString( aItem ) == "" )
145  return GetTextRect().GetWidth() - 2;
146  else
147  return wxOwnerDrawnComboBox::OnMeasureItemWidth( aItem );
148 }
wxString SafeGetString(int aItem) const
Safely get a string for an item, returning wxEmptyString if the item doesn't exist.
void FOOTPRINT_CHOICE::OnMouseUp ( wxMouseEvent &  aEvent)
protected

Mouse up on an item in the list.

Definition at line 167 of file footprint_choice.cpp.

Referenced by DoSetPopupControl().

168 {
169  int item = GetVListBoxComboPopup()->VirtualHitTest( aEvent.GetPosition().y );
170 
171  wxCommandEvent evt( EVT_INTERACTIVE_CHOICE );
172  evt.SetInt( item );
173  wxPostEvent( this, evt );
174 
175  aEvent.Skip();
176 }
wxString FOOTPRINT_CHOICE::SafeGetString ( int  aItem) const
protected

Safely get a string for an item, returning wxEmptyString if the item doesn't exist.

Definition at line 235 of file footprint_choice.cpp.

Referenced by OnDrawItem(), OnMeasureItem(), OnMeasureItemWidth(), TrySkipSeparator(), TryVetoMouse(), and TryVetoSelect().

236 {
237  if( aItem >= 0 && aItem < (int) GetCount() )
238  return GetVListBoxComboPopup()->GetString( aItem );
239  else
240  return wxEmptyString;
241 }
void FOOTPRINT_CHOICE::SetSelectionEither ( bool  aInner,
int  aSel 
)
protected

Safely set selection for either the outer (combo box) or inner (popup) list, doing nothing for invalid selections.

Definition at line 253 of file footprint_choice.cpp.

Referenced by TrySkipSeparator(), and TryVetoSelect().

254 {
255  if( aSel >= 0 && aSel < (int) GetCount() )
256  {
257  if( aInner )
258  return GetVListBoxComboPopup()->wxVListBox::SetSelection( aSel );
259  else
260  return SetSelection( aSel );
261  }
262 }
void FOOTPRINT_CHOICE::TrySkipSeparator ( wxKeyEvent &  aEvent,
bool  aInner 
)
protected

For arrow key events, skip over separators.

Parameters
aInner- true if event was called for the inner list (ie the popup)

Definition at line 213 of file footprint_choice.cpp.

References GetSelectionEither(), SafeGetString(), and SetSelectionEither().

Referenced by DoSetPopupControl().

214 {
215  int key = aEvent.GetKeyCode();
216  int sel = GetSelectionEither( aInner );
217  int new_sel = sel;
218 
219  if( key == WXK_UP && SafeGetString( sel - 1 ) == wxEmptyString )
220  {
221  new_sel = sel - 2;
222  }
223  else if( key == WXK_DOWN && SafeGetString( sel + 1 ) == wxEmptyString )
224  {
225  new_sel = sel + 2;
226  }
227 
228  if( new_sel != sel )
229  SetSelectionEither( aInner, new_sel );
230  else
231  aEvent.Skip();
232 }
int GetSelectionEither(bool aInner) const
Get selection from either the outer (combo box) or inner (popup) list.
void SetSelectionEither(bool aInner, int aSel)
Safely set selection for either the outer (combo box) or inner (popup) list, doing nothing for invali...
wxString SafeGetString(int aItem) const
Safely get a string for an item, returning wxEmptyString if the item doesn't exist.
void FOOTPRINT_CHOICE::TryVetoMouse ( wxMouseEvent &  aEvent)
protected

Veto a mouseover event if in the separator.

Definition at line 158 of file footprint_choice.cpp.

References SafeGetString().

Referenced by DoSetPopupControl().

159 {
160  int item = GetVListBoxComboPopup()->VirtualHitTest( aEvent.GetPosition().y );
161 
162  if( SafeGetString( item ) != "" )
163  aEvent.Skip();
164 }
wxString SafeGetString(int aItem) const
Safely get a string for an item, returning wxEmptyString if the item doesn't exist.
void FOOTPRINT_CHOICE::TryVetoSelect ( wxCommandEvent &  aEvent,
bool  aInner 
)
protected

Veto a select event for the separator.

Parameters
aInner- true if event was called for the inner list (ie the popup)

Definition at line 194 of file footprint_choice.cpp.

References GetSelectionEither(), m_last_selection, SafeGetString(), and SetSelectionEither().

Referenced by DoSetPopupControl().

195 {
196  int sel = GetSelectionEither( aInner );
197 
198  if( sel >= 0 && sel < (int) GetCount() )
199  {
200  wxString text = SafeGetString( sel );
201 
202  if( text == "" )
204  else
205  {
206  m_last_selection = sel;
207  aEvent.Skip();
208  }
209  }
210 }
int GetSelectionEither(bool aInner) const
Get selection from either the outer (combo box) or inner (popup) list.
void SetSelectionEither(bool aInner, int aSel)
Safely set selection for either the outer (combo box) or inner (popup) list, doing nothing for invali...
wxString SafeGetString(int aItem) const
Safely get a string for an item, returning wxEmptyString if the item doesn't exist.

Member Data Documentation

wxColour FOOTPRINT_CHOICE::m_grey
staticprotected

Definition at line 107 of file footprint_choice.h.

Referenced by OnDrawItem().

int FOOTPRINT_CHOICE::m_last_selection
private

Definition at line 110 of file footprint_choice.h.

Referenced by TryVetoSelect().


The documentation for this class was generated from the following files: