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

📄 odcombo.cpp

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

#if wxODC_ALLOW_FAKE_POPUP

    int existing_height = 200;
    if ( m_popup )
        existing_height = m_popup->GetSize().y;

    //wxLogDebug(wxT("Existing height: %i"),existing_height);

    int screen_width;
    GetParent()->GetClientSize(&screen_width,&screen_height);
    screen_width -= 2;
    scr_pos = GetPosition();

    space_above = scr_pos.y - 2;
    space_below = screen_height - space_above - ctrl_sz.y - 4;

    maxHeightPopup = space_below;
    if ( space_above > space_below )
        maxHeightPopup = space_above;

    //wxLogDebug(wxT("FakeMaxHei: %i"),maxHeightPopup);

    if ( maxHeightPopup >= existing_height )
    {
        if ( m_winPopup && m_fakePopupUsage!=2 )
        {
            delete m_winPopup;
            m_winPopup = (wxWindow*) NULL;
            m_popup = (wxWindow*) NULL;
        }
        m_fakePopupUsage = 2;
    }
    else
    {
        if ( m_winPopup && m_fakePopupUsage!=1 )
        {
            delete m_winPopup;
            m_winPopup = (wxWindow*) NULL;
            m_popup = (wxWindow*) NULL;
        }
        m_fakePopupUsage = 1;
#else
    {
#endif

        screen_height = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y );
        scr_pos = GetParent()->ClientToScreen(GetPosition());

        space_above = scr_pos.y;
        space_below = screen_height - space_above - ctrl_sz.y;

        maxHeightPopup = space_below;
        if ( space_above > space_below )
            maxHeightPopup = space_above;

        //wxLogDebug(wxT("RealMaxHei: %i"),maxHeightPopup);

    }

    // Width
    int widthPopup = ctrl_sz.x + m_extLeft + m_extRight;

    wxWindow* winPopup = m_winPopup;
    wxWindow* give_parent = (wxWindow*) NULL;

    if ( !winPopup )
    {
#if wxODC_ALLOW_FAKE_POPUP
        if ( m_fakePopupUsage == 2 )
        {
            //wxLogDebug(wxT("Faking popup!"));
            winPopup = new wxWindow();
        #ifdef __WXMSW__
            // Only wxMSW supports this
            winPopup->Hide();
        #endif
            winPopup->Create( GetParent(), -1 );
        }
        else
#endif
        {
            winPopup =
                new wxComboPopupWindow( this, wxNO_BORDER );
        }
        m_winPopup = give_parent = winPopup;
    }

    // Generate/resize window
    wxWindow* popup = m_popupInterface->GeneratePopup( give_parent,
        widthPopup, maxHeightPopup, m_heightPopup );

    wxASSERT ( !m_popup || m_popup == popup ); // Consistency check.

#if wxODC_ALLOW_FAKE_POPUP
    // Make sure fake popup didn't get too big
    if ( m_fakePopupUsage == 2 && popup->GetSize().x > screen_width )
    {
        popup->SetSize(screen_width-2,popup->GetSize().y);
    }
#endif

    // Add interface as event handler
    if ( !m_popup )
        popup->PushEventHandler( m_popupInterface );

    //
    // Reposition and resize popup window
    //

    wxSize szp = popup->GetSize();

    wxPoint ptp(scr_pos.x+ctrl_sz.x+m_extRight-szp.x,
        scr_pos.y + ctrl_sz.y);

#if wxODC_ALLOW_FAKE_POPUP
    if ( m_fakePopupUsage == 2 )
    {
        if ( space_below < szp.y )
        {
            //wxLogDebug(wxT("%i,%i"),space_below,space_above);
            if ( space_above > space_below )
            {
                if ( szp.y > space_above )
                {
                    popup->SetSize(szp.x,space_above);
                    szp.y = space_above;
                }
                ptp.y = scr_pos.y - szp.y;
            }
            else
            {
                if ( szp.y > space_below )
                {
                    popup->SetSize(szp.x,space_below);
                    szp.y = space_below;
                }
            }
        }
    }
    else
#endif
    if ( space_below < szp.y )
    {
        ptp.y = scr_pos.y - szp.y;
    }

    // Move to position
    //wxLogDebug(wxT("popup scheduled position1: %i,%i"),ptp.x,ptp.y);
    //wxLogDebug(wxT("popup position1: %i,%i"),winPopup->GetPosition().x,winPopup->GetPosition().y);

#if defined(__WXGTK__) && (wxMINOR_VERSION < 5 || ( wxMINOR_VERSION == 5 && wxRELEASE_NUMBER < 5 ))
    // Remedy for wxGTK popup resize issue
    winPopup->SetSizeHints(szp.x, szp.y, szp.x, szp.y);
#endif

    //winPopup->SetSize( ptp.x, ptp.y, szp.x, szp.y );
    // Some platforms (GTK) may need these two to be separate
    winPopup->SetSize( szp.x, szp.y );
    winPopup->Move( ptp.x, ptp.y );

    //wxLogDebug(wxT("popup position2: %i,%i"),winPopup->GetPosition().x,winPopup->GetPosition().y);

    //wxLogDebug(wxT("popup position3: %i,%i"),winPopup->GetPosition().x,winPopup->GetPosition().y);

    m_popup = popup;

    ((wxComboDropButton*)m_btn)->SetPopup( popup );

    if ( m_text )
    {
        m_text->SelectAll();

        // Set string selection (must be this way instead of SetStringSelection)
        m_popupInterface->SetValueFromString( m_text->GetValue() );

    #ifdef __WXDEBUG__
        // Id confirmation
        wxASSERT_MSG ( GetId() == m_text->GetId(),
            wxT("You must use wxPGComboBox::SetId to set its id - calling parent class's won't do"));
    #endif

    }
    else
    {
        Refresh();
    }

    // this must be after SetValueFromString
    m_isPopupShown = 1;

    // Show it
    {
    #if wxODC_USE_TRANSIENT_POPUP
        ((wxPopupTransientWindow*)winPopup)->Popup(popup);
    #else
        winPopup->Show();
        //popup->SetFocus();
    #endif
    }

#if wxODC_INSTALL_TOPLEV_HANDLER
    // If our real popup is wxDialog, then only install handler
    // incase of fake popup.
  #if !wxUSE_POPUPWIN
    if ( m_fakePopupUsage == 2 )
  #endif
    {
        // Put top level window event handler into place
        if ( !m_toplevEvtHandler )
            m_toplevEvtHandler = new wxComboFrameEventHandler(this);

        wxWindow* toplev = ::wxGetTopLevelParent( this );
        wxASSERT( toplev );
        ((wxComboFrameEventHandler*)m_toplevEvtHandler)->OnPopup();
        toplev->PushEventHandler( m_toplevEvtHandler );
    }
#endif

}

void wxPGComboBox::OnPopupDismiss()
{
    //wxLogDebug(wxT("wxPGComboBox::OnPopupDismiss"));

    ((wxComboDropButton*)m_btn)->SetPopup( (wxWindow*) NULL );

#if wxODC_INSTALL_TOPLEV_HANDLER
    // Remove top level window event handler
    if ( m_toplevEvtHandler )
    {
        wxWindow* toplev = ::wxGetTopLevelParent( this );
        if ( toplev )
            toplev->RemoveEventHandler( m_toplevEvtHandler );
    }

    // TODO: This may be needed for transient window as well
    // FIXME: This is a hack to resolve a bug wxPopupWindow+wxScrolledWindow
    /*
    wxSize orig_size = toplev->GetSize();
    wxSize new_size = orig_size;
    new_size.x += 1;
    toplev->SetSize(new_size);
    toplev->SetSize(orig_size);
    */

#endif

    wxWindow* focus_target = this;
    if ( m_text )
        focus_target = m_text;

    focus_target->SetFocus();

    m_isPopupShown = 0;

    // refresh control (necessary even if m_text)
    Refresh();
}

void wxPGComboBox::HidePopup( bool sendEvent )
{
    wxCHECK_RET( m_popupInterface, _T("no popup interface specified in wxPGComboBox") );
    if ( m_isPopupShown < 1 )
    {
        //wxLogDebug(wxT("wxPGComboBox::HidePopup: Warning: trying to hide hidden popup."));
        return;
    }

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

    // transfer value and refresh control
    m_valueString = m_popupInterface->GetValueAsString();
    if ( m_text )
        m_text->SetValue (m_valueString);

#if wxODC_USE_TRANSIENT_POPUP
    ((wxPopupTransientWindow*)m_winPopup)->Dismiss();
#else
    m_winPopup->Hide();
#endif

    OnPopupDismiss();

    if ( sendEvent )
    {
        // fire the event
        wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_SELECTED, GetId());
        event.SetEventObject(this);
        event.SetInt(GetSelection());
        GetEventHandler()->AddPendingEvent(event);
    }

}

// ----------------------------------------------------------------------------
// event handlers
// ----------------------------------------------------------------------------

void wxPGComboBox::OnButtonClick(wxCommandEvent& /*event*/ )
{
    SetFocus();

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

    // Must check exactly against 0 to allow -1 value to take effect below
    if ( m_isPopupShown == 0 )
    {
        ShowPopup();
    }
    else
    {
    #if !wxUSE_POPUPWIN
        if ( m_isPopupShown > 0 )
            HidePopup( false );

        m_isPopupShown++;
        // Normally do nothing - evt handler should close it for us
      //#if wxODC_ALLOW_FAKE_POPUP
        //if ( m_fakePopupUsage == 2 )
        //
      //#endif
    #elif !wxODC_USE_TRANSIENT_POPUP
        HidePopup( false );
        //m_winPopup->OnDismiss();
    #else
        // Why this? See wxComboPopupWindow::OnDismiss
        OnPopupDismiss();
    #endif
    }
}

void wxPGComboBox::OnPaint( wxPaintEvent& )
{
    wxPaintDC dc(this);

    // paint, whatever is required, on the control
    if ( m_btn && ( !m_text || m_widthCustomPaint ) )
    {
        wxASSERT ( m_popupInterface );
        wxASSERT ( m_widthCustomPaint >= 0 );
        //wxASSERT ( m_widthCustomPaint < m_btn->GetPosition().x );

        wxSize sz = GetClientSize();
        wxRect rect(0,0, sz.x - m_btn->GetSize().x, sz.y );

#if wxODC_BORDER_STYLE == 1
        // artifical simple border around custom-drawn value
        if ( m_widthCustomBorder )
        {
            dc.SetPen( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNSHADOW ) );
            dc.SetBrush( *wxTRANSPARENT_BRUSH );
            dc.DrawRectangle( rect );
            rect.Deflate(m_widthCustomBorder);
        }
#endif

        // this is intentionally here to allow drawed rectangle's
        // right edge to be hidden
        if ( m_text )
            rect.width = m_widthCustomPaint;

        wxColour win_col = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);

        dc.SetFont( GetFont() );

        dc.SetBrush ( win_col );
        dc.SetPen ( win_col );
        dc.DrawRectangle ( rect );

    #if wxODC_SELECTION_STYLE == 0
        // If popup is hidden and this control is focused,
        // then draw the focus-indicator (blue background etc.).
        wxWindow* cur_focus = FindFocus();
        if ( m_isPopupShown < 1 && (cur_focus == this || cur_focus == m_btn) &&
             !m_text
           )
        {
            wxRect sel_rect(rect);
            sel_rect.y += 1;
            sel_rect.height -= 2;
            sel_rect.x += m_widthCustomPaint + 1;
            sel_rect.width -= m_widthCustomPaint + 2;

            dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT) );

            DrawComboSelectionBackground( dc, sel_rect );
        }
        else
            dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT) );
    #else
        wxColour tx_col(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));

        // If popup is hidden and this control is focused,
        // then draw the focus-indicator (blue background etc.).
        wxWindow* cur_focus = FindFocus();
        if ( m_isPopupShown < 1 && (cur_focus == this || cur_focus == m_btn) &&
             !m_text
           )
        {
            wxRect sel_rect(rect);
            sel_rect.y += 1;
            sel_rect.height -= 2;
            sel_rect.x += m_widthCustomPaint + 1;
            sel_rect.width -= m_widthCustomPaint + 2;

             // Draw dotted edge (use sys_hilight_text colour)
            wxPen pen(tx_col,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( sel_rect );
       }
       dc.SetTextForeground( tx_col );
   #endif

        wxComboPaintCallback callback = m_popupInterface->GetCallback();

        if ( !(m_windowStyle & wxODCB_STD_CONTROL_PAINT) && callback )
        {
            int sel = GetSelection();

            ((GetParent())->*m_popupInterface->GetCallback())(this,
                sel,dc,rect,wxODCB_CB_PAINTING_CONTROL);
        }
        else if ( !m_text )
        {

            dc.DrawText(m_valueString,
                        3+wxODC_TEXTXADJUST,
                        (rect.height-dc.GetCharHeight())/2 );

        }
    }
}

void wxPGComboBox::OnMouseEvent( wxMouseEvent& event )
{
    int type = event.GetEventType();

    //if ( type != wxEVT_MOTION ) wxLogDebug(wxT("wxPGComboBox::OnMouseEvent"));

    if ( type == wxEVT_LEFT_DOWN || type == wxEVT_LEFT_DCLICK )
    {
        //wxLogDebug(wxT("wxPGComboBox::OnMouseEvent"));
    #if !wxODC_USE_TRANSIENT_POPUP
        // Check if event occurs on the button (technically not necessary on MSW,
        // but important in GTK).
        // TODO: Remove this
        if ( event.GetPosit

⌨️ 快捷键说明

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