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

📄 odcombo.cpp

📁 非常好用的可移植的多平台C/C++源代码编辑器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    }
}

// ----------------------------------------------------------------------------
// wxPGComboBox
// ----------------------------------------------------------------------------

IMPLEMENT_DYNAMIC_CLASS(wxPGComboBox, wxOwnerDrawnComboBoxBase)

BEGIN_EVENT_TABLE(wxPGComboBox, wxOwnerDrawnComboBoxBase)
    EVT_MOUSE_EVENTS(wxPGComboBox::OnMouseEvent)
    EVT_PAINT(wxPGComboBox::OnPaint)
    EVT_SIZE(wxPGComboBox::OnResize)
    //EVT_KEY_DOWN(wxPGComboBox::OnKey)
    //EVT_KEY_UP(wxPGComboBox::OnKey)
    EVT_BUTTON(wxID_ANY, wxPGComboBox::OnButtonClick)
    EVT_SET_FOCUS(wxPGComboBox::OnFocusEvent)
    EVT_KILL_FOCUS(wxPGComboBox::OnFocusEvent)
END_EVENT_TABLE()

void wxPGComboBox::Init()
{
    m_popupInterface = (wxComboPopupInterface*) NULL;
    m_winPopup = (wxWindow *)NULL;
    m_popup = (wxWindow *)NULL;
    m_isPopupShown = 0;
    m_hasIntValue = false;
    m_btn = (wxWindow*) NULL;
    m_text = (wxTextCtrl*) NULL;

    m_extraEvtHandler = (wxEvtHandler*) NULL;
    m_textEvtHandler = (wxEvtHandler*) NULL;
#if wxODC_INSTALL_TOPLEV_HANDLER
    m_toplevEvtHandler = (wxEvtHandler*) NULL;
#endif

    m_heightPopup = 175;

    m_widthCustomPaint = 0;

#if wxODC_BORDER_STYLE == 1
    m_widthCustomBorder = 0;
#endif

    m_extLeft = 0;
    m_extRight = 0;

    m_fakePopupUsage = 0;
}

bool wxPGComboBox::Create(wxWindow *parent,
                            wxWindowID id,
                            const wxString& value,
                            const wxPoint& pos,
                            const wxSize& size,
                            wxComboPopupInterface* iface,
                            long style,
                            const wxValidator& validator,
                            const wxString& name)
{

    // Prepare interface
    if ( iface )
        SetPopupInterface(iface);

    // Set border correctly.
    long border = style & wxBORDER_MASK;

#if wxODC_BORDER_STYLE == 0
    // msw style

    if ( !border )
        border = wxBORDER_SUNKEN;
    style = (style & ~(wxBORDER_MASK)) | border;
#else
    // gtk style

    // maybe save border to textctrl
    style = (style & ~(wxBORDER_MASK));

    if ( style & wxCB_READONLY )
    {
        if ( !border )
        {
            m_widthCustomBorder = 1;
            border = wxNO_BORDER;
        }

        style |= border;
    }
    else
    {
        style |= wxNO_BORDER;

        // border is then used by textctrl
        if ( !border )
        {
            //m_widthCustomBorder = 1;
            border = wxBORDER_SUNKEN;
        }
    }
#endif

    // first create our own window, i.e. the one which will contain all
    // subcontrols
    if ( !wxOwnerDrawnComboBoxBase::Create(parent,
                                             id,
                                             wxDefaultPosition,
                                             wxDefaultSize,
                                             style | wxWANTS_CHARS,
                                             wxDefaultValidator,
                                             name) )
        return false;

    id = GetId(); // Make sure we got a valid id.

    if ( !(style & wxCB_READONLY) )
    {
        // Use same id to make event handling straighforward
        m_text = new wxTextCtrl(this,id,value,
                                wxDefaultPosition,wxDefaultSize,
                            #if wxODC_BORDER_STYLE == 0
                                wxNO_BORDER,
                            #else
                                border,
                            #endif
                                validator);

        // This is required for some platforms (GTK atleast)
        // TODO: If textctrl minsize is patched at some point, then remove this.
        m_text->SetSizeHints(2,4);

        m_textEvtHandler = new wxComboBoxExtraInputHandler(this);
        m_text->PushEventHandler(m_textEvtHandler);
    }

    wxComboBoxExtraInputHandler* input_handler = new wxComboBoxExtraInputHandler(this);
    PushEventHandler(input_handler);
    m_extraEvtHandler = input_handler;

    m_btn = new wxComboDropButton(this,id+1,wxDefaultPosition,wxDefaultSize,wxNO_BORDER/*|wxBU_COMBO*/);

#if wxMINOR_VERSION >= 6 || ( wxMINOR_VERSION == 5 && wxRELEASE_NUMBER >= 3 )
    // Prevent excess background clearing
    //   (only if readonly)
    if ( style & wxCB_READONLY )
        SetBackgroundStyle( wxBG_STYLE_CUSTOM );
#endif

    SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));

    // for compatibility with the other ports, the height specified is the
    // combined height of the combobox itself and the popup
    // JMS: I do not understand this yet.
    /*if ( size.y == wxDefaultCoord )
    {
        // ok, use default height for popup too
        m_heightPopup = wxDefaultCoord;
    }
    else
    {
        m_heightPopup = size.y - DoGetBestSize().y;
    }

    SetBestSize(size);
    Move(pos);*/

    // Generate valid size
    wxSize use_size = size;
    wxSize best_size = DoGetBestSize();
    if ( use_size.x <= 0 )
        use_size.x = best_size.x;
    if ( use_size.y <= 0 )
        use_size.y = best_size.y;

    SetSize(pos.x,pos.y,use_size.x,use_size.y);

    return true;
}

wxPGComboBox::wxPGComboBox(wxWindow *parent,
                       wxWindowID id,
                       const wxString& value,
                       const wxPoint& pos,
                       const wxSize& size,
                       const wxArrayString& choices,
                       wxComboPaintCallback callback,
                       long style,
                       const wxValidator& validator,
                       const wxString& name)
{
    Init();

    Create(parent, id, value, pos, size, choices, callback, style, validator, name);
}

bool wxPGComboBox::Create(wxWindow *parent,
                        wxWindowID id,
                        const wxString& value,
                        const wxPoint& pos,
                        const wxSize& size,
                        const wxArrayString& choices,
                        wxComboPaintCallback callback,
                        long style,
                        const wxValidator& validator,
                        const wxString& name)
{
    wxCArrayString chs(choices);

    return Create(parent, id, value, pos, size, chs.GetCount(),
                  chs.GetStrings(), callback, style, validator, name);
}

bool wxPGComboBox::Create(wxWindow *parent,
                        wxWindowID id,
                        const wxString& value,
                        const wxPoint& pos,
                        const wxSize& size,
                        int n,
                        const wxString choices[],
                        wxComboPaintCallback callback,
                        long style,
                        const wxValidator& validator,
                        const wxString& name)
{

    wxVListBoxComboInterface* iface = new wxVListBoxComboInterface(callback);

    iface->Init(this);

    if ( !Create(parent, id, value, pos, size, iface, style,
                 validator, name) )
    {
        return false;
    }

    // Add initial choices to the interface.
    iface->Populate(n,choices);

    return true;
}

wxPGComboBox::~wxPGComboBox()
{
    ClearClientDatas();

    if ( m_isPopupShown > 0 )
        HidePopup( false );

    delete m_popupInterface;
    //m_popupInterface = (wxComboPopupInterface*) NULL;

    //delete m_popup;
    //m_popup = NULL;

    delete m_winPopup;
    //m_winPopup = NULL;

#if wxODC_INSTALL_TOPLEV_HANDLER
    delete ((wxComboFrameEventHandler*)m_toplevEvtHandler);
    m_toplevEvtHandler = (wxEvtHandler*) NULL;
#endif

    RemoveEventHandler(m_extraEvtHandler);

    if ( m_text )
        m_text->RemoveEventHandler(m_textEvtHandler);

    delete m_textEvtHandler;
    delete m_extraEvtHandler;

    //wxLogDebug( wxT("wxPGComboBox::~wxPGComboBox ends...") );
}

void wxPGComboBox::ClearClientDatas()
{
    if ( HasClientObjectData() )
    {
        size_t i;
        for ( i=0; i<m_clientDatas.GetCount(); i++ )
            delete (wxClientData*) m_clientDatas[i];
    }

    m_clientDatas.Empty();
}

bool wxPGComboBox::IsHighlighted ( int item ) const
{
    wxASSERT ( m_popupInterface );
    return m_popupInterface->IsHighlighted(item);
}

// ----------------------------------------------------------------------------
// geometry stuff
// ----------------------------------------------------------------------------

wxSize wxPGComboBox::DoGetBestSize() const
{
    wxASSERT ( m_btn );
    wxSize sizeBtn = m_btn->GetBestSize();
    wxSize sizeText(150,0);

    if ( m_text ) sizeText = m_text->GetBestSize();

    int fhei = 20;
    if ( m_font.Ok() )
        fhei = (m_font.GetPointSize()*2);

    return wxSize(sizeText.x + g_comboMargin + sizeBtn.x,
                  wxMax(fhei, sizeText.y) + 6);
}

void wxPGComboBox::DoMoveWindow(int x, int y, int width, int height)
{
    wxOwnerDrawnComboBoxBase::DoMoveWindow(x, y, width, height);

    /*
    // FIXME: Hack this is, since GetClientSize no longer (>=2.5.4) working here is.
    wxSize sz(width,height);
    int total_border = 0;
    if ( m_windowStyle & wxSIMPLE_BORDER ) total_border = 2;
    else if ( m_windowStyle & wxSUNKEN_BORDER ) total_border = (wxODC_SUNKEN_BORDER_WIDTH*2);
        
    sz.x -= total_border;
    sz.y -= total_border;

    int butWidth = sz.y;
    if ( butWidth > wxODC_DROPDOWN_BUTTON_MAX_WIDTH )
        butWidth = wxODC_DROPDOWN_BUTTON_MAX_WIDTH;

    m_btn->SetSize(sz.x - butWidth,
                   0,
                   butWidth,
                   sz.y
                  );

    if ( m_text )
    {
        //wxLogDebug( wxT("wxPGComboBox::DoMoveWindow(%i,%i)"),textRect.x,textRect.y);
        //m_text->SetSize(textRect);

#if wxODC_BORDER_STYLE == 1
        if ( m_text->GetWindowStyleFlag() & wxNO_BORDER )
#endif
        {
            // Centre textctrl
            wxSize tsz = m_text->GetSize();
            int diff = sz.y - tsz.y;
            m_text->SetSize(wxODC_TEXTCTRLXADJUST + m_widthCustomPaint,
                            wxODC_TEXTCTRLYADJUST + (diff/2),
                            sz.x - butWidth - g_comboMargin - (wxODC_TEXTCTRLXADJUST + m_widthCustomPaint),
                            -1);
        }
#if wxODC_BORDER_STYLE == 1
        else
        {
            m_text->SetSize(m_widthCustomPaint + m_widthCustomBorder,
                            0,
                            sz.x - butWidth - m_widthCustomPaint - m_widthCustomBorder,
                            sz.y);
        }
#endif
    }
    */

}

// ----------------------------------------------------------------------------
// popup window handling
// ----------------------------------------------------------------------------

void wxPGComboBox::SetPopupInterface( wxComboPopupInterface* iface )
{
    delete m_popupInterface;
    delete m_winPopup;

    m_popupInterface = iface;

#if wxODC_ALLOW_FAKE_POPUP
    m_fakePopupUsage = 0;
#endif

    bool create_now = iface->Init(this);

    if ( create_now )
    {
        m_winPopup = new wxComboPopupWindow ( this, wxNO_BORDER );

        // Dimensions are pretty much dummy here
        // (this is called again in ShowPopup to properly resize the control)
        m_popup = iface->GeneratePopup( m_winPopup,
            100, 400, m_heightPopup );

        // Add interface as event handler
        m_popup->PushEventHandler( iface );

        // FIXME: This bypasses wxGTK popupwindow bug
        //   (i.e. window is not initially hidden when it should be)
        m_winPopup->Hide();

#if wxODC_ALLOW_FAKE_POPUP
        m_fakePopupUsage = 1;
#endif
    }

    m_hasIntValue = iface->GetIntPtr() ? true : false;
}

void wxPGComboBox::SetCustomPaintArea( int width )
{
    if ( m_text )
    {
        // move textctrl accordingly
        wxRect r = m_text->GetRect();
        int inc = width - m_widthCustomPaint;
        r.x += inc; r.width -= inc;

        m_text->SetSize( r );

#if wxODC_BORDER_STYLE == 1
        // do we need to set/reset border?
        if ( !width )
        {
            m_widthCustomBorder = 0;
        }
        else
        {
            int tx_border = m_text->GetWindowStyleFlag() & wxBORDER_MASK;

            // FIXME: Get real border with.
            if ( !(tx_border & wxNO_BORDER) )
                m_widthCustomBorder = 1;
        }
#endif
    }
    
    m_widthCustomPaint = width;

}

void wxPGComboBox::ShowPopup()
{

    wxCHECK_RET( m_popupInterface, _T("no popup interface specified in wxPGComboBox") );
    wxCHECK_RET( !IsPopupShown(), _T("popup window already shown") );

    SetFocus();

    //wxLogDebug( wxT("wxPGComboBox::ShowPopup") );

    // Space above and below
    int screen_height;
    wxPoint scr_pos;
    int space_above;
    int space_below;
    int maxHeightPopup;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -