[ 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 // Name: wx/combo.h
// Purpose: wxComboCtrl declaration // Purpose: wxComboCtrl declaration
// Author: Jaakko Salli // Author: Jaakko Salli
// Modified by: // Modified by:
// Created: Apr-30-2006 // Created: Apr-30-2006
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) Jaakko Salli // Copyright: (c) Jaakko Salli
@ -304,7 +304,7 @@ public:
// flags: wxRendererNative flags: wxCONTROL_ISSUBMENU: is drawing a list item instead of combo control // flags: wxRendererNative flags: wxCONTROL_ISSUBMENU: is drawing a list item instead of combo control
// wxCONTROL_SELECTED: list item is selected // wxCONTROL_SELECTED: list item is selected
// wxCONTROL_DISABLED: control/item is disabled // 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. // Returns true if focus indicator should be drawn in the control.
bool ShouldDrawFocus() const bool ShouldDrawFocus() const

View File

@ -59,7 +59,7 @@ public:
virtual ~wxComboCtrl(); 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; } static int GetFeatures() { return wxComboCtrlFeatures::All; }

View File

@ -37,13 +37,13 @@ enum
// //
// Callback flags // Callback flags (see wxOwnerDrawnComboBox::OnDrawItem)
// //
enum enum
{ {
// when set, we are painting the selected item in control, // when set, we are painting the selected item in control,
// not in the popup // not in the popup
wxCP_PAINTING_CONTROL = 0x0001 wxODCB_PAINTING_CONTROL = 0x0001
}; };
@ -84,17 +84,6 @@ public:
virtual void OnComboDoubleClick(); virtual void OnComboDoubleClick();
virtual bool LazyCreate(); 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 // Item management
void SetSelection( int item ); void SetSelection( int item );
void Insert( const wxString& item, int pos ); void Insert( const wxString& item, int pos );
@ -132,14 +121,31 @@ protected:
// Re-calculates width for given item // Re-calculates width for given item
void CheckWidth( int pos ); void CheckWidth( int pos );
// wxVListBox implementation // Callbacks for drawing and measuring items. Override in a derived class for
virtual void OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const; // owner-drawnness. Font, background and text colour have been prepared according
//virtual wxCoord OnMeasureItem(size_t n) const; // to selection, focus and such.
void OnDrawBackground(wxDC& dc, const wxRect& rect, size_t n) const; //
// 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; 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 // filter mouse move events happening outside the list box
// move selection with cursor // move selection with cursor
void OnMouseMove(wxMouseEvent& event); void OnMouseMove(wxMouseEvent& event);
@ -181,8 +187,8 @@ private:
class WXDLLIMPEXP_ADV wxOwnerDrawnComboBox : public wxComboCtrl, class WXDLLIMPEXP_ADV wxOwnerDrawnComboBox : public wxComboCtrl,
public wxItemContainer public wxItemContainer
{ {
friend class wxComboPopupWindow; //friend class wxComboPopupWindow;
friend class wxComboCtrlBase; friend class wxVListBoxComboPopup;
public: public:
// ctors and such // ctors and such
@ -273,6 +279,23 @@ public:
protected: 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 // clears all allocated client datas
void ClearClientDatas(); void ClearClientDatas();

View File

@ -396,79 +396,14 @@ END_EVENT_TABLE()
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxOwnerDrawnComboBox with custom paint list items // wxOwnerDrawnComboBox with custom paint list items
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/*
class wxPenStyleComboBox : public wxOwnerDrawnComboBox class wxPenStyleComboBox : public wxOwnerDrawnComboBox
{ {
public: public:
virtual bool OnDrawListItem( wxDC& dc, const wxRect& rect, int item, int flags ) virtual void OnDrawItem( wxDC& dc,
{ const wxRect& rect,
wxRect r(rect); int item,
r.Deflate(3); int flags ) const
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
{ {
if ( item == wxNOT_FOUND ) if ( item == wxNOT_FOUND )
return; return;
@ -506,7 +441,7 @@ public:
// Get text colour as pen colour // Get text colour as pen colour
dc.SetPen ( pen ); dc.SetPen ( pen );
if ( !(flags & wxCP_PAINTING_CONTROL) ) if ( !(flags & wxODCB_PAINTING_CONTROL) )
{ {
dc.DrawText(GetString( item ), dc.DrawText(GetString( item ),
r.x + 3, r.x + 3,
@ -824,15 +759,13 @@ MyFrame::MyFrame(const wxString& title)
// When defining derivative class for callbacks, we need // When defining derivative class for callbacks, we need
// to use two-stage creation (or redefine the common wx // to use two-stage creation (or redefine the common wx
// constructor). // constructor).
odc = new wxOwnerDrawnComboBox(panel,wxID_ANY,wxEmptyString, odc = new wxPenStyleComboBox();
wxDefaultPosition, wxDefaultSize, odc->Create(panel,wxID_ANY,wxEmptyString,
arrItems, wxDefaultPosition, wxDefaultSize,
wxCB_READONLY //wxNO_BORDER | wxCB_READONLY arrItems,
); wxCB_READONLY //wxNO_BORDER | wxCB_READONLY
);
odc->SetPopupControl( new wxPenStylePopup() );
//m_odc->SetCustomPaintWidth( 60 );
odc->SetSelection(0); odc->SetSelection(0);
odc->SetButtonPosition(-2, // width adjustment odc->SetButtonPosition(-2, // width adjustment
-6, // height 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 // 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(); wxSize sz = GetClientSize();
bool isEnabled; bool isEnabled;

View File

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