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(); } }
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 ); } }
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; }