⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 odcombo.cpp

📁 非常好用的可移植的多平台C/C++源代码编辑器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
{
    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 + -