Redone (generic) wxComboCtrl background painting and handling. The 'actual' wxWindow background colour is now largely ignored and overridden to refer the text-area's background colour instead (as is usually the case with controls like this). Base 'transparent' background is now only painted when double-buffered rendering is required, and otherwise delegated to the system, as appropriate. This should significantly improve control's appearance and compliancy with GTK+ and OS X themes and custom backgrounds.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@67255 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -445,6 +445,9 @@ public:
|
||||
// Return true if Create has finished
|
||||
bool IsCreated() const { return m_iFlags & wxCC_IFLAG_CREATED ? true : false; }
|
||||
|
||||
// Need to override to return text area background colour
|
||||
wxColour GetBackgroundColour() const;
|
||||
|
||||
// common code to be called on popup hide/dismiss
|
||||
void OnPopupDismiss(bool generateEvent);
|
||||
|
||||
@@ -671,6 +674,9 @@ protected:
|
||||
wxRect m_tcArea;
|
||||
wxRect m_btnArea;
|
||||
|
||||
// Colour of the the text area, in case m_text is NULL
|
||||
wxColour m_tcBgCol;
|
||||
|
||||
// current button state (uses renderer flags)
|
||||
int m_btnState;
|
||||
|
||||
|
@@ -31,6 +31,8 @@
|
||||
|
||||
#endif
|
||||
|
||||
#include "wx/dcbuffer.h"
|
||||
|
||||
extern WXDLLIMPEXP_DATA_CORE(const char) wxComboBoxNameStr[];
|
||||
|
||||
class WXDLLIMPEXP_CORE wxGenericComboCtrl : public wxComboCtrlBase
|
||||
@@ -96,6 +98,21 @@ protected:
|
||||
virtual WXHWND GetEditHWND() const { return NULL; }
|
||||
#endif
|
||||
|
||||
// For better transparent background rendering
|
||||
virtual bool HasTransparentBackground()
|
||||
{
|
||||
#if wxALWAYS_NATIVE_DOUBLE_BUFFER
|
||||
#ifdef __WXGTK__
|
||||
// Sanity check for GTK+
|
||||
return IsDoubleBuffered();
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Mandatory virtuals
|
||||
virtual void OnResize();
|
||||
|
||||
|
@@ -1071,10 +1071,10 @@ wxComboCtrlBase::CreateTextCtrl(int style)
|
||||
|
||||
void wxComboCtrlBase::OnThemeChange()
|
||||
{
|
||||
// Leave the default bg on the Mac so the area used by the focus ring will
|
||||
// be the correct colour and themed brush. Instead we'll use
|
||||
// wxSYS_COLOUR_WINDOW in the EVT_PAINT handler as needed.
|
||||
#ifndef __WXMAC__
|
||||
// Because wxComboCtrl has transparent parts on most platforms, we
|
||||
// don't want to touch the actual background colour. Instead, we just
|
||||
// usually re-obtain m_tcBgCol here.
|
||||
|
||||
#if defined(__WXMSW__) || defined(__WXGTK__)
|
||||
wxVisualAttributes vattrs = wxComboBox::GetClassDefaultAttributes();
|
||||
#else
|
||||
@@ -1083,17 +1083,19 @@ void wxComboCtrlBase::OnThemeChange()
|
||||
vattrs.colBg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
|
||||
#endif
|
||||
|
||||
if ( !m_hasBgCol )
|
||||
m_tcBgCol = vattrs.colBg;
|
||||
|
||||
#ifndef __WXMAC__
|
||||
// Only change the colours if application has not specified
|
||||
// custom ones.
|
||||
if ( !m_hasFgCol )
|
||||
{
|
||||
SetOwnForegroundColour(vattrs.colFg);
|
||||
m_hasFgCol = false;
|
||||
}
|
||||
if ( !m_hasBgCol )
|
||||
if ( !HasTransparentBackground() )
|
||||
{
|
||||
SetOwnBackgroundColour(vattrs.colBg);
|
||||
m_hasBgCol = false;
|
||||
SetOwnBackgroundColour(GetParent()->GetBackgroundColour());
|
||||
}
|
||||
#endif // !__WXMAC__
|
||||
}
|
||||
@@ -1477,15 +1479,21 @@ bool wxComboCtrlBase::SetForegroundColour(const wxColour& colour)
|
||||
}
|
||||
|
||||
bool wxComboCtrlBase::SetBackgroundColour(const wxColour& colour)
|
||||
{
|
||||
if ( wxControl::SetBackgroundColour(colour) )
|
||||
{
|
||||
if ( m_text )
|
||||
m_text->SetBackgroundColour(colour);
|
||||
m_tcBgCol = colour;
|
||||
m_hasBgCol = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
wxColour wxComboCtrlBase::GetBackgroundColour() const
|
||||
{
|
||||
if ( m_text )
|
||||
return m_text->GetBackgroundColour();
|
||||
return m_tcBgCol;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// painting
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -1644,7 +1652,9 @@ void wxComboCtrlBase::DrawButton( wxDC& dc, const wxRect& rect, int flags )
|
||||
return;
|
||||
|
||||
// Need to clear button background even if m_btn is present
|
||||
if ( flags & Button_PaintBackground )
|
||||
if ( (flags & Button_PaintBackground) &&
|
||||
(!HasTransparentBackground() ||
|
||||
!(m_iFlags & wxCC_IFLAG_BUTTON_OUTSIDE)) )
|
||||
{
|
||||
wxColour bgCol;
|
||||
|
||||
|
@@ -201,8 +201,10 @@ bool wxGenericComboCtrl::Create(wxWindow *parent,
|
||||
// Add keyboard input handlers for main control and textctrl
|
||||
InstallInputHandlers();
|
||||
|
||||
// Set background
|
||||
SetBackgroundStyle( wxBG_STYLE_CUSTOM ); // for double-buffering
|
||||
// Set background style for double-buffering, when needed
|
||||
// (cannot use when system draws background automatically)
|
||||
if ( !HasTransparentBackground() )
|
||||
SetBackgroundStyle( wxBG_STYLE_PAINT );
|
||||
|
||||
// SetInitialSize should be called last
|
||||
SetInitialSize(size);
|
||||
@@ -238,11 +240,19 @@ void wxGenericComboCtrl::OnResize()
|
||||
|
||||
void wxGenericComboCtrl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) )
|
||||
{
|
||||
wxSize sz = GetClientSize();
|
||||
wxAutoBufferedPaintDC dc(this);
|
||||
// Determine wxDC to use based on need to double-buffer or
|
||||
// use system-generated transparent background portions
|
||||
wxDC* dcPtr;
|
||||
if ( HasTransparentBackground() )
|
||||
dcPtr = new wxPaintDC(this);
|
||||
else
|
||||
dcPtr = new wxAutoBufferedPaintDC(this);
|
||||
wxDC& dc = *dcPtr;
|
||||
|
||||
const wxRect& rectb = m_btnArea;
|
||||
wxRect rect = m_tcArea;
|
||||
wxSize sz = GetClientSize();
|
||||
const wxRect& butRect = m_btnArea;
|
||||
wxRect tcRect = m_tcArea;
|
||||
wxRect fullRect(0, 0, sz.x, sz.y);
|
||||
|
||||
// artificial simple border
|
||||
if ( m_widthCustomBorder )
|
||||
@@ -256,10 +266,10 @@ void wxGenericComboCtrl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) )
|
||||
dc.SetPen( pen1 );
|
||||
|
||||
// area around both controls
|
||||
wxRect rect2(0,0,sz.x,sz.y);
|
||||
wxRect rect2(fullRect);
|
||||
if ( m_iFlags & wxCC_IFLAG_BUTTON_OUTSIDE )
|
||||
{
|
||||
rect2 = m_tcArea;
|
||||
rect2 = tcRect;
|
||||
if ( customBorder == 1 )
|
||||
{
|
||||
rect2.Inflate(1);
|
||||
@@ -282,44 +292,49 @@ void wxGenericComboCtrl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) )
|
||||
dc.DrawRectangle(rect2);
|
||||
}
|
||||
|
||||
#ifndef __WXMAC__ // see note in OnThemeChange
|
||||
wxColour winCol = GetBackgroundColour();
|
||||
#else
|
||||
wxColour winCol = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
|
||||
#endif
|
||||
// Clear the main background if the system doesn't do it by itself
|
||||
if ( !HasTransparentBackground() &&
|
||||
(tcRect.x > 0 || tcRect.y > 0) )
|
||||
{
|
||||
wxColour winCol = GetParent()->GetBackgroundColour();
|
||||
dc.SetBrush(winCol);
|
||||
dc.SetPen(winCol);
|
||||
|
||||
//wxLogDebug(wxT("hei: %i tcy: %i tchei: %i"),GetClientSize().y,m_tcArea.y,m_tcArea.height);
|
||||
//wxLogDebug(wxT("btnx: %i tcx: %i tcwid: %i"),m_btnArea.x,m_tcArea.x,m_tcArea.width);
|
||||
|
||||
// clear main background
|
||||
dc.DrawRectangle(rect);
|
||||
dc.DrawRectangle(fullRect);
|
||||
}
|
||||
|
||||
if ( !m_btn )
|
||||
{
|
||||
// Standard button rendering
|
||||
DrawButton(dc,rectb);
|
||||
DrawButton(dc, butRect);
|
||||
}
|
||||
|
||||
// paint required portion on the control
|
||||
if ( (!m_text || m_widthCustomPaint) )
|
||||
if ( !m_text || m_widthCustomPaint )
|
||||
{
|
||||
wxASSERT( m_widthCustomPaint >= 0 );
|
||||
|
||||
// Clear the text-control area background
|
||||
wxColour tcCol = GetBackgroundColour();
|
||||
dc.SetBrush(tcCol);
|
||||
dc.SetPen(tcCol);
|
||||
dc.DrawRectangle(tcRect);
|
||||
|
||||
// this is intentionally here to allow drawed rectangle's
|
||||
// right edge to be hidden
|
||||
if ( m_text )
|
||||
rect.width = m_widthCustomPaint;
|
||||
tcRect.width = m_widthCustomPaint;
|
||||
|
||||
dc.SetFont( GetFont() );
|
||||
|
||||
dc.SetClippingRegion(rect);
|
||||
dc.SetClippingRegion(tcRect);
|
||||
if ( m_popupInterface )
|
||||
m_popupInterface->PaintComboControl(dc,rect);
|
||||
m_popupInterface->PaintComboControl(dc, tcRect);
|
||||
else
|
||||
wxComboPopup::DefaultPaintComboControl(this,dc,rect);
|
||||
wxComboPopup::DefaultPaintComboControl(this, dc, tcRect);
|
||||
}
|
||||
|
||||
delete dcPtr;
|
||||
}
|
||||
|
||||
void wxGenericComboCtrl::OnMouseEvent( wxMouseEvent& event )
|
||||
|
Reference in New Issue
Block a user