[ 1492053 ] Add wxVListBox style callbacks to wxOwnerDrawnComboBox.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@39730 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Włodzimierz Skiba 2006-06-14 18:38:47 +00:00
parent ec09e18d35
commit 40b26d752d
7 changed files with 151 additions and 130 deletions

View File

@ -2,7 +2,7 @@
// Name: wx/combo.h
// Purpose: wxComboCtrl declaration
// Author: Jaakko Salli
// Modified by:
// Modified by:
// Created: Apr-30-2006
// RCS-ID: $Id$
// Copyright: (c) Jaakko Salli
@ -304,7 +304,7 @@ public:
// flags: wxRendererNative flags: wxCONTROL_ISSUBMENU: is drawing a list item instead of combo control
// wxCONTROL_SELECTED: list item is selected
// wxCONTROL_DISABLED: control/item is disabled
virtual void DrawFocusBackground( wxDC& dc, const wxRect& rect, int flags );
virtual void DrawFocusBackground( wxDC& dc, const wxRect& rect, int flags ) const;
// Returns true if focus indicator should be drawn in the control.
bool ShouldDrawFocus() const

View File

@ -59,7 +59,7 @@ public:
virtual ~wxComboCtrl();
virtual void DrawFocusBackground( wxDC& dc, const wxRect& rect, int flags );
virtual void DrawFocusBackground( wxDC& dc, const wxRect& rect, int flags ) const;
static int GetFeatures() { return wxComboCtrlFeatures::All; }

View File

@ -37,13 +37,13 @@ enum
//
// Callback flags
// Callback flags (see wxOwnerDrawnComboBox::OnDrawItem)
//
enum
{
// when set, we are painting the selected item in control,
// not in the popup
wxCP_PAINTING_CONTROL = 0x0001
wxODCB_PAINTING_CONTROL = 0x0001
};
@ -84,17 +84,6 @@ public:
virtual void OnComboDoubleClick();
virtual bool LazyCreate();
// Callbacks for drawing and measuring items. Override in a derived class for
// owner-drawnness.
// item: item index to be drawn, may be wxNOT_FOUND when painting combo control itself
// and there is no valid selection
// flags: wxCP_PAINTING_CONTROL is set if painting to combo control instead of list
virtual void OnDrawItem( wxDC& dc, const wxRect& rect, int item, int flags ) const;
// Return item width, or -1 for calculating from text extent (default)
virtual wxCoord OnMeasureItemWidth( size_t item ) const;
// Item management
void SetSelection( int item );
void Insert( const wxString& item, int pos );
@ -132,14 +121,31 @@ protected:
// Re-calculates width for given item
void CheckWidth( int pos );
// wxVListBox implementation
virtual void OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const;
//virtual wxCoord OnMeasureItem(size_t n) const;
void OnDrawBackground(wxDC& dc, const wxRect& rect, size_t n) const;
// Callbacks for drawing and measuring items. Override in a derived class for
// owner-drawnness. Font, background and text colour have been prepared according
// to selection, focus and such.
//
// item: item index to be drawn, may be wxNOT_FOUND when painting combo control itself
// and there is no valid selection
// flags: wxODCB_PAINTING_CONTROL is set if painting to combo control instead of list
// NOTE: If wxVListBoxComboPopup is used with wxComboCtrl class not derived from
// wxOwnerDrawnComboBox, this method must be overridden.
virtual void OnDrawItem( wxDC& dc, const wxRect& rect, int item, int flags ) const;
// Return item height
// This is same as in wxVListBox
virtual wxCoord OnMeasureItem( size_t item ) const;
// Return item width, or -1 for calculating from text extent (default)
virtual wxCoord OnMeasureItemWidth( size_t item ) const;
// Draw item and combo control background. Flags are same as with OnDrawItem.
// NB: Can't use name OnDrawBackground because of virtual function hiding warnings.
virtual void OnDrawBg(wxDC& dc, const wxRect& rect, int item, int flags) const;
// Additional wxVListBox implementation (no need to override in derived classes)
virtual void OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const;
void OnDrawBackground(wxDC& dc, const wxRect& rect, size_t n) const;
// filter mouse move events happening outside the list box
// move selection with cursor
void OnMouseMove(wxMouseEvent& event);
@ -181,8 +187,8 @@ private:
class WXDLLIMPEXP_ADV wxOwnerDrawnComboBox : public wxComboCtrl,
public wxItemContainer
{
friend class wxComboPopupWindow;
friend class wxComboCtrlBase;
//friend class wxComboPopupWindow;
friend class wxVListBoxComboPopup;
public:
// ctors and such
@ -273,6 +279,23 @@ public:
protected:
// Callback for drawing. Font, background and text colour have been
// prepared according to selection, focus and such.
// item: item index to be drawn, may be wxNOT_FOUND when painting combo control itself
// and there is no valid selection
// flags: wxODCB_PAINTING_CONTROL is set if painting to combo control instead of list
virtual void OnDrawItem( wxDC& dc, const wxRect& rect, int item, int flags ) const;
// Callback for item height, or -1 for default
virtual wxCoord OnMeasureItem( size_t item ) const;
// Callback for item width, or -1 for default/undetermined
virtual wxCoord OnMeasureItemWidth( size_t item ) const;
// Callback for background drawing. Flags are same as with
// OnDrawItem.
virtual void OnDrawBackground( wxDC& dc, const wxRect& rect, int item, int flags ) const;
// clears all allocated client datas
void ClearClientDatas();

View File

@ -396,79 +396,14 @@ END_EVENT_TABLE()
// ----------------------------------------------------------------------------
// wxOwnerDrawnComboBox with custom paint list items
// ----------------------------------------------------------------------------
/*
class wxPenStyleComboBox : public wxOwnerDrawnComboBox
{
public:
virtual bool OnDrawListItem( wxDC& dc, const wxRect& rect, int item, int flags )
{
wxRect r(rect);
r.Deflate(3);
r.height -= 2;
int pen_style = wxSOLID;
if ( item == 1 )
pen_style = wxTRANSPARENT;
else if ( item == 2 )
pen_style = wxDOT;
else if ( item == 3 )
pen_style = wxLONG_DASH;
else if ( item == 4 )
pen_style = wxSHORT_DASH;
else if ( item == 5 )
pen_style = wxDOT_DASH;
else if ( item == 6 )
pen_style = wxBDIAGONAL_HATCH;
else if ( item == 7 )
pen_style = wxCROSSDIAG_HATCH;
else if ( item == 8 )
pen_style = wxFDIAGONAL_HATCH;
else if ( item == 9 )
pen_style = wxCROSS_HATCH;
else if ( item == 10 )
pen_style = wxHORIZONTAL_HATCH;
else if ( item == 11 )
pen_style = wxVERTICAL_HATCH;
wxPen pen( dc.GetTextForeground(), 3, pen_style );
// Get text colour as pen colour
dc.SetPen ( pen );
if ( !(flags & wxCP_PAINTING_CONTROL) )
{
dc.DrawText(GetString( item ),
r.x + 3,
(r.y + 0) + ( (r.height/2) - dc.GetCharHeight() )/2
);
dc.DrawLine( r.x+5, r.y+((r.height/4)*3), r.x+r.width - 5, r.y+((r.height/4)*3) );
}
else
{
dc.DrawLine( r.x+5, r.y+r.height/2, r.x+r.width - 5, r.y+r.height/2 );
}
return true;
}
virtual wxCoord OnMeasureListItem( int WXUNUSED(item) )
{
return 24;
}
virtual wxCoord OnMeasureListItemWidth( int WXUNUSED(item) )
{
return -1; // default - will be measured from text width
}
};
*/
class wxPenStylePopup : public wxVListBoxComboPopup
{
public:
virtual void OnDrawItem( wxDC& dc, const wxRect& rect, int item, int flags ) const
virtual void OnDrawItem( wxDC& dc,
const wxRect& rect,
int item,
int flags ) const
{
if ( item == wxNOT_FOUND )
return;
@ -506,7 +441,7 @@ public:
// Get text colour as pen colour
dc.SetPen ( pen );
if ( !(flags & wxCP_PAINTING_CONTROL) )
if ( !(flags & wxODCB_PAINTING_CONTROL) )
{
dc.DrawText(GetString( item ),
r.x + 3,
@ -824,15 +759,13 @@ MyFrame::MyFrame(const wxString& title)
// When defining derivative class for callbacks, we need
// to use two-stage creation (or redefine the common wx
// constructor).
odc = new wxOwnerDrawnComboBox(panel,wxID_ANY,wxEmptyString,
wxDefaultPosition, wxDefaultSize,
arrItems,
wxCB_READONLY //wxNO_BORDER | wxCB_READONLY
);
odc = new wxPenStyleComboBox();
odc->Create(panel,wxID_ANY,wxEmptyString,
wxDefaultPosition, wxDefaultSize,
arrItems,
wxCB_READONLY //wxNO_BORDER | wxCB_READONLY
);
odc->SetPopupControl( new wxPenStylePopup() );
//m_odc->SetCustomPaintWidth( 60 );
odc->SetSelection(0);
odc->SetButtonPosition(-2, // width adjustment
-6, // height adjustment

View File

@ -1092,7 +1092,7 @@ void wxComboCtrlBase::DoSetToolTip(wxToolTip *tooltip)
// ----------------------------------------------------------------------------
// draw focus background on area in a way typical on platform
void wxComboCtrlBase::DrawFocusBackground( wxDC& dc, const wxRect& rect, int flags )
void wxComboCtrlBase::DrawFocusBackground( wxDC& dc, const wxRect& rect, int flags ) const
{
wxSize sz = GetClientSize();
bool isEnabled;

View File

@ -103,10 +103,10 @@ void wxVListBoxComboPopup::PaintComboControl( wxDC& dc, const wxRect& rect )
{
if ( !(m_combo->GetWindowStyle() & wxODCB_STD_CONTROL_PAINT) )
{
m_combo->DrawFocusBackground(dc,rect,0);
OnDrawBg(dc,rect,m_value,wxODCB_PAINTING_CONTROL);
if ( m_value >= 0 )
{
OnDrawItem(dc,rect,m_value,wxCP_PAINTING_CONTROL);
OnDrawItem(dc,rect,m_value,wxODCB_PAINTING_CONTROL);
return;
}
}
@ -128,40 +128,56 @@ void wxVListBoxComboPopup::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) co
OnDrawItem(dc,rect,(int)n,0);
}
wxCoord wxVListBoxComboPopup::OnMeasureItem(size_t WXUNUSED(n)) const
wxCoord wxVListBoxComboPopup::OnMeasureItem(size_t n) const
{
return m_itemHeight;
wxOwnerDrawnComboBox* combo = (wxOwnerDrawnComboBox*) m_combo;
wxASSERT_MSG( combo->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)),
wxT("you must subclass wxVListBoxComboPopup for drawing and measuring methods") );
wxCoord h = combo->OnMeasureItem(n);
if ( h < 0 )
h = m_itemHeight;
return h;
}
wxCoord wxVListBoxComboPopup::OnMeasureItemWidth(size_t WXUNUSED(n)) const
wxCoord wxVListBoxComboPopup::OnMeasureItemWidth(size_t n) const
{
//return OnMeasureListItemWidth(n);
return -1;
wxOwnerDrawnComboBox* combo = (wxOwnerDrawnComboBox*) m_combo;
wxASSERT_MSG( combo->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)),
wxT("you must subclass wxVListBoxComboPopup for drawing and measuring methods") );
return combo->OnMeasureItemWidth(n);
}
void wxVListBoxComboPopup::OnDrawBg( wxDC& dc,
const wxRect& rect,
int item,
int flags ) const
{
wxOwnerDrawnComboBox* combo = (wxOwnerDrawnComboBox*) m_combo;
wxASSERT_MSG( combo->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)),
wxT("you must subclass wxVListBoxComboPopup for drawing and measuring methods") );
combo->OnDrawBackground(dc,rect,item,flags);
}
void wxVListBoxComboPopup::OnDrawBackground(wxDC& dc, const wxRect& rect, size_t n) const
{
// we need to render selected and current items differently
if ( IsCurrent(n) )
{
m_combo->DrawFocusBackground( dc, rect, wxCONTROL_ISSUBMENU|wxCONTROL_SELECTED );
}
//else: do nothing for the normal items
OnDrawBg(dc,rect,(int)n,0);
}
// This is called from wxVListBoxComboPopup::OnDrawItem, with text colour and font prepared
void wxVListBoxComboPopup::OnDrawItem( wxDC& dc, const wxRect& rect, int item, int flags ) const
{
if ( flags & wxCP_PAINTING_CONTROL )
{
dc.DrawText( m_combo->GetValue(),
rect.x + m_combo->GetTextIndent(),
(rect.height-dc.GetCharHeight())/2 + rect.y );
}
else
{
dc.DrawText( GetString(item), rect.x + 2, rect.y );
}
wxOwnerDrawnComboBox* combo = (wxOwnerDrawnComboBox*) m_combo;
wxASSERT_MSG( combo->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)),
wxT("you must subclass wxVListBoxComboPopup for drawing and measuring methods") );
combo->OnDrawItem(dc,rect,item,flags);
}
void wxVListBoxComboPopup::DismissWithEvent()
@ -550,7 +566,7 @@ void wxVListBoxComboPopup::Populate( const wxArrayString& choices )
// Find initial selection
wxString strValue = m_combo->GetValue();
if ( strValue.Length() )
if ( strValue.length() )
m_value = m_strings.Index(strValue);
}
@ -718,9 +734,10 @@ int wxOwnerDrawnComboBox::FindString(const wxString& s, bool bCase) const
void wxOwnerDrawnComboBox::Select(int n)
{
wxCHECK_RET( (n == wxNOT_FOUND) || IsValid(n), _T("invalid index in wxOwnerDrawnComboBox::Select") );
EnsurePopupControl();
wxCHECK_RET( (n == wxNOT_FOUND) || IsValid(n), _T("invalid index in wxOwnerDrawnComboBox::Select") );
m_popupInterface->SetSelection(n);
wxString str;
@ -751,10 +768,11 @@ int wxOwnerDrawnComboBox::DoAppend(const wxString& item)
int wxOwnerDrawnComboBox::DoInsert(const wxString& item, unsigned int pos)
{
EnsurePopupControl();
wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into sorted list"));
wxCHECK_MSG(IsValidInsert(pos), -1, wxT("invalid index"));
EnsurePopupControl();
m_popupInterface->Insert(item,pos);
return pos;
@ -782,4 +800,48 @@ wxClientData* wxOwnerDrawnComboBox::DoGetItemClientObject(unsigned int n) const
return (wxClientData*) DoGetItemClientData(n);
}
// ----------------------------------------------------------------------------
// wxOwnerDrawnComboBox item drawing and measuring default implementations
// ----------------------------------------------------------------------------
void wxOwnerDrawnComboBox::OnDrawItem( wxDC& dc,
const wxRect& rect,
int item,
int flags ) const
{
if ( flags & wxODCB_PAINTING_CONTROL )
{
dc.DrawText( GetValue(),
rect.x + GetTextIndent(),
(rect.height-dc.GetCharHeight())/2 + rect.y );
}
else
{
dc.DrawText( m_popupInterface->GetString(item), rect.x + 2, rect.y );
}
}
wxCoord wxOwnerDrawnComboBox::OnMeasureItem( size_t WXUNUSED(item) ) const
{
return -1;
}
wxCoord wxOwnerDrawnComboBox::OnMeasureItemWidth( size_t WXUNUSED(item) ) const
{
return -1;
}
void wxOwnerDrawnComboBox::OnDrawBackground(wxDC& dc, const wxRect& rect, int item, int flags) const
{
// we need to render selected and current items differently
if ( m_popupInterface->IsCurrent((size_t)item) )
{
DrawFocusBackground(dc,
rect,
(flags&wxODCB_PAINTING_CONTROL?0:wxCONTROL_ISSUBMENU) |
wxCONTROL_SELECTED);
}
//else: do nothing for the normal items
}
#endif // wxUSE_ODCOMBOBOX

View File

@ -239,9 +239,12 @@ static void wxMSWDrawFocusRect( wxDC& dc, const wxRect& rect )
}
// draw focus background on area in a way typical on platform
void wxComboCtrl::DrawFocusBackground( wxDC& dc, const wxRect& rect, int flags )
void wxComboCtrl::DrawFocusBackground( wxDC& dc, const wxRect& rect, int flags ) const
{
wxUxThemeEngine* theme = (wxUxThemeEngine*) NULL;
// Constructor only calls GetHWND() const, so it should be safe
// to cast "this" to const.
wxUxThemeHandle hTheme(this, L"COMBOBOX");
//COLORREF cref;