예제 #1
0
void wxComboCtrl::DoTimerEvent()
{
    bool stopTimer = false;

    wxWindow* win = GetPopupWindow();
    wxWindow* popup = GetPopupControl()->GetControl();

    // Popup was hidden before it was fully shown?
    if ( IsPopupWindowState(Hidden) )
    {
        stopTimer = true;
    }
    else
    {
        wxMilliClock_t t = ::wxGetLocalTimeMillis();
        const wxRect& rect = m_animRect;

#if wxUSE_LONGLONG
        int pos = (int) (t-m_animStart).GetLo();
#else
        int pos = (int) (t-m_animStart);
#endif
        if ( pos < COMBOBOX_ANIMATION_DURATION )
        {
            int height = rect.height;
            //int h0 = rect.height;
            int h = (((pos*256)/COMBOBOX_ANIMATION_DURATION)*height)/256;
            int y = (height - h);
            if ( y < 0 )
                y = 0;

            if ( m_animFlags & ShowAbove )
            {
                win->SetSize( rect.x, rect.y + height - h, rect.width, h );
            }
            else
            {
                // Note that apparently Move() should be called after
                // SetSize() to reduce (or even eliminate) animation garbage
                win->SetSize( rect.x, rect.y, rect.width, h );
                popup->Move( 0, -y );
            }
        }
        else
        {
            stopTimer = true;
        }
    }

    if ( stopTimer )
    {
        m_animTimer.Stop();
        DoShowPopup( m_animRect, m_animFlags );
        popup->Move( 0, 0 );

        // Do a one final refresh to clean up the rare cases of animation
        // garbage
        win->Refresh();
    }
}
예제 #2
0
void wxComboCtrl::DoTimerEvent()
{
    bool stopTimer = false;

    wxWindow* popup = GetPopupControl()->GetControl();

    // Popup was hidden before it was fully shown?
    if ( IsPopupWindowState(Hidden) )
    {
        stopTimer = true;
    }
    else
    {
        wxLongLong t = ::wxGetLocalTimeMillis();
        const wxRect& rect = m_animRect;
        wxWindow* win = GetPopupWindow();

        int pos = (int) (t-m_animStart).GetLo();
        if ( pos < COMBOBOX_ANIMATION_DURATION )
        {
            int height = rect.height;
            //int h0 = rect.height;
            int h = (((pos*256)/COMBOBOX_ANIMATION_DURATION)*height)/256;
            int y = (height - h);
            if ( y < 0 )
                y = 0;

            if ( m_animFlags & ShowAbove )
            {
                win->SetSize( rect.x, rect.y + height - h, rect.width, h );
            }
            else
            {
                popup->Move( 0, -y );
                win->SetSize( rect.x, rect.y, rect.width, h );
            }
        }
        else
        {
            stopTimer = true;
        }
    }

    if ( stopTimer )
    {
        popup->Move( 0, 0 );
        m_animTimer.Stop();
        DoShowPopup( m_animRect, m_animFlags );
    }
}
예제 #3
0
void wxComboCtrl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) )
{
    // TODO: Convert drawing in this function to Windows API Code

    wxSize sz = GetClientSize();
    wxDC* dcPtr = wxAutoBufferedPaintDCFactory(this);
    wxDC& dc = *dcPtr;

    const wxRect& rectButton = m_btnArea;
    wxRect rectTextField = m_tcArea;

    // FIXME: Either SetBackgroundColour or GetBackgroundColour
    //        doesn't work under Vista, so here's a temporary
    //        workaround.
    //        In the theme-less rendering code below, this fixes incorrect
    //        background on read-only comboboxes (they are gray, but should be
    //        white).
    wxColour bgCol = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);

#if wxUSE_UXTHEME
    const bool isEnabled = IsThisEnabled();

    wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl();
    HDC hDc = GetHdcOf(*impl);
    HWND hWnd = GetHwndOf(this);

    wxUxThemeHandle hTheme(this, L"COMBOBOX");
#endif // wxUSE_UXTHEME

    wxRect borderRect(0,0,sz.x,sz.y);

    if ( m_iFlags & wxCC_IFLAG_BUTTON_OUTSIDE )
    {
        borderRect = m_tcArea;
        borderRect.Inflate(1);
    }

    int drawButFlags = 0;

#if wxUSE_UXTHEME
    if ( hTheme )
    {
        const bool useVistaComboBox = ::wxGetWinVersion() >= wxWinVersion_Vista;

        RECT rFull;
        wxCopyRectToRECT(borderRect, rFull);

        RECT rButton;
        wxCopyRectToRECT(rectButton, rButton);

        RECT rBorder;
        wxCopyRectToRECT(borderRect, rBorder);

        bool isNonStdButton = (m_iFlags & wxCC_IFLAG_BUTTON_OUTSIDE) ||
                              (m_iFlags & wxCC_IFLAG_HAS_NONSTANDARD_BUTTON);

        //
        // Get some states for themed drawing
        int butState;

        if ( !isEnabled )
        {
            butState = CBXS_DISABLED;
        }
        // Vista will display the drop-button as depressed always
        // when the popup window is visilbe
        else if ( (m_btnState & wxCONTROL_PRESSED) ||
                  (useVistaComboBox && !IsPopupWindowState(Hidden)) )
        {
            butState = CBXS_PRESSED;
        }
        else if ( m_btnState & wxCONTROL_CURRENT )
        {
            butState = CBXS_HOT;
        }
        else
        {
            butState = CBXS_NORMAL;
        }

        int comboBoxPart = 0;  // For XP, use the 'default' part
        RECT* rUseForBg = &rBorder;

        bool drawFullButton = false;
        int bgState = butState;
        const bool isFocused = (FindFocus() == GetMainWindowOfCompositeControl()) ? true : false;

        if ( useVistaComboBox )
        {
            // Draw the entire control as a single button?
            if ( !isNonStdButton )
            {
                if ( HasFlag(wxCB_READONLY) )
                    drawFullButton = true;
            }

            if ( drawFullButton )
            {
                comboBoxPart = CP_READONLY;
                rUseForBg = &rFull;

                // It should be safe enough to update this flag here.
                m_iFlags |= wxCC_FULL_BUTTON;
            }
            else
            {
                comboBoxPart = CP_BORDER;
                m_iFlags &= ~wxCC_FULL_BUTTON;

                if ( isFocused )
                    bgState = CBB_FOCUSED;
                else
                    bgState = CBB_NORMAL;
            }
        }

        //
        // Draw parent's background, if necessary
        RECT* rUseForTb = NULL;

        if ( ::IsThemeBackgroundPartiallyTransparent( hTheme, comboBoxPart, bgState ) )
            rUseForTb = &rFull;
        else if ( m_iFlags & wxCC_IFLAG_BUTTON_OUTSIDE )
            rUseForTb = &rButton;

        if ( rUseForTb )
            ::DrawThemeParentBackground( hWnd, hDc, rUseForTb );

        //
        // Draw the control background (including the border)
        if ( m_widthCustomBorder > 0 )
        {
            ::DrawThemeBackground( hTheme, hDc, comboBoxPart, bgState, rUseForBg, NULL );
        }
        else
        {
            // No border. We can't use theme, since it cannot be relied on
            // to deliver borderless drawing, even with DrawThemeBackgroundEx.
            dc.SetBrush(bgCol);
            dc.SetPen(bgCol);
            dc.DrawRectangle(borderRect);
        }

        //
        // Draw the drop-button
        if ( !isNonStdButton )
        {
            drawButFlags = Button_BitmapOnly;

            int butPart = CP_DROPDOWNBUTTON;

            if ( useVistaComboBox )
            {
                if ( drawFullButton )
                {
                    // We need to alter the button style slightly before
                    // drawing the actual button (but it was good above
                    // when background etc was done).
                    if ( butState == CBXS_HOT || butState == CBXS_PRESSED )
                        butState = CBXS_NORMAL;
                }

                if ( m_btnSide == wxRIGHT )
                    butPart = CP_DROPDOWNBUTTONRIGHT;
                else
                    butPart = CP_DROPDOWNBUTTONLEFT;

            }
            ::DrawThemeBackground( hTheme, hDc, butPart, butState, &rButton, NULL );
        }
        else if ( useVistaComboBox &&
                  (m_iFlags & wxCC_IFLAG_BUTTON_OUTSIDE) )
        {
            // We'll do this, because DrawThemeParentBackground
            // doesn't seem to be reliable on Vista.
            drawButFlags |= Button_PaintBackground;
        }
    }
    else
#endif
    {
        // Windows 2000 and earlier
        drawButFlags = Button_PaintBackground;

        dc.SetBrush(bgCol);
        dc.SetPen(bgCol);
        dc.DrawRectangle(borderRect);
    }

    // Button rendering (may only do the bitmap on button, depending on the flags)
    DrawButton( dc, rectButton, drawButFlags );

    // Paint required portion of the custom image on the control
    if ( (!m_text || m_widthCustomPaint) )
    {
        wxASSERT( m_widthCustomPaint >= 0 );

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

        dc.SetFont( GetFont() );

        dc.SetClippingRegion(rectTextField);
        if ( m_popupInterface )
            m_popupInterface->PaintComboControl(dc,rectTextField);
        else
            wxComboPopup::DefaultPaintComboControl(this,dc,rectTextField);
    }

    delete dcPtr;
}