]> git.saurik.com Git - wxWidgets.git/commitdiff
[ 1492053 ] Add wxVListBox style callbacks to wxOwnerDrawnComboBox.
authorWłodzimierz Skiba <abx@abx.art.pl>
Wed, 14 Jun 2006 18:38:47 +0000 (18:38 +0000)
committerWłodzimierz Skiba <abx@abx.art.pl>
Wed, 14 Jun 2006 18:38:47 +0000 (18:38 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@39730 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/combo.h
include/wx/msw/combo.h
include/wx/odcombo.h
samples/combo/combo.cpp
src/common/combocmn.cpp
src/generic/odcombo.cpp
src/msw/combo.cpp

index 8c15a099c6ab7eae99e6a471e366c885310663b3..20ef7cb5b9d2a582c9a9b7d30dd4db4868c01603 100644 (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
index 8478f8cff2038c2d151c444d2aa3edef5515609d..7204e649d8517f1794f5e0156d9e74b2816c2d33 100644 (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; }
 
index 1e3f8aaa8ce30495466cb6709e3fa191cb2dabff..bb67677acf2497f90a13ab6f8f4fcecc94a2927e 100644 (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();
 
index 43e95ff6336c4e38df9fc20e6aa80646bf08accd..3c7934c75b6c48d16ec311151da8cc7fbb89d222 100644 (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
+class wxPenStyleComboBox : public wxOwnerDrawnComboBox
 {
 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->SetPopupControl( new wxPenStylePopup() );
+    odc = new wxPenStyleComboBox();
+    odc->Create(panel,wxID_ANY,wxEmptyString,
+                wxDefaultPosition, wxDefaultSize,
+                arrItems,
+                wxCB_READONLY //wxNO_BORDER | wxCB_READONLY
+               );
 
-    //m_odc->SetCustomPaintWidth( 60 );
     odc->SetSelection(0);
     odc->SetButtonPosition(-2, // width adjustment
                            -6, // height adjustment
index 36a3bbe91acd90c38212717fee75c29be7e72501..a1630119fb054210d0f230ab707abd49a06e97aa 100644 (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;
index f19b8309d04391eab992de737e88e9f5a6a5bf62..a568dd57840f4c36fd96b083506f37597caefc36 100644 (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
index 7ebac8b6aa5858503c7b0367f50f49ff85f76df0..c51a4bc77e3d5645d078b28ab367f8f878962c59 100644 (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;