📄 odcombo.cpp
字号:
{
dc.SetFont( m_font );
wxPGComboBox* pCb = m_iface->m_combo;
bool is_hilited = pCb->IsHighlighted(n);
// Set correct text colour for selected items
if ( is_hilited )
dc.SetTextForeground ( wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT) );
((pCb->GetParent())->*m_callback)(pCb,
n,dc,((wxRect&)rect),0);
// Restore text colour
if ( is_hilited )
dc.SetTextForeground ( wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT) );
}
wxCoord wxVListBoxComboPopup::OnMeasureItem(size_t n) const
{
wxRect rect(-1,-1,-1,-1);
wxDC* invalid_dc_ptr;
#ifdef __WXDEBUG__
// TODO: Change this to something safe.
invalid_dc_ptr = (wxDC*) NULL;
#else
invalid_dc_ptr = (wxDC*) NULL;
#endif
((m_iface->m_combo->GetParent())->*m_callback)(m_iface->m_combo,
n,*invalid_dc_ptr,rect,0);
wxASSERT_MSG ( rect.height >= 0, wxT("wxPGComboBox measure item call didn't return valid value in rect.height") );
return rect.height;
}
static void DrawComboSelectionBackground( wxDC& dc, const wxRect& rect )
{
wxColour sel_col = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
dc.SetBrush ( sel_col );
dc.SetPen ( sel_col );
dc.DrawRectangle ( rect );
#if wxODC_SELECTION_STYLE == 0
// Draw dotted edge (use sys_hilight_text colour)
wxPen pen(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVEBORDER),1,wxDOT);
// TODO: Remove this line after CreatePen/ExtCreatePen issue fixed in main lib
pen.SetCap( wxCAP_BUTT );
dc.SetPen( pen );
dc.SetBrush( *wxTRANSPARENT_BRUSH );
dc.DrawRectangle( rect );
#endif
}
void wxVListBoxComboPopup::OnDrawBackground(wxDC& dc, const wxRect& rect, size_t n) const
{
// we need to render selected and current items differently
if ( IsCurrent(n) )
{
DrawComboSelectionBackground( dc, rect );
/*dc.SetBrush( wxBrush(GetSelectionBackground(), wxSOLID) );
dc.SetPen( *wxTRANSPARENT_PEN );
dc.DrawRectangle(rect);*/
}
//else: do nothing for the normal items
}
void wxVListBoxComboPopup::SendSelectedEvent()
{
wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_SELECTED, GetId());
event.SetEventObject(this);
event.SetInt(GetSelection());
(void)GetEventHandler()->ProcessEvent(event);
}
void wxVListBoxComboPopup::OnMouseMove(wxMouseEvent& event)
{
int item_here = GetItemAtPosition(event.GetPosition());
if ( item_here >= 0 )
SetSelection(item_here);
event.Skip();
}
void wxVListBoxComboPopup::OnLeftClick(wxMouseEvent& event)
{
wxPoint pt = event.GetPosition();
wxSize sz = GetClientSize();
if ( pt.x >= 0 && pt.y >= 0 && pt.x < sz.x && pt.y < sz.y )
wxVListBoxComboPopup::SendSelectedEvent();
else
event.Skip();
}
void wxVListBoxComboPopup::OnKey(wxKeyEvent& event)
{
if ( event.GetKeyCode() == WXK_RETURN || event.GetKeyCode() == WXK_NUMPAD_ENTER )
wxVListBoxComboPopup::SendSelectedEvent();
else
event.Skip();
}
// ----------------------------------------------------------------------------
// wxVListBoxComboInterface is the "default" wxOwnerDrawComboBox combo
// interface. It uses wxVListBoxComboPopup as the popup control.
// ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(wxVListBoxComboInterface, wxEvtHandler)
EVT_COMBOBOX(wxID_ANY,wxVListBoxComboInterface::OnSelect)
//EVT_KEY_DOWN(wxVListBoxComboInterface::OnKey)
//EVT_KEY_UP(wxVListBoxComboInterface::OnKey)
//EVT_LEFT_UP(wxVListBoxComboInterface::OnMouseMove)
END_EVENT_TABLE()
wxVListBoxComboInterface::wxVListBoxComboInterface ( wxComboPaintCallback callback )
: wxComboPopupInterface()
{
m_callback = callback;
m_popup = (wxVListBoxComboPopup*) NULL;
m_widestWidth = 0;
m_avgCharWidth = 0;
m_baseImageWidth = 0;
}
wxVListBoxComboInterface::~wxVListBoxComboInterface ()
{
Clear();
}
bool wxVListBoxComboInterface::Init( wxPGComboBox* combo )
{
wxComboPopupInterface::Init(combo);
return false; // generate on first popup
}
void wxVListBoxComboInterface::OnSelect (wxCommandEvent& /*event*/)
{
m_value = m_popup->GetSelection();
m_combo->HidePopup();
}
void wxVListBoxComboInterface::OnMouseMove ( wxMouseEvent& event )
{
int type = event.GetEventType();
if ( type == wxEVT_LEFT_UP )
{
m_value = m_popup->GetSelection();
m_combo->HidePopup();
}
event.Skip();
}
void wxVListBoxComboInterface::OnKey(wxKeyEvent& event)
{
if ( event.GetKeyCode() == WXK_RETURN )
{
m_value = m_popup->GetSelection();
m_combo->HidePopup();
}
else
event.Skip();
}
void wxVListBoxComboInterface::CheckWidth( int pos, const wxString& item )
{
// Calculate average character width
if ( !m_avgCharWidth )
{
wxASSERT ( m_combo );
m_font = m_combo->GetFont();
wxClientDC dc(m_combo);
dc.SetFont(m_font);
m_avgCharWidth = (dc.GetCharWidth()*3)/2 + 1;
}
// Get usual custom image width
if ( !m_baseImageWidth )
{
wxASSERT( GetCount() > 0 );
wxRect rect(-1,-1,0,0);
wxDC* invalid_dc_ptr;
#ifdef __WXDEBUG__
// TODO: Change this to something safe.
invalid_dc_ptr = (wxDC*) NULL;
#else
invalid_dc_ptr = (wxDC*) NULL;
#endif
((m_combo->GetParent())->*m_callback)(m_combo,
pos,
*invalid_dc_ptr,
rect,
0);
m_baseImageWidth = rect.width;
}
int baseWidth = (m_avgCharWidth * item.length()) + m_baseImageWidth;
if ( m_widestWidth < baseWidth )
{
// Need to check the actual width
int x, y;
m_combo->GetTextExtent(item, &x, &y, 0, 0, &m_font);
int actualWidth = x + m_baseImageWidth;
if ( m_widestWidth < actualWidth )
{
//wxLogDebug(wxT("%i"),m_baseImageWidth);
//wxLogDebug(wxT("%s: %i"),item.c_str(),actualWidth);
m_widestWidth = actualWidth;
}
//wxLogDebug(wxT("%i (%i,%i)"),m_widestWidth,(int)m_avgCharWidth,(int)item.length());
}
}
void wxVListBoxComboInterface::Insert( const wxString& item, int pos )
{
m_strings.Insert(item,pos);
// Calculate width
CheckWidth(pos,item);
if ( m_popup )
m_popup->SetItemCount(m_popup->GetItemCount()+1);
}
void wxVListBoxComboInterface::Clear()
{
wxASSERT ( m_combo );
m_strings.Empty();
if ( m_popup )
m_popup->SetItemCount(0);
}
void wxVListBoxComboInterface::Delete( int item )
{
wxASSERT ( m_combo );
m_strings.RemoveAt(item);
/*
if ( m_combo->HasClientObjectData() )
delete (wxClientData *) m_datas[item];
m_datas.RemoveAt(item);
*/
if ( m_popup )
m_popup->SetItemCount(m_popup->GetItemCount()-1);
}
int wxVListBoxComboInterface::FindString(const wxString& s) const
{
return m_strings.Index(s);
}
/*void* wxVListBoxComboInterface::GetClientData( int item ) const
{
return m_datas[item];
}*/
int wxVListBoxComboInterface::GetCount() const
{
return m_strings.GetCount();
}
wxString wxVListBoxComboInterface::GetString( int item ) const
{
return m_strings[item];
}
wxString wxVListBoxComboInterface::GetValueAsString() const
{
if ( m_value >= 0 )
return m_strings[m_value];
return wxEmptyString;
}
/*void wxVListBoxComboInterface::SetClientData( int item,
void* clientData )
{
m_datas[item] = clientData;
}*/
void wxVListBoxComboInterface::SetSelection ( int item )
{
// This seems to be necessary (2.5.3 w/ MingW atleast)
if ( item < -1 || item >= (int)m_strings.GetCount() )
item = -1;
m_value = item;
if ( m_popup )
{
/*#if wxMINOR_VERSION < 5 || ( wxMINOR_VERSION == 5 && wxRELEASE_NUMBER < 4 )
if ( m_popup->GetSelection() != item )
#endif*/
m_popup->SetSelection(item);
}
}
void wxVListBoxComboInterface::SetString( int item, const wxString& str )
{
m_strings[item] = str;
}
void wxVListBoxComboInterface::SetValueFromString ( const wxString& value )
{
int index = m_strings.Index(value);
if ( index != wxNOT_FOUND )
SetSelection(index);
}
wxWindow* wxVListBoxComboInterface::GeneratePopup(wxWindow* parent, int minWidth,
int maxHeight, int prefHeight )
{
if ( parent )
{
m_popup = new wxVListBoxComboPopup(parent,this,m_callback,0);
m_popup->SetItemCount(m_strings.GetCount());
}
int height = 250;
if ( m_strings.GetCount() )
{
if ( prefHeight > 0 )
height = prefHeight;
if ( height > maxHeight )
height = maxHeight;
int total_height = m_popup->GetTotalHeight() + 3;
if ( height >= total_height )
{
height = total_height;
}
else
{
// Adjust height to a multiple of the height of the first item
int fih = m_popup->GetLineHeight ( 0 );
int shown = height/fih;
height = shown * fih;
}
}
else
height = 50;
// Take scrollbar into account in width calculations
int widestWidth = m_widestWidth + wxSystemSettings::GetMetric(wxSYS_VSCROLL_X); //27;
m_popup->Move(0,0);
m_popup->SetSize( minWidth > widestWidth ? minWidth : widestWidth,
height+2);
// *must* set value after size is set (this is because of a vlbox bug)
if ( m_value >= 0 )
SetSelection(m_value);
return m_popup;
}
void wxVListBoxComboInterface::Populate ( int n, const wxString choices[] )
{
int i;
for ( i=0; i<n; i++ )
{
m_strings.Add(choices[i]);
CheckWidth(n,choices[i]);
}
//m_datas.SetCount(m_datas.GetCount()+n);
}
const int* wxVListBoxComboInterface::GetIntPtr () const
{
return &m_value;
}
bool wxVListBoxComboInterface::IsHighlighted ( int item ) const
{
if ( m_popup->GetParent()->IsShown() )
{
return m_popup->IsCurrent( item );
}
return ( m_value == item );
}
// ----------------------------------------------------------------------------
// input handling
// ----------------------------------------------------------------------------
//
// This is pushed to the event handler queue of either combo box
// or its textctrl (latter only if it is created).
//
class wxComboBoxExtraInputHandler : public wxEvtHandler
{
public:
wxComboBoxExtraInputHandler( wxPGComboBox* combo )
: wxEvtHandler()
{
m_combo = combo;
}
~wxComboBoxExtraInputHandler() { }
void OnKey(wxKeyEvent& event);
protected:
wxPGComboBox* m_combo;
private:
DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE(wxComboBoxExtraInputHandler, wxEvtHandler)
EVT_KEY_DOWN(wxComboBoxExtraInputHandler::OnKey)
END_EVENT_TABLE()
void wxComboBoxExtraInputHandler::OnKey(wxKeyEvent& event)
{
int keycode = event.GetKeyCode();
#if wxMINOR_VERSION > 5 || ( wxMINOR_VERSION == 5 && wxRELEASE_NUMBER >= 3 )
if ( keycode == WXK_TAB )
{
wxNavigationKeyEvent evt;
evt.SetFlags(
#if wxMINOR_VERSION > 5 || ( wxMINOR_VERSION == 5 && wxRELEASE_NUMBER >= 4 )
wxNavigationKeyEvent::FromTab|
#endif
(!event.ShiftDown()?wxNavigationKeyEvent::IsForward:
wxNavigationKeyEvent::IsBackward));
evt.SetEventObject(m_combo);
m_combo->GetParent()->GetEventHandler()->AddPendingEvent(evt);
return;
}
#endif
if ( m_combo->IsPopupShown() )
{
// pass it to the popped up control
m_combo->GetPopupControl()->AddPendingEvent(event);
}
else // no popup
{
if ( keycode == WXK_NUMPAD_ENTER ||
keycode == WXK_UP || keycode == WXK_DOWN || keycode == WXK_RETURN )
{
m_combo->ShowPopup();
}
else
event.Skip();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -